The Finite Element Method

The aim of the Finite Element Method (FEM) is to solve (or more precisely approximate the solution of) a Partial Differential Equation (PDE) using a computer. In general the solution to a PDE is a function. Unfortunately it is computationally intractable to task a computer with finding this underlying function. The idea to resolve this issue is to parametrize a family of functions with the aim of computing the parameters through solving a linear system of equations. There is a plethora of ways to get to such a linear system of equations, with the most common being the so-called Galerkin approach.

1. Getting the computer to understand functions

In the most basic terms, computers are only capable of understanding numbers, which means that they are inherently unable to solve equations where the unknowns are functions. This is a problem when trying to solve differential equations. To solve this problem, the functions are instead approximated using parameterizations for which the coefficients (numbers) are unknown. Intuitively, these numbers are exactly what the computer is asked to find. For element methods, this parameterization is chosen to be the simplest possible: a linear combination of functions

๐‘(๐ฑ)โ‰ˆ๐“(๐ฑ)๐ฉ=[๐‘‡1(๐ฑ)๐‘‡2(๐ฑ)โ€ฆ๐‘‡๐‘›(๐ฑ)][๐‘1๐‘2โ‹ฎ๐‘๐‘›],

(1)

where ๐‘ is the unknown function being approximated. Note that the linearity is with respect to the unknown parameters ๐ฉ, but not necessarily in the known basis functions ๐“(๐ฑ).

One might ask: How does the above relate to the Finite Element Method? The answer is that the functions ๐‘‡๐‘– are chosen to be simpler functions with support equal to only a few subdomains of the original domain. These subdomains are commonly referred to as elements.

Interactive figureย 1: Piecewise polynomial approximation

Interactive figure 1 (Piecewise polynomial approximation)ย ย  In one dimension an approximation of the form (1) is easy to visualize. The graph shows the function ๐‘ (dashed) and the approximation ๐“(๐‘ฅ)๐ฉ (solid) on ๐‘ elements (every other one shaded). The coefficients ๐‘๐‘–=๐‘(๐‘ฅ๐‘–) are the large dots, and each basis function ๐‘‡๐‘–, scaled by its ๐‘๐‘–, is drawn faint. There are two ways to improve the approximation: more elements11 Called โ„Ž-refinement, as it decreases the element size โ„Ž=1/๐‘. or basis functions of a higher polynomial order ๐‘.22 Called ๐‘-refinement. Here ๐‘ is the order, not the function being approximated.

2. The Finite Element Method for the Helmholtz equation

In acoustics we are often interested in solving the Helmholtz equation, given as

ฮ”๐‘(๐ฑ)+๐‘˜2๐‘(๐ฑ)=0,๐ฑโˆˆฮฉ,

(2)

where ๐‘˜ is most often referred to as the wavenumber. In its current form the basis functions ๐“(๐ฑ) must be twice differentiable; piecewise linear functions, for example, have a vanishing second derivative inside each element and cannot be used. This constraint can be relieved using the so-called weak formulation. In order to do so we multiply the Helmholtz equation with a so-called test function ๐œ‘ followed by an integration over the domain ฮฉ

โˆซฮฉ๐œ‘(๐ฑ)(ฮ”๐‘(๐ฑ)+๐‘˜2๐‘(๐ฑ))d๐ฑ=0.

(3)

Utilizing integration by parts on the term including the Laplacian we can move derivatives from ๐‘(๐ฑ) onto ๐œ‘(๐ฑ) as

โˆซฮฉ(โˆ‡๐œ‘(๐ฑ))โŠคโˆ‡๐‘(๐ฑ)d๐ฑโˆ’๐‘˜2โˆซฮฉ๐œ‘(๐ฑ)๐‘(๐ฑ)d๐ฑโˆ’โˆซ๐œ•ฮฉ๐œ‘(๐ฑ)๐œ•๐‘๐œ•๐‘›(๐ฑ)d๐ฑ=0.

(4)

In the above the constraint on the smoothness of ๐‘(๐ฑ) has been reduced to first order. Furthermore the last term

โˆซ๐œ•ฮฉ๐œ‘(๐ฑ)๐œ•๐‘๐œ•๐‘›(๐ฑ)d๐ฑ

(5)

can be used to include the boundary conditions into the equation. For simplification purposes we will in the following assume that the above is equal to zero. As such we have

0=โˆซฮฉ(โˆ‡๐œ‘(๐ฑ))โŠคโˆ‡๐‘(๐ฑ)d๐ฑโˆ’๐‘˜2โˆซฮฉ๐œ‘(๐ฑ)๐‘(๐ฑ)d๐ฑ.

(6)

We will now use the Galerkin approach to discretize the above equation. Note that โ€œGalerkinโ€ simply refers to the approach where ๐œ‘(๐ฑ) and ๐‘(๐ฑ) are discretized using the same basis functions (๐“(๐ฑ)). In short this means that we introduce

๐‘(๐ฑ)โ‰ˆ๐“(๐ฑ)๐ฉ,๐œ‘(๐ฑ)โ‰ˆ๐šโŠค๐“(๐ฑ)โŠค,

(7)

where ๐šโˆˆโ„‚๐‘› is a set of arbitrary coefficients that parametrize a whole family of test functions and ๐ฉโˆˆโ„‚๐‘› are the coefficients that we aim to find. Inserting the approximations it follows that

0=โˆซฮฉ(โˆ‡๐œ‘(๐ฑ))โŠคโˆ‡๐‘(๐ฑ)d๐ฑโˆ’๐‘˜2โˆซฮฉ๐œ‘(๐ฑ)๐‘(๐ฑ)d๐ฑโ‰ˆโˆซฮฉ๐šโŠค(โˆ‡๐“(๐ฑ))โŠคโˆ‡๐“(๐ฑ)๐ฉd๐ฑโˆ’๐‘˜2โˆซฮฉ๐šโŠค๐“(๐ฑ)โŠค๐“(๐ฑ)๐ฉd๐ฑ=๐šโŠค(โˆซฮฉ(โˆ‡๐“(๐ฑ))โŠคโˆ‡๐“(๐ฑ)d๐ฑ)๐ฉโˆ’๐‘˜2๐šโŠค(โˆซฮฉ๐“(๐ฑ)โŠค๐“(๐ฑ)d๐ฑ)๐ฉ=๐šโŠค(โˆซฮฉ(โˆ‡๐“(๐ฑ))โŠคโˆ‡๐“(๐ฑ)d๐ฑโˆ’๐‘˜2โˆซฮฉ๐“(๐ฑ)โŠค๐“(๐ฑ)d๐ฑ)๐ฉ.

(8)

We can make the above equality hold for all possible test functions, i.e. for all ๐šโˆˆโ„‚๐‘›, if we find ๐ฉ such that

(โˆซฮฉ(โˆ‡๐“(๐ฑ))โŠคโˆ‡๐“(๐ฑ)d๐ฑโˆ’๐‘˜2โˆซฮฉ๐“(๐ฑ)โŠค๐“(๐ฑ)d๐ฑ)๐ฉ=๐ŸŽ.

(9)

This is exactly what we do in Finite Element computations. As a shorthand the above can be written as

(๐Šโˆ’๐‘˜2๐Œ)๐ฉ=๐ŸŽ,

(10)

where ๐Š is referred to as the stiffness matrix and ๐Œ as the mass matrix. In the literature the equation can also be found as

(๐‘2๐Šโˆ’๐œ”2๐Œ)๐ฉ=๐ŸŽ,

(11)

where ๐‘ is the propagation speed and ๐œ” is the angular frequency.

3. What is an element?

A key insight is that the element serves two purposes: it represents a subdomain of the original domain (also referred to as the geometry) while also describing parts of the unknown function(s) of interest. In general this subdomain is described by a parameterization, i.e. the element, as

๐ฑ๐‘’(๐ฎ)=๐—๐‘’๐๐‘’(๐ฎ)โˆˆฮฉ๐‘’,โˆ€๐ฎโˆˆโ„’๏ธ€๐‘’,

(12)

where the superscript ๐‘’ denotes the element number, ๐—๐‘’ is a matrix with columns equal to the interpolation nodes of the geometry, ๐๐‘’(๐ฎ) are the so-called shape functions, ฮฉ๐‘’ is the element in global coordinates and โ„’๏ธ€๐‘’ are the local coordinates. In addition to the geometric interpolation of each element, we need to further define interpolations of the unknown functions, which in acoustics is usually taken as the pressure ๐‘(๐ฑ). On element ๐‘’ this interpolation can be done as

๐‘(๐ฑ๐‘’(๐ฎ))=๐“(๐ฑ๐‘’(๐ฎ))๐ฉ=๐“(๐ฑ๐‘’(๐ฎ))(๐‹๐‘’)โŠคโŸ๐“๐‘’(๐ฎ)๐‹๐‘’๐ฉโŸ๐ฉ๐‘’=๐“๐‘’(๐ฎ)๐ฉ๐‘’,๐ฎโˆˆโ„’๏ธ€๐‘’,

(13)

where ๐‹๐‘’ is a permutation-like matrix that extracts the relevant values of ๐ฉ and the relevant functions of ๐“(๐ฑ) and orders them such that they correspond to the local values ๐ฉ๐‘’ and the local basis functions ๐“๐‘’(๐ฎ).

