calphy 1.3.10__py3-none-any.whl → 1.3.11__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.3.10"
7
+ __version__ = "1.3.11"
8
8
 
9
9
  def addtest(a,b):
10
10
  return a+b
calphy/input.py CHANGED
@@ -40,19 +40,7 @@ from pyscal3.core import structure_dict, element_dict, _make_crystal
40
40
  from ase.io import read, write
41
41
  import shutil
42
42
 
43
- __version__ = "1.3.10"
44
-
45
- def read_report(folder):
46
- """
47
- Read the finished calculation report
48
- """
49
- repfile = os.path.join(folder, "report.yaml")
50
- if not os.path.exists(repfile):
51
- raise FileNotFoundError(f"file {repfile} not found")
52
-
53
- with open(repfile, 'r') as fin:
54
- data = yaml.safe_load(fin)
55
- return data
43
+ __version__ = "1.3.11"
56
44
 
57
45
  def _check_equal(val):
58
46
  if not (val[0]==val[1]==val[2]):
calphy/integrators.py CHANGED
@@ -38,12 +38,13 @@ from ase.io import read
38
38
 
39
39
  #Constants
40
40
  h = const.physical_constants["Planck constant in eV/Hz"][0]
41
+ hJ = const.physical_constants["Planck constant"][0]
41
42
  hbar = h/(2*np.pi)
42
43
  kb = const.physical_constants["Boltzmann constant in eV/K"][0]
43
44
  kbJ = const.physical_constants["Boltzmann constant"][0]
44
45
  Na = const.physical_constants["Avogadro constant"][0]
45
46
  eV2J = const.eV
46
-
47
+ J2eV = 6.242E18
47
48
 
48
49
  #--------------------------------------------------------------------
49
50
  # TI PATH INTEGRATION ROUTINES
@@ -469,23 +470,18 @@ def get_einstein_crystal_fe(
469
470
  calc,
470
471
  vol,
471
472
  k,
472
- cm_correction=True):
473
+ cm_correction=True,
474
+ return_contributions=False):
473
475
  """
474
476
  Get the free energy of einstein crystal
475
477
 
476
478
  Parameters
477
479
  ----------
478
- temp : temperature, float
479
- units - K
480
-
481
- natoms : int
482
- no of atoms in the system
483
-
484
- mass : float
485
- units - g/mol
480
+ calc : Calculation object
481
+ contains all input parameters
486
482
 
487
- a : lattice constant, float
488
- units - Angstrom
483
+ vol : float
484
+ converged volume per atom
489
485
 
490
486
  k : spring constant, float
491
487
  units - eV/Angstrom^2
@@ -493,40 +489,77 @@ def get_einstein_crystal_fe(
493
489
  cm_correction : bool, optional, default - True
494
490
  add the centre of mass correction to free energy
495
491
 
492
+ return_contributions: bool, optional, default - True
493
+ If True, return individual contributions to the reference free energy.
494
+
496
495
  Returns
497
496
  -------
498
- fe : float
499
- free energy of Einstein crystal
497
+ F_tot : float
498
+ total free energy of reference crystal
499
+
500
+ F_e : float
501
+ Free energy of Einstein crystal without centre of mass correction. Only if `return_contributions` is True.
502
+
503
+ F_cm : float
504
+ centre of mass correction. Only if `return_contributions` is True.
505
+
506
+ Notes
507
+ -----
508
+ The equations for free energy of Einstein crystal and centre of mass correction are from https://doi.org/10.1063/5.0044833.
500
509
 
501
510
  """
502
- #convert mass first for single particle in kg
503
- mass = np.array([calc._element_dict[x]['mass'] for x in calc.element])
504
- mass = (mass/Na)*1E-3
505
- natoms = np.sum([calc._element_dict[x]['count'] for x in calc.element])
506
- concentration = np.array([calc._element_dict[x]['composition'] for x in calc.element])
511
+ #temperature
512
+ temp = calc._temperature
507
513
 
508
- #convert k from ev/A2 to J/m2
509
- k = np.array(k)*(eV2J/1E-20)
510
- omega = np.sqrt(k/mass)
514
+ #natoms
515
+ natoms = np.sum([calc._element_dict[x]['count'] for x in calc.element])
511
516
 
512
517
  #convert a to m3
513
518
  vol = vol*1E-30
514
519
 
515
- F_harm = 0
516
- F_cm = 0
520
+ #whats the beta
521
+ beta = (1/(kbJ*temp))
517
522
 
