3030from calphy .splines import splines , sum_spline1 , sum_spline25 , sum_spline50 , sum_spline75 , sum_spline100
3131from scipy .integrate import cumtrapz
3232from tqdm import tqdm
33+ import pyscal .core as pc
34+ from ase .io import read
3335
3436#Constants
3537h = const .physical_constants ["Planck constant in eV/Hz" ][0 ]
@@ -305,16 +307,83 @@ def integrate_mass(flambda, ref_mass, target_masses, target_counts,
305307
306308 return mcorarr , mcorsum
307309
308- def integrate_mts (folder1 , folder2 , natoms1 , natoms2 ,
309- pressure , temperature , nsims = 5 , scale_energy = True ,
310- full = False , stdscale = 0 ):
310+ def remove_steps (w , stdscale ):
311+ peak = np .abs (w - np .roll (w , shift = - 1 ))
312+ peak = np .where (peak > stdscale * np .std (peak ), peak , 0 )
313+ args = np .nonzero (peak )[0 ]
314+ print (f'No of peaks #{ len (args )} ' )
315+ diff = [w [x ]- w [x - 1 ] if x in args else 0 for x in range (len (w [:- 1 ]))]
316+ diff .append (0 )
317+ cum_diff = np .cumsum (diff )
318+ w = w - cum_diff
319+ return w
320+
321+ def remove_peaks (w , stdscale ):
322+ peak = np .minimum (np .abs (w - np .roll (w , shift = - 1 )), np .abs (np .roll (w , shift = 1 )- w ))
323+ args = np .argwhere (peak > stdscale * np .std (peak ))
324+ k = [(w [x - 1 ]+ w [x + 1 ])/ 2 if x in args else w [x ] for x in range (len (w [:- 1 ]))]
325+ k .append (w [- 1 ])
326+ return k
327+
328+ def integrate_dcc (folder1 , folder2 , nsims = 1 , scale_energy = True ,
329+ full = False , stdscale = 0.25 , fit_order = None ):
330+ """
331+ Integrate Dynamic Clausius-Clapeyron equation
332+
333+ Parameters
334+ ----------
335+ folder1: string
336+ Calculation folder for calculation of the first phase
337+
338+ folder2: string
339+ Calculation folder for calculation of the second phase
340+
341+ nsims: int
342+ Number of iterations, default 1
343+
344+ full: bool
345+ If True, return error, default False
346+
347+ stdscale: float
348+ Function used to smooth the integrand. If a value is provided,
349+ values in the greater than stdscale*std_dev and less than -stdscale*std_dev
350+ are identified as steps/peaks and smoothened. Default 0.25
351+
352+ fit_order: None
353+ If specified, a final fitting is done to remove kinks in the values
354+ Optional, default None.
355+
356+ """
357+
358+ #get number of atoms
359+ sys = pc .System ()
360+ sys .read_inputfile (os .path .join (folder1 , "traj.equilibration_stage1.dat" ))
361+ natoms1 = int (sys .natoms )
362+
363+ sys = pc .System ()
364+ sys .read_inputfile (os .path .join (folder2 , "traj.equilibration_stage1.dat" ))
365+ natoms2 = int (sys .natoms )
366+
367+ #get temp and pressure
368+ f1_raw = os .path .basename (folder1 ).split ("-" )
369+ pressure = float (f1_raw [- 1 ])
370+ temperature = float (f1_raw [- 2 ])
371+
372+ #recheck for folder2
373+ f2_raw = os .path .basename (folder2 ).split ("-" )
374+ if pressure != float (f2_raw [- 1 ]):
375+ raise ValueError ("Pressure for both calculations are different!" )
376+ if temperature != float (f2_raw [- 2 ]):
377+ raise ValueError ("Temperature for both calculations are different!" )
378+ if pressure == 0 :
379+ raise ValueError ("A non-zero pressure is needed for dcc" )
311380
312381 ws = []
313- for i in tqdm ( range (nsims ) ):
314- fsu , fsp , fsv , fsl = np .loadtxt (os .path .join (folder1 , "forward_%d.dat" % (i + 1 )), unpack = True )
315- bsu , bsp , bsv , bsl = np .loadtxt (os .path .join (folder1 , "backward_%d.dat" % (i + 1 )), unpack = True )
316- flu , flp , flv , fll = np .loadtxt (os .path .join (folder2 , "forward_%d.dat" % (i + 1 )), unpack = True )
317- blu , blp , blv , bll = np .loadtxt (os .path .join (folder2 , "backward_%d.dat" % (i + 1 )), unpack = True )
382+ for i in range (nsims ):
383+ fsu , fsp , fsv , fsl = np .loadtxt (os .path .join (folder1 , "ts. forward_%d.dat" % (i + 1 )), unpack = True )
384+ bsu , bsp , bsv , bsl = np .loadtxt (os .path .join (folder1 , "ts. backward_%d.dat" % (i + 1 )), unpack = True )
385+ flu , flp , flv , fll = np .loadtxt (os .path .join (folder2 , "ts. forward_%d.dat" % (i + 1 )), unpack = True )
386+ blu , blp , blv , bll = np .loadtxt (os .path .join (folder2 , "ts. backward_%d.dat" % (i + 1 )), unpack = True )
318387
319388 if scale_energy :
320389 fsu = fsu / fsl
@@ -338,18 +407,19 @@ def integrate_mts(folder1, folder2, natoms1, natoms2,
338407 fx = (fsu - flu )/ (fsv - flv )
339408 bx = (bsu - blu )/ (bsv - blv )
340409
410+ if stdscale > 0 :
411+ fx = remove_peaks (fx , stdscale = stdscale )
412+ bx = remove_peaks (bx , stdscale = stdscale )
413+
341414 wf = cumtrapz (fx , fsl , initial = 0 )
342415 wb = cumtrapz (bx [::- 1 ], bsl [::- 1 ], initial = 0 )
343416
344417 w = (wf + wb ) / (2 * fsl )
345418 q = (wf - wb ) / (2 * fsl )
346419
347420 if stdscale > 0 :
348- peak = (w - np .roll (w , shift = - 1 ))
349- stdcut = np .std (peak [:- 1 ])
350- for i in range (len (peak [:- 1 ])):
351- if not (- stdscale * stdcut < peak [i ] < stdscale * stdcut ):
352- w [i :] = w [i :] + peak [i ]
421+ w = remove_steps (w , stdscale = stdscale )
422+
353423 ws .append (w )
354424
355425 #return ws
@@ -361,6 +431,11 @@ def integrate_mts(folder1, folder2, natoms1, natoms2,
361431 #convert back
362432 xp = xp * 160.217 * 10000
363433
434+ #fit if needed
435+ if fit_order is not None :
436+ fit = np .polyfit (temp , xp , fit_order )
437+ xp = np .polyval (fit , temp )
438+
364439 #return the values
365440 if not full :
366441 return xp , temp
0 commit comments