Exampleย 1: Linear triangular elements

Example 1 (Linear triangular elements)ย ย 

The linear shape functions for a triangular element can have the form

๐๐‘’(๐‘ข1,๐‘ข2)=[1โˆ’๐‘ข1โˆ’๐‘ข2๐‘ข1๐‘ข2],๐‘ข1โˆˆ[0,1],๐‘ข2โˆˆ[0,1โˆ’๐‘ข1].

(14)

The choice in the wording is because the ordering of the columns of ๐—๐‘’ can change the ordering of the rows of ๐๐‘’(๐ฎ) or vice versa. This is something that one should keep in mind in practice when using different mesh file formats. Taking the second element of the figure above as an example, it could be that

๐—2=[๐ฑ3๐ฑ1๐ฑ4].

(15)

Note that extending the geometric interpolation to higher orders is as simple as adding more rows/functions to ๐๐‘’(๐‘ข1,๐‘ข2) as well as more columns/points to ๐—๐‘’.

Exampleย 2: Basis functions for continuous linear interpolation

Example 2 (Basis functions for continuous linear interpolation)ย ย 

Continuous linear basis functions on triangular elements are similar to shape functions for a linear triangular element and differ only in the fact that they are the transpose:

๐“continuous๐‘’(๐‘ข1,๐‘ข2)=[1โˆ’๐‘ข1โˆ’๐‘ข2๐‘ข1๐‘ข2],๐‘ข1โˆˆ[0,1],๐‘ข2โˆˆ[0,1โˆ’๐‘ข1],

(16)

where the subscript โ€œcontinuousโ€ is only there to highlight that it is a continuous formulation. Again, the ordering of the columns of the row vector depends on the ordering of the element corners.

Exampleย 3: Element localization matrix

Example 3 (Element localization matrix)ย ย  For a continuous linear element ๐‘’ all three corners correspond to a value of the global vector ๐ฉ. For example, the second element in the continuous plot has local corner values given by ๐ฉ2=[๐‘3๐‘1๐‘4]โŠค. This element would have ๐‹๐‘’ given as

๐‹2=[0010โ€ฆ01000โ€ฆ00001โ€ฆ0],

(17)

so that ๐ฉ2=๐‹2๐ฉ. Note that ๐‹๐‘’ is only an artifact of the mathematical description. Any reasonable implementation should use indexing instead of multiplication with ๐‹๐‘’.

4. Computing the stiffness and mass matrices

Using the element description of both the geometry and the pressure function the mass matrix can be computed as follows

๐Œ=โˆซฮฉ๐“(๐ฑ)โŠค๐“(๐ฑ)d๐ฑโ‰ˆโˆ‘๐‘’=1๐‘โˆซฮฉ๐‘’๐‹๐‘’โŠค๐‹๐‘’๐“(๐ฑ)โŠค๐“(๐ฑ)๐‹๐‘’โŠค๐‹๐‘’d๐ฑ=โˆ‘๐‘’=1๐‘๐‹๐‘’โŠค(โˆซโ„’๏ธ€๐‘’๐“๐‘’(๐ฎ)โŠค๐“๐‘’(๐ฎ)jacobian(ฮฉ๐‘’,๐ฎ)d๐ฎ)๐‹๐‘’โ‰ˆโˆ‘๐‘’=1๐‘๐‹๐‘’โŠค(โˆ‘๐‘–=1๐‘„๐‘ค๐‘–๐“๐‘’(๐ฎ๐‘–)โŠค๐“๐‘’(๐ฎ๐‘–)jacobian(ฮฉ๐‘’,๐ฎ๐‘–)โŸ๐Œ๐‘’)๐‹๐‘’,

(18)

where the first approximation is due to the geometry being approximated by the elements, and the second is due to the quadrature with the ๐‘„ points ๐ฎ๐‘– and weights ๐‘ค๐‘–. Furthermore, jacobian(ฮฉ๐‘’,๐ฎ) is a function that describes the distortion from the local coordinates โ„’๏ธ€๐‘’ onto the global element ฮฉ๐‘’. This distortion represents length, area, or volume depending on the dimensionality of the problem. Note that if the elements are the same size then ๐Œ๐‘’ is constant with respect to each element (this is the case in the code below).

The stiffness matrix is computed similarly but with a difference in the fact that the gradient must have its coordinates changed from global to local. Using the chain rule it follows that

โˆ‡๐ฎ๐‘(๐ฑ(๐ฎ))=๐‰(๐ฎ)โˆ‡๐ฑ๐‘(๐ฑ(๐ฎ)),

(19)

