I would like to numerically solve the following equation: $$\frac{\partial \rho (z,t)}{\partial t} = B(N_D \rho (z,t) + \rho(z,t)^2) + D \frac{\partial^2 \rho (z,t)}{\partial z^2}$$
with the boundary conditions being:
$$D \frac{\partial \rho}{\partial z}|_{z=0} = S_f \rho (z=0,t)$$
$$D \frac{\partial \rho}{\partial z}|_{z=L} = -S_b \rho (z=L,t)$$
Here, the constants $D$, $G$, $B$, $S_f$, $S_b$, $N_d$ are given, and are assumed not to vary with $z$, $t$, or $\rho$
In attempting to numerically solve this, I used central differencing to convert the boundary conditions to a set of ghost points in the $z$ mesh as follows:
$$\rho (-\Delta z, t) = \rho(\Delta z, t) - \frac{S_f \Delta z \rho(0, t)}{D}$$ and
$$\rho (L+\Delta z, t)=\rho(L - \Delta z,t)-(\frac{S_b \Delta z \rho(L,t)}{D})$$.
I then implemented the following code in python:
import scipy as sp
from scipy.integrate import odeint
import numpy as np
def ODEEq(rho, t, D, B, Nd):
return (D*np.gradient(np.gradient(rho))-B*(Nd*rho+(rho**2)))
def Solver(delz, delt, L, T, G0, D, B, Nd, Sf, Sb, unitMaker=1e-9):
tspace = np.linspace(0,T,int(T/delt))
xm1Ghost = G0[1] - (Sf*delz*G0[0]/D)
xLp1Ghost = G0[-2] - (Sb*delz*G0[-1]/D)
rho = G0
np.insert(rho, 0, xm1Ghost)
np.append(rho, xLp1Ghost)
sol = odeint(ODEEq, rho, tspace, args=(D, B, Nd), full_output=1)
return sol
L = 4000
timeRange = 2000
D = 1.639e18
B = 2e13
Nd = 0
delz = 0.1
delt = 0.1
G0 = 640*np.exp((-6.4e-2)*np.linspace(0,L,int(L/delz)))
Sf = 0.64
Sb = 0.64
sol = Solver(delz, delt, L, timeRange, G0, D, B, Nd, Sf, Sb)
The initial conditions (G0) are visualized as:
However, there seems to be some issue with this implementation (aside from the fact that it is extremely slow).
I'm hoping to get some help in resolving the issues with this approach, and any ideas on how to make it faster.