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 CHANGED
@@ -4,7 +4,7 @@ from calphy.solid import Solid
4
4
  from calphy.alchemy import Alchemy
5
5
  from calphy.routines import MeltingTemp
6
6
 
7
- __version__ = "1.4.3"
7
+ __version__ = "1.4.5"
8
8
 
9
9
  def addtest(a,b):
10
10
  return a+b
calphy/clitools.py CHANGED
@@ -125,4 +125,5 @@ def phase_diagram():
125
125
  arg = ap.ArgumentParser()
126
126
  arg.add_argument("-i", "--input", required=True, type=str,
127
127
  help="name of the input file")
128
+ args = vars(arg.parse_args())
128
129
  prepare_inputs_for_phase_diagram(args['input'])
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.3"
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
- if os.path.exists(errfile):
34
- with open(errfile, 'r') as fin:
35
- for line in fin:
36
- if 'calphy.errors' in line:
37
- break
38
- try:
39
- error_code = line.split(':')[0].split('.')[-1]
40
- except:
41
- pass
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.NaN)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calphy
3
- Version: 1.4.3
3
+ Version: 1.4.5
4
4
  Summary: free energy calculation for python
5
5
  Home-page: https://github.com/ICAMS/calphy
6
6
  Author: Sarath Menon, Yury Lysogorskiy, Ralf Drautz
@@ -1,25 +1,25 @@
1
- calphy/__init__.py,sha256=0kafBUoGTV6xYpg_eCXGg42xa8W1ge6tDoJz6sS2Y38,233
1
+ calphy/__init__.py,sha256=ajDpPU1OkfwLqHSjYro8IgKKujLpCZhkszpGfQHA_5U,233
2
2
  calphy/alchemy.py,sha256=IEYLfsJRsjfB0zFfApmxGbYXif7IE6mUY_vjTZoXdII,17236
3
- calphy/clitools.py,sha256=CjADSz3nc8CLYhAmw2Os7aT-Iu_0LLIF6tdAmUMJErw,4398
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=sDMbnyjyUs3al0kdHpMYBKzBbe4iug2426YPLnVxhl0,33169
8
- calphy/integrators.py,sha256=hJYmbznsgY-x-eZm7ng8gW0qsGbopERl5gGDnw5uLms,21719
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=rmOb_T2IsSR48HNvpACnlw9USYagzWT5zqZXymnVVA4,53231
11
+ calphy/phase.py,sha256=F4GRrEG0IDR6f0rFabQYP7aYBzpKAyxPvol-n7vAj08,53540
12
12
  calphy/phase_diagram.py,sha256=Yu192y7bhWsj-xQL7ITSBdMHKXJ6I_4gV0cLfdXTOa4,27791
13
- calphy/postprocessing.py,sha256=WmCVj_xyCOU3pO5hycj8Qmfrx-bhIWcVnSfjx_yZkwQ,15164
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.3.dist-info/licenses/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
21
- calphy-1.4.3.dist-info/METADATA,sha256=ldKbDFVDC_C1qk1jzLw7lCV3-S558UunR2wNfZ16cbA,4469
22
- calphy-1.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- calphy-1.4.3.dist-info/entry_points.txt,sha256=KX5dP2iYy9GB4Mo0lbCPAz6jo-8b1Gt9GDmsDFzt9pQ,439
24
- calphy-1.4.3.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
25
- calphy-1.4.3.dist-info/RECORD,,
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