Original Stack Overflow Question: https://stackoverflow.com/questions/65683788/indexerror-index-31-is-out-of-bounds-for-axis-1-with-size-31?noredirect=1#comment116218335_65683788
PDE: u_t = u_xx + u(u_x)^2
The backward difference was used the time derivative meanwhile a central difference was used for the first space derivative.
If you follow the link you can see that I cannot get solutions that make sense and I cannot figure out how to. I'm adamant it is to do with the function f at the finite-difference algorithm stage. Currently, I understand that f is a vector and hence only generating the initial condition. But when I try something like f[1:M, q]
it doesn't work.
Code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import math
from scipy.sparse import spdiags
from numpy.linalg import inv
M = 30
dx = 1 / M
r = 0.25
tmax = 0.2
dt = r * dx**2
N = math.floor(tmax / dt)
x = np.linspace(0, 1, M + 1)
t = np.linspace(0, tmax, N + 1)
U = np.zeros((M + 1, N + 1)) # Initial array for solution u(x, t)
U[:, 0] = 40 * x**2 * (1 - x) / 3 # Initial condition
U[0, :] = 0 # Boundary condition at x = 0
U[-1, :] = 0 # Boundary condition at x = 1
for q in range(1, N):
U[:, q+1] = U[:, q]
for p in range(1, 10):
f = np.zeros((M+1, M+1))
for k in range(2, M):
f = U[k, q+1] - r * (U[k+1, q+1] + U[k-1, q+1]) + 2 * r * U[k, q+1] \
- r * U[k, q+1] * U[k+1, q+1]**2 + r * U[k+1, q+1]**2 * U[k, q+1] - r * U[k, q+1]**3
updiag = -r - 2 * r * U[p, q + 1] * U[p+1, q + 1] + 2 * r * U[p, q + 1]**2
diag = 1 + 2 * r + 3 * r * U[p, q + 1]**2 - 4 * r * U[p+1, q + 1] * U[p+1, q+1] - 2 * r * U[p, q + 1]**2
lowdiag = r
Jdata = np.array([31 * [diag], 31 * [lowdiag], 31 * [updiag]])
Diags = [0, -1, 1]
J = spdiags(Jdata, Diags, 31, 31).toarray()
d = inv(J) * f
u = U[:, q+1]
u = u + d
U[1, q + 1] = 0
U[M, q + 1] = 0
T, X = np.meshgrid(t, x)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(T, X, U, cmap=cm.coolwarm)
ax.set_xlabel('t')
ax.set_ylabel('x')
ax.set_zlabel('u(x, t)')
plt.tight_layout()
plt.savefig('BDImplSol.pdf', bbox_inches='tight')
plt.show()
Edit Discretisation formula:
$$ U_i^{n + 1} = U_i^n + r \left(\left(U_{i+1}^{n+1} - 2 U_i^{n+1} + U_{i-1}^{n+1} \right) + U_i^{n + 1} \left(U_{i + 1}^{n + 1} - U_i^{n+1} \right)^2 \right) $$ $$ r = \frac{dt}{dx^2} $$