where ๐‰(๐ฎ)=(๐œ•๐ฑ/๐œ•๐ฎ)โŠค, i.e. ๐ฝ๐‘–๐‘—=(๐œ•๐‘ฅ๐‘—)/(๐œ•๐‘ข๐‘–), so that jacobian(ฮฉ๐‘’,๐ฎ)=|det๐‰(๐ฎ)|. From this we can isolate the global gradient as

โˆ‡๐ฑ๐‘(๐ฑ(๐ฎ))=๐‰(๐ฎ)โˆ’1โˆ‡๐ฎ๐‘(๐ฑ(๐ฎ)).

(20)

Putting things together the stiffness matrix can therefore be computed as

๐Š=โˆซฮฉ(โˆ‡๐“(๐ฑ))โŠคโˆ‡๐“(๐ฑ)d๐ฑโ‰ˆโˆ‘๐‘’=1๐‘โˆซฮฉ๐‘’๐‹๐‘’โŠค๐‹๐‘’(โˆ‡๐ฑ๐“(๐ฑ))โŠคโˆ‡๐ฑ๐“(๐ฑ)๐‹๐‘’โŠค๐‹๐‘’d๐ฑ=โˆ‘๐‘’=1๐‘๐‹๐‘’โŠค(โˆซโ„’๏ธ€๐‘’(โˆ‡๐ฑ๐“๐‘’(๐ฎ))โŠคโˆ‡๐ฑ๐“๐‘’(๐ฎ)jacobian(ฮฉ๐‘’,๐ฎ)d๐ฎ)๐‹๐‘’=โˆ‘๐‘’=1๐‘๐‹๐‘’โŠค(โˆซโ„’๏ธ€๐‘’(โˆ‡๐ฎ๐“๐‘’(๐ฎ))โŠค(๐‰(๐ฎ)โŠค)โˆ’1๐‰(๐ฎ)โˆ’1โˆ‡๐ฎ๐“๐‘’(๐ฎ)jacobian(ฮฉ๐‘’,๐ฎ)d๐ฎ)๐‹๐‘’โ‰ˆโˆ‘๐‘’=1๐‘๐‹๐‘’โŠค(โˆ‘๐‘–=1๐‘„๐‘ค๐‘–(โˆ‡๐ฎ๐“๐‘’(๐ฎ๐‘–))โŠค(๐‰(๐ฎ๐‘–)โŠค)โˆ’1๐‰(๐ฎ๐‘–)โˆ’1โˆ‡๐ฎ๐“๐‘’(๐ฎ๐‘–)jacobian(ฮฉ๐‘’,๐ฎ๐‘–)โŸ๐Š๐‘’)๐‹๐‘’.

(21)

In the following code we implement three different ways of assembling the mass and stiffness matrices. Note that the first two implementations are only for educational purposes as they are both based on dense matrices.

Exampleย 4: Matrix assembly implementations

Example 4 (Matrix assembly implementations)ย ย 

