1
0
forked from IPKM/nmreval

add tnmh stuff

This commit is contained in:
Dominik Demuth 2023-05-13 19:23:15 +02:00
parent 15c959fd71
commit 11ed3c16eb
5 changed files with 40806 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
# tau_TNMH=77.93669386254352 beta=0.6334823578561849 x=0.4107577725462226 deltaE=205554.80338165778
# Temp dTfdT_data dTfdT_fit
1.50007e+02 -1.54659e-03 5.04753e-03
1.50258e+02 -1.35164e-03 -5.81695e-03
1.50509e+02 -1.15321e-03 -5.24594e-03
1.50760e+02 1.33378e-03 -5.19023e-03
1.51011e+02 -4.19078e-03 -5.23034e-03
1.51262e+02 -3.69741e-03 -5.32106e-03
1.51514e+02 -1.17892e-03 -5.44569e-03
1.51765e+02 -4.26847e-04 -5.59617e-03
1.52016e+02 1.34823e-03 -5.76806e-03
1.52267e+02 -8.53837e-04 -5.95864e-03
1.52518e+02 -3.32957e-03 -6.16618e-03
1.52769e+02 -3.18265e-03 -6.38951e-03
1.53021e+02 -9.27941e-04 -6.62778e-03
1.53272e+02 2.81209e-03 -6.88034e-03
1.53523e+02 2.53703e-03 -7.14668e-03
1.53774e+02 2.79565e-03 -7.42632e-03
1.54025e+02 3.73709e-03 -7.71879e-03
1.54277e+02 -4.74193e-04 -8.02362e-03
1.54528e+02 5.53513e-03 -8.34027e-03
1.54779e+02 5.40911e-03 -8.66813e-03
1.55030e+02 4.61145e-03 -9.00648e-03
1.55281e+02 3.12182e-03 -9.35449e-03
1.55532e+02 6.75992e-03 -9.71118e-03
1.55784e+02 3.14577e-03 -1.00754e-02
1.56035e+02 2.59412e-03 -1.04458e-02
1.56286e+02 -1.54718e-03 -1.08208e-02
1.56537e+02 1.17037e-04 -1.11987e-02
1.56788e+02 -2.03614e-03 -1.15774e-02
1.57039e+02 1.33113e-03 -1.19545e-02
1.57291e+02 -5.96949e-03 -1.23274e-02
1.57542e+02 -6.48426e-03 -1.26931e-02
1.57793e+02 -1.59997e-03 -1.30481e-02
1.58044e+02 -3.72898e-04 -1.33886e-02
1.58295e+02 1.30990e-03 -1.37104e-02
1.58547e+02 4.08780e-03 -1.40088e-02
1.58798e+02 -7.05642e-03 -1.42784e-02
1.59049e+02 -2.00584e-03 -1.45134e-02
1.59300e+02 -1.92937e-03 -1.47073e-02
1.59551e+02 -6.58517e-04 -1.48531e-02
1.59802e+02 7.32033e-04 -1.49429e-02
1.60054e+02 2.36722e-03 -1.49682e-02
1.60305e+02 -1.17443e-03 -1.49196e-02
1.60556e+02 4.59116e-04 -1.47868e-02
1.60807e+02 8.17255e-03 -1.45588e-02
1.61058e+02 8.48647e-03 -1.42234e-02
1.61310e+02 7.96560e-03 -1.37674e-02
1.61561e+02 1.29202e-02 -1.31766e-02
1.61812e+02 4.84645e-03 -1.24355e-02
1.62063e+02 1.24679e-02 -1.15274e-02
1.62314e+02 1.08789e-02 -1.04342e-02
1.62565e+02 9.31453e-03 -9.13630e-03
1.62817e+02 1.10428e-02 -7.61265e-03
1.63068e+02 1.81300e-02 -5.84047e-03
1.63319e+02 9.70774e-03 -3.79521e-03
1.63570e+02 1.20566e-02 -1.45035e-03
1.63821e+02 1.49584e-02 1.22268e-03
1.64072e+02 1.72350e-02 4.25478e-03
1.64324e+02 2.03471e-02 7.67928e-03
1.64575e+02 3.74633e-02 1.15322e-02
1.64826e+02 2.20722e-02 1.58527e-02
1.65077e+02 2.90447e-02 2.06828e-02
1.65328e+02 3.56891e-02 2.60686e-02
1.65580e+02 4.02175e-02 3.20598e-02
1.65831e+02 4.99873e-02 3.87108e-02
1.66082e+02 6.52373e-02 4.60809e-02
1.66333e+02 5.16469e-02 5.42346e-02
1.66584e+02 6.50874e-02 6.32432e-02
1.66835e+02 7.59582e-02 7.31846e-02
1.67087e+02 8.82617e-02 8.41446e-02
1.67338e+02 9.75569e-02 9.62183e-02
1.67589e+02 1.08193e-01 1.09511e-01
1.67840e+02 1.09727e-01 1.24138e-01
1.68091e+02 1.30829e-01 1.40230e-01
1.68342e+02 1.55907e-01 1.57932e-01
1.68594e+02 1.71526e-01 1.77404e-01
1.68845e+02 1.87568e-01 1.98829e-01
1.69096e+02 2.05094e-01 2.22407e-01
1.69347e+02 2.27806e-01 2.48367e-01
1.69598e+02 2.58337e-01 2.76962e-01
1.69850e+02 2.88510e-01 3.08478e-01
1.70101e+02 3.20528e-01 3.43232e-01
1.70352e+02 3.57173e-01 3.81577e-01
1.70603e+02 4.02201e-01 4.23903e-01
1.70854e+02 4.47497e-01 4.70630e-01
1.71105e+02 5.06370e-01 5.22210e-01
1.71357e+02 5.66666e-01 5.79104e-01
1.71608e+02 6.33707e-01 6.41763e-01
1.71859e+02 7.08395e-01 7.10580e-01
1.72110e+02 7.86941e-01 7.85817e-01
1.72361e+02 8.80202e-01 8.67486e-01
1.72612e+02 9.72949e-01 9.55178e-01
1.72864e+02 1.07283e+00 1.04780e+00
1.73115e+02 1.17098e+00 1.14323e+00
1.73366e+02 1.26581e+00 1.23794e+00
1.73617e+02 1.36284e+00 1.32657e+00
1.73868e+02 1.40164e+00 1.40186e+00
1.74120e+02 1.45067e+00 1.45520e+00
1.74371e+02 1.46476e+00 1.47830e+00
1.74622e+02 1.44706e+00 1.46612e+00
1.74873e+02 1.40520e+00 1.42006e+00
1.75124e+02 1.35811e+00 1.34934e+00
1.75375e+02 1.26322e+00 1.26857e+00
1.75627e+02 1.20703e+00 1.19227e+00
1.75878e+02 1.15871e+00 1.12985e+00
1.76129e+02 1.12062e+00 1.08413e+00
1.76380e+02 1.09118e+00 1.05315e+00
1.76631e+02 1.07111e+00 1.03314e+00
1.76882e+02 1.05191e+00 1.02044e+00
1.77134e+02 1.04878e+00 1.01241e+00
1.77385e+02 1.04027e+00 1.00731e+00
1.77636e+02 1.03275e+00 1.00413e+00
1.77887e+02 1.02782e+00 1.00219e+00
1.78138e+02 1.02566e+00 1.00108e+00
1.78390e+02 1.02147e+00 1.00049e+00
1.78641e+02 1.01938e+00 1.00020e+00
1.78892e+02 1.02000e+00 1.00007e+00
1.79143e+02 1.01835e+00 1.00002e+00
1.79394e+02 1.01657e+00 1.00001e+00
1.79645e+02 1.01941e+00 1.00000e+00
1.79897e+02 1.00523e+00 1.00000e+00
1.80148e+02 1.00689e+00 1.00000e+00
1.80399e+02 1.00730e+00 1.00000e+00
1.80650e+02 1.00768e+00 1.00000e+00
1.80901e+02 1.00746e+00 1.00000e+00
1.81152e+02 1.00606e+00 1.00000e+00
1.81404e+02 1.00202e+00 1.00000e+00
1.81655e+02 9.93205e-01 1.00000e+00
1.81906e+02 9.98851e-01 1.00000e+00
1.82157e+02 1.00478e+00 1.00000e+00
1.82408e+02 1.00147e+00 1.00000e+00
1.82660e+02 1.00747e+00 1.00000e+00
1.82911e+02 9.83522e-01 1.00000e+00
1.83162e+02 9.90690e-01 1.00000e+00
1.83413e+02 9.94175e-01 1.00000e+00
1.83664e+02 9.95883e-01 1.00000e+00
1.83915e+02 9.92199e-01 1.00000e+00
1.84167e+02 9.90755e-01 1.00000e+00
1.84418e+02 9.86480e-01 1.00000e+00
1.84669e+02 9.93964e-01 1.00000e+00
1.84920e+02 9.94745e-01 1.00000e+00
1.85171e+02 9.95895e-01 1.00000e+00
1.85422e+02 9.97575e-01 1.00000e+00
1.85674e+02 9.99326e-01 1.00000e+00
1.85925e+02 9.97579e-01 1.00000e+00
1.86176e+02 1.00187e+00 1.00000e+00
1.86427e+02 9.99647e-01 1.00000e+00
1.86678e+02 1.00026e+00 1.00000e+00
1.86930e+02 1.00307e+00 1.00000e+00
1.87181e+02 1.01192e+00 1.00000e+00
1.87432e+02 9.96247e-01 1.00000e+00
1.87683e+02 9.98530e-01 1.00000e+00
1.87934e+02 1.00165e+00 1.00000e+00
1.88185e+02 1.00562e+00 1.00000e+00
1.88437e+02 1.01337e+00 1.00000e+00
1.88688e+02 1.01309e+00 1.00000e+00
1.88939e+02 9.95564e-01 1.00000e+00
1.89190e+02 1.00160e+00 1.00000e+00
1.89441e+02 1.00596e+00 1.00000e+00
1.89692e+02 1.01222e+00 1.00000e+00
1.89944e+02 1.00825e+00 1.00000e+00
1.90195e+02 1.00603e+00 1.00000e+00
1.90446e+02 1.00770e+00 1.00000e+00
1.90697e+02 9.89746e-01 1.00000e+00
1.90948e+02 1.00511e+00 1.00000e+00
1.91200e+02 1.00621e+00 1.00000e+00
1.91451e+02 1.00143e+00 1.00000e+00
1.91702e+02 1.00224e+00 1.00000e+00
1.91953e+02 1.03274e+00 1.00000e+00
1.92204e+02 9.87474e-01 1.00000e+00
1.92455e+02 9.93631e-01 1.00000e+00
1.92707e+02 9.96782e-01 1.00000e+00
1.92958e+02 9.99014e-01 1.00000e+00
1.93209e+02 1.00251e+00 1.00000e+00
1.93460e+02 1.01135e+00 1.00000e+00
1.93711e+02 9.92486e-01 1.00000e+00
1.93962e+02 9.94748e-01 1.00000e+00
1.94214e+02 9.96729e-01 1.00000e+00
1.94465e+02 9.99500e-01 1.00000e+00
1.94716e+02 1.00314e+00 1.00000e+00
1.94967e+02 1.00767e+00 1.00000e+00
1.95218e+02 9.92280e-01 1.00000e+00
1.95470e+02 9.93172e-01 1.00000e+00
1.95721e+02 9.99065e-01 1.00000e+00
1.95972e+02 1.00089e+00 1.00000e+00
1.96223e+02 1.00147e+00 1.00000e+00
1.96474e+02 1.00277e+00 1.00000e+00
1.96725e+02 9.93517e-01 1.00000e+00
1.96977e+02 9.89833e-01 1.00000e+00
1.97228e+02 1.00075e+00 1.00000e+00
1.97479e+02 1.00224e+00 1.00000e+00
1.97730e+02 9.97354e-01 1.00000e+00
1.97981e+02 9.96498e-01 1.00000e+00
1.98232e+02 1.01632e+00 1.00000e+00
1.98484e+02 9.86819e-01 1.00000e+00
1.98735e+02 1.00374e+00 1.00000e+00
1.98986e+02 1.00217e+00 1.00000e+00
1.99237e+02 1.00089e+00 1.00000e+00
1.99488e+02 1.00215e+00 1.00000e+00
1.99740e+02 1.01197e+00 1.00000e+00
1.99991e+02 9.92503e-01 1.00000e+00

