calphy 1.3.10__py3-none-any.whl → 1.3.13__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/input.py +1 -13
- calphy/integrators.py +68 -35
- calphy/phase.py +19 -7
- calphy/postprocessing.py +229 -0
- calphy/solid.py +6 -3
- {calphy-1.3.10.dist-info → calphy-1.3.13.dist-info}/METADATA +1 -1
- {calphy-1.3.10.dist-info → calphy-1.3.13.dist-info}/RECORD +12 -11
- {calphy-1.3.10.dist-info → calphy-1.3.13.dist-info}/WHEEL +1 -1
- {calphy-1.3.10.dist-info → calphy-1.3.13.dist-info}/LICENSE +0 -0
- {calphy-1.3.10.dist-info → calphy-1.3.13.dist-info}/entry_points.txt +0 -0
- {calphy-1.3.10.dist-info → calphy-1.3.13.dist-info}/top_level.txt +0 -0
calphy/__init__.py
CHANGED
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.
|
|
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.13"
|
|
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
|
-
|
|
479
|
-
|
|
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
|
-
|
|
488
|
-
|
|
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
|
-
|
|
499
|
-
free energy of
|
|
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
|
-
#
|
|
503
|
-
|
|
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
|
-
#
|
|
509
|
-
|
|
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
|
-
|
|
516
|
-
|
|
520
|
+
#whats the beta
|
|
521
|
+
beta = (1/(kbJ*temp))
|
|
517
522
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
|
|
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
|
|
@@ -596,8 +598,12 @@ class Phase:
|
|
|
596
598
|
|
|
597
599
|
#now we can check if it converted
|
|
598
600
|
file = os.path.join(self.simfolder, "avg.dat")
|
|
599
|
-
|
|
600
|
-
lxpc =
|
|
601
|
+
#we have to clean the data, so as just the last block is selected
|
|
602
|
+
lx, ly, lz, lxpc = np.loadtxt(file, usecols=(1, 2, 3, 4), unpack=True)
|
|
603
|
+
lx = lx[-ncount+1:]
|
|
604
|
+
ly = ly[-ncount+1:]
|
|
605
|
+
lz = lx[-ncount+1:]
|
|
606
|
+
lxpc = lxpc[-ncount+1:]
|
|
601
607
|
mean = np.mean(lxpc)
|
|
602
608
|
std = np.std(lxpc)
|
|
603
609
|
volatom = np.mean((lx*ly*lz)/self.natoms)
|
|
@@ -610,16 +616,20 @@ class Phase:
|
|
|
610
616
|
ncount = int(self.calc.md.n_small_steps)//int(self.calc.md.n_every_steps*self.calc.md.n_repeat_steps)
|
|
611
617
|
|
|
612
618
|
file = os.path.join(self.simfolder, "avg.dat")
|
|
613
|
-
lx, ly, lz,
|
|
614
|
-
|
|
619
|
+
lx, ly, lz, lxpc = np.loadtxt(file, usecols=(1, 2, 3, 4), unpack=True)
|
|
620
|
+
lx = lx[-ncount+1:]
|
|
621
|
+
ly = ly[-ncount+1:]
|
|
622
|
+
lz = lx[-ncount+1:]
|
|
623
|
+
lxpc = lxpc[-ncount+1:]
|
|
624
|
+
|
|
615
625
|
mean = np.mean(lxpc)
|
|
616
626
|
std = np.std(lxpc)
|
|
617
627
|
volatom = np.mean((lx*ly*lz)/self.natoms)
|
|
618
628
|
|
|
619
629
|
self.calc._pressure = mean
|
|
620
|
-
self.lx = np.round(np.mean(lx
|
|
621
|
-
self.ly = np.round(np.mean(ly
|
|
622
|
-
self.lz = np.round(np.mean(lz
|
|
630
|
+
self.lx = np.round(np.mean(lx), decimals=3)
|
|
631
|
+
self.ly = np.round(np.mean(ly), decimals=3)
|
|
632
|
+
self.lz = np.round(np.mean(lz), decimals=3)
|
|
623
633
|
self.volatom = volatom
|
|
624
634
|
self.vol = self.lx*self.ly*self.lz
|
|
625
635
|
self.rho = self.natoms/(self.lx*self.ly*self.lz)
|
|
@@ -682,6 +692,8 @@ class Phase:
|
|
|
682
692
|
report["results"]["free_energy"] = float(self.fe)
|
|
683
693
|
report["results"]["error"] = float(self.ferr)
|
|
684
694
|
report["results"]["reference_system"] = float(self.fref)
|
|
695
|
+
report["results"]["einstein_crystal"] = float(self.feinstein)
|
|
696
|
+
report["results"]["com_correction"] = float(self.fcm)
|
|
685
697
|
report["results"]["work"] = float(self.w)
|
|
686
698
|
report["results"]["pv"] = float(self.pv)
|
|
687
699
|
report["results"]["unit"] = "eV/atom"
|
calphy/postprocessing.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import numpy as np
|
|
3
|
+
import yaml
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
def read_report(folder):
|
|
8
|
+
"""
|
|
9
|
+
Read the finished calculation report
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
folder: string
|
|
14
|
+
folder from which calculation is to be read
|
|
15
|
+
|
|
16
|
+
Returns
|
|
17
|
+
-------
|
|
18
|
+
data: dict
|
|
19
|
+
dictionary with results
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
repfile = os.path.join(folder, "report.yaml")
|
|
23
|
+
if not os.path.exists(repfile):
|
|
24
|
+
raise FileNotFoundError(f"file {repfile} not found")
|
|
25
|
+
|
|
26
|
+
with open(repfile, 'r') as fin:
|
|
27
|
+
data = yaml.safe_load(fin)
|
|
28
|
+
return data
|
|
29
|
+
|
|
30
|
+
def _extract_error(errfile):
|
|
31
|
+
error_code = None
|
|
32
|
+
if os.path.exists(errfile):
|
|
33
|
+
with open(errfile, 'r') as fin:
|
|
34
|
+
for line in fin:
|
|
35
|
+
if 'calphy.errors' in line:
|
|
36
|
+
break
|
|
37
|
+
try:
|
|
38
|
+
error_code = line.split(':')[0].split('.')[-1]
|
|
39
|
+
except:
|
|
40
|
+
pass
|
|
41
|
+
return error_code
|
|
42
|
+
|
|
43
|
+
def gather_results(mainfolder):
|
|
44
|
+
"""
|
|
45
|
+
Gather results from all subfolders in a given folder into a Pandas DataFrame
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
mainfolder: string
|
|
50
|
+
folder where calculations are stored
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
df: pandas DataFrame
|
|
55
|
+
DataFrame with results
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
import pandas as pd
|
|
59
|
+
except ImportError:
|
|
60
|
+
raise ImportError('Please install pandas to use this function')
|
|
61
|
+
|
|
62
|
+
datadict = {}
|
|
63
|
+
datadict['mode'] = []
|
|
64
|
+
datadict['status'] = []
|
|
65
|
+
datadict['temperature'] = []
|
|
66
|
+
datadict['pressure'] = []
|
|
67
|
+
datadict['free_energy'] = []
|
|
68
|
+
datadict['reference_phase'] = []
|
|
69
|
+
datadict['error_code'] = []
|
|
70
|
+
datadict['composition'] = []
|
|
71
|
+
datadict['calculation'] = []
|
|
72
|
+
|
|
73
|
+
folders = next(os.walk(mainfolder))[1]
|
|
74
|
+
for folder in folders:
|
|
75
|
+
#adjust for pyiron folder, see
|
|
76
|
+
if folder.split('_')[-1] == 'hdf5':
|
|
77
|
+
#this could be a pyiron calc
|
|
78
|
+
withouthdf = folder.split('_hdf5')[0]
|
|
79
|
+
folder = f'{folder}/{withouthdf}'
|
|
80
|
+
|
|
81
|
+
inpfile = os.path.join(mainfolder, folder, 'input_file.yaml')
|
|
82
|
+
#print(inpfile)
|
|
83
|
+
if not os.path.exists(inpfile):
|
|
84
|
+
continue;
|
|
85
|
+
|
|
86
|
+
#ok, valid calculation, try to parse input file to get info
|
|
87
|
+
with open(inpfile, 'r') as fin:
|
|
88
|
+
inp = yaml.safe_load(fin)
|
|
89
|
+
#grab the first calculation
|
|
90
|
+
inp = inp['calculations'][0]
|
|
91
|
+
#mode
|
|
92
|
+
mode = inp['mode']
|
|
93
|
+
datadict['mode'].append(mode)
|
|
94
|
+
datadict['temperature'].append(inp['temperature'])
|
|
95
|
+
datadict['pressure'].append(inp['pressure'])
|
|
96
|
+
datadict['reference_phase'].append(inp['reference_phase'])
|
|
97
|
+
datadict['composition'].append(None)
|
|
98
|
+
datadict['calculation'].append(folder)
|
|
99
|
+
|
|
100
|
+
#check output file
|
|
101
|
+
outfile = os.path.join(mainfolder, folder, 'report.yaml')
|
|
102
|
+
datadict['error_code'].append(None)
|
|
103
|
+
|
|
104
|
+
#print(inpfile)
|
|
105
|
+
if not os.path.exists(outfile):
|
|
106
|
+
datadict['status'].append('False')
|
|
107
|
+
datadict['free_energy'].append(np.NaN)
|
|
108
|
+
#check if error file is found
|
|
109
|
+
errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
|
|
110
|
+
datadict['error_code'][-1] = _extract_error(errfile)
|
|
111
|
+
continue;
|
|
112
|
+
|
|
113
|
+
if mode in ['fe', 'alchemy', 'composition_scaling']:
|
|
114
|
+
datadict['status'].append('True')
|
|
115
|
+
|
|
116
|
+
#ok, valid calculation, try to parse input file to get info
|
|
117
|
+
with open(outfile, 'r') as fin:
|
|
118
|
+
out = yaml.safe_load(fin)
|
|
119
|
+
|
|
120
|
+
datadict['free_energy'].append(out['results']['free_energy'])
|
|
121
|
+
|
|
122
|
+
#add normal composition
|
|
123
|
+
el_arr = np.array(out['input']['element'].split(' ')).astype(str)
|
|
124
|
+
comp_arr = np.array(out['input']['concentration'].split(' ')).astype(float)
|
|
125
|
+
composition = {x:y for x,y in zip(el_arr, comp_arr)}
|
|
126
|
+
datadict['composition'][-1] = composition
|
|
127
|
+
|
|
128
|
+
if mode == 'composition_scaling':
|
|
129
|
+
#we need to update composition
|
|
130
|
+
compdict = inp['composition_scaling']['output_chemical_composition']
|
|
131
|
+
maxatoms = np.sum([val for key, val in compdict.items()])
|
|
132
|
+
for key, val in compdict.items():
|
|
133
|
+
compdict[key] = val/maxatoms
|
|
134
|
+
datadict['composition'][-1] = compdict
|
|
135
|
+
|
|
136
|
+
#parse extra info
|
|
137
|
+
if mode in ['ts', 'tscale']:
|
|
138
|
+
datafile = os.path.join(os.getcwd(), mainfolder, folder, 'temperature_sweep.dat')
|
|
139
|
+
if os.path.exists(datafile):
|
|
140
|
+
datadict['status'].append('True')
|
|
141
|
+
t, f = np.loadtxt(datafile, unpack=True, usecols=(0,1))
|
|
142
|
+
datadict['temperature'][-1] = t
|
|
143
|
+
datadict['free_energy'][-1] = f
|
|
144
|
+
else:
|
|
145
|
+
datadict['status'].append('False')
|
|
146
|
+
errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
|
|
147
|
+
datadict['error_code'][-1] = _extract_error(errfile)
|
|
148
|
+
|
|
149
|
+
df = pd.DataFrame(data=datadict)
|
|
150
|
+
return df
|
|
151
|
+
|
|
152
|
+
def find_transition_temperature(folder1, folder2, fit_order=4, plot=True):
|
|
153
|
+
"""
|
|
154
|
+
Find transition temperature where free energy of two phases are equal.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
folder1: string
|
|
159
|
+
directory with temperature scale calculation
|
|
160
|
+
|
|
161
|
+
folder2: string
|
|
162
|
+
directory with temperature scale calculation
|
|
163
|
+
|
|
164
|
+
fit_order: int, optional
|
|
165
|
+
default 4. Order for polynomial fit of temperature vs free energy
|
|
166
|
+
|
|
167
|
+
plot: bool, optional
|
|
168
|
+
default True. Plot the results.
|
|
169
|
+
"""
|
|
170
|
+
file1 = os.path.join(folder1, 'temperature_sweep.dat')
|
|
171
|
+
file2 = os.path.join(folder2, 'temperature_sweep.dat')
|
|
172
|
+
if not os.path.exists(file1):
|
|
173
|
+
raise FileNotFoundError(f'{file1} does not exist')
|
|
174
|
+
if not os.path.exists(file2):
|
|
175
|
+
raise FileNotFoundError(f'{file2} does not exist')
|
|
176
|
+
|
|
177
|
+
t1, f1 = np.loadtxt(file1, unpack=True, usecols=(0,1))
|
|
178
|
+
t2, f2 = np.loadtxt(file2, unpack=True, usecols=(0,1))
|
|
179
|
+
|
|
180
|
+
#do some fitting to determine temps
|
|
181
|
+
t1min = np.min(t1)
|
|
182
|
+
t2min = np.min(t2)
|
|
183
|
+
t1max = np.max(t1)
|
|
184
|
+
t2max = np.max(t2)
|
|
185
|
+
|
|
186
|
+
tmin = np.min([t1min, t2min])
|
|
187
|
+
tmax = np.max([t1max, t2max])
|
|
188
|
+
|
|
189
|
+
#warn about extrapolation
|
|
190
|
+
if not t1min == t2min:
|
|
191
|
+
warnings.warn(f'free energy is being extrapolated!')
|
|
192
|
+
if not t1max == t2max:
|
|
193
|
+
warnings.warn(f'free energy is being extrapolated!')
|
|
194
|
+
|
|
195
|
+
#now fit
|
|
196
|
+
f1fit = np.polyfit(t1, f1, fit_order)
|
|
197
|
+
f2fit = np.polyfit(t2, f2, fit_order)
|
|
198
|
+
|
|
199
|
+
#reevaluate over the new range
|
|
200
|
+
fit_t = np.arange(tmin, tmax+1, 1)
|
|
201
|
+
fit_f1 = np.polyval(f1fit, fit_t)
|
|
202
|
+
fit_f2 = np.polyval(f2fit, fit_t)
|
|
203
|
+
|
|
204
|
+
#now evaluate the intersection temp
|
|
205
|
+
arg = np.argsort(np.abs(fit_f1-fit_f2))[0]
|
|
206
|
+
transition_temp = fit_t[arg]
|
|
207
|
+
|
|
208
|
+
#warn if the temperature is shady
|
|
209
|
+
if np.abs(transition_temp-tmin) < 1E-3:
|
|
210
|
+
warnings.warn('It is likely there is no intersection of free energies')
|
|
211
|
+
elif np.abs(transition_temp-tmax) < 1E-3:
|
|
212
|
+
warnings.warn('It is likely there is no intersection of free energies')
|
|
213
|
+
|
|
214
|
+
#plot
|
|
215
|
+
if plot:
|
|
216
|
+
c1lo = '#ef9a9a'
|
|
217
|
+
c1hi = '#b71c1c'
|
|
218
|
+
c2lo = '#90caf9'
|
|
219
|
+
c2hi = '#0d47a1'
|
|
220
|
+
|
|
221
|
+
plt.plot(fit_t, fit_f1, color=c1lo, label=f'{folder1} fit')
|
|
222
|
+
plt.plot(fit_t, fit_f2, color=c2lo, label=f'{folder2} fit')
|
|
223
|
+
plt.plot(t1, f1, color=c1hi, label=folder1, ls='dashed')
|
|
224
|
+
plt.plot(t2, f2, color=c2hi, label=folder2, ls='dashed')
|
|
225
|
+
plt.axvline(transition_temp, ls='dashed', c='#37474f')
|
|
226
|
+
plt.ylabel('Free energy (eV/atom)')
|
|
227
|
+
plt.xlabel('Temperature (K)')
|
|
228
|
+
plt.legend(frameon=False)
|
|
229
|
+
return transition_temp
|
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
|
-
|
|
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 =
|
|
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,24 +1,25 @@
|
|
|
1
|
-
calphy/__init__.py,sha256=
|
|
1
|
+
calphy/__init__.py,sha256=O46MqskwAlD2DmoXB8prjLeuCUBlzHuKsv-SaqjTohY,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=
|
|
8
|
-
calphy/integrators.py,sha256=
|
|
7
|
+
calphy/input.py,sha256=836ifhhVHm6Nd9jMWLjMUYKukk_pcZwvoGcLzQXIWuU,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=
|
|
11
|
+
calphy/phase.py,sha256=NBkOGkG3U9Uo-dbupFWndOaaCiiSRoD8WHUpunYZty0,45190
|
|
12
12
|
calphy/phase_diagram.py,sha256=2EwmT_qkT5BEP6Sx0_rm09kPP2RWh5JY4sogIBK_AhA,12992
|
|
13
|
+
calphy/postprocessing.py,sha256=CztgekCvQ8lZPVfZ_hMAwlyvwetjSfADjTca8aVTftY,7602
|
|
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=
|
|
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.
|
|
20
|
-
calphy-1.3.
|
|
21
|
-
calphy-1.3.
|
|
22
|
-
calphy-1.3.
|
|
23
|
-
calphy-1.3.
|
|
24
|
-
calphy-1.3.
|
|
20
|
+
calphy-1.3.13.dist-info/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
|
|
21
|
+
calphy-1.3.13.dist-info/METADATA,sha256=JCQSN5W690zkuPLQ9vqmc8mSOr56K6GOq8EiqEaymWo,4216
|
|
22
|
+
calphy-1.3.13.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
23
|
+
calphy-1.3.13.dist-info/entry_points.txt,sha256=W9qq254koyWnAgo1jtfQP9bO5Q7sgZrzc8BMnfo3vf4,386
|
|
24
|
+
calphy-1.3.13.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
|
|
25
|
+
calphy-1.3.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|