Pavel Sumets - Computational Framework For The Finite Element Method in MATLAB® and Python-CRC Press (2022)
Pavel Sumets - Computational Framework For The Finite Element Method in MATLAB® and Python-CRC Press (2022)
Computational Framework for the Finite Element Method in MATLAB® and Python
aims to provide a programming framework for coding linear FEM using matrix-based
MATLAB® language and Python scripting language. It describes FEM algorithm imple-
mentation in the most generic formulation so that it is possible to apply this algorithm to
as many application problems as possible.
Readers can follow the step-by-step process of developing algorithms with clear explana-
tions of its underlying mathematics and how to put it into MATLAB and Python code.
The content is focused on aspects of numerical methods and coding FEM rather than
FEM mathematical analysis. However, basic mathematical formulations for numerical
techniques which are needed to implement FEM are provided. Particular attention is paid
to an efficient programming style using sparse matrices.
Features
• Contains ready-to-use coding recipes allowing fast prototyping and solving of math-
ematical problems using FEM
• Suitable for upper-level undergraduates and graduates in applied mathematics, science
or engineering
• Both MATLAB and Python programming codes are provided to give readers more
flexibility in the practical framework implementation
Pavel Sumets is a research and development software engineer from New Zealand whose
main interest and expertise are biomechanics, numerical methods and scientific program-
ming.
Taylor & Francis
Taylor & Francis Group
http://taylorandfrancis.com
Computational
Framework for the Finite
Element Method in
MATLAB® and Python
Pavel Sumets
MATLAB® is a trademark of The MathWorks, Inc. and is used with permission. The MathWorks
does not warrant the accuracy of the text or exercises in this book. This book’s use or discussion of
MATLAB® software or related products does not constitute endorsement or sponsorship by The
MathWorks of a particular pedagogical approach or particular use of the MATLAB® software.
Reasonable efforts have been made to publish reliable data and information, but the author and pub-
lisher cannot assume responsibility for the validity of all materials or the consequences of their use.
The authors and publishers have attempted to trace the copyright holders of all material reproduced
in this publication and apologize to copyright holders if permission to publish in this form has not
been obtained. If any copyright material has not been acknowledged please write and let us know so
we may rectify in any future reprint.
Except as permitted under U.S. Copyright Law, no part of this book may be reprinted, reproduced,
transmitted, or utilized in any form by any electronic, mechanical, or other means, now known or
hereafter invented, including photocopying, microfilming, and recording, or in any information stor-
age or retrieval system, without written permission from the publishers.
For permission to photocopy or use material electronically from this work, access www.copyright.
com or contact the Copyright Clearance Center, Inc. (CCC), 222 Rosewood Drive, Danvers, MA
01923, 978-750-8400. For works that are not available on CCC please contact mpkbookspermis-
[email protected]
Trademark notice: Product or corporate names may be trademarks or registered trademarks and are
used only for identification and explanation without intent to infringe.
DOI: 10.1201/9781003265979
Publisher’s note: This book has been prepared from camera-ready copy provided by the authors.
Contents
Introduction ix
v
vi ■ Contents
Conclusion 137
Bibliography 163
Index 165
Introduction
ix
x ■ Introduction
drawbacks. Although the pivot point of the book is the FEM algorithm,
various complementary tasks are considered. To be specific, the book
provides a programming framework for coding linear FEM algorithms
using the matrix-based MATLAB⃝ R
language and the Python scripting
language in application to solving ordinary and partial differential equa-
tions. Special attention is paid to building numerical algorithms and its
efficient implementation for both one- and two-dimensional problems. A
reader can follow a step-by-step process of developing algorithms with
explanations of their underlying mathematics and how to put them into
MATLAB and Python code with corresponding analysis of their effi-
ciency.
The content is focussed on aspects of numerical methods and cod-
ing FEM algorithms rather than FEM mathematical analysis; however,
basic mathematical formulations for numerical techniques needed to im-
plement FEM algorithms are provided.
Level of presentation:
The mathematical background is assumed to be covered by matrix
algebra, vector calculus and the basics of ordinary and partial differential
equations. It is going to be a demonstration of how the FEM works in
the one- and two-dimensional case, written as applied mathematicians
usually write it. The content throughout the book is not restricted to
either Laplace or Poisson equations but rather covers general linear el-
liptic boundary value problems. Unlike the majority of the books on the
FEM method which imply that a reader is familiar with structural me-
chanics, the current book is based on more generic formulations without
assuming any mechanics background. Structural finite elements are not
considered in examples and they are not discussed at all since, contrary
to expectations, the structural elements are much more complicated to
describe and use. They are left to an advanced FEM course. The book
has a number of appendices which contain more detailed explanations of
the numerical methods used in the main body of the book, so a reader
can refresh or enrich their corresponding knowledge.
We use MATLAB and Python as programming languages to code
the steps of the FEM algorithm. Throughout the book, the ideas of
coding are illustrated using MATLAB with complementary translation
to Python as well. Providing the code examples in both programming
languages is done to add flexibility in framework implementation.
In terms of programming background, it is expected that a reader is
familiar with basic matrix and vector manipulation using MATLAB and
the NumPy package in Python. Every code example given in the book
Introduction ■ xi
xiii
xiv ■ Background and Basic Concepts
differential equation. The final step is to solve the system and represent
the final solution through a piecewise interpolating polynomial.
Programming FEM involves coding various numerical methods and
binding them together into one pipeline. It is worth noting that every
piece of the pipeline matters as any error introduced at any stage prop-
agates further with accumulative effect which could invalidate the final
result. That is why coding numerical implementation is an important
part of numerical simulation which should not be underestimated. At a
high level, coding includes the following main stages: Firstly, an algo-
rithm of geometry discretization comes into play where final elements are
generated. Then, based on the shape and distribution of these elements,
implementation of particular numerical integration methods has to be
coded. The next important part is to define an algorithm of assembling
all these calculated values over individual finite elements into a matrix
which forms forming linear system to be solved numerically.
Once the FEM algorithm is coded, validation is carried out to make
sure that the implementation is correct. This is usually done against a
benchmark with a known analytical solution so that we can estimate
error and convergence of the method with various discretization param-
eters.
There are a large number of books on FEM including FEM math-
ematical analysis, coding FEM and solving application problems using
FEM which could be helpful for understanding FEM algorithms. For
example, a reader could find a comprehensive FEM analysis in [1] which
covers finite elements of different types. The book by [3] is focussed on
steady-state boundary value problems. It contains thorough theoretical
and practical aspects of implementing FEM and explains how to write
a finite element code from scratch. MATLAB implementation of FEM
algorithms with detailed descriptions of numerical analysis and mesh-
ing techniques can be found in [5] and [2]. Reading [4] and [7] is useful
to learn about using Python for scientific computing. For better un-
derstanding of how to use specific MATLAB tools to solve differential
equations, see documentation [6].
CHAPTER 1
DOI: 10.1201/9781003265979-1 1
2 ■ Computational Framework for the Finite Element Method
GLOSSARY
u, v, . . . : vectors are written using bold fonts.
P
n
(u · v): dot product of two vectors, u · v = ui vi .
i=1
C k (a, b): set of continuous functions that have continuous first k deriva-
tives.
L2 (a, b): space of functions defined on (a, b) for which the second power
of the absolute value is Lebesgue integrable. If v(x) ∈ L2 (a, b), then
Rb
∥v∥2L2 = a |v|2 dx < ∞.
Here, c(x), b(x), a(x) and f (x) are known functions; u(x) is unknown
function to be found, and u′ = du/dx. It is assumed that c ∈
C 1 [s0 , s1 ]; b, a, f ∈ C[s0 , s1 ] and c(x) > 0 ∀x ∈ [s0 , s1 ]. Negative sign in
equation (1.1) is for convenience and the reason of keeping this sign will
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 3
EXERCISES
▶ To see clearly how solution property depends on particular BC,
solve the equation
and show that it has unique solution for any value of parameter α.
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 5
f
f - Pr(f )
xzcv
1 v
H
Pr(f )
Zs1
′
−c(x)u′ (x) + b(x)u′ (x) + a(x)u(x) v(x)dx
s0
Zs1
= f (x)v(x)dx, (1.5)
s0
1
Integration by parts rule:
Zs1 Zs1 s1
′
u (x)v(x)dx = − u(x)v ′ (x)dx + (uv) .
s0
s0 s0
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 7
as follows.
EXERCISES
▶ Prove that (1.1)–(1.2) follow from (1.9). Instruction: take any point
x0 ∈ (s0 , s1 ); consider an interval [x0 − h, x0 + h] ⊂ (s0 , s1 ) and
use the expression (1.7) defined on this interval with v ∈ C 1 [s0 , s1 ]
and v(x) = 0 for x ∈ / [x0 − h, x0 + h]; perform passage to the limit
h → 0 and obtain (1.1).
▶ Deduce integral equation and define sets W and W 0 for the problem
(1.1) with following BC:
uh (xi ) = ui , i = 1, . . . , m + 1. (1.10)
Note that uh (x) is not the same as u(x), but rather an approximation,
which coincides with u(x) in a given set of nodes. Polynomial approxi-
mation uh (x) can be created in different ways, but we are interested in
Lagrange interpolating polynomials having the form
X
m+1 Y
m+1
x − xj
uh (x) = ui φi (x), φi (x) = . (1.11)
xi − xj
i=1 j=1,j̸=i
φi ∈ Gm , φi (xj ) = δij , j = 1, . . . , m + 1,
X
m+1
φi (x) = 1, x ∈ [s0 , s1 ]. (1.12)
i=1
2
Kronecker delta function is defined as:
(
0, if i ̸= j,
δij =
1, if i = j.
10 ■ Computational Framework for the Finite Element Method
βi X
m+1
βi
φi (x) = w(x) , uh (x) = w(x) ui , (1.13)
x − xi x − xi
i=1
where
−1
Y
m+1 Y
m+1
w(x) = (x − xj ), βi = (xi − xj ) , (1.14)
j=1 j=1,j̸=i
X
m+1 X
m+1
βi
1= φi (x) = w(x) ,
x − xi
i=1 i=1
and by using this fact, we come to the final form of the barycentric
interpolation formula
!−1 m+1
X
m+1
βi X βi
uh (x) = ui , (1.15)
x − xi x − xi
i=1 i=1
1.5
0.5
-0.5
0 0.5 1 1.5 2 2.5 3
2 3
2.5
1
2
1.5
0
1
0.5
-1
-2 -0.5
0 0.5 1 1.5 2 2.5 3 0 0.5 1 1.5 2 2.5 3
(a) (b)
uh (x) ∈ Gm , x ∈ ei , i = 1, . . . , n,
uh (xj ) = u(xj ), j = 1, . . . , N,
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 13
S
n
where h = max{hi , i = 1, . . . , n}. In other words, [s0 , s1 ] = ei and
i=1
function u(x) is interpolated on each subinterval ei through Lagrange
polynomial of the mth order.
1.5
0.5
-0.5
0 1 2 3 4 5 6
Now, we have come to the state when we are ready to give a definition
of the FEM corresponding to the BVP (1.1)–(1.2).
Zs1
cu′h vh′ + bu′h vh + auh vh dx + σuh (s1 )vh (s1 )
s0
Zs1
= f vh dx + µvh (s1 ). (1.18)
s0
1.5 1
0.8
0.6
0.5 0.4
0.2
-0.5 -0.2
0 1 2 3 4 5 6 0 1 2 3 4 5 6
(a) (b)
X
N X
N
uh (x) = uj φj (x) = us0 φ1 (x) + uj φj (x),
j=1 j=2
(1.19)
X
N
vh (x) = vi φi (x), x ∈ [s0 , s1 ],
i=1
or
uh (x) = φT u, vh (x) = φT v, (1.20)
where u = {ui }N
i=1 , v = {vi }i=1 and φ = {φi (x)}i=1 are column-vectors.
N N
3
Note that v0 = 0 by definition of subspace Wh0 to which vh belongs.
16 ■ Computational Framework for the Finite Element Method
Zs1
cv T φ′ (φ′ )T u + bv T φ(φ′ )T u + av T φφT u dx
s0
Zs1
T T
+ σv φ(s1 )φ(s1 ) u = f v T φdx + µv T φ(s1 ). (1.21)
s0
Zs1
F̃i = f φi dx + µφi (s1 ), (1.23)
s0
v T Ãu = v T F̃ . (1.24)
X
N
Ãij uj = F̃i − us0 Ãi1 , i = 2, . . . , N. (1.25)
j=2
From solving linear system (1.25), we obtain values for uj and the final
approximate solution to the BVP can be found using the first formula
in (1.19).
4
Here, we use the fact that
Elements of the stiffness matrix and forcing vector are calculated us-
ing expressions (1.22) and (1.23); however, it is impractical to use these
formulas directly. Below, we consider efficient method of assembling ma-
trices and derive corresponding computational algorithm for calculating
their elements.
EXERCISES
▶ Plot the Lagrange basis functions corresponding to the spline with
final elements e1 = [0, 1], e2 = [1, 2] and e3 = [2, 3] having nodes
{x1 = 0, x2 = 1, x3 = 2, x4 = 3} (linear basis functions).
▶ Deduce a linear system of the FEM corresponding to the following
BC:
It can be seen from comparing with generic BVP (1.1)–(1.2) that the
problem (1.26) corresponds to the coefficient values c(x) = 1, b(x) =
0, a(x) = 1, σ(x) = 0, µ(x) = 1. Consider a three-element discretiza-
tion of [0, 1] with nodes {x1 = 0, x2 = 1/3, x3 = 2/3, x4 = 1}.
1 1 2 2
e1 = 0, , e2 = , , e2 = ,1 . (1.28)
3 3 3 3
There are four basis functions associated with four interpolation nodes
which gives the following form of the approximate solution
1 2
uh = u(0)φ1 (x) + u φ2 (x) + u φ3 (x) + u(1)φ4 (x). (1.29)
3 3
Function value u(0) = 1 is known from the BC and the rest values,
u(1/2), u(2/3) and u(1) have to be found.
In each element there are just two nodes; hence, the interpolation
polynomials for each element must be linear. Basis functions associated
with each node are found from (1.11) and have the form
(
−3x + 1, 0 ≤ x ≤ 13 ,
φ1 (x) = 1
(1.30)
0, 3 < x < 0,
3x, 0 ≤ x ≤ 13 ,
φ2 (x) = −3x + 2, 31 ≤ x ≤ 23 , (1.31)
2
0, 3 < x < 0,
3x − 1, 3 ≤ x ≤ 3,
1 2
0.8
0.6
0.4
0.2
0
0 0.2 0.4 0.6 0.8 1
1
Z1 Z3
Ã12 = Ã21 = φ′1 φ′2 + φ1 φ2 dx = ·dx, (1.36)
0 0
Z1
Ã13 = Ã31 = φ′1 φ′3 + φ1 φ3 dx = 0, (1.37)
0
20 ■ Computational Framework for the Finite Element Method
Z1
Ã14 = Ã41 = φ′1 φ′4 + φ1 φ4 dx = 0, (1.38)
0
1 2
Z1 Z3 Z3
2
Ã22 = φ′2 + (φ2 )2 dx = ·dx + ·dx, (1.39)
0 0 1
3
2
Z1 Z3
Ã23 = Ã32 = φ′2 φ′3 + φ2 φ3 dx = ·dx, (1.40)
0 1
3
Z1
Ã24 = Ã42 = φ′2 φ′4 + φ2 φ4 dx = 0, (1.41)
0
2
Z1 Z3 Z1
2
Ã33 = φ′3 + (φ3 )2 dx = ·dx + ·dx, (1.42)
0 1 2
3 3
Z1 Z1
Ã34 = Ã43 = φ′3 φ′4 + φ3 φ4 dx = ·dx, (1.43)
0 2
3
Z1 Z1
2
Ã44 = φ′4 + (φ4 ) 2
dx = ·dx. (1.44)
0 2
3
We can see that due to the symmetry of formula (1.34), index order is
not important and the stiffness matrix becomes symmetrical. In addi-
tion, elements Ã13 , Ã31 , Ã14 , Ã41 , Ã24 and Ã42 equal to zero since
corresponding, basis functions are non-overlapping, which gives zeroth
integrands (the only coupling occurs between nodes associated with the
same element). Also, the domain integrals over the interval [0, 1] can be
replaced by the sum of integrals taken separately over the finite elements
and only those integrals can be left which have non-zero values. Elements
Ã22 and Ã33 include two integrals because corresponding integrands are
non-zero over two finite elements. As a result, the stiffness matrix can
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 21
Z1 Z1
′ 2
1 1 28
Āe222 = (3(1 − x̂) ) + (1 − x̂) dx̂ = 2
9 + (1 − x̂)2 dx̂ = .
3 3 9
0 0
(1.49)
Z1
1 53
Āe232 = (−9 + (1 − x̂)x̂) dx̂ = − . (1.50)
3 18
0
Z1
1 28
Āe332 = 9 + x̂2 dx̂ = . (1.51)
3 9
0
Z1
1 28
Āe333 = 9 + (1 − x̂)2 dx̂ = . (1.52)
3 9
0
Z1
1 53
Āe343 = (−9 + (1 − x̂)x̂) dx̂ = − . (1.53)
3 18
0
Z1
1 28
Āe443 = 9 + x̂2 dx̂ = . (1.54)
3 9
0
Once the local stiffness matrices Āe1 , Āe2 and Āe3 are found, the final
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 23
Z1
F̃i = xφi dx + φi (1), i = 1, 2, 3, 4. (1.56)
0
Following the same logic as for stiffness matrix, let us consider individual
integrals and deduce vector formation pattern.
1
Z1 Z3
F̃1 = xφ1 dx + φ1 (1) = xφ1 dx, (1.57)
0 0
1 2
Z1 Z3 Z3
F̃2 = xφ2 dx + φ2 (1) = xφ2 dx + xφ2 dx, (1.58)
0 0 1
3
2
Z1 Z3 Z1
F̃3 = xφ3 dx + φ3 (1) = xφ3 dx + xφ3 dx, (1.59)
0 1 2
3 3
Z1 Z1
F̃4 = xφ4 dx + φ4 (1) = xφ4 dx + 1. (1.60)
0 2
3
Here, we take into account the fact that only φ4 (1) is non-zero with the
unity value. By splitting domain integral into individual integrals over
the finite elements, we come to the following schematic representation
24 ■ Computational Framework for the Finite Element Method
2
Z3 Z1
1 2
F̄2e2 = x(−3x + 2)dx = (1 + x̂)(1 − x̂)dx̂ = . (1.64)
9 27
1 0
3
2
Z3 Z1
1 5
F̄3e2 = x(3x − 1)dx = (1 + x̂)x̂dx̂ = . (1.65)
9 54
1 0
3
Z1 Z1
1 7
F̄3e3 = x(−3x + 3)dx = (2 + x̂)(1 − x̂)dx̂ = . (1.66)
9 54
2 0
3
Z1 Z1
1 4
F̄4e3 = x(3x − 2)dx = (2 + x̂)x̂dx̂ = . (1.67)
9 27
2 0
3
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 25
From (1.55) and (1.68), the equations can be written in the form
28 1
9 − 53
18 0 0 1 54
− 53 56
− 53 u 1 1
18 9 18 0 3 9
53 2 = , (1.69)
0 − 18
53 56
9 − 18 u 3 29
0 0 − 53
18
28
9
u(1) 31
27
or 53
28 − 18 0
9 56 53
− 53
18 1 9 2 − 18
0 + u + u
3 − 53 3 56 9
18
0 0 − 53
18
1 (1.70)
0 54
0 9
1
+u(1)
53
− 18 = .
29
28 31
9 27
Note that BC specifies u(0) = 1 and there are only three unknowns left
in the system (1.70). Then, moving first vector in (1.70) to the right
hand side of the equation and removing first row in the entire system
(see (1.25)) we come to the final linear system for the function values
56 1 55
− 53 0 u 3
9
53
18
53
2
18
2
− 18 56
9 − 18 u 3 = 9 . (1.71)
0 − 53
18
28
9 u(1) 31
27
• Delete the first row of the matrix à and the first element of
the vector F̃ .
• Calculate F̃ = F̃ − us0 Ã1 , where Ã1 is the first column of
the matrix Ã.
• Delete the first column of the matrix Ã.
Now, let us consider more closely an integral over a local finite el-
ement el and determine only those basis functions which are nonzero
over the element el . It is easy to see that lth element spans the points
xm(l−1)+1 , . . . , xml+1 , or, by introducing a local numeration index β =
1, . . . , m + 1 and a global starting index notation nl = m(l − 1), we can
write that xnl +β ∈ el . As a result, φnl +β are the basis functions associ-
ated with el which are nonzero over this element. These nonzero values
form a matrix Āl ∼ ((m + 1) × (m + 1)) with elements
xnZ
l +m+1
Ālαβ = cφ′nl +α φ′nl +β + bφnl +α φ′nl +β + aφnl +α φnl +β dx,
xnl +1
α, β = 1, . . . , m + 1. (1.75)
28 ■ Computational Framework for the Finite Element Method
Definition 1.9 Matrix (1.75) is called a local stiffness matrix of the lth
finite element.
Note that the extended local forcing vector, F l , contains all zero elements
except of values defined by the local forcing vector (1.79).
Matrix S and vector M result from the boundary conditions and
they are specified at the single point s1 . Since φi (xj ) = δij and s1 = xN ,
then each of S and M has the single nonzero value, namely, SN N = σ
and MN = µ.
As a result, we come to the algorithm for assembling stiffness matrix
and forcing vector.
• AN N = AN N + σ .
• FN = FN + µ.
Y
m+1
x − xnl +j
φnl +α (x) = , x ∈ [xnl +1 , xnl +m+1 ], (1.80)
xnl +α − xnl +j
j=1,j̸=α
and el = [xnl +1 , xnl +m+1 ] → ê = [0, 1], ∀nl . As a result, any finite
element is transformed into a canonical, or basis, element of the unity
length. Moreover, substitution (1.81) into (1.80) gives
Y
m+1
x̂ − x̂j
φnl +α (x) = φnl +α (xnl +1 + x̂hl ) = = φ̂α (x̂), (1.82)
x̂α − x̂j
j=1,j̸=α
where basis functions φ̂α are now expressed in terms of the local variable
x̂. If we denote fˆ = f (xnl +1 + x̂hl ), then integral (1.78) can be rewritten
as
Z1
F̄αl = hl fˆφ̂α dx̂, α = 1, . . . , m + 1. (1.83)
0
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 31
Z1
Ālαβ = (h−1 ′ ′ ′
l ĉφ̂α φ̂β + b̂φ̂α φ̂β + hl âφ̂α φ̂β )dx̂, α, β = 1, . . . , m + 1.
0
X
q
Ālαβ ≈ γ̂k (h−1 ′ ′ ′ ˆ
l ĉφ̂α φ̂β + b̂φ̂α φ̂β + hl âφ̂α φ̂β )(dk ),
k=1
α, β = 1, . . . , m + 1. (1.85)
where
l ˆ
 = hl diag γ̂1 â(d1 ), . . . , γ̂q â(dq ) , ˆ
B̂ l = diag γ̂1 b̂(dˆ1 ), . . . , γ̂q b̂(dˆq ) ,
Ĉ l = h−1
l diag γ̂ 1 ĉ( ˆ
d1 ), . . . , γ̂ q ĉ( ˆ
dq ) .
X
m+1 X
m+1
uh (x) = φnl +α (x)unl +α = φ̂α (x̂)unl +α = φ̂(x̂)T ul ,
α=1 α=1
u = {unl +α }m+1
l
α=1 , x ∈ el .
Y
m+1
x̂ − x̂j
φ̂α (x̂) = ,
x̂α − x̂j
j=1,j̸=α
6. Calculate the local stiffness matrix and the local forcing vector:
Āl = D̂T Ĉ l + Ê T B̂ l D̂ + Ê T Âl Ê,
l l
F̄ = Ê T F̂ .
34 ■ Computational Framework for the Finite Element Method
Z1 Z1
1X ˜ ˜ X
q q
1
fˆdx̂ = f˜dx̃ ≈ γ̃k f (dk ) = γ̂k fˆ(dˆk ),
2 2
0 −1 k=1 i=1
1 1 d˜k
γ̂k = γ̃k , dˆk = + .
2 2 2
It is worth mentioning that Gaussian quadrature is a type of quadrature
formula, which has the highest order of precision with the given number
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 35
21 21
20 20
19 19
18 18
17 17
16 16
15 15
14 14
13 13
12 12
11 11
10 10
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
(a) (b)
theory that
Zs1 k 2 !
hk−1 d u
∥u − uh ∥H 1 ≤ C k−1 ∥u∥H k , ∥u∥2H k = u2 + k dx.
m dx
s0
• number of nodes q ≥ m,
.
Finite Element Method for the One-Dimensional Boundary Value Problem ■ 39
Programming
One-Dimensional Finite
Element Method for the
Linear Boundary Value
Problem
DOI: 10.1201/9781003265979-2 41
42 ■ Computational Framework for the Finite Element Method
stiffness matrices and BC. As a last step, the high-level main function
will be considered which implements logic of algorithm 1.
The main data structure used in the code implementation is a matrix,
so it is assumed that a reader is familiar with basic skills of matrix
manipulation commands in MATLAB and Python. There is, however, a
special case of matrices which we will discuss in detail, namely, sparse
matrices. As we have seen from chapter 1, FEM results in matrices with
sparse structure which we need to reflect in coding.
1. Creating a sparse matrix from the full one. In this case the argu-
ment of the function sparse() is a dense matrix and returning value
is a sparse matrix with the shape and values of the dense one. For
example,
B =[1 3 0
0 4 0
2 0 5 ] ;
A = sparse (B)
A = (1 ,1) 1
(3 ,1) 2
(1 ,2) 3
(2 ,2) 4
(3 ,3) 5
(2) functions c(x), b(x), a(x) and f (x) specifying BVP coefficients;
There is nothing special about item (1) while representation of (2) and
(3) in terms of MATLAB structures needs to be clarified. Functions in
MATLAB can be defined either through anonymous inline declaration
f = @(x) sin(x)
or using stand-along .m file containing function definition
function y=f(x)
y=sin(x);
end
and returns a pair of vectors, d and w, which are quadrature nodes and
weights accordingly. Here, quadrature nodes are zeroes of Legendre poly-
nomial. The function can take either three or one argument and in case
of a single argument, it is assumed the nodes are sought on the interval
[−1,1]. This logic is implemented in lines 2–4 with MATLAB function
nargin which returns the number of function input arguments given in the
call to the currently executing function. The code lines 8–10 compute
the elements of matrix Q (see (1.87)) and compose the matrix using di-
agonal assembling. Function diag(bta,k) places the elements of vector bta
on the k-th diagonal (k=0 represents the main diagonal, k=1 is above the
main diagonal, and k=−1 is below the main diagonal). Then, we perform
eigen value decomposition (line 11) and extract sorted eigen values (line
12). To perform eigen values extraction, first, we use MATLAB function
diag() which being called with matrix L returns its main diagonal, then
we call the function sort() which returns sorted nodes, d, and it also re-
turns an index vector, k, that describes the rearrangement of elements
such that d = L(k,:). We need this index vector to keep correspondence
between sorted eigen values and unsorted eigen vectors, U. The last step
is to calculate weights on the interval [−1,1] (line 13) and to perform
transformation for extended region [s0,s1] (lines 14–15). Note that all
calculations here are vectorized, namely, we do not use loops to iterate
over vector or matrix elements, but rather use vectors itself in calcu-
lation formulas. This significantly improves performance and simplifies
code readability.
1 function [d,w] = GaussQuad (n,s0 ,s1)
2 if nargin ==1
3 s0=−1; s1 =1;
4 end
5 if n==1
6 d=(s0+s1 )/2; w=s1−s0; return ;
7 end
8 j=1:n−1; bta=j./ sqrt(4∗ j.^2−1); Q=diag(bta,−1)+diag(bta ,1);
9 [U,L]= eig(Q);
10 [d,k]= sort(diag(L));
11 w=2∗ U(1,k).^2; w=w(:);
12 d=s0+0.5 ∗ (s1−s0)∗(d+1);
13 w=0.5 ∗ (s1−s0)∗ w;
14 end
Y
m+1
Êk,α = φ̂α (dˆk ) = βα (dˆk − x̂j ), (2.2)
j=1,j̸=α
X
m+1 Y
m+1
D̂k,α = φ̂′α (dˆk ) = βα (dˆk − x̂j ). (2.3)
l=1,l̸=α j=1,j̸=α,j̸=l
13 for l=j
14 i1=min(i,l); i2=max(i,l);
15 jj =[1:(i1 −1),(i1 +1):( i2 −1),(i2 +1): nx];
16 ds=ds+prod(d(k)−x(jj ));
17 end
18 D(k,i)=b(i)∗ ds;
19 end
20 end
21 end
13 y( i ref )=E∗u( i c );
14 dy( i ref )=D∗u( i c )/h;
15 end
16 end
EXERCISES
▶ Verify that the number of operations to calculate E and D using
function interpolatingMat() has the order of O(nx2 nd) and O(nx3 nd),
respectively.
▶ Show that when x=d then the matrix D can be calculated through
βj X
n
D̂ij = , i ̸= j, D̂ij = − D̂ij .
βi (x̂i − x̂j )
j=1,j̸=i
22 end
23 I=(ib:ie)’;
24 A0=A(I,I);
25 F0=F(I);
26 end
Once the final stiffness matrix, A0, and forcing vector, F0, are created
using function assemblingBC(), resulting FEM system can be solved and
solution can be composed according to the steps 4 and 5 of algorithm 1.
Function solveFEM() in listing 2.7 returns the final solution, u. The code
lines 12–13 call linear solver (backslash MATLAB operator) and append
Dirichlet BC if any (u s0 and u s1).
1 function u = solveFEM (bc ,A0 ,F0)
2 u s0 =[]; u s1 =[];
3 if bc (1 ,1)==1 , u s0 =bc (1 ,3) ; end
4 if bc (2 ,1)==1 , u s1 =bc (2 ,3) ; end
5 u0=A0\F0;
6 u=[ u s0 ;u0; u s1 ];
7 end
Function errorNorm() which code is given in listing 2.9 calculates and out-
puts these norms. Here, e0 is a value of L2 error norm, e1 is a value of
H 1 error norm, u and du are exact solution and its derivative, y is an
FEM solution, xl is a vector of finite element nodes and d is a vector
of interpolation points on the basis element [0,1]. Function errorNorm()
uses Gaussian quadrature to calculate the norms, and interpolating and
differentiating matrices to find corresponding values of the solution.
1 function [e0 ,e1]= errorNorm (u,du ,y,xl ,d)
2 m=numel(d)−1;
3 [ d new ,w]= GaussQuad (m+2 ,0 ,1);
4 [E,D]= interpolatingMat (d, d new );
5 e0 =0; e1 =0;
6 for l=1: numel(xl)−1
7 h=xl(l+1)−xl(l);
8 dl=xl(l)+h∗ d new ;
9 ic=(l−1)∗m+(1:m+1);
10 uh=E∗y(ic); duh=D∗y(ic )/h;
11 e=u(dl)−uh; de=du(dl)−duh;
12 e0=e0+h/2∗ sum(w.∗ e .^2); e1=e1+h/2∗ sum(w.∗ de .^2);
13 end
14 e0=e0 ^(1/2); e1=e1 ^(1/2);
15 end
Plots generated by this script are shown in figures 2.1, 2.2 and 2.3
where the finite element nodes are indicated as circles and crosses are
quadrature nodes which coincide with interpolation nodes.
Estimations of numerical error for the FEM solution are given in
table 2.1. It can be seen that implementation of the FEM algorithm
performs numerical calculations with acceptable accuracy.
0.5
h
0
u
-0.5
-1
-1 -0.5 0 0.5 1
x
EXERCISES
▶ Find numerical solution to the problems given below with known
exact solutions. Boundary conditions of the first type may be cho-
sen to close BVP. Specify your own values for parameter ε. Perform
analysis of the solution behaviour when ε becomes small. Choose
different FEM parameters and make observation regarding changes
Programming One-Dimensional Finite Element Method ■ 57
8e-06
6e-06
4e-06
2e-06
h
u-u
-2e-06
-4e-06
-6e-06
-1 -0.5 0 0.5 1
x
FIGURE 2.2: Absolute error of the FEM solution to the problem (2.4).
0.0004
0.0003
0.0002
0.0001
h
u’-u’
-0.0001
-0.0002
-0.0003
-1 -0.5 0 0.5 1
x
Python listings given below contain functions which names and func-
tionality repeat ones written in MATLAB, so notations of arguments and
returning values have consistent with MATLAB counterparts meaning.
While providing Python implementation of particular function, the fo-
cus will be on specific Python language features which differ the code
from MATLAB version rather than on describing logic, which already
has been discussed in previous sections.
Let us look into Python implementation of Gaussian and Lobatto
quadrature rules (see listings 2.12 and 2.13). By design, arguments s0
and s1 can be omitted, so the code line 2 retrieves the number of ac-
tual input arguments and stores it in the variable nargin. This is done
through the function locals() which returns a vector of arguments, and
the function len() returning vector length.
We can see in the code arithmetic calculation of the form j∗∗2, which
implements raising j to the second power. The function numpy.diag(bta,k)
constructs a diagonal matrix from a given array, bta, and a diagonal posi-
tion, k. The function linalg.eig(Q) computes eigenvalues and eigenvectors
of the matrix Q. To obtain ordered eigenvalues, function numpy.argsort(L)
is used which returns the indices that would sort the array L.
1 def GaussQuad (n,s0 ,s1 ):
2 nargin =len( locals ())
3 d=[]; w=[]
4 if nargin ==1:
Programming One-Dimensional Finite Element Method ■ 61
5 s0=−1; s1=1
6 if n==1:
7 d=(s0+s1 )/2; w=s1−s0
8 return d,w
9 j=numpy. arange (1,n)
10 bta=j/numpy.sqrt(4∗(j∗∗2)−1)
11 Q=numpy.diag(bta , k=−1)+numpy .diag(bta , k=1)
12 L,U = numpy. linalg .eig(Q)
13 k=numpy. argsort (L)
14 d=L[k]; w=2∗(U[0][k]∗∗2)
15 d=s0+0.5 ∗ (s1−s0)∗(d+1)
16 w=0.5 ∗ (s1−s0)∗ w
17 return d,w
16 i1=min(i,l); i2=max(i,l)
17 jj=numpy. delete ( j all ,[i1 ,i2 ])
18 ds=ds+ numpy .prod(d[k]−x[jj ])
19 D[k,i]=b[i]∗ ds
20 return E,D
7 if bc [0 ,0]==3:
8 A[0 ,0]=A[0 ,0]+ bc [0 ,1]
9 F[0]=F[0]+ bc [0 ,2]
10 if bc [1 ,0]==3:
11 A[n,n]=A[n,n]+ bc [1 ,1]
12 F[n ,0]=F[n ,0]+ bc [1 ,2]
13 #set boundary conditions of the first type
14 ib =0; ie=n+3
15 if bc [0 ,0]==1:
16 ib =1; u s0 =bc [0 ,2]
17 F=F−u s0 ∗A[: ,0]
18 if bc [1 ,0]==1:
19 ie=n+2; u s1 =bc [1 ,2]
20 F=F−u s1 ∗A[:,n]
21 A0=A[ib:ie ,ib:ie]
22 F0=F[ib:ie ,0]
23 return A0 ,F0
DOI: 10.1201/9781003265979-3 69
70 ■ Computational Framework for the Finite Element Method
GLOSSARY
f (x): a function of multiple variables.
u(x) = uD (x), x ∈ ΓD ,
c(x)∇u · ν(x) + σ(x)u = µ(x), x ∈ ΓR .
Here, ΓD and ΓR are the boundary parts for Dirichlet and Robin bound-
ary conditions, respectively, and either of them could be empty (in this
case the corresponding boundary condition is omitted); Γ is supposed
to be closed; ν(x) is the unit outward normal vector at the point x.
Functions c, a, f, uD , σ, µ and b(x) = (b1 (x), b2 (x))T are known
and supposed to be piecewise smooth. The model problem (3.1) can be
reduced to variety of particular problems with appropriate definition of
the coefficients, for example, when c(x) = 1, b(x) = a(x) = 0 we come
to a Poisson’s equation.
Let us reformulate the problem (3.1) in terms of integral equations.
First, we consider function sets W and W 0
W = w ∈ H 1 (Ω) : w(x) = uD (x), x ∈ ΓD ,
W 0 = w ∈ H 1 (Ω) : w(x) = 0, x ∈ ΓD ,
1 1
0.8 0.8
0.6 0.6
2
2
x1
x
0.4 0.4
0.2 0.2
0 0
0 0.2 0.4 0.6 0.8 1 0 0.2 0.4 0.6 0.8 1
x x1
1 1
(a) (b)
FIGURE 3.1: Examples of the triangulation with three (a) and six (b)
interpolation points over a triangle element.
X
np
vh (x) = vi φi (x),
i=1
Z Z
F̃i = f (x)φi dx + µ(x)φi dx (3.6)
Th Γh
R
Similarly,
Z Z
F̃ = F + M , Fi = f φi dx, Mi = µφi dx, i = 1, . . . , np .
Th Γh
R
4
Note that S is a symmetric matrix; A is a symmetric matrix provided b = 0.
Finite Element Method for the Two-Dimensional Boundary Value Problem ■ 75
which is the local stiffness matrix of the finite element τl . Now, we can
express global matrix in terms of local stiffness matrices by introducing
extended local stiffness matrix Al ∼ (np ×np ) so that matrix Al contains
zeros except of elements with indices tαl and tβl , and
X
nt
A= Al .
l=1
The latter expression indicates that the global stiffness matrix A can
be obtained by summation of the extended local stiffness matrices, Al .
Since there is no sense to sum up zeros, we come to the algorithm of
composing global matrix A (see algorithm 4).
3. For each l = 1, 2, . . . , nt :
2. For each l = 1, 2, . . . , nt :
l
(a) calculate F̄ ∼ (mτ × 1) :
Z
l
F̄α = f (x)φtαl (x)dx
τl
9. Solve linear system (3.7) and find the vector of nodal values u for
the solution uh ;
Building
Two-Dimensional
Meshes
irst four steps of the FEM algorithm given in section 3.6 will be
F covered in this chapter. We will describe how to define geometry of
a problem and build two-dimensional triangular mesh using MATLAB
and Python tools. Basic data structure for the mesh representation will
be considered.
Basically, generating geometry for a domain with simple boundary
shape is not a challenge; however things become more complicated when
a geometry has subdomains or nontrivial boundary shape. In general,
the problem of generating geometry can be viewed as having two tasks:
geometry definition through some data structure, and performing tri-
angulation to build finite elements. In this chapter we are focussed on
the first task, namely, various approaches of how to create data struc-
tures for geometry definition and how to represent mesh in a matrix
form. Questions of how to encode boundary and build geometry will be
discussed as well.
To perform triangulation itself using predefined geometry definition,
we are going to use specific MATLAB and Python tools. Triangula-
tion algorithm implementation is not discussed below and it is beyond
the scope of the book, but rather existing implementation as a tool or
third-party library is used. Interested reader can find mesh generating
algorithms in [3] where some triangulation techniques are discussed.
DOI: 10.1201/9781003265979-4 79
80 ■ Computational Framework for the Finite Element Method
where xstart = x(0) and xend = x(1) are starting and ending points of
a line segment. A circle segment has a parametric form
x1 (s) = r cos(s)+xcentre
1 , x2 (s) = r sin(s)+xcentre
2 , s ∈ [s0 , s1 ], (4.2)
Sparam = 1 1 1 1 1 1 1 1 1 1 1 3π
2
2π π2 π
03313300033 0 0 0 0
12200213321 1 1 1 1
2 1.25 1.25 2 2 0.75 0 0 0 0.75 0
0 1.25 0.75 2 2 1.25 0 0 2 0.75 2
X1 X2 = −1 0.75 0.25 −1 0 0.75 −1 0 1 0.25 0
−1 0.25 0.25 0 1 0.75 0 1 1 0.75 0
Here, matrix Sparam ∼ (4 × 15) has 15 columns with one column per
boundary segment. Columns from first to eleventh are for straight line
segments and from twelve to fifteen are for circle segments. First and
second rows of Sparam contain parameter values for starting and end-
point of the corresponding segment, third and fourth rows contain la-
bels of the left hand and right hand regions correspondingly. Matrix
X1 X2 ∼ (4 × 11) encodes coordinates of straight line segments with one
column per segment. Here, first two rows are x1 coordinates of starting
and endpoints, and the last two rows are x2 coordinates of line segments
correspondingly. Having matrices Sparam and X1 X2 along with formu-
las (4.1) and (4.2) allows calculating coordinates of any point on the
boundary given an index of boundary segment. In general, quite compli-
cated geometries (not only lines and circles) can be represented through
parametric form and encoded in the similar way.
Here, we introduce a MATLAB function geometryFunction(b index , s)
which returns (x1 , x2 ) coordinates of a boundary point for any segment
with index b index and parameter value s. Parameter b index can be either
scalar or vector and it is allowed to omit parameters. Function call with a
single argument, geometryFunction(b index), returns corresponding entries of
the matrix Sparam with one column for each boundary segment specified
in b index. If the function is called without arguments, geometryFunction(),
it returns total number of boundary segments.
1 function [x1 ,x2]= geometryFunction ( b index , s)
2 % Geometry data
3 s param =[ 0 0 0 0 0 0 0 0 0 0 0 pi 3/2∗ pi 0 pi /2
4 1 1 1 1 1 1 1 1 1 1 1 3/2∗ pi 2∗ pi pi /2 pi
Building Two-Dimensional Meshes ■ 83
5 0 3 3 1 3 3 0 0 0 3 3 0 0 0 0
6 1 2 2 0 0 2 1 3 3 2 1 1 1 1 1 ];
7 x1x2 =[2 1.25 1.25 2 2 0.75 0 0 0 0.75 0
8 0 1.25 0.75 2 2 1.25 0 0 2 0.75 2
9 −1 0.75 0.25 −1 0 0.75 −1 0 1 0.25 0
10 −1 0.25 0.25 0 1 0.75 0 1 1 0.75 0 ];
11 if nargin ==0 , x1=size( s param ,2); return ; end
12 if nargin ==1 , x1= s param (:, b index ); return ; end
13 x1= zeros (size(s));
14 x2= zeros (size(s));
15 [m,n]= size( b index );
16 if m==1 && n==1, b index = b index ∗ones(size(s)); end
17 if ~ isempty (s),
18 % line segments
19 for k=1:11
20 i=find( b index ==k);
21 if ~ isempty (i)
22 x1(i)= x1x2 (1,k)+( x1x2 (2,k)−x1x2 (1,k))∗ s(i);
23 x2(i)= x1x2 (3,k)+( x1x2 (4,k)−x1x2 (3,k))∗ s(i);
24 end
25 end
26 % circle segments
27 for k =12:15
28 i=find( b index ==k);
29 if ~ isempty (i)
30 c x1 =1; c x2=−0.5; rc =0.25;
31 x1(i)=rc∗cos(s(i))+ c x1 ;
32 x2(i)=rc∗sin(s(i))+ c x2 ;
33 end
34 end
35 end
36 end
0.5
-0.5
-1
0 0.5 1 1.5 2
In general, the mesh data structure should serve two main purposes.
Firstly, it should provide information about triangle vertices to allow
performing interpolation on elements. Secondly, it should contain in-
formation about element edges which belong to boundary segments to
correctly apply BC. As such, the mesh data should encapsulate infor-
mation about mesh points, their connectivity to form triangles (finite
elements) and relation between element edges and boundary segments.
One of the most convenient forms of mesh representation which has be-
came an industry standard is a matrix form. Three matrices, P, T and
E , store all necessary information which allow apply FEM interpolation
algorithms. Below we discuss them individually.
Given enumerated np mesh points, let us form a matrix P ∼ (2 × np )
which stores coordinates of mesh points (triangle vertices) so that for
ith point coordinate x1 = P1,i and x2 = P2,i . Matrix P can be used to
access any mesh points but it does not keep any information about mesh
elements formation.
Structure representing how mesh triangles are formed from the set
of vertices is called connectivity matrix, T . Given a number of triangles,
nt , matrix T ∼ (4 × nt ) stores indices of vertices for each triangular ele-
ment and corresponding subdomain label to which this triangle belongs.
Elements T1,j , T2,j and T3,j are the indices of vertices of the j th triangle
(counted anticlockwise), element T4,j is the subdomain label. Note that
the matrix T is formed using indices of points from matrix P , so the
order in which points are arranged in P is important.
The last structure is an edge matrix, E , which stores information
regarding finite element edges belonging to the boundary segments (in-
ternal and external). Given a number of edges, ne , matrix E ∼ (7 × ne )
contains the following information. Elements E1,k and E2,k contain in-
dices of vertices belonging to the k th edge (vertex index with respect
to matrix P ), elements E3,k and E4,k are the corresponding parameter
values s0 and s1 for parametric representation, element E5,k is the index
of boundary segment to which the edge belongs, elements E6,k and E7,k
are the subdomain labels from the left and right hand side of the edge
according to the parameterization direction.
To better understand mesh encoding, let us consider a simple case of
L-shaped geometry given in figure 4.4 with 3 subdomains and 10 bound-
ary segments (8 external and 2 internal segments). Splitting each square
(subdomain) into two triangles results in rough mesh with 6 finite ele-
ments. In figure 4.4, all points and boundary segments are enumerated.
86 ■ Computational Framework for the Finite Element Method
2
1 3 4
10 6
0.5
7 8
2
0 1 8 7
x
1 9 5
-0.5
3 4
-1 2 5 6
-1 -0.5 0 0.5 1
x
1
Matrices P, T and E for the mesh shown in figure 4.4 have the form
−1 −1 0 1 0 1 1 0
P = ,
0 −1 1 1 −1 −1 0 0
1 4 7 2 5 6
2 3 4 5 6 7
T =
8
,
8 8 8 8 8
2 1 1 2 3 3
1 3 2 5 6 7 1 8 5 8
2 4 5 6 7 4 8 7 8 3
0 0 0 0 0 0 0 0 0 0
E=
1 1 1 1 1 1 1 1 1 1.
1 2 3 4 5 6 7 8 9 10
2 0 2 3 3 1 0 1 2 0
0 1 0 0 0 0 2 3 3 1
Building Two-Dimensional Meshes ■ 87
Matrix Text for the mesh given in figure 4.4 takes the form
1 0 0 0 0 0
1 0 0 1 0 0
0 1 0 0 0 0
0 1 1 0 0 0
Text =
0 0
,
0 1 1 0
0 0 0 0 1 1
0 0 1 0 0 1
1 1 1 1 1 1
It can be seen that ith mesh node is the vertex of triangles with indices
it(pt(i):pt(i+1)−1).
Resolving 2nd and 3rd questions. Let us introduce two complementary
matrices E c and T c as follows:
1
The matrix has only 7 rows if all segments are straight lines.
Building Two-Dimensional Meshes ■ 93
File lshapeg.m for this geometry is provided in the MATLAB pde toolbox
(parameter inf indicates building rough mesh). Figure 4.4 shows trian-
gulation with given labels of triangles, edges and vertices and function
plotG1mesh() plots this triangulation.
Similarly, complementary mesh discussed in section 4.3 can also be
labelled with corresponding indices using following script
[p,e,t]= initmesh (’lshapeg ’,’hmax ’,inf );
[ e c , t c ]= complMeshG1 (p,e,t);
plotComplMeshG1 (p,e,t, e c ,12);
17 end
18 for i=1: size(t ,2) % element labels
19 I=t(1:3 ,i);
20 text(sum(p(1,I))/3 , sum(p(2,I))/3 , int2str (i), ...
21 ’FontSize ’,fs−1,’Color ’,’b’);
22 end
23 end
As a result, we obtain figure 4.5 with given indices for mesh points,
triangle elements and edges. Boundary edges are marked with two num-
bers: index of the edge and index of the boundary segment.
2
1 3 5 4
2
10 6
0.5 6 8 7
7 8
2
0 1 2 8 13 7
x
1 6
1 9 5
-0.5 1 4 10 12 11
4 5
3 4
-1 2 3 5 9 6
-1 -0.5 0 0.5 1
x
1
for mesh processing rather than discussing particular mesh building al-
gorithm. There is a powerful mesh generation tool, named Gmsh, having
its own scripting language allowing creating complex geometries. The
library PyGmsh provides a Python interface for the Gmsh scripting language
so one can create geometry and generate meshes more easily with excess
to Python’s features. After installing PyGmsh, the default Gmsh kernel with
basic geometry construction functions can be used.
Module PyGmsh has a class Geometry to represent a geometry in the
following way: first, it is to be defined points (using the method
add point), then lines (using add line, add circle,add circle arc, add line loop,
etc.), and finally surfaces (using add plane surface method). These geomet-
rical entities are assigned identification numbers when they are created.
Groups of geometrical entities can be defined (using add physical line or
add physical surface methods) and are called physical entities with unique
identification numbers. The purpose of these physical entities is to assem-
ble geometrical entities into larger groups so that they can be referred
to by the mesh module as single entities. In terms of domain geome-
try definitions, physical entities can be viewed as labelled boundaries or
subdomains on which boundary conditions or coefficients are defined. As
an example, script in listing 4.7 defines geometry illustrated in figures
4.2 and 4.3. Function geometry() has a parameter h – mesh triangular size,
and returns two structures: geometry object, geom, and labels of geometry
elements, geom labels.
1 import pygmsh
2 import numpy
3 def geometry (h):
4 geom = pygmsh . built in . Geometry () # initialize geometry object
5 #rectangular #1
6 rect1 p1 =geom. add point ([0.0 , −1.0, 0.0] , h)
7 rect1 p2 =geom. add point ([0.0 , 0.0, 0.0] , h)
8 rect1 p3 =geom. add point ([2.0 , 0.0, 0.0] , h)
9 rect1 p4 =geom. add point ([2.0 , −1.0, 0.0] , h)
10 rect1 l1 =geom. add line ( rect1 p1 , rect1 p2 )
11 rect1 l2 =geom. add line ( rect1 p2 , rect1 p3 )
12 rect1 l3 =geom. add line ( rect1 p3 , rect1 p4 )
13 rect1 l4 =geom. add line ( rect1 p4 , rect1 p1 )
14 # circular hole
15 cirlcle p0 =geom. add point ([1.0 , −0.5, 0.0] , h) #center
16 cirlcle p1 =geom. add point ([0.75 , −0.5, 0.0] , h)
96 ■ Computational Framework for the Finite Element Method
57 # domain labels
58 ph rect1 surf =geom. add physical surface ( rect1 surf , label ="1")
59 geom labels [ group id[−1]]="1"
60 ph rect2 surf =geom. add physical surface ( rect2 surf , label ="2")
61 geom labels [ group id[−1]]="2"
62 ph rect3 surf =geom. add physical surface ( rect3 surf , label ="3")
63 geom labels [ group id[−1]]="3"
64 # boundary labels
65 ph rect1 l1 =geom. add physical line ( rect1 l1 , label ="7: L0:R1")
66 geom labels [ group id[−1]]="7: L0:R1"
67 ph rect1 l2 =geom. add physical line ( rect1 l2 , label ="11: L3:R1")
68 geom labels [ group id[−1]]="11: L3:R1"
69 ph rect1 l3 =geom. add physical line ( rect1 l3 , label ="4: L0:R1")
70 geom labels [ group id[−1]]="4: L0:R1"
71 ph rect1 l4 =geom. add physical line ( rect1 l4 , label ="1: L0:R1")
72 geom labels [ group id[−1]]="1: L0:R1"
73 ph rect2 l1 =geom. add physical line ( rect2 l1 , label ="10: L3:R2")
74 geom labels [ group id[−1]]="10: L3:R2"
75 ph rect2 l2 =geom. add physical line ( rect2 l2 , label ="6: L3:R2")
76 geom labels [ group id[−1]]="6: L3:R2"
77 ph rect2 l3 =geom. add physical line ( rect2 l3 , label ="2: L3:R2")
78 geom labels [ group id[−1]]="2: L3:R2"
79 ph rect2 l4 =geom. add physical line ( rect2 l4 , label ="3: L3:R2")
80 geom labels [ group id[−1]]="3: L3:R2"
81 ph rect3 l1 =geom. add physical line ( rect3 l1 , label ="8: L0:R3")
82 geom labels [ group id[−1]]="8: L0:R3"
83 ph rect3 l2 =geom. add physical line ( rect3 l2 , label ="9: L0:R3")
84 geom labels [ group id[−1]]="9: L0:R3"
85 ph rect3 l3 =geom. add physical line ( rect3 l3 , label ="5: L0:R3")
86 geom labels [ group id[−1]]="5: L0:R3"
87 p h a r c 1 =geom. add physical line ( arc 1 ,label ="12: L0:R1")
88 geom labels [ group id[−1]]="12: L0:R1"
89 p h a r c 2 =geom. add physical line ( arc 2 ,label ="13: L0:R1")
90 geom labels [ group id[−1]]="13: L0:R1"
91 p h a r c 3 =geom. add physical line ( arc 3 ,label ="14: L0:R1")
92 geom labels [ group id[−1]]="14: L0:R1"
93 p h a r c 4 =geom. add physical line ( arc 4 ,label ="15: L0:R1")
94 geom labels [ group id[−1]]="15: L0:R1"
98 ■ Computational Framework for the Finite Element Method
Listing 4.8: Python code for building a mesh from given geometry.
Programming
Two-Dimensional Finite
Element Method
Listing 5.1: First version of the code for assembling stiffness matrix which
uses element by element strategy.
Listing 5.2: Second version of the code for assembling stiffness matrix
which uses partly vectorized approach.
Programming Two-Dimensional Finite Element Method ■ 103
Listing 5.3: Third version of the code for assembling stiffness matrix
which uses coordinate form of sparse matrix.
Listing 5.4: Fourth version of the code for assembling stiffness matrix
which uses fully vectorized approach.
Function stiffnessAssemb 4() is loop free and operates only with vec-
tors. For the symmetric matrix A the algorithm could be more memory
efficient (in this case some of aij can be replaced by a single vector and
A=A+A.’). We can avoid vectorization of the local stiffness matrices in func-
tion stiffnessAssemb 4() and save some memory. For example, the following
version of assembling algorithm is comparable in terms of computational
cost with the previous one
1 function A= stiffnessAssemb 5 (p,t)
2 np=size(p ,2) ;
3 nt=size(t ,2) ;
4 ntep =3;
5 %indices of local points
6 k1=t(1 ,:) ;
7 k2=t(2 ,:) ;
8 k3=t(3 ,:) ;
9 Al=ones(nt ,ntep ,ntep) ; % all local stiffness matrices
10 A= sparse (k1 ,k2 ,Al (: ,1 ,2) ,np ,np) ;
11 A=A+ sparse (k1 ,k3 ,Al (: ,1 ,3) ,np ,np) ;
12 A=A+ sparse (k2 ,k3 ,Al (: ,2 ,3) ,np ,np) ;
13 % replace next 3 lines by A=A+A.’for symmetric A
14 A=A+ sparse (k2 ,k1 ,Al (: ,2 ,1) ,np ,np) ;
Programming Two-Dimensional Finite Element Method ■ 105
Listing 5.5: Fifth version of the code for assembling stiffness matrix which
uses fully vectorized approach with improved memory usage efficiency.
Listing 5.7: Version of the code for assembling stiffness matrix with finite
elements of arbitrary shape.
Listing 5.8: Version of the code for assembling forcing vector which uses
fully vectorized approach.
Listing 5.9: Version of the code for assembling forcing vector which uses
fully vectorized approach with improved memory usage efficiency.
Listing 5.10: Version of the code for assembling forcing vector with finite
elements of arbitrary shape.
which results in table 5.2. It follows from table 5.2 that computational
cost for the third method five times higher compared with first or second
method.
TABLE 5.2: Summary of the computational efficiency test for the algo-
rithm of assembling global forcing vector. Last three columns contain
CPU time for the corresponding version of the algorithm.
φ̂1 (x̂) = 1 − x̂1 x̂2 , φ̂2 (x̂) = x̂1 , φ̂3 (x̂) = x̂2
represent basis functions on element τ̂ , and it is clear that φ̂i (pˆj ) = δij .
Transformation from τ̂ to τ is given by
x = Bτ x̂ + p1 : τ̂ → τ (5.6)
Consequently,
Basis functions φi (x) on the element τ are obtained from the ba-
sis functions on the element τ̂ through the transformation φi (x) =
φ̂i (Bτ−1 (x − p1 )). As a result,
First integral on the right hand side of the expression (5.7) being calcu-
lated either analytically or numerically using quadrature formula with
one node results in the value of 1/6, and we come to the expression
Z
1
Āαβ = |τ | c(pτ )∇φiβ · ∇φiα + b(pτ ) · ∇φiβ + a(pτ )Jτ φ̂iβ φ̂iα dx̂.
3
τ̂
The last integral results in different answers depending on the applied
calculation methods. When using quadrature formula the answer is
Z Z 1 1
18
φ̂iβ φ̂iα dx̂ = φ̂iβ (pˆτ ) φ̂iα (pˆτ ) dx̂ = 1 18 ,
1
18 18
τ̂ τ̂
but applying analytical integration gives
Z 1 1
φ̂iβ φ̂iα dx̂ = 12
1
24
1 .
24 12
τ̂
Next, we consider calculation of the local forcing vector on the ele-
ment τ Z
F̄α = f (x)φiα (x)dx.
τ
Both, analytical integration and quadrature method, lead to the same
result, namely
1
F̄α = Jτ f (pτ ), α = 1, 2, 3.
6
Regarding calculation boundary integrals
Z Z
S̄αβ = σ(x)φiα φiβ dx, M̄α = µ(x)φiα (x)dx, (5.8)
e e
which are associated with the boundary conditions on the edge e having
the vertex indices i1 and i2 , we can apply both approaches mentioned
above. For the components of the vector M we come to the same expres-
sion regardless of the integration method, M̄α = |e|/2µ(pe ), α = 1, 2,
where |e| is the length of the edge e and pe is the midpoint of the edge.
For the matrix S̄ we obtain two results depending on the calculation
method. In case of analytical integration we have
1 1
S̄αβ = |e|µ(pe ) 13 61 .
6 3
This function can be called at any time when coefficient values need
to be calculated. It is worth noting that this is a vectorized function
which allows to calculate coefficients over all subdomain points.
55 ff=(ff/6). ∗ J ;
56 F= sparse (k1 ,1,ff ,np ,1) ;
57 F=F+ sparse (k2 ,1,ff ,np ,1) ;
58 F=F+ sparse (k3 ,1,ff ,np ,1) ;
59 else
60 F=[] ;
61 end
62 end
Listing 5.13: MATLAB code for the vectorized version of the algorithm
for calculating elements and assembling FEM matrices.
3 % 1-st subdomain
4 I=find(sdl ==1); f(I)=1;
5 % 2-nd subdomain
6 I=find(sdl ==2); f(I)=1 ;
7 % 3-d subdomain
8 I=find(sdl ==3); f(I)=1 ;
9 end
Then, we run the script shown in listing 5.19 to measure CPU time
for three meshes with different number of nodes.
1 function testAssemblingAF
2 time =[] ; time nv =[] ; % assembling time
3 nt =[] ; np =[] ;
4 g= geometryMatrix ;
5 % PDE coefficients;
6 c= @c coeff ;
Programming Two-Dimensional Finite Element Method ■ 119
7 a= @a coeff ;
8 b1= @b1 coeff ;
9 b2= @b2 coeff ;
10 f= @f coeff ;
11 for h=[0.1 0.05 0.02]
12 [p,e,t]= initmesh (g,’hmax ’,h) ;
13 np=[np size(p ,2)] ; nt =[ nt size(t ,2)] ;
14 tic ;
15 [A,F]= assemblingAF (p,t,c,a,b1 ,b2 ,f) ;
16 time =[ time toc ];
17 tic ;
18 [A,F]= assemblingAF nv (p,t,c,a,b1 ,b2 ,f) ;
19 time nv =[ time nv toc ];
20 end
21 disp (’ np nt assemblingAF assemblingAF nv ’)
22 disp ([np ’ nt ’ time ’ time nv ’])
23 end
Listing 5.19: MATLAB code for testing efficiency of vectorized and non-
vectorized FEM assembling algorithms.
As a result, we come to table 5.3 which shows that vectorized version
outperforms non-vectorized one, that is predictable due to more efficient
memory management of the vectorized calculations in MATLAB.
np nt assemblingAF assemblingAF nv
704 1312 0.00391 1.08008
2670 5148 0.00781 3.73047
16473 32466 0.05566 23.62988
n n
where the matrix à = {Ãij }i,j=1
p
= A + S , F̃ = {F̃i }i=1
p
= F + M , ID
are the indices of the points with Dirichlet boundary conditions, and IU
are the rest points.
Function assemblingAF() (see section 5.5) calculates matrix A and vec-
tor F and we need a similar function to calculate S and M . In addition,
this function would enable us calculating vector U D with np elements
such that all its elements are equal to zero apart from elements with
indices j ∈ ID having value of uDj .
Matrix ÃIU = {Ã}i,j∈IU is obtained from the matrix à by deleting
rows and columns with indices belonging to the set ID . To perform this
operation we introduce a matrix N ∼ (np × m) where m is the number
of elements in the set IU and
Note that after solving the system ÃIU u = q the final vector of solution
at the node points can be obtained as U = N u + U D (complementing
vector u by the boundary values U D ). As a result, we come to the
function assemblingBC() in listing 5.21 which calculates contributions from
the boundary elements.
1 function [N,S,UD ,M]= assemblingBC (bc ,p,e)
2 % The following call is also allowed :
3 % [N,S]=assemblingBC(bc,p,e)
4 % [N,S,UD]=assemblingBC(bc,p,e)
5 np=size(p ,2) ;
6 S= sparse (np ,np) ; M= sparse (np ,1) ; N= speye (np ,np) ;
7 UD= sparse (np ,1) ;
122 ■ Computational Framework for the Finite Element Method
48 bsD=bc.bsD ;
49 if numel (bsD)>0
50 if bsD == inf
51 bsD=bsg ;
52 end % all b.c. are the Dirichlet one
53 local(bsD )=1: numel (bsD) ;
54 if all(local ==0)
55 disp (’error. bsD+bsR ~= number of boundary segments ’)
56 end
57 eD=e([1 2 5], ismember (k,bsD )) ; % Dirichlet BC edges
58 sdl=local(eD (3 ,:)) ;
59 k1=eD (1 ,:) ; k2=eD (2 ,:) ; % indices of corner points
60 iD=[k1 k2] ;
61 [id ,~]= find( sparse (iD ,iD ,1,np ,np )) ; % Dirichlet point indices
62 iN=ones (1,np) ; iN(id )= zeros (1, numel (id )) ;
63 iN=find(iN) ; % indices of non-Dirichlet points
64 niN=numel(iN) ;
65 N= sparse (iN ,1: niN ,1,np ,niN) ;
66 if nargout >=3 % evaluate UD on Dirichlet points
67 UD(k1)= feval (bc.uD ,p(1,k1),p(2,k1),sdl) ;
68 UD(k2)= feval (bc.uD ,p(1,k2),p(2,k2),sdl) ;
69 end
70 end
71 end
Listing 5.22: MATLAB code for assembling FEM matrices and solving
a PDE problem.
u(x) = uD (x), x ∈ ΓD ;
c(x)∇u · ν(x) + σ(x)u = µ(x), x ∈ ΓR ,
We define coefficients
c = 2 + x1 + x2 ,
a = x1 + x2 ,
b = (x1 , x2 ),
f = −8 − 6(x1 + x2 ) + (2 + x1 + x2 )(x21 + x22 ),
uD = x21 + x22 ,
(
0, on 2nd segment,
σ=
2, on 4th segment ,
(
2(2 + x1 + x2 )uD , on 2nd segment,
µ=
2(2 + x1 + x2 + 1)uD , on 4th segment.
and relative error, errh = err/h2 . Function testPDE in listing 5.26 solves
this problem and calculates FEM solution errors.
Programming Two-Dimensional Finite Element Method ■ 127
1 function testPDE
2 clear all ; close all ; clc
3 g=’circleg ’ ; np =[] ; nt =[] ; errh2 =[] ; err =[] ;
4 t assemblingAF =[] ; t assemblingBC =[] ; t solving =[] ;
5 for h=[0.5 0.1 0.05 0.02]
6 [p,e,t]= initmesh (g,’hmax ’,h) ;
7 exact =@(x1 ,x2 ,sdl) x1 .^2+ x2 .^2; % exact solution
8 x1=p(1 ,:) ; x2=p(2 ,:) ;
9 u exact =exact(x1 ,x2 ,1) ’;
10 % PDE coefficients
11 c=@(x1 ,x2 ,sdl) 2+ x1+x2 ;
12 a=@(x1 ,x2 ,sdl) x1+x2 ;
13 f=@(x1 ,x2 ,sdl) −8−6∗(x1+x2 )+(2+ x1+x2).∗(x1 .^2+ x2 .^2) ;
14 b1=@(x1 ,x2 ,sdl) x1 ;
15 b2=@(x1 ,x2 ,sdl) x2 ;
16 % boundary conditions
17 bc.bsD =[1 3] ; bc.uD= @u D ;
18 bc.bsR =[2 4] ; bc.sg= @sigma ; bc.mu=@mu ;
19 tic
20 [A,F]= assemblingAF (p,t,c,a,b1 ,b2 ,f) ;
21 t assemblingAF =[ t assemblingAF toc] ;
22 tic
23 [N,S,UD ,M]= assemblingBC (bc ,p,e) ;
24 t assemblingBC =[ t assemblingBC toc] ;
25 tic
26 u= assemblingPDE (bc ,p,e,t,c,a,b1 ,b2 ,f) ;
27 t solving =[ t solving toc] ;
28 np=[np size(p ,2)] ; nt =[ nt size(t ,2)] ;
29 err =[ err norm( u exact−u,inf )] ;
30 errh2 =[ errh2 norm( u exact−u,inf )/h^2] ;
31 end
32 disp (’np assemblingAF assemblingBC solving ’)
33 disp ( [np ’ t assemblingAF ’ t assemblingBC ’ t solving ’] )
34 err
35 errh2
36 end
TABLE 5.4: Summary of the solving test problem. Last three columns
contain CPU time for the corresponding functions.
Nonlinear Basis
Functions
X
6
ẑ(x̂) = ẑ(p̂i )φ̂i (x̂), x̂ ∈ τ̂ .
i=1
x = Bτ x̂ + p1 , (6.2)
X
6
z(x) = z(pi )φi (x), x ∈ τ. (6.3)
i=1
It is worth noting here that unlike G1 mesh, basis functions for G2 mesh
are nonlinear functions, namely, of the second order. This fact results in
slightly more complicated calculations of its gradients.
X
6
x= pi φ̂i (x̂), x̂ ∈ τ̂ (6.4)
i=1
which transforms τ̂ into τ , and points p̂i are transformed into pi . Note
that if nodes of the element τ lie on the straight line, then transformation
(6.4) reduces to linear form (6.2). As such, the difference between linear
and curvilinear triangle elements is the way of transformation from τ̂ to
τ.
Likewise linear G2 elements, to represent any function defined on
curvilinear element τ through the basis function we utilize the expression
(6.3) where basis functions now are not polynomials of the second order
but function of the x being itself second-order polynomial.
column-vectors n o6
φ̂(d̂i ) = φ̂β (d̂i ) ,
β=1
X
q X
q
Āαβ = γ̂i ẑ(d̂i ) = γ(d̂i ) ĉ(d̂i )D β (d̂i ) · D α (d̂i )
i=1 i=1
+ b̂(d̂i ) · D β (d̂i ) + â(d̂i )φ̂β (d̂i ) φ̂α (d̂i ) ,
X
q
Ā = γ(d̂i ) ĉ(d̂i )DT (d̂i )D(d̂i )
i=1
+φ̂(d̂i ) b̂(d̂i )D(d̂i ) + â(d̂i )φ̂T (d̂i ) .
X
q
F̄ = γ(d̂i )fˆ(d̂i )φ̂(d̂i ).
i=1
It is worth noting that the following is valid for the curvilinear tri-
angular element (see 6.4)
a1 = 0.09157621350977073, a2 = 0.09157621350977073,
b1 = 0.4459484909159649, b2 = 0.4459484909159649,
a3 = 1 − a1 − a2 , b3 = 1 − b1 − b2 ,
a1 a 1 a3 b1 b1 b3
dˆ = ,
a2 a3 a2 b2 b3 b2
γ1 = 0.1099517436553218, γ2 = 0.2233815896780115,
1
γ̂ = γ1 γ1 γ1 γ2 γ2 γ2 .
2
Now, we consider calculation of the boundary matrix S̄ = {S̄αβ } and
boundary vector M̄ = {M̄α } (see expression 5.8). Let e be the boundary
edge with endpoints p1 , p2 and midpoint p3 , and ê = {θ̂ ∈ [0, 1]} is a
basis edge having endpoints pˆ1 = 0, pˆ2 = 1 and midpoint pˆ3 = 0.5.
Then, basis functions defined on the edge can be expressed as
φ̂1 (θ̂) = (1 − 2θ̂)(1 − θ̂), φ̂2 (θ̂) = θ̂(2θ̂ − 1), φ̂3 (θ̂) = 4θ̂(1 − θ̂).
Expression
Z1 X
q
ẑ(θ̂)dθ̂ ≈ γ̂i ẑ(dˆi ).
0 i=1
137
APPENDIX A
Variational Formulation
of a Boundary Value
Problem
where c(x), a(x) and f (x) are piecewise continuous functions and c(x) >
0, b(x) > 0. A variational problem is to find a function u(x) which
minimizes J(u).
J(u) → min, u(s0 ) = us0 , u(s1 ) = us1 . (A.4)
Then, the Euler-Lagrange equation takes the form
′
− c(x)u′ (x) + a(x)u(x) = f (x). (A.5)
It can be shown that stationary point in this case is a function which
minimizes (A.3). As a result, solving (A.3) – (A.4) is equivalent to solving
BVP (A.5) – (A.2).
In practice, the BVP (A.5) – (A.2) is replaced by the integral expres-
sion (A.3) for which a minimization problem is considered with some ap-
proximation of unknown function. In the context of FEM, the unknown
function u is represented through linear combination of some known
functions, φi (x), and coefficients, αi , as follows:
X
N
u(x) = αi φi (x). (A.6)
i=1
Discussion of Global
Interpolating
Polynomial
The short answer is not. To illustrate this, let us consider the Runge
function1 f (x) = 1/(1 + 25x2 ), x ∈ [−1, 1], and a simple strategy which
1
Given example is referred to Runge’s phenomenon.
1 1
0.8
0.8
0.6
0.6
0.4
0.4
0.2
0.2
0
0 -0.2
-1 -0.5 0 0.5 1 -1 -0.5 0 0.5 1
(a) (b)
2 8
1.5 6
1 4
0.5 2
0 0
-0.5 -2
-1 -0.5 0 0.5 1 -1 -0.5 0 0.5 1
(c) (d)
2 0.01
1.5
0.005
0.5
-0.005
0
-0.5 -0.01
-1 -0.5 0 0.5 1 -1 -0.5 0 0.5 1
(a) (b)
where
ωm+1 (x) = (x − x1 )(x − x2 ) · · · (x − xm+1 ),
and ξ ∈ [s0 , s1 ]. It can be seen that the error depends on function ωm+1
which, in turn, depends on the relative nodes location. The problem of
divergence can be resolved by choosing nodes to be roots of an orthogonal
polynomial, for example, taking nodes to be xi = − cos(π(i−1)/m), 1 ≤
i ≤ m + 1 improves convergence (see figure B.2).2
Although taking orthogonal polynomial roots as interpolation nodes
is a good strategy, practically it could be inapplicable in some cases,
for example, when interpolation nodes are prescribed through a table of
function values which leaves no freedom of changing the nodes distribu-
tion.
Error of input data and approximation accuracy. Another
source of polynomial approximation error arises from the fact that the
function values at the interpolation nodes, fi = f (xi ), are specified or
2
Nodes xi = − cos(π(i − 1)/m), 1 ≤ i ≤ m + 1 are roots of the orthogonal
′
polynomial of the form (1−x2 )Um−1 (x) where Um−1 (x) is the Chebyshev polynomial
of the second kind of order m − 1.
144 ■ Computational Framework for the Finite Element Method
X
m+1
∗
max |Pm (x) − Pm (x)| ≤ Λm ϵ∗ , Λm = max |φj (x)|.
[s0 ,s1 ] [s0 ,s1 ]
j=1
Here, Λm is called the Lebesgue constant. It can be seen that the con-
stant Λm represents the factor by which approximation error increases
when the input data error is introduced. Sensitivity of the approxima-
tion method to the errors of input data is characterized by a conditional
number which can be defined by the Lebesgue constant. The value of
Λm depends only on nodes distribution but not on the interval length.
Asymptotic estimation shows that the Lebesgue constant grows logarith-
mically with m → ∞ if Chebyshev nodes are used. On the other hand,
it grows exponentially in the case of equidistant nodes. The former fact
leads to conclusion, that it is recommended to avoid using high order
global interpolation polynomials having equidistant nodes distribution.
Alternative approach is to use a piecewise local interpolation when the
interval [s0 , s1 ] is split into subintervals and function f is approximated
by interpolating polynomial of low order on each subinterval.
APPENDIX C
Interpolatory
Quadrature Formulas
Here xi are called nodes of the formula and γi are called weights.
There are several algorithms for computing the nodes xi and weights
wi of Gaussian quadrature rule and one of them is given below. We start
by considering a quadrature for the interval [−1, 1] with n nodes1
Z1 X
n
f dx ≈ γi f (xi ).
−1 i=1
Note that this formula is exact for the polynomial of some degree N if
and only if it is exact for the set of functions f = 1, x, x2 , . . . , xN . This is
equivalent to the fact that nodes and weights must satisfy the following
system of nonlinear equations
X
n Z1
1 − (−1)k+1
γi xki = xk dx = , k = 0, . . . , N.
k+1
i=1 −1
It can be shown that the system has unique solution if the number of
unknowns is equal to the number of equations, so N = 2n − 1. For
example, Gaussian quadrature with two nodes corresponds to n = 1 and
N = 3. Weights and nodes are found from the system
Z1
γ1 + γ2 = dx = 2,
−1
Z1
γ1 x1 + γ2 x2 = xdx = 0,
−1
Z1
2
γ1 x21 + γ1 x22 = x2 dx = ,
3
−1
Z1
γ1 x31 + γ1 x32 = x3 dx = 0.
−1
1
Integration over an arbitrary interval, [s0 , s1 ], can be obtained from the integra-
tion over the interval [−1, 1] through the transformation x̃ = (s0 +s1 )/2+x(s1 −s0 )/2
Zs1
s1 − s0 X
n
f dx ≈ γi f (x̃i ).
2 i=1
s0
148 ■ Computational Framework for the Finite Element Method
√ √
By solving it, we find the values: γ1 = γ2 = 1, x1 = −1/ 3, x2 = 1/ 3.
As a result we obtain Gaussian quadrature with two nodes being exact
for polynomials of the third order
Z1
1 1
f dx ≈ f −√ +f √ .
3 3
−1
Nodes and weights for larger values of m can be found tabulated in many
numerical analysis books.
Conditional number of interpolatory quadrature formulas.
When computing integrals, an integrand is often known approximately
with some error (for example, it could be computed with some rounding
error or measured with error). As a result, instead of exact value of
the integrand, f , approximated value is available, f ∗ = f + ϵ, having
some error ϵ. Let us estimate sensitivity of interpolatory quadrature with
respect to input data, or equivalently, defined a quadrature conditional
number, ν . If we assume that |f (x) − f ∗ (x)| < ϵ∗ ∀x ∈ [s0 , s1 ], then
n
X X
n X
n Xn
γi f (xi ) − γi f ∗ (xi ) ≤ ϵ∗ |γi | = νϵ∗ , ν = |γi |.
i=1 i=1 i=1 i=1
which means that if all weights are positive we obtain the smallest condi-
tional number; otherwise, we come to an ill-conditional quadrature. All
weights of Gaussian quadrature are positive which guarantees stability
with respect to input data errors.
APPENDIX D
where
bk ck
αk = , k ≥ 0, βk = , k ≥ 1. (D.2)
ak ak−1 ak
4. Polynomial roots, {xk }nk=1 , are the nodes of Gauss Jacobi quadra-
ture
Zs1 Xn
f (x)ω(x)dx ≈ γk f (xk ), (D.3)
s0 k=1
where U1k is the first row of the matrix U , columns of which are
normalized eigenvectors (i.e., eigenvectors with unity Euclidean
norm) of the matrix An , and An = U ΛU −1 , Λ = diag(x1 , . . . , xn ).
(α,β) (α,β) 1
P0 (x) = 1, P1 (x) = ((α + β + 2) x + α − β) .
2
Quadrature Rules and Orthogonal Polynomials ■ 151
(2k + α + β + 1)(2k + α + β + 2)
ak = , (D.5)
2(k + 1)(k + α + β + 1)
(β 2 − α2 )(2k + α + β + 1)
bk = ,
2(k + 1)(k + α + β + 1)(2k + α + β)
(k + α)(k + β)(2k + α + β + 2)
ck = .
(k + 1)(k + α + β + 1)(2k + α + β)
Γ(α + 1)Γ(β + 1)
m0 = 2α+β+1 , (D.6)
Γ(α + β + 2)
Z1 X
n
f (x)dx ≈ γk f (xk ),
−1 k=1
Z1 X
n−1
2 2
f (x)dx ≈ f (−1) + γk f (xk ) + f (1).
n(n − 1) n(n − 1)
−1 k=2
Computational
Framework in Python
56 bg1=b1f∗ g1 x1 +b2f∗ g1 x2
57 bg2=b1f∗ g2 x1 +b2f∗ g2 x2
58 bg3=b1f∗ g3 x1 +b2f∗ g3 x2
59 A= sparse . coo matrix (( a12+bg2 ,(k1 ,k2)), shape =(np ,np ))
60 A=A+ sparse . coo matrix (( a23+bg3 ,(k2 ,k3)), shape =(np ,np ))
61 A=A+ sparse . coo matrix (( a31+bg1 ,(k3 ,k1)), shape =(np ,np ))
62 A=A+ sparse . coo matrix (( a12+bg1 ,(k2 ,k1)), shape =(np ,np ))
63 A=A+ sparse . coo matrix (( a23+bg2 ,(k3 ,k2)), shape =(np ,np ))
64 A=A+ sparse . coo matrix (( a31+bg3 ,(k1 ,k3)), shape =(np ,np ))
65 A=A+ sparse . coo matrix ((ad−a31−a12+bg1 ,(k1 ,k1)), \
66 shape =(np ,np ))
67 A=A+ sparse . coo matrix ((ad−a12−a23+bg2 ,(k2 ,k2)), \
68 shape =(np ,np ))
69 A=A+ sparse . coo matrix ((ad−a23−a31+bg3 ,(k3 ,k3)), \
70 shape =(np ,np ))
71 if f!= None:
72 ff=f(x1 ,x2 ,sdl)
73 ff=(ff/6)∗ J
74 k zero =numpy. zeros (k1. shape )
75 F= sparse . coo matrix ((ff ,(k1 , k zero )), shape =(np ,1))
76 F=F+ sparse . coo matrix ((ff ,(k2 , k zero )), shape =(np ,1))
77 F=F+ sparse . coo matrix ((ff ,(k3 , k zero )), shape =(np ,1))
78 return A,F
79 else: return A
7 # 2-nd segment
8 I=sdl ==1
9 f[I]= numpy. square (x1[I])+ numpy . square (x2[I])
10 return f
we can specify Dirichlet boundary conditions on the first and third seg-
ments as
bc={}
bc["bsD"]=[1 , 3]
bc["uD"]= uD
26 if nargout >=2:
27 bsR=bc["bsR"]
28 if len(bsR)>0:
29 if bsR == None: # all BC are mixed
30 bsR=bsg
31 local[bsR ]= range (0, len(bsR ))
32 # find boudary edges with mixed b.c.
33 eR=e[:, numpy .isin(k,bsR )]
34 eR=eR[[0, 1, 4] ,:]
35 k1=eR [0 ,:]
36 k2=eR [1 ,:] # indices of starting points and endpoints
37 x1=0.5 ∗ (p[0,k1 ]+p[0,k2 ])
38 x2=0.5 ∗ (p[1,k1 ]+p[1,k2 ])
39 h=numpy.sqrt( numpy . square (p[0,k2]−p[0,k1 ])
40 +numpy . square (p[1,k2]−p[1,k1 ])) # edges length
41 sdl= local [eR [2 ,:]]
42 # evaluate sigma , mu on edges barycenter
43 sf=bc["sg"](x1 ,x2 ,sdl)
44 mf=bc["mu"](x1 ,x2 ,sdl)
45 # ’exact’ integration
46 so=( sf/6)∗ h
47 sd=2∗ so
48 # quadrature rule
49 #so=(sf/4)*h
50 #sd = so
51 S= sparse . coo matrix ((so ,(k1 ,k2)), shape =(np ,np ))
52 S=S+ sparse . coo matrix ((so ,(k2 ,k1)), shape =(np ,np ))
53 S=S+ sparse . coo matrix ((sd ,(k1 ,k1)), shape =(np ,np ))
54 S=S+ sparse . coo matrix ((sd ,(k2 ,k2)), shape =(np ,np ))
55 if nargout ==4:
56 mf=bc["mu"](x1 ,x2 ,sdl)
57 mf=(mf/2)∗ h
58 k zero = numpy . zeros (k1. shape )
59 M= sparse . coo matrix ((mf ,(k1 , k zero )), \
60 shape =(np ,1))
61 M=M+ sparse . coo matrix ((mf ,(k2 , k zero )), \
62 shape =(np ,1))
63 # set Dirichlet boundary conditions
64 bsD=bc["bsD"]
65 if len(bsD)>0:
158 ■ Computational Framework for the Finite Element Method
36
37 # boundary conditions
38 def uD(x1 ,x2 ,sdl ):
39 f=numpy.zeros(x1. shape )
40 I=sdl ==0
41 f[I]= numpy. square (x1[I])+ numpy . square (x2[I])
42 I=sdl ==1
43 f[I]= numpy. square (x1[I])+ numpy . square (x2[I])
44 return f
45
46 def sigma(x1 ,x2 ,sdl ):
47 f=numpy.zeros(x1. shape )
48 I=sdl ==0
49 f[I]=0
50 I=sdl ==1
51 f[I]=2
52 return f
53
54 def mu(x1 ,x2 ,sdl ):
55 f=numpy.zeros(x1. shape )
56 I=sdl ==0
57 f[I]=2 ∗ (2+x1[I]+x2[I])∗(numpy . square (x1[I])+ \
58 numpy . square (x2[I]))
59 I=sdl ==1
60 f[I]=2 ∗ (2+x1[I]+x2[I]+1) ∗ ( numpy . square (x1[I])+ \
61 numpy . square (x2[I]))
62 return f
63
64 #main function
65 def testPDE ():
66 np =[] ; nt =[] ; errh2 =[] ; err =[] ;
67 for h in [0.5 , 0.1 , 0.05 , 0.02]:
68 geom , geom labels =mg.disk(h)
69 p,t,e = generateMesh (geom , geom labels )
70 p=numpy. transpose (p)
71 t=numpy. transpose (t)
72 e=numpy. transpose (e)
73 x1=p[0 ,:]
74 x2=p[1 ,:]
75 def exact(x1 ,x2 ,sdl ):
162 ■ Computational Framework for the Finite Element Method
163
Index
165