using Plots, LaTeXStrings, Printf
plot_ρ(x,ρ,t) = plot(x, ρ, ylim=[0.0,1.5],
=@sprintf("t = %0.3f", t),
title=2,thickness_scaling = 1.5,label="") linewidth
plot_ρ (generic function with 1 method)
Métodos Numéricos Avanzados. 2023-2024
La ecuación de Burgers corresponde a un fluido que se mueve con velocidad \(v = \rho/2\), es decir \(F = v \rho\) y
\[ \frac{\partial \rho}{\partial t} = - \frac{\partial}{\partial x} \frac {\rho^2} 2 \]
El \(2\) procede de \(\frac{\partial \rho}{\partial t} =- \rho \frac{\partial \rho }{\partial x}\).
\[ \rho_0 = \min\Big(1,\max(2-4|x|,0)\Big) \]
using Plots, LaTeXStrings, Printf
plot_ρ(x,ρ,t) = plot(x, ρ, ylim=[0.0,1.5],
=@sprintf("t = %0.3f", t),
title=2,thickness_scaling = 1.5,label="") linewidth
plot_ρ (generic function with 1 method)
= 64;
N = range(-1.0,1.0,N+1); x = vec(x[1:end-1])
x = x[2] - x[1]
Δx ρ0(x) = min.(1,max.(-4*abs.(x).+2,0))
plot_ρ(x,ρ0(x),0)
Si intentamos buscar soluciones exactas \(\rho_t (X_t ) = \rho_0 (y)\) deducimos que \[ \frac{dX_t}{dt} (t) = \rho_0(y) \]
Luego \(\rho_t (y + \rho_0(y) t) = \rho_0(y)\)
= copy(x)
y
@gif for t=0:0.01:2
plot_ρ( y + ρ0(y)*t , ρ0(y), t )
end
Las características ya no son paralelas. ¡Se cortan y aparecen discontinuidades!
Si a un punto \((x,t)\) llegan dos características, es decir \(x = y_1 + \rho_0(y_1) t = y_2 + \rho_0(y_2) t,\)
para calcular \(\rho_t (x)\) tengamos que elegir entre \(\rho_0(y_1)\) y \(\rho_0(y_2)\).
Escribimos método de Euler explícito para el tiempo y up-winding tomando como aproximación de la velocidad \[v_{i+\frac 1 2} = \frac 1 2 \left( \alpha \rho_i + (1-\alpha)\rho_{i+1}\right)\] para algún \(\alpha \in (0,1)\).
Nótese que \(v_{i+\frac 1 2} \ge 0\) si \(\rho_i \ge 0\). De manera que el up-winding se simplifica.
Resulta el método \[ \rho_{i}^{n+1} = \rho_i^n - \frac{\Delta t}{2 \Delta x} \left( {\rho_i^n} \left( \alpha \rho_i^n + (1-\alpha)\rho_{i+1}^n \right) - {\rho_{i-1}^n} \left( \alpha \rho_{i-1}^n + (1-\alpha)\rho_{i}^n \right) \right) \]
Ejercicio. Calcular una condición CFL heredada del caso de velocidad constante:
Puesto que \(0 \le v_{i+\frac 1 2} (t) \le \frac {\max_i \rho_i (t)} 2\)
una condición CFL del método de velocidad constante sería
\[ \frac {\max_i \rho_i (t)} 2\frac{\Delta t}{\Delta x} \le 1 \]
Dado que la solución exacta cumple \(0 \le \rho_t \le 1\),
cabe esperar que \(\frac 1 2 \frac{\Delta t}{\Delta x} \le 1\) sea suficiente.
Experimento numérico.
Calcular la solución numérica con \(\alpha = \frac 1 2\), y responder a la siguientes preguntas:
¿Es suficiente esta condición CFL para que el método converja?
¿Es posible calcular una condición CFL para este problema?
El método de Euler explícito con \(\alpha = \frac 1 2\) resulta \[ \rho_{i}^{n+1} = \rho_i^n - \frac{\Delta t}{4 \Delta x} \left( {\rho_i^n} \left( \rho_i^n + \rho_{i+1}^n \right) - {\rho_{i-1}^n} \left( \rho_{i-1}^n + \rho_{i}^n \right) \right) \]
= 2
T = Δx;
Δt = ρ0(x);
ρ
= zeros(N,1); #F[i] = F_{i+\frac 1 2}
F @gif for n=0:ceil(T/Δt)
plot_ρ(x, ρ, n*Δt)
1:end-1]= ρ[1:end-1].*
F[1:end-1] + ρ[2:end])/4
(ρ[end] = ρ[end]*(ρ[end] + ρ[1])/4
F[
1] -= Δt/Δx*( F[1] - F[end] )
ρ[2:end] -= Δt/Δx*( F[2:end] - F[1:end-1] )
ρ[end
Las oscilaciones producen que se pierda CFL.
Así \(\rho_i\) deja de ser positivo.
De forma que estamos perdiendo el up-winding, y violando la condición CFL.
Nótese que \(\overline \rho_i^n = 1\) es solución del método.
Las soluciones exactas cumplen \(\rho(t) \le \overline \rho = 1\) (principio de comparación).
Aunque se tiene CFL y \(\rho_0 \le 1\), no se tiene \(\rho_i^n \le \overline \rho_i^n = 1\).
Esto se conoce como pérdida de la monotonía.
¿Cómo preservar la monotonía en un método explícito?
Tomemos un método explícito genérico
\[ \rho_i^{n+1} = H(\rho_{i+1}^n,\rho_i^n, \rho_{i-1}^n). \]
Supongamos que \(\rho_i^n \le 1\) para todo \(i\), entonces queremos que
\[ 1 \ge \rho_{i}^{n+1} = H(\rho_{i+1}^n, \rho_{i-1}^n, \rho_{i-1}^n). \]
Para preservar la monotonía, \(H\) debe ser monótona no-decreciente en cada componente.
Si \(v_{i+\frac 1 2}\) es combinación de \(\rho_i\) y \(\rho_{i+1}\) teníamos que \[ \rho_{i}^{n+1} = \rho_i^n - \frac{\Delta t}{\Delta x} \left( {\rho_i^n}\dfrac{\alpha \rho_i^n + (1-\alpha)\rho_{i+1}^n}{2} - {\rho_{i-1}^n}\dfrac{\alpha \rho_{i-1}^n + (1-\alpha)\rho_{i}^n}{2} \right) \]
Luego \[ H(p,q,r) = \left( 1 - \frac{\Delta t}{\Delta x} \frac{ {(1-\alpha) p + \alpha q}}{2} \right)q + \frac{\Delta t }{\Delta x} \frac{{(1-\alpha) q + \alpha r}}{2} r \]
Volvemos sobre \[ H(p,q,r) = \left( 1 - \frac{\Delta t}{\Delta x} \frac{ {(1-\alpha) p + \alpha q}}{2} \right)q + \frac{\Delta t }{\Delta x} \frac{{(1-\alpha) q + \alpha r}}{2} r \]
Debemos pedir que \[ 0 \le \frac{\partial H}{\partial p} = - \frac{\Delta t}{\Delta x} \frac{{1-\alpha}}{2} q \]
Necesariamente \(\alpha = 1\). Reducimos la fórmula a este caso
\[ H(p,q,r) = \left( 1 - \frac{\Delta t}{\Delta x} \frac q 2 \right)q + \frac{\Delta t }{\Delta x} \frac{r^2}{2}. \]
Debemos pedir también que \[ 0 \le \frac{\partial H}{\partial q} = 1 - \frac{\Delta t}{\Delta x} q \]
Esta condición dice que para todo \(i\) \[ \frac{\Delta t}{\Delta x} \rho_i^n \le 1. \] ¡Más exigente que CFL!
Por último \[ 0 \le \frac{\partial H}{\partial r} = \frac{\Delta t}{\Delta x} r \] que no impone nada nuevo.
Concluimos que el método monótono es \[ \rho_{i}^{n+1} = \rho_i^n - \frac{\Delta t}{\Delta x} \left( \frac{(\rho_i^n)^2}{2} - \frac{(\rho_{i-1}^n)^2}{2} \right) \] Y añadimos la condición CFL \(\Delta t \le \frac{\Delta x}{\max_i \rho_i^0}\).
Ejercicio. Programar el método anterior añadiendo condiciones de contorno periódicas
= Δx; # Condición de monotonía
Δt = ρ0(x);
ρ @gif for n=0:ceil(T/Δt)
global ρ
plot_ρ(x, ρ, n*Δt)
= ρ.^2/2 # puesto que v > 0.
F
1] -= Δt/Δx * ( F[1] - F[end] ) # Condición periódica
ρ[2:end] -= Δt/Δx * ( F[2:end] - F[1:end-1] )
ρ[end
En general, se pueden estudiar leyes de conservación de la forma \[ \frac{\partial \rho}{\partial t} + \frac{\partial}{\partial x} \Phi(\rho) = 0, \] es decir \(F = \Phi (\rho)\).
No siempre es necesario verlas como problemas de transporte donde \(F = \rho \frac{\Phi(\rho)}{\rho}\)
(es decir \(v = \frac{\Phi(\rho)}{\rho}\)).
Se pueden construir esquemas monótonos con aproximaciones monótonas del flujo, sin tener necesariamente en cuenta el up-winding de la ecuación de transporte. En tal caso \[ F_{i+\frac 1 2} = g_{i+\frac 1 2}^{n+1} ( \rho_1, \cdots, \rho_M ) . \]
Estos métodos son consistentes si \[ g_{i+\frac 1 2} (s, \cdots, s) = \Phi (s) . \] Habitualmente, \(g\) no depende de todas las componentes de \(\rho\), si no de una cantidad finita.
Se habla de estas elecciones según el número de punto. Típicamente la fórmula de \(g\) no cambia. Por ejemplo, un método de 3 puntos resulta \[ \rho_i^{n+1} = \rho_i^n - \frac{\Delta t}{\Delta x} \Big( g(\rho_{i+1}^{n} ,\rho_i^n ) - g(\rho_{i}^{n} ,\rho_{i-1}^n ) \Big) \]
El método es monótono si y sólo si \[ \frac{\partial g}{\partial a} \le 0, \qquad \frac{\partial g}{\partial b} \ge 0, \]
y, además, se cumple la condición \[ \frac{\Delta t}{\Delta x} \left( \frac{\partial g}{\partial b} (\rho_{i+1}^n, \rho_i^n) - \frac{\partial g}{\partial a} (\rho_{i}^n, \rho_{i-1}^n) \right) \le 1 . \]
Ver [Eymard, Gallouët & Herbin, 2000]
Esquema de flux-splitting. Si podemos escribir \(f = f_1 + f_2\) con \(f_1' \ge 0 \ge f_2'\) entonces \[ g(a,b) = f_1(a) + f_2(b). \] Entendiendo el problema como una ley de transporte, es decir \(F = \rho v\) y \(v = \frac{ \Phi(\rho) }{\rho}\), se observa que el up-winding corresponde a la descomposición \(f_1(s) = (\Phi(s))_+\) y \(f_2 (s) = (\Phi(s))_-\).
Esquema de Godunov. Se toma \[ g(a,b) = \begin{dcases} \min_{[a,b]} f & \text{si } a \le b , \\ \max_{[a,b]} f & \text{si } a > b. \end{dcases} \]
Esquema de Lax-Friedrichs modificado: se toma \[ g(a,b) = \frac{f(a) + f(b)}{2} + D(a-b) \] donde \(2 D \ge |f'(s)|\).
La versión implícita del método anterior es \[ \rho_{i}^{n+1} = \rho_i^n - \frac{\Delta t}{\Delta x} \left( \frac{(\rho_i^{n+1})^2}{2} - \frac{(\rho_{i-1}^{n+1})^2}{2} \right) \]
Es decir, en cada paso queremos resolver un sistema de ecuaciones.
Planteado como ecuación no lineal \[ h(\xi) = 0 \qquad \text{ donde } h_i (\xi) = -\rho_i^n + \xi_{i} + \frac{\Delta t}{\Delta x} \left( \frac{(\xi_i)^2}{2} - \frac{(\xi_{i-1})^2}{2} \right) \]
Para resolver \(f(\xi) = 0\) el método de Newton propone resolver el problema linealizado \[ h(\xi^n) + Dh(\xi^n) (\xi^{n+1} - \xi^n ) = 0. \]
Es decir \[ \xi^{n+1} = \xi^n - [Dh(\xi^n)]^{-1} h(\xi^n). \]
Normalmente iteramos hasta que \(\max_i|\xi_i^n - \xi_i^{n+1}| < \mathrm{tol}.\)
function fixed_point(ρ,h,Dh)
= 1e-5; max_iter = 1e3
tol = copy(ρ)
ρn = 1
iter = ones(size(ρ))
δ while (maximum(abs.(δ)) > tol) & (iter < max_iter)
= Dh(ρ,ρn) \ h(ρ,ρn)
δ = ρ - δ
ρ += 1
iter end
if (iter == max_iter)
warning("Punto fijo no convergió")
end
return ρ
end;
Nosotros queremos resolver \[ h(\xi) = 0 \qquad \text{ donde } h_i (\xi) = -\rho_i^n + \xi_{i} + \frac{\Delta t}{\Delta x} \left( \frac{(\xi_i)^2}{2} - \frac{(\xi_{i-1})^2}{2} \right) \]
Luego \[ \frac{\partial h_i}{\partial \xi_i} = 1 + \frac{\Delta t}{\Delta x} \xi_i \qquad \qquad \frac{\partial h_i}{\partial \xi_{i-1}} = - \frac{\Delta t}{\Delta x} \xi_{i-1} \]
Es decir \[ Dh(\xi) = I + \frac{\Delta t}{\Delta x} \begin{pmatrix} 1 & 0 &\cdots & -1\\ -1 & 1 \\ &&\ddots \\ &&& - 1& 1 \end{pmatrix} \begin{pmatrix} \rho_1 \\ & \rho_2 \\ &&& \ddots \\ &&&&\rho_N \end{pmatrix} \]
Escribimos las derivadas de h
= length(x)
N = zeros(N,N)
D 1,N] = -Δt/Δx
D[for i=1:N D[i,i] = +Δt/Δx end
for i=2:N D[i,i-1] = -Δt/Δx end
using LinearAlgebra
= Matrix(1.0I, N, N)
Id
h(ρ,ρn) = ρ + D * ρ.^2/2 - ρn
Dh(ρ,ρn) = Id + D * Diagonal(ρ);
Y lanzamos el método
= ρ0(x);
ρ @gif for n=0:ceil(T/Δt)
global ρ
plot_ρ(x, ρ, n*Δt)
= fixed_point(ρ,h,Dh)
ρ end
La ecuación de Burgers puede formar discontinuidades. Una forma de evitarlo es añadir un término “viscoso” \[ \frac{\partial \rho}{\partial t} + \frac{\partial}{\partial x} \frac{\rho^2}{2} = \varepsilon \Delta \rho \] Al límite \(\varepsilon \to 0\) se lo llama de vanishing viscosity
Un método de Euler explícito en este caso \[ \frac{\rho_{i}^{n+1} - \rho_i^n}{\Delta t} + \frac{ \frac{(\rho_i^n)^2}{2} - \frac{(\rho_{i-1}^n)^2}{2}}{\Delta x} = \varepsilon \frac{ \rho_{i+1}^n - 2 \rho_i^n + \rho_{i-1}^n }{(\Delta x)^2} \]
Empleando las técnicas anteriores, el método es monótono si \[ 2 \varepsilon \frac{\Delta t}{(\Delta x)^2} + \rho_i^n \frac{\Delta t}{\Delta x} \le 1. \]
= 5e-2
ϵ = 64;
N = range(-1.0,1.0,N+1); x = vec(x[1:end-1])
x = x[2] - x[1]
Δx
= 0.9 / ( 2 * ϵ / (Δx)^2 + 1 / (Δx) ) ; # Condicion de monotonía
Δt = ρ0(x);
ρ @gif for n=0:ceil(T/Δt)
global ρ
plot_ρ(x, ρ, n*Δt)
title!(latexstring(@sprintf("\\varepsilon =%0.3f, \\quad t = %0.3f", ϵ, (n-1)*Δt)))
= copy(ρ)
ρn
= ρn.^2/2 # puesto que v > 0.
F
per(n) = mod(n-1,N)+1
= ρ - Δt/Δx * ( F - F[per.(0:N-1)] ) + ϵ*Δt/((Δx)^2)*( ρn[per.(2:N+1)] - 2*ρ + ρ[per.(0:N-1)] )
ρ end
Otra opción es hacer el método implícito en la difusión \[ \frac{\rho_{i}^{n+1} - \rho_i^n}{\Delta t} + \frac{ \frac{(\rho_i^n)^2}{2} - \frac{(\rho_{i-1}^n)^2}{2}}{\Delta x} = \varepsilon \frac{ \rho_{i+1}^{n+1} - 2 \rho_i^{n+1} + \rho_{i-1}^{n+1} }{(\Delta x)^2} \]
= 5e-2
ϵ = 128
N = 1
T
= range(-1.0,1.0,N+1); x = vec(x[1:end-1])
x = x[2] - x[1]
Δx
= Δx ;
Δt
= length(x)
N = zeros(N,N)
D 1,N] = -Δt/Δx
D[for i=1:N D[i,i] = +Δt/Δx end
for i=2:N D[i,i-1] = -Δt/Δx end
= zeros(N,N)
D2 1,N] = -1
D2[for i=1:N D2[i,i] = +2 end
for i=2:N D2[i,i-1] = -1 end
for i=1:N-1 D2[i,i+1] = -1 end
1] = -1
D2[N,
using LinearAlgebra
= Matrix(1.0I, N, N)
Id
= Id + ϵ*Δt/((Δx)^2)*D2
A
= ρ0(x);
ρ @gif for n=0:ceil(T/Δt)
global ρ
plot_ρ(x, ρ, n*Δt)
title!(latexstring(@sprintf("\\varepsilon =%0.3f, \\quad t = %0.3f", ϵ, (n-1)*Δt)))
= ρ.^2/2 # puesto que v > 0.
F
= A \ ( ρ - D*F )
ρ end