julia
1
### Importing relevant packages
2
using FastGaussQuadrature
3
using BenchmarkTools
4
using LinearAlgebra
5
using SparseArrays
6
using ForwardDiff
7
using Random
8
Random.seed!(42)
9
## Defining geometry.
10
# Impedance tube of diameter 10 cm and length 1 m (used later)
11
D = 0.1 # 100 mm diameter
12
L = 10*D # Length of the cavity
13
ne = 600 # Number of quadratic elements
14
nnt = 2*ne+1 # Total number of nodes
15
h = L/ne # Length of the elements
16
x = Vector(0:h/2:L) # Coordinates table
17
18
## Computing the element matrices
19
# Local basis functions (gradient by ForwardDiff: slow but easy)
20
Tแต‰(u) = [u .* (u .- 1)/2; 1 .- u .^2; u .* (u .+ 1)/2]'
21
โˆ‡Tแต‰(u) = hcat(ForwardDiff.derivative.(Tแต‰,u)...)
22
# All elements are equal, so the Jacobian is the same for each.
23
# It maps [-1,1] onto [x_i,x_{i+1}], i.e. length 2 onto length h.
24
jacobian(u) = h/2
25
# In 1D the Jacobian function and matrix are equal (not so in 2D).
26
J(u) = h/2
27
# The element matrices, the same for all elements of equal size.
28
Q = 3 # Number of Gauss points
29
u,w = gausslegendre(Q)
30
Me = sum(i -> w[i]*Tแต‰(u[i])'*Tแต‰(u[i])*jacobian(u[i]),1:Q)
31
Ke = sum(i -> w[i]*โˆ‡Tแต‰(u[i])'*J(u[i])^(-1)*J(u[i])^(-1)*โˆ‡Tแต‰(u[i])*
32
jacobian(u[i]),1:Q)
33
34
## Assembly 1: with the localization matrices (never do this!)
35
function assembly1(Me, Ke, nnt, ne)
36
K = zeros(nnt, nnt) # Dense matrix! Not ideal!
37
M = zeros(nnt, nnt) # Dense matrix! Not ideal!
38
for ie = 1:ne
39
Le = zeros(3, nnt)
40
Le[:, ie*2-1:ie*2+1] = Diagonal(ones(3))
41
K += Le'*Ke*Le
42
M += Le'*Me*Le
43
end
44
return K, M
45
end
46
@btime K, M = assembly1(Me, Ke, nnt, ne)
47
48
## Assembly 2: with indexing instead of localization matrices
49
function assembly2(Me, Ke, nnt, ne)
50
K = zeros(nnt, nnt) # Dense matrix! Not ideal!
51
M = zeros(nnt, nnt) # Dense matrix! Not ideal!
52
for ie = 1:ne
53
K[ie*2-1:ie*2+1, ie*2-1:ie*2+1] += Ke
54
M[ie*2-1:ie*2+1, ie*2-1:ie*2+1] += Me
55
end
56
return K, M
57
end
58
@btime K, M = assembly2(Me, Ke, nnt, ne)
59
60
## Assembly 3: sparse, using the compact support of the elements
61
function assembly3(Me, Ke, nnt, ne)
62
I = zeros(Int64, 4nnt - 3)
63
J = zeros(Int64, 4nnt - 3)
64
Kd = zeros(ComplexF64, length(I))
65
Md = zeros(ComplexF64, length(I))
66
for ie=1:ne
67
for i = 1:3
68
r = (8*(ie-1)+1 + 3*(i-1)):(8*(ie-1) + 3*i)
69
I[r] .= ie*2-1:ie*2-1+2
70
J[r] .= (ie-1)*2 + i
71
Kd[r] += Ke[:, i]
72
Md[r] += Me[:, i]
73
end
74
end
75
K = sparse(I, J, Kd)
76
M = sparse(I, J, Md)
77
return K, M
78
end
79
@btime K, M = assembly3(Me, Ke, nnt, ne)

5. Examples

Exampleย 5: Impedance tube

Example 5 (Impedance tube)ย ย  The procedure used in an impedance tube to measure the surface impedance and absorption coefficient of an acoustic material works as follows. A loudspeaker is installed at one end (๐‘ฅ=๐ฟ) and an acoustic material of thickness โ„Ž and surface impedance ๐‘ฬ‚ is bonded onto the other rigid and impervious end, with the surface of the material at ๐‘ฅ=0. Below the cut-off frequency of the tube, only plane waves propagate and the problem is amenable to a one-dimensional analysis.

In this case the surface impedance of the material can be obtained from the measurement of the transfer function ๐ปฬ‚12=๐‘ฬ‚2/๐‘ฬ‚1 between two microphones adequately placed in the tube (e.g., standard ASTM E1050):

๐‘ฬ‚๐œŒ0๐‘0=1+๐‘…1โˆ’๐‘…,๐‘…=๐ปฬ‚12โˆ’exp(โˆ’๐‘–๐‘˜0๐‘ )exp(๐‘–๐‘˜0๐‘ )โˆ’๐ปฬ‚12exp(2๐‘–๐‘˜0(๐‘‘+๐‘ )),

(22)

where ๐‘‘ is the distance from microphone 2 to the sample, ๐‘  is the spacing between the two microphones, and ๐‘˜0=๐œ”/๐‘0 is the wavenumber of air. The normal-incidence absorption coefficient ๐›ผ is directly obtained from the reflection coefficient ๐‘…: ๐›ผ=1โˆ’|๐‘…|2.

Figureย 1: The impedance tube, with the surface of the material at ๐‘ฅ=0 and the loudspeaker at ๐‘ฅ=๐ฟ.

The impedance of a material of thickness โ„Ž bonded onto a rigid wall (at ๐‘ฅ=โˆ’โ„Ž) and excited by a plane wave with incidence angle ๐œƒ=0 is given by [1]:

๐‘ฬ‚=โˆ’๐‘–๐‘ฬ‚๐‘cot(๐‘˜ฬ‚๐‘โ„Ž).

(23)

In the following the loudspeaker is modeled as a displacement of ๐‘ˆ๐ฟ=1. Furthermore, the specific details of the setup are:

  • Diameter of impedance tube ๐ท=10 cm (and thus cut-off frequency 1.84๐‘0/(๐œ‹๐ท)โ‰ˆ2004 Hz).
  • Length of impedance tube: ๐ฟ=10๐ท.
  • Microphone spacing: ๐‘ =๐ท/2.
  • Distance between microphone 2 and the surface of the material: ๐‘‘=๐ท/2.
  • Thickness of the material: โ„Ž=2 cm.
  • Characteristic impedance ๐‘ฬ‚๐‘=๐œŒ0๐‘0[1+0.057๐‘‹โˆ’0.754โˆ’๐‘–0.087๐‘‹โˆ’0.732] (where ๐‘‹=๐œŒ0๐‘“/๐œŒ๐‘).
  • Wavenumber ๐‘˜ฬ‚๐‘=(๐œ”/๐‘0)[1+0.0978๐‘‹โˆ’0.700โˆ’๐‘–0.189๐‘‹โˆ’0.595] (where ๐‘‹=๐œŒ0๐‘“/๐œŒ๐‘).
  • Density and propagation speed: ๐œŒ0=1.2 kg/mยณ, ๐‘0=342.2 m/s.
  • Flow resistivity of the material: ๐œŒ๐‘=10000 Rayls/m.

A 1D model of an impedance tube with a loudspeaker at ๐‘ฅ=๐ฟ and a material at ๐‘ฅ=0 can be described by the following set of equations

{d2๐‘d๐‘ฅ2(๐‘ฅ)+๐‘˜02๐‘(๐‘ฅ)=0,๐‘ฅโˆˆ[0,๐ฟ]d๐‘d๐‘ฅ(๐ฟ)=โˆ’๐‘–๐œŒ0๐œ”๐‘ฃ๐ฟ=๐œŒ0๐œ”2๐‘ˆ๐ฟd๐‘d๐‘ฅ(0)=๐‘–๐‘˜0๐›ฝ๐‘(0)

(24)

where ๐›ฝ=๐œŒ0๐‘0/๐‘ฬ‚ is the surface admittance of the material, normalized by the characteristic impedance of air, and ๐‘ˆ๐ฟ is the displacement of the loudspeaker, with velocity ๐‘ฃ๐ฟ=๐‘–๐œ”๐‘ˆ๐ฟ. Here, and in the formulas above, time-harmonic quantities vary as ๐‘’๐‘–๐œ”๐‘ก.

The PDE is modeled using the FEM as previously

(๐Šโˆ’๐‘˜02๐Œ)๐ฉ=๐ŸŽ.

(25)

However, in this case โˆซ๐œ•ฮฉ๐œ‘(๐‘ฅ)๐œ•๐‘๐œ•๐‘›(๐‘ฅ)d๐‘ฅโ‰ 0. Instead we have

[๐œ‘(๐‘ฅ)d๐‘d๐‘ฅ(๐‘ฅ)]0๐ฟ=๐šโŠค๐“(๐ฟ)โŠคd๐‘d๐‘ฅ(๐ฟ)โˆ’๐šโŠค๐“(0)โŠคd๐‘d๐‘ฅ(0)=๐šโŠค([00โ‹ฎ1]๐œŒ0๐œ”2๐‘ˆ๐ฟโˆ’[10โ‹ฎ0]๐‘–๐‘˜0๐›ฝ๐‘(0))=๐šโŠค([00โ‹ฎ1]๐œŒ0๐œ”2๐‘ˆ๐ฟโˆ’diag([๐‘–๐‘˜0๐›ฝ0โ‹ฎ0])๐ฉ).

(26)

In the above we utilized the prescribed boundary conditions as well as the definition of ๐“(๐‘ฅ), so that ๐‘(0)=๐‘1 is the first entry of ๐ฉ. Putting things together we find that

(๐Šโˆ’๐‘˜02๐Œ+diag([๐‘–๐‘˜0๐›ฝ0โ‹ฎ0]))๐ฉ=[00โ‹ฎ1]๐œŒ0๐œ”2๐‘ˆ๐ฟ.

(27)

Using the previously implemented FEM routines we can numerically solve the problem, and use the analytical expression to check the results, as shown in Figureย 2.

julia
1
include("assembly_1d.jl")
2
using CairoMakie
3
## Recomputing FEM matrices
4
K,M = assembly3(Me,Ke,nnt,ne)
5
## Setup
6
ฯโ‚€ = 1.2 # Fluid density
7
cโ‚€ = 342.2 # Speed of sound
8
U_L = 1 # Piston displacement
9
D = 0.1 # Diameter of Impedance Tube
10
s = 0.5*D # Microphone spacing
11
d = D/2 # Distance between mic 2 and sample
12
## Frequency domain
13
fc = floor(1.84*cโ‚€/D/pi) # Cut off frequency
14
freq = Vector(100:2:fc)
15
ฯ‰ = 2*pi*freq
16
kโ‚€ = ฯ‰/cโ‚€
17
## Impedance properties
18
Zโ‚€ = ฯโ‚€ * cโ‚€
19
thickness = 0.02 # thickness of the material
20
ฯƒ = 10000 # flow resistivity
21
X = ฯโ‚€*freq/ฯƒ
22
Zc = Zโ‚€*(1 .+ 0.057*X.^(-0.754) - im*0.087.*X.^(-0.732))
23
kc = kโ‚€ .*(1 .+ 0.0978*X.^(-0.700) - im*0.189.*X.^(-0.595))
24
Z = -im.*Zc.*cot.(kc*thickness) / Zโ‚€
25
beta = 1.0 ./ Z # convert to admittance
26
# Finding nodes located on the microphones
27
in2 = findall(x->x,abs.(x .- d) .< 1e-6)[1]
28
in1 = findall(x->x,abs.(x .- (d+s)) .< 1e-6)[1]
29
# Correcting the s and d distances to fit the numerical values
30
s = abs(x[in1] - x[in2])
31
d = x[in2]
32
33
## Output
34
ndof = nnt
35
nfreqs = length(ฯ‰)
36
P_mic1 = zeros(ComplexF64,nfreqs)
37
P_mic2 = zeros(ComplexF64,nfreqs)
38
A = Diagonal(zeros(ComplexF64,nnt))
39
F = zeros(ComplexF64,ndof)
40
41
## Frequency sweep
42
for i in eachindex(ฯ‰)
43
A[1,1] = im*kโ‚€[i]*beta[i]
44
F[end,1] = ฯโ‚€*ฯ‰[i]^2*U_L
45
S = K - kโ‚€[i]^2*M + A
46
p = S\F
47
P_mic2[i] = p[in2]
48
P_mic1[i] = p[in1]
49
end
50
51
# Calculate the normalized impedance
52
Hโ‚โ‚‚ = P_mic2 ./ P_mic1
53
R = (Hโ‚โ‚‚ - exp.(-im*kโ‚€*s))./(exp.(im*kโ‚€*s) - Hโ‚โ‚‚) .*
54
exp.(im*2*kโ‚€ * (d + s))
55
Z_num = (1 .+ R)./(1 .- R)
56
## Comparison with the exact solution
57
fig = Figure(size=(800,320))
58
ax_re = Axis(fig[1,1],xlabel="Frequency (Hz)",ylabel="Real part")
59
lines!(ax_re,freq,real.(Z),label="Analytical")
60
lines!(ax_re,freq,real.(Z_num),label="FEM",linestyle=:dash)
61
ax_im = Axis(fig[1,2],xlabel="Frequency (Hz)",ylabel="Imaginary part")
62
lines!(ax_im,freq,imag.(Z))
63
lines!(ax_im,freq,imag.(Z_num),linestyle=:dash)
64
axislegend(ax_re)
65
fig
Figureย 2: The normalized surface impedance ๐‘ฬ‚/(๐œŒ0๐‘0) of the material, analytical and computed with the FEM.

Exampleย 6: Modes of a 10 ร— 4 m room

Example 6 (Modes of a 10 ร— 4 m room)ย ย  The Finite Element Method can also be used to compute the modes, i.e. finding the eigenvalues ๐œ”2 of the generalized eigenvalue problem

๐‘2๐Š๐ฉ=๐œ”2๐Œ๐ฉ.

(28)

For a rectangular room with side lengths ๐ฟ๐‘ฅ and ๐ฟ๐‘ฆ, here ๐ฟ๐‘ฅ=10 m and ๐ฟ๐‘ฆ=4 m, the frequencies of the modes can be computed analytically as

๐‘“๐‘›๐‘ฅ๐‘›๐‘ฆ=๐‘2(๐‘›๐‘ฅ๐ฟ๐‘ฅ)2+(๐‘›๐‘ฆ๐ฟ๐‘ฆ)2.

(29)

The room is meshed with a regular grid of bilinear quadrilateral elements:

julia
1
using LinearAlgebra, CairoMakie
2
## Defining geometry.
3
Lx = 10
4
Ly = 4
5
n = 20+1
6
m = 8+1
7
ne = (n-1)*(m-1) # Number of linear elements
8
nnt = n*m # Total number of nodes
9
## Plotting the elements
10
x = Vector(0:Lx/(n-1):Lx)
11
y = Vector(0:Ly/(m-1):Ly)
12
X = kron(x,ones(m))
13
Y = kron(ones(n),y)
14
scatter(X,Y,axis=(aspect=DataAspect(),))

The Finite Element computation for the 2D room looks similar to the one for the 1D impedance tube. One difference is the reliance on the topology (connectivity) matrix, which lists the nodes of each element. The end of the script computes the analytical frequencies for comparison:

julia
1
include("modes_geometry.jl")
2
using ForwardDiff, SparseArrays, LinearAlgebra
3
using FastGaussQuadrature, Arpack
4
cโ‚€ = 342.2
5
## Creating the topology
6
T = reshape(1:nnt,m,n) # Numbering all nodes on the grid
7
topology = zeros(Int,4,ne)
8
topology[1,:] = T[1:end-1,1:end-1][:]
9
topology[2,:] = T[1:end-1,2:end][:]
10
topology[3,:] = T[2:end,2:end][:]
11
topology[4,:] = T[2:end,1:end-1][:]
12
## Computing Element matrices
13
# Local basis functions (gradient by ForwardDiff: slow but easy)
14
Tแต‰(u) = [(1-u[1])*(1-u[2]); (1+u[1])*(1-u[2]);
15
(1+u[1])*(1+u[2]); (1-u[1])*(1+u[2])]'/4
16
โˆ‡Tแต‰(u) = hcat(ForwardDiff.jacobian(Tแต‰,u))'
17
# All elements are equal, so the Jacobian is the same for each.
18
jacobian(u) = (x[2]-x[1])/2*(y[2]-y[1])/2
19
J(u) = Diagonal([x[2]-x[1];y[2]-y[1]])/2
20
# Defining the local element matrices.
21
Q = 2
22
u,wu = gausslegendre(Q)
23
v,wv = gausslegendre(Q)
24
U = kron(u,ones(Q))
25
V = kron(ones(Q),v)
26
W = kron(wu,wv)
27
P = [U';V']
28
29
Me = sum(i -> W[i]*jacobian(P[:,i])*Tแต‰(P[:,i])'*Tแต‰(P[:,i]),1:Q^2)
30
Ke = sum(i -> W[i]*jacobian(P[:,i])*โˆ‡Tแต‰(P[:,i])'*
31
J(P[:,i])'^(-1)*J(P[:,i])^(-1)*โˆ‡Tแต‰(P[:,i]),1:Q^2)
32
33
## Assembly
34
function connected_topology(topology,nnt,ne)
35
source_connections = [zeros(Int,0) for _ in 1:nnt]
36
for element = 1:ne
37
for i = 1:4
38
node = topology[i,element]
39
append!(source_connections[node],topology[:,element])
40
end
41
end
42
sort!.(unique.(source_connections))
43
end
44
function create_I_J(connections)
45
I = zeros(Int,sum(length.(connections)))
46
J = zeros(Int,sum(length.(connections)))
47
lower = 1
48
for (idx,con) in enumerate(connections)
49
upper = lower + length(con)
50
I[lower:upper-1] .= con
51
J[lower:upper-1] .= idx
52
lower = upper
53
end
54
return I,J
55
end
56
function assembly(Me,Ke,topology,nnt)
57
ne = size(topology,2)
58
connections = connected_topology(topology,nnt,ne)
59
I,J = create_I_J(connections)
60
S = sparse(I,J,1:length(I))
61
Kd = zeros(length(I))
62
Md = zeros(length(I))
63
for ie=1:ne
64
top = topology[:,ie]
65
Kd[S[top,top]] += Ke
66
Md[S[top,top]] += Me
67
end
68
K = sparse(I,J,Kd)
69
M = sparse(I,J,Md)
70
return K,M
71
end
72
K,M = assembly(Me,Ke,topology,nnt);
73
74
using Arpack
75
F = eigs(cโ‚€^2*K,M,which=:SM,nev=10);
76
freq = sort(sqrt.(abs.(F[1]))/2/ฯ€);
77
78
## The analytical frequencies, for comparison
79
nx, ny = 0:4, 0:4
80
freq_analytical = cโ‚€/2*sqrt.((nx/Lx).^2 .+ (ny'/Ly).^2)
81
analytical_freqs = sort(freq_analytical[:])
82
println("FEM: ", round.(freq[2:10],digits=2))
83
println("Analytical: ", round.(analytical_freqs[2:10],digits=2))

As seen in Figureย 3, the FEM frequencies lie slightly above the analytical ones, and the difference grows with the frequency, as the mesh resolves the shorter wavelengths of the higher modes less accurately.

Figureย 3: The first nine nonzero mode frequencies of the 10ร—4 m room, analytical and computed with the FEM.

Cite this post

bibtex
@misc{paltorp2026femintroduction,
author = {Paltorp, Mikkel},
title = {{The Finite Element Method}},
year = {2026},
month = may,
url = {https://mipals.github.io/pdf/2026/05-11-fem-introduction/fem-introduction.pdf},
note = {Blog post}
}

Bibliography

  • [1] J.-F. Allard and N. Atalla, Propagation of Sound in Porous Media: Modelling Sound Absorbing Materials, 2nd ed. Wiley, 2009. doi: 10.1002/9780470747339.