518
- for count, om in enumerate(omega):
519
- if concentration[count] > 0:
520
- F_harm += concentration[count]*np.log((hbar*om)/(kb*calc._temperature))
521
- if cm_correction:
522
- F_cm += np.log((natoms*concentration[count]/vol)*(2*np.pi*kbJ*calc._temperature/(natoms*concentration[count]*k[count]))**1.5)
523
- #F_cm = 0
524
- F_harm = 3*kb*calc._temperature*F_harm
525
- F_cm = (kb*calc._temperature/natoms)*F_cm
526
-
527
- F_harm = F_harm + F_cm
523
+ #create an array of mass
524
+ mass = []
525
+ for x in calc.element:
526
+ for count in range(calc._element_dict[x]['count']):
527
+ mass.append(calc._element_dict[x]['mass'])
528
+ mass = np.array(mass)
529
+
530
+ #convert mass to kg
531
+ mass = (mass/Na)*1E-3
528
532
 
529
- return F_harm
533
+ #create an array of k as well
534
+ karr = []
535
+ for c, x in enumerate(calc.element):
536
+ for count in range(calc._element_dict[x]['count']):
537
+ karr.append(k[c])
538
+ k = np.array(karr)
539
+ #convert k from ev/A2 to J/m2
540
+ k = k*(eV2J/1E-20)
541
+
542
+ #fe of Einstein crystal
543
+ Z_e = ((beta**2*k*hJ**2)/(4*np.pi**2*mass))**1.5
544
+ F_e = np.log(Z_e)
545
+ F_e = kb*temp*np.sum(F_e)/natoms #*J2eV #convert back to eV
546
+
547
+ #now get the cm correction
548
+ if cm_correction:
549
+ mass_sum = np.sum(mass)
550
+ mu = mass/mass_sum
551
+ mu2_over_k = mu**2/k
552
+ mu2_over_k_sum = np.sum(mu2_over_k)
553
+ prefactor = vol
554
+ F_cm = np.log(prefactor*(beta/(2*np.pi*mu2_over_k_sum))**1.5)
555
+ F_cm = kb*temp*F_cm/natoms #convert to eV
556
+ else:
557
+ F_cm = 0
558
+
559
+ F_tot = F_e - F_cm
560
+ if return_contributions:
561
+ return F_e, -F_cm
562
+ return F_tot
530
563
 
531
564
  #--------------------------------------------------------------------
532
565
  # REF. STATE ROUTINES: LIQUID
calphy/phase.py CHANGED
@@ -163,6 +163,8 @@ class Phase:
163
163
 
164
164
  self.ferr = 0
165
165
  self.fref = 0
166
+ self.feinstein = 0
167
+ self.fcm = 0
166
168
  self.fideal = 0
167
169
 
168
170
  self.w = 0
@@ -682,6 +684,8 @@ class Phase:
682
684
  report["results"]["free_energy"] = float(self.fe)
683
685
  report["results"]["error"] = float(self.ferr)
684
686
  report["results"]["reference_system"] = float(self.fref)
687
+ report["results"]["einstein_crystal"] = float(self.feinstein)
688
+ report["results"]["com_correction"] = float(self.fcm)
685
689
  report["results"]["work"] = float(self.w)
686
690
  report["results"]["pv"] = float(self.pv)
687
691
  report["results"]["unit"] = "eV/atom"
