calphy 1.4.3__py3-none-any.whl → 1.4.4__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.4"
8
8
 
9
9
  def addtest(a,b):
10
10
  return a+b
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.4"
52
53
 
53
54
 
54
55
  def _check_equal(val):
@@ -180,6 +181,22 @@ class MeltingTemperature(BaseModel, title="Input options for melting temperature
180
181
  step: Annotated[int, Field(default=200, ge=20)]
181
182
  attempts: Annotated[int, Field(default=5, ge=1)]
182
183
 
184
+ class MaterialsProject(BaseModel, title='Input options for materials project'):
185
+ api_key: Annotated[str, Field(default="", exclude=True)]
186
+ conventional: Annotated[bool, Field(default=True)]
187
+ target_natoms: Annotated[int, Field(default=1500, description='The structure parsed from materials project would be repeated to approximately this value')]
188
+
189
+ @field_validator("api_key", mode="after")
190
+ def resolve_api_key(cls, v: str) -> str:
191
+ if not v:
192
+ return v
193
+ value = os.getenv(v)
194
+ if not value:
195
+ raise ValueError(
196
+ f"Environment variable '{v}' not found or empty. "
197
+ f"Set it before running, e.g.:\n export {v}='your_api_key_here'"
198
+ )
199
+ return value
183
200
 
184
201
  class Calculation(BaseModel, title="Main input class"):
185
202
  monte_carlo: Optional[MonteCarlo] = MonteCarlo()
@@ -191,6 +208,8 @@ class Calculation(BaseModel, title="Main input class"):
191
208
  tolerance: Optional[Tolerance] = Tolerance()
192
209
  uhlenbeck_ford_model: Optional[UFMP] = UFMP()
193
210
  melting_temperature: Optional[MeltingTemperature] = MeltingTemperature()
211
+ materials_project: Optional[MaterialsProject] = MaterialsProject()
212
+
194
213
  element: Annotated[List[str], BeforeValidator(to_list), Field(default=[])]
195
214
  n_elements: Annotated[int, Field(default=0)]
196
215
  mass: Annotated[List[float], BeforeValidator(to_list), Field(default=[])]
@@ -496,6 +515,44 @@ class Calculation(BaseModel, title="Main input class"):
496
515
  self._original_lattice = self.lattice.lower()
497
516
  write_structure_file = True
498
517
 
518
+ elif self.lattice.split('-')[0] == 'mp':
519
+ #confirm here that API key exists
520
+ if not self.materials_project.api_key:
521
+ raise ValueError('could not find API KEY, pls set it.')
522
+ #now we need to fetch the structure
523
+ try:
524
+ from mp_api.client import MPRester
525
+ except ImportError:
526
+ raise ImportError('Could not import mp_api, make sure you install mp_api package!')
527
+ #now all good
528
+ rest = {
529
+ "use_document_model": False,
530
+ "include_user_agent": True,
531
+ "api_key": self.materials_project.api_key,
532
+ }
533
+ with MPRester(**rest) as mpr:
534
+ docs = mpr.materials.summary.search(material_ids=[self.lattice])
535
+
536
+ structures = []
537
+ for doc in docs:
538
+ struct = doc['structure']
539
+ if self.materials_project.conventional:
540
+ aseatoms = struct.to_conventional().to_ase_atoms()
541
+ else:
542
+ aseatoms = struct.to_primitive().to_ase_atoms()
543
+ structures.append(aseatoms)
544
+ structure = structures[0]
545
+
546
+ if np.prod(self.repeat) == 1:
547
+ x = int(np.ceil((self.materials_project.target_natoms/len(structure))**(1/3)))
548
+ structure = structure.repeat(x)
549
+ else:
550
+ structure = structure.repeat(self.repeat)
551
+
552
+ self._natoms = len(structure)
553
+ self._original_lattice = self.lattice.lower()
554
+ write_structure_file = True
555
+
499
556
  else:
500
557
  # this is a file
501
558
  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
@@ -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.4
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=jdtdEFX95fL5I9BhMCehg_tsIWI3TuF5BEEax1JqdCE,233
2
2
  calphy/alchemy.py,sha256=IEYLfsJRsjfB0zFfApmxGbYXif7IE6mUY_vjTZoXdII,17236
3
3
  calphy/clitools.py,sha256=CjADSz3nc8CLYhAmw2Os7aT-Iu_0LLIF6tdAmUMJErw,4398
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=hGq4ecaxHJvZV9XI5RGM1eVIpcEpvbRkSCyr1ousTRo,35644
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=SLHiW5lrTZ4t_t1ZGCCehQnKioS5eFvyxxLuecYS9Iw,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.4.dist-info/licenses/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
21
+ calphy-1.4.4.dist-info/METADATA,sha256=UCs0MNKdMuusbCZkwRF7NjT07jTKdhVQ4An9_Us_0SE,4469
22
+ calphy-1.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ calphy-1.4.4.dist-info/entry_points.txt,sha256=KX5dP2iYy9GB4Mo0lbCPAz6jo-8b1Gt9GDmsDFzt9pQ,439
24
+ calphy-1.4.4.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
25
+ calphy-1.4.4.dist-info/RECORD,,
File without changes