"""Define all Core FHI-aims jobs."""from__future__importannotationsimportloggingfromcollections.abcimportSequencefromdataclassesimportdataclass,fieldfrompathlibimportPathfromtypingimportTYPE_CHECKINGfromjobflowimportResponse,jobfrommonty.serializationimportdumpfnfrompymatgen.io.aims.parsersimportread_aims_outputfrompymatgen.io.aims.sets.bsimportBandStructureSetGenerator,GWSetGeneratorfrompymatgen.io.aims.sets.coreimport(RelaxSetGenerator,SocketIOSetGenerator,StaticSetGenerator,)fromatomate2importSETTINGSfromatomate2.aims.filesimportcleanup_aims_outputs,write_aims_input_setfromatomate2.aims.jobs.baseimport_FILES_TO_ZIP,BaseAimsMakerfromatomate2.aims.runimportrun_aims_socket,should_stop_childrenfromatomate2.aims.schemas.taskimportAimsTaskDocfromatomate2.common.filesimportgzip_output_folderifTYPE_CHECKING:frompymatgen.coreimportMolecule,Structurefrompymatgen.io.aims.sets.baseimportAimsInputGeneratorlogger=logging.getLogger(__name__)
[docs]@dataclassclassStaticMaker(BaseAimsMaker):"""Maker to create FHI-aims SCF jobs. Parameters ---------- calc_type: str The type key for the calculation name: str The job name input_set_generator: .AimsInputGenerator The InputGenerator for the calculation """calc_type:str="scf"name:str="SCF Calculation"input_set_generator:AimsInputGenerator=field(default_factory=StaticSetGenerator)
[docs]@dataclassclassRelaxMaker(BaseAimsMaker):"""Maker to create relaxation calculations. Parameters ---------- calc_type: str The type key for the calculation name: str The job name input_set_generator: .AimsInputGenerator The InputGenerator for the calculation """calc_type:str="relax"name:str="Relaxation calculation"input_set_generator:AimsInputGenerator=field(default_factory=RelaxSetGenerator)
[docs]@classmethoddeffixed_cell_relaxation(cls,*args,**kwargs)->RelaxMaker:"""Create a fixed cell relaxation maker."""returncls(input_set_generator=RelaxSetGenerator(*args,relax_cell=False,**kwargs),name=cls.name+" (fixed cell)",)
[docs]@classmethoddeffull_relaxation(cls,*args,**kwargs)->RelaxMaker:"""Create a full relaxation maker."""returncls(input_set_generator=RelaxSetGenerator(*args,relax_cell=True,**kwargs))
[docs]@dataclassclassSocketIOStaticMaker(BaseAimsMaker):"""Maker for the SocketIO calculator in FHI-aims. Parameters ---------- calc_type: str The type key for the calculation name: str The job name host: str The name of the host to maintain the socket server on port: int The port number the socket server will listen on input_set_generator: .AimsInputGenerator The InputGenerator for the calculation """calc_type:str="multi_scf"name:str="SCF Calculations Socket"host:str="localhost"port:int=12345input_set_generator:AimsInputGenerator=field(default_factory=SocketIOSetGenerator)
[docs]@jobdefmake(self,structure:list[Structure|Molecule],prev_dir:str|Path|None=None,)->Response:"""Run multiple FHI-aims calculation with the socket. Calculate the properties for multiple structures using the same parameters using socket communication to speed up the calculations. Parameters ---------- structure : list[Molecule | Structure] The list of structure objects to run FHI-aims on prev_dir : str or Path or None A previous FHI-aims calculation directory to copy output files from. Returns ------- The output response for the calculations """# copy previous inputsifnotisinstance(structure,list):structure=[structure]from_prev=prev_dirisnotNoneiffrom_prev:hostless_prev_dir=str(prev_dir).split(":")[1]images=read_aims_output(f"{hostless_prev_dir}/aims.out")ifnotisinstance(images,Sequence):images=[images]forimginimages:img.calc=Noneforiiinrange(-1*len(structure),0,-1):ifstructure[ii]inimages:delstructure[ii]# write aims input filesself.write_input_set_kwargs["prev_dir"]=prev_dirwrite_aims_input_set(structure[0],self.input_set_generator,**self.write_input_set_kwargs)# write any additional dataforfilename,datainself.write_additional_data.items():dumpfn(data,filename.replace(":","."))# run FHI-aimsrun_aims_socket(structure,**self.run_aims_kwargs)# parse FHI-aims outputstask_doc=AimsTaskDoc.from_directory(Path.cwd(),**self.task_document_kwargs)task_doc.task_label=self.name# decide whether child jobs should proceedstop_children=should_stop_children(task_doc,**self.stop_children_kwargs)# cleanup files to save disk spacecleanup_aims_outputs(directory=Path.cwd())# gzip foldergzip_output_folder(directory=Path.cwd(),setting=SETTINGS.VASP_ZIP_FILES,files_list=_FILES_TO_ZIP,)returnResponse(stop_children=stop_children,output=task_docifself.store_output_dataelseNone,)
[docs]@dataclassclassBandStructureMaker(BaseAimsMaker):"""A job Maker for a band structure calculation. Parameters ---------- calc_type: str The type key for the calculation name: str The job name input_set_generator: .BandStructureSetGenerator The InputGenerator for the calculation """calc_type="band_structure"name:str="bands"input_set_generator:BandStructureSetGenerator=field(default_factory=BandStructureSetGenerator)
[docs]@dataclassclassGWMaker(BaseAimsMaker):"""A job Maker for a GW band structure calculation. Parameters ---------- calc_type: str The type key for the calculation name: str The job name input_set_generator: .GWSetGenerator The InputGenerator for the calculation """calc_type="gw"name:str="GW"input_set_generator:GWSetGenerator=field(default_factory=GWSetGenerator)