Periodic variations in seafloor temperature
We will explore how periodic variations in seafloor temperature affect the sub-seafloor temperature structure. For this we will learn about flux boundary conditions
[14]:
import numpy as np
import numpy.matlib
from scipy.linalg import solve
from scipy.sparse import spdiags
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML
import matplotlib as mpl
[39]:
# Physical parameters
L = 30 # Length of modeled domain [m]
Ttop = 4 # Temperature at seafloor [C]
kappa = 1e-6 # Thermal diffusivity of rock [m2/s]
day = 60*60*24 # seconds per day
hf = 0.06 # basement heat flow in W/m2
k = 1.5 # thermal conductivity of sediment
ampl = 1 # surface temperature variation
zeval = -5
r_time = 10*365*day
# Numerical parameters
ny = 101 # Number of gridpoints in y-direction
steps = 301;
Time,dt = np.linspace(0, r_time, steps, retstep=True)
Yvec,dy = np.linspace(-L, 0, ny, retstep=True) # Y coordinate vector, constant spacing
[40]:
# Boundary and initial conditions
Tsurf = Ttop + ampl*np.sin(2*np.pi/(365/2*day)*Time);
gradT = -hf/k;
T_init = Ttop + gradT*Yvec;
time = 0;
beta = kappa*dt/dy**2
[41]:
# hide
# setup coefficient matrix with flux boundary condition at the bottom
data = (np.ones((ny,1))*np.array([-beta, (1+2*beta), -beta ])).T
diags = np.array([-1, 0, 1])
A = spdiags(data, diags, ny, ny).toarray()
# Boundary conditions
# constant temperature at seafloor
A[ny-1,ny-1] = 1
A[ny-1,ny-2] = 0
# constant gradient at the bottom
A[0,(0,1)] = [(1+2*beta), -2*beta]
[42]:
# setup coefficient matrix with flux boundary condition at the bottom
# data = (np.ones((ny,1))*np.array([-beta, (1+2*beta), -beta ])).T
# diags = np.array([-1, 0, 1])
# A = spdiags(data, diags, ny, ny).toarray()
# Set boundary conditions!!
# constant temperature at seafloor
# A[???] = ???
# A[???] = ???
# constant gradient at the bottom
# A[???] = [???]
A[0:6,0:6]
[42]:
array([[ 24.36, -23.36, 0. , 0. , 0. , 0. ],
[-11.68, 24.36, -11.68, 0. , 0. , 0. ],
[ 0. , -11.68, 24.36, -11.68, 0. , 0. ],
[ 0. , 0. , -11.68, 24.36, -11.68, 0. ],
[ 0. , 0. , 0. , -11.68, 24.36, -11.68],
[ 0. , 0. , 0. , 0. , -11.68, 24.36]])
[43]:
# Implicit FD solve with flux boundary conditions
def fdm_solve(Rhs):
Tnew=solve(A,Rhs)
return Tnew
[44]:
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure(figsize=(10,5))
ax = plt.axes(xlim=(Ttop-ampl-1, Ttop-L*gradT+1), ylim=(-L, 0))
# how many lines do you want to display
num_solutions = 20
solution_list,lines = [],[]
for i in range(0,num_solutions):
line, = ax.plot([], [], lw=1)
lines.append(line)
timeLabel=ax.text(0.02,0.98,'Time: ',transform=ax.transAxes,va='top')
ax.set_xlabel('Temperature ($^{\circ}$C)')
ax.set_ylabel('Depth (m)')
# Initialize Tnew
Tnew=T_init
# Animation function which updates figure data. This is called sequentially
def animate(i):
timeLabel._text='Time: %.1f day'%(i*dt/day)
# use global keyword to store the latest solution and update it using fdm_solve function
global Tnew
Rhs = Tnew.copy()
Rhs[0]= Rhs[0] + 2*beta*dy*hf/k;
Rhs[-1] = Tsurf[i];
Tnew=fdm_solve(Rhs)
# Update solution list and always keep latest solutions
if(len(solution_list)<num_solutions):
solution_list.append(Tnew)
elif(len(solution_list)==num_solutions):
solution_list.pop(0) #remove the oldest resolution
solution_list.append(Tnew)
# update lines
for i in range(0,len(solution_list)):
lines[i].set_data(solution_list[i], Yvec)
lines[i].set_color('k')
lines[i].set_alpha((num_solutions-i)/num_solutions)
# Call the animator.
anim = animation.FuncAnimation(fig, animate,frames=steps,interval=50)
plt.close(anim._fig)
# Call function to display the animation
#HTML(anim.to_html5_video()) # lower resolution
HTML(anim.to_jshtml()) # higher resolution
[44]:
[ ]:
[ ]: