Skip to content

Commit 356aebf

Browse files
authored
Merge pull request #100 from ICAMS/fix_automated_tm
Fix automated tm
2 parents 746eccc + 38774ac commit 356aebf

File tree

3 files changed

+83
-77
lines changed

3 files changed

+83
-77
lines changed

calphy/input.py

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from pydantic import BaseModel, Field, ValidationError, model_validator, conlist, PrivateAttr
2727
from pydantic.functional_validators import AfterValidator, BeforeValidator
2828
from annotated_types import Len
29+
import mendeleev
2930

3031
import yaml
3132
import numpy as np
@@ -127,6 +128,7 @@ class Calculation(BaseModel, title='Main input class'):
127128
Field(default=[])]
128129
_element_dict: dict = PrivateAttr(default={})
129130
kernel: Annotated[int, Field(default=0)]
131+
inputfile: Annotated[str, Field(default='')]
130132

131133
mode: Annotated[str, Field(default=None)]
132134
lattice: Annotated[str, Field(default="")]
@@ -235,14 +237,38 @@ def _validate_all(self) -> 'Input':
235237
raise ValueError('Unknown format for pressure')
236238

237239
self._temperature_input = copy.copy(self.temperature)
238-
if self.temperature is None:
239-
self._temperature = None
240+
#guess a melting temp of the system, this will be mostly ignored
241+
#chem = mendeleev.element(self.element[0])
242+
#self._melting_temperature = chem.melting_point
243+
try:
244+
chem = mendeleev.element(self.element[0])
245+
self._melting_temperature = chem.melting_point
246+
except:
247+
self._melting_temperature = None
248+
249+
if self.temperature == 0:
250+
#the only situation in which it can be None is if mode is melting temp
251+
if len(self.element) > 1:
252+
raise ValueError("Cannot guess start temperature for more than one species, please specify")
253+
#now try to guess
254+
if self._melting_temperature is None:
255+
raise ValueError("Could not guess start temperature for more than one species, please specify")
256+
self._temperature = self._melting_temperature
257+
self._temperature_stop = self._melting_temperature
258+
if self.temperature_high == 0:
259+
self._temperature_high = 2*self._melting_temperature
260+
else:
261+
self._temperature_high = self.temperature_high
262+
240263
elif np.shape(np.atleast_1d(self.temperature)) == (1,):
241264
temp = np.atleast_1d(self.temperature)
242265
self._temperature = temp[0]
243266
self._temperature_stop = temp[0]
244-
if self._temperature_high is None:
267+
if self.temperature_high == 0:
245268
self._temperature_high = 2*temp[0]
269+
else:
270+
self._temperature_high = self.temperature_high
271+
246272
elif np.shape(self.temperature) == (2,):
247273
temp = self.temperature
248274
self._temperature = temp[0]
@@ -293,16 +319,16 @@ def _validate_all(self) -> 'Input':
293319
if self.lattice == "":
294320
#fetch from dict
295321
if len(self.element) > 1:
296-
raise ValueError("MeltingTemperature can be used only with one element")
322+
raise ValueError("Cannot create lattice for more than one element")
297323
if self.element[0] in element_dict.keys():
298-
self.lattice = element_dict[self.element[0]]['structure']
324+
self.lattice = element_dict[self.element[0]]['structure']
299325
self.lattice_constant = element_dict[self.element[0]]['lattice_constant']
300326
else:
301327
raise ValueError("Could not find structure, please provide lattice and lattice_constant explicitely")
302328

