Ondřej Šrámek, Charles University, ondrej.sramek@gmail.com, 14 January 2019
If we wanted to represent the decay of radiogenic heat production from several major radionuclides (238U, 232Th, 40K) by one simple exponential, what would be the representative half-life?
Constraints:
import numpy as np
from math import log
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12,8)
Mearth = 5.97218e24 # mass of Earth in kg (Chambat et al 2010)
Mcore = 1.93e24 # mass of core in kg (Yoder 1995)
Mbse = Mearth-Mcore # mass of BSE in kg
nuclides = ["238U", "235U", "232Th", "40K"]
halflives = np.array([4.4683, 0.70348, 14.1, 1.262]) # in Gyr
abundances = np.array([20.0e-9, 20.0e-9, 75.4e-9, 280e-6]) # in kg-element per kg-rock
powerspec = np.array([94.247, 4.046, 26.180, 0.003387]) * 1e-6 *1e-12 # in TW per kg-element
H0 = abundances*powerspec*Mbse # H0[] in TW in BSE
H0sum = sum(H0) # H0 in TW in BSE
lambdas = log(2.)/halflives
print ("Th/U mass ratio = {:.3f}".format(abundances[2]/abundances[0]))
print ("K/U mass ratio = {:.0f}".format(abundances[3]/abundances[0]))
heat_production_BSE = H0sum # in TW
print ("CHECK: Heat production in BSE = {:.2f} TW".format(heat_production_BSE))
age = np.linspace(0, 4.568, 128) # even time grid over the age of the Earth
# heat production vs. age: sum of exponentials
Hage = np.zeros(age.size)
for i in range(halflives.size):
Hage = Hage + H0[i]*np.exp(lambdas[i]*age)
from scipy.optimize import curve_fit
# 1 parameter fit – only decay constant
def func(a, lam):
return H0sum*np.exp(lam*a)
p_opt, p_cov = curve_fit(func, age, Hage)
print (p_opt)
print (p_cov)
lam_opt = p_opt[0]
lam_err = np.sqrt(p_cov[0][0])
print ("\ndecay constant fit = ({:.4f} ± {:.4f}) Gyr-1\n".format(lam_opt, lam_err))
halflife_fit = log(2.)/lam_opt
print ("half-life fit = {:.4f} Gyr".format(halflife_fit))
# 2 parameter fit – decay constant and H0
def func2(a, lam, h0):
return h0*np.exp(lam*a)
p_opt, p_cov = curve_fit(func2, age, Hage)
print (p_opt)
print (p_cov)
lam2_opt = p_opt[0]
lam2_err = np.sqrt(p_cov[0][0])
H0_opt = p_opt[1]
H0_err = np.sqrt(p_cov[1][1])
print ("\ndecay constant fit = ({:.4f} ± {:.4f}) Gyr-1".format(lam2_opt, lam2_err))
print ("present-day H0 = ({:.4f} ± {:.4f}) TW\n".format(H0_opt, H0_err))
halflife2_fit = log(2.)/lam2_opt
print ("half-life fit = {:.4f} Gyr".format(halflife2_fit))
Hfit = H0sum*np.exp(lam_opt*age)
Hfit2 = H0_opt*np.exp(lam2_opt*age)
plt.plot(age, Hage, label='actual')
plt.plot(age, Hfit, label='1-parameter fit')
plt.plot(age, Hfit2, "--", label='2-parameter fit')
plt.xlabel("Age in Gyr")
plt.ylabel("Heat production in TW")
plt.legend()
plt.show()