I want to solve the Poisson PDE for heat flow in a 3-D solid cube with given dimensions $x$, $y$, and $z$:
$$\rho C\frac{\partial T}{\partial t} = k \Delta T$$
The cube is irradiated with a constant heat flux $I(x,y)$ at the $z=0$ surface. The boundaries should meet the Neumann condition for radiative cooling given by $\frac{\partial T}{\partial x_i} = \pm\epsilon\sigma(T^4-300^4)$, where the sign depends on wether you look at $x_i=$max or $x_i=0$. Due to the irradiation the $z=0$ surface is an exception, where the condition should rather be $\frac{\partial T}{\partial x_i} = \epsilon\sigma(T^4-300^4) + I(x,y)$. The last term represents the intensity distribution of the radiative flux.
I decided to go for a numerical approach I found in this thread using Python. As a result, I came up with the following piece of code.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplotn3d
dt = 3
di = 0.01
#Thermal conductivity
k = 1.38
#Density
rho = 2202
#Specific Heat capacity
cp = 745
#Thermal diffusivity
alpha = k/(rho*cp)
#Emissivity
emissivity = 0.79
sigma = 5.670367e-8
y_max = 0.3
x_max = 0.3
z_max = 0.3
t_max = 60
P = 1
omega = 0.02
#Function that generates a gaussian intensity pattern I(x,y) with power P and beam waist omega
def get_beam(P, omega, di, x_max, ymax, z_max):
x = np.arange(0,x_max+di,di)
y = np.arange(0,y_max+di,di)
z = np.arange(0,z_max+di,di)
t = np.arange(0,t_max+dt,dt)
r = len(t)
cx = len(x)
cy = len(y)
cz = len(z)
I = np.zeros([r, cx, cy, cz])
for jx in range(0,cx-1):
for jy in range(0,cy-1):
I[:,jx,jy,0] = 2*P/(np.pi*omega**2)*np.exp(-2*(abs(di*(jx-cx/2))**2 + abs(di*(jy-cy/2))**2)/(omega**2))
return I
def FTCS(dt,dy,t_max,x_max,y_max,z_max,k,T0, I):
s = alpha*dt/di**2
x = np.arange(0,x_max+di,di)
y = np.arange(0,y_max+di,di)
z = np.arange(0,z_max+di,di)
t = np.arange(0,t_max+dt,dt)
r = len(t)
cx = len(x)
cy = len(y)
cz = len(z)
#Initialize mesh
T = np.ones([r,cx, cy, cz])*T0
#time loop
for n in range(0,r-1):
print(n)
#y loop
for jy in range(0,cy-1):
#x loop
for jx in range(0,cx-1):
#z loop
for jz in range(0,cz-1):
#Compute T at next time step: Tn+1 = Tn + d^2T/dx^2 + d^2T/dy^2 + d^2T/dz^2
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx+1,jy,jz]) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy+1,jz]) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz+1])
#Boundary Condition
#Set boundary condition for x on both sides
T[n+1,cx-1,:,:] = T[n,cx-1,:,:] + s*(T[n,cx-2,:,:] - 2*T[n,cx-1,:,:] + T[n,cx-2,:,:] - 2*di*emissivity*sigma/k*(T[n,cx-1, :,:]**4-300**4))#- 2*di*4*emissivity*sigma/k*(T[n,cx-1,:,:]*300**3))
T[n+1,0,:,:] = T[n,0,:,:] + s*(T[n,1,:,:] - 2*T[n,0,:,:] + T[n,1,:,:] - 2*di*emissivity*sigma/k*(T[n,0,:,:]**4-300**4))#- 2*di*4*emissivity*sigma/k*(T[n,0,:,:]*300**3))
#Set boundary condition for y on both sides
T[n+1,:,cy-1,:] = T[n,:,cy-1,:] + s*(T[n,:,cy-2,:] - 2*T[n,:,cy-1,:] + T[n,:,cy-2,:] - 2*di*emissivity*sigma/k*(T[n,:,cy-1,:]**4-300**4))#- 2*di*4*emissivity*sigma/k*(T[n,:,cy-1,:]*300**3))
T[n+1,:,0,:] = T[n,:,0,:] + s*(T[n,:,1,:] - 2*T[n,:,0,:] + T[n,:,1,:] - 2*di*emissivity*sigma/k*(T[n,:,0,:]**4-300**4))#- 2*di*4*emissivity*sigma/k*(T[n,:,0,:]*300**3))
#Set boundary condition for z on both sides
T[n+1,:,:,cz-1] = T[n,:,:,cz-1] + s*(T[n,:,:,cz-2] - 2*T[n,:,:,cz-1] + T[n,:,:,cz-2] - 2*di*emissivity*sigma/k*(T[n,:,:,cz-1]**4-300**4))#- 2*di*4*emissivity*sigma/k*(T[n,:,:,cz-1]*300**3))
T[n+1,:,:,0] = T[n,:,:,0] + s*(T[n,:,:,1] - 2*T[n,:,:,0] + T[n,:,:,1] - 2*di*emissivity*sigma/k*(T[n,:,:,0]**4-300**4) + 2*di/k*I[n,:,:,0])#- 2*di*4*emissivity*sigma/k*(T[n,:,:,0]*300**3) + 2*di*I[n,:,:,0])
return x,y,z,t,T,r,s
I = get_beam(P, omega, di, x_max, y_max, z_max)
x,y,z,t,T,r,s = FTCS(dt,di,t_max,x_max,y_max,z_max,k,300,I)
fig = plt.figure()
X, Y = np.meshgrid(x, y)
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, T[-1,:,:,0])
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')
The result looks promising but is not equal to references I found. Furthermore, the result scales rapidly with the mesh size $d_i$ and crashes for huge point densities. I couldn't figure out whether and if so where I did a mistake. Can you help me?
//-----------------------------------//
I updated the code to include the correct boundaries. The loop looks like this now. I know its a bit clunky, but I thought I take care of it later. Nevertheless, the dependence from the mesh size is still there. I am afraid that I just forgot a $di$ somewhere, but I couldn't find out where.
for n in range(0,r-1):
print(n)
for jy in range(0,cy-1):
for jx in range(0,cx-1):
for jz in range(0,cz-1):
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx+1,jy,jz]) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy+1,jz]) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz+1])
if jx == cx-1:
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx-1,jy,jz] + 2*di*emissivity*sigma/k*(T[n,jx, jy, jz]**4-300**4)) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy+1,jz]) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz+1])
elif jx == 0:
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx-1,jy,jz] - 2*di*emissivity*sigma/k*(T[n,jx, jy, jz]**4-300**4)) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy+1,jz]) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz+1])
elif jy == cy-1:
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx+1,jy,jz]) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy-1,jz] + 2*di*emissivity*sigma/k*(T[n,jx,jy,jz]**4-300**4)) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz+1])
elif jy == 0:
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx+1,jy,jz]) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy-1,jz] - 2*di*emissivity*sigma/k*(T[n,jx,jy,jz]**4-300**4)) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz+1])
elif jz == cz-1:
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx+1,jy,jz]) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy+1,jz]) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz-1] + 2*di*emissivity*sigma/k*(T[n,jx,jy,jz]**4-300**4))
elif jz == 0:
T[n+1,jx,jy,jz] = T[n,jx,jy,jz] + s*(T[n,jx-1,jy,jz] - 2*T[n,jx,jy,jz] + T[n,jx+1,jy,jz]) + s*(T[n,jx,jy-1,jz] - 2*T[n,jx,jy,jz] + T[n,jx,jy+1,jz]) + s*(T[n,jx,jy,jz-1] - 2*T[n,jx,jy,jz] + T[n,jx,jy,jz-1] - 2*di*emissivity*sigma/k*(T[n,jx,jy,jz]**4-300**4) + 2*di*I[n,jx,jy,0])