303329
if self.repeat == [1,1,1]:
304330
self.repeat = [5,5,5]
305-
331+
306332
structure = _make_crystal(self.lattice.lower(),
307333
lattice_constant=self.lattice_constant,
308334
repetitions=self.repeat,
@@ -317,7 +343,7 @@ def _validate_all(self) -> 'Input':
317343
self._element_dict[t]['composition'] = typecounts[c]/np.sum(typecounts)
318344

319345
self._natoms = structure.natoms
320-
self._original_lattice = self.lattice
346+
self._original_lattice = self.lattice.lower()
321347
write_structure_file = True
322348

323349
elif self.lattice.lower() in structure_dict.keys():
@@ -347,7 +373,7 @@ def _validate_all(self) -> 'Input':
347373
#self._composition = concdict_frac
348374
#self._composition_counts = concdict_counts
349375
self._natoms = structure.natoms
350-
self._original_lattice = self.lattice
376+
self._original_lattice = self.lattice.lower()
351377
write_structure_file = True
352378

353379
else:
@@ -369,7 +395,7 @@ def _validate_all(self) -> 'Input':
369395
self._element_dict[t]['count'] = typecounts[c]
370396
self._element_dict[t]['composition'] = typecounts[c]/np.sum(typecounts)
371397
self._natoms = structure.natoms
372-
self._original_lattice = self.lattice
398+
self._original_lattice = os.path.basename(self.lattice)
373399
self.lattice = os.path.abspath(self.lattice)
374400

375401
#if needed, write the file out
@@ -435,19 +461,14 @@ def create_identifier(self):
435461
"""
436462
#lattice processed
437463
prefix = self.mode
438-
if prefix == 'melting_temperature':
439-
ts = int(0)
440-
ps = int(0)
441-
l = 'tm'
464+
ts = int(self._temperature)
465+
if self._pressure is None:
466+
ps = "None"
442467
else:
443-
ts = int(self._temperature)
444-
if self._pressure is None:
445-
ps = "None"
446-
else:
447-
ps = "%d"%(int(self._pressure))
448-
l = self._original_lattice
449-
l = l.split('/')
450-
l = l[-1]
468+
ps = "%d"%(int(self._pressure))
469+
l = self._original_lattice
470+
l = l.split('/')
471+
l = l[-1]
451472

452473
if self.folder_prefix is None:
453474
identistring = "-".join([prefix, l.lower(), self.reference_phase, str(ts), str(ps)])
@@ -524,6 +545,7 @@ def _read_inputfile(file):
524545
calculations = []
525546
for count, calc in enumerate(data['calculations']):
526547
calc['kernel'] = count
548+
calc['inputfile'] = file
527549
calculations.append(Calculation(**calc))
528550
return calculations
529551

@@ -559,6 +581,7 @@ def _convert_legacy_inputfile(file, return_calcs=False):
559581
#calc['reference_phase'] = str(ci["reference_phase"]) if "reference_phase" in ci.keys() else 'none'
560582
#calc['lattice_constant'] = float(ci["lattice_constant"]) if "lattice_constant" in ci.keys() else 0
561583
calc['kernel'] = cc
584+
calc['inputfile'] = file
562585
calculations.append(calc)
563586

564587
else:
@@ -608,6 +631,7 @@ def _convert_legacy_inputfile(file, return_calcs=False):
608631
calc["pressure"] = _to_float(combo[1])
609632
calc["temperature"] = _to_float(combo[2])
610633
calc['kernel'] = cc
634+
calc['inputfile'] = file
611635
cc += 1
612636
calculations.append(calc)
613637

calphy/routines.py

Lines changed: 37 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import os
2727
import time
2828
from mendeleev import element
29+
import yaml
2930

3031
from calphy.input import read_inputfile
3132
#import calphy.queuekernel as cq
@@ -56,19 +57,16 @@ def __init__(self, calculation=None, simfolder=None, log_to_screen=False):
5657
self.calc = calculation
5758
self.simfolder = simfolder
5859
self.log_to_screen = log_to_screen
59-
self.org_tm = 0
6060
self.dtemp = self.calc.melting_temperature.step
6161
self.maxattempts = self.calc.melting_temperature.attempts
6262
self.attempts = 0
63-
self.exp_tm = self.calc._temperature
6463
self.calculations = []
6564

66-
self.get_props(self.calc.element[0])
6765
self.get_trange()
6866
self.arg = None
6967

7068

71-
logfile = os.path.join(os.getcwd(), "calphy.log")
69+
logfile = os.path.join(os.getcwd(), f'{self.calc.create_identifier()}.log')
7270
self.logger = ph.prepare_log(logfile, screen=log_to_screen)
7371

7472
def prepare_calcs(self):
@@ -83,53 +81,39 @@ def prepare_calcs(self):
8381
-------
8482
None
8583
"""
86-
self.calc.temperature = [int(self.tmin), int(self.tmax)]
87-
self.calc._temperature = int(self.tmin)
88-
self.calc._temperature_stop = int(self.tmax)
89-
csol = copy.deepcopy(self.calc)
90-
clqd = copy.deepcopy(self.calc)
91-
92-
#csol.lattice = self.lattice.upper()
93-
#clqd.lattice = 'LQD'
94-
csol.reference_phase = 'solid'
95-
clqd.reference_phase = 'liquid'
96-
#csol.lattice_constant = self.lattice_constant
97-
#clqd.lattice_constant = self.lattice_constant
98-
csol._temperature_high = self.tmin
99-
clqd._temperature_high = 1.5*self.tmax
100-
csol.mode = 'ts'
101-
clqd.mode = 'ts'
102-
103-
#csol['directory'] = create_identifier(csol)
104-
#clqd['directory'] = create_identifier(clqd)
105-
self.calculations = [csol, clqd]
106-
107-
108-
def get_props(self, elem):
109-
"""
110-
Get properties from mendeleev
111-
112-
Parameters
113-
----------
114-
elem : string
115-
Chemical symbol of the element
11684

117-
Returns
118-
-------
119-
None
120-
"""
121-
chem = element(elem)
122-
#lattice = chem.lattice_structure
123-
#self.lattice_constant = chem.lattice_constant
124-
self.org_tm = chem.melting_point
85+
#here, we need to prepare a new calculation
86+
#protocol, read in, modify, write a output
87+
#read input again
88+
calculations = {"calculations": []}
12589

126-
if self.exp_tm == 0:
127-
self.exp_tm = chem.melting_point
128-
129-
#if lattice == "HEX":
130-
# lattice = "HCP"
131-
#self.lattice = lattice.lower()
90+
with open(self.calc.inputfile, 'r') as fin:
91+
data = yaml.safe_load(fin)
92+
calc = data["calculations"][int(self.calc.kernel)]
93+
94+
calc["mode"] = "ts"
95+
calc["temperature"] = [int(self.tmin), int(self.tmax)]
96+
calc["reference_phase"] = 'solid'
97+
calculations["calculations"].append(calc)
98+
99+
with open(self.calc.inputfile, 'r') as fin:
100+
data = yaml.safe_load(fin)
101+
calc = data["calculations"][int(self.calc.kernel)]
102+
103+
calc["mode"] = "ts"
104+
calc["temperature"] = [int(self.tmin), int(self.tmax)]
105+
calc["reference_phase"] = 'liquid'
106+
calculations["calculations"].append(calc)
107+
108+
outfile = f'{self.calc.create_identifier()}.{self.attempts}.yaml'
109+
with open(outfile, "w") as fout:
110+
yaml.safe_dump(calculations, fout)
111+
112+
#now read in again, which would allow for checking and so on
113+
#one could do this smartly, and simply create from here.
114+
self.calculations = read_inputfile(outfile)
132115

116+
133117
def get_trange(self):
134118
"""
135119
Get temperature range for calculations
@@ -142,10 +126,10 @@ def get_trange(self):
142126
-------
143127
None
144128
"""
145-
tmin = self.exp_tm - self.dtemp
129+
tmin = self.calc._temperature - self.dtemp
146130
if tmin < 0:
147131
tmin = 10
148-
tmax = self.exp_tm + self.dtemp
132+
tmax = self.calc._temperature + self.dtemp
149133
self.tmax = tmax
150134
self.tmin = tmin
151135

@@ -332,8 +316,9 @@ def calculate_tm(self):
332316
self.start_calculation()
333317
tm, tmerr = self.find_tm()
334318
self.logger.info('Found melting temperature = %.2f +/- %.2f K '%(tm, tmerr))
335-
self.logger.info('Experimental melting temperature = %.2f K '%(self.org_tm))
336-
self.logger.info('STATE: Tm = %.2f K +/- %.2f K, Exp. Tm = %.2f K'%(tm, tmerr, self.org_tm))
319+
if self.calc._melting_temperature is not None:
320+
self.logger.info('Experimental melting temperature = %.2f K '%(self.calc._melting_temperature))
321+
self.logger.info('STATE: Tm = %.2f K +/- %.2f K'%(tm, tmerr))
337322

338323
def routine_fe(job):
339324
"""

examples/example_04/input.1.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@ calculations:
99
n_switching_steps: 15000
1010
pair_coeff: '* * ../potentials/Cu01.eam.alloy Cu'
1111
pair_style: eam/alloy
12+
equilibration_control: berendsen
1213
queue:
1314
commands:
1415
- conda activate calphy
1516
cores: 4
1617
scheduler: local
17-
repeat:
18-
- 5
19-
- 5
20-
- 5

0 commit comments

Comments
 (0)