Recordamos la fórmula \[
\diver(v \nabla u) = \nabla v \nabla u + v \Delta u
\]
Con el teorema de la divergencia \[
\int_{\partial \Omega} v \nabla u \cdot n = \int_\Omega \nabla v \nabla u + \int_\Omega v \Delta u.
\] donde \(n\) es el vector normal exterior a \(\Omega\).
Un momento de teoría
Si \(v\) es una función Lipschitz, entonces es derivable en casi todo punto (teorema de Rademacher). Y denotamos a su derivada \(\nabla v\).
Esta derivada (a veces llamada “débil”) sigue teniendo la propiedad de integración por partes: si \(u\) es de clase \(C^2\) entonces \[
\int_{\partial \Omega} v \nabla u \cdot n = \int_\Omega \nabla v \nabla u + \int_\Omega v \Delta u.
\]
El espacio de funciones Lipschitz es un ejemplo de los llamados espacios de Sobolev. Denotaremos \[
\begin{aligned}
W^{1,\infty} (\Omega) &= \{ v : \overline \Omega \to \mathbb R \mid \text{ Lipschitz} \} \\
W^{1,\infty}_0 (\Omega) &= \{ v \in W^{1,\infty} (\Omega) \mid \text{ tal que } v = 0 \text{ en } \partial \Omega \}.
\end{aligned}
\]
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 \(\Omega\) con condiciones de Dirichlet homogéneas \(u = 0\) en \(\partial \Omega\). La solución exacta de la ecuación satisface que para toda \(v\) Lipscthitz se tiene
\[
\int_\Omega \frac{\partial u}{\partial t} v = \int_\Omega (\Delta u) v + \int_\Omega f v
\]
Si \(v = 0\) en \(\partial \Omega\) podemos integrar por partes \[
\int_\Omega \frac{\partial u}{\partial t} v = - \int_\Omega \nabla u \nabla v + \int_\Omega f v , \qquad \forall v \in W_0^{1,\infty} (\Omega).
\]
Con \(n = 2\) se tiene \[
\nabla u \cdot \nabla v = \frac{\partial u}{\partial x}\frac{\partial v}{\partial x} + \frac{\partial u}{\partial y}\frac{\partial v}{\partial y}
\]
La solución exacta satisface \[
\int_\Omega \frac{\partial u}{\partial t} v = - \int_\Omega \nabla u \nabla v + \int_\Omega f v , \qquad \forall v \in W_0^{1,\infty} (\Omega).
\]
Tomando \(\varphi_1^h, \cdot,s, \varphi_N^h \in W_0^{1,\infty}\) vamos a buscar
Pediremos que cumpla \[
\int_\Omega \frac{\partial u^h}{\partial t} v = - \int_\Omega \nabla u^h \nabla v + \int_\Omega f v , \qquad \forall v \in V^h.
\]
Estos es equivalente al sistema de \(N\) ecuaciones (diferenciales) \[
\int_\Omega \frac{\partial u^h}{\partial t} \varphi_i^h = - \int_\Omega \nabla u^h \nabla \varphi_i^h + \int_\Omega f \varphi_i^h , \qquad i = 1, \cdots, N.
\]
Al igual que ocurría en \(n=1\) podemos escribir esto como un sistema 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)
\]
Ejemplo. Ecuación de calor con condiciones Neumann
Tomemos \(\eqref{eq:calor}\) en \(\Omega\) con condiciones de Dirichlet homogéneas \(\nabla u \cdot n = 0\) en \(\partial \Omega\). La solución exacta de la ecuación satisface que para toda \(v\) Lipscthitz se tiene
\[
\int_\Omega \frac{\partial u}{\partial t} v = \int_\Omega (\Delta u) v + \int_\Omega f v
\]
Podemos integrar por partes incluso si \(v \ne 0\) en el borde, es decir \[
\int_\Omega \frac{\partial u}{\partial t} v = - \int_\Omega \nabla u \nabla v + \int_\Omega f v , \qquad \forall v \in W^{1,\infty} (\Omega).
\]
Elementos finitos
Fijemos \(d = 2\) por simplicidad. De nuevo, tomaremos una descomposición de \(\overline \Omega\) en polígonos convexos (llamada \(\mathcal T\)), y \(\varphi_i^h\) para que generen el espacio \[
V^h = \{ v \in C^p (\overline \Omega) : \forall K \in \mathcal T \text{ tenemos }v|_K \text{ es un polinomio de grado } g \}
\]
De nuevo, el caso más fácil es \(p = 0\) (funciones continuas) y \(g=1\) (lineales en cada \(K\)).
Sea \(K \in \mathcal T\) polígono. Si intentamos que \(\varphi_i^h\) sea lineal en \(K\) tiene 3 coeficientes. Así, si queremos fijar los valores de \(\varphi_i^h\) en los vértices de \(K\), sólo puede haber \(3\). Es decir, \(K\) tiene que ser un tríangulo.
Mallas cuadradas
Malla cuadradas
Para esta sección vamos a seguir el planteamiento propuesto en [Süli, 2020]. Consideramos en cuadrado \(\overline \Omega = [0,1]\times[0,1]\) y puntos \((x_i,y_j) = (ih, ih)\) con \(i,j = 0, \cdots, N\) definiendo una malla uniforme. Elegimos sobre esta malla los triángulos tal y como se presentan en la Figure 1.
Funciones lineales a trozos
Podemos indexar los puntos de la malla como \(P_{ij}\) e igualmente las funciones lineales a trozos.
function∇ϕ(vertices,i)# gradient of linear function which is 1 on vertices[i] and 0 on the others x1,y1 = vertices[i] x2,y2 = vertices[ minimum( setdiff( Set(1:3) , Set(i) ) ) ] x3,y3 = vertices[ maximum( setdiff( Set(1:3) , Set(i) ) ) ] D = (x2-x1)*(y3-y1) - (x3-x1)*(y2-y1)return [(y2-y3)/D , -(x2-x3)/D]end
∇ϕ (generic function with 1 method)
Cálculo de la matriz de rigidez
Numerados los puntos de la malla como \(P_1, \cdots P_N\),
Sean \(\varphi_i\) las funciones lineales a trozos con \(\varphi_i (P_j) = \delta_{ij}\).
Observación. Como \(\varphi_{i}\) son lineales en \(T\), las derivadas son constantes, y la integral se calcula de forma exacta.
Condiciones de borde
Para no tener que tratar de manera especial los elementos de borde, podemos construir el sistema incluyendo también los puntos de borde (como si estableciésemos). A posteriori, podemos reducir el sistema fijando el valor en los puntos borde y quitan las correspondientes ecuaciones.
Sean \[
I_{in} = \{ i : P_i \text{ es punto interior} \}, \qquad I_{\partial} = \{1, \cdots , N\} \setminus I_{in}.
\]
Las ecuaciones cuando \(i \in I_{\partial}\), no nos hacen falta. Por otro lado, si escribimos \[
\sum_{j \in I_{in}} a_{ij} u_j + \sum_{j \in I_{\partial}} a_{ij} u_j = \int_\Omega f \varphi_i \qquad \forall i \in I_{in}
\]
podemos reducir el sistema a \[
\sum_{j \in I_{in}} a_{ij} u_j = b_i , \qquad b_i = \int_\Omega f \varphi_i - \sum_{j \in I_{\partial}} a_{ij} u_j \qquad i \in I_{in}
\]
Condiciones Dirichlet \(u = g\)
Se puede fijar \(u_j = g(x_j)\). En términos de Julia (o Matlab) se puede definir la matriz del sistema reducido \[
A_r \gets A[ I_{in}, I_{in } ]
\] Si sólo buscamos las componentes \(u[I_{in}]\), podemos y resolver \[
A_r u_r = b_r
\] y tomar \(u[I_{in}] \gets u_r\). El resto de valores se recuperan de \(g\).
El paquete Triangulate.jl
Para la construcción de la malla vamos a utilizar el paquete Triangulate.jl. Es una interfaz del algoritmo Triangle de Jonathan Richard Shewchuk.
Podremos una condición de masa sobre los diferentes triángulos, para que la malla sea pequeña.
Süli, E. (2020) Lecture notes on finite element methods for partial differential equations. 2020. Mathematical Institute, University of Oxford. https://people.maths.ox.ac.uk/suli/fem.pdf.