Files
astaroth/analysis/python/calc/shu_selfsim.py
2019-06-14 14:19:07 +03:00

280 lines
8.8 KiB
Python

'''
Copyright (C) 2014-2019, Johannes Pekkilae, Miikka Vaeisalae.
This file is part of Astaroth.
Astaroth is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Astaroth is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Astaroth. If not, see <http://www.gnu.org/licenses/>.
'''
import numpy as np
import pylab as plt
G_newton = 6.674e-8 #cm**3 g**-1 s**-2
def dv_dx(xx,vv, alpha):
EE = alpha*(xx-vv) - 2.0/xx
HH = (xx-vv)**2.0 - 1.0
return (EE/HH)*(xx-vv)
def dalpha_dx(xx,vv, alpha):
EE = alpha*(alpha - (2.0/xx)*(xx-vv))
HH = (xx-vv)**2.0 - 1.0
return (EE/HH)*(xx-vv)
###def dv_dx(xx,vv, alpha):
### return 2.0*(xx-vv)
###
###def dalpha_dx(xx,vv, alpha):
### return -1.0*(xx-vv)
def get_m(xx, vv, alpha):
mm = xx**2.0 * alpha * (xx-vv)
return mm
def alpha_to_rho(alpha, tt):
rho = alpha/(4.0*np.pi*G_newton*(tt**2.0))
return rho
def vv_to_uu(vv, cs0):
uu = cs0*vv
return uu
def mm_to_MM(mm, tt, cs0):
MM = (((cs0**3.0)*tt)/G_newton)*mm
return MM
def euler(xx_step, xx, vv, alpha, mm, target):
diff = target - xx[-1]
if diff >= 0:
while xx[-1] <= target:
vv_step = vv[-1] + xx_step*dv_dx(xx[-1], vv[-1], alpha[-1])
alpha_step = alpha[-1] + xx_step*dalpha_dx(xx[-1], vv[-1], alpha[-1])
xx = np.append(xx, xx[-1]+xx_step)
alpha = np.append(alpha, alpha_step)
vv = np.append(vv, vv_step)
mm_step = get_m(xx[-1], vv[-1], alpha[-1])
mm = np.append(mm, mm_step)
else:
while xx[-1] <= target:
vv_step = vv[-1] + xx_step*dv_dx(xx[-1], vv[-1], alpha[-1])
alpha_step = alpha[-1] + xx_step*dalpha_dx(xx[-1], vv[-1], alpha[-1])
xx = np.append(xx, xx[-1]+xx_step)
alpha = np.append(alpha, alpha_step)
vv = np.append(vv, vv_step)
mm_step = get_m(xx[-1], vv[-1], alpha[-1])
mm = np.append(mm, mm_step)
return xx, vv, alpha, mm
def RK4_step(vv, xx, alpha, xx_step):
vv1 = xx_step*dv_dx(xx[-1], vv[-1], alpha[-1])
alpha1 = xx_step*dalpha_dx(xx[-1], vv[-1], alpha[-1])
vv2 = xx_step*dv_dx(xx[-1]+xx_step/2.0, vv[-1]+vv1/2.0, alpha[-1]+alpha1/2.0)
alpha2 = xx_step*dalpha_dx(xx[-1]+xx_step/2.0, vv[-1]+vv1/2.0, alpha[-1]+alpha1/2.0)
vv3 = xx_step*dv_dx(xx[-1]+xx_step/2.0, vv[-1]+vv2/2.0, alpha[-1]+alpha2/2.0)
alpha3 = xx_step*dalpha_dx(xx[-1]+xx_step/2.0, vv[-1]+vv2/2.0, alpha[-1]+alpha2/2.0)
vv4 = xx_step*dv_dx(xx[-1]+xx_step, vv[-1]+vv3, alpha[-1]+alpha3)
alpha4 = xx_step*dalpha_dx(xx[-1]+xx_step, vv[-1]+vv3, alpha[-1]+alpha3)
vv_step = vv[-1] + (1.0/6.0)*(vv1 + 2.0*vv2 + 2.0*vv3 + vv4)
alpha_step = alpha[-1] + (1.0/6.0)*(alpha1 + 2.0*alpha2 + 2.0*alpha3 + alpha4)
return vv_step, alpha_step
def RK4(xx_step, xx, vv, alpha, mm, target, epsilon):
#Runge-Kutta RK4
diff = target - xx[-1]
#if diff < 0:
if diff >= 0:
while xx[-1] <= target:
if (np.abs(xx[-1] - vv[-1] - 1.0) > epsilon):
vv_step, alpha_step = RK4_step(vv, xx, alpha, xx_step)
print( vv_step, alpha_step)
else:
vv_step = vv[-1]
alpha_step = alpha[-1]
print("PIIP")
#print(np.abs(xx[-1] - vv[-1]), epsilon)
xx = np.append(xx, xx[-1]+xx_step)
alpha = np.append(alpha, alpha_step)
vv = np.append(vv, vv_step)
mm_step = get_m(xx[-1], vv[-1], alpha[-1])
mm = np.append(mm, mm_step)
else:
while xx[-1] >= target:
if (np.abs(xx[-1] - vv[-1] - 1.0) > epsilon):
vv_step, alpha_step = RK4_step(vv, xx, alpha, xx_step)
print( vv_step, alpha_step)
else:
vv_step = vv[-1]
alpha_step = alpha[-1]
print("PIIP")
#print(np.abs(xx[-1] - vv[-1]), epsilon)
xx = np.append(xx, xx[-1]+xx_step)
alpha = np.append(alpha, alpha_step)
vv = np.append(vv, vv_step)
mm_step = get_m(xx[-1], vv[-1], alpha[-1])
mm = np.append(mm, mm_step)
return xx, vv, alpha, mm
# From Shu 1977 TABLE II
xx_SHU = np.array([0.05 , 0.10 , 0.15 , 0.20 , 0.25 , 0.30 , 0.35 , 0.40 , 0.45 ,
0.50 , 0.55 , 0.60 , 0.65 , 0.70 , 0.75 , 0.80 , 0.85 ,
0.90 , 0.95 , 1.00])
alpha_SHU = np.array([71.5 , 27.8 , 16.4 , 11.5 , 8.76 , 7.09 , 5.95 , 5.14 , 4.52 ,
4.04 , 3.66 , 3.35 , 3.08 , 2.86 , 2.67 , 2.50 , 2.35 ,
2.22 , 2.10 , 2.00])
vv_SHU = -np.array([5.44 , 3.47 , 2.58 , 2.05 , 1.68 , 1.40 , 1.18 , 1.01 , 0.861,
0.735, 0.625, 0.528, 0.442, 0.363, 0.291, 0.225, 0.163,
0.106, 0.051, 0.00])
mm_SHU = np.array([0.981, 0.993, 1.01 , 1.03 , 1.05 , 1.08 , 1.12 , 1.16 , 1.20 ,
1.25 , 1.30 , 1.36 , 1.42 , 1.49 , 1.56 , 1.64 , 1.72 ,
1.81 , 1.90 , 2.00])
##From Shu (1977)
#AA = [ 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0]
#m0 = [0.975, 1.45, 1.88, 2.31, 2.74, 3.18, 3.63, 4.10, 4.58, 5.08, 5.58]
#AA = np.array(AA)
#m0 = np.array(m0)
#xx0 = xx_SHU[1]
#alpha0 = alpha_SHU[1]
#vv0 = vv_SHU[1]
#xx_step = 0.005
#target = 1.0
xx0 = xx_SHU[-3]
alpha0 = alpha_SHU[-3]
vv0 = vv_SHU[-3]
target = 0.05
xx_step = -0.005
xx_step = -0.001
print(get_m(xx0, alpha0, vv0))
xx = np.array([])
alpha = np.array([])
vv = np.array([])
mm = np.array([])
xx = np.append(xx, xx0)
alpha = np.append(alpha, alpha0)
vv = np.append(vv, vv0)
mm = np.append(mm, get_m(xx0, alpha0, vv0))
print(xx, alpha, vv, mm)
xx_EUL, vv_EUL, alpha_EUL, mm_EUL = euler(xx_step, xx, vv, alpha, mm, target)
xx_RK , vv_RK , alpha_RK , mm_RK = RK4(xx_step, xx, vv, alpha, mm, target, epsilon = 0.000001)
mm_EUL = get_m(xx_EUL, alpha_EUL, vv_EUL)
mm_RK = get_m(xx_RK , alpha_RK , vv_RK )
mm_SHU = get_m(xx_SHU, alpha_SHU, vv_SHU)
# Plotting time
figQ, axQ = plt.subplots(nrows=2, ncols=2, sharex=True)
axQ[0,0].plot(xx_EUL, alpha_EUL, label=r'$\alpha$ (Euler)', linewidth = 3.0)
axQ[0,0].plot(xx_RK , alpha_RK , label=r'$\alpha$ (RK4)', linewidth = 3.0)
axQ[0,0].plot(xx_SHU, alpha_SHU, 'd', label=r'$\alpha$ (Shu)', linewidth = 3.0)
axQ[0,0].set_xlabel(r'x')
axQ[0,0].set_ylabel(r'$\alpha$')
axQ[0,0].legend()
axQ[0,1].plot(xx_EUL, np.abs(vv_EUL), label='v (Euler)', linewidth = 3.0)
axQ[0,1].plot(xx_RK , np.abs(vv_RK ), label='v (RK4)', linewidth = 3.0)
axQ[0,1].plot(xx_SHU, np.abs(vv_SHU),'d', label='v (Shu)', linewidth = 3.0)
axQ[0,1].set_xlabel(r'x')
axQ[0,1].set_ylabel(r'-v')
axQ[0,1].legend()
axQ[1,0].plot(xx_EUL, mm_EUL, label='m (Euler)', linewidth = 3.0)
axQ[1,0].plot(xx_RK , mm_RK , label='m (RK4)', linewidth = 3.0)
axQ[1,0].plot(xx_SHU , mm_SHU , 'd', label='m (Shu)', linewidth = 3.0)
axQ[1,0].set_xlabel(r'x')
axQ[1,0].set_ylabel(r'm')
axQ[1,0].legend()
axQ[1,1].plot(xx_EUL, xx_EUL-vv_EUL, label='x-v (Euler)', linewidth = 3.0)
axQ[1,1].plot(xx_RK , xx_RK -vv_RK , label='x-v (RK4)', linewidth = 3.0)
axQ[1,1].plot(xx_SHU, xx_SHU-vv_SHU, 'd', label='x-v (Shu)', linewidth = 3.0)
axQ[1,1].set_xlabel(r'x')
axQ[1,1].set_ylabel(r'x-v')
axQ[1,1].legend()
# Time to convert to physical quantities
yr = 3.154e+7 #s
kyr = 1000.0*yr
km = 1e5 #cm
AU = 1.496e+13 #cm
Msun = 1.98847e33 #g
cs0 = 20000 #cs cm/s "a" in Shu notation
tt_list = np.linspace(10*kyr, 20.0*kyr, num=4)
mm = get_m(xx_RK, vv_RK, alpha_RK)
fig, ax = plt.subplots(nrows=1, ncols=3, sharex=True)
for tt in tt_list:
rho = alpha_to_rho(alpha_RK, tt)
RR = xx_RK*(cs0*tt)
time = r'%.2f $\mathrm{kyr}$' % (tt/kyr)
ax[0].plot(RR/AU, rho, label= r'$\rho$, t = ' + time, linewidth = 3.0)
ax[0].set_xlabel(r'R (AU)')
ax[0].set_ylabel(r'$\rho$ (g/cm$^3$)')
ax[0].set_xscale('log')
ax[0].set_yscale('log')
ax[0].legend()
uu = vv_to_uu(vv_RK, cs0)
ax[1].plot(RR/AU, -uu/km, label= r'$u$, t = ' + time, linewidth = 3.0)
ax[1].set_xlabel(r'R (AU)')
ax[1].set_ylabel(r'-$u$ (km/s)')
ax[1].set_yscale('log')
ax[1].legend()
MM = mm_to_MM(mm, tt, cs0)
ax[2].plot(RR/AU, MM/Msun, label= r'$M$, t = ' + time, linewidth = 3.0)
ax[2].set_xlabel(r'R (AU)')
ax[2].set_ylabel(r'$M$ ($M_\odot}$)')
ax[2].legend()
plt.show()