Lecture 6 (d)

Nodes vs elements

Unstructured grids

  • Most problems have complex domains.
  • Use unstructured grids.
  • Use Finite Elements.
  • Move from nodes as key to elements.

An unstructued grid representing parts of the UK

Matrix form

Shape functions \(N_A(x)\) take PDE to

\[ \sum_A K_{AB} \psi_A = F_B \, . \]

\(\psi_A\) are nodal values of \(\psi\).

\(K_{AB}\) from all overlapping shape functions at node.

Gets too complex when

  • grid is not regular;
  • move to higher dimensions.

Shape functions for an *uneven* domain with three elements (hence four nodes).

Element approach

Focus on one element only.

\[ x \in [x_A, x_{A+1}] \to \xi \in [-1, 1]. \]

Two shape functions in element,

\[ N_a = \tfrac{1}{2} (1 + \xi_a \xi), \quad a = 1, 2 \, . \]

These contribute to element stiffness

\[ \begin{aligned} k^{(e)}_{ab} &= \int_{x_A}^{x_{A+1}} \mathrm{d}x \, \partial_x N_a \partial_x N_b \\ &= \int_{-1}^1 \mathrm{d}\xi (\partial_\xi x)^{-1} \partial_\xi N_a \partial_\xi N_b \\ &= \frac{(-1)^{a+b}}{x_{A+1} - x_A} \, . \end{aligned} \]

One element is mapped to the reference element.

Assembly

All \(k^{e}_{ab}\) add up to \(K_{AB}\). Need \(\{a\}\to\{A\}\) map.

No formula: set location matrix LM s.t.

\[ K_{LM(a, e), LM(b, e)} = K_{LM(a, e), LM(b, e)} + k^{(e)}_{ab} \, . \]

In 1d

  • \(LM(1,e)\) is left node of element \(e\)
  • \(LM(2,e)\) is right node of element \(e\).

Force vector

Write \(S(x) = \sum_a S_a N_a(x)\) in element.

\[ \begin{aligned} f^{(e)}_b &= \int_0^1 \mathrm{d}x N_b(x) S(x) \\ &= \sum_a \int_{-1}^1 \mathrm{d}\xi (\partial_\xi x) N_b N_a S_a \\ & \simeq \frac{x_{A+1} - x_A}{6} \begin{pmatrix} 2 S_1 + S_2 \\ S_1 + 2 S_2 \end{pmatrix} \end{aligned} \]

Better Gauss quadrature methods work for higher accuracy bases.

Assembly: \[ F_{LM(b, e)} = F_{LM(b, e)} + f^{(e)}_{b} \, . \]

Boundaries

Weak form includes \([ w(x) \partial_x \psi(x) ]_0^1\).

  • Neumann

\[ \partial_x \psi|_{x=1} = \beta \quad \implies \quad F_C = F_C + \beta \]

where \(x_C = 1\).

  • Dirichlet

\[ \psi_{x=0} = \alpha \quad \implies \quad F_C = F_C - \alpha k^{(e)}_{12} \]

where \(e\) is the element at boundary, \(x_C\) in \(e\), not at boundary.

Example

Ne = 10
nodes = np.array([0, *sorted(np.random.rand(Ne-1)), 1])
LM = np.zeros((2, Ne), dtype=np.int64)
for e in range(Ne):
    if e==0:
        LM[0, e] = -1
        LM[1, e] = 0
    else:
        LM[0, e] = LM[1, e-1]
        LM[1, e] = LM[0, e] + 1
K = np.zeros((Ne, Ne))
F = np.zeros((Ne,))
for e in range(Ne):
    k_e = stiffness(nodes[e:e+2])
    f_e = force(nodes[e:e+2], S)
    for a in range(2):
        A = LM[a, e]
        for b in range(2):
            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]
    # Modify force vector for Dirichlet BC
    if e == 0:
        F[0] -= alpha * k_e[1, 0]
# Modify force vector for Neumann BC
F[-1] += beta
# Solve
Psi_A = np.zeros_like(nodes)
Psi_A[0] = alpha
Psi_A[1:] = np.linalg.solve(K, F)

Apply Finite Element scheme to one dimensional case.

Summary

  • Finite elements use function basis.
  • Basis not orthogonal: overlap leads to stiffness matrix.
  • Use weak form to shift derivatives to test function.
  • Galerkin: single set of basis functions for everything.
  • Get linear system.
  • Work on elements, not nodes: applies to higher dimensions.