1
1
import os
2
2
import numpy as np
3
3
import yaml
4
+ import matplotlib .pyplot as plt
5
+ import warnings
4
6
5
7
def read_report (folder ):
6
8
"""
@@ -145,4 +147,83 @@ def gather_results(mainfolder):
145
147
datadict ['error_code' ][- 1 ] = _extract_error (errfile )
146
148
147
149
df = pd .DataFrame (data = datadict )
148
- return df
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
0 commit comments