Beruflich Dokumente
Kultur Dokumente
Masterarbeit
Master Thesis
Computational Engineering Science
Eigenständigkeitserklärung
Hiermit versichere ich, dass ich die vorliegende Arbeit selbständig verfasst und keine
anderen als die angegebenen Quellen und Hilfsmittel benutzt habe. Die Stellen meiner
Arbeit, die dem Wortlaut oder dem Sinn nach anderen Werken entnommen sind, habe
ich in jedem Fall unter Angabe der Quelle als Entlehnung kenntlich gemacht. Dasselbe
gilt sinngemäß für Tabellen und Abbildungen. Diese Arbeit hat in dieser oder einer
ähnlichen Form noch nicht im Rahmen einer anderen Prüfung vorgelegen.
Lambert Theisen
Zusammenfassung
Die vorliegende Masterarbeit stellt eine Simulationsumgebung für die Untersuchung
von Gasströmungen im Nichtgleichgewicht bereit, die auf der FEniCS Computing
Platform aufbaut [18]. Die R13 Gleichungen werden präsentiert, nachdem eine Diskus-
sion über die klassischen Modelle von Navier–Stokes und Fourier deren Schwächen
aufzeigt und somit die Modellierung mit erweiterten Modellgleichungen motiviert.
Das entsprechende System von Gleichungen wird vereinfacht, sodass ein stationäres
und linearisiertes System von Bilanzgleichungen für einen zweidimensionalen Anwen-
dungsfall formuliert werden kann.
Während einer Validierung der numerischen Methode mit exakten Lösungen, wird
insbesondere auf Aspekte bezüglich der Implementierung eingegangen, denn FEniCS
stellt erweiterte Funktionen für das Behandeln von Tensoren bereit. Dies erlaubt es,
eine fast eins-zu-eins ähnliche Implementierung der jeweiligen mathematischen For-
mulierungen im Quellcode. Ein dokumentierter und validierter Löser wurde implemen-
tiert und in [58] veröffentlicht. Dieser Löser erlaubt das Simulieren von willkürlichen
zweidimensionalen Geometrien mit einer Reihe von Randwerten.
Um die Benutzung von erweiterten Modellgleichungen für Gasströmungen erhöhter
Knudsen Zahl zu rechtfertigen, werden typische Beispiele mit auftreten Nichtgle-
ichgewichtseffekten betrachtet und gelöst. In diesen Anwendungsfällen, wird das
Knudsen Paradoxon und eine thermische Transpirationsströmung beobachtet, die mit
klassischen Lösern nicht vorhergesagt werden können.
Keywords: R13 equations, FEniCS project, Non-equilibrium gas flows, Finite ele-
ment method, CIP stabilization
Acknowledgments
This thesis was written between April and September 2019 at the MathCCES, RWTH
Aachen University.
First of all, I would like to thank my supervisor Prof. Manuel Torrilhon allowing me to
work on this project and for his motivational and valuable hints, fruitful discussions
as well as for the freedom to follow own ideas and to actively participate in the
determination of the direction of this thesis. The provided working environment in
the institute was extraordinary and undoubtedly contributed to the outcome of this
work. The topic was very well suited for the Computational Engineering Science
study program, involving many concepts, I learned during the last ten semesters,
while combining them all together in an interdisciplinary way.
I would further like to thank all my colleagues at the MathCCES group for including
me into the team and for all the on- and off-topic discussions during coffee and lunch
breaks. I really had a great time during the last months.
Special thanks are sent to my parents, my family, my girlfriend, and all others that
contributed to this work by supporting me and by accepting that one or two weekends
have been spent to finish this thesis in time.
Contents
List of Figures I
List of Listings V
1. Introduction 1
1.1. Research Background and Context . . . . . . . . . . . . . . . . . . . 3
1.2. Thesis Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3. Thesis Outline and Scope . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4. The FEniCS Project . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
5.2. Stabilization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.3. Convergence Study Based on Mesh Refinement . . . . . . . . . . . . . 46
5.3.1. Computational Domain and Input Parameters . . . . . . . . . 46
5.3.2. Error Discussion . . . . . . . . . . . . . . . . . . . . . . . . . 48
8. Applications 75
8.1. Lid-Driven Cavity Benchmark . . . . . . . . . . . . . . . . . . . . . . 75
8.2. Knudsen Paradox in a Channel Flow . . . . . . . . . . . . . . . . . . 76
8.3. Thermal Transpiration Flow in a Knudsen Pump . . . . . . . . . . . 79
9. Conclusion 81
9.1. Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
9.2. Technical Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
9.2.1. Solver Source Code . . . . . . . . . . . . . . . . . . . . . . . . 85
9.2.2. Calculations and Hardware . . . . . . . . . . . . . . . . . . . . 85
9.2.3. Software Versions . . . . . . . . . . . . . . . . . . . . . . . . . 85
Bibliography 171
List of Figures
1.1. Graphical representation of chapter dependencies. . . . . . . . . . . 5
1.2. Google search interests for popular finite element software since 2010. 6
6.1. Computational domain and parameters for the decoupled stress system. 60
6.2. DSS: Errors using P1 P1 P1 with stabilization (test case 1). . . . . . . 61
6.3. DSS: Errors using P3 P2 P1 without stabilization (test case 2). . . . . 62
II List of Figures
7.1. Computational domain for the linearized R13 system (test case 1). . 68
7.2. LinR13: Errors using stabilized P1 equal-order elements (test case 1). 69
7.3. LinR13: Errors using stabilized P2 equal-order elements (test case 1). 70
7.4. Schematic results of first test case for the linearized R13 equations. . 71
a. Shear stress σxy and velocity streamlines ui . . . . . . . . . . . 71
b. Temperature θ and heat flux streamlines si . . . . . . . . . . . 71
7.5. Computational domain for the linearized R13 system (test case 2). . 71
7.6. LinR13: Errors using stabilized P1 equal-order elements (test case 2). 72
7.7. Schematic results of second test case for the linearized R13 equations. 73
a. Shear stress σxy and velocity streamlines ui . . . . . . . . . . . 73
b. Temperature θ and heat flux streamlines si . . . . . . . . . . . 73
4.1. Mesh generation for a unit square domain Ω = [0, 1]2 [14]. . . . . . . . 34
4.2. Generation of function space using P1 elements for a given mesh [14]. 35
4.3. Definition of Dirchlet boundary conditions [14]. . . . . . . . . . . . . 35
4.4. Weak form specification for Poisson’s problem [14]. . . . . . . . . . . 36
4.5. Solving the weak formulation using given Dirichlet data [14]. . . . . . 37
4.6. Mixed function space definition for Taylor–Hood elements [15]. . . . . 39
4.7. Mixed weak formulation for the Stokes problem [15]. . . . . . . . . . 40
D.1. FEniCS demo program to solve the Poisson problem using linear P1
elements (demo_poisson.py in [14, 18]). . . . . . . . . . . . . . . . . 169
D.2. FEniCS demo program to solve the Stokes problem using Taylor–Hood
elements P2 P1 (demo_stokes-taylor-hood.py in [15, 18]). . . . . . . 170
1. Introduction
Understanding the world in its true nature has always been a great desire in humanity
and can be considered as the motivation and the foundation for all sciences and all
research efforts. However, the exact underlying laws and physical mechanisms can
only be observed up to a limited precision or can only be derived by theoretical
considerations following generalization aspects. With these insights, mathematical
models are formulated based on the cause and effect principle. The resulting models
are then used to describe and predict the behavior of physical systems, e.g., the flow
of gases. In general, one has to keep in mind that models always contain assumptions
and admissibility restrictions apply to them.
The classical models, given by Navier–Stokes and Fourier, are nowadays heavily used
in academia and industry to predict the behavior of gas flows. A major driving
factor was the advances in efficient and scalable numerical methods, combined with
the increasing computational resources available nowadays. It allowed for relatively
accurate simulation results by approximating the underlying equations and solving
them with a reasonable computational effort. Today, computational fluid dynamics
(CFD) is undoubtedly part of every design process for all kinds of products and
processes to increase efficiency, to understand certain behaviors and eventually to
decrease costs in an industrial simulation context. In practice, the classical and
historical models are used because they work out very well in most of the considered
situations. Besides challenges in the modeling of turbulent structures [53], the overall
research field seems very well understood.
2 1. Introduction
However, with the great success in simulation contexts, one might easily forget about
the fact, that the classical Navier–Stokes–Fourier models are not the ground truth
and quickly lose their validity when leaving standard conditions. Also, the equations
of state for the considered gas, such as the ideal gas law, for example, are of course
not universal and only hold for specific conditions. The flow around a space vehi-
cle, reentering the earth’s atmosphere at high altitudes, for example, fundamentally
behaves different, expressed in a nutshell as:
“Just imagine you are at very high altitude where the air density is very
low. You might see a lot of weird things.”
— Zhenning Cai, December 2016 [11]
The following question may arise: What is so fundamentally different in the flow
situation leading to a failure of the classical models? Well, the underlying continuum
assumption – stating that a big collection of gas particles act as a continuum due to
many collisions – is violated because of the very low gas density. In these rarefied sit-
uations, the mean free path, that gas particles can travel without a collision, becomes
significant in relation to the considered length scale. In the context of dimension-
less similitude analysis, the Knudsen number is the primary dimensionless quantity
describing this crucial relation between the mean path and the process length scale.
For increasing Knudsen numbers above zero, a gas leaves its thermodynamic equi-
librium state and enters the non-equilibrium. In a non-equilibrium, a whole range
of rarefaction effects can be observed, that seem “weird” at first glance. The reason
for this might be the fact that these effects contradict our intuitive understanding of
gas flows at standard conditions. Similar effects can also be observed in microtech-
nology applications. For example, microelectromechanical systems (MEMS) provide
an electrical, mechanical, hydraulic, or pneumatic function on a chip with shallow
dimensions. In the near future, these “micro-machines” can become very important
and could become as pervasive as electronics nowadays [75]. It is clear that more
sophisticated models are needed in order to accurately predict and simulate flows in a
rarefied or micro-scale setting by capturing all the relevant non-equilibrium effects.
In the context of the kinetic gas theory, there exist microscopic descriptions account-
ing for individual gas particle dynamics, such as the Boltzmann equations. These
models can be used for rarefied gas situations. However, in practice, their simulation
is often rather expensive. This motivated the derivation of extended macroscopic
models, that can be used, just as the classical models, as a compact set of partial dif-
ferential evolution equations for the main gas quantities. The regularized 13-moment
(R13) equations can capture the relevant rarefaction effects while still being relatively
compact. They act as an extension to the classical NSF description of gases. However,
with extended evolution equation for the heat flux and fluid stress, their numerical
simulation remains challenging due to the increased modeling complexity.
1.1. Research Background and Context 3
solid framework allowing for further research and more complex flow situations.
Special effort is put into intuitive implementation concepts, offered by the FEn-
iCS computing platform. This includes, for example, the usage of tensorial
objects to have a one-to-one correspondence between mathematical formulation
and final implementation. This can be seen as a test for current capabilities of
the FEniCS computing framework. Furthermore, the solver shall be publicly
available and sufficiently documented and tested.
4. Discussion of application cases: In particular, applications with occurring rar-
efaction effects are presented. This shall justify the usage of extended gas flow
models and differentiate them from classical simulation approaches.
In this Chapter 1, the present work was embedded in the physical context and the
current research context. A short presentation of the FEniCS Project, as the leading
software used throughout this work, is given in the following Section 1.4.
This thesis contains two main parts. The first part, starting with Chapter 2, revisits
the classical gas flow models and shows their deficiencies in rarefied gas applications.
This leads to the derivation of extended gas flow models, presented in Chapter 3, and
sets the mathematical modeling context of this work.
The second part starts with a brief introduction into the programming paradigms of
the FEniCS project by presenting an introduction example in Chapter 4. In order
to systematically validate the programmed solver, the model equations are split into
a decoupled heat system, validated and discussed in Chapter 5. After an analogous
validation of the second part, i.e. a decoupled stress system in Chapter 6, the full
linear R13 equation system is solved and validated in Chapter 7.
In Chapter 8, some example applications, mostly inspired by typical examples from
the literature, are presented. These application cases are particularly relevant in
the rarefied gas or micro-scale flow setting. The last Chapter 9 aims to provide an
extensive overview of future work opportunities to motivate the further development
of finite element strategies for extended gas models.
A graphical overview of the chapter dependencies is given in Fig. 1.1. However, these
dependencies are not very strong, and essential concepts or ideas are revisited if it in-
creases the clarity of the presentation. It is only natural that this present work aims at
graduating students with a background in computational modeling and mathematics.
However, as part of the Computational Engineering Science (CES) program with its
interdisciplinary concept, the present work makes use of concepts from the disciplines
1.4. The FEniCS Project 5
Chapter 1: Introduction
Chapter 4: Solving
Chapter 2: Classical Theory
PDEs using FEniCS
Chapter 8: Applications
Chapter 9: Conclusion
Figure 1.1. Graphical representation of chapter dependencies throughout the thesis. Except for
the derivation of the relevant physical models in Chapters 2 and 3, the thesis structure follows a
linear strategy.
As the thesis title suggests, the FEniCS computing platform is used for all simulations
throughout this work. It was already mentioned, that the implementation of new
mathematical models can require large parts of auxiliary code to be written, in order
to solve the actual physical model problem. Especially in the context of Galerkin
or finite element methods, the solution procedure, for example, needs routines for
connectivity assemblage, evaluation of functions and their derivatives as well as the
final linear solve. The implementation of different finite element spaces as in [3, 5] can
also be seen as a subfield in the broad context of solving a model equation numerically.
All the above-listed prerequisites can increase the complexity and the effort when
building simulation software and are error-prone. This work, therefore, builds up
upon the existing simulation framework FEniCS [3, 35] to have a reliable existing
framework in order to set the focus more on the modeling and formulation aspects.
project is rather trendy nowadays, as seen in Fig. 1.2. Possible reasons for this trend
can be the generality or extensibility of FEniCS. While other software often has a
limited range of physical problems that can be analyzed, FEniCS can solve arbitrary
model formulations as long as the physical problem can be formulated mathematically.
Also, there exists a decent amount of open-access documentation, i.a. [32, 35], which
can contribute to the popularity of software in general.
1.0
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
2010 2011 2012 2013 2014 2015 2016 2017 2018 2019
Python C++ C
Figure 1.2. Relative Google search interests for popular finite element software since 2010. While
the search interests in general are very volatile for all the listed software, the FEniCS Project shows
a continuous popularity trend in contrast to the other software packages. A reference plot shows the
search interest for the programming language Python in comparison to C/C++ for the same time
range. The data was extracted from [22, 23]. The original data further shows an inhomogeneity
in terms of the geographical location of the web searches. For example, while Code_Aster and
FreeFem++ are dominant in France, Elmer is often searched in Finland and deal.II is more popular
in Germany and the USA. A possible reason for such effects can be the location of the initial and
ongoing development or language-induced accessibility barriers in the documentation of a software.
In terms of usability, FEniCS offers both a modern high-level and easy to use Python
interface as well as a high-performance C++ backend. Therefore, as presented
in Fig. 1.2, the FEniCS computing platform may also has benefitted from increasing
popularity of the Python programming language in the time range since 2010. In
order to write the mathematical models in a very high-level manner, the whole FEn-
iCS project consists of several building blocks [32], i.e flexible and reusable software
components. The effort to write a large portion of code is shifted away from the user
to the developer with automated code generation. This approach aims to solve the
“disconnect between mathematics and code” (e.g. a rather simple Poisson equation
−∆u = f vs. 100–10000 lines of code) [34]. In the optimal case, a user should only
1.4. The FEniCS Project 7
write the mathematical statements of the model problem, and all the auxiliary work
is executed automatically. To get an overview of how this concept of automated code
generation can be achieved, we will shortly introduce the main components of the
FEniCS framework.
The main component of FEniCS is DOLFIN [28, 36], being an acronym for Dynamic
Object oriented Library for FINite element computation. This library implements
the high-performance C++ backend, consisting of the relevant data structures such
as meshes, functions spaces and functions. The main algorithms in the context of the
finite element method, i.a. element assembly, mesh handling or connection to linear
algebra solvers, are also part of DOLFIN. From a user perspective, DOLFIN is the
main connection layer between the high-level Python interface and the core compo-
nents, because it handles the communication between all components and extends
them with external software. The most important internal low-level components of
FEniCS are:
• UFL [2]: The Unified Form Language is a domain-specific language to formulate
problems, in the context of finite element methods, in their weak variational form.
With UFL, a model problem can be expressed in a natural and mathematical
form. It also serves as the input for the form compiler.
• FFC [31]: The FEniCS Form Compiler automatically generates DOLFIN code
from a given variational form. The goal of a form compiler is to use a well-tested
compiler, performing automated code generation tasks, in order to improve the
correctness of the resulting code.
• FIAT [30]: The FInite element Automatic Tabulator enables the automatic
computation of basis functions for nearly arbitrary finite elements.
An extensive description of all components can be found in [35]. Note, that some
design changes in the overall framework were made since the initial publication of [35].
For example, the meshing capabilities were bundled into a standalone component
named mshr [3]. Therefore, additional and more recent resources such as [3, 32] should
be consulted together with the collection of all source code repositories in [18].
It should further be mentioned that other simulation frameworks utilize a similar
concept as FEniCS. The Firedrake project [44], e.g., also uses the Unified Form
Language allowing a potentially steep learning curve for existing FEniCS users [26].
FEniCS-HPC [27] focuses on high-performance aspects such as partitioning and load
balancing. However, FEniCS-HPC is based on an earlier version of the DOLFIN
library, and DOLFIN itself has decent scalability properties as experiments showed
in [45].
Recently, the developers of FEniCS presented a Roadmap 2019–2020, announcing a
significant redevelopment of core libraries under the names DOLFIN-X and FFC-X.
8 1. Introduction
Stable releases are expected in early 2020 [46]. The work of this thesis, therefore, still
uses the most recent version 2019.1.0.r3.
2. Modeling Ideal Gas Flows Using
the Classical Theory
To understand and derive models for rarefied gas flows, we will first introduce the
classical theory to describe the behavior of general gas flows. This chapter starts by
introducing the fundamental balance laws in Section 2.1 followed by the presentation
of classical closures in Section 2.2 that are not able to capture non-equilibrium effects
as discussed in Section 2.3.
The overall goal is to determine these evolutions for all points x ∈ Ω from given
initial conditions, e.g. ρ0 (x, 0), u0 (x, 0), T (x, 0), together with a set of given boundary
conditions. The latter describe the outer environment and boundary behavior of
the fields on the domain boundary ∂Ω. In general, the change of all quantities is
described by model equations – in our particular gas flow setting by partial differential
equations (PDEs) – as introduced in the next Section 2.1.
The flow of gas follows three fundamental laws of physics: the point-wise conserva-
tion of mass in Eq. (2.1a), the conservation of momentum in Eq. (2.1b) (Newton’s
second law of motion) and the conservation of total energy in Eq. (2.1c) (first law of
10 2. Modeling Ideal Gas Flows Using the Classical Theory
∂ρ ∂(ρuj )
+ = 0, (2.1a)
∂t ∂xj
∂(ρui ) ∂(ρui uj + Πij )
+ = bi , (2.1b)
∂t ∂xj
∂Etot ∂(Etot uj + Πij ui + sj )
+ = r + u j bj . (2.1c)
∂t ∂xj
Examining the conservations laws in Eq. (2.1), some observations can be done in
accordance with [61]: In Eq. (2.1a), nuclear reactions are neglected, so that the total
mass is entirely conserved. The momentum balance Eq. (2.1b) allows us to compute
the change in momentum, i.e. mass multiplied by velocity, depending on the acting
forces. The total energy in Eq. (2.1c), however, changes due to the supplied heat and
the power of all acting forces. The latter is further composed of the internal energy
density and the kinetic energy density as
1
Etot = ρ + ρu2 , (2.2)
2
√
with denoting the specific internal energy and u = kuk2 = ui ui denoting the
velocity magnitude.
It is common to use the internal energy balance instead of the total energy bal-
ance. The derivation takes the kinetic energy balance into account, that is a direct
consequence of the momentum conservation multiplied by ui as
Evaluating the temporal derivative and using the product rule leads to
! ! !
∂ui ∂ρ ∂(ρuj ) ∂ui ∂(Πij ui ) ∂ui
ρui + u2i + u2i + ρui uj + − Πij = bi ui ,
∂t ∂t ∂xj ∂xj ∂xj ∂xj
(2.4)
2.1. Fundamental Balance Laws 11
where we further apply a split to use the mass conservation to express the temporal
density derivative as u2i ∂ρ
∂t
= 12 u2i ∂ρ
∂t
− 21 u2i ∂(ρu
∂xj
j)
. The remaining time derivatives are
recognized as the temporal change of kinetic energy with
∂ui 1 2 ∂ρ ∂ 1 2
ρui + ui = ρu , (2.5)
∂t 2 ∂t ∂t 2 i
and after reordering and a collection of spatial derivatives, the expression
!
∂ 1 2 1 2 ∂(ρuj ) ∂ui ∂(Πij ui ) ∂ui
ρui + ui + ρui uj + = bi ui + Πij , (2.6)
∂t 2 2 ∂xj ∂xj ∂xj ∂xj
∂ 1 2 ∂ 1 2 ∂ui
ρui + ρui + Πij ui = bi ui + Πij . (2.7)
∂t 2 ∂xj 2 ∂xj
Note that the kinetic energy itself is not conserved in contrast to the total energy.
After subtracting the kinetic energy balance Eq. (2.7) from the conservation of total
energy Eq. (2.1c), the balance law for the internal energy can be formulated as
Using the mass conservation again, after expanding the internal energy terms, leads
to an alternative form as
∂ ∂ ∂sj ∂ui
ρ + ρuj + + Πij = r. (2.9)
∂t ∂xj ∂xj ∂xj
Again note, that the internal energy itself is also not conserved because of the pro-
∂ui
duction term Πij ∂x j
describing energy conversion by, e.g., mechanical dissipation [61].
The symmetric Cauchy stress tensor Πij is usually [64] decomposed into the isotropic
pressure p := 13 Πkk and the deviatoric, trace-free stress tensor σij := Πij − 13 δij Πkk
as
Πij = pδij + σij . (2.10)
The decomposition of Eq. (2.10) is inserted into the conservation laws for mass and
momentum of Eqs. (2.1a) and (2.1b) and into the internal energy balance of Eq. (2.9).
Using the index shift properties of the Kronecker delta [47] tensor
1 i=j
δij = , (2.11)
0 else
12 2. Modeling Ideal Gas Flows Using the Classical Theory
we arrive, in accordance with [63] where source terms are omitted, at the system of
evolution equations in Lagrangian form
Dρ ∂vk
+ρ = 0, (2.12a)
Dt ∂xk
Dui ∂p ∂σij
ρ + + = bi , (2.12b)
Dt ∂xi ∂xj
D ∂ui ∂ui ∂si
ρ +p + σij + = r. (2.12c)
Dt ∂xi ∂xj ∂xi
∂
D
Here, the material derivative is used as Dt := ∂t + uj ∂x∂ j and the mass conserva-
tion of Eq. (2.1a) was used to rewrite the velocity terms in the momentum bal-
ance Eq. (2.1b) as
its particles are most of the time in a free flight without collisions. This fact can be
expressed as
τc
1, (2.16)
τ
with τc denoting the mean time between collisions and τ denoting the mean time in
free flight. It is obvious from Eq. (2.16), that gases at low density behave ideal because
of a high average particle distance and therefore a considerable mean free flight time
τ . Further arguments in [50] consider the mean kinetic energy to argue, that gases
also at high temperatures can behave ideally. Struchtrup showed in [50], that a
gas without special molecular structure behaves ideally under standard conditions,
i.e. temperature T0 = 298 K and pressure p0 = 1 bar.
Assuming an ideal gas, the pressure p can be related to the mass density ρ and the
absolute temperature T through the ideal gas law
R
p = ρRs T = ρ T, (2.17)
M
where R ≈ 8.314 molJ K is the universal gas constant, M is the molar mass of the
R
gas [37] and Rs = M is the specific gas constant. The ideal gas law is also called
thermal equation of state. The caloric equation of state, further, relates the specific
internal energy to the temperature [37] with
R
=z (T − TR ) + R . (2.18)
M
In Eq. (2.18), the coefficient z depends on the atomic structure of the considered gas,
with the relation
3
2 monoatomic
z = 52 diatomic . (2.19)
3 else
The restriction to monoatomic gases and an absolute scale (TR = 0, R = 0) allows
restating the relation of Eq. (2.18) to
= cv T, (2.20)
where the heat capacity at constant volume cv = 32 Rs = const is used. A gas with
ideal thermal behavior of Eq. (2.17) and constant cv is called calorically perfect or
perfect gas in some contexts [41, 76]. With the two equations of state, the fields of
pressure, temperature and density can be related.
It remains to prescribe closure relations for the deviatoric stress σ and the heat flux s,
so-called constitutive equations [37] or laws [61]. The classical theory of gas dynamics
14 2. Modeling Ideal Gas Flows Using the Classical Theory
The classical NSF theory is routinely [50] used in engineering applications to analyze
fluid flows under standard conditions using the finite element method [16, 19, 55],
although they are not yet fully understood from a mathematical perspective [8]. From
a physical point of view, it is almost surprising, that a massive amount of individual
acting gas particles can be described by a rather low amount of partial differential
equations – because after all, a gas at standard conditions (1 bar, 25 ◦C) contains
about 2.43 × 1016 gas atoms per cubic millimeter [50].
The reason for this behavior is the massive amount of resulting collisions. These
collisions equally distribute deviations and disturbances of individual particles – they
behave as a continuum [50, 61, 64] – in which a macroscopic description, using the
classical NSF system is sufficient. The continuum assumption erases the molecular dis-
continuities by averaging all microscopic quantities over a small sampling volume [29].
For this to be possible, the gas has to be in thermodynamic equilibrium, where the
intermolecular collision frequency ν is much higher than the process frequency ω [29,
50], expressed as
ω
1. (2.23)
ν
An equivalent description can be derived using the mean free flight time τ = ν1 and
the mean free path λ = cavg τ with the mean particle speed cavg [50, 64]. The mean
free path, therefore, is the mean distance traveled between two particle collisions.
The requirement of Eq. (2.23) is therefore fulfilled, if the mean free path is sufficiently
small compared to the relevant characteristic length scale L, resulting in
λ ω
Kn := = 1. (2.24)
L ν
The Knudsen number Kn in Eq. (2.24) is the dimensionless parameter describing
these considerations.
equations serve as a sufficiently good description of the gas behavior. The Euler
equations consist of the fundamental balance laws in the reversible case with si = 0
and σij = 0 [50, 61]. The Navier–Stokes–Fourier system with non-trivial heat flux
and stress closures, presented in Section 2.3, extends the range of sufficiently small
modeling errors to higher Kn-numbers of Kn . 0.01. The range, where classical
models can be used, is called the hydrodynamic regime. Outside this hydrodynamic
range, a gas flow is called rarefied and extended macroscopic models or a microscopic
description of the gas is needed. A rarefied gas is more diluted, having fewer particles
in a given control volume, but it is still possible, to use continuum models with
macroscopic descriptions. In fact, it is possible to incorporate higher-order slip
boundary condition terms into the NSF system to extend the range even further [29].
However, as we will discuss in the following Section 2.3.2, they cannot describe other
gas rarefaction effects occurring in the transition regime of 0.05 . Kn [43, 62]. A
graphical summary of gas models and a characterization, based on the Knudsen
number, is presented in Fig. 2.1.
The Boltzmann equation, introduced and discussed in Chapter 3, describes gas flows at
all Knudsen numbers within a microscopic framework. However, this central equation
of the kinetic theory of gases [50], is numerically expensive to solve [43]. It is possible,
to approximate the Boltzmann equations to extract a set of macroscopic equations.
That is desirable in order to keep the compact description of gases macroscopically.
In the context of this work, we will use the R13 equations, proposed by Struchtrup
and Torrilhon in [52] and reviewed in e.g. [51, 62], as one prominent example for
extended macroscopic gas flow models suitable in the transition regime. This set of
equations is capable of predicting various non-equilibrium effects as discussed in the
following Section 2.3.2.
dT 1 d2 T
T (x + λ) → T (x̃ + Kn) = T (x̃) + Kn + 2
Kn2 + O(Kn3 ). (2.25)
dx̃ 2 dx̃
Therefore, for larger Kn-numbers, higher-order terms become more significant and
have to be taken into account, i.e. specifying only first-order terms through the
∂T ∂uhi
classical closures (si = −κ ∂x i
and σij = −2µ ∂xji ) is not sufficient.
2.3. Discussion of Classical Models 17
Euler
NSF
Model Simplicity
R13
Boltzmann equation
λ
0 0.001 0.01 0.1 1 10 100 L
= Kn
Hydrodynamic Slip Flow Transition Regime Free Molecular
Regime Regime NSF equations fail, Flow (Free Flight)
NSF valid suffi- Higher-order modeling with extended Particle collisions
ciently close to BC needed macroscopic models are not dominant.
thermod. equilibrium. for NSF. or BM equation.
Figure 2.1. Comparison of different gas flow models and their validity among the Knudsen number
spectrum. The Euler equations are only valid very close to the thermodynamic equilibrium at
Kn ≈ 0. The classical Navier–Stokes–Fourier equations have a broader validity and can be shipped
with special higher-order boundary conditions, above the hydrodynamic flow regime, into the slip flow
regime. For accurate modeling of gas flows in the transition regime, where rarefaction effects play a
role, extended macroscopic models have to be considered. These models extend the classical NSF
closures and typical examples are the Burnett, Super-Burnett, Grad13, R13 or the R26 equations.
The Boltzmann equation, however, is valid across the complete Knudsen spectrum but can be
computationally inefficient at lower Kn-numbers. Note that the schematic ranges of the flow regime
naming are not exact and the definitions may vary, depending on the context. In [62], e.g., an
additional kinetic regime is mentioned at about 2 . Kn . 15, where a detailed description through
a distribution function is necessary. The plot extends ideas from [48] with information from [29, 50,
51].
Recalling the definition of the Knudsen number Kn = Lλ as the ratio between the
mean free path and the characteristic length scale, a non-equilibrium gas flow is
present for processes involving:
• Gas rarefaction (λ ↑): A gas flow situation, in which the mean free path is
relatively high compared to the relevant process length scale. Examples are
re-entry flights at high altitudes where low pressure and low density are present.
The relatively low amount of particles lead to a significant ratio between the
mean free path and the length dimension of the aircraft. Other examples are
vacuum devices with very low gas densities.
In a general non-equilibrium gas flow at about Kn & 0.05, many interesting rarefaction
effects or micro-scale phenomena were observed in experiments or from the analysis of
the Boltzmann equation [51]. A comprehensive list of effects is given in [51] and [62],
i.e. a parallel heat flux (in flow direction) in a channel flow, contradicting Fourier’s law
as there is no temperature difference; a non-constant pressure behavior in Couette and
Poiseuille channel flows although no flow across the channel is present; a minimum
of the mass flow rate (Knudsen minimum) in a in force-driven Poiseuille flow, also
known as Knudsen paradox; a non-convex temperature profile in such microchannels
while NSF predicts a strictly convex profile for the same setup; temperature-induced
flow situations in channels; Knudsen boundary layers, i.e. temperature jump and
velocity slip at walls.
With the extensive list of non-equilibrium effects, the overall motivation to derive
extended macroscopic models for gas flows becomes clear, i.e. to predict as many of
these rarefaction effects as possible while keeping the set of equations compact using
a macroscopic model. These flow situations shall, therefore, be predicted quantitative
in terms of gas phenomena and qualitative in terms of a low modeling error by keeping
a high model accuracy. Another general aspect of rating the success of an extended
model is the accurate prediction of shock structures at larger Ma-numbers [59].
It turned out, that the Boltzmann equation, predicting all of the above-listed effects
accurately, can be approximated to extract extended model equations, as the following
Chapter 3 proceeds. These extended models act as an extension or generalization to
classical NSF closures, that are not able to predict the relevant flow phenomena at
higher Knudsen numbers.
3. Kinetic Theory of Non-Equilibrium
Gas Flows
The complete opposite approach compared to the classical macroscopic models, in-
troduced in Chapter 2, is to model every particle α separately, i.e on a microscopic
level, using Newton’s second law of classical mechanics. Every particle α has the
same mass m and a position xα = (xα , yα , zα ). A force Fα would then influence the
dynamic behavior of a particle α, induced by the current state of all other particles
{xβ }β=1,..,B , through [61]
mẍα = Fα ({xβ }β=1,..,B ). (3.1)
However, considering the large number of particles, this approach would lead to a
huge set of coupled equations that cannot be solved efficiently. Also, the individual
positions of all particles α are not relevant in practical applications [61]. In fact, it
practically does not make a difference, if the individual particle α = 1 or the individual
particle α = 2 is at the position x = (1, 2, 3) – because in the end, they have the same
properties anyway. However, it is important to know, how many particles are at a
given position x = (1, 2, 3) and how their current state, in terms of their velocities c, is
described. These two properties are encoded in the distribution function f (or phase
density), that serves as the primary quantity of interest in the kinetic gas theory.
In the following, a short introduction to the basic concepts of kinetic theory is given,
being preliminary to the introduction of the main model equations of this thesis,
namely the set of R13 equations.
The distribution function is defined over the phase space V := Ω × R3 , that is the
product of the spatial domain x ∈ Ω ⊂ R3 and the velocity c ∈ R3 . The distribution
function f : R+ × V, (t, x, c) 7→ f (t, x, c) describes the probability of encountering
particles with the velocity c at the location x for the time t. In fact, the number of
20 3. Kinetic Theory of Non-Equilibrium Gas Flows
The particle density atR a location x and time t can be obtained by an integration over
all possible velocities R3 f (t, x, c) dc, such that mass density ρ(x, t), as the particle
mass m times the particle density, can be identified through
Z
ρ(x, t) = m f (t, x, c) dc. (3.3)
R3
Knowledge of f does not only lead to expressions for the density. In fact, all other
macroscopic quantities (see Chapter 2) can be computed from the distribution func-
tion. The velocity u(x, t) and the internal energy density (x, t) as remaining quanti-
ties of the fundamental balance laws and the first two non-equilibrium quantities, heat
flux q(x, t) and the deviatoric stress tensor σ(x, t), can be identified [62] through
m Z
ui (x, t) = ci f (t, x, c) dc, (3.4)
ρ(x, t) R3
m Z 1
(x, t) = (ci − vi )2 f (t, x, c) dc, (3.5)
ρ(x, t) R3 2
Z
1
si (x, t) = m Ci Cj2 f (t, x, c) dc, (3.6)
R 3 2
Z
σij (x, t) = m Chi Cji f (t, x, c) dc, (3.7)
R3
∂f ∂f bi ∂f
+ ci + = S(f, f ), (3.8)
∂t ∂xi m ∂ci
where S(f, f ) denotes the collision integral. In general, due to its higher dimension-
ality over the phase space Ω × R3 , the direct computation of f is computationally
expensive. This is the reason to approximate the Boltzmann equation in order to
derive a set of extended equations with model complexity above the classical NSF
system.
3.2. Derivation of Extended Macroscopic Models 21
The Chapman–Enskog series expansion assumes that the distribution function f can
be expanded [64] with respect to the Knudsen number as
∞
Knj f (j) (t, x, c)
X
f (t, x, c, Kn) = (3.9)
j=0
i.e. the Maxwell distribution. The resulting first-order distribution function is called
Chapman–Enskog distribution fCE . This hierarchical concept can be extended to
arbitrary Kn-order.
Together with the set of fundamental balance laws Eq. (2.12), these distribution
functions can then be projected with Eqs. (3.6) and (3.7) to produce [64] the
• Euler equations using the zeroth-order distribution function fM , i.e. si = 0 and
σij = 0.
22 3. Kinetic Theory of Non-Equilibrium Gas Flows
The method of moments assumes that the state of a gas can be described by an
extended set of moments as [50]
Z
uA = ΨA (ck )f (t, x, c) dc, (3.12)
R3
The multiplication of the Boltzmann equation with ΨA and integration over the
velocity space produces a set of moment evolution equations. In these equations,
higher-order moments are introduced and need an explicit closure formula. The
derivation of these closures uses the Grad 13-moment distribution, that is derived
[13]
by an ansatz in the polynomials ΨA . The resulting function fG13 is then used
to evaluate the expressions for the higher-order moments [64] in order to express
these terms as functions from the variables uA – the classical closure strategy. The
complete procedure can also be seen as a model reduction by replacing the linear
higher-dimensional equation by a set of low-dimensional non-linear equations. The
collision terms on the right-hand side of Eq. (3.8) can also be evaluated using the
BGK model [64] and assuming Maxwell molecules with special power potential [50].
While the resulting G13 system of equations can predict some rarefaction effects, it
produces artifacts in shock wave profiles [64].
3.3. Regularized 13-Moment Equations 23
The set of equations, as revisited in [62], consists of the three fundamental balance
laws from Eq. (2.12) as
Dρ ∂vk
+ρ = 0, (3.13)
Dt ∂xk
Dui ∂p ∂σij
ρ + + = bi , (3.14)
Dt ∂xi ∂xj
D ∂ui ∂ui ∂si
ρ +p + σij + = r, (3.15)
Dt ∂xi ∂xj ∂xi
with an evolution equation for the stress tensor
∂σij ∂σij uk 4 ∂shi ∂uhi ∂uji ∂mijk
+ + + 2p + 2σkhi + = −νσij , (3.16)
∂t ∂xk 5 ∂xji ∂xji ∂xk ∂xk
and an evolution equation for the heat flux
∂si ∂si uk ∂ui 5 1 ∂σjk 1 ∂p 5 ∂θ
+ + sk − pδij + σij − σij + p
∂t ∂xk ∂xk 2 ρ ∂xk ρ ∂xj 2 ∂xi
6 ∂uj 1 ∂ R̄ik 2
+ δ(ij sk) + mijk + = −ν si , (3.17)
5 ∂xk 2 ∂xk 3
24 3. Kinetic Theory of Non-Equilibrium Gas Flows
Neglecting the highest-order terms mijk , Rij , R would reduce the equations to the
G13 system [62]. Considering an ideal and monoatomic gas as in Chapter 2, the
pressure is given by p = ρRs T = ρRs cv = 23 ρ and using the temperature in terms of
k
energy units as θ = m T with Boltzmann constant k, we further have p = ρθ [62].
The evolution Eq. (3.17) for the heat flux can be rewritten only to have first-order
derivative terms. We insert the abbreviation of Eq. (3.18) and expand
and further expand the symmetric term, using the symmetry of δij , as
!
6 ∂uj 61 ∂uj ∂uj ∂uj
δ(ij sk) = δij sk + δki sj + δjk si (3.26)
5 ∂xk 53 ∂xk ∂xk ∂xk
!
2 ∂ui ∂uk ∂uk
= sk + sk + si . (3.27)
5 ∂xk ∂xi ∂xk
3.3. Regularized 13-Moment Equations 25
With the increased number of variables in the R13 system, an extensive set of boundary
conditions is required. The R13 equations are derived from the kinetic gas theory
using the distribution function f (t, x, c) as discussed in Section 3.3.1. Boundary
conditions are, therefore, also derived in this framework by prescribing the incoming
half of the distribution function (i.e. c · n > 0 where n is the normal pointing into the
domain) at a wall [66].
Following [66], the most common boundary condition for f is given by the Maxwell
accommodation model. It assumes that a certain fraction χ of particles hitting the
wall is accommodated back into the gas with a given distribution function, that is
assumed to be a Maxwellian fM as in Eq. (3.11). The remaining parameters in fM
are chosen according to the wall conditions θw and either ρw or pw . The remaining
porting of particles (1 − χ) is specularly reflected [64].
In short, the distribution function in an infinitesimal neighborhood of the considered
wall is given by
(∗)
χf + (1 − χ)fgas
M (c) (c) n · (c − v w ) > 0,
f˜(c) = (3.29)
fgas (c) n · (c − v w ) < 0,
(∗)
where fgas accounts for transformed velocities as the result of specular reflection.
Using the method of moments as in Section 3.2.2, the resulting projection can be eval-
uated, and suitable boundary conditions can be derived [66]. The relevant linearized
boundary conditions are given in Section 3.3.3.
Throughout this thesis, we will consider the steady-state and linearized R13 equations
using pressure p and temperature θ instead of density ρ. These pressure-primitive
variables are a common choice for engineering applications [55]. Reformulation of
26 3. Kinetic Theory of Non-Equilibrium Gas Flows
Eqs. (3.13) to (3.15) is done by expanding the material derivatives, using p = ρθ,
using = 23 θ and by neglecting the temporal derivatives as
∂ρ ∂ρ ∂uk ∂( pθ ) p ∂uk
0= + uk +ρ = uk + (3.30)
∂t ∂xk ∂xk ∂xk θ ∂xk
!
p ∂θ 1 ∂p p ∂uk
= uk − 2 + + (3.31)
θ ∂xk θ ∂xk θ ∂xk
!
uk ∂p p ∂θ p ∂uk
= − + , (3.32)
θ ∂xk θ ∂xk θ ∂xk
∂ui ∂ui ∂p ∂σij
bi = ρ + ρuk + + (3.33)
∂t ∂xk ∂xi ∂xj
p ∂ui ∂p ∂σij
= uk + + , (3.34)
θ ∂xk ∂xi ∂xj
∂ ∂( 32 θ) ∂ui ∂ui ∂si
r = ρ + ρuk +p + σij + (3.35)
∂t ∂xk ∂xi ∂xj ∂xi
3p ∂θ ∂ui ∂ui ∂si
= uk +p + σij + . (3.36)
2θ ∂xk ∂xi ∂xj ∂xi
While the evolution Eq. (3.16) for the stress does not have any density or internal
energy variables and therefore only has a vanishing temporal derivative, the evolution
Eq. (3.28) for the heat flux is restated using
θ ∂ρ θ ∂( pθ )
−σik = −σik (3.37)
ρ ∂xk ρ ∂xk
∂θ θ ∂p
= σik − σik . (3.38)
∂xk p ∂xk
Both equations then read
∂σij uk 4 ∂shi ∂uhi ∂uji ∂mijk
+ + 2p + 2σkhi + = −νσij , (3.39)
∂xk 5 ∂xji ∂xji ∂xk ∂xk
from this state as U = U 0 + δ Ũ . This ansatz is then inserted into the equation
and only the δ-linear terms are kept as deviation quantities. For quantitates in the
denominator, an additional Taylor expansion has to be utilized [69].
However, an equivalent but more general [1] approach is to consider each of the
Eqs. (3.32), (3.34), (3.36), (3.39) and (3.40) as a function Y = f (U ) where U =
(U1 , . . . , Un ) consists of all variables including derivatives. By means of a multi-variant
Taylor expansion around an operating point U 0 , that also includes expressions for all
variables and derivates, the initial function, which is formulated in terms of absolute
quantities U , can then be stated in terms of deviation quantities û := U − U 0 =
(û1 , . . . , ûn ) as
" # " #
∂f (U ) ∂f (U )
ŷ = û1 + · · · + ûn + O(û2i ) ∀1 ≤ i ≤ n. (3.41)
∂U1
U =U 0
∂Un
U =U 0
For example, the steady-state mass balance Eq. (3.32) can be seen as
!
uk ∂p p ∂θ p ∂uk
Y := 0 = − + =: f (U ), (3.42)
θ ∂xk θ ∂xk θ ∂xk
∂p
with U = (p, θ, uk , ∂x , ∂θ , ∂uk ) and the operating point U 0 = (p0 , θ0 , 0, 0, 0, 0). The
k ∂xk ∂xk
resulting equation is written in terms of deviation quantities as
" # " # " #
∂f (U ) ∂f (U ) ∂f (U )
0̂ = 0 ≈
p̂ +
θ̂ +
uˆk (3.43)
∂p
U0
∂θ
U0
∂uk
U0
ˆ ! ˆ !
∂f (U ) ∂p ∂f (U ) ∂θ
+ ∂p
+ ∂θ
∂ ∂xk U 0 ∂xk ∂ ∂xk U 0 ∂xk
ˆ !
∂f (U ) ∂u k
+ ∂u ,
∂ ∂xkk
U0
∂xk
1
"
∂p p ∂θ
!#
uk
ˆ ! u p
∂p ˆ !
∂θ
k
+ −
uˆk +
+ − 2
θ ∂xk θ ∂xk
U0
θ
U0
∂xk θ U ∂xk
0
p ˆ !
∂u k
+ ,
θ U0
∂xk
28 3. Kinetic Theory of Non-Equilibrium Gas Flows
and due to the operating point U 0 , the only remaining term is the divergence of u
due to
0 = [0] p̂ + [0] θ̂ (3.45)
ˆ
∂p
! ˆ
∂θ
!
p0
ˆ
∂u
!
k
+ [0] uˆk + [0] + [0] + ,
∂xk ∂xk θ0 ∂xk
which finally then yields the linearized, steady-state mass balance. This more general
approach would also allow linearizing around an operating state with a non-vanishing
partial derivative, such as an evolved velocity profile across a channel. The remaining
balance laws (Eqs. (3.34) and (3.36)) can be linearized in the same way. Dropping
the deviation indicator ˆ·, we obtained the steady-state and linearized fundamental
balance laws
∂uk
= 0, (3.46)
∂xk
∂p ∂σij
+ = bi , (3.47)
∂xi ∂xj
∂ui ∂si
p0 + = r. (3.48)
∂xi ∂xi
The linearized, steady-state extended evolution equations of Eqs. (3.39) and (3.40)
then read
4 ∂shi ∂uhi ∂mijk
+ 2p0 + = −νσij , (3.49)
5 ∂xji ∂xji ∂xk
5 ∂θ ∂σik 1 ∂Rik 1 ∂R 2
p0 + θ0 + + = −ν si , (3.50)
2 ∂xi ∂xk 2 ∂xk 6 ∂xi 3
while the linearized closures from Eqs. (3.19) to (3.21) can also be processed in the
same manner as
θ0 ∂σhij
mijk = −2 , (3.51)
ν ∂xki
24 θ0 ∂shi
Rij = − , (3.52)
5 ν ∂xji
θ0 ∂sk
R = −12 . (3.53)
ν ∂xk
The body force bi and the heat source r are neglected for simplicity. Further sim-
plifications can be done by either setting all reference values θ0 , p0 to unity and end
up with the only remaining parameter τ = ν1 . Another more general approach is to
reformulate the equations in a dimensionless form by relating every quantity to its
reference. We apply the latter approach and define
xi θ p τ ui
x̂i := , θ̂ := , p̂ := , τ̂ := , ûi := √ , (3.54)
L θ0 p0 τ0 θ0
3.3. Regularized 13-Moment Equations 29
σ si mijk Rij
σ̂ij = , ŝi = √ , m̂ijk = √ , R̂ij = , (3.55)
p0 p0 θ0 p0 θ0 p0 θ0
All quantitates are then replaced by their dimensionless counterpart multiplied with
the reference value, e.g. xi → Lx̂, and are inserted into the linearized equations.
Furthermore, the Knudsen number can be identified as
√
τ0 θ0
Kn = . (3.56)
L
The resulting system of interest, i.e. the linearized, steady-state and dimensionless
R13 equations, can then be written as
∂uk
= 0, (3.57)
∂xk
∂p ∂σij
+ = 0, (3.58)
∂xi ∂xj
∂ui ∂si
+ = 0. (3.59)
∂xi ∂xi
4 ∂shi ∂uhi ∂mijk 1
+2 + =− σij , (3.60)
5 ∂xji ∂xji ∂xk Kn
5 ∂θ ∂σik 1 ∂Rik 1 2
+ + =− si . (3.61)
2 ∂xi ∂xk 2 ∂xk Kn 3
∂σhij
mijk = −2 Kn , (3.62)
∂xki
24 ∂shi
Rij = − Kn , (3.63)
5 ∂xji
where the marker ˆ·, denoting dimensionless and linearized deviation quantities, has
again been dropped. Further note that the closure R̂ is zero due to the setup of no
heat source and no mass source, that allows to insert the mass balance into the heat
balance and therefore identifying the heat flux s as a divergence-free quantity. The
30 3. Kinetic Theory of Non-Equilibrium Gas Flows
∇ · u = 0, (3.64)
∇p + ∇ · σ = 0, (3.65)
∇ · u + ∇ · s = 0, (3.66)
4 1
(∇s)STF + 2(∇u)STF + ∇ · m = − σ, (3.67)
5 Kn
5 1 1 2
∇θ + ∇ · σ + ∇ · R = − s, (3.68)
2 2 Kn 3
m = −2 Kn (∇σ)STF , (3.69)
24
R = − Kn (∇s)STF . (3.70)
5
Here, the deviatoric part of the symmetric tensor is denoted by (·)STF . To allow
formulating boundary value problems, a set of boundary conditions is required. The
most recent version was given in [42] while we use the notation of [65, 68] as
un = 0, (3.71)
1
σnt = χ̃ (ut − uw
t ) + st + mnnt , (3.72)
5
11
Rnt = χ̃ −(ut − uw t ) + s t − m nnt , (3.73)
5
1 2
w
sn = χ̃ 2(θ − θ ) + σnn + Rnn , (3.74)
2 5
2 7 2
w
mnnn = χ̃ − (θ − θ ) + σnn − Rnn , (3.75)
5 5 25
1 1
mnnn + mntt = χ̃ σnn + σtt , (3.76)
2 2
where a two-dimensional local boundary-aligned coordinate system in terms of normal
and tangential components (n, t) is used in order
q to generate the projections. The
χ
modified accommodation factor is given by χ̃ = πθ20 2−χ [68]. The boundary condi-
tions are equal to the Onsager boundary conditions of [42] and have been adjusted
compared to previous publications, as described in [65]. The most general version
of the boundary conditions includes Onsager coefficients that are not focused in the
context of this work.
4. Introduction to the FEniCS
Computing Platform
Before proceeding to treat the linearized R13 equations, a short introduction re-
garding the usage of the FEniCS project is given. This introduction also serves
as an introduction to the finite element method. Extensive example material can
be found in [32, 35]. However, due to the dynamic development of FEniCS, these
examples might not be executable without modifications. We, therefore, stick to
the current documentation [13] and its examples [18]. Furthermore, throughout this
thesis, we use the Python interface due to its modern high-level language style and
its interoperability with other Python software.
We will first consider Poisson’s equation in Section 4.1, where the general concept
of reformulating a problem from a strong into a variational or weak form, suitable
for finite element discretization, is presented. Two types of boundary conditions,
namely Dirichlet and Neumann type, are discussed. The second example problem
is Stokes’ problem, considered in Section 4.2. For this two-equation problem, the
concept of mixed finite element methods is introduced with particular focus on the
corresponding implementation in FEniCS. Mixed finite element methods require a
stable pair of elements, such as the well-known Taylor–Hood elements, that we utilize
in that example.
One of the most important and most popular partial differential equations is Poisson’s
equation. The linear, second-order and elliptic PDE is a generalization of Laplace’s
equation arising in a variety of physical contexts [17], such as heat, chemical concentra-
tion or electrostatic field modeling. An example problem involving Poisson’s equation
acts as an introductory example to the FEniCS platform and is given in [14].
−∆u = f in Ω, (4.1)
u=0 on ΓD , (4.2)
∇u · n = g on ΓN , (4.3)
In the strong formulation 4.1, the Laplace operator ∆ can be written as the divergence
2
of the gradient leading to ∆u = ∇·(∇u) = 2i=1 ∂∂xu2 which is used in Gauß’s divergence
P
i
theorem in the following.
As outlined in [16], the general idea of a spatial discretization using the finite element
method consists of weakening the requirements for u by allowing larger function
spaces than C m and reformulating the problem in a weak, variational sense. The first
step is, therefore, the multiplication of Eq. (4.1) with a test (or weighting) function
v and a subsequent integration over the domain Ω, that leads to
Z Z
− v∆u dΩ = vf dΩ. (4.4)
Ω Ω
Note, that the regularity requirement of u is already weakened and the second deriva-
tive does not have to be continuous anymore. In fact, it is sufficient that u is twice
differentiable, while the second derivative is square-integrable. In other words, the
function has to fulfill u ∈ H 2 (Ω) while the Sobolev space H 2 (Ω) consists of all func-
tions whose partial derivatives up to the second order are square-integrable and thus
part of the Lebesgue space L2 (Ω), following the general definition of
∂ |α| u
( )
H k (Ω) = u ∈ L2 (Ω) : ∈ L2 (Ω) ∀|α| ≤ k , (4.5)
∂xα1 1 ∂xα2 2
that is using the product rule for the divergence operator ∇ · (v∇u) = v (∇ · ∇u) +
∇v · ∇u and Gauß’s divergence theorem [73]. The regularity requirements have been
further modified, such that u, v ∈ H 1 (Ω).
4.1. The Poisson Problem 33
The natural (Neumann) boundary conditions can now be inserted into the weak form
while the essential (Dirichlet) boundary conditions are embedded into the function
spaces, such that
n o
u ∈ S := u ∈ H 1 (Ω) : u = uD on ΓD , (4.7)
n o
v ∈ V := v ∈ H 1 (Ω) : v = 0 on ΓD . (4.8)
For our case with uD = 0, both spaces S and V are equal. The continuous weak form
can then be formulated as:
for all v ∈ V.
can be identified. Using the FEniCS framework, the continuous weak form is sufficient
to solve the problem together with the boundary conditions using a prescribed finite
element. For the sake of completeness, we will continue to present the general concepts,
as they are used in the solver backend, before focusing on the FEniCS implementation
of Poisson’s problem.
In general, the Lax–Milgram lemma can be used to prove existence and uniqueness
of a solution to the weak formulation 4.2, if the bilinear form a(u, v) is continuous
and coercive and the linear mapping l(v) is continuous. In the case of inhomogeneous
Dirichlet conditions, further treatment of u is needed to have S = V in order to apply
the lemma, see for example [16]. To finally solve the problem, finite-dimensional
subspaces S h , V h of S, V are considered. For a given triangulation T h (Ω) of Ω into
the subdomains Ωe , the discrete spaces consist of piecewise polynomials of degree m
and read:
n o
S h = u ∈ H 1 (Ω) : u|Ωe ∈ Pm (Ωe ) ∀e and u = uD on ΓD , (4.12)
n o
V h = v ∈ H 1 (Ω) : v|Ωe ∈ Pm (Ωe ) ∀e and v = 0 on ΓD , (4.13)
for all v h ∈ V h ⊂ V.
With the help of Cea’s lemma, one can prove, that the error of such an approximation
is bounded, details can be found for example in [16]. To produce a linear system
of equations, the trial function uh is discretized and therefore expressed as a linear
combination of shape functions – for homogenous Dirichlet boundary conditions and
following the notation of [16] as
uh (x) =
X
NA (x)uA , (4.15)
A∈η
where A is a node in the finite element mesh and NA (x) its corresponding shape func-
tion. It is not possible and necessary to test the weak formulation against all possible
v h ∈ V h . In fact, using the same basis V h := span {NA (x)} for the test functions
produces a system of equations for the coefficients uA and the final solution can be
reconstructed by means of Eq. (4.15) as a linear combination of shape functions.
Solving this Poisson problem using FEniCS can be achieved conveniently. After
loading the dolfin module, the computational domain is restricted to a unit square
Ω = [0, 1]2 , and a triangular mesh is created using:
1 from dolfin import *
2 # Create mesh and define function space
3 mesh = UnitSquareMesh(32, 32)
2
Listing 4.1 Mesh generation for a unit square domain Ω = [0, 1] [14].
The next step is to prescribe the discrete function space V h . Here, and throughout
this thesis, we focus on H 1 -conforming Lagrangian finite elements Pm (in FEniCS
terminology CGm [35]), where m denotes the maximal polynomial degree. These
elements are the most essential choice and should be implemented in all finite element
software. The usual strategy is to transform the integrals occurring in the weak form
to a simple reference element, where the basis functions Na (x) are defined only once,
using the nodes on the reference triangle a. For Lagrange triangular elements, the
nodes (degrees of freedom) are distributed uniformly across the edges of the reference
2-simplex defined by the points (0, 0), (0, 1) and (1, 0).
Furthermore, the basis functions form a nodal basis, such that at a given reference
node a, only the corresponding basis function has a value of one while all other basis
functions vanish:
Na (xb ) = δab ∀a, b. (4.16)
4.1. The Poisson Problem 35
Here, a, b are basis points of the reference element. The basis functions for the
first-order P1 element are therefore linear and are shown in Fig. 4.1.
Figure 4.1. P1 shape functions on the triangular reference element (2-simplex). The figures and a
WolframScript to generate arbitrary order Lagrangian basis function plots can be found in [54].
It should be mentioned that the FEniCS framework offers a variety of other elements,
some of them rather exotic, that can be explored in other examples [13] or in [35].
Some physical model problems require the usage of special elements. To improve
the quality of the discretization, we will later on use higher-order Pm elements. To
furthermore present an exemplary distribution of basis points inside the reference
triangle, all shape functions for the P3 element are presented in Fig. 4.2
The definition of a function space in FEniCS needs information about the mesh, such
as the spatial dimension. The definition of a suitable function space, using Lagrange
element of first order, then reads:
1 V = FunctionSpace(mesh, "Lagrange", 1)
Listing 4.2 Generation of function space using P1 elements for a given mesh [14].
The Dirichlet boundary conditions are defined with the help of an indicator function
and and DirichletBC-object. In the case of the model problem 4.1, the function u
is set to zero at the Dirichlet boundary ΓD = {(x, y) ∈ R : (0, y) ∪ (1, y) ⊂ ∂Ω}. The
corresponding definition in FEniCS uses the array of spatial coordinates, i.a. x[0],
and reads:
1 # Define Dirichlet boundary (x = 0 or x = 1)
2 def boundary(x):
3 return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS
4 # Define boundary condition
5 u0 = Constant(0.0)
6 bc = DirichletBC(V, u0, boundary)
In order to solve the actual weak form 4.2, the trial and test functions are defined over
the previously created function space, so that the trial function can be expressed using
36 4. Introduction to the FEniCS Computing Platform
.
Figure 4.2. P3 shape functions on the triangular reference element (2-simplex). The figures and a
WolframScript to generate arbitrary order Lagrangian basis function plots can be found in [54]
the given basis function with a simultaneous testing in the same basis. Furthermore,
all other relevant input data has to be defined. The source function f and the
Neumann boundary function (normal derivative) g are prescribed as
7 )
8 g = Expression("sin(5*x[0])", degree=2)
9 a = inner(grad(u), grad(v))*dx
10 L = f*v*dx + g*v*ds
The formulation of the weak form is sufficient in order to solve the discrete system. In
fact, all other element-level and system assembly routines are performed automatically.
The Dirichlet boundary conditions are also encoded in the function space by the
specification in the solve-method. It is, therefore, possible to efficiently solve the
same model equations with different boundary conditions. The discrete solution uh
of a(uh , v h ) = l(v h ) ∀v h ∈ V h is stored in a separate function, that can be written
to a file, e.g. in VTK file format. Due to its interoperability, solution fields can be
directly plotted using matplotlib. The final piece of the example code then reads:
1 # Compute solution
2 u = Function(V)
3 solve(a == L, u, bc)
4 # Save solution in VTK format
5 file = File("poisson.pvd")
6 file << u
7 # Plot solution
8 import matplotlib.pyplot as plt
9 plot(u)
10 plt.show()
Listing 4.5 Solving the weak formulation using given Dirichlet data [14].
The complete example source code example can be found in [18] and is listed in
Appendix D under Listing D.1 for reproducibility.
In contrast to the Poisson problem of Section 4.1, the Stokes problem includes two
equations, the scalar-valued incompressibility constraint in Eq. (4.20) and the vector-
valued momentum balance in Eq. (4.19). It is therefore required to multiple with test
functions of matching tensorial degree. Eq. (4.19) is multiplied with v and integrated
over the domain Ω. Integration by parts is performed, allowing to insert the Neumann
boundary condition naturally. Note, that the divergence operator is recognized from
the inner product
I : ∇v = ∇ · v. (4.23)
Eq. (4.20) is integrated and multiplied with the pressure-corresponding test function
q with no integration by parts applied.
The weak form required for FEniCS does not include Dirichlet terms. This is because
of the particular way of encoding Dirichlet conditions into the corresponding spaces,
before solving the variational formulation. It is therefore sufficient to supply a weak
form assuming homogenous Dirichlet boundary conditions because the treatment
of essential boundary conditions is done automatically. Having this in mind, the
required weak formulation therefore reads:
with proper mixed function spaces W h accounting for Dirichlet boundary conditions.
4.2. The Stokes Problem 39
The Stokes problem is of saddle-point structure with the pressure acting as a La-
grangian multiplier of the incompressibility constraint [16]. The solvability of the
discrete system, therefore, depends on the choice of the discrete finite element spaces.
In fact, after performing a rank analysis of the discrete matrix problem [16] to obtain
a non-singular system of equations, a necessary condition for a unique solution for
both pressure and velocity can be given in terms of function space dimensions [16]
as
dim Qh ≤ dim V h . (4.27)
A sufficient condition is the Ladyzhenskaya–Babuška–Brezzi (LBB) compatibility
condition [16], relating the discrete function spaces as
qh, ∇ · vh
Ω
inf sup ≥ α > 0. (4.28)
q h ∈Qh v h ∈V h kq h k0 kv h k1
Intuitively, one can think of this inf-sup condition as a restriction to the minimum
dimension of V h . In fact, for all q h ∈ Qh , there must exist a v h , such that the
projection (q h , ∇ · v h ) (in accord with the term occurring in the weak form) is non
vanishing.
The most common LBB-compliant mixed finite element is the Taylor–Hood element
P2 P1 , having piecewise continuous pressure and velocity. The velocity function
space allows for quadratic polynomials, while the pressure function space consists of
linear polynomials. Another option to circumvent the LBB condition is the use of
stabilization techniques, that are later introduced Chapter 5.
Listing 4.6 Mixed function space definition for Taylor–Hood elements [15].
After defining the boundary conditions, trial and test functions are now created from
the mixed element function space and the resulting weak form is implemented as:
40 4. Introduction to the FEniCS Computing Platform
Listing 4.7 Mixed weak formulation for the Stokes problem [15].
The complete example source code can be found in [18] and is listed in Appendix D
under Listing D.2 for reproducibility.
This chapter introduced the implementation concepts of FEniCS in general with
the help of two introductory examples. It became clear that the focus is on the
specification of the weak formulation in tensorial notation. The treatment of essential
boundary condition is also done in a user-convenient way. The basic concepts can
easily be extended for mixed finite element problems, as we will encounter in the next
Chapter 5.
5. Decoupled Linearized Heat System
In order to get a better understanding of the full R13 system, we will split the system
physically into a heat system and a stress system to validate them separately, as it
was proposed in [68]. The first validation model problem, therefore, is extracted by
only considering all temperature and heat flux terms from the steady-state linearized
R13 system. The corresponding boundary conditions also only consists of θ, s and R
terms by neglecting all other cross-coupling terms. The extracted problem is called
decoupled heat system and reads:
Problem 5.1 (Decoupled Linearized Heat System, DLHS). For a given closed domain
nS
bc
Ω with boundary Γ := ∂Ω = Γi , find the temperature θ : Ω → R and the heat flux
i=1
s : Ω → Rd , such that
24
− Kn (∇s)STF − R = 0 in Ω, (5.1)
5
1 2 1 5
∇·R+ s + ∇θ = 0 in Ω, (5.2)
2 3 Kn 2
∇ · s = fh in Ω, (5.3)
1
2χ̃ (θ − θw ) + Rnn = sn on Γ, (5.4)
5
11
χ̃ st = Rnt on Γ, (5.5)
5
for a given heat source fh , a given modified accommodation coefficient χ̃, a given wall
temperature θw and under a given non-equilibrium situation described by the Knudsen
number Kn.
To proceed further, we collect the boundary integrals and decompose the highest-
order moment R. In fact, for two spatial dimensions and with reference to a local
normal/tangential coordinate system along the boundary path, it holds that
R · n · r = Rnn rn + Rnt rt , (5.8)
θ (r · n) = θrn , (5.9)
allowing to collect the two boundary integrals of Eqs. (5.6) and (5.7) as
! !
5Z 1 1 5Z 1 1 11
Rnn + θ rn + Rnt rt dl = sn + θw rn + χ̃ st rt dl,
2 ∂Ω 5 5 2 ∂Ω 2χ̃ 5 5
(5.10)
where the rearranged boundary conditions (Eqs. (5.4) and (5.5))
1 1
Rnn + θ = sn + θ w , (5.11)
5 2χ
11
Rnt = χ̃ st , (5.12)
5
have naturally been inserted. Note that there is no need to enforce essential boundary
conditions. Lastly, the closure relation of Eq. (5.1) for the highest-order moment is
used to eliminate R. This is analogous to classical approaches, e.g. similar to the
elimination of the stress tensor in the classical Stokes problem [16]. The discrete weak
form can then be formulated as:
Weak Formulation 5.2. Find (s, θ) ∈ Vsh × Vθh , such that
!
12 Z Z
5 5
Kn (∇s)STF : ∇r dx + sn + θw rn dl
5 Ω Γ 4χ̃ 2
Z
11χ̃ 2 1 Z
5 Z
+ st rt dl + s · r dx − θ (∇ · r) dx = 0 (5.13)
Γ 10 3 Kn ΩZ 2 Ω Z
− (∇ · s) κ dx + fh κ dx = 0 (5.14)
Ω Ω
5.1. Weak Formulation 43
The discrete weak form for the decoupled heat system is in agreement to previous
work in [68]. The superscript (·)h , usually denoting discrete functions, is skipped to
increase readability. Note that all natural boundary conditions enter the weak form.
No special treatment for Dirichlet boundary conditions has to be considered. We can
further identify the bilinear form a((·, ·), (·, ·)) and the linear functional ls ((·, ·)) on
the product space Vsh × Vθh as
ah ((s, θ), (r, κ)) = a1 ((s, θ), (r, κ)) + a2 ((s, θ), (r, κ)), (5.15)
ls ((r, κ)) = l1 ((r, κ)) + l2 ((r, κ)), (5.16)
with
Z
12 2 1 5
a1 ((s, θ), (r, κ)) = Kn (∇s)STF : ∇r + s · r − θ (∇ · r) dx (5.17)
Ω 5 3 Kn 2 !
Z
5 11χ̃
+ s n rn + st rt dl,
∂Ω 4χ̃ 10
Z
a2 ((s, θ), (r, κ)) = − (∇ · s) κ dx, (5.18)
Ω
Z
5 w
l1 ((r, κ)) = − θ rn dl, (5.19)
Z∂Ω 2
l2 ((r, κ)) = − fh κ dx. (5.20)
Ω
In order to proceed with the numerical method, it remains to prescribe the spaces
2
Vsh ⊂ [H 1 (Ω)] and Vθh ⊂ H 1 (Ω) as the discrete subspaces of the Sobolev space H 1 (Ω).
We will use H 1 -conforming Lagrangian elements Pm , as introduced in Section 4.1.
The full implementation of the weak form is presented in the source code, Ap-
pendix B.2. An important implementation detail is the treatment of the symmetric
and trace-free (STF) operator in Eq. (5.17). For strictly two-dimensional problems,
the default built-in operators sym and dev of FEniCS/UFL can be used successively.
However, assuming a two-dimensional problem resulting from a z-homogenous three-
dimensional problem requires a change in the operator. In fact, the deviatoric part
of a 2-tensor is defined in the UFL [67] as
Aii
(A)dev = A − I, (5.21)
d
using the dimension d and Einstein’s summation notation in the trace Aii . If a
computation is therefore performed on a two-dimensional mesh, d is set to 2. In the
following, we assume homogeneity in the third spatial dimension leading to the two-
dimensional problem 5.2. A modified version to obtain the symmetric and trace-free
44 5. Decoupled Linearized Heat System
part of a 2-tensor is, therefore, used to account for this. For A ∈ R2×2 , the modified
STF operator is thus, for our purposes, defined as
1 Aii
(A)STF = A + AT − I. (5.22)
2 3
This can also be seen when assuming a 3D problem where none of the relevant fields
depends on the z-coordinate [65]. All operators except for (∇s)STF in Definition 5.2
would act two-dimensionally and the only required change to perform a 2D calculation
would be to enforce Eq. (5.22). The corresponding implementation of (·)STF therefore
artificially assumes d = 3 and reads:
1 def stf3d2(rank2_2d):
2 symm = 1/2 * (rank2_2d + ufl.transpose(rank2_2d))
3 return (
4 symm
5 - (1/3) * ufl.tr(symm) * ufl.Identity(2)
6 )
5.2. Stabilization
As already discussed in Section 4.2, mixed finite element problems require to use
compatible element pairs. In the case of Stokes’s problem, a suitable choice to
circumvent the LBB condition is the Taylor–Hood element P2 P1 , where the dimension
of the velocity function space is higher than the dimension of the pressure function
space. When it comes to application cases, we do not want to focus on a particular
field, such that an equal order discretization is desired. Because of the lack of physical
intuition about higher-order moments, these should also not be focussed in terms
of discretization order. This is especially the case for even more extended model
equations above the R13 case.
One approach to overcome the compatible condition on the discrete function spaces
is stabilization. In general, stabilization techniques modify the left-hand side of the
weak form in order to stabilize the discrete system, i.e. adding entries to the zero
submatrix in the Stokes case for example. Residual-based stabilization techniques are
popular for flow problem [16] and add a stabilization term based on the value of the
current residuum R(u), which is the difference between the left and the right-hand
side of the considered model problem, as
nel
X
ã(u, v) = a(u, v) + (P(v), δR(u))Ωe , (5.23)
e=1
5.2. Stabilization 45
where the stabilization parameter δ has to be chosen and P(v) can be seen as a
perturbation of the test function v. Depending on the considered model, promi-
nent example are the Streamline-Upwind Petrov–Galerkin (SUPG) stabilization for
the steady advection-diffusion equation, the Galerkin/Least-Squares (GLS) stabi-
lization for the unsteady advection-diffusion equation or the Pressure-Stabilizing/
Petrov–Galerkin (PSPG) method for the Navier–Stokes equations [16].
where E is the index set of all interior element edges, δ1 is a stabilization parameter
(comparable to δ in Eq. (5.23)) and [f · n] = f + · n+ + f − · n− denoting the jump of
the quantity f across the edge, weighted with the oppositely directed edge normals
n+ and n− . If the temperature field θ is assumed to be in C 1 , no stabilization term
is added and the method is consistent [71]. In general, interior penalty methods have
strong mathematical foundations [49] and a wide application range [78]. An analysis
of the discrete system in [69] proposed a scaling of the stabilization term as
δ1 = δ˜1 h3 , (5.25)
such that the order of stabilization does not change due to mesh refinement. The
remaining parameter is not very sensitive and the method is very robust in order to
produce low errors for a wide range of δ˜1 -values. A discussion is presented e.g. in [10],
where the method was applied for the generalized Stokes problem.
The implementation in FEniCS uses the support for discontinuous Galerkin (DG)
operators in the UFL. An integration over all interior edges, as a subset of all edges,
can be archived using dS instead of ds. The resulting implementation then intuitively
reads:
1 # Apply stabilization
2 h_avg = (h("+") + h("-"))/2.0
3 stab_heat = - (
4 delta_1 * h_avg**3 *
5 df.jump(df.grad(theta), n) * df.jump(df.grad(kappa), n)
6 ) * df.dS
7 form_a = a1 + a2 + stab_heat
Listing 5.2 Implementation of CIP stabilization for the decoupled heat system.
46 5. Decoupled Linearized Heat System
The considered domain Ω ⊂ R2 is a ring and consists of the area between two coaxial
circles with radii R1 and R2 as
n o
Ω = x = (x, y)T : R1 ≤ kxk2 ≤ R2 , (5.26)
and follows previous works [65, 68]. This domain allows the computation of exact
solutions for the decoupled heat system 5.1. Sharp corners are also avoided and a
prescription of normal fluxes does not produce any problems, because the circle origin
is excluded from the domain. As already indicated in Section 5.1, we assume 2D
problems as simplifications for 3D problems with full symmetry and homogeneity
in the third spatial direction. The considered 2D domain can, therefore, be seen as
an area cut of an infinitely stretched cylinder with full symmetry and no change in
z-direction (vanishing gradients) as sketched in Fig. 5.1.
Figure 5.1. Extraction of a 2D model problem from an infinite cylinder with homogeneity in the
third spatial direction and thus vanishing gradients. A sketch of the two-dimensional cut is presented
in Fig. 5.2
The inner circle boundary is denoted by Γ1 and the outer circle by Γ2 . The remaining
parameters are chosen, such that comparison to existing literature [68] is possible.
5.3. Convergence Study Based on Mesh Refinement 47
The wall temperatures are prescribed as θw |Γ1 = 1.0 and θw |Γ2 = 0.5. The heat
2
√ 2 f2h depends on the radius and reads fh (R) = 2 − R withT R = kxk2 =
source
x + y denoting the radius as distance from the circle center (0, 0) . Furthermore,
the accommodation coefficient is assumed to be unity for the sake of simplicity.
Note, that this technically contradicts with the results obtained with the Maxwell
accommodation model, discussed in Section 3.3.3. In fact, the previously introduced
linearized accommodation coefficient
s
2 χ
χ̃ = , (5.27)
πθ0 2 − χ
2
χ= q > 1, (5.28)
2
1+ π
which contradicts with χ ∈ [0, 1] [65]. The overall computational domain with all
relevant parameters is shown Fig. 5.2.
R2
fh
R1
Ω : Kn
Γ1
Γi : χ̃, θw
Γ2
Figure 5.2. Computational domain and all relevant parameters for the decoupled heat system. Inside
the domain Ω, the flow situation is described through the Knudsen number Kn and a heat source
fh acts. At both boundaries, the linearized accommodation coefficient χ̃ and the wall temperature
θw have to be prescribed.
approach, the numerical method is, therefore, tested for principal correctness and
better results are expected using structured or adaptive meshes.
The mesh generator Gmsh [20] is used to create the series of ring meshes, because
it provided better meshing results than the FEniCS internal mshr-tool. Note that
no element split is applied to obtain the refined meshes. In fact, finer meshes are
the result of a complete remeshing procedure with a lower cell size factor. The mesh
resolution is characterized by the maximum cell size hmax . Some example meshes
are presented in Fig. 5.3 with their corresponding hmax . In contrast to [68], no
isoparametric higher-order representation of the domain boundaries is considered due
to the lack of compatibility in the current implementation of FEniCS. L2 -convergence
rates beyond second order are therefore not expected.
Figure 5.3. Series of unstructured triangular meshes used for the convergence study. Note, that the
coarsest mesh is not uniform to sufficiently resolve the inner boundary. This is the default behavior
of Gmsh, and with finer meshes, this effect vanishes. The bounding box of the mesh slightly varies
due to the curved boundary and the node placement.
The test case, introduced in Section 5.3, is evaluated for a gas rarefaction setting of
Kn = 0.1. To rate the success of the numerical method, we first have to introduce
suitable error measures. The relative L2 function error eL2 is used as
where fex is the exact solution projected to a sufficiently large function space [32]
depending on the function space for the discrete solution fh and η is the set of all mesh
nodes. For vector- or tensor-valued fields, the error is calculated component-wise.
5.3. Convergence Study Based on Mesh Refinement 49
while l∞ is used to indicate that this error only considers point-wise errors based on
mesh node values. For cases, where the exact solution is uniformly vanishing, the
absolute error is used. If el∞ decays to zero for refined meshes, it is ensured, that for
all points of interest – i.e. the mesh nodes – the solution converges against the exact
solution.
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
Figure 5.4. Errors for the decoupled heat system using P2 P1 elements without stabilization. All
solution errors scale with second order in the mesh size h. The underlying error data is listed in
Tables A.1 and A.2.
50 5. Decoupled Linearized Heat System
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
10−5 10−5
10−2 10−1 100 10−2 10−1 100
hmax hmax
θ sx sy O(h) O(h2 )
Figure 5.5. Errors for the decoupled heat system using P1 P1 and CIP-stabilization (δ̃1 = 1). A
decreased converge rate for the scalar-valued θ can be observed in contrast to Taylor–Hood elements
without stabilization. The underlying error data is listed in Tables A.3 and A.4.
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
Figure 5.6. Errors for the decoupled heat system using P2 P2 and CIP-stabilization (δ̃1 = 1).
Second-order converges rates can be observed for all fields. The order of the relative error is similar
for all solution components. The underlying error data is listed in Tables A.5 and A.6.
θ ��� ��
�
-�
-�
-� -� � � �
Figure 5.7. Schematic results of the heat system test case. A radial-symmetric heat flux is induced
by the temperature difference between the inner and the outer walls.
6. Decoupled Linearized Stress
System
After the decoupled heat system 5.1 has been successfully discretized and solved,
the validation of the decoupled stress system is done analogously. The problem is
extracted from the full steady-state and linearized R13 system by only considering
the terms including the pressure, the velocity, the stress tensor and the highest-order
moment m. The corresponding boundary terms also only consist of p, u, σ and m
terms by neglecting all cross-coupling to the heat variables.
Following [68], a mass source fm , acting inside the domain Ω, is also added to the
mass balance equation as ∇ · u = fm . This mass source can be used to create test
cases with a mass source induced flow. Note, that the addition of a mass source
can violate the assumptions made in Section 3.3.1, because in that case, the energy
equation can not be simplified and the highest-order moment R is not zero. From a
physical point of view, the mass flow rate can result from chemical reactions under
different conditions, such that the mass source can be spatial dependent. However,
for real applications cases, it is very rare to model flows with a mass source but rather
common to use inflow/outflow-based induction mechanisms. The resulting problem
is called decoupled stress system and reads:
Problem 6.1 (Decoupled Linearized Stress System, DLHS). For a given closed
nS
bc
domain Ω ∈ Rd with boundary Γ := ∂Ω = Γi , find the pressure p : Ω → R, the
i=1
54 6. Decoupled Linearized Stress System
velocity u : Ω → Rd and the symmetric and trace-free stress tensor σ : Ω → Rd×d STF ,
such that
1
2(∇σ)STF + m=0 in Ω, (6.2)
Kn
1
∇·m+ σ + 2(∇u)STF = 0 in Ω, (6.3)
Kn
∇ · σ + ∇p = 0 in Ω, (6.4)
∇ · u = fm in Ω, (6.5)
w w w
χ̃ ((p − p ) + σnn ) = (un − un ) on Γ, (6.6)
w
χ̃ ((ut − ut ) + mnnt ) = σnt on Γ, (6.7)
7
χ̃σnn = mnnn on Γ, (6.8)
5
1 1
χ̃ σtt + σnn = mntt + mnnn on Γ, (6.9)
2 2
for a given mass source fm , a given modified accommodation coefficient χ̃, a given
wall pressure pw , a given normal wall velocity uw n , a given tangential wall velocity
w w
ut , a normal velocity prescription coefficient and under a given gas rarefaction
situation described by the Knudsen number Kn.
The model problem can be seen as an extension to classical flow modeling with
an additional evolution equation for the stress tensor σ. In Section 6.1, the weak
formulation of this problem is derived and the corresponding stabilization is applied in
Section 6.2. The convergence study, based on mesh refinement, in Section 6.3 discusses
the numerical errors in Section 6.3.2 for test cases defined in Section 6.3.1.
The weak form is derived by multiplying with the test functions (ψ, v, q) and integra-
tion over the domain Ω. The tensorial Eq. (6.3) is multiplied with the tensorial test
function ψ, the vectorial Eq. (6.4) with v and the scalar Eq. (6.5) with q.
1
(∇u)STF = (∇u)sym − tr(∇u)I, (6.11)
3
6.1. Weak Formulation 55
such that
Z Z
1Z
(∇u)STF : ψ dx = (∇u)sym : ψ dx − (∇ · u)I : ψ dx (6.12)
Ω Ω 3 Ω
Z
1Z
= (∇u)sym : ψ dx − (∇ · u)tr(ψ) dx. (6.13)
Ω 3 Ω
We reconsider that the stress tensor is symmetric and trace-free and the same prop-
erties are chosen for the test 2-tensor ψ, such that
σxx σxy 0 ψxx ψxy 0
σ= σ
xy σyy 0
, ψ =
ψ
xy ψyy 0 .
(6.14)
0 0 − (σxx + σyy ) 0 0 − (ψxx + ψyy )
This setup vanishes the trace in Eq. (6.13) and by using the orthogonality principle
of the additive tensor decomposition into a symmetric and a skew-symmetric part,
integration by parts becomes possible as
Z Z
(∇u)STF : ψ dx = ∇u : ψ dx (6.15)
Ω ΩZ Z
=− u · (∇ · ψ) dx + u · (ψ · n) dl. (6.16)
Ω ∂Ω
The boundary terms of Eqs. (6.10) and (6.16) can further be decomposed with the
same technique as in Section 5.1 using a local boundary coordinate system as
(m · n) : ψ = mnnn ψnn + 2mnnt ψnt + mntt ψtt + (−mntt − mnnn )(−ψtt − ψnn ) (6.17)
3 1 1
= mnnn ψnn + 2mnnt ψnt + 2 mntt + mnnn ψtt + ψnn , (6.18)
2 2 2
u · (ψ · n) = un ψnn + ut ψnt , (6.19)
where mnnt = mntn was utilized. All boundary terms of the tensorial equation can
now be collected as
Z
3
Z Z
(m · n) : ψ dl + 2 u · (ψ · n) dl = mnnn + 2un ψnn dl
∂Ω ∂Ω ∂Ω 2
1 1
Z Z
+ (2mnnt + 2ut ) ψnt dl + 2 mnnn + mntt ψnn + ψtt dl, (6.20)
∂Ω ∂Ω 2 2
where the reordered boundary conditions (Eqs. (6.6) to (6.9))
are then inserted naturally. No integration by parts is applied for the vector-valued
equation but for the scalar-valued equation to enforce the normal velocity boundary
conditions as Z Z Z
− (∇ · u)q dx = u · ∇q dx − un q dl. (6.25)
Ω Ω ∂Ω
The complete discrete weak form then reads:
Weak Formulation 6.2. Find (σ, u, p) ∈ Vσh × Vuh × Vph , such that
Z Z
21
2 Kn (∇σ)STF ∵ ∇ψ dx + χ̃σnn ψnn dl
Ω Γ 10 !
Z
w w 2 Z
+ (2 χ̃ ((p − p ) + σnn ) + dl + σnt + 2uw
uw
n ) ψnn
t ψnt dl
Γ Γ χ̃
1 1 1 Z
Z
+ 2χ̃ σtt + σnn ψtt + ψnn dl + σ : ψ dx
Γ 2 2 Kn ZΩ
−2 u · (∇ · ψ) dx = 0 (6.26)
Z Ω Z
(∇ · σ) · v dx + ∇p · v dx = 0 (6.27)
Z Z Ω ΩZ
We can again collect the combined functional as ((·, ·, ·), (·, ·, ·)), which is a bilinear
form on the product space Vσh × Vuh × Vph , and the linear functional ls ((·, ·, ·)) by a
simple reordering analogous to Section 5.1.
As we already notice, the weak formulation becomes relatively large, although written
in tensorial notation. It would be possible to implement the system component-wise
and solve for p, ux , uy , σxx , σxy , σyy after expanding all operators in the weak form 6.2.
However, this would increase the complexity even more and can be error-prone.
For example, the inner product of the 3-tensors (∇σ)STF and ∇ψ using the shape
assumptions of σ and ψ would read component-wise as
2 ∂σxx ∂ψxx 16 ∂σxx ∂ψxx 4 ∂σxx ∂ψxy
(∇σ)STF ∵ ∇ψ = + −
3 ∂y ∂y 15 ∂x ∂x 15 ∂x ∂y
2 ∂σxx ∂ψxy 1 ∂σxx ∂ψyy 1 ∂σxx ∂ψyy 2 ∂σxy ∂ψxx
+ + + +
3 ∂y ∂x 3 ∂y ∂y 3 ∂x ∂x 3 ∂x ∂y
4 ∂σxy ∂ψxx 16 ∂σxy ∂ψxy 16 ∂σxy ∂ψxy 4 ∂σxy ∂ψyy
− + + −
15 ∂y ∂x 15 ∂y ∂y 15 ∂x ∂x 15 ∂x ∂y
2 ∂σxy ∂ψyy 1 ∂σyy ∂ψxx 1 ∂σyy ∂ψxx 2 ∂σyy ∂ψxy
+ + + +
3 ∂y ∂x 3 ∂y ∂y 3 ∂x ∂x 3 ∂x ∂y
4 ∂σyy ∂ψxy 16 ∂σyy ∂ψyy 2 ∂σyy ∂ψyy
− + + . (6.29)
15 ∂y ∂x 15 ∂y ∂y 3 ∂x ∂x
6.1. Weak Formulation 57
We will, therefore, make extensive use of the tensor capabilities, provided by FEniCS
and UFL, to avoid to compute such expressions and have the corresponding source
code in a compact form, that directly matches the mathematical formulation. In
fact, up to second-order tensors, all UFL operators are intuitive, except for the
already discussed encoding of 3D information presented in Section 5.1. Dealing with
3-tensors, however, is not straight-forward because some required operators are not
yet implemented in FEniCS.
First of all, using a two-dimensional mesh leads to the creation of only two spatial
variables acting in the differential operators. In order to respect the shape assumptions
on σ and ψ of Eq. (6.14), a lifting operator L is defined, mapping a 2D 2-tensor
artificially to a trace-free 3D 2-tensor. The definition
! a b 0
a b
L : R2×2 → R3×3 , →
7 c d 0 , (6.30)
TF
c d
0 0 −(a + d)
The gradient operator is extended in a similar fashion to account for the third dimen-
sion as:
1 def grad3dOf2(rank2_3d):
2 grad2d = df.grad(rank2_3d)
3 dim3 = df.as_tensor([
4 [0, 0, 0],
5 [0, 0, 0],
6 [0, 0, 0],
7 ])
8 grad3d = df.as_tensor([
9 grad2d[:, :, 0],
10 grad2d[:, :, 1],
11 dim3[:, :]
12 ])
13 return grad3d
Here, the symmetric part of a 3-tensor is the average over all possible transpositions
and is given by
1
A(ijk) = (Aijk + Aikj + Ajik + Ajki + Akji + Akij ) . (6.32)
6
Again, the symmetric part can also be directly translated into UFL code using:
1 def sym3d3(rank3_3d):
2 i, j, k = ufl.indices(3)
3 symm_ijk = 1/6 * (
4 # all permutations
5 + rank3_3d[i, j, k] + rank3_3d[i, k, j] + rank3_3d[j, i, k]
6 + rank3_3d[j, k, i] + rank3_3d[k, i, j] + rank3_3d[k, j, i]
7 )
8 return ufl.as_tensor(symm_ijk, (i, j, k))
6.2. Stabilization
To allow the usage of equal-order elements, the stress system also has to be stabilized.
We stick to the same CIP framework as proposed in [68] and modify the left-hand
side of the weak formulation as
ãs ((σ, u, p), (ψ, v, q)) = as ((σ, u, p), (ψ, v, q)) + S((u, p), (v, q)), (6.33)
where the stabilization term is given by
XZ XZ
S((u, p), (v, q)) = δ2 [∇u · n] · [∇v · n] dl − δ3 [∇p · n] [∇q · n] dl.
E∈E E E∈E E
(6.34)
Note that the stress system, in contrast to the heat system, consists of three equations,
such that the two lowest-order quantities are stabilized. The stabilization parameters
are set to
δ2 = δ˜2 h3 , (6.35)
δ3 = δ˜3 h, (6.36)
in accordance to [68].
The computational ring domain remains the same compared to the test of Section 5.3.1.
Both inner and outer ring walls are first modeled as solid walls, such that w = 0 and
uwn = 0 for both walls. This setup allows to compare against existing exact solutions
from [68]. We further use a moderate rarefaction state with Kn = 0.1 while the
stabilization terms are set to δ̃2 = 1 for the velocity and δ̃3 = 0.01 for the pressure
terms.
The flow inside the domain is either induced by the prescribed mass source fm or
by a prescribed tangential velocity uw
t at the inner cylinder wall. The computational
domain with all the prescribed parameters is presented in Fig. 6.1.
60 6. Decoupled Linearized Stress System
R2
R1
uw
t Ω : Kn
fm
Γ1
Γi : χ̃, w , pw uw w
n , ut
Γ2
Figure 6.1. The computational domain and all relevant parameters for the decoupled stress system.
Inside the domain Ω, the flow situations is described through the Knudsen number Kn and a mass
source fm is acting inside the domain. At both boundaries, the linearized accommodation coefficient
χ̃ has to be prescribed. Furthermore, both walls have a normal velocity component vtw = 0 to model
solid walls, and a rotation of the inner cylinder is prescribed by the tangential velocity component
vtw . The inflow model can be activated by prescribing w 6= 0 together with a wall pressure pw .
Two test cases are considered to validate the decoupled stress system. In order to be
consistent with the simplification of the initial R13 system of Section 3.3.1, the first
test case does not include a mass source. The flow inside the domain is induced only
w,1
by a rotating inner cylinder with uw t = ut = −10 resulting in a counter-clockwise
rotation. The second test case considers the same inner rotation combined with a mass
2
source fm = 25 (1 − 185R
Kn2
) cos(φ), where φ ∈ [−π, π] is the polar angle with respect to
the positive x-axis. The exact solution for the second test case is derived in [68] while
the exact solution for the first test case has been derived separately as a simplification
of the second test case. Both exact solutions are listed in Appendix A.1.2. The
pressure has no reference in the problem specification, such that it is only determined
up to a constant. In order to compare with exact solutions, the pressure is therefore
scaled to have zero mean before an error comparison is performed.
Test Case 1: Stabilized P1 P1 P1 Equal-Order Elements The first test case de-
scribes a flow, that is induced by a rotation of the inner cylinder, without any mass
source. The error results for stabilized P1 equal-order elements are presented in
Fig. 6.2. Optimal convergence rates for the L2 -errors are obtained for all fields. In the
more restrictive l∞ -error, both velocity fields convergence, but with an order between
6.3. Convergence Study Based on Mesh Refinement 61
one and two. A schematic visualization of the discrete solution for this test case is
presented in Fig. 6.6a.
100 100
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
10−5 10−5
10−2 10−1 100 10−2 10−1 100
hmax hmax
p ux uy σxx σxy σyy O(h) O(h2 )
Figure 6.2. Errors for the decoupled stress system using P1 P1 P1 and CIP-stabilization (δ̃2 =
1, δ̃3 = 0.01) for the first test case. Second-order converges rates in the L2 -norm can be observed
for all fields. The pressure and stress fields have second-order convergence in the l∞ -norm while the
velocity is limited to about first-order. The underlying error data is listed in Tables A.7 and A.8.
Test Case 2: Unstabilized P3 P2 P1 Elements For the second test case, the most
natural choice of a stable triple of finite elements P3 P2 P1 is considered. The resulting
errors are presented in Fig. 6.3. The error of the pressure and stress components
have a lower error compared to the velocity components. Both velocity components
have a reduced convergence rate in the L2 -norm and in the l∞ -norm. An inspection
of the resulting fields for pressure, velocity and stress tensor showed no oscillations.
A schematic visualization of the discrete solution for this test case is presented in
Fig. 6.6b.
100 100
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
10−1 100 10−1 100
hmax hmax
p ux uy σxx σxy σyy O(h) O(h2 )
Figure 6.3. Errors for the decoupled stress system using P3 P2 P1 for the second test case. Second-
order converges rates in the L2 - and the l∞ -norm can be observed for the pressure and stress. The
errors in both velocity are higher and the convergence order is reduced compared to the other fields.
The underlying error data is listed in Tables A.9 and A.10.
100 100
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
10−5 10−5
10−2 10−1 100 10−2 10−1 100
hmax hmax
p ux uy σxx σxy σyy O(h) O(h2 )
Figure 6.4. Errors for the decoupled stress system using P1 P1 P1 and CIP-stabilization (δ̃2 =
1, δ̃3 = 0.01) for the second test case. Second-order converges rates in the L2 -norm can be observed
for almost all fields. The pressure and stress fields have second-order convergence in the l∞ -norm
while the velocity is limited to approximately first-order. The underlying error data is listed in
Tables A.11 and A.12.
100 100
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
Figure 6.5. Errors for the decoupled stress system using P2 P2 P2 and CIP-stabilization (δ̃2 =
1, δ̃3 = 0.01) for the second test case. Second-order converges rates in the L2 - and the l∞ -norm can
be observed for all fields. The underlying error data is listed in Tables A.13 and A.14.
64 6. Decoupled Linearized Stress System
� �
� �
-� -�
-� -�
-� -� � � � -� -� � � �
a) First test case. b) Second test case.
Figure 6.6. In Fig. 6.6a, a radial velocity profile can be observed due to the prescribed tangential
rotation of the inner cylinder wall. With mass source in Fig. 6.6b, a flow around the cylinder is
developed. Due to the present rotation of inner cylinder, the flow field is not symmetric.
7. Full Linearized R13 System
After the separate validation of the decoupled heat and stress system in Chapters 5
and 6, the coupled system, as derived in Section 3.3.1, is considered by adding all
coupling terms to the equations and the boundary conditions. In fact, the heat flux
balance has the additional coupling term ∇·σ while the deviatoric stress tensor balance
has the additional coupling term 45 (∇s)STF . The strong formulation consists of five
balance laws with two closures for the highest-order moments R and m, combined
with a set of six boundary conditions including the inflow model, that was introduced
in Chapter 6. The resulting problem can be formulated as:
Problem 7.1 (Linearized R13 System, LinR13). For a given closed domain Ω ∈ Rd
nS
bc
with boundary Γ := ∂Ω = Γi , find the temperature θ : Ω → R, the heat flux
i=1
s : Ω → Rd , the pressure p : Ω → R, the velocity u : Ω → Rd and the symmetric and
trace-free stress tensor σ : Ω → Rd×d
STF , such that
5 1 1 2
∇θ + ∇ · σ + ∇ · R = − s in Ω, (7.1)
2 2 Kn 3
∇ · s = fh in Ω, (7.2)
4 1
(∇s)STF + 2(∇u)STF + ∇ · m = − σ in Ω, (7.3)
5 Kn
∇p + ∇ · σ = 0 in Ω, (7.4)
∇ · u = fm in Ω, (7.5)
24
R = − Kn (∇s)STF in Ω, (7.6)
5
m = −2 Kn (∇σ)STF in Ω, (7.7)
66 7. Full Linearized R13 System
(un − uw w w
n ) = χ̃ ((p − p ) + σnn ) on Γ, (7.8)
1
σnt = χ̃ (ut − uw t ) + st + mnnt on Γ, (7.9)
5
11
Rnt = χ̃ −(ut − uw t ) + s t − m nnt on Γ, (7.10)
5
1 2
sn = χ̃ 2(θ − θw ) + σnn + Rnn on Γ, (7.11)
2 5
2 7 2
w
mnnn = χ̃ − (θ − θ ) + σnn − Rnn on Γ, (7.12)
5 5 25
1 1
mnnn + mntt = χ̃ σnn + σtt on Γ, (7.13)
2 2
for a given heat source fh , a given mass source fm , a given modified accommoda-
tion coefficient χ̃, a given wall temperature θw , a given wall pressure pw , a given
normal wall velocity uw w
n , a given tangential wall velocity ut , a given normal velocity
prescription coefficient w and under a given gas rarefaction situation described by
the Knudsen number Kn.
Weak Formulation 7.2. Find (s, θ, σ, u, p) ∈ Vsh × Vθh × Vσh × Vuh × Vph , such that
12 Z
2 1 Z 5Z
Kn (∇s)STF : ∇r dx + s · r dx − θ (∇ · r) dx
5 Ω 3 Kn Ω 2 Ω!
Z Z
5 5 5
∇ · σ · r dx + sn − σnn + θw rn dl
Ω Γ 4χ̃ 8 2
Z
6χ̃ 1
+ st − σnt rt dl = 0 (7.16)
Z Γ 5 2Z
− (∇ · s) κ dx + fh κ dx = 0 (7.17)
Ω Ω
Z
1 Z Z
2 Kn (∇σ)STF ∵ ∇ψ dx + σ : ψ dx − 2 u · (∇ · ψ) dx
Ω Kn Z Ω Ω
4Z 9 3
+ (∇s)STF : ψ dx + χ̃σnn − sn ψnn dl
5 Ω Γ 4 10
1 1
Z
+ 2χ̃ σtt + σnn ψtt + ψnn dl
Γ 2 !
2
Z
2 2
+ σnt + 2uwt − st ψnt dl
Γ χ̃ 5
Z
+ (2w χ̃ ((p − pw ) + σnn ) + uw
n ) ψnn dl = 0 (7.18)
Γ Z Z
(∇ · σ) · v dx + ∇p · v dx = 0 (7.19)
Z Z Ω ΩZ
The full implementation of the weak formulation for the linearized R13 system is
listed in Appendix B.2.
The mass source induced test case is the combination of the test cases for the decou-
pled heat and the decoupled stress system, presented in Sections 5.3 and 6.3. The
computational domain again consists of the area between two coaxial circles with radii
R1 = 12 and R2 = 2. A rotation of the inner cylinder is prescribed with uw,1 t = −10
5R2
while the mass source is increased to fm = (1 − 18 Kn2 ) cos(φ). The inflow model is
deactivated with w = 0 and the walls are modeled as impermeable with uw n = 0.
The addition of the heat system terms increases the number of parameters, such that
boundary conditions for the temperature with θw |Γ1 = 1 and θw |Γ2 = 12 are required.
No heat source fh = 0 is applied. The flow is characterized by a relatively high
Knudsen number of Kn = 1. Using this set of boundary conditions, the test case can
be compared to [68, 69]. The computational domain with all parameters is shown in
Fig. 7.1 while the exact solution for this test case is listed in Appendix A.1.3. The sta-
bilization parameters are inherited from both subsystems as δ̃1 = 1, δ̃2 = 1, δ̃3 = 0.01.
The following test cases show that the convergence results for the full system are
similar to the results of two separate tests of the subsystems.
R2
R1
uw
t Ω : Kn
fm
Γ1
Γi : χ̃, θw , uw w w w
t , un , p ,
Γ2
Figure 7.1. Computational domain and all relevant parameters for the linearized R13 system. Inside
the domain Ω, the flow situations is described through the Knudsen number Kn and a mass source
fm acts. At both boundaries, the linearized accommodation coefficients and the wall temperature θw
has to be prescribed. Furthermore, both walls have a normal velocity component vtw = 0 to model
solid walls and a rotation of the inner cylinder is prescribed by the tangential velocity component
vtw . The inflow model can be activated by prescribing w 6= 0 together with a wall pressure pw .
The convergence behavior for P1 equal-order elements for all fields is presented in
Fig. 7.2. In the L2 -norm and the l∞ -norm, the heat flux s, the pressure p and the
stress tensor σ have second order convergence rates. The temperature θ and the
7.2. Convergence Study Based on Mesh Refinement 69
Figure 7.2. Errors for the linearized R13 system using stabilized P1 equal-order elements (test case
1). The fields s, p, σ have second-order convergence rates in the L2 - and the l∞ -norm. The fields
θ, u have a reduced L2 -rate and have a first-order convergence behavior in the l∞ -norm. The largest
relative error can be observed for the velocity components. The underlying error data is listed in
Tables A.15 and A.16
In order to improve the convergence rates, equal-order P2 elements are tested for
the same test case. The corresponding errors are shown in Fig. 7.3. Especially, the
critical velocity and temperature fields, in that case, also show a second-order error
convergence behavior in the L2 -norm. The l∞ -rates are still slightly decreased and
are almost of second order.
Fig. 7.4 shows schematic field results for this test case using the last setup with
equal-order P2 elements. In contrast to the results for the decoupled stress system
in Fig. 6.6b, an opposite-directed flow can be observed. The reason for this is the
2
Kn-dependence of the mass source fm = (1− 185RKn2
) cos(φ) and the increased Knudsen
number of Kn = 1 in contrast to Kn = 0.1 in Fig. 6.6b.
70 7. Full Linearized R13 System
100 100
10−1 10−1
10−2
10−2
10−3
10−3
10−4
10−4
10−1 100 10−1 100
hmax hmax
θ sx sy p ux uy σxx σxy σyy O(h) O(h2 )
Figure 7.3. Errors for the linearized R13 system using stabilized P2 equal-order elements (test case
1). All fields have second-order convergence rates in the L2 -norm. The fields θ and u have a reduced
l∞ -rate while all other fields also convergence with second order in the l∞ -norm. In contrast to
Fig. 7.2, the number of refined meshes is decreased due to memory limitations. The underlying error
data is listed in Tables A.17 and A.18
The second test case considers a flow scenario with inflow and outflow boundary
conditions prescribed, similar to the test case in [65]. The velocity prescription
coefficient, therefore, has to be w 6= 0. In contrast to previous test cases, the outer
wall is not modeled as impermeable but only acts as a cut-off from a larger homogenous
velocity field. The inner cylinder wall is still modeled as a non-rotating solid wall
with zero normal velocity uw w
n |Γ1 = 0 and zero tangential velocity ut |Γ1 = 0 prescribed.
A temperature difference is applied between the inner and the outer cylinder walls
with θw |Γ1 = 1 and θw |Γ2 = 2.
The flow is driven by a pressure difference at the outer cylinder wall with pw |Γ2 =
−p0 nx , in which the background pressure is set to p0 = 0.27 and nx is equal to
cos(φ) for the considered geometry. The velocity components at the outer boundary
are set to uw w
n |Γ2 = u0 nx and ut |Γ2 = −u0 ny with background velocity u0 = 1 and
ny = sin(φ). The remaining parameters read w |Γ1 = 10−3 to focus on velocity
prescription, w |Γ2 = 103 to focus on pressure prescription and Kn = 1 as flow
characterization. The computational domain with all parameters is shown in Fig. 7.5
while the exact solution for this test case is listed in Appendix A.1.3.
7.2. Convergence Study Based on Mesh Refinement 71
� �
� �
-� -�
-� -�
-� -� � � � -� -� � � �
a) Shear stress σxy and velocity streamlines ui . b) Temperature θ and heat flux streamlines si .
Figure 7.4. Schematic results of first test case for the linearized R13 equations. The flow past the
cylinder in Fig. 7.4a is not symmetric due to the prescribed rotation of the inner wall. In Fig. 7.4b,
a heat flux from warm to cold regions can be observed due to supplied boundary conditions.
R2
R1
Ω : Kn
Γ1
Γi : χ̃, θw , uw w w w
t , un , p ,
Γ2
Figure 7.5. Computational domain and all relevant parameters for the linearized R13 system (test
case 2). Inside the domain Ω, the flow situations is described through the Knudsen number Kn.
The inner cylinder wall is assumed to be solid (small w and zero tangential and normal velocity
components). A pressure gradient in x-direction is acting at the outer boundary.
The stabilization parameters remain unchanged compared to the previous test case
and the errors using P1 equal-order elements are presented in Fig. 7.6. A similar
convergence behavior, as for the previous test case, can be observed. In the l∞ -
norm, the heat flux, the pressure and the stress tensor components show second-order
72 7. Full Linearized R13 System
convergence rates while the remaining temperature and velocity components only
show first-order convergence. This is similar to all previous test cases with stabilized
P1 elements. However, in the L2 -norm, both velocity components, now, also show
second-order and only the temperature shows a convergence rate below second-order.
This is a difference compared to the previous test case using P1 elements.
100 100
10−1 10−1
10−2 10−2
10−3 10−3
10−4 10−4
10−5 10−5
10−2 10−1 100 10−2 10−1 100
hmax hmax
θ sx sy p ux uy σxx σxy σyy O(h) O(h2 )
Figure 7.6. Errors for the linearized R13 system using stabilized P1 equal-order elements (test case
2). All fields, except for the temperature, have second-order convergence rates in the L2 -norm. The
temperature error, furthermore, shows a reduced l∞ -rate together with both velocity components
while all other fields also convergence with second order in the l∞ -norm. The underlying error data
is listed in Tables A.19 and A.20
Fig. 7.7 shows schematic field results for this test case. The homogenous outer flow
field enters the computational domain in Fig. 7.7a in parallel. The stress component
σxy has a greater magnitude at areas, where the flow field is parallel to the inner
cylinder walls. As expected with the given set of heat boundary conditions, Fig. 7.7b
shows a heat flux from the warm outer cylinder wall to the cold inner wall. However,
the temperature field is advected in flow direction, such that a colder gas region can
only be observed behind the cylinder while the region before the cylinder is warmer.
7.2. Convergence Study Based on Mesh Refinement 73
� �
� �
-� -�
-� -�
-� -� � � � -� -� � � �
a) Shear stress σxy and velocity streamlines ui . b) Temperature θ and heat flux streamlines si .
Figure 7.7. Schematic results of second test case for the linearized R13 equations. The flow past
the cylinder in Fig. 7.7a induces higher |σxy | values above and below the cylinder, where the flow
direction is tangential to the inner cylinder walls. The temperature distribution in Fig. 7.7b reveals
a colder region behind the cylinder due to the present flow field.
8. Applications
In order to present the capabilities of the developed solver, available from [58], this
chapter shortly presents some application case. It is possible to perform calculations
on arbitrary shaped two-dimensional geometries. We will, therefore, consider three
application cases. The first case in Section 8.1 is the lid-driven cavity, which is a very
common benchmark for two-dimensional flow solvers. The case also acts as the first
test case for non-curved boundaries.
In order to highlight the enhanced capabilities to predict flows for moderate Knudsen
numbers, the other two test cases will discuss typical rarefaction effects. In fact, the
channel flow example in Section 8.2 shows a similar behavior, regarding the Knudsen
paradox, as it was discussed in [62] for the one-dimensional case. In Section 8.3, a
temperature gradient at the domain walls induces a thermal transpiration flow without
the presence of gravity. The two latter application cases would not be possible using
a classical NSF solver and confirm the previously made statement, that the R13
equations, in fact, are able to predict rarefaction effects.
u0
Γ2 : θw
Ω : Kn
Γ1 : θw
L
Figure 8.1. Computational domain for the lid-driven cavity application case as the unit square
with a prescribed tangential velocity at the upper boundary. All other boundaries are modeled as
solid walls.
We solve the problem with equal-order P1 elements using the CIP stabilization method
with the stabilization parameters δ̃1 = δ̃2 = 1, δ̃3 = 0.01. The computational mesh is
a uniformly sized unstructured triangular mesh, consisting of 2654 elements and 1392
nodes. The corresponding solver input file is listed in Listing C.1 and the solution
routine takes 1 s to run.
The discrete solutions are presented in Fig. 8.2. The deviatoric shear stress σxy and
the velocity streamlines are shown in Fig. 8.2a. These fields are similar to the results
obtained in [43]. The heat flux and the temperature distribution in Fig. 8.2b is not
symmetric.
��� ���
��� ���
��� ���
��� ���
��� ���
��� ��� ��� ��� ��� ��� ��� ��� ��� ��� ��� ���
a) Shear stress σxy and velocity streamlines ui . b) Temperature θ and heat flux streamlines si .
Figure 8.2. Schematic results of the lid-driven cavity application case. The velocity field in Fig. 8.2a
shows a clockwise rotation as expected. The heat flux and the temperature in Fig. 8.2b are not
entirely symmetric, which is similar to the results of [43].
Γ3
Γ4 : pw,4 Ω : Kn H Γ2 : pw,2
Γ1
L
Figure 8.3. Computational domain for the channel flow application case. The flow is driven by a
pressure difference between the inflow and outflow boundary. The upper and lower boundaries are
modeled as solid walls.
The resulting computational mesh consists of 10712 uniform but unstructured triangles
with 5517 nodes. The problem is discretized using P1 equal-order finite elements and
CIP stabilization with the usual parameters is applied. After the discrete system is
solved in 3 s, the result in Fig. 8.4 are obtained for a Knudsen number of Kn = 0.1.
As expected, the flow field in Fig. 8.4a is almost parallel to the outer walls, and
the deviatoric stress component σxy has its maxima at both outer channel walls. In
Fig. 8.4b, the heat flux is nonzero, although no temperature gradient is applied.
78 8. Applications
Figure 8.4. Schematic results of the channel flow application case for Kn = 0.1. The velocity field
in Fig. 8.4a shows a flow, that is almost parallel to the outer walls. Varying temperatures and a
heat flux in inflow direction can be observed in Fig. 8.2b.
An exciting phenomenon can further be observed during a parameter study for the
Knudsen number. A series of calculations are performed for a range of Kn-numbers
in [0.03, 2.0] using the same overall problem setup. A dimensionless mass flow rate
through the outflow boundary can be defined as
Z
J˜ := u · n dl, (8.1)
Γ2
0.7
Linearized R13 equations
Diml. mass flow rate J˜
0.6
0.5
0.4
0.3
10−1 100
Kn
Figure 8.5. Knudsen paradox in a channel flow. With increasing Knudsen number, the dimensionless
mass flow through the channel first decreases to a minimum before increasing again. Increasing the
λ
Knudsen number, in this context Kn = H , either means diluting the gas or decreasing the channel
width H.
8.3. Thermal Transpiration Flow in a Knudsen Pump 79
Another rarefaction effect can be observed in a Knudsen pump, which is inspired by [4,
33, 72]. Without any body force acting, a flow is solely induced by a temperature
gradient at the outer walls.
θ0 Γ6 θ1
R2
θ0 Γ2 θ1
L
Γ7 Γ3 Γ1 Ω Γ5
R1
θ1 Γ4 θ0
θ1 Γ8 θ0
Figure 8.6. Computational domain for the Knudsen pump application case. The flow is driven
by a temperature gradient at the outer walls. All walls are modeled as impermeable. The starting
points of both half rings act as control points for the prescribed temperatures θ0 and θ1 . In between
these points, a linear temperature gradient is applied.
The boundary path between θ0 and θ1 have a linear temperature profile applied. In
order to derive the corresponding expressions for θw , we need to define a modified
polar angle function. Let φ(a,b) (x, y) : R2 → [−π, π] denote a function, returning the
polar angle concerning the shifted origin (a, b), such that for example φ(1,0) (1, 2) = π2 .
This function is available in most programming languages as atan2(y,x). Table 8.1
shows the corresponding boundary expressions for the temperature at the inner wall.
For the outer wall, the same expressions as for the inner wall are used, such that
for example θ|Γ5 = θ|Γ1 . The corresponding input file also makes use of predefined
macros to obtain the polar angle and is listed in Listing C.3.
80 8. Applications
� �
� �
-� -�
-� -�
-� -� -� � � � � -� -� -� � � � �
a) Shear stress σxy and velocity streamlines ui . b) Temperature θ and heat flux streamlines si .
Figure 8.7. Schematic results of the Knudsen pump application case. A gas flow in counter-
clockwise direction can be observed in Fig. 8.2a, similar to the results obtained in [4, 72]. In
Fig. 8.2b, the linear temperature gradient at both boundary walls can be observed, resulting in a
heat flux from warm to cold regions.
9. Conclusion
Aim of this project was to enable the simulation of gas flows in non-equilibrium
situations using the FEniCS computing platform. Recalling the discussion of Chap-
ter 1, the FEniCS framework is a promising-looking, modern and popular software for
solving partial differential equations using the finite element method. As it turns out
throughout this thesis, its enhanced capabilities of treating tensor-valued expressions
in weak formulations are very beneficial for the specific use case of modeling rarefied
gas flows using the tensor-valued system of R13 equations.
In order to generally motivate the usage of extended models, suitable for moderate
Knudsen number flows, the classical gas models were introduced in Chapter 2. They
consist of the three fundamental balance laws together with the closures of Navier–
Stokes and Fourier. A subsequent discussion showed the limitations of the classical
models, i.e. the lack of predicting various rarefaction effects, that play an essential role
in non-equilibrium gas flows. In fact, gas flows in the transition regime with moderate
Knudsen numbers, require more refined and extended model equations to accurately
predict the behavior of rarefied gases or gas flows in miniaturized applications.
The R13 equations were the main model equations throughout this project. The
set of equations was derived from the kinetic gas theory in Chapter 3 and can be
seen as an approximation of the Boltzmann equation. Being two orders of magni-
tude more accurate in the Kn-number from an asymptotic perspective [64], the R13
equations extend the classical NSF system with additional evolution equations for
the heat flux and the deviatoric stress tensor leading to an increase model complexity.
This additional model accuracy is required to predict the rarefaction effects of a gas
in the non-equilibrium. As a first step, the full nonlinear R13 system was reduced
to a steady-state, linearized and two-dimensional system of equations, that is still
capable of predicting non-equilibrium effects as seen in Chapter 8. In fact, both
decoupled systems were implemented as mixed systems in Chapters 5 and 6. During
the implementation, it turned out, that additional tensorial operations had to be
implemented in order to treat tensors with a rank above two. Code snippets showed
the corresponding operators, implemented using the summation convention, that can
naturally be used in form language of FEniCS. These additional operator functions
enabled an implementation, that matches the mathematical formulation of the corre-
sponding weak form – one of the main concepts in the software engineering approach
82 9. Conclusion
of FEniCS according to [34]. The numerical discretization, using the finite element
method, was performed successively for a decoupled heat and stress system before
the full linearized R13 system was addressed. After a general introduction to the
finite element method and the FEniCS framework in Chapter 4, the intuitive imple-
mentation of a mixed finite element formulation was discussed using the exemplary
Stokes problem. This allowed understanding requirements and pitfalls in the process
of translating the mathematical mixed weak formulation into its corresponding source
code statements.
Both extracted subsystems were stabilized using the CIP method to enable the use
of equal-order Lagrangian elements, as the most basic and intuitive choice for finite
elements. A convergence study with exact solution showed convergence for both
subsystems, such that the full linearized R13 system resulted by the combination of
both weak forms with additional coupling terms, as discussed in Chapter 7. The full
linearized system was also validated against exact solutions for test cases, including
mass flow driven and inflow induced gas situations. The resulting convergence rates
were similar to the convergence rates of both subsystems, such that the full equations
also converge. While the usual convergence measure is often solely the L2 -norm,
all convergence studies in this work additionally considered a more restrictive node-
wise l∞ -error, in which a decreased convergence rate was observed in contrast to the
traditional L2 -error.
An essential part of this project was the implementation of a rarefied gas solver
fenicsR13 [58]. The solver can be accessed according to Section 9.2.1 and builds on
the most recent version of the FEniCS platform. The particular software engineering
concept of FEniCS, i.e. separating the mathematical statements from auxiliary FEM
implementation, enabled an intuitive implementation in the unified form language.
This high-level Python interface of FEniCS integrates well with other software tools
and file formats. The programmed solver is, therefore, programmed in a general way
allowing for arbitrary complex geometries and a wide range of boundary conditions
using a clean input file. Popular Python software engineering tools, such as pytest
and Sphinx, are integrated and enable continuous integration (CI) testing and an
automated generation of source code documentation. The capabilities of the imple-
mented solver were tested in Chapter 8 by considering application cases, in which
rarefaction effects are expected. Due to the observed convergence of the numerical
method to exact solutions, the prediction of the Knudsen paradox in Section 8.2 was
no surprise because it was already found in a similar one-dimensional setting in [62]
analytically. A transpiration or temperature-induced flow without a body force was
observed in Section 8.3. The implemented solver should serve as a starting point for
future work and could be a valuable alternative to classical NSF simulations for gas
flows in a rarefied setting. Possible extensions are discussed and presented in the
following Section 9.1.
9.1. Future Work 83
The underlying computing platform FEniCS, indeed, turned out to be an easy, and
intuitive to use, framework that allows to implement mathematical models quickly.
Numerical methods for the R13 equations required the treatment of tensorial struc-
tures and the ability to quickly interchange between mathematical formulations,
e.g. to switch stabilization methods, system formulations or boundary conditions.
Except for the treatment of rank-3 tensors, FEniCS can handle all the above in its
current implementation, and the resulting source code remains rather compact and
readable.
The underlying formulations of the fenicsR13 solver for the steady-state, linearized
and two-dimensional R13 equations were presented. The current implementation of
the solver, therefore, allows to extend the research in various directions and can act as
a starting point for further improvements and new ideas. During the theoretical recap
of the model equations and during the formulation of the numerical method, certain
simplifications were applied. Future work could aim to remove these simplifications
in order to extend the solver to more general use cases. Further improvement and
new directions of research can be collected and can be sorted into the following four
categories:
for simple geometries such as spheres. These exact solutions should be used to
validate the method further.
• Performance and Error Comparison: The used finite element framework can
be tested against other numerical approaches in terms of accuracy and overall
performance. A comparison could identify bottlenecks and should be executed
with respect to already existing approaches, such as finite difference schemes,
discontinuous Galerkin methods, or Direct Simulation Monte Carlo (DSMC)
methods. An aim could further be to test the method against experimental
data for a series of problem parameters. This could help to identify parameter
regions, where the given models are not sufficiently accurate. The capabilities
of FEniCS for parallel simulations can also be subject for further studies.
In order to guarantee reproducibility of the obtained results, the used hardware, the
relevant software and other technical details are listed in the following.
9.2. Technical Details 85
The solver is hosted on RWTH’s Gitlab instance in [58]. The solver’s documentation
is also hosted on RWTH’s Gitlab instance using the pages feature of Gitlab in [57].
The repository contains all convergence tests and all application cases. A snapshot
of the current solver documentation and the relevant solver source code are given in
Appendices B.1 and B.2.
In Table 9.1, the specific version numbers of all software tools, used in the context of
this work, are listed.
Program Version
Gmsh 4.4.0
FEniCS (Docker image) 2019.1.0.r3
Python 3.6.8
Docker 2.1.0.2
Paraview 5.6.0
Wolfram Mathematica 12
The listed exact solutions are based on an ansatz inspired by the derivation of exact
solutions for the Stokes equations in cylindrical coordinates (using R, φ, z), that was
performed in [68, 69]. The fields of interest in this coordinate system then read:
system Wolfram Mathematica was used to calculate the integration constants for the
given ansatz.
To use the exact fields in a two-dimensional cartesian coordinate system (using
x, y), the following transformations [47] for a vector u and a symmetric 2-tensor σ
(i.e. σRφ = σφR ) are applied:
53 // https://ocw.mit.edu/courses/aeronautics-and-astronautics/
54 // ...16-07-dynamics-fall-2009/lecture-notes/MIT16_07F09_Lec05.pdf
55 double s_x = s_R * cos(phi) - s_phi * sin(phi);
56 double s_y = s_R * sin(phi) + s_phi * cos(phi);
57
58 values[0] = s_x ;
59 values[1] = s_y ;
60 }
61 };
62
63
64 PYBIND11_MODULE(SIGNATURE, m) {
65
66 py::class_<Temperature, std::shared_ptr<Temperature>, dolfin::Expression>
67 (m, "Temperature")
68 .def(py::init<>());
69
70 py::class_<Heatflux, std::shared_ptr<Heatflux>, dolfin::Expression>
71 (m, "Heatflux")
72 .def(py::init<>());
73
74 }
52 public:
53 Pressure() : dolfin::Expression() {}
54 void eval(Eigen::Ref<Eigen::VectorXd> values,
55 Eigen::Ref<const Eigen::VectorXd> x) const override {
56
57 double R = sqrt(pow(x[0],2)+pow(x[1],2));
58 double phi = atan2(x[1],x[0]);
59
60 double d_0 = C_9 + C_2*K_0( R*lambda_2/kn) + C_8*I_0(R*lambda_2/kn);
61 double d = - (10*A_1 * pow(R,2))/(27*kn) + (4*C_4*R)/(kn) - (2*C_5*kn)/R + C_14*K_1( R*lambda_2/kn) + C_15* I_1(
R*lambda_2/kn);
62
63 values[0] = d_0 + cos(phi) * d;
64 }
65 };
66
67 class Velocity : public dolfin::Expression {
68 public:
69 Velocity() : dolfin::Expression(2) {}
70 void eval(Eigen::Ref<Eigen::VectorXd> values,
71 Eigen::Ref<const Eigen::VectorXd> x) const override {
72
73 double R = sqrt(pow(x[0],2)+pow(x[1],2));
74 double phi = atan2(x[1],x[0]);
75
76 double a_0 = C_7*kn/R;
77 double a = -A_1*R*((2*pow(R,2))/(27*pow(kn,2)) - 2.0/3.0) + C_0 - (C_3*pow(kn,2))/(2*pow(R,2)) + (C_4 *
pow(R,2))/(2*pow(kn,2)) + C_5 * (std::log(R/kn)-1.0/2.0);
78
79 double b_0 = C_1/(2*R*kn) + C_6*R;
80 double b = -A_1*R*((pow(R,2))/(54*pow(kn,2)) - 1.0/3.0) + C_0 + (C_3*pow(kn,2))/(2*pow(R,2)) + (3*C_4 *
pow(R,2))/(2*pow(kn,2)) + C_5 * (std::log(R/kn)+1.0/2.0);
81
82 double u_R = a_0 + cos(phi) * a;
83 double u_phi = b_0 - sin(phi) * b;
84
85 double u_x = u_R * cos(phi) - u_phi * sin(phi);
86 double u_y = u_R * sin(phi) + u_phi * cos(phi);
87
88 values[0] = u_x ;
89 values[1] = u_y ;
90 }
91 };
92
93 class Stress : public dolfin::Expression {
94 public:
95 Stress() : dolfin::Expression(2,2) {}
96 void eval(Eigen::Ref<Eigen::VectorXd> values,
97 Eigen::Ref<const Eigen::VectorXd> x) const override {
98
99 double R = sqrt(pow(x[0],2)+pow(x[1],2));
100 double phi = atan2(x[1],x[0]);
101
102 double gamma_0 =
103 + (2*C_7*pow(kn,2))/(pow(R,2))
104 + (C_10*kn*K_1((R*lambda_3)/kn))/(lambda_3*R)
105 + (C_11*kn*I_1((R*lambda_3)/kn))/(lambda_3*R)
106 + C_2*(
107 + (kn*K_1((R*lambda_2/kn)))/(2*lambda_2*R)
108 - K_2(R*lambda_2/kn)
109 )
110 + C_8*(
111 - (kn*I_1(R*lambda_2/kn))/(2*lambda_2*R)
112 - I_2(R*lambda_2/kn)
113 );
114 double gamma =
115 + (7.*A_1*pow(R,2))/(27.*kn)
116 - (2.*pow(kn,3)*(C_3-(64.*C_5)/15.))/pow(R,3)
117 - (2.*C_4*R)/kn
118 - (2.*C_5*kn)/R
119 + (C_12*kn*I_2(R*lambda_3/kn))/(lambda_3*R)
120 + (C_13*kn*K_2(R*lambda_3/kn))/(lambda_3*R)
121 + C_14*(
122 - K_1(R*lambda_2/kn)
123 - (3.*kn*K_2(R*lambda_2/kn))/(2.*lambda_2*R)
124 )
125 + C_15*(
126 + (3.*kn*I_2(R*lambda_2/kn))/(2.*lambda_2*R)
127 - I_1(R*lambda_2/kn)
128 );
129
130 double kappa_0 =
131 C_1/pow(R,2);
132 double kappa =
133 - (A_1*pow(R,2))/(9*kn)
A.1. Exact Solutions 91
134 - (2.*pow(kn,3)*(C_3-(64.*C_5)/15.))/pow(R,3)
135 + (2.*C_4*R)/kn
136 + (C_12*kn*I_2(R*lambda_3/kn))/(lambda_3*R)
137 + (C_13*kn*K_2(R*lambda_3/kn))/(lambda_3*R)
138 - (3.*C_14*kn*K_2(R*lambda_2/kn))/(2.*lambda_2*R)
139 + (3.*C_15*kn*I_2(R*lambda_2/kn))/(2.*lambda_2*R);
140
141 double omega_0 =
142 (2*C_7*pow(kn,2))/pow(R,2)
143 + C_10*(K_0(R*lambda_3/kn)+(kn*K_1(R*lambda_3/kn)/(lambda_3*R)))
144 + C_11*((kn*I_1(R*lambda_3/kn))/(lambda_3*R)-I_0(R*lambda_3/kn)) + C_2 * (
145 - 1./2.*K_0(R*lambda_2/kn)
146 - (3*kn*K_1(R*lambda_2/kn))/(2*lambda_2*R)
147 )
148 + C_8 * (
149 + (3*kn*I_1(R*lambda_2/kn))/(2*lambda_2*R)
150 - 1./2.*I_0(R*lambda_2/kn)
151 );
152 double omega =
153 (2*A_1*pow(R,2))/(27*kn)
154 - (2*pow(kn,3)*(C_3-(64*C_5)/15.))/(pow(R,3))
155 - (2*C_4*R)/kn
156 - (2*C_5*kn)/R
157 + C_12 * (
158 + (kn*I_2(R*lambda_3/kn))/(lambda_3*R)
159 - I_1(R*lambda_3/kn)
160 )
161 + C_13 * (
162 + K_1(R*lambda_3/kn)
163 + (kn*K_2(R*lambda_3/kn))/(lambda_3*R)
164 )
165 + C_14 * (
166 + (kn*K_2(R*lambda_2/kn))/(2*lambda_2*R)
167 - 1/2.*K_3(R*lambda_2/kn)
168 )
169 + C_15 * (
170 - (kn*I_2(R*lambda_2/kn))/(2*lambda_2*R)
171 - 1/2.*I_3(R*lambda_2/kn)
172 );
173
174 double sigma_RR = gamma_0 + cos(phi) * gamma;
175 double sigma_Rphi = kappa_0 + sin(phi) * kappa;
176 double sigma_phiphi = -(omega_0 + cos(phi) * omega);
177
178 // Heinz Schade p377: Assume symmetry of tensor <=> a_Rphi = a_phiR
179 double sigma_xx =
180 + sigma_RR * pow(cos(phi),2)
181 - (sigma_Rphi + sigma_Rphi) * cos(phi) * sin(phi)
182 + sigma_phiphi * pow(sin(phi),2);
183 double sigma_xy =
184 + sigma_Rphi * pow(cos(phi),2)
185 + (sigma_RR - sigma_phiphi) * cos(phi) * sin(phi)
186 - sigma_Rphi * pow(sin(phi),2);
187 double sigma_yy =
188 + sigma_phiphi * pow(cos(phi),2)
189 + (sigma_Rphi + sigma_Rphi) * cos(phi) * sin(phi)
190 + sigma_RR * pow(sin(phi),2);
191
192 values[0] = sigma_xx ;
193 values[1] = sigma_xy ;
194 values[2] = sigma_yy ;
195 }
196 };
197
198 PYBIND11_MODULE(SIGNATURE, m) {
199
200 py::class_<Pressure, std::shared_ptr<Pressure>, dolfin::Expression>
201 (m, "Pressure")
202 .def(py::init<>());
203
204 py::class_<Velocity, std::shared_ptr<Velocity>, dolfin::Expression>
205 (m, "Velocity")
206 .def(py::init<>());
207
208 py::class_<Stress, std::shared_ptr<Stress>, dolfin::Expression>
209 (m, "Stress")
210 .def(py::init<>());
211 }
1 #include <pybind11/pybind11.h>
2 #include <pybind11/pybind11.h>
3 #include <pybind11/eigen.h>
92 A. Convergence Data and Exact Solutions
4
5 #include <cmath>
6 #include <boost/math/special_functions/bessel.hpp>
7
8 using namespace std;
9 //using namespace boost::math;
10
11 namespace py = pybind11;
12
13 #include <dolfin/function/Expression.h>
14
15 double C_0 = -50.80230139855979;
16 double C_1 = 0.6015037593984962;
17 double C_2 = 0;
18 double C_3 = -444.7738727200452;
19 double C_4 = -0.12443443849461801;
20 double C_5 = 39.38867688999618;
21 double C_6 = -0.6917293233082705;
22 double C_7 = 0;
23 double C_8 = 0;
24 double C_9 = 0;
25 double C_10 = 0;
26 double C_11 = 0;
27 double C_12 = 2.255312046238658E-11;
28 double C_13 = 407.2248457002586;
29 double C_14 = -104.89346597195336;
30 double C_15 = 4.870715709115059E-7;
31 double kn = 0.1;
32 double A_1 = 0.4;
33 // // double A_1 = 0.0;
34
35 double lambda_1 = sqrt(5.0/9.0);
36 double lambda_2 = sqrt(5.0/6.0);
37 double lambda_3 = sqrt(3.0/2.0);
38
39 double BI( int n, double x ) { return boost::math::cyl_bessel_i(n,x); }
40 double BK( int n, double x ) { return boost::math::cyl_bessel_k(n,x); }
41
42 double I_0( double x) { return BI(0,x); }
43 double I_1( double x) { return BI(1,x); }
44 double I_2( double x) { return BI(2,x); }
45 double I_3( double x) { return BI(3,x); }
46
47 double K_0( double x) { return BK(0,x); }
48 double K_1( double x) { return BK(1,x); }
49 double K_2( double x) { return BK(2,x); }
50 double K_3( double x) { return BK(3,x); }
51
52 class Pressure : public dolfin::Expression {
53 public:
54 Pressure() : dolfin::Expression() {}
55 void eval(Eigen::Ref<Eigen::VectorXd> values,
56 Eigen::Ref<const Eigen::VectorXd> x) const override {
57
58 double R = sqrt(pow(x[0],2)+pow(x[1],2));
59 double phi = atan2(x[1],x[0]);
60
61 double d_0 = C_9 + C_2*K_0( R*lambda_2/kn) + C_8*I_0(R*lambda_2/kn);
62 double d = - (10*A_1 * pow(R,2))/(27*kn) + (4*C_4*R)/(kn) - (2*C_5*kn)/R + C_14*K_1( R*lambda_2/kn) + C_15* I_1(
R*lambda_2/kn);
63
64 values[0] = d_0 + cos(phi) * d;
65 }
66 };
67
68 class Velocity : public dolfin::Expression {
69 public:
70 Velocity() : dolfin::Expression(2) {}
71 void eval(Eigen::Ref<Eigen::VectorXd> values,
72 Eigen::Ref<const Eigen::VectorXd> x) const override {
73
74 double R = sqrt(pow(x[0],2)+pow(x[1],2));
75 double phi = atan2(x[1],x[0]);
76
77 double a_0 = C_7*kn/R;
78 double a = -A_1*R*((2*pow(R,2))/(27*pow(kn,2)) - 2.0/3.0) + C_0 - (C_3*pow(kn,2))/(2*pow(R,2)) + (C_4 *
pow(R,2))/(2*pow(kn,2)) + C_5 * (std::log(R/kn)-1.0/2.0);
79
80 double b_0 = C_1/(2*R*kn) + C_6*R;
81 double b = -A_1*R*((pow(R,2))/(54*pow(kn,2)) - 1.0/3.0) + C_0 + (C_3*pow(kn,2))/(2*pow(R,2)) + (3*C_4 *
pow(R,2))/(2*pow(kn,2)) + C_5 * (std::log(R/kn)+1.0/2.0);
82
83 double u_R = a_0 + cos(phi) * a;
84 double u_phi = b_0 - sin(phi) * b;
85
A.1. Exact Solutions 93
171 )
172 + C_15 * (
173 - (kn*I_2(R*lambda_2/kn))/(2*lambda_2*R)
174 - 1/2.*I_3(R*lambda_2/kn)
175 );
176
177 double sigma_RR = gamma_0 + cos(phi) * gamma;
178 double sigma_Rphi = kappa_0 + sin(phi) * kappa;
179 double sigma_phiphi = -(omega_0 + cos(phi) * omega);
180
181 // Heinz Schade p377: Assume symmetry of tensor <=> a_Rphi = a_phiR
182 double sigma_xx =
183 + sigma_RR * pow(cos(phi),2)
184 - (sigma_Rphi + sigma_Rphi) * cos(phi) * sin(phi)
185 + sigma_phiphi * pow(sin(phi),2);
186 double sigma_xy =
187 + sigma_Rphi * pow(cos(phi),2)
188 + (sigma_RR - sigma_phiphi) * cos(phi) * sin(phi)
189 - sigma_Rphi * pow(sin(phi),2);
190 double sigma_yy =
191 + sigma_phiphi * pow(cos(phi),2)
192 + (sigma_Rphi + sigma_Rphi) * cos(phi) * sin(phi)
193 + sigma_RR * pow(sin(phi),2);
194
195 values[0] = sigma_xx ;
196 values[1] = sigma_xy ;
197 values[2] = sigma_yy ;
198 }
199 };
200
201 PYBIND11_MODULE(SIGNATURE, m) {
202
203 py::class_<Pressure, std::shared_ptr<Pressure>, dolfin::Expression>
204 (m, "Pressure")
205 .def(py::init<>());
206
207 py::class_<Velocity, std::shared_ptr<Velocity>, dolfin::Expression>
208 (m, "Velocity")
209 .def(py::init<>());
210
211 py::class_<Stress, std::shared_ptr<Stress>, dolfin::Expression>
212 (m, "Stress")
213 .def(py::init<>());
214 }
1 #include <pybind11/pybind11.h>
2 #include <pybind11/eigen.h>
3
4 #include <cmath>
5 #include <boost/math/special_functions/bessel.hpp>
6
7 using namespace std;
8
9 namespace py = pybind11;
10
11 #include <dolfin/function/Expression.h>
12
13 double kn = 1.0;
14
15 // // Constants eps=10^-5
16 // double C_0 = 1.088418574133493;
17 // double C_1 = -0.4708784837854026;
18 // double C_2 = -0.1060780078877844;
19 // double C_3 = 0.6397363738946663;
20 // double C_4 = -0.04268373030990083;
21 // double C_5 = 0.1027291801998076;
22 // double C_6 = -0.1867020667903523;
23 // double C_7 = 2.864923360570221e-7;
24 // double C_8 = 1.963244537638472;
25 // double C_9 = 0.007704644954804194;
26 // double CK_1 = -0.01841555365364274;
27 // double CK_2 = 0.02647436311982035;
28 // double CK_3 = -0.0722116290730638;
29 // double CK_4 = 0.01263372155827893;
30 // double CK_5 = 0.03846910453592139;
31 // double CK_6 = 0.003998659067908465;
32 // double CK_7 = 0.05469703377538136;
33 // double CK_8 = 0.04448263813229264;
34 // double CK_9 = -0.001607567940383826;
35 // double CK_10 = 0.1781491089766695;
36
37 // // Constants eps=10^-4
38 // double C_0 = 1.088458465830652;
39 // double C_1 = -0.4708795265589713;
40 // double C_2 = -0.1060844454754048;
41 // double C_3 = 0.6397268622237638;
42 // double C_4 = -0.0426888328939176;
43 // double C_5 = 0.1027285697835575;
44 // double C_6 = -0.1867022145254646;
45 // double C_7 = 2.864825757859002e-6;
98 A. Convergence Data and Exact Solutions
131
132 double I_0( double x) { return BI(0,x); }
133 double I_1( double x) { return BI(1,x); }
134 double I_2( double x) { return BI(2,x); }
135 double I_3( double x) { return BI(3,x); }
136
137 double K_0( double x) { return BK(0,x); }
138 double K_1( double x) { return BK(1,x); }
139 double K_2( double x) { return BK(2,x); }
140 double K_3( double x) { return BK(3,x); }
141
142 class Temperature : public dolfin::Expression {
143 public:
144 Temperature() : dolfin::Expression() {}
145 void eval(Eigen::Ref<Eigen::VectorXd> values,
146 Eigen::Ref<const Eigen::VectorXd> x) const override {
147
148 double R = sqrt(pow(x[0],2)+pow(x[1],2));
149 double phi = atan2(x[1],x[0]);
150
151 double c_0 = C_8 + (2*CK_4*I_0((R*lambda_2)/kn))/5. + (2*CK_3*K_0((R*lambda_2)/kn))/5. - (4*C_6*std::log(R/kn))/15.;
152 double c = (-4*C_2*R)/(15.*kn) + (8*C_4*R)/(5.*kn) - (2*C_1*kn)/(15.*R) - (4*C_5*kn)/(5.*R) +
(2*CK_10*I_1((R*lambda_2)/kn))/5. + (2*CK_9*K_1((R*lambda_2)/kn))/5.;
153
154 double theta = c_0 + cos(phi) * c;
155
156 values[0] = theta;
157 }
158 };
159
160 class Heatflux : public dolfin::Expression {
161 public:
162 Heatflux() : dolfin::Expression(2) {}
163 void eval(Eigen::Ref<Eigen::VectorXd> values,
164 Eigen::Ref<const Eigen::VectorXd> x) const override {
165
166 double R = sqrt(pow(x[0],2)+pow(x[1],2));
167 double phi = atan2(x[1],x[0]);
168
169 double alpha_0 = (C_6*kn)/R;
170 double alpha = C_2 - (C_1*std::pow(kn,2))/(2.*std::pow(R,2)) - (5*((2*CK_1*kn*I_1((R*lambda_1)/kn))/(R*lambda_1) +
(2*CK_2*kn*K_1((R*lambda_1)/kn))/(R*lambda_1)))/2.;
171
172 double beta_0 = 0;
173 double beta = C_2 + (C_1*std::pow(kn,2))/(2.*std::pow(R,2)) - (5*(CK_1*(I_0((R*lambda_1)/kn) + I_2((R*lambda_1)/kn)) -
CK_2*(K_0((R*lambda_1)/kn) + K_2((R*lambda_1)/kn))))/2.;
174
175 double s_R = alpha_0 + cos(phi) * alpha;
176 double s_phi = beta_0 - sin(phi) * beta;
177
178 double s_x = s_R * cos(phi) - s_phi * sin(phi);
179 double s_y = s_R * sin(phi) + s_phi * cos(phi);
180
181 values[0] = s_x ;
182 values[1] = s_y ;
183 }
184 };
185
186 class Pressure : public dolfin::Expression {
187 public:
188 Pressure() : dolfin::Expression() {}
189 void eval(Eigen::Ref<Eigen::VectorXd> values,
190 Eigen::Ref<const Eigen::VectorXd> x) const override {
191
192 double R = sqrt(pow(x[0],2)+pow(x[1],2));
193 double phi = atan2(x[1],x[0]);
194
195 double d_0 = C_9 + CK_4*I_0((R*lambda_2)/kn) + CK_3*K_0((R*lambda_2)/kn);
196 double d = (4*C_4*R)/kn - (2*C_5*kn)/R + CK_10*I_1((R*lambda_2)/kn) + CK_9*K_1((R*lambda_2)/kn);
197
198 double p = d_0 + cos(phi) * d;
199
200 values[0] = p;
201 }
202 };
203
204 class Velocity : public dolfin::Expression {
205 public:
206 Velocity() : dolfin::Expression(2) {}
207 void eval(Eigen::Ref<Eigen::VectorXd> values,
208 Eigen::Ref<const Eigen::VectorXd> x) const override {
209
210 double R = sqrt(pow(x[0],2)+pow(x[1],2));
211 double phi = atan2(x[1],x[0]);
212
100 A. Convergence Data and Exact Solutions
hmax θ sx sy
9.89−1 2.00−1 2.21−1 2.23−1
6.34−1 1.29−1 1.05−1 1.06−1
3.29−1 3.69−2 2.15−2 2.12−2
1.68−1 1.05−2 5.71−3 5.70−3
8.73−2 2.60−3 1.39−3 1.39−3
4.71−2 6.72−4 3.62−4 3.62−4
2.33−2 1.73−4 9.22−5 9.22−5
hmax θ sx sy
9.89−1 1.21−1 2.90−1 2.26−1
6.34−1 7.85−2 1.43−1 1.50−1
3.29−1 2.84−2 2.89−2 3.70−2
1.68−1 8.40−3 7.99−3 6.25−3
8.73−2 2.67−3 1.59−3 1.64−3
4.71−2 6.45−4 3.98−4 3.90−4
2.33−2 1.83−4 9.58−5 9.51−5
hmax θ sx sy
9.89−1 1.85−1 3.82−1 5.19−1
6.34−1 2.00−1 3.53−1 3.48−1
3.29−1 7.36−2 1.45−1 1.44−1
1.68−1 1.81−2 2.81−2 2.75−2
8.73−2 4.24−3 5.66−3 5.67−3
4.71−2 1.16−3 1.38−3 1.38−3
2.33−2 3.30−4 3.48−4 3.49−4
1.20−2 9.61−5 8.67−5 8.67−5
hmax θ sx sy
9.89−1 1.15−1 3.06−1 2.89−1
6.34−1 1.89−1 3.01−1 3.08−1
3.29−1 9.47−2 1.36−1 1.52−1
1.68−1 3.82−2 4.22−2 4.32−2
8.73−2 1.15−2 8.34−3 7.99−3
4.71−2 4.79−3 1.85−3 1.80−3
2.33−2 2.02−3 5.67−4 5.10−4
1.20−2 8.74−4 1.28−4 1.18−4
hmax θ sx sy
9.89−1 1.70−1 1.87−1 1.55−1
6.34−1 7.48−2 7.89−2 8.04−2
3.29−1 2.26−2 2.03−2 1.95−2
1.68−1 6.36−3 5.62−3 5.62−3
8.73−2 1.59−3 1.39−3 1.38−3
4.71−2 4.10−4 3.61−4 3.61−4
2.33−2 1.04−4 9.22−5 9.22−5
hmax θ sx sy
9.89−1 1.20−1 1.92−1 1.31−1
6.34−1 6.66−2 8.46−2 8.65−2
3.29−1 2.05−2 1.69−2 2.20−2
1.68−1 5.45−3 5.53−3 5.46−3
8.73−2 1.28−3 1.38−3 1.39−3
4.71−2 3.31−4 3.51−4 3.55−4
2.33−2 8.91−5 9.03−5 8.97−5
Table A.7. DLSS: L2 -errors for stabilized P1 P1 P1 elements (test case 1).
Table A.8. DLSS: l∞ -errors for stabilized P1 P1 P1 elements (test case 1).
104 A. Convergence Data and Exact Solutions
Table A.9. DLSS: L2 -errors for unstabilized P3 P2 P1 elements (test case 2).
Table A.10. DLSS: l∞ -errors for unstabilized P3 P2 P1 elements (test case 2).
Table A.11. DLSS: L2 -errors for stabilized P1 P1 P1 elements (test case 2).
Table A.12. DLSS: l∞ -errors for stabilized P1 P1 P1 elements (test case 2).
A.2. Convergence Errors 105
Table A.13. DLSS: L2 -errors for stabilized P2 P2 P2 elements (test case 2).
Table A.14. DLSS: l∞ -errors for stabilized P2 P2 P2 elements (test case 2).
Table A.15. LinR13: L2 -errors for stabilized P1 P1 P1 P1 P1 elements (test case 1).
106 A. Convergence Data and Exact Solutions
Table A.16. LinR13: l∞ -errors for stabilized P1 P1 P1 P1 P1 elements (test case 1).
Table A.17. LinR13: L2 -errors for stabilized P2 P2 P2 P2 P2 elements (test case 1).
Table A.18. LinR13: l∞ -errors for stabilized P2 P2 P2 P2 P2 elements (test case 1).
Table A.19. LinR13: L2 -errors for stabilized P1 P1 P1 P1 P1 elements (test case 2).
A.2. Convergence Errors 107
Table A.20. LinR13: l∞ -errors for stabilized P1 P1 P1 P1 P1 elements (test case 2).
B. Solver Related Data
The implementation of a rarefied gas solver was essential part of this thesis. In terms
of reproducibility for the obtained results, all relevant solver data is listed in its
current form by the date of the submission of this work. An up-to-date version can
be found in the solver repository, as explained in Section 9.2.1. The current solver
documentation in LATEX-format is listed in Appendix B.1 while the relevant parts of
the solver implementation are listed in Appendix B.2.
fenicsR13
Release 1.0
Lambert Theisen
Sep 23 19 at 06:12
B.1. Solver Documentation 111
CONTENTS
1 Installation 2
1.1 Docker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2 Documentation 5
2.1 Pre-Build Version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Manual Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4 Contact 10
5 Change log 11
5.1 1.0 (2019-09-23) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.2 0.5 (2019-09-13) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.3 0.4 (2019-08-21) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.4 0.3 (2019-08-11) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.5 0.2 (2019-07-29) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.6 0.1 (2019-07-17) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
7 Contents 14
7.1 src . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
7.2 heat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
7.3 stress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
7.4 r13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
7.5 examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Bibliography 34
Index 36
i
112 B. Solver Related Data
CONTENTS 1
B.1. Solver Documentation 113
CHAPTER
ONE
INSTALLATION
1.1 Docker
2
114 B. Solver Related Data
The main folder of this repository contains a Dockerfile defining the used environment. Here, we used
the optimized and official FEniCS Docker image and include Gmsh and install some requirements from the
requirements.txt. This can take a while, especially the Gmsh mirror can be quite slow. To avoid very long
execution commands (docker run <..> -v <volume share> <etc..>), a docker-compose.yml is
used to store all these parameters. docker-compose acts as an wrapper for the Docker execution.
The fenics environment (also called service in the docker-compose.yml) first has to be build and can be
executed afterwards. The steps to perform read
The whole repository is mounted as a volume under /home/fenics/shared in the container and should
be the default folder on startup. To execute a simulation case, go to to the case folder (e.g. examples/
lid_driven_cavity) and execute the solver main program fenicsR13.py (which is located in the src-
directory in the top level) while specifying the input file as first command line argument. This can be for exam-
ple python3 ../../src/fenicsR13.py inout.yml. Output files should be written to a folder which is
named after the output_folder keyword of the input.yml. Each output field (temperature, pressure,. . . ) has a
1.1. Docker 3
B.1. Solver Documentation 115
.h5-file and an .xdmf-file. The XDMF-files can be opened in Paraview to perform visualization.
It is possible to use a Jupyter sever or a X11 forwarding but this is not recommended anymore. All relevant plots are
now written by default without the need for the tricky X11 forwarding or interactive usage with Jupyter.
4 Chapter 1. Installation
116 B. Solver Related Data
CHAPTER
TWO
DOCUMENTATION
Visit the hosted version on Gitlab Pages or download the artifacts from Gitlab’s CI pages-pipeline.
# cat .gitlab-ci.yml
cd docs
sphinx-apidoc -o source/src ../src
sphinx-apidoc -o source/tests/heat ../tests/heat
sphinx-apidoc -o source/tests/stress ../tests/stress
sphinx-apidoc -o source/tests/r13 ../tests/r13
sphinx-apidoc -o source/examples ../examples
make html
make latex
5
B.1. Solver Documentation 117
CHAPTER
THREE
_math_header = """
// cmath functions
#include <boost/math/special_functions/bessel.hpp> // Added
%s
"""
import os
cwd = os.getcwd()
print(cwd)
6
118 B. Solver Related Data
• The build stage has to be triggered manually when something in the setup changes. This is because it takes a
fair amount of time.
• In ~/.gitlab-runner/config.toml (for the runner):
– change priviliges to true
– Use local images: pull_policy = "if-not-present"
– To [[runners]] add environment = ["DOCKER_TLS_CERTDIR="] (See https://gitlab.
com/gitlab-org/gitlab-ce/issues/64959)
• Run local: gitlab-runner exec docker --docker-privileged build or with build replaced by job name
– maybe local vars have to be change to use local Docker images because CI_REGISTRY,. . . are not
set
An example gitlab runner config/toml in ~/.gitlab-runner can look like:
concurrent = 1
check_interval = 0
[[runners]]
name = "190716-macbookpro"
url = "https://git.rwth-aachen.de/"
token = "<PRIVATE_TOKEN>"
executor = "docker"
environment = ["DOCKER_TLS_CERTDIR="]
[runners.docker]
tls_verify = false
image = "docker:stable"
privileged = true
disable_cache = false
(continues on next page)
3. Open a X11 server and set the ip variable (that is used in the docker-compose.yml when starting the
Docker container to set export DISPLAY=${ip}:0).
CHAPTER
FOUR
CONTACT
Author
Lambert Theisen
lambert.theisen@rwth-aachen.de
Supervisor
Prof. Dr. Manuel Torrilhon
Lehrstuhl für Mathematik (MathCCES)
RWTH Aachen University
mt@mathcces.rwth-aachen.de
Context
Masterthesis Computational Engineering Science
RWTH Aachen University
Simulation of Non-Equilibrium Gas Flows Using the FEniCS Computing Platform
10
122 B. Solver Related Data
CHAPTER
FIVE
CHANGE LOG
• Improve examples
– Remove auxiliary files, clean cases, improve output plots and change some meshes
• Add WELCOME screen to Docker container with link to website and documentation
• Introduce more variables as dolfin.Constant() for parameters study w.o. compiling
• Add time measure for linear solve
• Thesis submission version
11
B.1. Solver Documentation 123
• Finish documentation
– Also includes some doctests to test for edge cases
• Introduce develop branch to only have major version at master branch
• Add relative error calculation
• Add channel flow example (to test for Knudsen paradox)
• Fix error calculation for higher-order Ansatz function
– The previous error was based on DOFS (P2 elements therefore differ), the new error is based on vertex
values
• Add logo
• Add Sphinx documentation
• Add pytests
• Add Gitlab CI scripts
CHAPTER
SIX
• genindex
• modindex
• search
13
B.1. Solver Documentation 125
CHAPTER
SEVEN
CONTENTS
7.1 src
fenicsR13.main()
Execute the main program.
Searches for an "input.yml" file in the current directory to use as input.
Usage:
14
126 B. Solver Related Data
class input.Input(yaml_file)
Bases: object
Class to handle the input file in YAML format.
An example input file could look like:
# General
# =======
# - output_folder: Used as output folder
output_folder: r13_1_coeffs_sources_rot_noinflow_p2p2p2p2p2_stab
# Meshes
# ======
# - meshes: List of input meshes in h5 format to run simulations on
meshes:
- ../mesh/ring0.h5
- ../mesh/ring1.h5
- ../mesh/ring2.h5
- ../mesh/ring3.h5
- ../mesh/ring4.h5
# - ../mesh/ring5.h5
# - ../mesh/ring6.h5
# - ../mesh/ring7.h5
# - ../mesh/ring8.h5
# Numerical Parameters
# ====================
# - elements: Must contain the fields: theta, s, p, u, sigma
# - fields: List of FEM parameters (shape, degree)
# - shape: Element shape, e.g. Lagrange
# - degree: Element degree, e.g. 2
# - stabilization: Must contain cip
# - cip: Collection of Continous Interior Penalty (CIP) parameters
# - enable: Enable CIP stabilization
# - delta_1: Stabilization of grad(T)*grad(T_test) over edge
# - delta_2: Stabilization of grad(u)*grad(u_test) over edge
# - delta_3: Stabilization of grad(p)*grad(p_test) over edge
elements:
theta:
shape: Lagrange
degree: 2
s:
shape: Lagrange
degree: 2
p:
shape: Lagrange
degree: 2
u:
shape: Lagrange
degree: 2
sigma:
shape: Lagrange
degree: 2
stabilization:
cip:
enable: True
delta_1: 1.0
delta_2: 1.0
(continues on next page)
7.1. src 15
B.1. Solver Documentation 127
# Formulation Parameters
# ======================
# - nsd: Number of spatial dimensions == 2
# - mode: Formulation mode, one of heat, stress, r13
# - use_coeffs: Use real R13 coefficients, False only valid in heat
# - kn: Knudsen numberkn
# - xi_tilde: Refaction coefficient in Maxwell accomodation model
# - heat_source: Heat source function for mode==heat||r13
# - mass_source: Mass source function for mode==stress||r13
nsd: 2
mode: r13
use_coeffs: True
kn: 1.0
xi_tilde: 1.0
heat_source: 0
mass_source: 1.0 * (1.0 - (5.0*pow(R,2))/(18.0*pow(kn,2))) * cos(phi)
# Boundary Conditions
# ===================
# - bcs: Dictionary of all boundary IDs from mesh
# - bc_id: must contain theta_w, u_t_w, u_n_w, p_w, epsilon_w
# - theta_w: Value for temperature at wall
# - u_t_w: Value for tangential velocity at wall
# - u_n_w: Value for normal velocity at wall
# - p_w: Value for pressure at wall
# - epsilon_w: Inflow-model parameter <=> Weight of pressure
bcs:
3000:
theta_w: 1.0
u_t_w: -10
u_n_w: 0
p_w: 0
epsilon_w: 0
3100:
theta_w: 0.5
u_t_w: 0
u_n_w: 0
p_w: 0
epsilon_w: 0
# Convergence Study
# =================
# - enable: Enable convergence study on given meshes
# - exact_solution: Path to exact solution in cpp-format to compare
# - plot: Show errors in matplotlib window. PDF output is default
# - write_systemmatrix: Writes out systemmatrix (LHS)
# - rescale_pressure: Rescale numerical pressure result for zero mean
# - relative_errors: Use relative errors. If esol=0, use absolute.
convergence_study:
enable: True
exact_solution: esols/1_coeffs_sources_rot_noinflow.cpp
plot: False
write_systemmatrix: False
rescale_pressure: True
relative_error: True
(continues on next page)
16 Chapter 7. Contents
128 B. Solver Related Data
# Postprocessing
# ==============
# - write_pdfs: Write all solution fields as PDF plot
# - massflow: List of BC IDs to compute massflow J=int_bc dot(u,n) ds
postprocessing:
write_pdfs: True
# Parameter Study
# ==============
# - enable: Repeat simulation with different p. values (study)
# - parameter_key: Key as list, e.g. ["elemenets", "p", "degree"]
# - parameter_values: List of value for parameter, e.g. [0.01,0.1,1,10]
parameter_study:
enable: True
parameter_key: ["kn"]
parameter_values: [1,2,3]
Examples
__init__(yaml_file)
Construct the Input class.
get_from_input(map_list)
Get value of the input dict by using a list of stacked keys.
Source: https://stackoverflow.com/questions/14692690/.. ..access-nested-dictionary-items-via-a-list-
of-keys/37704379
set_in_input(map_list, value)
Change value of the input dict by using a list of stacked keys.
7.1. src 17
B.1. Solver Documentation 129
Examples
__init__(h5_file)
Construct the object.
This includes:
(1) Read mesh
(2) Read subdomains
(3) Read boudnaries
Parameters
• data (list of dicts) – Data to plot, see above for shape.
• output_folder (string) – output folder for PDF plot.
__init__(data, output_folder)
Construct postprocessor.
Only sets arguments
18 Chapter 7. Contents
130 B. Solver Related Data
plot_errors(show_popup)
Use matplotlib to plot all errors in a figure.
A slope marker is added.
Exporting PDFs with:
write_errors()
Write errors to a csv file.
The output file (e.g. error.csv) looks like:
h,p_L_2,p_l_inf,ux_L_2,ux_l_inf,uy_L_2,uy_l_inf,sigmaxx_L_2,...
0.9,0.2,0.2,0.1,0.1,0.2,0.1,0.2,0.5,0.2,0.3,0.2,0.5
0.6,0.1,0.1,0.0,0.1,0.1,0.1,0.0,0.3,0.0,0.3,0.0,0.3
Example
7.1. src 19
B.1. Solver Documentation 131
calculate_errors()
Calculate and return the errors of numerical to exact solution.
This includes all calculated fields.
Note: Usage of np.max() does not work in parallel. So convergence studies have to be performed in serial
for now. Final fields should be right, so MPI can be used for production simulations.
write_content_to_file(filename, content)
Write content to a file in the output folder.
write()
Write all solver data to separate folder.
This includes the writing of:
(1) Solutions
(2) Parameter functions
(3) System matrices if set in input file
_Solver__calc_field_errors(field_, field_e_, v_field, name_)
Calculate both 𝐿2 and 𝑙∞ errors.
Works for scalars, vectors and tensors. The difference is written to a file. The exact solution is written to a
file. Relative errors are based per field component and the maximum value of the analytical solution. If the
analytical solution is uniformly zero, then the absolute erorrs is used. (equivalent to setting the maximum
to 1)
Parameters
• field_ (DOLFIN function) – calculated field
• field_e_ (DOLFIN function) – exact solution of field
20 Chapter 7. Contents
132 B. Solver Related Data
Notes
For other norm types, see DOLFIN documentation1 and search for norms.
References
_Solver__calc_sf_mean(scalar_function)
Calculate the mean of a scalar function.
np.set_printoptions(precision=16)
# Precision is not soo nice, only 9 digits:
print(mean)
# In solve() has m. prec. hmmm:
print(self.__calc_sf_mean(self.sol["p"]))
Note: The following does not work in parallel because the mean is then only local. So convergence
studies have to be performed in serial:
mean = np.mean(scalar_function.compute_vertex_values())
_Solver__check_bcs()
Check if all boundaries from the input mesh have BCs prescribed.
Raises an exception if one BC is missing.
_Solver__createMacroExpr(cpp_string)
Return a DOLFIN expression with predefined macros.
These macros include:
1 DOLFIN documentation
7.1. src 21
B.1. Solver Documentation 133
_Solver__load_exact_solution()
Load exact solution from the location given in input.yml.
The exact solution must be C++ format with a specific syntax. The esol.cpp must contain the classes:
Class mode
Temperature heat or r13
Heatflux heat or r13
Pressure stress or r13
Velocity stress or r13
Stress stress or r13
The file has to follow a specific syntax for DOLFIN. An example file could look like:
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
#include <cmath>
// additional includes
#include <boost/math/special_functions/bessel.hpp>
using namespace std;
namespace py = pybind11;
#include <dolfin/function/Expression.h>
double lambda_3 = sqrt(3.0/2.0); // some own constants
class Temperature : public dolfin::Expression {
public:
Temperature() : dolfin::Expression() {}
void eval(Eigen::Ref<Eigen::VectorXd> values,
Eigen::Ref<const Eigen::VectorXd> x) const override {
values[0] = 1; // value
}
};
class Heatflux : public dolfin::Expression {
public:
Heatflux() : dolfin::Expression(2) {} // note components=2!
void eval(Eigen::Ref<Eigen::VectorXd> values,
Eigen::Ref<const Eigen::VectorXd> x) const override {
values[0] = 42;
values[1] = 3.14;
}
};
class Pressure : public dolfin::Expression {
public:
Pressure() : dolfin::Expression() {}
void eval(Eigen::Ref<Eigen::VectorXd> values,
Eigen::Ref<const Eigen::VectorXd> x) const override {
values[0] = boost::math::cyl_bessel_i(1,2.71); // external
}
(continues on next page)
22 Chapter 7. Contents
134 B. Solver Related Data
_Solver__setup_function_spaces()
Set up function spaces for trial and test functions for assembling.
Depends on the mode. Function spaces depend on the choice of the element and its degree (see the input
file input.Input).
The following DOLFIN functions are used:
7.1. src 23
B.1. Solver Documentation 135
_Solver__write_discrete_system()
Write the discrete system matrix and the RHS vector.
Can be used to analyze e.g. condition number. Include writing of A and b of Ax = b.
File-ending is .mat.
Import the matrices/vectors e.g. into Matlab with:
Example
24 Chapter 7. Contents
136 B. Solver Related Data
_Solver__write_parameters()
Write parameter functions for debug reasons.
This includes:
(1) Heat source as f_mass
(2) Mass Source as f_heat
The parameter functions are internally interpolated into a 𝑃1 space before writing.
_Solver__write_solutions()
Write all solutions fields.
_Solver__write_xdmf(name, field, write_pdf )
Write a given field to a XDMF file in the output folder.
Arguments
name The name to be given to the field. Will be used as filename and is the name of the field in e.g.
Paraview.
field The field to write.
write_pdf If true, write a simple PDF plot for all solution fields
tensoroperations.sym3d3(rank3_3d)
Return the symmetric part of a 3D 3-tensor.
Returns the symmetric part 𝐴(𝑖𝑗𝑘) of a 3D rank-3 tensor 𝐴 ∈ R3×3×3 [STR2005] [TOR2018].
1
𝐴(𝑖𝑗𝑘) = (𝐴𝑖𝑗𝑘 + 𝐴𝑖𝑘𝑗 + 𝐴𝑗𝑖𝑘 + 𝐴𝑗𝑘𝑖 + 𝐴𝑘𝑖𝑗 + 𝐴𝑘𝑗𝑖 )
6
7.1. src 25
B.1. Solver Documentation 137
tensoroperations.stf3d3(rank3_3d)
Return the symmetric and trace-free part of a 3D 3-tensor.
Return the symmetric and trace-free part of a 3D 3-tensor. (dev(sym(.)))
Returns the STF part 𝐴⟨𝑖𝑗𝑘⟩ of a rank-3 tensor 𝐴 ∈ R3×3×3 [TOR2018].
1 [︀ ]︀
𝐴⟨𝑖𝑗𝑘⟩ = 𝐴(𝑖𝑗𝑘) − 𝐴(𝑖𝑙) 𝛿𝑗𝑘 + 𝐴(𝑙𝑗𝑙) 𝛿𝑖𝑘 + 𝐴(𝑙𝑙𝑘) 𝛿𝑖𝑗
5
𝜕𝑆⟨𝑖𝑗
A gradient 𝜕𝑥𝑘⟩ of a symmetric 2-tensor 𝑆 ∈ R3×3 has the deviator [STR2005]:
(︂ )︂ [︂(︂ )︂
𝜕𝑆⟨𝑖𝑗 1 𝜕𝑆𝑖𝑗 𝜕𝑆𝑖𝑘 𝜕𝑆𝑗𝑘 1 𝜕𝑆𝑖𝑟 𝜕𝑆𝑖𝑟 𝜕𝑆𝑟𝑟
= + + − + + 𝛿𝑗𝑘
𝜕𝑥𝑘⟩ 3 𝜕𝑥𝑘 𝜕𝑥𝑗 𝜕𝑥𝑖 15 𝜕𝑥𝑟 𝜕𝑥𝑟 𝜕𝑥𝑖
(︂ )︂ (︂ )︂ ]︂
𝜕𝑆𝑗𝑟 𝜕𝑆𝑗𝑟 𝜕𝑆𝑟𝑟 𝜕𝑆𝑘𝑟 𝜕𝑆𝑘𝑟 𝜕𝑆𝑟𝑟
+ + + 𝛿𝑖𝑘 + + + 𝛿𝑖𝑗
𝜕𝑥𝑟 𝜕𝑥𝑟 𝜕𝑥𝑗 𝜕𝑥𝑟 𝜕𝑥𝑟 𝜕𝑥𝑘
tensoroperations.gen3dTF2(rank2_2d)
Generate a 3D tracefree 2-tensor from a 2D 2-tensor.
Returns the synthetic 3D version 𝐴 ∈ R3×3 of a 2D rank-2 tensor 𝐵 ∈ R2×2 .
(︂ )︂
𝑏 𝑏
𝐵 = 𝑥𝑥 𝑥𝑦
𝑏𝑦𝑥 𝑏𝑦𝑦
⎛ ⎞
𝑏𝑥𝑥 𝑏𝑥𝑦 0
𝐴 = ⎝𝑏𝑦𝑥 𝑏𝑦𝑦 0 ⎠
0 0 −(𝑏𝑦𝑥 + 𝑏𝑦𝑦 )
Example
tensoroperations.gen3d2(rank2_2d)
Generate a 3D 2-tensor from a 2D 2-tensor (add zeros to last dimensions).
Returns the synthetic 3D version 𝐴 ∈ R3×3 of a 2D rank-2 tensor 𝐵 ∈ R2×2 . The 3D-components are set to
zero.
(︂ )︂
𝑏 𝑏
𝐵 = 𝑥𝑥 𝑥𝑦
𝑏𝑦𝑥 𝑏𝑦𝑦
⎛ ⎞
𝑏𝑥𝑥 𝑏𝑥𝑦 0
𝐴 = 𝑏𝑦𝑥 𝑏𝑦𝑦 0⎠
⎝
0 0 0
26 Chapter 7. Contents
138 B. Solver Related Data
Example
tensoroperations.grad3dOf2(rank2_3d)
Return 3D gradient of 3D 2-tensor.
𝜕𝐴𝑖𝑗
Returns the 3D gradient (w.r.t. 𝑥, 𝑦, 𝑧) 𝜕𝑥𝑘 of a 3D 𝑧-independent rank-2 tensor 𝐴(𝑥, 𝑦) ∈ R3×3 where
⎛ ⎞
𝑎𝑥𝑥 (𝑥, 𝑦) 𝑎𝑥𝑦 (𝑥, 𝑦) 𝑎𝑥𝑧 (𝑥, 𝑦)
𝐴𝑖𝑗 = ⎝𝑎𝑦𝑥 (𝑥, 𝑦) 𝑎𝑦𝑦 (𝑥, 𝑦) 𝑎𝑦𝑧 (𝑥, 𝑦)⎠
𝑎𝑧𝑥 (𝑥, 𝑦) 𝑎𝑧𝑦 (𝑥, 𝑦) 𝑎𝑧𝑧 (𝑥, 𝑦)
𝜕𝐴𝑖𝑗
The function then returns the 3-tensor with components 𝜕𝑥𝑘 where
⎛ ⎞
𝜕𝑥 𝑎𝑥𝑥 (𝑥, 𝑦) 𝜕𝑥 𝑎𝑥𝑦 (𝑥, 𝑦) 𝜕𝑥 𝑎𝑥𝑧 (𝑥, 𝑦)
𝜕𝐴𝑖𝑗 𝜕𝐴𝑖𝑗
= = ⎝𝜕𝑥 𝑎𝑦𝑥 (𝑥, 𝑦) 𝜕𝑥 𝑎𝑦𝑦 (𝑥, 𝑦) 𝜕𝑥 𝑎𝑦𝑧 (𝑥, 𝑦)⎠ ,
𝜕𝑥1 𝜕𝑥
𝜕𝑥 𝑎𝑧𝑥 (𝑥, 𝑦) 𝜕𝑥 𝑎𝑧𝑦 (𝑥, 𝑦) 𝜕𝑥 𝑎𝑧𝑧 (𝑥, 𝑦)
⎛ ⎞
𝜕𝑦 𝑎𝑥𝑥 (𝑥, 𝑦) 𝜕𝑦 𝑎𝑥𝑦 (𝑥, 𝑦) 𝜕𝑦 𝑎𝑥𝑧 (𝑥, 𝑦)
𝜕𝐴𝑖𝑗 𝜕𝐴𝑖𝑗
= = ⎝𝜕𝑦 𝑎𝑦𝑥 (𝑥, 𝑦) 𝜕𝑦 𝑎𝑦𝑦 (𝑥, 𝑦) 𝜕𝑦 𝑎𝑦𝑧 (𝑥, 𝑦)⎠ ,
𝜕𝑥2 𝜕𝑦
𝜕𝑦 𝑎𝑧𝑥 (𝑥, 𝑦) 𝜕𝑦 𝑎𝑧𝑦 (𝑥, 𝑦) 𝜕𝑦 𝑎𝑧𝑧 (𝑥, 𝑦)
⎛ ⎞
0 0 0
𝜕𝐴𝑖𝑗
= 0 = 0 0 0⎠
⎝
𝜕𝑥3
0 0 0
7.2 heat
7.2. heat 27
B.1. Solver Documentation 139
run_solver(inputfile)
Run the solver as subprocess with the given input file.
Test fails if subprocess return Exception or error.
compare_errors(errorsfile, ref_errorsfile)
Check against reference errors. Compares absolute differences.
Absolute Error allowed: 1E-10 Return exception if diff returns with !=0 A comparison for complete
equalness can be obtained with:
subprocess.check_call([
"diff", "-u", "--strip-trailing-cr", errorsfile, ref_errorsfile
], cwd=self.working_dir)
create_meshes()
Create the test meshes. Executed before any test of the class.
Often not needed if meshes are in Git through LFS for reproducability.
test_heat_01_coeffs_p1p1_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
Formulation Coefficients
Elements 𝑃1 𝑃1
Stabilization CIP, 𝛿1 = 1
test_heat_10_coeffs_p2p2_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 10.0
Formulation Coefficients
Elements 𝑃2 𝑃2
Stabilization CIP, 𝛿1 = 1
test_heat_01_coeffs_p2p2_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
Formulation Coefficients
Elements 𝑃2 𝑃2
Stabilization CIP, 𝛿1 = 1
test_heat_01_coeffs_p1p2_nostab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
Formulation Coefficients
Elements 𝑃2 𝑃1
Stabilization CIP, 𝛿1 = 1
28 Chapter 7. Contents
140 B. Solver Related Data
test_heat_01_nocoeffs_p1p2_nostab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
Formulation No Coefficients
Elements 𝑃2 𝑃1
Stabilization CIP, 𝛿1 = 1
7.3 stress
create_meshes()
Create the test meshes. Executed before any test of the class.
Often not needed if meshes are in Git through LFS for reproducability.
test_stress_01_nosource_rot_p1p1p1_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
𝑓mass 0
𝑣𝑡1 10.0
Elements 𝑃1 𝑃1 𝑃1
Stabilization CIP, 𝛿2 = 1, 𝛿3 = 0.01
7.3. stress 29
B.1. Solver Documentation 141
test_stress_01_source_norot_p1p1p1_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
5𝑅2
𝑓mass 0.4(1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑣𝑡1 0
Elements 𝑃1 𝑃 1 𝑃1
Stabilization CIP, 𝛿2 = 1, 𝛿3 = 0.01
test_stress_01_source_rot_p1p1p1_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
5𝑅2
𝑓mass 0.4(1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑣𝑡1 10.0
Elements 𝑃1 𝑃 1 𝑃1
Stabilization CIP, 𝛿2 = 1, 𝛿3 = 0.01
test_stress_01_source_rot_p1p2p3_nostab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
5𝑅2
𝑓mass 0.4(1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑣𝑡1 10.0
Elements 𝑃1 𝑃 2 𝑃3
Stabilization CIP, 𝛿2 = 1, 𝛿3 = 0.01
test_stress_01_source_rot_p2p2p2_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 0.1
5𝑅2
𝑓mass 0.4(1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑣𝑡1 10.0
Elements 𝑃2 𝑃 2 𝑃2
Stabilization CIP, 𝛿2 = 1, 𝛿3 = 0.01
test_stress_10_source_rot_p1p1p1_stab()
Execute decoupled heat system test and check with reference errors.
Parameter Value
𝐾𝑛 10.0
5𝑅2
𝑓mass 0.4(1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑣𝑡1 10.0
Elements 𝑃1 𝑃 1 𝑃1
Stabilization CIP, 𝛿2 = 1, 𝛿3 = 0.01
30 Chapter 7. Contents
142 B. Solver Related Data
7.4 r13
subprocess.check_call([
"diff", "-u", "--strip-trailing-cr", errorsfile, ref_errorsfile
], cwd=self.working_dir)
create_meshes()
Create the test meshes. Executed before any test of the class.
Often not needed if meshes are in Git through LFS for reproducability.
test_r13_1_coeffs_sources_rot_noinflow_p1p1p1p1p1_stab()
Execute full linear R13 system test and check with reference errors.
Test case is similar to [WES2019].
7.4. r13 31
B.1. Solver Documentation 143
Parameter Value
𝐾𝑛 1.0
5𝑅2
𝑓mass (1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑓heat 0
1
𝜃𝑤 1.0
𝑣𝑡1 10.0
𝑣𝑛1 0
𝑝1𝑤 0
𝜖1𝑤 0
2
𝜃𝑤 0.5
𝑣𝑡2 0.0
𝑣𝑛2 0
𝑝2𝑤 0
𝜖2𝑤 0
Elements 𝑃1 𝑃1 𝑃1 𝑃1 𝑃1
Stabilization CIP: 𝛿1 , 𝛿2 = 1, 𝛿3 = 0.01
test_r13_1_coeffs_sources_rot_noinflow_p2p2p2p2p2_stab()
Execute full linear R13 system test and check with reference errors.
Test case is similar to [WES2019].
Parameter Value
𝐾𝑛 1.0
5𝑅2
𝑓mass (1 − 18𝐾𝑛 2 ) cos(𝜑)
𝑓heat 0
1
𝜃𝑤 1.0
𝑣𝑡1 10.0
𝑣𝑛1 0
𝑝1𝑤 0
𝜖1𝑤 0
2
𝜃𝑤 0.5
𝑣𝑡2 0.0
𝑣𝑛2 0
𝑝2𝑤 0
𝜖2𝑤 0
Elements 𝑃2 𝑃2 𝑃2 𝑃2 𝑃2
Stabilization CIP: 𝛿1 , 𝛿2 = 1, 𝛿3 = 0.01
test_r13_1_coeffs_nosources_norot_inflow_p1p1p1p1p1_stab()
Execute full linear R13 system test and check with reference errors.
Test case is similar to [TOR2017].
32 Chapter 7. Contents
144 B. Solver Related Data
Parameter Value
𝐾𝑛 1.0
𝑓mass 0
𝑓heat 0
1
𝜃𝑤 1.0
𝑣𝑡1 0
𝑣𝑛1 0
𝑝1𝑤 0
𝜖1𝑤 10−3
2
𝜃𝑤 2.0
𝑣𝑡2 −1.00 sin(𝜑)
𝑣𝑛2 +1.00 cos(𝜑)
𝑝2𝑤 −0.27 cos(𝜑)
𝜖2𝑤 103
Elements 𝑃1 𝑃1 𝑃1 𝑃1 𝑃1
Stabilization CIP: 𝛿1 , 𝛿2 = 1, 𝛿3 = 0.01
7.5 examples
7.5. examples 33
B.1. Solver Documentation 145
BIBLIOGRAPHY
[TOR2003] H Struchtrup, M Torrilhon (2003). Regularization of Grad’s 13 moment equations: derivation and linear
analysis.
[STR2005] Struchtrup, H. (2005). Macroscopic transport equations for rarefied gas flows. In Macroscopic Transport
Equations for Rarefied Gas Flows. Springer, Berlin, Heidelberg.
[TOR2018] Torrilhon, M. et al. (2018). “Kinetic Theory of Non-Equilibrium Gas Flows: Theory and Computations”.
Lecture Notes. Indian Institute of Technology Madras.
[WES2019] A. Westerkamp and M. Torrilhon. “Finite Element Methods for the Linear Regularized 13-Moment Equa-
tions Describing Slow Rarefied Gas Flows”. In: Journal of Computational Physics 389 (2019).
[TOR2017] Torrilhon, M. et al. (2017). “Hierarchical Boltzmann simulations and model error estimation”. In: Journal
of Computational Physics 342 (2017), pp. 66–84.
34
146 B. Solver Related Data
f
fenicsR13, 14
i
input, 14
m
meshes, 17
p
postprocessor, 18
s
solver, 19
t
tensoroperations, 25
test_examples, 33
test_heat_convergence, 27
test_r13_convergence, 31
test_stress_convergence, 29
35
B.1. Solver Documentation 147
INDEX
Symbols
_Solver__calc_field_errors() (solver.Solver method), 20
_Solver__calc_sf_mean() (solver.Solver method), 21
_Solver__check_bcs() (solver.Solver method), 21
_Solver__createMacroExpr() (solver.Solver method), 21
_Solver__load_exact_solution() (solver.Solver method), 22
_Solver__setup_function_spaces() (solver.Solver method), 23
_Solver__write_discrete_system() (solver.Solver method), 24
_Solver__write_parameters() (solver.Solver method), 25
_Solver__write_solutions() (solver.Solver method), 25
_Solver__write_xdmf() (solver.Solver method), 25
__init__() (input.Input method), 17
__init__() (meshes.H5Mesh method), 18
__init__() (postprocessor.Postprocessor method), 18
__init__() (solver.Solver method), 19
A
assemble() (solver.Solver method), 20
C
calculate_errors() (solver.Solver method), 20
compare_errors() (test_heat_convergence.TestHeatConvergence method), 28
compare_errors() (test_r13_convergence.TestR13Convergence method), 31
compare_errors() (test_stress_convergence.TestStressConvergence method), 29
create_meshes() (test_examples.TestExamples method), 33
create_meshes() (test_heat_convergence.TestHeatConvergence method), 28
create_meshes() (test_r13_convergence.TestR13Convergence method), 31
create_meshes() (test_stress_convergence.TestStressConvergence method), 29
F
fenicsR13 (module), 14
G
gen3d2() (in module tensoroperations), 26
gen3dTF2() (in module tensoroperations), 26
get_from_input() (input.Input method), 17
grad3dOf2() (in module tensoroperations), 27
H
H5Mesh (class in meshes), 17
36
148 B. Solver Related Data
I
Input (class in input), 14
input (module), 14
M
main() (in module fenicsR13), 14
meshes (module), 17
P
params (solver.Solver attribute), 20
plot_errors() (postprocessor.Postprocessor method), 19
Postprocessor (class in postprocessor), 18
postprocessor (module), 18
print_information() (in module fenicsR13), 14
R
run_solver() (test_examples.TestExamples method), 33
run_solver() (test_heat_convergence.TestHeatConvergence method), 27
run_solver() (test_r13_convergence.TestR13Convergence method), 31
run_solver() (test_stress_convergence.TestStressConvergence method), 29
S
set_in_input() (input.Input method), 17
solve() (solver.Solver method), 20
Solver (class in solver), 19
solver (module), 19
solver_path (test_examples.TestExamples attribute), 33
solver_path (test_heat_convergence.TestHeatConvergence attribute), 27
solver_path (test_r13_convergence.TestR13Convergence attribute), 31
solver_path (test_stress_convergence.TestStressConvergence attribute), 29
stf3d2() (in module tensoroperations), 25
stf3d3() (in module tensoroperations), 25
sym3d3() (in module tensoroperations), 25
T
tensoroperations (module), 25
test_channel_flow() (test_examples.TestExamples method), 33
test_examples (module), 33
test_heat_01_coeffs_p1p1_stab() (test_heat_convergence.TestHeatConvergence method), 28
test_heat_01_coeffs_p1p2_nostab() (test_heat_convergence.TestHeatConvergence method), 28
test_heat_01_coeffs_p2p2_stab() (test_heat_convergence.TestHeatConvergence method), 28
test_heat_01_nocoeffs_p1p2_nostab() (test_heat_convergence.TestHeatConvergence method), 29
test_heat_10_coeffs_p2p2_stab() (test_heat_convergence.TestHeatConvergence method), 28
test_heat_convergence (module), 27
test_knudsen_pump() (test_examples.TestExamples method), 33
test_lid_driven_cavity() (test_examples.TestExamples method), 33
test_r13_1_coeffs_nosources_norot_inflow_p1p1p1p1p1_stab()
(test_r13_convergence.TestR13Convergence method), 32
test_r13_1_coeffs_sources_rot_noinflow_p1p1p1p1p1_stab() (test_r13_convergence.TestR13Convergence
method), 31
test_r13_1_coeffs_sources_rot_noinflow_p2p2p2p2p2_stab() (test_r13_convergence.TestR13Convergence
method), 32
test_r13_convergence (module), 31
Index 37
B.1. Solver Documentation 149
test_stress_01_nosource_rot_p1p1p1_stab() (test_stress_convergence.TestStressConvergence
method), 29
test_stress_01_source_norot_p1p1p1_stab() (test_stress_convergence.TestStressConvergence
method), 29
test_stress_01_source_rot_p1p1p1_stab() (test_stress_convergence.TestStressConvergence method),
30
test_stress_01_source_rot_p1p2p3_nostab() (test_stress_convergence.TestStressConvergence
method), 30
test_stress_01_source_rot_p2p2p2_stab() (test_stress_convergence.TestStressConvergence method),
30
test_stress_10_source_rot_p1p1p1_stab() (test_stress_convergence.TestStressConvergence method),
30
test_stress_convergence (module), 29
TestExamples (class in test_examples), 33
TestHeatConvergence (class in test_heat_convergence), 27
TestR13Convergence (class in test_r13_convergence), 31
TestStressConvergence (class in test_stress_convergence), 29
W
working_dir (test_heat_convergence.TestHeatConvergence attribute), 27
working_dir (test_r13_convergence.TestR13Convergence attribute), 31
working_dir (test_stress_convergence.TestStressConvergence attribute), 29
write() (solver.Solver method), 20
write_content_to_file() (solver.Solver method), 20
write_errors() (postprocessor.Postprocessor method), 19
38 Index
150 B. Solver Related Data
83 solver = None
84 gc.collect()
85
86 if __name__ == ’__main__’:
87 main()
77 "required": True,
78 },
79 "mass_source": {
80 "anyof": [{"type": "string"}, {"type": "float"}],
81 "required": True,
82 },
83 "postprocessing": {
84 "type": "dict",
85 "required": True,
86 "schema": {
87 "write_pdfs": {
88 "type": "boolean",
89 "required": True
90 },
91 "massflow": {
92 "type": "list",
93 "required": True,
94 "schema": {"type": "integer"}
95 },
96 }
97 },
98 "parameter_study": {
99 "type": "dict",
100 "required": True,
101 "schema": {
102 "enable": {
103 "type": "boolean",
104 "required": True
105 },
106 "parameter_key": {
107 "type": "list",
108 "required": True,
109 },
110 "parameter_values": {
111 "type": "list",
112 "required": True,
113 },
114 }
115 },
116 "convergence_study": {
117 "type": "dict",
118 "required": True,
119 "schema": {
120 "enable": {
121 "type": "boolean",
122 "required": True
123 },
124 "exact_solution": {
125 "type": "string",
126 "required": True
127 },
128 "plot": {
129 "type": "boolean",
130 "required": True
131 },
132 "write_systemmatrix": {
133 "type": "boolean",
134 "required": True
135 },
136 "rescale_pressure": {
137 "type": "boolean",
138 "required": True
139 },
140 "relative_error": {
141 "type": "boolean",
142 "required": True
143 },
144 }
145 },
146 "output_folder": {
147 "type": "string",
148 "required": True,
149 },
150 "stabilization": {
151 "type": "dict",
152 "required": True,
153 "keysrules": {"type": "string", "regex": "cip"},
154 "valuesrules": {
155 "type": "dict",
156 "schema": {
157 "enable": {
158 "type": "boolean",
159 "required": True
160 },
161 "delta_1": {
B.2. Solver Source Code 153
247 },
248 "degree": {
249 "type": "integer",
250 "required": True,
251 "min": 0
252 }
253 }
254 },
255 }
256 }
257 }
258
259 if not val.validate(self.dict, input_schema):
260 print(val.errors)
261 raise Exception("Parsing error")
262
263 print("Input:\n" + dumps(self.dict, indent=None))
264
265 def get_from_input(self, map_list):
266 try:
267 return reduce(operator.getitem, map_list, self.dict)
268 except:
269 raise Exception("Dict has no entry with the key:", map_list)
270
271 def set_in_input(self, map_list, value):
272 self.get_from_input(map_list[:-1])[map_list[-1]] = value
1 """
2 Module to store the mesh classes.
3
4 Currently, the only mesh format is h5.
5 """
6
7 import os
8 import dolfin as df
9
10 class H5Mesh:
11
12 def __init__(self, h5_file):
13 if not os.path.isfile(h5_file):
14 raise Exception(f"{h5_file} not found")
15
16 self.mesh = df.Mesh()
17
18 hdf = df.HDF5File(self.mesh.mpi_comm(), h5_file, "r")
19
20 hdf.read(self.mesh, "/mesh", False)
21 dim = self.mesh.topology().dim()
22
23 self.subdomains = df.MeshFunction("size_t", self.mesh, dim)
24 hdf.read(self.subdomains, "/subdomains")
25
26 self.boundaries = df.MeshFunction("size_t", self.mesh, dim - 1)
27 hdf.read(self.boundaries, "/boundaries")
1 # pylint: disable=invalid-name
2
3 """
4 Module to store the postprocessor classes.
5
6 Currently, only Psotprocessor class present.
7 """
8
9 from itertools import chain
10
11 import csv
12 from math import sqrt, ceil, log, log10
13 import numpy as np
14 import matplotlib.pyplot as plt
15
16 class Postprocessor:
17
18 def __init__(self, data, output_folder):
19 self.data = data
20 self.output_folder = output_folder
21
22 def plot_errors(self, show_popup):
B.2. Solver Source Code 155
108
109 with open(output_path, mode=’w’) as file:
110 print("Write {}".format(output_path))
111 writer = csv.writer(file, delimiter=’,’, quotechar=’"’)
112
113 # header
114 writer.writerow(
115 ["h"] + list(
116 chain.from_iterable([
117 [first+"_"+second for second in data[0].get(first, "")]
118 for first in [
119 first for first in data[0] if first != "h"
120 ]
121 ])
122 )
123 )
124
125 # data of all runs
126 for run in data:
127 writer.writerow(
128 [run["h"]] + list(chain.from_iterable([
129 [run[field]["L_2"], run[field]["l_inf"]]
130 for field in [f for f in run if f != "h"]
131 ]))
132 )
1 import os
2 import copy
3 import time as time_module
4 import dolfin as df
5 import ufl
6 import numpy as np
7 import tensoroperations as to
8
9
10 class Solver:
11
12 def __init__(self, params, mesh, time):
13 """Initialize solver and setup variables from input parameters."""
14 self.params = params #: Doctest
15 self.mesh = mesh.mesh
16 self.boundaries = mesh.boundaries
17 self.cell = self.mesh.ufl_cell()
18 self.time = time
19 self.mode = params["mode"]
20 self.use_coeffs = params["use_coeffs"]
21 self.kn = params["kn"]
22 self.xi_tilde = params["xi_tilde"]
23 self.use_cip = self.params["stabilization"]["cip"]["enable"]
24 self.delta_1 = self.params["stabilization"]["cip"]["delta_1"]
25 self.delta_2 = self.params["stabilization"]["cip"]["delta_2"]
26 self.delta_3 = self.params["stabilization"]["cip"]["delta_3"]
27
28 self.write_pdfs = self.params["postprocessing"]["write_pdfs"]
29 self.massflow = self.params["postprocessing"]["massflow"]
30
31 # Create boundary field and sources expressions
32 self.bcs = copy.deepcopy(self.params["bcs"])
33 for edge_id in self.bcs:
34 for field in self.bcs[edge_id].keys():
35 self.bcs[edge_id][field] = self.__createMacroExpr(
36 self.bcs[edge_id][field]
37 )
38 self.heat_source = self.__createMacroExpr(self.params["heat_source"])
39 self.mass_source = self.__createMacroExpr(self.params["mass_source"])
40
41 self.exact_solution = self.params["convergence_study"]["exact_solution"]
42 self.write_systemmatrix = self.params["convergence_study"][
43 "write_systemmatrix"
44 ]
45 self.rescale_p = self.params["convergence_study"]["rescale_pressure"]
46 self.relative_error = self.params["convergence_study"][
47 "relative_error"
48 ]
49 self.output_folder = self.params["output_folder"] + "/"
50 self.var_ranks = {
51 "theta": 0,
52 "s": 1,
53 "p": 0,
54 "u": 1,
55 "sigma": 2,
56 }
B.2. Solver Source Code 157
57 self.elems = {
58 "theta": None,
59 "s": None,
60 "p": None,
61 "u": None,
62 "sigma": None,
63 }
64 self.fspaces = {
65 "theta": None,
66 "s": None,
67 "p": None,
68 "u": None,
69 "sigma": None,
70 }
71 self.mxd_elems = {
72 "heat": None,
73 "stress": None,
74 "r13": None,
75 }
76 self.mxd_fspaces = {
77 "heat": None,
78 "stress": None,
79 "r13": None,
80 }
81 self.form_a = None
82 self.form_b = None
83 self.sol = {
84 "theta": None,
85 "s": None,
86 "p": None,
87 "u": None,
88 "sigma": None,
89 }
90 self.esol = {
91 "theta": None,
92 "s": None,
93 "p": None,
94 "u": None,
95 "sigma": None,
96 }
97 self.errors = {}
98
99 def __createMacroExpr(self, cpp_string):
100 R = df.Expression("sqrt(pow(x[0],2)+pow(x[1],2))", degree=2)
101 phi = df.Expression("atan2(x[1],x[0])", degree=2)
102 kn = self.kn
103 return df.Expression(
104 str(cpp_string),
105 degree=2,
106 kn=kn,
107 phi=phi,
108 R=R
109 )
110
111 def __setup_function_spaces(self):
112 # Setup elements for all fields
113 cell = self.cell
114 msh = self.mesh
115 for var in self.elems:
116 e = self.params["elements"][var]["shape"]
117 deg = self.params["elements"][var]["degree"]
118 if self.var_ranks[var] == 0:
119 self.elems[var] = df.FiniteElement(e, cell, deg)
120 elif self.var_ranks[var] == 1:
121 self.elems[var] = df.VectorElement(e, cell, deg)
122 elif self.var_ranks[var] == 2:
123 self.elems[var] = df.TensorElement(e, cell, deg, symmetry=True)
124 self.fspaces[var] = df.FunctionSpace(msh, self.elems[var])
125
126 # Bundle elements per mode into ‘mxd_elems‘ dict
127 # 1) heat
128 heat_elems = [self.elems["theta"], self.elems["s"]]
129 self.mxd_elems["heat"] = df.MixedElement(heat_elems)
130 self.mxd_fspaces["heat"] = df.FunctionSpace(
131 msh, self.mxd_elems["heat"]
132 )
133 # 2) stress
134 stress_elems = [self.elems["p"], self.elems["u"], self.elems["sigma"]]
135 self.mxd_elems["stress"] = df.MixedElement(stress_elems)
136 self.mxd_fspaces["stress"] = df.FunctionSpace(
137 msh, self.mxd_elems["stress"]
138 )
139 # 3) r13
140 r13_elems = heat_elems + stress_elems
141 self.mxd_elems["r13"] = df.MixedElement(r13_elems)
158 B. Solver Related Data
227 + (
228 + 5/(4*xi_tilde) * s_n
229 - cpl * 5/8 * sigma_nn
230 # + cpl * sigma_nn # SAME RESULTS
231 ) * r_n
232 + (
233 + 11/10 * xi_tilde * s_t
234 + cpl * 1/10 * xi_tilde * s_t
235 - cpl * 1/2 * sigma_nt
236 # + cpl * sigma_nt # SAME RESULTS
237 ) * r_t
238 ) * df.ds
239 l1 = sum([
240 - 5.0/2.0 * r_n * bcs[bc]["theta_w"] * df.ds(bc)
241 for bc in bcs.keys()
242 ])
243
244 a2 = - (df.div(s) * kappa) * df.dx
245 l2 = - (f_heat * kappa) * df.dx
246
247 a3 = (
248 + 2 * kn * df.inner(
249 to.stf3d3(to.grad3dOf2(to.gen3dTF2(sigma))),
250 to.grad3dOf2(to.gen3dTF2(psi))
251 )
252 + (1/kn) * df.inner(to.gen3dTF2(sigma), to.gen3dTF2(psi))
253 - 2 * df.dot(u, df.div(psi))
254 + cpl * 4/5 * df.inner(to.stf3d2(df.grad(s)), psi)
255 ) * df.dx + (
256 + (
257 + 21/10 * xi_tilde * sigma_nn
258 + cpl * 3/20 * xi_tilde * sigma_nn
259 - cpl * 3/10 * s_n
260 ) * psi_nn
261 + 2 * xi_tilde * (
262 (sigma_tt + (1/2)*sigma_nn)*(psi_tt + (1/2)*psi_nn)
263 )
264 + (
265 + (2/xi_tilde) * sigma_nt
266 - cpl * 2/5 * s_t
267 ) * psi_nt
268 ) * df.ds + 2 * sum([
269 bcs[bc]["epsilon_w"] * (p + sigma_nn) * psi_nn * df.ds(bc)
270 for bc in bcs.keys()
271 ])
272 l3 = sum([
273 - 2.0 * psi_nt * bcs[bc]["u_t_w"] * df.ds(bc)
274 - 2.0 * (
275 - bcs[bc]["epsilon_w"] * bcs[bc]["p_w"]
276 + bcs[bc]["u_n_w"]
277 ) * psi_nn * df.ds(bc)
278 for bc in bcs.keys()
279 ])
280
281 a4 = (
282 + df.dot(df.div(sigma), v)
283 + df.dot(df.grad(p), v)
284 ) * df.dx
285 l4 = + df.Constant(0) * df.div(v) * df.dx
286
287 a5 = + (
288 df.dot(u, df.grad(q))
289 ) * df.dx - sum([
290 bcs[bc]["epsilon_w"] * (p + sigma_nn) * q * df.ds(bc)
291 for bc in bcs.keys()
292 ])
293 l5 = - (f_mass * q) * df.dx + sum([
294 (
295 - bcs[bc]["epsilon_w"] * bcs[bc]["p_w"]
296 + bcs[bc]["u_n_w"]
297 ) * q * df.ds(bc)
298 for bc in bcs.keys()
299 ])
300 else:
301 a1 = (
302 kn * df.inner(to.stf3d2(df.grad(s)), df.grad(r))
303 + (1/kn) * df.inner(s, r)
304 - theta * df.div(r)
305 ) * df.dx + (
306 + 1/(xi_tilde) * s_n * r_n
307 + xi_tilde * s_t * r_t
308 ) * df.ds
309 a2 = - (df.div(s) * kappa) * df.dx
310 l1 = sum([
311 - 1 * r_n * bcs[bc]["theta_w"] * df.ds(bc)
160 B. Solver Related Data
567
568 # Mass source
569 f_mass = df.interpolate(self.mass_source, V)
570 self.__write_xdmf("f_mass", f_mass, False)
571
572 def __write_discrete_system(self):
573 file_ending = ".mat"
574 np.savetxt(
575 self.output_folder + "A_{}".format(self.time) + file_ending,
576 df.assemble(self.form_a).array()
577 )
578 np.savetxt(
579 self.output_folder + "b_{}".format(self.time) + file_ending,
580 df.assemble(self.form_b)
581 )
582
583 def __write_xdmf(self, name, field, write_pdf):
584 fname_xdmf = (
585 self.output_folder + name + "_" + str(self.time) + ".xdmf"
586 )
587 with df.XDMFFile(self.mesh.mpi_comm(), fname_xdmf) as file:
588 for degree in range(5): # test until degree five
589 # Writing symmetric tensors crashes.
590 # Therefore project symmetric tensor in nonsymmetric space
591 # This is only a temporary fix, see:
592 # https://fenicsproject.discourse.group/t/...
593 # ...writing-symmetric-tensor-function-fails/1136
594 el_symm = df.TensorElement(
595 df.FiniteElement(
596 "Lagrange", df.triangle, degree+1
597 ), symmetry=True
598 ) # symmetric tensor element
599 el_sol = field.ufl_function_space().ufl_element()
600 if el_sol == el_symm:
601 # Remove symmetry with projection
602 field = df.project(
603 field, df.TensorFunctionSpace(
604 self.mesh, "Lagrange", degree+1
605 )
606 )
607 break
608
609 field.rename(name, name)
610
611 print("Write {}".format(fname_xdmf))
612 file.write(field, self.time)
613
614 if write_pdf:
615 import matplotlib.pyplot as plt
616 plt.switch_backend(’agg’)
617 dimension = len(field.value_shape())
618
619 if dimension < 2:
620 # skip tensors
621 fname_pdf = (
622 self.output_folder + name + "_" + str(self.time) + ".pdf"
623 )
624 plot = df.plot(field)
625 plt.colorbar(plot)
626 plt.xlabel("x")
627 plt.ylabel("y")
628 plt.title(field)
629 print("Write {}".format(fname_pdf))
630 plt.savefig(fname_pdf, dpi=150)
631 plt.close()
632
633 if dimension > 0:
634 # skip scalars
635 components = len(field.split())
636 indexMap = {
637 1: {
638 1: "x",
639 2: "y"
640 },
641 2: {
642 1: "xx",
643 2: "xy",
644 3: "yx",
645 4: "yy",
646 }
647 }
648 for i in range(components):
649 fieldname = name + "_" + str(indexMap[dimension][i+1])
650 fname_pdf = (
651 self.output_folder + fieldname
164 B. Solver Related Data
1 import dolfin as df
2 import ufl
3
4 def stf3d2(rank2_2d):
5 symm = 1/2 * (rank2_2d + ufl.transpose(rank2_2d))
6 return (
7 symm
8 - (1/3) * ufl.tr(symm) * ufl.Identity(2)
9 )
10
11 def sym3d3(rank3_3d):
12 i, j, k = ufl.indices(3)
13 symm_ijk = 1/6 * (
14 # all permutations
15 + rank3_3d[i, j, k]
16 + rank3_3d[i, k, j]
17 + rank3_3d[j, i, k]
18 + rank3_3d[j, k, i]
19 + rank3_3d[k, i, j]
20 + rank3_3d[k, j, i]
21 )
22 return ufl.as_tensor(symm_ijk, (i, j, k))
23
24 def stf3d3(rank3_3d):
25 i, j, k, l = ufl.indices(4)
26 delta = df.Identity(3)
27
28 sym_ijk = sym3d3(rank3_3d)[i, j, k]
29 traces_ijk = 1/5 * (
30 + sym3d3(rank3_3d)[i, l, l] * delta[j, k]
31 + sym3d3(rank3_3d)[l, j, l] * delta[i, k]
32 + sym3d3(rank3_3d)[l, l, k] * delta[i, j]
33 )
34 tracefree_ijk = sym_ijk - traces_ijk
35 return ufl.as_tensor(tracefree_ijk, (i, j, k))
36
37 def gen3dTF2(rank2_2d):
38 return df.as_tensor([
39 [rank2_2d[0, 0], rank2_2d[0, 1], 0],
40 [rank2_2d[1, 0], rank2_2d[1, 1], 0],
41 [0, 0, -rank2_2d[0, 0]-rank2_2d[1, 1]]
42 ])
43
44 def gen3d2(rank2_2d):
45 return df.as_tensor([
46 [rank2_2d[0, 0], rank2_2d[0, 1], 0],
47 [rank2_2d[1, 0], rank2_2d[1, 1], 0],
48 [0, 0, 0]
49 ])
50
51 def grad3dOf2(rank2_3d):
52 grad2d = df.grad(rank2_3d)
53 dim3 = df.as_tensor([
54 [0, 0, 0],
55 [0, 0, 0],
56 [0, 0, 0],
57 ])
58 grad3d = df.as_tensor([
59 grad2d[:, :, 0], # pylint: disable=unsubscriptable-object
60 grad2d[:, :, 1], # pylint: disable=unsubscriptable-object
61 dim3[:, :]
62 ])
63 return grad3d
1 output_folder: results_channel_flow
166 C. Solver Input Files for Application Cases
2 meshes:
3 - channel5.h5
4 elements:
5 theta:
6 shape: Lagrange
7 degree: 1
8 s:
9 shape: Lagrange
10 degree: 1
11 p:
12 shape: Lagrange
13 degree: 1
14 u:
15 shape: Lagrange
16 degree: 1
17 sigma:
18 shape: Lagrange
19 degree: 1
20 stabilization:
21 cip:
22 enable: True
23 delta_1: 1.0
24 delta_2: 1.0
25 delta_3: 0.1
26 nsd: 2
27 mode: r13
28 use_coeffs: True
29 kn: 1.0
30 xi_tilde: 1.0
31 heat_source: 0
32 mass_source: 0
33 bcs:
34 3001: # bot
35 theta_w: 1
36 u_t_w: 0
37 u_n_w: 0
38 p_w: 0
39 epsilon_w: pow(10,-3)
40 3002: # right
41 theta_w: 1
42 u_t_w: 0
43 u_n_w: 0
44 p_w: 0
45 epsilon_w: pow(10,+3)
46 3003: # top
47 theta_w: 1
48 u_t_w: 0
49 u_n_w: 0
50 p_w: 0
51 epsilon_w: pow(10,-3)
52 3004: # left
53 theta_w: 1
54 u_t_w: 0
55 u_n_w: 0
56 p_w: 1
57 epsilon_w: pow(10,+3)
58 convergence_study:
59 enable: False
60 exact_solution: esols/01_coeffs.cpp
61 plot: False # to avoid error exit code due to $DISPLAY
62 write_systemmatrix: False
63 rescale_pressure: True
64 relative_error: True
65 postprocessing:
66 write_pdfs: True
67 massflow: [3002]
68 parameter_study:
69 enable: True
70 parameter_key: ["kn"]
71 parameter_values: [0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4,
1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
1 output_folder: results_knudsen_pump
2 meshes:
3 - knudsen_pump3.h5
4 elements:
5 theta:
6 shape: Lagrange
7 degree: 1
8 s:
9 shape: Lagrange
10 degree: 1
167
11 p:
12 shape: Lagrange
13 degree: 1
14 u:
15 shape: Lagrange
16 degree: 1
17 sigma:
18 shape: Lagrange
19 degree: 1
20 stabilization:
21 cip:
22 enable: True
23 delta_1: 1.0
24 delta_2: 1.0
25 delta_3: 0.1
26 nsd: 2
27 mode: r13
28 use_coeffs: True
29 kn: 0.1
30 xi_tilde: 1.0
31 heat_source: 0
32 mass_source: 0
33 bcs:
34 3010: # inner top
35 theta_w: x[0]/1.0
36 u_t_w: 0
37 u_n_w: 0
38 p_w: 0
39 epsilon_w: 0
40 3011: # inner left
41 theta_w: -(atan2(x[1],-(x[0]+1.0)))/(M_PI/2.0)
42 u_t_w: 0
43 u_n_w: 0
44 p_w: 0
45 epsilon_w: 0
46 3012: # inner bottom
47 theta_w: -x[0]/1.0
48 u_t_w: 0
49 u_n_w: 0
50 p_w: 0
51 epsilon_w: 0
52 3013: # inner right
53 theta_w: (atan2(x[1],(x[0]-1.0)))/(M_PI/2.0)
54 u_t_w: 0
55 u_n_w: 0
56 p_w: 0
57 epsilon_w: 0
58 3020: # outer top
59 theta_w: x[0]/1.0
60 u_t_w: 0
61 u_n_w: 0
62 p_w: 0
63 epsilon_w: 0
64 3021: # outer left
65 theta_w: -(atan2(x[1],-(x[0]+1.0)))/(M_PI/2.0)
66 u_t_w: 0
67 u_n_w: 0
68 p_w: 0
69 epsilon_w: 0
70 3022: # outer bottom
71 theta_w: -x[0]/1.0
72 u_t_w: 0
73 u_n_w: 0
74 p_w: 0
75 epsilon_w: 0
76 3023: # outer right
77 theta_w: (atan2(x[1],(x[0]-1.0)))/(M_PI/2.0)
78 u_t_w: 0
79 u_n_w: 0
80 p_w: 0
81 epsilon_w: 0
82 convergence_study:
83 enable: False
84 exact_solution: esols/01_coeffs.cpp
85 plot: False # to avoid error exit code due to $DISPLAY
86 write_systemmatrix: False
87 rescale_pressure: True
88 relative_error: True
89 postprocessing:
90 write_pdfs: True
91 massflow: []
92 parameter_study:
93 enable: False
94 parameter_key: []
95 parameter_values: []
168 C. Solver Input Files for Application Cases
Listing D.1 FEniCS demo program to solve the Poisson problem using linear P1 elements
(demo_poisson.py in [14, 18]).
Listing D.2 FEniCS demo program to solve the Stokes problem using Taylor–Hood elements
P2 P1 (demo_stokes-taylor-hood.py in [15, 18]).
Bibliography
[1] D. Abel. Regelungstechnik und Ergänzungen (Höhere Regelungstechnik). Um-
druck zur Vorlesung. Verlag Mainz, 2018. URL: https : / / www . verlag -
mainz . de / regelungstechnik - und - erg % C3 % A4nzungen - h % C3 % B6here -
regelungstechnik.html (visited on 09/10/2019).
[2] M. S. Alnæs, A. Logg, K. B. Ølgaard, M. E. Rognes, and G. N. Wells. “Unified
Form Language: A Domain-Specific Language for Weak Formulations of Partial
Differential Equations”. In: ACM Transactions on Mathematical Software
(TOMS) 40.2 (2014), p. 9. URL: https : / / doi . org / 10 . 1145 / 1731022 .
1731030 (visited on 08/28/2019).
[3] M. Alnæs, J. Blechta, J. Hake, A. Johansson, B. Kehlet, A. Logg, C. Richardson,
J. Ring, M. E. Rognes, and G. N. Wells. “The FEniCS Project Version 1.5”.
In: Archive of Numerical Software 3.100 (2015). URL: https://doi.org/10.
11588/ans.2015.100.20553 (visited on 08/21/2019).
[4] K. Aoki, P. Degond, L. Mieussens, M. Nishioka, and S. Takata. “Numerical
Simulation of a Knudsen Pump Using the Effect of Curvature of the Channel”.
In: Rarefied Gas Dynamics (2007), pp. 1079–1084. URL: https : / / www .
math.u- bordeaux.fr/~lmieusse/PAGE_WEB/PUBLICATIONS/2007/admnt-
final.pdf (visited on 09/13/2019).
[5] D. N. Arnold and A. Logg. “Periodic Table of the Finite Elements”. In: SIAM
News 47.9 (2014), pp. 1, 8–9. URL: https://sinews.siam.org/Current-
Issue/Issue-Archives/Issue-Archives-ListView/PID/2282/mcat/2279/
evl/0/TagID/247?TagName=Volume-47-%7C-Number-9-%7C-November-2014
(visited on 08/21/2019).
[6] M. Behr. “Finite Elements in Fluids”. Lecture Notes WS18/19. RWTH
Aachen University, 2018. URL: https : / / www . cats . rwth - aachen . de /
cms/CATS/Studium/Lehre/Wintersemester/~ogqr/Finite- Elemente- in-
Fluiddynamik/?lidx=1 (visited on 09/03/2019).
[7] R. B. Bird, W. E. S. Stewart, and E. N. Lightfoot. Transport Phenom-
ena. John Wiley & Sons, 2006. URL: https : / / www . wiley . com / en -
us / Transport + Phenomena % 2C + Revised + 2nd + Edition - p - 9780470115398
(visited on 08/25/2019).
172 Bibliography
[39] I. Müller and T. Ruggeri. Rational Extended Thermodynamics. 2nd ed. Vol. 37.
Springer Tracts in Natural Philosophy. Springer-Verlag New York, 1998. URL:
https://doi.org/10.1007/978-1-4612-2210-1 (visited on 08/25/2019).
[40] K. Müller. “Computing Rarefied External Flows Using Extended Fluid Dynam-
ics”. Diploma Thesis. Swiss Federal Institute of Technology Zurich (ETH
Zürich), 2010. URL: http : / / www . csc . kth . se / ~kasparm / #outline -
container-sec-4 (visited on 08/30/2019).
[41] R. Rajput. Thermal Engineering. Laxmi Publications Pvt Limited, 2010.
URL: https : / / books . google . de / books ? id = 65gxCX2dC84C (visited on
08/25/2019).
[42] A. S. Rana and H. Struchtrup. “Thermodynamically Admissible Boundary
Conditions for the Regularized 13 Moment Equations”. In: Physics of Fluids
28.2 (2016), p. 027105. URL: https://doi.org/10.1063/1.4941293 (visited
on 09/10/2019).
[43] A. Rana, M. Torrilhon, and H. Struchtrup. “A Robust Numerical Method
for the R13 Equations of Rarefied Gas Dynamics: Application to Lid Driven
Cavity”. In: Journal of Computational Physics 236 (2013), pp. 169–186. URL:
https://doi.org/10.1016/j.jcp.2012.11.023 (visited on 08/25/2019).
[44] F. Rathgeber, D. A. Ham, L. Mitchell, M. Lange, F. Luporini, A. T. McRae,
G.-T. Bercea, G. R. Markall, and P. H. Kelly. “Firedrake: Automating the
Finite Element Method by Composing Abstractions”. In: ACM Transactions
on Mathematical Software (TOMS) 43.3 (2017), p. 24. URL: https://doi.
org/10.1145/2998441 (visited on 08/28/2019).
[45] C. N. Richardson and G. N. Wells. Parallel Scaling of DOLFIN on ARCHER.
2015. URL: https://doi.org/10.6084/m9.figshare.1304537.v1 (visited
on 08/28/2019).
[46] Roadmap 2019–2020. FEniCS Project, 2019. URL: https://fenicsproject.
org/fenics-project-roadmap-2019/ (visited on 08/28/2019).
[47] H. Schade and K. Neemann. Tensoranalysis. De Gruyter Lehrbuch. De Gruyter,
2009. URL: https://www.degruyter.com/viewbooktoc/product/40403
(visited on 08/25/2019).
[48] R. Schärer. “Entropy-Based Moment Closures for Rarefied Gases and Plasmas”.
PhD Thesis. RWTH Aachen University, 2016. URL: http://www.mathcces.
rwth-aachen.de/3teaching/00projects/archive (visited on 08/24/2019).
[49] B. Stamm. “Stabilization Strategies for Discontinuous Galerkin Methods”. PhD
Thesis. Lausanne: IACS, 2008. URL: http://dx.doi.org/10.5075/epfl-
thesis-4135 (visited on 09/06/2019).
176 Bibliography
[50] H. Struchtrup. Macroscopic Transport Equations for Rarefied Gas Flows. Inter-
action of Mechanics and Mathematics. Springer-Verlag Berlin Heidelberg, 2005.
URL: https://doi.org/10.1007/3-540-32386-4 (visited on 08/25/2019).
[51] H. Struchtrup and P. Taheri. “Macroscopic Transport Models for Rarefied Gas
Flows: A Brief Review”. In: IMA Journal of Applied Mathematics 76.5 (2011),
pp. 672–697. URL: https://doi.org/10.1093/imamat/hxr004 (visited on
08/24/2019).
[52] H. Struchtrup and M. Torrilhon. “Regularization of Grad’s 13 Moment Equa-
tions: Derivation and Linear Analysis”. In: Physics of Fluids 15.9 (2003),
pp. 2668–2680. URL: https://doi.org/10.1063/1.1597472 (visited on
08/25/2019).
[53] L. Theisen. “Automated Boundary Layer Mesh Generation for Simulation
of Convective Cooling”. Bachelor Thesis. RWTH Aachen University, 2018,
to appear. URL: http : / / www . mathcces . rwth - aachen . de / 3teaching /
00projects/archive (visited on 09/19/2019).
[54] L. Theisen. P3 Finite Element Basis Functions on 2-Simplex. 2019. URL:
https://figshare.com/articles/P3_Finite_Element_Basis_Functions_
on_2-Simplex_/9767021/1 (visited on 09/04/2019).
[55] L. Theisen. “Shear-Slip Mesh Update Method for Compressible Flow Simu-
lations Involving Rotating Sub-Domains”. Seminar Thesis. RWTH Aachen
University, 2019, to appear. URL: http://www.mathcces.rwth-aachen.de/
3teaching/0classes/ceswseminar/bisher (visited on 08/22/2019).
[56] L. Theisen, L. Reiher, and C. Geller. Mathematische Modelle der Natur- und In-
genieurwissenschaften (WS18/19): Hausaufgabe 5. RWTH Aachen University,
2019. URL: http://www.mathcces.rwth-aachen.de/3teaching/0classes/
pdemodeling (visited on 08/22/2019).
[57] L. Theisen and M. Torrilhon. fenicsR13: Solver Documentation. RWTH
Aachen University, 2019. URL: https : / / lamboo . pages . rwth - aachen .
de/fenicsR13/ (visited on 09/15/2019).
[58] L. Theisen and M. Torrilhon. fenicsR13: Solver Repository. RWTH Aachen
University, 2019. URL: https://git.rwth-aachen.de/lamBOO/fenicsR13
(visited on 09/15/2019).
[59] M. Torrilhon and H. Struchtrup. “Regularized 13-Moment Equations: Shock
Structure Calculations and Comparison to Burnett Models”. In: Journal of
Fluid Mechanics 513 (2004), pp. 171–198. URL: https://doi.org/10.1017/
S0022112004009917 (visited on 08/25/2019).
Bibliography 177