View File

@ -0,0 +1,7 @@
#Heating Rate tau_TNMH beta x deltaE Tg fictive
1.0000e+01 9.0613e+01 6.2053e-01 3.9548e-01 2.0820e+05 1.6911e+02
#Heating Rate tau_TNMH beta x deltaE Tg fictive
1.0000e+01 3.5330e+01 6.7660e-01 5.2984e-01 1.7362e+05 1.6934e+02
#Heating Rate tau_TNMH beta x deltaE Tg fictive
1.0000e+01 7.7937e+01 6.3348e-01 4.1076e-01 2.0555e+05 1.6925e+02

View File

@ -0,0 +1,197 @@
# Tool-Naranayaswamy-Moynihan-Hodge model
# by Florian Pabst 2020
import re
import os
import sys
import time
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad, cumulative_trapezoid
from scipy.optimize import curve_fit, fsolve
from scipy.stats import linregress
from nmreval.data import Points
def slope(x, t, m):
return t+x*m
def tau_k(tau_0, deltaE, temp_k, xx, T_f_km1):
return tau_0 * np.exp(xx*deltaE / (R*temp_k) + (1-xx) * deltaE / (R*T_f_km1))
# Read data
dataName = sys.argv[1]
try:
data = np.loadtxt(dataName, skiprows=0).T
print("Loading")
temp = data[0]
heat_capacity = data[1]
except IndexError:
print("File not found")
exit()
def get_fictive_temperature(pts: Points, glass: tuple[float, float], liquid: tuple[float, float]):
min_glass, max_glass = min(glass), max(glass)
min_liquid, max_liquid = min(liquid), max(liquid)
region = pts.copy()
region.cut(min_glass, max_liquid)
glass_regime = (min_glass < region.x) & (region.x < max_glass)
regress = linregress(region.x[glass_regime], region.y[glass_regime])
glass_extrapolation = regress.slope * region.x + regress.intercept
region.y -= glass_extrapolation
liquid_regime = (min_liquid < region.x) & (region.x < max_liquid)
regress = linregress(region.x[liquid_regime], region.y[liquid_regime])
liquid_extrapolation = regress.slope * region.x + regress.intercept
real_area = -cumulative_trapezoid(region.y, region.x, initial=0)
real_area -= real_area[-1]
equivalent_area = cumulative_trapezoid(liquid_extrapolation, region.x, initial=0)
equivalent_area -= equivalent_area[-1]
equivalent_area *= -1
return region.x, region.x[np.argmin(np.abs(real_area[:, None] - equivalent_area[None, :]), axis=1)]
curve = Points(x=temp, y=heat_capacity, name=dataName)
# First step: Calculate fictive Temperature T_f(T) from Cp data, then dT_f/dT
temperatures, fictiveTemp = get_fictive_temperature(curve, glass=(150, 160), liquid=(190, 200))
# Determine limiting T_f, i.e. T_f at lowest temperature
initial_Tf = np.mean(fictiveTemp[:20])
rate = curve.value
# Calculate dTf/dT
with np.errstate(all='ignore'):
dTfdT = np.gradient(fictiveTemp, temperatures)
nan_filter = ~np.isnan(dTfdT)
temperatures = np.array(temperatures)[nan_filter]
dTfdT = dTfdT[nan_filter]
exponents = []
taus = []
temps = [0]
T_f_ns = []
R = 8.314
def tnmfunc(temperature, tau_g, xx, beta, deltaE):
steps = len(temperature)
tau = np.zeros(steps)
temp_fictive = np.zeros(steps)
# Initialize first values
temp_fictive[0] = temperature[0]
tau[0] = relax(temp_fictive[0], temp_fictive[0], tau_g, T_g, deltaE, xx)
deltaT = np.zeros(steps)
deltaT[1:] = np.diff(temperature)
delta_t = deltaT * 60 / rate
dttau = np.zeros(steps)
for i in range(1, steps):
tau[i] = relax(temperature[i], temp_fictive[i-1], tau_g, T_g, deltaE, xx)
dttau[:i] += delta_t[i-1] / tau[i]
temp_fictive[i] = np.sum(deltaT[:i] * (1-np.exp(-(dttau[:i])**beta))) + temp_fictive[0]
print(i, temperature[i], temp_fictive[i-i], dttau, tau[i], delta_t[i-1], deltaT[i-1])
return temp_fictive
def relax(t, tf, tau_g, t_glass, ea, x):
h = ea/R
return tau_g * np.exp((x*h / t) + ((1 - x) * h / tf) - h / t_glass)
# TNMH Code (adapted from Badrinarayanan's PhD Thesis):
def tnmfunc2(xdata, tau_0, xx, beta, deltaE):
delhR = deltaE/8.314
T = []
Tf = []
t = []
delt = []
tau = []
dttau = []
delT = []
step = len(xdata)
for k in range(0, step):
dttau.append(0)
T.append(240)
Tf.append(240)
t.append(0)
delt.append(0)
tau.append(0)
dttau.append(0)
delT.append(0)
T[1] = xdata[1]
Tf[1] = T[1]
t[1] = 0
delt[1] = 0
tau[1] = tau_0 * np.exp((xx*delhR / T[1]) + ((1 - xx)*delhR / Tf[1])-delhR/T_g)
dttau[1] = delt[1] / tau[1]
delT[1] = 0
Tfinit = T[1]
T_f_ns = [xdata[0]]
for i in range(1, step):
T[i] = xdata[i]
delT[i] = xdata[i] - xdata[i-1]
delt[i] = abs(delT[i]) / (rate/60)
t[i] = t[i-1] + delt[i]
tau[i] = tau_0 * np.exp((delhR*xx / T[i]) + ((1 - xx)*delhR / Tf[i-1])-delhR/T_g)
print(tau[i], T[i], Tf[i-1])
for j in np.arange(2, i).reshape(-1):
dttau[j] = dttau[j] + (delt[i] / tau[i])
Tfinit = Tfinit + (delT[j] * (1 - np.exp(- (dttau[j] ** beta))))
Tf[i] = Tfinit
T_f_ns.append(Tfinit)
Tfinit = Tf[1]
return T_f_ns
# Use T_g = T_fictive for tau determination
T_g = initial_Tf
# Start values
p0 = [10, 0.5, 0.4, 225085]
def fitTNMH(x, tau_0, xx, beta, deltaE):
dTNMHdT = []
modelTemp = np.append(x[::-1], x[1:])
TNMH = tnmfunc2(modelTemp, tau_0, xx, beta, deltaE)
for i in range(len(modelTemp)-1):
dTNMHdT.append((TNMH[i+1]-TNMH[i]) / (modelTemp[i+1]-modelTemp[i]))
res = dTNMHdT[len(modelTemp)//2-1:]
plt.plot(x, res)
plt.show()
return np.array(res)
# Use only every 20th data point to reduce fitting time
temperaturesInterpol = np.linspace(temperatures[0], temperatures[-1], 20)
temperaturesInterpol = np.linspace(150, 200, 5)
dTfdTInterpol = np.interp(temperaturesInterpol, temperatures, dTfdT)
plt.plot(tnmfunc2(temperaturesInterpol, *p0))
plt.plot(tnmfunc(temperaturesInterpol, *p0))
plt.show()
# print(fitTNMH(temperaturesInterpol, *p0))

View File

@ -0,0 +1,333 @@
# Tool-Naranayaswami-Moynihan-Hodge model
# by Florian Pabst 2020
import time
import re
import os
import sys
import numpy as np
import matplotlib.pyplot as plt
import scipy.odr as odr
from scipy.integrate import quad
from scipy.optimize import curve_fit, fsolve
# Read data
dataName = sys.argv[1]
try:
data = np.loadtxt(dataName,skiprows=0)
print("Loading")
dataTemp = data[:, 0]
dataCp = data[:, 1]
except IndexError:
print("File not found")
exit()
dataOutName = os.path.splitext(str(dataName))[0] + "_Tfict+TNMH.dat"
# First step: Calculate fictive Temperature T_f(T) from Cp data, then dT_f/dT
# Find start and end point for glass Cp linear fit
coordsGl = [(150, -0.126), (160, -0.09)]
"""
print("Please click on the left limit for glass Cp linear fit")
fig, (ax1) = P.subplots(1)
ax1.set_xlabel('Temperature / K')
ax1.set_xlim(left=140)
ax1.set_xlim(right=200)
ax1.plot(dataTemp,dataCp, 'ro')
#ax1.legend()
def onclick(event):
ix = event.xdata
iy = event.ydata
print(ix)
global coordsGl
coordsGl.append((ix, iy))
if len(coordsGl) == 1:
print('right limit')
if len(coordsGl) == 2:
fig.canvas.mpl_disconnect(cid)
return coordsGl
cid = fig.canvas.mpl_connect('button_press_event', onclick)
P.show()
"""
print(coordsGl)
for i in range(0,len(dataTemp)):
if dataTemp[i] < coordsGl[0][0]:
fitLimitLeft_Gl = i
if dataTemp[i] < coordsGl[1][0]:
fitLimitRight_Gl = i
# Find start and end point for liquid Cp linear fit
coordsLq = [(190, 2.07), (200, 1.773)]
"""
print("Please click on the left limit for liquid Cp linear fit")
fig, (ax1) = P.subplots(1)
ax1.set_xlabel('Temperature / K')
ax1.set_xlim(left=180)
ax1.set_xlim(right=250)
ax1.plot(dataTemp,dataCp, 'ro')
#ax1.legend()
def onclick(event):
ix = event.xdata
iy = event.ydata
print(ix)
global coordsLq
coordsLq.append((ix, iy))
if len(coordsLq) == 1:
print('right limit')
if len(coordsLq) == 2:
fig.canvas.mpl_disconnect(cid)
return coordsLq
cid = fig.canvas.mpl_connect('button_press_event', onclick)
P.show()
#print(coordsLq)
"""
for i in range(0, len(dataTemp)):
if dataTemp[i] < coordsLq[0][0]:
fitLimitLeft_Lq = i
if dataTemp[i] < coordsLq[1][0]:
fitLimitRight_Lq = i
def slope(x, t, m):
return t+x*m
# Determine glass Cp slope
res = curve_fit(slope, dataTemp[fitLimitLeft_Gl:fitLimitRight_Gl], dataCp[fitLimitLeft_Gl:fitLimitRight_Gl])
glassCpParam = res[0]
# Determine liquid Cp slope
res = curve_fit(slope, dataTemp[fitLimitLeft_Lq:fitLimitRight_Lq], dataCp[fitLimitLeft_Lq:fitLimitRight_Lq])
liquidCpParam = res[0]
xLin = np.linspace(coordsGl[0][0], coordsLq[1][0], len(dataTemp))
CpInterpol = np.interp(xLin, dataTemp, dataCp)
"""
fig, (ax1) = P.subplots(1)
ax1.set_xlabel('Temperature / K')
ax1.set_xlim(left=coordsGl[0][0])
ax1.set_xlim(right=coordsLq[1][0])
ax1.set_ylim(bottom=coordsGl[0][1]-0.1)
ax1.set_ylim(top=coordsLq[1][1]+0.1)
ax1.plot(dataTemp,dataCp, 'ro')
ax1.plot(dataTemp,slope(dataTemp,glassCpParam[0],glassCpParam[1]), 'b-')
ax1.plot(dataTemp,slope(dataTemp,liquidCpParam[0],liquidCpParam[1]), 'b-')
ax1.plot(xLin,CpInterpol, 'g-')
P.show()
"""
# Calculate Fictive Temperature for all temperatures in range
intStart = fitLimitLeft_Gl
intStop = fitLimitRight_Lq
fictiveTemp = []
temperatures = []
for i,tempStart in enumerate(dataTemp):
if fitLimitLeft_Gl < i < fitLimitRight_Lq:
intStart = i
integration2 = np.trapz((dataCp[intStart:intStop]-slope(dataTemp[intStart:intStop], glassCpParam[0], glassCpParam[1])), dataTemp[intStart:intStop])
def integrand1(temp):
return slope(temp, liquidCpParam[0], liquidCpParam[1])-slope(temp, glassCpParam[0], glassCpParam[1])
def fictiveTempEq(x):
return quad(integrand1, x, coordsLq[1][0])[0] - integration2
ficTemp = fsolve(fictiveTempEq, np.array([160]))
fictiveTemp.append(ficTemp[0])
temperatures.append(tempStart)
# Determine limiting T_f, i.e. T_f at lowest temperatures
def constant(x, t):
return t
res = curve_fit(constant, temperatures[0:20], fictiveTemp[0:20])
T_f_0 = res[0]
print(T_f_0[0])
# Calculate dTf/dT
dTfdT = []
temperaturesCut = []
for i in range(len(temperatures)-1):
if (temperatures[i+1]-temperatures[i]) != 0:
dTfdT.append((fictiveTemp[i+1]-fictiveTemp[i]) / (temperatures[i+1]-temperatures[i]))
temperaturesCut.append(temperatures[i+1])
"""
fig, (ax1) = P.subplots(1)
ax1.set_xlabel('Temperature / K')
ax1.set_ylabel('Fictive Temperature / K')
#ax1.set_xlim(left=coordsGl[0][0])
#ax1.set_xlim(right=coordsLq[1][0])
#ax1.set_ylim(bottom=coordsGl[0][1]-0.1)
#ax1.set_ylim(top=coordsLq[1][1]+0.1)
ax1.plot(temperatures,fictiveTemp, 'ro')
#ax1.plot(temperatures,(T_f_0+temperatures*0), 'b-')
ax1.axhline(y=T_f_0[0], color='b', linestyle='-')
#ax1.plot(temperatures[:-1],dTfdT, 'ro')
P.show()
"""
# Second step: Calcualte and Fit TNMH-model
try:
rate = float(str((re.findall(r'\d+\.\d+K', dataName))[0])[:-1])
print("\tRate: %fK-min" % rate)
except IndexError:
rate = int(input("\tPlease enter the heating rate: "))
print("\tRate: %fK-min" %rate)
def tau_k(tau_0, deltaE, T_k, xx, T_f_km1):
return tau_0 * np.exp(xx*deltaE/(R*T_k) + (1-xx)*deltaE/(R*T_f_km1))
exponents = []
taus = []
temps = [0]
T_f_ns = []
markovs = [coordsLq[1][0]]
R = 8.31
# TNMH Code (adapted from Badrinarayanan's PhD Thesis):
def tnmfunc2(xdata, tau_0, xx, beta, deltaE):
delhR = deltaE/8.314
T = []
Tf = []
t = []
delt = []
tau = []
dttau = []
delT = []
step = len(xdata)
for k in range(0, step):
dttau.append(0)
T.append(240)
Tf.append(240)
t.append(0)
delt.append(0)
tau.append(0)
dttau.append(0)
delT.append(0)
T[1] = xdata[1]
Tf[1] = T[1]
t[1] = 0
delt[1] = 0
tau[1] = tau_0 * np.exp((xx*delhR / T[1]) + ((1 - xx)*delhR / Tf[1])-delhR/T_g)
dttau[1] = delt[1] / tau[1]
delT[1] = 0
Tfinit = T[1]
T_f_ns = [coordsLq[1][0]]
for i in range(1, step):
T[i] = xdata[i]
delT[i] = xdata[i] - xdata[i-1]
delt[i] = abs(delT[i]) / (rate/60)
t[i] = t[i-1] + delt[i]
tau[i] = tau_0 * np.exp((delhR*xx / T[i]) + ((1 - xx)*delhR / Tf[i-1])-delhR/T_g)
for j in np.arange(2, i).reshape(-1):
dttau[j] = dttau[j] + (delt[i] / tau[i])
Tfinit = Tfinit + (delT[j] * (1 - np.exp(- (dttau[j] ** beta))))
Tf[i] = Tfinit
T_f_ns.append(Tfinit)
Tfinit = Tf[1]
print(T_f_ns[:10])
return T_f_ns
####################################################
# Use T_g = T_fictive for tau determination
T_g = T_f_0[0]
# or plug in T_half, T_onset, ... from separate evaluation
# Start values
p0 = [10, 0.5, 0.4, 225085]
def fitTNMH(p, x):
dTNMHdT = []
modelTemp = np.append(x[::-1], x[1:])
tau_0, xx, beta, deltaE = p
TNMH = tnmfunc2(modelTemp, tau_0, xx, beta, deltaE)
for i in range(len(modelTemp)-1):
dTNMHdT.append((TNMH[i+1]-TNMH[i]) / (modelTemp[i+1]-modelTemp[i]))
res = dTNMHdT[len(modelTemp)//2-1:]
return np.array(res)
# Use only every 20th data point to reduce fitting time
temperaturesInterpol = np.linspace(temperaturesCut[0], temperaturesCut[len(temperaturesCut)-1], 200)
dTfdTInterpol = np.interp(temperaturesInterpol, temperaturesCut, dTfdT)
ts = time.time()
model = odr.Model(fitTNMH)
whichFit = [1, 1, 1, 1]
odrdata = odr.Data(temperaturesInterpol, dTfdTInterpol)
myodr = odr.ODR(odrdata, model, beta0=p0, ifixb=whichFit, maxit=3000)
result = (myodr.run())
print(result.stopreason)
p0 = result.beta
print('TNMH heating Fit:')
print(p0)
# print('errors:')
# print(result.sd_beta)
ts = time.time()-ts
print('Time for fit:')
print(ts)
tau_0, xx, beta, deltaE = p0
fitResult = fitTNMH(p0, temperaturesInterpol)
"""
fig, (ax1) = P.subplots(1)
ax1.set_xlabel('Temperature / K')
ax1.set_ylabel('Fictive Temperature / K')
#ax1.set_xlim(left=coordsGl[0][0])
#ax1.set_xlim(right=coordsLq[1][0])
#ax1.set_ylim(bottom=coordsGl[0][1]-0.1)
#ax1.set_ylim(top=coordsLq[1][1]+0.1)
#ax1.plot(temperatures,fictiveTemp, 'bo')
#ax1.plot(temperatures,T_f_ns, 'r-')
ax1.plot(temperaturesCut,dTfdT, 'bo')
#ax1.plot(temperatures[0:5454],dTNMHdT[0:5454], 'bo')
#ax1.plot(temperatures[5456:],dTNMHdT[5455:], 'ro')
#ax1.plot(temperaturesModel[0:99],dTNMHdT[0:99], 'b-')
#ax1.plot(temperaturesModel[100:199],dTNMHdT[100:199], 'r-')
ax1.plot(temperaturesInterpol,dTfdTInterpol, 'yo')
ax1.plot(temperaturesInterpol,fitResult, 'r-')
P.show()
"""
dataOutName = os.path.splitext(str(dataName))[0] + "_dTfdT_tau.fit"
dataOut = np.column_stack((temperaturesInterpol, dTfdTInterpol, fitResult))
save = 0 # input("Save parameter to file? (yes = 1, no = 0): ")
if save == '1':
np.savetxt(dataOutName, dataOut, fmt='%1.5e', header="tau_TNMH="+str(tau_0) + "\tbeta="+str(beta) + "\tx="+str(xx) + "\tdeltaE="+str(deltaE) + "\nTemp\t\tdTfdT_data\t\tdTfdT_fit")
# Try to determine the heating rate from the data file name (Searching for digits followed by ".")
paramName = ((str(dataName)).split("_"))[0] + "_DSC_tau.param"
print(paramName)
with open(paramName, 'a') as f:
f.write('\n#Heating Rate \t tau_TNMH \t beta \t\t\t x \t deltaE \t Tg fictive')
f.write('\n')
f.write('%1.4e \t %1.4e \t %1.4e \t %1.4e \t %1.4e \t %1.4e' % (rate, tau_0, beta, xx, deltaE, T_g))