Lecture 7(a)

Finite elements in two dimensions

Unstructured grids

  • Most problems have complex domains.
  • Use unstructured grids.
  • Use Finite Elements.
  • Higher dimensions increases practical complexity.

An unstructued grid representing parts of the UK

Reference triangle

  • Split unit square into two triangles.
  • Each element maps to reference triangle.
  • Compute local \(K^{(e)}, F^{(e)}\) on reference element.
  • Assemble.
  • Solve.

The square domain split into triangular elements. Red dots are the nodes. Red squares contain the element numbers. Green squares contain the *global* node numbers. Blue squares contain the *local* node numbers, with the associated element number as subscript.

Local calculations

Follow 1d case, need local arrays.

Stiffness matrix

\[ k^e_{ab} = \int_{\triangle^e} \text{d}\triangle^e \, \left( \partial_{x} N_a (\mathbf{x}) \partial_{x} N_b(\mathbf{x}) + \partial_{y} N_a(\mathbf{x}) \partial_{y} N_b(\mathbf{x}) \right). \]

Force vector

\[ f^e_b = \int_{\triangle^e} \text{d}\triangle^e \, N_b(\mathbf{x}) S(\mathbf{x}). \]

Integrate over elements

\[ \begin{aligned} \int_\triangle \mathrm{d} \triangle \phi(x, y) &= \int_{0}^1 \mathrm{d}\xi_2 \int_0^{1-\xi_2} \mathrm{d}\xi_1 \phi(\xi_1, \xi_2) j(\xi_1, \xi_2) \, , \\ j = \det \left[ \frac{\partial \mathbf{x}}{\partial \symbf{\xi}} \right] &= \det \begin{pmatrix} \partial_{\xi_1} x & \partial_{\xi_2} x \\ \partial_{\xi_1} y & \partial_{\xi_2} y \end{pmatrix} \, . \end{aligned} \]

Gauss quadrature on reference triangle:

\[ \begin{split} \int_{0}^1 \mathrm{d}\xi_2 \int_0^{1-\xi_2} \mathrm{d}\xi_1 \psi(\symbf{\xi}) \simeq \tfrac{1}{6} \sum_{j=1}^3 \psi(\mathbf{x}(\symbf{\xi}^{(j)})) \, , \\ \symbf{\xi}^{(1)} = \tfrac{1}{6} \begin{pmatrix} 1 & 1 \end{pmatrix} \, , \quad \symbf{\xi}^{(2)} = \tfrac{1}{6} \begin{pmatrix} 1 & 4 \end{pmatrix} \, , \quad \symbf{\xi}^{(3)} = \tfrac{1}{6} \begin{pmatrix} 4 & 1 \end{pmatrix} \, . \end{split} \]

Maps

  • Coordinates are scalar fields.
  • So use function basis:

\[ x = x^e_0 N_0(\symbf{\xi}) + x^e_1 N_1(\symbf{\xi}) + x^e_2 N_2(\symbf{\xi}) \, . \]

Linear basis on reference triangle

\[ \begin{split} N_0 = 1 - \xi_1 - \xi_2, \quad N_1 = \xi_1, \quad N_2 = \xi_2 \\ \implies \qquad \partial_{\xi_1} x = -x^e_0 + x^e_1 \, . \end{split} \]

Gridding

Now need four things:

  1. List of node locations nodes (\(\mathtt{i} \to \mathbf{x}\));
  2. List of nodes in elements IEN (\(\mathtt{e} \to \mathtt{i}_0, \mathtt{i}_1, \mathtt{i}_2\));
  3. List of boundary nodes with values, type;
  4. Location matrix LM linking local/global numbering.

Node numbers arbitrary: add all nodes not on Dirichlet boundaries to ID.

\[ \mathtt{LM}(\mathtt{a}, \mathtt{e}) = \mathtt{ID}(\mathtt{IEN}(\mathtt{e}, \mathtt{a})) \, . \]

Diffusion with sources

nodes = np.loadtxt('data/ews_nodes_s5k_lc50k.txt')
IEN = np.loadtxt('data/ews_IEN_s5k_lc50k.txt', 
                 dtype=np.int64)
boundary_nodes = np.loadtxt('data/ews_bdry_s5k_lc50k.txt', 
                            dtype=np.int64)
# Make all boundary points Dirichlet
ID = np.zeros(len(nodes), dtype=np.int64)
n_eq = 0
for i in range(len(nodes[:, 1])):
    if i in boundary_nodes:
        ID[i] = -1
    else:
        ID[i] = n_eq
        n_eq += 1
N_equations = np.max(ID)+1
N_elements = IEN.shape[0]
N_nodes = nodes.shape[0]
N_dim = nodes.shape[1]
# Location matrix
LM = np.zeros_like(IEN.T)
for e in range(N_elements):
    for a in range(3):
        LM[a,e] = ID[IEN[e,a]]
# Global stiffness matrix and force vector
K = np.zeros((N_equations, N_equations))
F = np.zeros((N_equations,))
# Loop over elements
for e in range(N_elements):
    k_e = stiffness_2d(nodes[IEN[e,:],:])
    f_e = force_2d(nodes[IEN[e,:],:], S)
    for a in range(3):
        A = LM[a, e]
        for b in range(3):
            B = LM[b, e]
            if (A >= 0) and (B >= 0):
                K[A, B] += k_e[a, b]
        if (A >= 0):
            F[A] += f_e[a]
# Solve
Psi_interior = np.linalg.solve(K, F)
Psi_A = np.zeros(N_nodes)
for n in range(N_nodes):
    if ID[n] >= 0: # Otherwise Psi should be zero, and we've initialized that already.
        Psi_A[n] = Psi_interior[ID[n]]

The diffusion equation with homogeneous Dirichlet boundaries and a source is solved on an unstructured grid.

Summary

  • Finite elements use function basis.
  • Extension to higher dimensions requires
    • mapping to reference triangle/tetrahedron;
    • multi-point Gauss quadrature;
    • more complex gridding.
  • Use gridding software.
  • Core of algorithm conceptually identical.