@@ -20,21 +20,154 @@ def ase_to_pyiron(structure):
2020
2121def extract (job ):
2222 if type (job ).__name__ == 'Lammps' :
23- return process_job_lammps (job )
23+ return lammps_process_job (job )
24+ elif type (job ).__name__ == 'Calphy' :
25+ return calphy_process_job (job )
26+ elif type (job ).__name__ == 'Murnaghan' :
27+ return murnaghan .process_job (job )
28+ elif type (job ).__name__ == 'QuasiHarmonicJob' :
29+ return qha .process_job (job )
30+ elif type (job ).__name__ == 'Calphy' :
31+ return calphy .process_job (job )
32+ else :
33+ raise TypeError ("These type of pyiron Job is not currently supported" )
34+
35+
36+ def lammps_process_job (job ):
37+ method_dict = Simulation .template ()
38+ _lammps_identify_method (job , method_dict )
39+ _lammps_add_software (method_dict )
40+ _lammps_get_simulation_folder (job , method_dict )
41+ _lammps_extract_calculated_quantities (job , method_dict )
42+ _lammps_get_structures (job , method_dict )
43+ return method_dict
2444
25- def process_job_lammps (job ):
45+ def calphy_process_job (job ):
2646 method_dict = Simulation .template ()
27- identify_method (job , method_dict )
28- add_software (method_dict )
29- get_simulation_folder (job , method_dict )
30- extract_calculated_quantities (job , method_dict )
31- get_structures (job , method_dict )
47+ _calphy_identify_method (job , method_dict )
48+ _calphy_add_software (method_dict )
49+ _lammps_get_simulation_folder (job , method_dict )
50+ _calphy_extract_calculated_quantities (job , method_dict )
51+ _lammps_get_structures (job , method_dict )
3252 return method_dict
3353
34- def get_simulation_folder (job , method_dict ):
54+ def murnaghan_process_job (job ):
55+ #murnaghan job processing; add individual lammps jobs first
56+ job_dicts = []
57+ for jobid in job .child_ids :
58+ child_job = job .project .load (jobid )
59+ if type (child_job ).__name__ == 'Lammps' :
60+ single_job_dict = lammps_process_job (child_job )
61+ #note that we turn the jobs to child here
62+ job_dicts .append (single_job_dict )
63+
64+ #create an additional jobdict with the murnaghan job
65+ murnaghan_dict = Simulation .template ()
66+ _lammps_get_structures (job , murnaghan_dict )
67+ _lammps_get_simulation_folder (job , murnaghan_dict )
68+
69+ #add the murnaghan method
70+ murnaghan_dict ['method' ] = "EquationOfStateFit"
71+ outputs = []
72+ outputs .append (
73+ {
74+ "label" : "EquilibriumEnergy" ,
75+ "value" : np .round (job ['output/equilibrium_energy' ], decimals = 4 ),
76+ "unit" : "EV" ,
77+ "associate_to_sample" : True ,
78+ "basename" : "TotalEnergy" ,
79+ }
80+ )
81+ outputs .append (
82+ {
83+ "label" : "EquilibriumVolume" ,
84+ "value" : np .round (job ['output/equilibrium_volume' ], decimals = 4 ),
85+ "unit" : "ANGSTROM3" ,
86+ "associate_to_sample" : True ,
87+ "basename" : "Volume" ,
88+ }
89+ )
90+ outputs .append (
91+ {
92+ "label" : "TotalEnergy" ,
93+ "value" : np .round (job ['output/energy' ], decimals = 4 ),
94+ "unit" : "EV" ,
95+ "associate_to_sample" : True ,
96+ "basename" : "TotalEnergy" ,
97+ }
98+ )
99+ outputs .append (
100+ {
101+ "label" : "SimulationCellVolume" ,
102+ "value" : np .round (job ['output/volume' ], decimals = 4 ),
103+ "unit" : "ANGSTROM3" ,
104+ "associate_to_sample" : True ,
105+ "basename" : "SimulationCellVolume" ,
106+ }
107+ )
108+ outputs .append (
109+ {
110+ "label" : "BulkModulus" ,
111+ 'basename' : "BulkModulus" ,
112+ "value" : np .round (job ['output/equilibrium_bulk_modulus' ], decimals = 2 ),
113+ "unit" : "GigaPA" ,
114+ "associate_to_sample" : True ,
115+ }
116+ )
117+
118+ murnaghan_dict ['calculated_property' ] = outputs
119+ _lammps_add_software (murnaghan_dict )
120+ job_dicts .append (murnaghan_dict )
121+ return job_dicts
122+
123+ def quasiharmonic_process_job (job ):
124+ #murnaghan job processing; add individual lammps jobs first
125+ job_dicts = []
126+
127+ #create an additional jobdict with the murnaghan job
128+ quasi_dict = Simulation .template ()
129+ _lammps_get_structures (job , quasi_dict )
130+ _lammps_get_simulation_folder (job , quasi_dict )
131+
132+ #add the murnaghan method
133+ quasi_dict ['method' ] = "QuasiHarmonicApproximation"
134+ outputs = []
135+ outputs .append (
136+ {
137+ "label" : "QuasiharmonicFreeEnergy" ,
138+ "value" : np .round (job ['output/free_energy' ].T , decimals = 4 ),
139+ "unit" : "EV" ,
140+ "associate_to_sample" : True ,
141+ "basename" : "FreeEnergy" ,
142+ }
143+ )
144+ outputs .append (
145+ {
146+ "label" : "QuasiharmonicVolume" ,
147+ "value" : np .round (job ['output/volumes' ].T , decimals = 4 ),
148+ "unit" : "ANGSTROM3" ,
149+ "associate_to_sample" : True ,
150+ "basename" : "SimulationCellVolume" ,
151+ }
152+ )
153+ outputs .append (
154+ {
155+ "label" : "QuasiharmonicTemperature" ,
156+ "value" : np .round (job ['output/temperatures' ][0 ], decimals = 2 ),
157+ "unit" : "K" ,
158+ "associate_to_sample" : True ,
159+ "basename" : "Temperature" ,
160+ }
161+ )
162+ quasi_dict ['calculated_property' ] = outputs
163+ _lammps_add_software (quasi_dict )
164+ job_dicts .append (quasi_dict )
165+ return job_dicts
166+
167+ def _lammps_get_simulation_folder (job , method_dict ):
35168 method_dict ['path' ] = os .path .join (job .project .path , f'{ job .name } _hdf5' )
36169
37- def identify_method (job , method_dict ):
170+ def _lammps_identify_method (job , method_dict ):
38171 job_dict = job .input .to_dict ()
39172 input_dict = {
40173 job_dict ["control_inp/data_dict" ]["Parameter" ][x ]: job_dict [
@@ -134,7 +267,7 @@ def identify_method(job, method_dict):
134267 }
135268 )
136269
137- def add_software (method_dict ):
270+ def _lammps_add_software (method_dict ):
138271 method_dict ["workflow_manager" ] = {}
139272 method_dict ["workflow_manager" ]["uri" ] = "https://doi.org/10.1016/j.commatsci.2018.07.043"
140273 method_dict ["workflow_manager" ]["label" ] = "pyiron"
@@ -146,7 +279,7 @@ def add_software(method_dict):
146279 }
147280 method_dict ["software" ] = [software ]
148281
149- def extract_calculated_quantities (job , method_dict ):
282+ def _lammps_extract_calculated_quantities (job , method_dict ):
150283 """
151284 Extracts calculated quantities from a job.
152285
@@ -207,9 +340,136 @@ def extract_calculated_quantities(job, method_dict):
207340
208341 method_dict ['calculated_property' ] = outputs
209342
210- def get_structures (job , method_dict ):
343+ def _lammps_get_structures (job , method_dict ):
211344 initial_pyiron_structure = job .structure
212345 final_pyiron_structure = job .get_structure (frame = - 1 )
213346
214347 method_dict ['initial_sample' ] = initial_pyiron_structure
215- method_dict ['final_sample' ] = final_pyiron_structure
348+ method_dict ['final_sample' ] = final_pyiron_structure
349+
350+
351+ def _calphy_identify_method (job , method_dict ):
352+ pressure = job .input .pressure
353+ if pressure is None :
354+ iso = True
355+ fix_lattice = True
356+ elif np .isscalar (pressure ):
357+ iso = True
358+ fix_lattice = False
359+ elif np .shape (pressure ) == (1 ,):
360+ iso = True
361+ fix_lattice = False
362+ elif np .shape (pressure ) == (2 ,):
363+ iso = True
364+ fix_lattice = False
365+ elif np .shape (pressure ) == (1 , 3 ):
366+ iso = False
367+ fix_lattice = False
368+ elif np .shape (pressure ) == (2 , 3 ):
369+ iso = False
370+ fix_lattice = False
371+
372+ dof = []
373+ dof .append ("AtomicPositionRelaxation" )
374+ ensemble = 'IsothermalIsobaricEnsemble'
375+
376+ if not fix_lattice :
377+ dof .append ("CellVolumeRelaxation" )
378+ ensemble = "CanonicalEnsemble"
379+
380+ if not iso :
381+ dof .append ("CellShapeRelaxation" )
382+
383+ method_dict ["method" ] = {'basename' : 'ThermodynamicIntegration' }
384+ method_dict ["degrees_of_freedom" ] = dof
385+ method_dict ["thermodynamic_ensemble" ] = {'basename' : ensemble }
386+
387+ # now process potential
388+ inpdict = job .input .to_dict ()
389+ ps = inpdict ["potential_inp/data_dict" ]["Value" ][0 ]
390+ name = inpdict ["potential_inp/potential/Name" ]
391+ potstr = job .input .to_dict ()["potential_inp/potential/Citations" ]
392+ potdict = ast .literal_eval (potstr [1 :- 1 ])
393+ url = None
394+ if "url" in potdict [list (potdict .keys ())[0 ]].keys ():
395+ url = potdict [list (potdict .keys ())[0 ]]["url" ]
396+
397+ pssplit = ps .split ('/' )
398+ if len (pssplit ) > 1 :
399+ ps = pssplit [0 ]
400+
401+ method_dict ["interatomic_potential" ] = {
402+ 'potential_type' : ps ,
403+ }
404+
405+ if url is not None :
406+ method_dict ["interatomic_potential" ]["uri" ] = url
407+ else :
408+ method_dict ["interatomic_potential" ]["uri" ] = name
409+
410+ #add temperature and pressure as inputs
411+ method_dict ['input_parameter' ].append (
412+ {
413+ "basename" : "Temperature" ,
414+ "label" : "Temperature" ,
415+ "value" : job .input .temperature ,
416+ "unit" : "K" ,
417+ }
418+ )
419+
420+ method_dict ['input_parameter' ].append (
421+ {
422+ "basename" : "Pressure" ,
423+ "label" : "Pressure" ,
424+ "value" : job .input .pressure ,
425+ "unit" : "GigaPA" ,
426+ }
427+ )
428+
429+ def _calphy_add_software (method_dict ):
430+ method_dict ["workflow_manager" ] = {}
431+ method_dict ["workflow_manager" ]["uri" ] = "https://doi.org/10.1016/j.commatsci.2018.07.043"
432+ method_dict ["workflow_manager" ]["label" ] = "pyiron"
433+ # and finally code details
434+
435+ software1 = {
436+ "uri" : "https://doi.org/10.1016/j.cpc.2021.108171" ,
437+ "label" : "LAMMPS" ,
438+ }
439+ software2 = {
440+ "uri" : "https://doi.org/10.5281/zenodo.10527452" ,
441+ "label" : "Calphy" ,
442+ }
443+ method_dict ["software" ] = [software1 , software2 ]
444+
445+ def _calphy_extract_calculated_quantities (job , method_dict ):
446+
447+ outputs = []
448+ outputs .append (
449+ {
450+ "label" : "FreeEnergy" ,
451+ "basename" : "FreeEnergy" ,
452+ "value" : np .round (job ['output/energy_free' ], decimals = 4 ),
453+ "unit" : "EV" ,
454+ "associate_to_sample" : True ,
455+ }
456+ )
457+ outputs .append (
458+ {
459+ "label" : "VirialPressure" ,
460+ "basename" : "VirialPressure" ,
461+ "value" : np .round (job ['output/pressure' ], decimals = 4 ),
462+ "unit" : "GigaPA" ,
463+ "associate_to_sample" : True ,
464+ }
465+ )
466+ outputs .append (
467+ {
468+ "label" : "Temperature" ,
469+ "basename" : "Temperature" ,
470+ "value" : np .round (job ['output/temperature' ], decimals = 2 ),
471+ "unit" : "K" ,
472+ "associate_to_sample" : True ,
473+ }
474+ )
475+ method_dict ['calculated_property' ] = outputs
0 commit comments