I am attempting to solve a nonlinear diffusion equation of the form $\partial_t u = \partial_x (\kappa(u) \partial_x u)$, where the conductivity function $\kappa(u)$ is a power law $\kappa = u^{5/2}$, using the LSODA time integrator in Python interfaced through SciPy. The equation is discretized by finite difference on a spatial grid, and the resulting system of ODEs is time-integrated by LSODA. The spatial domain is $x \in [0,1]$, the boundary values are fixed as $u(0,t)=u_l$ and $u(1,t)=u_{r}$. Here is a little Python code implementing all this.
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def kappa(z):
#-heat conductivity
return z**2.5
def rhs(u, t, dx, param):
N = len(u) - 1
rhs = np.zeros(N+1)
#-fixed value on the left end
rhs[0] = 0.0
for i in range(1, N):
rhs[i] = (1/dx**2)*(
(kappa(u[i])*(u[i+1] - 2*u[i] + u[i-1]) +
(kappa(u[i+1])-kappa(u[i-1]))*(u[i+1]-u[i-1])/4.0)
)
#-fixed value on the right end
rhs[N] = 0.0
return rhs
def run_hc1d(L = 1.0, nx = 40, lval=1.0, rval=3.0, nt=10, tmax=1e0):
#-spatial grid
x = np.linspace(0, L, nx+1)
dx = x[1] - x[0]
U_0 = np.zeros(nx+1)
#-boundary values
U_0[0] = lval
U_0[nx] = rval
#-initial values
U_0[1:nx] = np.min([lval,rval])
#-time grid
t = np.linspace(0,tmax,nt)
#-solving ODEs
u = odeint(rhs, U_0, t, args=(dx,0.))
plt.plot(x,u[0,:])
plt.title("Nonlinear diffusion equation w/ LSODE")
plt.xlabel("x")
for it in range(0,nt):
plt.plot(x,u[it,:])
plt.show()
run_hc1d(tmax=0.1)
Using $u_l$=1 and $u_r$=3 I can obtain the solution with my Python code, calling it as
>>>run_hc1d(tmax=0.1, rval=3.0)
And it produces a reasonably looking solution, here are several snapshots:
However, using a slightly larger value for $u_r$ results in failure of the time integrator, e.g., it fails if the code is called as
>>> run_hc1d(tmax=0.1, rval=4.0)
This behavior is puzzling since this equation does not look hard to solve, after all. Why is the time integrator failing? What can be done to make it better behaving, in terms of the choices for the solver parameters, finite difference etc?