99
1010
1111def run_lammps (modelname : str , temperature_K : float , pressure_bar : float , timestep_ps : float ,
12- number_sampling_timesteps : int , species : List [str ],
12+ thermo_sampling_period : int , species : List [str ],
1313 msd_threshold_angstrom_squared_per_sampling_timesteps : float , number_msd_timesteps : int ,
14- lammps_command : str , random_seed : int ) -> Tuple [str , str , str , str ]:
14+ rlc_run_length : int , rlc_n_every : int , output_dir : str , equilibration_plots : bool , lammps_command : str ,
15+ random_seed : int ) -> Tuple [str , str , str , str , str ]:
1516 """
1617 Run LAMMPS NPT simulation with the given parameters.
1718
@@ -33,9 +34,9 @@ def run_lammps(modelname: str, temperature_K: float, pressure_bar: float, timest
3334 :param timestep_ps:
3435 Timestep in picoseconds.
3536 :type timestep_ps: float
36- :param number_sampling_timesteps :
37+ :param thermo_sampling_period :
3738 Number of timesteps for sampling thermodynamic quantities.
38- :type number_sampling_timesteps : int
39+ :type thermo_sampling_period : int
3940 :param species:
4041 List of chemical species in the system.
4142 :type species: List[str]
@@ -47,6 +48,19 @@ def run_lammps(modelname: str, temperature_K: float, pressure_bar: float, timest
4748 Before the mean-squared displacement is monitored, the system will be equilibrated for the same number of
4849 timesteps.
4950 :type number_msd_timesteps: int
51+ :param rlc_run_length:
52+ Number of timesteps after which kim-convergence will check for convergence.
53+ This is also the timestep interval for generated trajectories.
54+ :type rlc_run_length: int
55+ :param rlc_n_every:
56+ Number of timesteps between storage of values for the run-length control in kim-convergence.
57+ :type rlc_n_every: int
58+ :param output_dir:
59+ Directory to store the output files.
60+ :type output_dir: str
61+ :param equilibration_plots:
62+ Whether to plot the equilibration plots.
63+ :type equilibration_plots: bool
5064 :param lammps_command:
5165 Command to run LAMMPS (e.g., "mpirun -np 4 lmp_mpi" or "lmp").
5266 :type lammps_command: str
@@ -55,15 +69,19 @@ def run_lammps(modelname: str, temperature_K: float, pressure_bar: float, timest
5569 :type random_seed: int
5670
5771 :return:
58- A tuple containing paths to the LAMMPS log file, restart file, full average position file, and full average cell
59- file.
60- :rtype: Tuple[str, str, str, str]
72+ A tuple containing paths to the LAMMPS log file, restart file, full average position file, full average cell
73+ file, and melted crystal dump file (only exists if crystal melted) .
74+ :rtype: Tuple[str, str, str, str, str ]
6175 """
62- pdamp = timestep_ps * 100.0
63- tdamp = timestep_ps * 1000.0
64-
65- log_filename = "output/lammps.log"
66- restart_filename = "output/final_configuration.restart"
76+ pdamp = timestep_ps * 1000.0
77+ tdamp = timestep_ps * 100.0
78+
79+ # Lammps will be run directly in output_dir so all paths are with respect to that directory.
80+ log_filename = "lammps.log"
81+ restart_filename = "final_configuration.restart"
82+ melted_crystal_filename = "melted_crystal.dump"
83+ average_position_filename = "average_position.dump"
84+ average_cell_filename = "average_cell.dump"
6785 variables = {
6886 "modelname" : modelname ,
6987 "temperature" : temperature_K ,
@@ -72,43 +90,48 @@ def run_lammps(modelname: str, temperature_K: float, pressure_bar: float, timest
7290 "pressure" : pressure_bar ,
7391 "pressure_damping" : pdamp ,
7492 "timestep" : timestep_ps ,
75- "number_sampling_timesteps " : number_sampling_timesteps ,
93+ "thermo_sampling_period " : thermo_sampling_period ,
7694 "species" : " " .join (species ),
77- "average_position_filename" : "output/average_position.dump.*" ,
78- "average_cell_filename" : "output/average_cell.dump" ,
95+ "zero_temperature_crystal_filename" : "zero_temperature_crystal.lmp" ,
96+ "average_position_filename" : f"{ average_position_filename } .*" ,
97+ "average_cell_filename" : average_cell_filename ,
7998 "write_restart_filename" : restart_filename ,
80- "trajectory_filename" : "output/ trajectory.lammpstrj" ,
81- "msd_trajectory_filename" : "output/ msd_trajectory.lammpstrj" ,
99+ "trajectory_filename" : "trajectory.lammpstrj" ,
100+ "msd_trajectory_filename" : "msd_trajectory.lammpstrj" ,
82101 "msd_threshold" : msd_threshold_angstrom_squared_per_sampling_timesteps ,
83102 "msd_timesteps" : number_msd_timesteps ,
84- "melted_crystal_output" : "output/melted_crystal.dump"
103+ "rlc_run_length" : rlc_run_length ,
104+ "rlc_n_every" : rlc_n_every ,
105+ "melted_crystal_output" : melted_crystal_filename
85106 }
86107
87108 command = (
88109 f"{ lammps_command } "
89110 + " " .join (f"-var { key } '{ item } '" for key , item in variables .items ())
90111 + f" -log { log_filename } "
91- + " -in npt.lammps" )
112+ + f " -in npt.lammps" )
92113
93- subprocess .run (command , check = True , shell = True )
114+ subprocess .run (command , check = True , shell = True , cwd = output_dir )
94115
95- plot_property_from_lammps_log (log_filename , ("v_vol_metal" , "v_temp_metal" , "v_enthalpy_metal" ))
116+ if equilibration_plots :
117+ plot_property_from_lammps_log (f"{ output_dir } /{ log_filename } " ,
118+ ("v_vol_metal" , "v_temp_metal" , "v_enthalpy_metal" ))
96119
97- # 10000 offset from MSD detection during which kim_convergence was not used.
98- equilibration_time = extract_equilibration_step_from_logfile (log_filename ) + 10000
99- # Round to next multiple of 10000.
100- equilibration_time = int (ceil (equilibration_time / 10000.0 )) * 10000
120+ equilibration_time = extract_equilibration_step_from_logfile (f"{ output_dir } /{ log_filename } " )
121+ # Round to next multiple of rlc_run_length.
122+ equilibration_time = int (ceil (equilibration_time / float (rlc_run_length ))) * rlc_run_length
101123
102- full_average_position_file = "output/average_position.dump .full"
103- compute_average_positions_from_lammps_dump ("output" ,
104- "average_position.dump" ,
124+ full_average_position_file = f" { output_dir } / { average_position_filename } .full"
125+ compute_average_positions_from_lammps_dump (output_dir ,
126+ average_position_filename ,
105127 full_average_position_file , equilibration_time )
106128
107- full_average_cell_file = "output/average_cell.dump .full"
108- compute_average_cell_from_lammps_dump ("output/average_cell.dump " ,
129+ full_average_cell_file = f" { output_dir } / { average_cell_filename } .full"
130+ compute_average_cell_from_lammps_dump (f" { output_dir } / { average_cell_filename } " ,
109131 full_average_cell_file , equilibration_time )
110132
111- return log_filename , restart_filename , full_average_position_file , full_average_cell_file
133+ return (f"{ output_dir } /{ log_filename } " , f"{ output_dir } /{ restart_filename } " , full_average_position_file ,
134+ full_average_cell_file , f"{ output_dir } /{ melted_crystal_filename } " )
112135
113136
114137def plot_property_from_lammps_log (in_file_path : str , property_names : Iterable [str ]) -> None :
0 commit comments