@@ -0,0 +1,148 @@
1
+ import os
2
+ import numpy as np
3
+ import yaml
4
+
5
+ def read_report(folder):
6
+ """
7
+ Read the finished calculation report
8
+
9
+ Parameters
10
+ ----------
11
+ folder: string
12
+ folder from which calculation is to be read
13
+
14
+ Returns
15
+ -------
16
+ data: dict
17
+ dictionary with results
18
+
19
+ """
20
+ repfile = os.path.join(folder, "report.yaml")
21
+ if not os.path.exists(repfile):
22
+ raise FileNotFoundError(f"file {repfile} not found")
23
+
24
+ with open(repfile, 'r') as fin:
25
+ data = yaml.safe_load(fin)
26
+ return data
27
+
28
+ def _extract_error(errfile):
29
+ error_code = None
30
+ if os.path.exists(errfile):
31
+ with open(errfile, 'r') as fin:
32
+ for line in fin:
33
+ if 'calphy.errors' in line:
34
+ break
35
+ try:
36
+ error_code = line.split(':')[0].split('.')[-1]
37
+ except:
38
+ pass
39
+ return error_code
40
+
41
+ def gather_results(mainfolder):
42
+ """
43
+ Gather results from all subfolders in a given folder into a Pandas DataFrame
44
+
45
+ Parameters
46
+ ----------
47
+ mainfolder: string
48
+ folder where calculations are stored
49
+
50
+ Returns
51
+ -------
52
+ df: pandas DataFrame
53
+ DataFrame with results
54
+ """
55
+ try:
56
+ import pandas as pd
57
+ except ImportError:
58
+ raise ImportError('Please install pandas to use this function')
59
+
60
+ datadict = {}
61
+ datadict['mode'] = []
62
+ datadict['status'] = []
63
+ datadict['temperature'] = []
64
+ datadict['pressure'] = []
65
+ datadict['free_energy'] = []
66
+ datadict['reference_phase'] = []
67
+ datadict['error_code'] = []
68
+ datadict['composition'] = []
69
+ datadict['calculation'] = []
70
+
71
+ folders = next(os.walk(mainfolder))[1]
72
+ for folder in folders:
73
+ #adjust for pyiron folder, see
74
+ if folder.split('_')[-1] == 'hdf5':
75
+ #this could be a pyiron calc
76
+ withouthdf = folder.split('_hdf5')[0]
77
+ folder = f'{folder}/{withouthdf}'
78
+
79
+ inpfile = os.path.join(mainfolder, folder, 'input_file.yaml')
80
+ #print(inpfile)
81
+ if not os.path.exists(inpfile):
82
+ continue;
83
+
84
+ #ok, valid calculation, try to parse input file to get info
85
+ with open(inpfile, 'r') as fin:
86
+ inp = yaml.safe_load(fin)
87
+ #grab the first calculation
88
+ inp = inp['calculations'][0]
89
+ #mode
90
+ mode = inp['mode']
91
+ datadict['mode'].append(mode)
92
+ datadict['temperature'].append(inp['temperature'])
93
+ datadict['pressure'].append(inp['pressure'])
94
+ datadict['reference_phase'].append(inp['reference_phase'])
95
+ datadict['composition'].append(None)
96
+ datadict['calculation'].append(folder)
97
+
98
+ #check output file
99
+ outfile = os.path.join(mainfolder, folder, 'report.yaml')
100
+ datadict['error_code'].append(None)
101
+
102
+ #print(inpfile)
103
+ if not os.path.exists(outfile):
104
+ datadict['status'].append('False')
105
+ datadict['free_energy'].append(np.NaN)
106
+ #check if error file is found
107
+ errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
108
+ datadict['error_code'][-1] = _extract_error(errfile)
109
+ continue;
110
+
111
+ if mode in ['fe', 'alchemy', 'composition_scaling']:
112
+ datadict['status'].append('True')
113
+
114
+ #ok, valid calculation, try to parse input file to get info
115
+ with open(outfile, 'r') as fin:
116
+ out = yaml.safe_load(fin)
117
+
118
+ datadict['free_energy'].append(out['results']['free_energy'])
119
+
120
+ #add normal composition
121
+ el_arr = np.array(out['input']['element'].split(' ')).astype(str)
122
+ comp_arr = np.array(out['input']['concentration'].split(' ')).astype(float)
123
+ composition = {x:y for x,y in zip(el_arr, comp_arr)}
124
+ datadict['composition'][-1] = composition
125
+
126
+ if mode == 'composition_scaling':
127
+ #we need to update composition
128
+ compdict = inp['composition_scaling']['output_chemical_composition']
129
+ maxatoms = np.sum([val for key, val in compdict.items()])
130
+ for key, val in compdict.items():
131
+ compdict[key] = val/maxatoms
132
+ datadict['composition'][-1] = compdict
133
+
134
+ #parse extra info
135
+ if mode in ['ts', 'tscale']:
136
+ datafile = os.path.join(os.getcwd(), mainfolder, folder, 'temperature_sweep.dat')
137
+ if os.path.exists(datafile):
138
+ datadict['status'].append('True')
139
+ t, f = np.loadtxt(datafile, unpack=True, usecols=(0,1))
140
+ datadict['temperature'][-1] = t
141
+ datadict['free_energy'][-1] = f
142
+ else:
143
+ datadict['status'].append('False')
144
+ errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
145
+ datadict['error_code'][-1] = _extract_error(errfile)
146
+
147
+ df = pd.DataFrame(data=datadict)
148
+ return df
calphy/solid.py CHANGED
@@ -516,17 +516,20 @@ class Solid(cph.Phase):
516
516
  Calculates the final work, energy dissipation and free energy by
517
517
  matching with Einstein crystal
