Elementos Finitos en \(d=1\)
Métodos Numéricos Avanzados. 2022-2023
Formulación débil
Integración por partes
\[ \newcommand{\diff}{\mathrm{d}} \]
Recordamos que \[ \frac{\partial}{\partial x} \left( v \frac{\partial u}{\partial x} \right) = \frac{\partial v}{\partial x} \frac{\partial u}{\partial x} + v \frac{\partial^2 u}{\partial x^2} \]
Integrando \[ v(1) \frac{\partial u}{\partial x}(t,1) - v(-1) \frac{\partial u}{\partial x}(t,-1) = \int_{-1}^1 \frac{\partial v}{\partial x} (x) \frac{\partial u}{\partial x}(t,x) \diff x + \int_{-1}^1 v(x) \frac{\partial^2 u}{\partial x^2} (t,x) \diff x \]
Un momento de teoría
Si \(v\) es una función Lipschitz, entonces es derivable en casi todo punto. Y denotamos \(\frac{\diff v}{\diff x}\).
Esta derivada (a veces llamada “débil”) sigue teniendo la propiedad de integración por partes: si \(u\) es de clase \(C^2\) entonces \[ v(1) \frac{\partial u}{\partial x}(t,1) - v(-1) \frac{\partial u}{\partial x}(t,-1) = \int_{-1}^1 \frac{\partial v}{\partial x} (x) \frac{\partial u}{\partial x}(t,x) \diff x + \int_{-1}^1 v(x) \frac{\partial^2 u}{\partial x^2} (t,x) \diff x \]
El espacio de funciones Lipschitz es un ejemplo de los llamados espacios de Sobolev. Denotaremos \[ W^{1,\infty}_0 (-1,1) = \{ v \in C([-1,1]) \text{ Lipschitz tal que } v(-1) = v(1) = 0 \}. \]
Ejemplo. Ecuación de calor con condiciones Dirichlet
Volvemos sobre la ecuación de calor \[ \tag{C} \label{eq:calor} \frac{\partial u}{\partial t} = \Delta u + f(t,x) \]
Tomemos \(\eqref{eq:calor}\) en \((-1,1)\) con condiciones de Dirichlet homogéneas \(u(t,-1) = u(t,1) = 0\). La solución exacta de la ecuación satisface que para toda \(v\) Lipscthitz se tiene
\[ \int_{-1}^1 \frac{\partial u}{\partial t} v = \int_{-1}^1 (\Delta u) v + \int_{-1}^1 f v \]
Si \(v(\pm 1) = 0\) podemos integrar por partes llegamos a la llamada llamada formulación débil \[ \int_{-1}^1 \frac{\partial u}{\partial t} v = - \int_{-1}^1 \frac{\partial u}{\partial x} \frac{\partial v}{\partial x} + \int_{-1}^1 f v , \qquad \forall v \in W_0^{1,\infty} (\Omega). \]
Ejemplo. Ecuación de calor con condiciones Neumann
Tomemos \(\eqref{eq:calor}\) en \((-1,1)\) con condiciones de Neumann homogéneas \(\frac{\partial u}{\partial x}(t,-1) = \frac{\partial u}{\partial x}(t,1) = 0\). La solución exacta de la ecuación satisface que para toda \(v\) Lipscthitz se tiene
\[ \int_{-1}^1 \frac{\partial u}{\partial t} v = \int_{-1}^1 (\Delta u) v + \int_{-1}^1 f v \]
Podemos integrar por partes incluso si \(v(\pm 1) \ne 0\) a la llamada llamada formulación débil \[ \int_{-1}^1 \frac{\partial u}{\partial t} v = - \int_{-1}^1 \frac{\partial u}{\partial x} \frac{\partial v}{\partial x} + \int_{-1}^1 f v , \qquad \forall v \in W^{1,\infty} (\Omega). \]
Método de Galerkin
Un problema en dimensión finita
Elegimos funciones de ``base’’ \[ \varphi^h_1, \cdots, \varphi^h_N \]
y queremos buscar una aproximación \(u(t,x) \sim u^{h} (t,x)\) donde \[ \tag{U} \label{eq:uh} u^{h} (t,x)= \sum_{j=1}^N u_j^h (t) \varphi^h_j (x). \]
Estas funciones \(\varphi^h_i\) generan un sub-espacio vectorial en el espacio de funciones, que llamamos \(V^h\). Se busca \[ u^h (t) \in V^h = \mathrm{span} \{ \varphi^h_1, \cdots, \varphi^h_N \}. \]
Sin pérdida de generalidad consideramos que son linealmente independiente, eliminando en las que sean necesario para construir un base, y cambiándolo los índices.
Ejemplo. Ecuación de calor con condiciones Dirichlet
Volvemos sobre \(\eqref{eq:calor}\) en \(t > 0\) y \(x \in (-1,1)\) con condiciones de Dirichlet homogéneas \(u(t,-1) = u(t,1) = 0\).
La solución exacta es la única curva \(t \mapsto u(t) \in C^2([-1,1] ) \cap C_0([-1,1])\) tal que \[ \int_{-1}^1 \frac{\partial u}{\partial t} v = - \int_{-1}^1 \frac{\partial u}{\partial x} \frac{\partial v}{\partial x} + \int_{-1}^1 f v , \qquad \forall v \in W_0^{1,\infty}([-1,1]) \]
Como aproximación numérica buscamos un espacio \(V^h \subset W_0^{1,\infty} (-1,1)\) y la única curva \(t \mapsto u^h(t) \in V^h\) tal que \[ \int_{-1}^1 \frac{\partial u^h}{\partial t} v = - \int_{-1}^1 \frac{\partial u^h}{\partial x} \frac{\partial v}{\partial x} + \int_{-1}^1 f v \diff x , \qquad \forall v \in V^h. \]
Como \(V^h\) es un espacio de dimensión finita, esto es equivalente a que
\[ \int_{-1}^1 \frac{\partial u^h}{\partial t} \varphi_i^h = - \int_{-1}^1 \frac{\partial u^h}{\partial x} \frac{\partial \varphi_i^h}{\partial x} + \int_{-1}^1 f \varphi_i^h \diff x , \qquad \forall i = 1, \cdots, N. \]
Volviendo sobre \(\eqref{eq:uh}\) tenemos \[ \sum_{j=1}^N \frac{\diff u_j^h}{\diff t} (t) \int_{-1}^1 \varphi_j^h \varphi_i^h = - \sum_{j=1}^N u_j^h(t) \int_{-1}^1 \frac{\partial \varphi_j^h}{\partial x} \frac{\partial \varphi_i^h}{\partial x} + \int_{-1}^1 f(t,x) \varphi_i^h (x) \diff x. \]
Llegamos a un sistema de la forma \[ M^h \frac{\diff }{\diff t} \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} = - A^h \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} + b^h (t) \]
donde \[ M^h_{ij} = \int_{-1}^1 \varphi_j^h \varphi_i^h , \qquad A_{ij}^h = \int_{-1}^1 \frac{\diff \varphi_j^h}{\diff x} \frac{\diff \varphi_i^h}{\diff x}, \qquad b_i^h (t) = \int_{-1}^1 f(t,x) \varphi_i^h (x) \diff x . \]
Dado que los elementos de la base son linealmente independiente, la matriz \(M^h\) es no singular. Por tanto, podemos escribir \[ \frac{\diff }{\diff t} \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} = - (M^h)^{-1} A^h \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} + (M^h)^{-1} b^h(t) \] Este problema evolutivo tiene siempre solución.
Concluímos así la semi-discretización espacial. Vamos a estudiar las buenas propiedades que tiene este método, empezando por el problema estacionario asociado.
Ejemplo: ecuación de Laplace con condiciones Dirichlet
Consiste en encontrar soluciones estacionarias (e.d. independientes del tiempo) de la ecuación de calor, es decir buscamos un único vector \(u^h \in \mathbb R^N\) tal que \[ A^h \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} = b^h \]
Marco abstracto
Sea \(A: H \to H\) un operador lineal, donde \(H\) tiene un producto escalar \((\cdot, \cdot)_H\).
Para estudiar el problema evolutivo
\[ \frac{\diff}{\diff t} u = - A u \]
Siempre podemos escoger una base y escribir \(\eqref{eq:uh}\).
Repitiendo el razonamiento anterior, donde \(Au = - \Delta u - f\), tenemos \[ M^h \frac{\diff }{\diff t} \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} = - A^h \begin{pmatrix} u_1^h \\ \vdots \\ u^N_h \end{pmatrix} \]
La matriz \(M^h\) se suele llamar matriz de masa, y \(A^h\) se llama matriz de rigidez. Esto tiene que ver con los problemas de cuarto orden que aparecen en elasticidad.
donde \[ M^h_{ij} = (\varphi_j^h, \varphi_i^h)_H , \qquad A_{ij}^h = - (A \varphi_j, \varphi_i)_H. \]
Observación Se puede extender esta formulación a un problema no-lineal.
Método de elementos finitos
El método de elementos finitos consiste en:
Dividir el dominio en poliedros (es decir, crear una malla)
Tomar como funciones de base funciones que son polinomios de un grado \(g\) dado en cada elemento
Para esta sección recomendamos la bibliografía: Ramos (2012), Süli (2020)
En dimensión 1
En dimensión 1, esto significa tomar puntos \[ a = x_0^h < x_1^h < \dots < x_{M+1}^h = b. \]
Sobre esta malla se toma el espacio de las funciones de polinomios de grado \(g\) a trozos.
Si introducimos condiciones de tipo Dirichlet, entonces añadimos esta condiciones al espacio: \[ V^h = \{ v^h \in C_0 ([-1,1]) : v^h|_{[x_i, x_{i+1}]} \text{ es polinomio de grado } g \} \] Este espacio se denota, a veces, como \(V_g^h\).
La base de funciones de funciones lineales a trozos
Es muy habitual tomar \(g = 1\), es decir funciones continuas y lineales a trozos.
Como las funciones son lineales, para determinar una de ellas nos basta con determinar los valores \(v^h(x_i)\).
Elegimos la base de funciones tales que \(\varphi_i(x_j) = \delta_{ij}\).
En tal caso, se cogen las funciones de base lineales a trozos \[ \varphi_i (x) = \begin{dcases} \left( \frac{x-x_{i-1}}{x_i - x_{i-1}} \right)_+ & x \le x_i , \\ \left( \frac{x_{i+1}-x}{x_{i+1} - x_i} \right)_+ & x > x_i , \\ \end{dcases}, \]
Matriz de rigidez para el Laplaciano con condiciones Dirichlet
Como las condiciones son Dirichlet podemos tomar el espacio \[ V^h = \mathrm{span} \{ \varphi_1, \cdots, \varphi_M \}. \]
Si la malla es uniforme \(x_{i+1} - x_i = \Delta x\) y tomamos condiciones Dichlet \[ \int_{-1}^1 \frac{\partial \varphi_i^h}{\partial x} \frac{\partial \varphi_j^h}{\partial x} = \frac 1 {\Delta x} \begin{cases} 2 & i = j \\ {-1} & |i-j| = 1, \\ 0 & |i-j| > 1. \end{cases} \]
Acabamos con la famosa matriz para el problema de Dichilet \[ A^h = \frac{1}{\Delta x} \begin{pmatrix} 2 & - 1 & \\ -1 & 2 & -1 \\ && \ddots \\ && -1 & 2 \end{pmatrix} \]
No calcularemos analíticamente la matriz \(M^h\) ahora.
Observación. En el método de diferencias finitas la matriz tiene factor \((\Delta x)^2\). Pero el vector \[ b_i^h(t) = \int_{-1}^1 f(t,x) \varphi_i^h(x) \diff x \sim \Delta x \]
Matriz de rigidez para el Laplaciano con condiciones Neumann
Como las condiciones son Neumann podemos tomar el espacio \[ V^h = \mathrm{span} \{ \varphi_0, \varphi_1, \cdots, \varphi_M, \varphi_{M+1} \}. \]
Para los puntos interiores los la integrales son iguales. Para los puntos de borde \[ \int_{-1}^1 \frac{\partial \varphi_0}{\partial x}\frac{\partial \varphi_0}{\partial x} = \frac 1 {\Delta x} \qquad \int_{-1}^1 \frac{\partial \varphi_0}{\partial x}\frac{\partial \varphi_1}{\partial x} = \frac {-1} {\Delta x} \]
Se tiene la matriz \[ A^h = \frac{1}{\Delta x} \begin{pmatrix} 1 & - 1 & \\ -1 & 2 & -1 \\ && \ddots \\ && -1 & 1 \end{pmatrix} \]
Cálculo simbólico
El paquete SymPy.jl
Utilizaremos una librería de Python sympy
. Debemos tener instalado python en el sistema
En MacOS / Linux ejecutar en terminal
$ pip3 install sympy
Y luego en la interfaz en Julia
using Pkg; Pkg.add("SymPy")
En Windows si Python está instalado mediante Anaconda, el cálculo simbólico explicado abajo sólo funcionará en libreta de Jupyter. En una libreta de Jupyter escribir
using Pkg; Pkg.add("SymPy")
Función lineal a trozos para puntos equiespaciados
Son un desplazamiento de
using SymPy, Plots, LaTeXStrings
= symbols("x", real=true)
x
= sympy.Piecewise(
Φ 1 + x , And(Ge(x,-1),Le(x, 0))) ,
( 1 - x, And(Le(x,1),Gt(x, 0))),
( 0, True))
(
display(Φ)
plot(Φ,xlim=(-2.0, 2.0), label=L"\Phi", thickness_scaling=1.5, linewidth=2)
⎧x + 1 for x ≥ -1 ∧ x ≤ 0
⎪
⎨1 - x for x ≤ 1 ∧ x > 0
⎪
⎩ 0 otherwise
Problema con condiciones Dirichlet
Funciones de base lineales a trozos con condiciones de Dirichlet
Tomamos la malla \[ x_0 = -1 < x_1 = -1+\Delta x < \cdots < x_{M+1} = 1 \] Las condiciones de Dirichlet homogéneas nos dicen que los valores \(u^h(t,\pm 1)=0\), luego las incógnitas son \(u_1^h, \cdots, u_N^h\).
Construímos las funciones de base lineales a trozos en los puntos que son incógnitas
= 2.0^(-2)
Δx = (-1.0 + Δx):Δx:(1.0-Δx)
xx = length(xx);
NN
φ = subs.(Φ , x , x/Δx .- xx/Δx )
display(φ[1]);
⎧4.0⋅x + 4.0 for 4.0⋅x + 3.0 ≥ -1 ∧ 4.0⋅x + 3.0 ≤ 0
⎪
⎨-4.0⋅x - 2.0 for 4.0⋅x + 3.0 ≤ 1 ∧ 4.0⋅x + 3.0 > 0
⎪
⎩ 0 otherwise
= plot(xlim=(-1,1),thickness_scaling=1.5,legend=:outerright,
p =L"x",ylabel=L"u")
xlabelfor i=1:length(xx)
=plot!(φ[i], label=latexstring("\\varphi_{$(i)}"),linewidth=2)
pend
plot(p)
Matriz de masa con condiciones de Dirichlet
Con esta elección, el cálculo de las matrices \[ M_{ij} = \int_a^b \varphi_j \varphi_i , \qquad A_{ij} = \int_a^b \frac{\diff \varphi_j}{\diff x} \frac{\diff \varphi_i}{\diff x} \] puede hacerse de forma analítica.
Primero la matriz de masa
= zeros(NN,NN)
M for i=1:NN, j=maximum([i-1,1]):minimum([i+1,NN])
= integrate(φ[i]*φ[j],(x,-1.0,1.0))
M[j,i] end
M
7×7 Matrix{Float64}:
0.166667 0.0416667 0.0 0.0 0.0 0.0 0.0
0.0416667 0.166667 0.0416667 0.0 0.0 0.0 0.0
0.0 0.0416667 0.166667 0.0416667 0.0 0.0 0.0
0.0 0.0 0.0416667 0.166667 0.0416667 0.0 0.0
0.0 0.0 0.0 0.0416667 0.166667 0.0416667 0.0
0.0 0.0 0.0 0.0 0.0416667 0.166667 0.0416667
0.0 0.0 0.0 0.0 0.0 0.0416667 0.166667
Matriz de rigidez con condiciones de Dirichlet
Para construir la matriz de rigidez calculamos primero las derivadas simbólicas
= diff.(φ,x)
Dφ display(Dφ[1])
⎧4.0 for 4.0⋅x + 3.0 ≥ -1 ∧ 4.0⋅x + 3.0 ≤ 0
⎪
⎨-4.0 for 4.0⋅x + 3.0 ≤ 1 ∧ 4.0⋅x + 3.0 > 0
⎪
⎩ 0 otherwise
Calculamos la matriz de rigidez
= zeros(NN,NN)
A for i=1:NN, j=maximum([i-1,1]):minimum([i+1,NN])
= integrate(Dφ[i]*Dφ[j],(x,-1.0,1.0))
A[j,i] end
A
7×7 Matrix{Float64}:
8.0 -4.0 0.0 0.0 0.0 0.0 0.0
-4.0 8.0 -4.0 0.0 0.0 0.0 0.0
0.0 -4.0 8.0 -4.0 0.0 0.0 0.0
0.0 0.0 -4.0 8.0 -4.0 0.0 0.0
0.0 0.0 0.0 -4.0 8.0 -4.0 0.0
0.0 0.0 0.0 0.0 -4.0 8.0 -4.0
0.0 0.0 0.0 0.0 0.0 -4.0 8.0
Resolución de la ecuación de Laplace con condición Dirichlet
Resolvemos la ecuación de Laplace \[ \begin{cases} -\frac{\partial^2 u}{\partial x^2} = 12 x^2 & \text{en } (-1,1) \\ u(1) = u(-1) = 0 \end{cases} \] que tiene solución exacta \(u(x) = 1-x^4\).
= 1 - x^4
u = 12*x^2
f
= zeros(NN,1)
b for i=1:NN
= integrate(f*φ[i],(x,-1.0,1.0))
b[i] end
= A \ b;
uh
plot([-1;xx;1],[0;uh;0], label="Sol numérica", thickness_scaling=1.5,linewidth=2,legend=:outerright)
plot!(u, label="Sol exacta",linewidth=2)
Problemas con condición Neumann
Funciones de base lineales a trozos en el caso Neumann
Con la malla \[ x_0 = -1 < x_1 = -1+\Delta x < \cdots < x_{M+1} = 1 \]
Ahora debemos tomar el espacio \[ V^h = \mathrm{span} \{ \varphi_0, \cdots, \varphi_{M+1} \} \]
Es decir
Code
= 2.0^(-2)
Δx = -1.0:Δx:1.0
xx
φ = subs.(Φ , x , x/Δx .- xx/Δx )
= plot(xlim=(-1,1),thickness_scaling=1.5,legend=:outerright,
p =L"x",ylabel=L"u")
xlabelfor i=1:length(xx)
=plot!(φ[i], label=latexstring("\\varphi_{$(i-1)}"),linewidth=2)
pend
plot(p)