calphy 1.4.3__py3-none-any.whl → 1.4.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- calphy/__init__.py +1 -1
- calphy/clitools.py +1 -0
- calphy/input.py +84 -1
- calphy/integrators.py +7 -2
- calphy/phase.py +6 -1
- calphy/postprocessing.py +10 -10
- {calphy-1.4.3.dist-info → calphy-1.4.5.dist-info}/METADATA +1 -1
- {calphy-1.4.3.dist-info → calphy-1.4.5.dist-info}/RECORD +12 -12
- {calphy-1.4.3.dist-info → calphy-1.4.5.dist-info}/WHEEL +0 -0
- {calphy-1.4.3.dist-info → calphy-1.4.5.dist-info}/entry_points.txt +0 -0
- {calphy-1.4.3.dist-info → calphy-1.4.5.dist-info}/licenses/LICENSE +0 -0
- {calphy-1.4.3.dist-info → calphy-1.4.5.dist-info}/top_level.txt +0 -0
calphy/__init__.py
CHANGED
calphy/clitools.py
CHANGED
calphy/input.py
CHANGED
|
@@ -28,6 +28,7 @@ from pydantic import (
|
|
|
28
28
|
Field,
|
|
29
29
|
ValidationError,
|
|
30
30
|
model_validator,
|
|
31
|
+
field_validator,
|
|
31
32
|
conlist,
|
|
32
33
|
PrivateAttr,
|
|
33
34
|
)
|
|
@@ -48,7 +49,7 @@ from pyscal3.core import structure_dict, element_dict, _make_crystal
|
|
|
48
49
|
from ase.io import read, write
|
|
49
50
|
import shutil
|
|
50
51
|
|
|
51
|
-
__version__ = "1.4.
|
|
52
|
+
__version__ = "1.4.5"
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
def _check_equal(val):
|
|
@@ -181,6 +182,30 @@ class MeltingTemperature(BaseModel, title="Input options for melting temperature
|
|
|
181
182
|
attempts: Annotated[int, Field(default=5, ge=1)]
|
|
182
183
|
|
|
183
184
|
|
|
185
|
+
class MaterialsProject(BaseModel, title="Input options for materials project"):
|
|
186
|
+
api_key: Annotated[str, Field(default="", exclude=True)]
|
|
187
|
+
conventional: Annotated[bool, Field(default=True)]
|
|
188
|
+
target_natoms: Annotated[
|
|
189
|
+
int,
|
|
190
|
+
Field(
|
|
191
|
+
default=1500,
|
|
192
|
+
description="The structure parsed from materials project would be repeated to approximately this value",
|
|
193
|
+
),
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
@field_validator("api_key", mode="after")
|
|
197
|
+
def resolve_api_key(cls, v: str) -> str:
|
|
198
|
+
if not v:
|
|
199
|
+
return v
|
|
200
|
+
value = os.getenv(v)
|
|
201
|
+
if not value:
|
|
202
|
+
raise ValueError(
|
|
203
|
+
f"Environment variable '{v}' not found or empty. "
|
|
204
|
+
f"Set it before running, e.g.:\n export {v}='your_api_key_here'"
|
|
205
|
+
)
|
|
206
|
+
return value
|
|
207
|
+
|
|
208
|
+
|
|
184
209
|
class Calculation(BaseModel, title="Main input class"):
|
|
185
210
|
monte_carlo: Optional[MonteCarlo] = MonteCarlo()
|
|
186
211
|
composition_scaling: Optional[CompositionScaling] = CompositionScaling()
|
|
@@ -191,6 +216,8 @@ class Calculation(BaseModel, title="Main input class"):
|
|
|
191
216
|
tolerance: Optional[Tolerance] = Tolerance()
|
|
192
217
|
uhlenbeck_ford_model: Optional[UFMP] = UFMP()
|
|
193
218
|
melting_temperature: Optional[MeltingTemperature] = MeltingTemperature()
|
|
219
|
+
materials_project: Optional[MaterialsProject] = MaterialsProject()
|
|
220
|
+
|
|
194
221
|
element: Annotated[List[str], BeforeValidator(to_list), Field(default=[])]
|
|
195
222
|
n_elements: Annotated[int, Field(default=0)]
|
|
196
223
|
mass: Annotated[List[float], BeforeValidator(to_list), Field(default=[])]
|
|
@@ -496,6 +523,62 @@ class Calculation(BaseModel, title="Main input class"):
|
|
|
496
523
|
self._original_lattice = self.lattice.lower()
|
|
497
524
|
write_structure_file = True
|
|
498
525
|
|
|
526
|
+
elif self.lattice.split("-")[0] == "mp":
|
|
527
|
+
# confirm here that API key exists
|
|
528
|
+
if not self.materials_project.api_key:
|
|
529
|
+
raise ValueError("could not find API KEY, pls set it.")
|
|
530
|
+
# now we need to fetch the structure
|
|
531
|
+
try:
|
|
532
|
+
from mp_api.client import MPRester
|
|
533
|
+
except ImportError:
|
|
534
|
+
raise ImportError(
|
|
535
|
+
"Could not import mp_api, make sure you install mp_api package!"
|
|
536
|
+
)
|
|
537
|
+
# now all good
|
|
538
|
+
rest = {
|
|
539
|
+
"use_document_model": False,
|
|
540
|
+
"include_user_agent": True,
|
|
541
|
+
"api_key": self.materials_project.api_key,
|
|
542
|
+
}
|
|
543
|
+
with MPRester(**rest) as mpr:
|
|
544
|
+
docs = mpr.materials.summary.search(material_ids=[self.lattice])
|
|
545
|
+
|
|
546
|
+
structures = []
|
|
547
|
+
for doc in docs:
|
|
548
|
+
struct = doc["structure"]
|
|
549
|
+
if self.materials_project.conventional:
|
|
550
|
+
aseatoms = struct.to_conventional().to_ase_atoms()
|
|
551
|
+
else:
|
|
552
|
+
aseatoms = struct.to_primitive().to_ase_atoms()
|
|
553
|
+
structures.append(aseatoms)
|
|
554
|
+
structure = structures[0]
|
|
555
|
+
|
|
556
|
+
if np.prod(self.repeat) == 1:
|
|
557
|
+
x = int(
|
|
558
|
+
np.ceil(
|
|
559
|
+
(self.materials_project.target_natoms / len(structure))
|
|
560
|
+
** (1 / 3)
|
|
561
|
+
)
|
|
562
|
+
)
|
|
563
|
+
structure = structure.repeat(x)
|
|
564
|
+
else:
|
|
565
|
+
structure = structure.repeat(self.repeat)
|
|
566
|
+
|
|
567
|
+
# extract composition
|
|
568
|
+
types, typecounts = np.unique(
|
|
569
|
+
structure.get_chemical_symbols(), return_counts=True
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
for c, t in enumerate(types):
|
|
573
|
+
self._element_dict[t]["count"] = typecounts[c]
|
|
574
|
+
self._element_dict[t]["composition"] = typecounts[c] / np.sum(
|
|
575
|
+
typecounts
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
self._natoms = len(structure)
|
|
579
|
+
self._original_lattice = self.lattice.lower()
|
|
580
|
+
write_structure_file = True
|
|
581
|
+
|
|
499
582
|
else:
|
|
500
583
|
# this is a file
|
|
501
584
|
if not os.path.exists(self.lattice):
|
calphy/integrators.py
CHANGED
|
@@ -226,6 +226,7 @@ def integrate_rs(simfolder, f0, t,
|
|
|
226
226
|
|
|
227
227
|
"""
|
|
228
228
|
ws = []
|
|
229
|
+
es = []
|
|
229
230
|
p = p/(10000*160.21766208)
|
|
230
231
|
|
|
231
232
|
for i in range(1, nsims+1):
|
|
@@ -245,9 +246,12 @@ def integrate_rs(simfolder, f0, t,
|
|
|
245
246
|
wf = cumtrapz(fdx, flambda,initial=0)
|
|
246
247
|
wb = cumtrapz(bdx[::-1], blambda[::-1],initial=0)
|
|
247
248
|
w = (wf + wb) / (2*flambda)
|
|
249
|
+
e = np.max(np.abs((wf - wb)/(2*flambda)))
|
|
250
|
+
|
|
248
251
|
ws.append(w)
|
|
249
|
-
|
|
252
|
+
es.append(e)
|
|
250
253
|
|
|
254
|
+
e_diss = np.min(es)
|
|
251
255
|
wmean = np.mean(ws, axis=0)
|
|
252
256
|
werr = np.std(ws, axis=0)
|
|
253
257
|
temp = t/flambda
|
|
@@ -257,8 +261,9 @@ def integrate_rs(simfolder, f0, t,
|
|
|
257
261
|
if not return_values:
|
|
258
262
|
outfile = os.path.join(simfolder, "temperature_sweep.dat")
|
|
259
263
|
np.savetxt(outfile, np.column_stack((temp, f, werr)))
|
|
264
|
+
return None, e_diss
|
|
260
265
|
else:
|
|
261
|
-
return (temp, f, werr)
|
|
266
|
+
return (temp, f, werr), e_diss
|
|
262
267
|
|
|
263
268
|
|
|
264
269
|
def integrate_ps(simfolder, f0, natoms, pi, pf, nsims=1,
|
calphy/phase.py
CHANGED
|
@@ -1206,7 +1206,7 @@ class Phase:
|
|
|
1206
1206
|
res : list of lists of shape 1x3
|
|
1207
1207
|
Only returned if `return_values` is True.
|
|
1208
1208
|
"""
|
|
1209
|
-
res = integrate_rs(
|
|
1209
|
+
res, ediss = integrate_rs(
|
|
1210
1210
|
self.simfolder,
|
|
1211
1211
|
self.fe,
|
|
1212
1212
|
self.calc._temperature,
|
|
@@ -1217,6 +1217,11 @@ class Phase:
|
|
|
1217
1217
|
return_values=return_values,
|
|
1218
1218
|
)
|
|
1219
1219
|
|
|
1220
|
+
self.logger.info(f'Maximum energy dissipation along the temperature scaling part: {ediss} eV/atom')
|
|
1221
|
+
if np.abs(ediss) > 1E-4:
|
|
1222
|
+
self.logger.warning(f'Found max energy dissipation of {ediss} along the temperature scaling path. Please ensure there are no structural changes!')
|
|
1223
|
+
|
|
1224
|
+
|
|
1220
1225
|
if return_values:
|
|
1221
1226
|
return res
|
|
1222
1227
|
|
calphy/postprocessing.py
CHANGED
|
@@ -30,15 +30,15 @@ def read_report(folder):
|
|
|
30
30
|
|
|
31
31
|
def _extract_error(errfile):
|
|
32
32
|
error_code = None
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
try:
|
|
34
|
+
if os.path.exists(errfile):
|
|
35
|
+
with open(errfile, 'r') as fin:
|
|
36
|
+
for line in fin:
|
|
37
|
+
if 'calphy.errors' in line:
|
|
38
|
+
break
|
|
39
|
+
error_code = line.split(':')[0].split('.')[-1]
|
|
40
|
+
except:
|
|
41
|
+
pass
|
|
42
42
|
return error_code
|
|
43
43
|
|
|
44
44
|
def gather_results(mainfolder, reduce_composition=True,
|
|
@@ -121,7 +121,7 @@ def gather_results(mainfolder, reduce_composition=True,
|
|
|
121
121
|
#print(inpfile)
|
|
122
122
|
if not os.path.exists(outfile):
|
|
123
123
|
datadict['status'].append('False')
|
|
124
|
-
datadict['free_energy'].append(np.
|
|
124
|
+
datadict['free_energy'].append(np.nan)
|
|
125
125
|
#check if error file is found
|
|
126
126
|
errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
|
|
127
127
|
datadict['error_code'][-1] = _extract_error(errfile)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
calphy/__init__.py,sha256=
|
|
1
|
+
calphy/__init__.py,sha256=ajDpPU1OkfwLqHSjYro8IgKKujLpCZhkszpGfQHA_5U,233
|
|
2
2
|
calphy/alchemy.py,sha256=IEYLfsJRsjfB0zFfApmxGbYXif7IE6mUY_vjTZoXdII,17236
|
|
3
|
-
calphy/clitools.py,sha256=
|
|
3
|
+
calphy/clitools.py,sha256=ZUr6ZfdopFxWMbrzNT_TQaUA16iPmZ3144oPcwcDazY,4433
|
|
4
4
|
calphy/composition_transformation.py,sha256=z3X4fFVoym6QgRDpLBYZ_fM9V0IgJvBq-wITu1nwVmw,17247
|
|
5
5
|
calphy/errors.py,sha256=KN47RWTLbg1H_NZMrhCiJCbqjqJScJ1pgQAuzj1-l84,1268
|
|
6
6
|
calphy/helpers.py,sha256=goN_n5kceSaevjBilQDgHD5-QZxsQsOwTiWsY00jMcM,8411
|
|
7
|
-
calphy/input.py,sha256=
|
|
8
|
-
calphy/integrators.py,sha256=
|
|
7
|
+
calphy/input.py,sha256=3xVoJcbwq3T7y_1drIvg1Erel9dz6y9A4rgNsncEfgw,36225
|
|
8
|
+
calphy/integrators.py,sha256=q5sIJX3nh4c9kmDQJ4Pqhvm38tRWKELoJwm5gW0lqws,21858
|
|
9
9
|
calphy/kernel.py,sha256=wjSpQ59PN-aqHQ1kvOxTYnP2d3wE1Zx4A9ZhqQFqGlI,6311
|
|
10
10
|
calphy/liquid.py,sha256=ECF3DxPZv7XHnmQzk_yz1fol-Vsd98lRojTMAR1YS3M,15025
|
|
11
|
-
calphy/phase.py,sha256=
|
|
11
|
+
calphy/phase.py,sha256=F4GRrEG0IDR6f0rFabQYP7aYBzpKAyxPvol-n7vAj08,53540
|
|
12
12
|
calphy/phase_diagram.py,sha256=Yu192y7bhWsj-xQL7ITSBdMHKXJ6I_4gV0cLfdXTOa4,27791
|
|
13
|
-
calphy/postprocessing.py,sha256=
|
|
13
|
+
calphy/postprocessing.py,sha256=XxpFGbR8dUoKhGb7GCPEWPA4CWl7ZftuM1cN4tz7-fQ,15164
|
|
14
14
|
calphy/queuekernel.py,sha256=4GMIYnjMiAPipoLNKP5noYcfeEOI_vCqm84zgokk7Xw,5321
|
|
15
15
|
calphy/routines.py,sha256=YaVoAbeAbZ3ytAP_A0o5ngkpPiXpc_lk2I0bN3nqhPs,17858
|
|
16
16
|
calphy/scheduler.py,sha256=nIxlKKGj8ol_FuYMMtXrQinPGhPlYs2h-JsEGHC7_wY,8666
|
|
17
17
|
calphy/solid.py,sha256=zHSqri8roW23hIQ21huxHHJqq3P5EklSj6Z0z9ywfbc,21911
|
|
18
18
|
calphy/splines.py,sha256=BGwUVz_qXQxUzpUCuZo6CsELcd5JVNWzI-Ttcz22G_E,61627
|
|
19
19
|
calphy/utils.py,sha256=0UpsYoxjS5N-iGs-cdm0YDMkLF8IHvKO3smXDHrj3eg,3818
|
|
20
|
-
calphy-1.4.
|
|
21
|
-
calphy-1.4.
|
|
22
|
-
calphy-1.4.
|
|
23
|
-
calphy-1.4.
|
|
24
|
-
calphy-1.4.
|
|
25
|
-
calphy-1.4.
|
|
20
|
+
calphy-1.4.5.dist-info/licenses/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
|
|
21
|
+
calphy-1.4.5.dist-info/METADATA,sha256=za1qlwUMSyzxwl2bghD8i9HdGRMLKpxslgpkX-jiM2s,4469
|
|
22
|
+
calphy-1.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
calphy-1.4.5.dist-info/entry_points.txt,sha256=KX5dP2iYy9GB4Mo0lbCPAz6jo-8b1Gt9GDmsDFzt9pQ,439
|
|
24
|
+
calphy-1.4.5.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
|
|
25
|
+
calphy-1.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|