La ecuación de advección necesita ser discretizada para ser utilizada para el método de Crank-Nicolson. ¿Alguien puede mostrarme cómo hacer eso?
La ecuación de advección necesita ser discretizada para ser utilizada para el método de Crank-Nicolson. ¿Alguien puede mostrarme cómo hacer eso?
Respuestas:
Comenzando con la ecuación de advección es de forma conservadora,
El método de Crank-Nicolson consiste en una diferencia centrada promediada en el tiempo.
Con respecto a la notación, los subíndices son para puntos en el espacio, y los superíndices son para puntos en el tiempo.
Los puntos en están en el futuro: son incógnitas. Ahora tenemos que reorganizar la ecuación anterior para que todos los conocimientos estén en la derecha y las incógnitas estén en la derecha.
Haciendo la sustitución,
da,
Esta es la ecuación de advección discretizada utilizando el método de Crank-Nicolson. Puedes escribirlo como una ecuación matricial,
Algunas palabras de advertencia. Esta es la solución básica que deseaba, pero deberá incluir algún tipo de condición límite para un problema bien planteado. Además, Crank-Nicolson no es necesariamente el mejor método para la ecuación de advección. Es de segundo orden preciso e incondicionalmente estable , lo cual es fantástico. Sin embargo, generará (como con todas las plantillas de diferencia centrada) una oscilación espuria si tiene soluciones puntuales muy agudas o condiciones iniciales.
Escribí el siguiente código para usted en Python, debería ayudarlo a comenzar. El código resuelve la ecuación de advección para una curva gaussiana inicial que se mueve hacia la derecha con velocidad constante.
from __future__ import division
from scipy.sparse import spdiags
from scipy.sparse.linalg import spsolve
import numpy as np
import pylab
def make_advection_matrices(z, r):
"""Return matrices A and M for advection equations"""
ones = np.ones(len(z))
A = spdiags( [-beta*r, ones, beta*r], (-1,0,1), len(z), len(z) )
M = spdiags( [(1-beta) * r, ones, -(1-beta) * r], (-1,0,1), len(z), len(z) )
return A.tocsr(), M.tocsr()
def plot_iteration(z, u, iteration):
"""Plot the solver progress"""
pylab.plot(z, u, label="Iteration %d" % iteration)
# Set up basic constants
beta = 0.5
J = 200 # total number of mesh points
z = np.linspace(-10,10,J) # vertices
dz = abs(z[1]-z[0]) # space step
dt = 0.2 # time step
v = 2 * np.ones(len(z)) # velocity field (constant)
r = v / 2 * dt / dz
# Initial conditions (peak function)
gaussian = lambda z, height, position, hwhm: height * np.exp(-np.log(2) * ((z - position)/hwhm)**2)
u_init = gaussian(z, 1, -3, 2)
A, M = make_advection_matrices(z, r)
u = u_init
for i in range(10):
u = spsolve(A, M * u)
plot_iteration(z, u, i)
pylab.legend()
pylab.show()