"""(Work)flows for FHI-aims."""from__future__importannotationsfromcopyimportdeepcopyfromdataclassesimportdataclass,fieldfrompathlibimportPathfromtypingimportTYPE_CHECKING,AnyfromjobflowimportFlow,Makerfrompymatgen.io.aims.sets.coreimportRelaxSetGeneratorfromatomate2.aims.jobs.coreimportRelaxMakerifTYPE_CHECKING:frompymatgen.coreimportMolecule,Structurefromtyping_extensionsimportSelffromatomate2.aims.jobs.baseimportBaseAimsMaker
[docs]@dataclassclassDoubleRelaxMaker(Maker):"""Double relaxation maker for FHI-aims. A maker to perform a double relaxation in FHI-aims (first with light, and then with tight species_defaults). Parameters ---------- name : str A name for the flow relax_maker1: .BaseAimsMaker A maker that generates the first relaxation relax_maker2: .BaseAimsMaker A maker that generates the second relaxation """name:str="Double relaxation"relax_maker1:BaseAimsMaker=field(default_factory=RelaxMaker)relax_maker2:BaseAimsMaker=field(default_factory=RelaxMaker)
[docs]defmake(self,structure:Structure|Molecule,prev_dir:str|Path|None=None,)->Flow:"""Create a flow with two chained relaxations. Parameters ---------- structure : Structure or Molecule The structure to relax. prev_dir : str or Path or None A previous FHI-aims calculation directory to copy output files from. """relax1=self.relax_maker1.make(structure,prev_dir=prev_dir)relax1.name+=" 1"relax2=self.relax_maker2.make(relax1.output.structure,prev_dir=relax1.output.dir_name)relax2.name+=" 2"returnFlow([relax1,relax2],relax2.output,name=self.name)
[docs]@classmethoddeffrom_parameters(cls,parameters:dict[str,Any],species_defaults:list[str]|tuple[str,str]=("light","tight"),)->Self:"""Create the maker from an ASE parameter set. Creates a DoubleRelaxFlow for the same parameters with two different species defaults. Parameters ---------- parameters : dict a dictionary with calculation parameters species_defaults: list | tuple paths for species defaults to use relative to the given `species_dir` in parameters """# various checksiflen(species_defaults)!=2:raiseValueError("Two species defaults directories must be provided for DoubleRelaxFlow")if"species_dir"notinparameters:raiseKeyError("Provided parameters do not include species_dir")species_dir=Path(parameters["species_dir"])forbasis_setinspecies_defaults:ifnot(species_dir/basis_set).exists():basis_set_dir=(species_dir/basis_set).as_posix()raiseOSError(f"The species defaults directory {basis_set_dir} does not exist")# now the actual work beginsmakers=[]forbasis_setinspecies_defaults:parameters["species_dir"]=(species_dir/basis_set).as_posix()input_set=RelaxSetGenerator(user_params=deepcopy(parameters))makers.append(RelaxMaker(input_set_generator=input_set))returncls(relax_maker1=makers[0],relax_maker2=makers[1])