"""Flows for running molecular dynamics simulations."""from__future__importannotationsfromdataclassesimportdataclass,fieldfromtypingimportTYPE_CHECKINGfromjobflowimportFlow,Maker,OutputReferencefromatomate2.vasp.jobs.mdimportMDMaker,md_outputfromatomate2.vasp.sets.coreimportMDSetGeneratorifTYPE_CHECKING:frompathlibimportPathfrompymatgen.coreimportStructurefromtyping_extensionsimportSelffromatomate2.vasp.jobs.baseimportBaseVaspMaker
[docs]@dataclassclassMultiMDMaker(Maker):""" Maker to perform an MD run split in several steps. Parameters ---------- name : str Name of the flows produced by this maker. md_makers : .BaseVaspMaker Maker to use to generate the first relaxation. """name:str="multi md"md_makers:list[BaseVaspMaker]=field(default_factory=lambda:[MDMaker()])
[docs]defmake(self,structure:Structure,prev_dir:str|Path|None=None,prev_traj_ids:list[str]|None=None,)->Flow:"""Create a flow with several chained MD runs. Parameters ---------- structure : .Structure A pymatgen structure object. prev_dir : str or Path or None A previous VASP calculation directory to copy output files from. prev_traj_ids: a list of ids of job identifying previous steps of the MD trajectory. Returns ------- Flow A flow containing n_runs MD calculations. """md_job=Nonemd_jobs=[]md_structure=structuremd_prev_dir=prev_dirforidx,makerinenumerate(self.md_makers,start=1):ifmd_jobisnotNone:md_structure=md_job.output.structuremd_prev_dir=md_job.output.dir_namemd_job=maker.make(md_structure,prev_dir=md_prev_dir)md_job.name+=f" {idx}"md_jobs.append(md_job)output_job=md_output(structure=md_jobs[-1].output.structure,vasp_dir=md_jobs[-1].output.dir_name,traj_ids=[j.uuidforjinmd_jobs],prev_traj_ids=prev_traj_ids,)output_job.name="molecular dynamics output"md_jobs.append(output_job)returnFlow(md_jobs,output_job.output,name=self.name)
[docs]defrestart_from_uuid(self,md_ref:str|OutputReference)->Flow:"""Create a flow from the output reference of another MultiMDMaker. The last output will be used as the starting point and the reference to all the previous steps will be included in the final document. Parameters ---------- md_ref: str or OutputReference The reference to the output of another MultiMDMaker Returns ------- A flow containing n_runs MD calculations. """ifisinstance(md_ref,str):md_ref=OutputReference(md_ref)returnself.make(structure=md_ref.structure,prev_dir=md_ref.vasp_dir,prev_traj_ids=md_ref.full_traj_ids,)
[docs]@classmethoddeffrom_parameters(cls,nsteps:int,time_step:float,n_runs:int,ensemble:str,start_temp:float,end_temp:float|None=None,**kwargs,)->Self:"""Create an instance of the Maker based on the standard parameters. Set values in the Flow maker, the Job Maker and the VaspInputGenerator, using them to create the final instance of the Maker. Parameters ---------- nsteps: int Number of time steps for simulations. The VASP `NSW` parameter. time_step: float The time step (in femtosecond) for the simulation. The VASP `POTIM` parameter. n_runs : int Number of MD runs in the flow. ensemble: str Molecular dynamics ensemble to run. Options include `nvt`, `nve`, and `npt`. start_temp: float Starting temperature. The VASP `TEBEG` parameter. end_temp: float or None Final temperature. The VASP `TEEND` parameter. If None the same as start_temp. kwargs: Other parameters passed Returns ------- A MultiMDMaker """ifend_tempisNone:end_temp=start_tempmd_makers=[]start_temp_i=start_tempincrement=(end_temp-start_temp)/n_runsfor_inrange(n_runs):end_temp_i=start_temp_i+incrementgenerator=MDSetGenerator(nsteps=nsteps,time_step=time_step,ensemble=ensemble,start_temp=start_temp_i,end_temp=end_temp_i,)md_makers.append(MDMaker(input_set_generator=generator))start_temp_i=end_temp_ireturncls(md_makers=md_makers,**kwargs)