518
518
  """
519
- f1 = get_einstein_crystal_fe(
519
+ fe, fcm = get_einstein_crystal_fe(
520
520
  self.calc,
521
521
  self.vol,
522
- self.k)
522
+ self.k,
523
+ return_contributions=True)
523
524
 
524
525
  w, q, qerr = find_w(self.simfolder,
525
526
  self.calc,
526
527
  full=True,
527
528
  solid=True)
528
529
 
529
- self.fref = f1
530
+ self.fref = fe + fcm
531
+ self.feinstein = fe
532
+ self.fcm = fcm
530
533
  self.w = w
531
534
  self.ferr = qerr
532
535
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: calphy
3
- Version: 1.3.10
3
+ Version: 1.3.11
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,24 +1,25 @@
1
- calphy/__init__.py,sha256=w9XLioZKvY0Z1pvwKo_2S1s8SsILErVXJOpojhsHbA4,234
1
+ calphy/__init__.py,sha256=yzftsRGAExKS7j5P49gh0fpg-c43MIsUCXKiUgGnCCg,234
2
2
  calphy/alchemy.py,sha256=epv_vJoAMVbj-S1TuPSbBGr4w_a9qEr4EIxKlgwdlSo,12893
3
3
  calphy/clitools.py,sha256=oDqaw0s-LJ7tAdW_Njk2SFljVx6K34Rs8sdMz48SNSI,4125
4
4
  calphy/composition_transformation.py,sha256=Hh240-iVGC8ATlJ3nQK757qVZIBrE2aw7dsF46mi3oo,15353
5
5
  calphy/errors.py,sha256=KN47RWTLbg1H_NZMrhCiJCbqjqJScJ1pgQAuzj1-l84,1268
6
6
  calphy/helpers.py,sha256=nj8g53H6ScohQtyV7Enzms8Rv_89PRrDDY1IHjFSZdQ,8292
7
- calphy/input.py,sha256=qI8BCx_zZ_909Jaa2sxePHQDcp4oDzychVaZKfUgAVM,29718
8
- calphy/integrators.py,sha256=pblWLGngLgjBbHwVsjl3K7pr3eh4z3oZ261XdLlQNOA,20774
7
+ calphy/input.py,sha256=R-M0C-7i1ux1IWop0UzlqAKoYIre7cxVuFLspcUwsPk,29400
8
+ calphy/integrators.py,sha256=hJYmbznsgY-x-eZm7ng8gW0qsGbopERl5gGDnw5uLms,21719
9
9
  calphy/kernel.py,sha256=rd_-EfCiBhQjkxcVaoLtVJB2_qDgS-g-dQ0BZBTJQ_A,6190
10
10
  calphy/liquid.py,sha256=a5NTAjc3VsrPBQoEMGe9O1WXfv1vxGoB0xPguf0fOyM,13762
11
- calphy/phase.py,sha256=ukqad4MJ-MNGiyOsq2_jntG2s10UHbJVi2Ounpg_S2U,44787
11
+ calphy/phase.py,sha256=FOm5_eP_8XbCYG3_UJoAToD3KKxlXcbSoEfQncZXTeA,44967
12
12
  calphy/phase_diagram.py,sha256=2EwmT_qkT5BEP6Sx0_rm09kPP2RWh5JY4sogIBK_AhA,12992
13
+ calphy/postprocessing.py,sha256=hFsc5Kr1FOgfjicjm23Dy19BUbZU9GxKpbCa8_U6gbU,4947
13
14
  calphy/queuekernel.py,sha256=4GMIYnjMiAPipoLNKP5noYcfeEOI_vCqm84zgokk7Xw,5321
14
15
  calphy/routines.py,sha256=W6OZEPv6HEG11EYsoIbum2WVrO3Ly36i5UWsYQ4oBdQ,17473
15
16
  calphy/scheduler.py,sha256=IN8ogDedpTbZZsdpOj-hYZI05gWoD4bN7mHOb1z77Vo,8579
16
- calphy/solid.py,sha256=49gT0wNOP3h8lRDXarULP-bU09lIrnDCTUcyxE7X-UE,19795
17
+ calphy/solid.py,sha256=ZU_c4LqASoLzhjXX6eQY_8k_FNO9wjmMVTiOCKNsmis,19896
17
18
  calphy/splines.py,sha256=BGwUVz_qXQxUzpUCuZo6CsELcd5JVNWzI-Ttcz22G_E,61627
18
19
  calphy/utils.py,sha256=0UpsYoxjS5N-iGs-cdm0YDMkLF8IHvKO3smXDHrj3eg,3818
19
- calphy-1.3.10.dist-info/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
20
- calphy-1.3.10.dist-info/METADATA,sha256=-Pgiun1WuVVvcxqipSbOcN5TSr9AdYRJ_CQWpAE1KG4,4216
21
- calphy-1.3.10.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
22
- calphy-1.3.10.dist-info/entry_points.txt,sha256=W9qq254koyWnAgo1jtfQP9bO5Q7sgZrzc8BMnfo3vf4,386
23
- calphy-1.3.10.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
24
- calphy-1.3.10.dist-info/RECORD,,
20
+ calphy-1.3.11.dist-info/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
21
+ calphy-1.3.11.dist-info/METADATA,sha256=Pw5F6YJyyaGZlJG4kPU_MMf8UoilMH16JPa4iU7TFvY,4216
22
+ calphy-1.3.11.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
23
+ calphy-1.3.11.dist-info/entry_points.txt,sha256=W9qq254koyWnAgo1jtfQP9bO5Q7sgZrzc8BMnfo3vf4,386
24
+ calphy-1.3.11.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
25
+ calphy-1.3.11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (75.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5