domain: math phys info nlin spi

text:
The three L 2 , L ∞ and H 1 errors are printed for a h = 1/10 uniform mesh. Note that an unstructured quasi-uniform mesh can be simply generated by using the mkgeo_ugrid command: mkgeo_ugrid -t 10 > square.geo geo square.geo

Let n el denotes the number of elements in the mesh. Since the mesh is quasi-uniform, we have

.7 plots in logarithmic scale the error versus n 1 2 el for both P k approximations, k = 1, 2, 3 and the various norms. Observe that the error behaves as predicted by the theory.

Curved domains

The error analysis applies also for curved boundaries and high order approximations.

Introduction

Rheolef is a programming environment for finite element method computing. The reader is assumed to be familiar with (i) the c++ programming language and (ii) the finite element method. As a Lego game, the Rheolef bricks allow the user to solve most problems, from simple to complex multi-physics ones, in few lines of code. The concision and readability of codes written with Rheolef is certainly a major keypoint of this environment. Here is an example of a Rheolef code for solving the Poisson problem with homogeneous boundary conditions: Example: find u such that -∆u = 1 in Ω and u = 0 on ∂Ω form a = integrate (dot(grad(u),grad(v)));

Let Ω ⊂ R N , N = 1, 2, 3

X h = {v ∈ H 1 (Ω); v |K ∈ P k , ∀K ∈ T h } V h = X h ∩ H 1 0 (Ω) a(u, v) = Ω ∇u.∇v dx (P ) : find u h ∈ V h such that a(u h , v h ) = l(v h ), ∀v h ∈ V h l(v) = Ω v dx
The right column shows the one-to-one line correspondence between the code and the variational formulation. Let us quote [START_REF] Stroustrup | C++ programming styles and libraries[END_REF], the conceptor of the c++ language:

"The time taken to write a program is at best roughly proportional to the number of lines written, and so is the number of errors in that code. If follows that a good way of writing correct programs is to write short programs. In other words, we need good libraries to allow us to write correct code that performs well. This in turn means that we need libraries to get our programs finished in a reasonable time. In many fields, such c++ libraries exist."

Rheolef is an attempt to provide such a library in the field of finite element methods for partial differential equations. Rheolef provides both a c++ library and a set of unix commands for shell programming, providing data structures and algorithms [START_REF] Wirth | Algorithm + data structure = programs[END_REF].

• Data structures fit the variational formulation concept: field, bilinear form and functional space, are c++ types for variables. They can be combined in algebraic expressions, as you write it on the paper.

• Algorithms refer to the most up-to-date ones: direct an iterative sparse matrix solvers for linear systems. They supports efficient distributed memory and parallel computations. Nonlinear c++ generic algorithms such as fixed point, damped Newton and continuation methods are also provided.

General high order piecewise polynomial finite element approximations are implemented, together with some mixed combinations for Stokes and incompressible elasticity. The characteristic method can be used for diffusion-convection problems while hyperbolic systems can be discretized by the discontinuous Galerkin method.

Notations

Rheolef mathematics description Rheolef mathematics description the gradient of a vector field sin(phi) sin(ϕ) standard mathematical functions cos(phi) cos (ϕ) extended to scalar fields tan(phi) tan(ϕ) acos(phi) cos -1 (ϕ) asin(phi) sin -1 (ϕ) atan(phi) tan -1 (ϕ) cosh(phi) cosh(ϕ) sinh(phi) sinh(ϕ) tanh(phi) tanh(ϕ) exp(phi) exp(ϕ) log(phi) log(ϕ) log10(phi) log 10(ϕ) floor(phi) ⌊ϕ⌋ largest integral not greater than ϕ ceil(phi) ⌈ϕ⌉ smallest integral not less than ϕ min(phi,psi) min(ϕ, ψ) max(phi,psi) max(ϕ, ψ) pow(phi,psi) ϕ ψ atan2(phi,psi) tan -1 (ψ/ϕ) fmod(phi,psi) ϕ -⌊ϕ/ψ + 1/2⌋ ψ floating point remainder

d d ∈ {1,
compose(f,phi) f • ϕ = f (ϕ)
applies an unary function f compose(f,phi1,...,phin) f (ϕ 1 , . . . , ϕ n ) applies a n-ary function f , n ⩾ 1 compose(phi,X) ϕ • X, X(x) = x + d(x) composition with a characteristic

Chapter 1

Getting started

The first chapter of this book starts with the Dirichlet problem with homogeneous boundary condition: this example is declined with details in dimension 1, 2 and 3, as a starting point to Rheolef.

Next chapters present various boundary conditions: for completeness, we treat non-homogeneous Dirichlet, Neumann, and Robin boundary conditions for the model problem. The last two examples presents some special difficulties that appears in most problems: the first one introduce to problems with non-constant coefficients and the second one, a ill-posed problem where the solution is defined up to a constant. This first chapter can be viewed as a pedagogic preparation for more advanced applications, such as Stokes and elasticity, that are treated in the second chapter of this book. Problem with nonconstant coefficients are common as suproblems generated by various algorithms for non-linear problem.

The model problem

For obtaining and installing Rheolef, see the installation instructions on the Rheolef home page:

http://www-ljk.imag.fr/membres/Pierre.Saramito/rheolef Before to run examples, please check your Rheolef installation with:

rheolef-config --check
The present book is available in the documentation directory of the Rheolef distribution. This documentation directory is given by the following unix command:

rheolef-config --docdir

All examples presented along the present book are also available in the example/ directory of the Rheolef distribution. This directory is given by the following unix command:

rheolef-config --exampledir

This command returns you a path, something like /usr/share/doc/rheolef-doc/examples and you should make a copy of these files: (P): find u, defined in Ω, such that:

-∆u = 1 in Ω (1.1)

u = 0 on ∂Ω (1.2)
where ∆ denotes the Laplace operator. The variational formulation of this problem expresses (see appendix A.1.1 for details):

(VF): find u ∈ H 1 0 (Ω) such that:

a(u, v) = l(v), ∀v ∈ H 1 0 (Ω) (1.3)
where the bilinear form a(., .) and the linear form l(.) are defined by

a(u, v) = Ω ∇u.∇v dx, ∀u, v ∈ H 1 0 (Ω) l(v) = Ω v dx, ∀v ∈ L 2 (Ω)
The bilinear form a(., .) defines a scalar product in H 1 0 (Ω) and is related to the energy form. This form is associated to the -∆ operator.

Approximation

Let us introduce a mesh T h of Ω and the finite dimensional space X h of continuous piecewise polynomial functions.

X h = {v ∈ H 1 (Ω); v /K ∈ P k , ∀K ∈ T h }

where k = 1 or 2. Let V h = X h ∩ H 1 0 (Ω) be the functions of X h that vanishes on the boundary of Ω. The approximate problem expresses: (V F ) h : find u h ∈ V h such that:

a(u h , v h ) = l(v h ), ∀v h ∈ V h
By developing u h on a basis of V h , this problem reduces to a linear system. The following C++ code implement this problem in the Rheolef environment.

Comments

This code applies for both one, two or three dimensional meshes and for both piecewise linear or quadratic finite element approximations. Four major classes are involved, namely: geo, space, form and field.

Let us now comment the code, line by line.

problem p ( a ); p . solve ( lh , uh );

Finally, the problem related to the bilinear form a and the right-hand-side lh is solved and uh contains the solution. The field is printed to standard output:

dout << uh ;
The dout stream is a specific variable defined in the Rheolef library: it is a distributed and parallel extension of the usual cout stream in C++ Let us study with more details the linear system. Let (φ i ) 0⩽i<dim(X h ) be the basis of X h associated to the Lagrange nodes, e.g. the vertices of the mesh for the P 1 approximation and the vertices and the middle of the edges for the P 2 approximation. The approximate solution u h expresses as a linear combination of the continuous piecewise polynomial functions (φ i ):

u h = i u i φ i
Thus, the field u h is completely represented by its coefficients (u i ). The coefficients (u i ) of this combination are grouped into to sets: some have zero values, from the boundary condition and are related to blocked coefficients, and some others are unknown. Blocked coefficients are stored into the uh.b array while unknown one are stored into uh.u. Thus, the restriction of the bilinear form a(., .) to X h × X h can be conveniently represented by a block-matrix structure: The resolution of this linear system for the a.uu matrix is then performed via the solver class: this call is performed by the problem class. For more details, see the Rheolef reference manual related to the problem and solver classes, available on the web site and via the unix command:

man problem man solver

How to compile the code

First, create a file 'Makefile' as follow:

include $(shell rheolef-config --libdir)/rheolef/rheolef.mk CXXFLAGS = $(INCLUDES_RHEOLEF) LDLIBS = $(LIBS_RHEOLEF) default: dirichlet Then, enter: make dirichlet Now, your program, linked with Rheolef, is ready to run on a mesh. Enter the commands: mkgeo_grid -t 10 > square.geo geo square.geo

How to run the program

The first command generates a simple 10x10 bidimensional mesh of Ω =]0, 1[ 2 and stores it in the file square.geo. The second command shows the mesh. It uses paraview visualization program by default. The next commands perform the computation and visualization:

./dirichlet square.geo P1 > square.field field square.field

The result is hown on Fig. 1.1. By default, the visualization appears in a paraview window. If you are in trouble with this software, you can switch to the simpler gnuplot visualization mode: field square.field -gnuplot

Advanced and stereo visualization

We could explore some graphic rendering modes (see Fig. www.ecolofrance.com/56-lunettes-anaglyphe-rouge-cyan-carton-pas-cher for how to find anaglyph red-cyan glasses. For simplicity, it would perhaps prefer to switch to the gnuplot render: field square.field -gnuplot field square.field -gnuplot -bw field square.field -gnuplot -gray Please, consult the Rheolef reference manual page for more on the unix commands field, geo and mkgeo_grid. The manual is available both on the web site: firefox https://www-ljk.imag.fr/membres/Pierre.Saramito/rheolef and as individual unix man pages: man mkgeo_grid man geo man field

See also man rheolef

The complete list of Rheolef man page is obtained by: man -k rheolef 1.1.7 High-order finite element methods Turning to the P2 or P3 approximations simply writes:

./dirichlet square.geo P2 > square-P2.field field square-P2.field You can replace the P2 command-line argument by any Pk, where k ⩾ 1. Now, let us consider a mono-dimensional problem Ω =]0, 1[: mkgeo_grid -e 10 > line.geo geo line.geo ./dirichlet line.geo P1 | field -

The first command generates a subdivision containing ten edge elements. The last two lines show the mesh and the solution via gnuplot visualization, respectively. Conversely, the P2 case writes:

./dirichlet line.geo P2 | field -

Tridimensional computations

Let us consider a three-dimensional problem Ω =]0, 1[ 3 . First, let us generate a mesh: mkgeo_grid -T 10 > cube.geo geo cube.geo geo cube.geo -fill geo cube.geo -cut geo cube.geo -shrink geo cube.geo -shrink -cut

The 3D visualization bases on the paraview render. These commands present some cuts (-cut) inside the internal mesh structure: a simple click on the central arrow draws the cut plane normal vector or its origin, while the red square allows a translation. The following command draws the mesh with all internal edges (-full), together with the stereoscopic anaglyph (-stereo): geo cube.geo -stereo -full Then, we perform the computation and the visualization:

./dirichlet cube.geo P1 > cube.field field cube.field

The visualization presents an isosurface. Also here, you can interact with the cutting plane. On the Properties of the paraview window, select Contour, change the value of the isosurface and click on the green Apply button. Finally exit from the visualization and explore the stereoscopic anaglyph mode (see Fig. 1.4, right):

field cube.field -stereo

It is also possible to add a second isosurface (Contour) or a cutting plane (Slice) to this scene by using the corresponding Properties menu. Finally, the following command, with the -volume option, allows a 3D color light volume graphical rendering: field cube.field -volume After this exploration of the 3D visualization capacities of our environment, let us go back to the Dirichlet problem and perform the P2 approximation:

./dirichlet cube.geo P2 | field -1.1.9 Quadrangles, prisms and hexahedra Quadrangles and hexahedra are also supported in meshes: mkgeo_grid -q 10 > square.geo geo square.geo mkgeo_grid -H 10 > cube.geo geo cube.geo

Note also that the one-dimensional exact solution expresses explicitly:

u(x) =
x(1 -x) 2 In the two-and three dimensional cases, an explicit expression of the solution, based on Fourier expansion, is also known (see e.g. Saramito and Roquet, 2001, annex B, page 5411).

Direct versus iterative solvers

In order to measure the performances of the solver, the dirichlet.cc (page 14) has been modified as: double t0 = dis_wall_time (); solver_option sopt ; sopt . iterative = false ; // or true sopt . tol = 1 -5; // when iterative problem p (a , sopt ); double t_factorize = dis_wall_time () -t0 ; p . solve ( lh , uh ); double t_solve = dis_wall_time () -t0 -t_factorize ; derr << " time " << t_factorize << " " << t_solve << endl ;

The dis_wall_time function returns the wall-clock time in seconds, while the solver_option sopt enables to choose between a direct or an iterative solver method: by default Rheolef selects a direct method when d ⩽ 2 and an iterative one when d = 3. For a 3D mesh, the compilation and run writes: make dirichlet mkgeo_grid -T 60 > cube-60.geo ./dirichlet cube-60.geo P1 > cube-60.field Fig. 1.5 plots the performances of the direct and iterative solvers used in Rheolef. The computing time T (n) is represented versus size n of the linear system, says Ax = b. Note that for a square-k.geo or cube-k.geo mesh, the size of the linear system is n = (k -1) d . For the direct method, two times are represented: first, the time spend to factorize A = LDL T , where L is lower triangular and D is diagonal, and second, the time used to solve LDL T = x (in three steps: solving Lz = b, then Dy = z and finally L T x = y). For the iterative method, the conjugate gradient algorithm is considered, without building any preconditioner, so there is nothing to initialize, and only one time is represented. The tolerance on the residual term is set to 10 -5 . In the bidimensional case, the iterative solver presents asymptotically, for large n, a computing time similar to the factorization time of the direct solver, roughly O(n 3/2 ) while the time to solve by the direct method is dramatically lower, roughly O(n). As the factorization can be done one time for all, the direct method is advantageous most of the time. In the three dimensional case, the situation is different. The factorization time is very time consuming roughly O(n 2 ), while the time to solve for both direct and iterative methods behave as O(n 4/3 ). Thus, the iterative method is clearly advantageous for three-dimensionnal problems. Future works will improve the iterative approach by building preconditioners. The asymptotic behaviors of direct methods strongly depends upon the ordering strategy used for the factorization. For the direct solver, Rheolef was configured with the mumps [START_REF] Amestoy | A fully asynchronous multifrontal solver using distributed dynamic scheduling[END_REF][START_REF] Amestoy | Hybrid scheduling for the parallel solution of linear systems[END_REF]] library and mumps was configured with the parallel scotch [START_REF] Pellegrini | PT-Scotch and libscotch 5.1 user's guide[END_REF] ordering library. For a regular grid and in the bidimensional case, there exists a specific ordering called nested disection [START_REF] Hoffman | Complexity bounds for regular finite difference and finite element grids[END_REF][START_REF] George | Nested dissection of a regular finite element mesh[END_REF] that minimize the fillin of the sparse matrix during the factorization. For three-dimensional case this ordering is called nested multisection [START_REF] Ashcraft | Robust ordering of sparse matrices using multisection[END_REF]]. Asymptotic computing time for these regular grid are then explicity known versus the grid size n:

d direct/factorize direct/solve iterative 1 n n n 2 2 n 3/2 n log n n 3/2 3 n 2 n 4/3 n 4/3
The last column gives the asymptotic computing time for the conjugate gradient on a general mesh [Saramito, 2013a]. Remark that these theoretical results are consistent with numerical experiments presented on Fig. 1.5. In conclusion, the best strategy is to choose a direct method when d ⩽ 2 and an iterative one when d = 3: this is the default behavior with Rheolef.

Distributed and parallel runs

For large meshes, a computation in a distributed and parallel environment is profitable:

mpirun -np 8 ./dirichlet cube-60.geo P1 > cube-60.field mpirun -np 16 ./dirichlet cube-60.geo P1 > cube-60.field

The computing time T (n, p) depends now upon the linear system size n and the number of processes p. For a fixed size n, the speedup S(p) when using p processors is defined by the ratio of the time required by a sequential computation with the time used by a parallel one: S(p) = T (n, 1)/T (n, p). The speedup is presented on Fig 1 .6 for the two phases of the computation: the assembly phase and the solve one, and for d = 2 (direct solver) and 3 (iterative solver). The ideal speedup S(p) = p and the null speedup S(p) = 1 are represented by dotted lines. Observe on Fig 1 .6 that for too small meshes, using too much processes is not profitable, as more time is spend by communications rather by computations, especially for the solve phase. Conversely, when the mesh size increases, using more processes leads to a remarkable speedup for both d = 2 and 3. The largest mesh used here contains about three millions of elements. The speedup behavior is roughly linear up to a critical number of processor denotes as p c . Then, there is a transition to a plateau (the Amdahl's law), where communications dominate. Note that p c increases with the mesh size: larger problems lead to a higher speedup. Also p c increases also with the efficiency of communications.

Present computation times are measured on a BullX DLC supercomputer (Bull Newsca) composed of nodes having two intel sandy-bridge processors and connected to a FDR infiniband non-blocking low latency network. The assembly phase corresponds to dirichlet.cc (page 14) line 7 to 13 and the solve phase to lines 14 and 15. 1.1.12 Non-homogeneous Dirichlet conditions

Formulation

We turn now to the case of a non-homogeneous Dirichlet boundary conditions. Let f ∈ H -1 (Ω) and g ∈ H 1 2 (∂Ω). The problem writes: (P 2 ) find u, defined in Ω such that:

-∆u = f in Ω u = g on ∂Ω
The variational formulation of this problem expresses:

(V F 2 ) find u ∈ V such that: a(u, v) = l(v), ∀v ∈ V 0 where a(u, v) = Ω ∇u.∇v dx l(v) = Ω f v dx V = {v ∈ H 1 (Ω); v |∂Ω = g} V 0 = H 1 0 (Ω)

Approximation

As usual, we introduce a mesh T h of Ω and the finite dimensional space X h :

X h = {v ∈ H 1 (Ω); v /K ∈ P k , ∀K ∈ T h }
Then, we introduce:

V h = {v ∈ X h ; v |∂Ω = π h (g)} V 0,h = {v ∈ X h ; v |∂Ω = 0}
where π h denotes the Lagrange interpolation operator. The approximate problem writes:

(V F 2 ) h : find u h ∈ V h such that: a(u h , v h ) = l(v h ), ∀v h ∈ V 0,h
The following C++ code implement this problem in the Rheolef environment. Remarks the notation x = (x 0 , . . . , x d-1 ) for the Cartesian coordinates in R d : since all arrays start at index zero in C++ codes, and in order to avoid any mistakes between the code and the mathematical formulation, we also adopt this convention here. This choice of f and g is convenient, since the exact solution is known:

u(x) = d-1 i=0 cos(πx i )
The following C++ code implement this problem by using the concept of function object, also called class-function (see e.g. Musser and Saini, 1996a). A convenient feature is the ability for function objects to store auxiliary parameters, such as the space dimension d for f here, or some constants, as π for f and g.

Comments

The class point describes the coordinates of a point (x 0 , . . . , x d-1 ) ∈ R d as a d-uplet of Float. The Float type is usually a double. This type depends upon the Rheolef configuration (see Saramito, 2012a, installation instructions), and could also represent some high precision floating point class.

The dirichlet-nh.cc code looks like the previous one dirichlet.cc related to homogeneous boundary conditions. Let us comments the changes. The dimension d comes from the geometry Ω:

size_t d = omega . dimension ();

The linear form l(.) is associated to the right-hand side f and writes:

field lh = integrate ( f ( d )* v );
Note that the function f that depends upon the dimension d parameter, is implemented by a functor, i.e. a C++ class that possesses the operator() member function. The space W h of piecewise P k functions defined on the boundary ∂Ω is defined by: space Wh ( omega [ " boundary " ] , argv [2]);

where P k is defined via the second command line argument argv [2]. This space is suitable for the Lagrange interpolation of g on the boundary:

uh [ " boundary " ] = interpolate ( Wh , g ( d ));

The values of the degrees of freedom related to the boundary are stored into the field uh.b, where non-homogeneous Dirichlet conditions applies. The rest of the code is similar to the homogeneous Dirichlet case.

How to run the program

First, compile the program: The optional -volume allows a 3D color light volume graphical rendering. Here, the P1 approximation can be replaced by P2, P3, etc, by modifying the command-line argument.

make dirichlet-

Error analysis

Since the solution u is regular, the following error estimates holds:

∥u -u h ∥ 0,2,Ω = O(h k+1 ) ∥u -u h ∥ 0,∞,Ω = O(h k+1 ) ∥u -u h ∥ 1,2,Ω = O(h k )
providing the approximate solution u h uses P k continuous finite element method, k ⩾ 1. Here, ∥.∥ 0,2,Ω , ∥.∥ 0,∞,Ω and ∥.∥ 1,2,Ω denotes as usual the L 2 (Ω), L ∞ (Ω) and H 1 (Ω) norms.

The following code implement the computation of the error.

File 1.4: cosinusprod_error.cc # include " rheolef . h " using namespace rheolef ; using namespace std ;

# include " cosinusprod . 10 -2 10 -1

∥u h -π h (u)∥ 0,∞,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 10 -8
10 -6

10 -4 10 -2 10 0 10 -2 10 -1 First, generate the test source file and compile it:

|u h -π h (u)| 1,2,Ω 1 = k 2 3 h k = 1 k = 2 k = 3
sed -e 's/sinusprod/sinusrad/' < dirichlet-nh.cc > dirichlet_nh_ball.cc sed -e 's/sinusprod/sinusrad/' < cosinusprod_error.cc > cosinusrad_error.cc make dirichlet_nh_ball cosinusrad_error Then, generates the mesh of a circle and run the test case: mkgeo_ball -order 1 -t 10 > circle-P1.geo geo circle-P1 -gnuplot ./dirichlet_nh_ball circle-P1.geo P1 | ./cosinusrad_error For a high order k = 3 isoparametric approximation: mkgeo_ball -order 3 -t 10 > circle-P3.geo geo circle-P3 -gnuplot ./dirichlet_nh_ball circle-P3.geo P3 | ./cosinusrad_error Observe Fig. 1.8: for meshes based on triangles: the error behave as expected when k = 1, 2, 3, 4. These features are available for arbitrarily P k high order approximations and three-dimensional geometries. In practice, the current implementation is efficient up to k = 5: for higher polynomial degrees, a more specific implementation is in development.

∥u h -π h (u)∥ 0,∞,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 k = 4 -8 -6 -4 -2 10 0 10 -2 10 -1 |u h -π h (u)| 1,2,Ω 1 = k 2 3 h k = 1 k = 2 k = 3 k = 4
∥u h -π h (u)∥ 0,∞,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 k = 4 10 -8
10 -6

10 -4 10 -2 10 -2 10 -1

|u h -π h (u)| 1,2,Ω 1 = k 2 3 h k = 1 k = 2 k = 3 k = 4
Figure 1.9: Curved domains (quadrangles): error analysis in L 2 , L ∞ and H 1 norms.

Non-homogeneous Neumann boundary conditions for the Helmholtz operator

Formulation

Let us show how to insert Neumann boundary conditions. Let f ∈ H -1 (Ω) and g ∈ H -1 2 (∂Ω). The problem writes:

(P 3 ): find u, defined in Ω such that:

u -∆u = f in Ω ∂u ∂n = g on ∂Ω
The variational formulation of this problem expresses:

(V F 3 ): find u ∈ H 1 (Ω) such that: a(u, v) = l(v), ∀v ∈ H 1 (Ω)
where

a(u, v) = Ω (u v + ∇u.∇v) dx l(v) = Ω f v dx + ∂Ω g v ds

Approximation

As usual, we introduce a mesh T h of Ω and the finite dimensional space X h :

X h = {v ∈ H 1 (Ω); v /K ∈ P k , ∀K ∈ T h }
The approximate problem writes:

(V F 3 ) h : find u h ∈ X h such that: a(u h , v h ) = l(v h ), ∀v h ∈ X h
f (x) = (1 + dπ 2 ) d-1 i=0 sin(πx i ) g(x) =                -π when d = 1 -π d-1 i=0 sin(πx i ) when d = 2 -π d-1 i=0 sin(πx i ) sin(x (i+1)mod d when d = 3
This example is convenient, since the exact solution is known:

u(x) = d-1 i=0 sin(πx i ) (1.5)
File 1.9: sinusprod_helmholtz.h

Comments

The neumann-nh.cc code looks like the previous one dirichlet-nh.cc. Let us comments only the changes.

form a = integrate ( u * v + dot ( grad ( u ) , grad ( v )));

The bilinear form a(., .) is defined. Notes the flexibility of the integrate function that takes as argument an expression involving the trial and test functions. The right-hand side is computed as:

field lh = integrate ( f ( d )* v ) + integrate ( " boundary " , g ( d )* v );
The second integration is performed on ∂Ω. The additional first argument of the integrate function is here the name of the integration domain.

How to run the program

First, compile the program: make neumann-nh

Running the program is obtained from the homogeneous Dirichlet case, by replacing dirichlet by neumann-nh.

The Robin boundary conditions

Formulation

Let f ∈ H -1 (Ω) and Let g ∈ H 1 2 (∂Ω).
The problem writes: (P 4 ) find u, defined in Ω such that:

-∆u = f in Ω ∂u ∂n + u = g on ∂Ω
The variational formulation of this problem expresses:

(V F 4 ): find u ∈ H 1 (Ω) such that: a(u, v) = l(v), ∀v ∈ H 1 (Ω)
where

a(u, v) = Ω ∇u.∇v dx + ∂Ω uv ds l(v) = Ω f v dx + ∂Ω gv ds Approximation As usual, let X h = {v ∈ H 1 (Ω); v /K ∈ P k , ∀K ∈ T h }
The approximate problem writes:

(V F 4 ) h : find u h ∈ X h such that: a(u h , v h ) = l(v h ), ∀v h ∈ X h
File 1.10: robin.cc This statement reflects directly the definition of the bilinear form a(., .), as the sum of two integrals, the first one over Ω and the second one over its boundary.

How to run the program

First, compile the program: make robin

Running the program is obtained from the homogeneous Dirichlet case, by replacing dirichlet by robin.

Neumann boundary conditions for the Laplace operator

In this chapter we study how to solve a ill-posed problem with a solution defined up to a constant.

Formulation

Let Ω be a bounded open and simply connected subset of

R d , d = 1, 2 or 3. Let f ∈ L 2 (Ω) and g ∈ H 1 2 (
∂Ω) satisfying the following compatibility condition:

Ω f dx + ∂Ω g ds = 0
The problem writes: (P 5 ) h : find u, defined in Ω such that:

-∆u = f in Ω ∂u ∂n = g on ∂Ω
Since this problem only involves the derivatives of u, it is defined up to a constant: it is then clear that its solution is never unique [Girault and Raviart, 1986, p. 11]. A discrete version of this problem could be solved iteratively by the conjugate gradient or the MINRES algorithm [START_REF] Paige | Solution of sparse indefinite systems of linear equations[END_REF]. In order to solve it by a direct method, we get round this difficulty by seeking u in the following space

V = {v ∈ H 1 (Ω); b(v, 1) = 0} where b(v, µ) = µ Ω v dx, ∀v ∈ L 2 (Ω), ∀µ ∈ R
The variational formulation of this problem writes:

(V F 5 ): find u ∈ V such that: a(u, v) = ℓ(v), ∀v ∈ V where a(u, v) = Ω ∇u.∇v dx ℓ(v) = Ω f v dx + ∂Ω gv ds
Since the direct discretization of the space V is not an obvious task, the constraint b(u, 1) = 0 is enforced by a Lagrange multiplier λ ∈ R. Let us introduce the Lagrangian, defined for all v ∈ H 1 (Ω) and µ ∈ R by:

L(v, µ) = 1 2 a(v, v) + b(v, µ) -ℓ(v)
The saddle point (u, λ) ∈ H 1 (Ω) × R of this Lagrangian is characterized as the unique solution of:

a(u, v) + b(v, λ) = ℓ(v), ∀v ∈ H 1 (Ω) b(u, µ) = 0, ∀µ ∈ R It is clear that if (u, λ) is solution of this problem, then u ∈ V and u is a solution of (V F 5 ). Conversely, let u ∈ V the solution of (V F 5 ). Choosing v = v 0 where v 0 (x) = 1, ∀x ∈ Ω leads to λ meas(Ω) = ℓ(v 0 ).
From the definition of ℓ(.) and the compatibility condition between the data f and g, we get λ = 0. Note that the saddle point problem extends to the case when f and g does not satisfies the compatibility condition, and in that case λ = ℓ(v 0 )/meas(Ω).

Approximation

As usual, we introduce a mesh T h of Ω and the finite dimensional space X h :

X h = {v ∈ H 1 (Ω); v /K ∈ P k , ∀K ∈ T h }
The approximate problem writes:

(V F 5 ) h : find (u h , λ h ) ∈ X h × R such that: a(u h , v) + b(v, λ h ) = ℓ(v), ∀v ∈ X h b(u h , µ) = 0, ∀µ ∈ R

Comments

Let Ω ⊂ R d , d = 1, 2, 3. We choose f (x) = 1 and g(x) = -1/(2d). This example is convenient, since the exact solution is known:

u(x) = - 1 12 + 1 2d d i=1 x i (1 -x i )
The code looks like the previous ones. Let us comment the changes. The discrete bilinear form b is computed as b ∈ X h that interprets as a linear application from

X h to R: b(v h ) = m(v h , 1). Thus b is computed as field b = integrate ( v ); Let A = a trans(b) b 0 , U = uh lambda , B = lh 0
The problem admits the following matrix form:

A U = B
The matrix that represents the bilinear fo and its right-hand side are assembled as:

form A = {{ a , b } , { trans ( b ) , 0}}; field Bh = { lh , 0};
Both the pairs U = (u h , λ) and B = (b, 0) belong to the vectorial space X h × R. and B = (b, 0) belong to the Then, the variable Uh could be declared as:

field Uh ( Bh . get_space () , 0);

Note that the matrix A is symmetric and non-singular, but indefinite : it admits eigenvalues that are either strictly positive or strictly negative. While the Choleski factorization is not possible, its variant the LDL T one is performed, thanks to the ldlt function:

A . set_symmetry ( true ); problem p ( A ); p . solve ( Bh , Uh );

Then, the uh field is extracted as the first component of the the Uh one:

dout << Uh [0];

How to run the program

As usual, enter: make neumann-laplace mkgeo_grid -t 10 > square.geo ./neumann-laplace square P1 | field -

Non-constant coefficients and multi-regions

This section is related to the so-called transmission problem. We introduce some new concepts: problems with non-constant coefficients, regions in the mesh, weighted forms and discontinuous approximations.

Formulation

Let us consider a diffusion problem with a non-constant diffusion coefficient η in a domain bounded 2,3: (P ): find u defined in Ω such that:

Ω ⊂ R d , d = 1,
-div(η∇u) = f in Ω (1.6) u = 0 on Γ left ∪ Γ right (1.7) ∂u ∂n = 0 on Γ top ∪ Γ bottom when d ⩾ 2 (1.8) ∂u ∂n = 0 on Γ front ∪ Γ back when d = 3 (1.9)
where f is a given source term. We consider here the important special case when η is piecewise constant:

η(x) = ε when x ∈ Ω west 1 when x ∈ Ω east
where (Ω west , Ω east ) is a partition of Ω in two parts (see Fig. 1.10). This is the so-called transmission problem: the solution and the flux are continuous on the interface Γ 0 = ∂Ω east ∩ ∂Ω west between the two domains where the problem reduce to a constant diffusion one:

u Ωwest = u Ωeast on Γ 0 ε ∂u /Ωwest ∂n = ∂u Ωeast ∂n on Γ 0
It expresses the transmission of the quantity u and its flux across the interface Γ 0 between two regions that have different diffusion properties: Note that the more classical problem, with constant diffusion η on Ω is obtained by simply choosing when ε = 1.

The variational formulation of this problem expresses:

(V F ): find u ∈ V such that: a(u, v) = l(v), ∀v ∈ V
where the bilinear forms a(., .) and the linear one l(.) are defined by

a(u, v) = Ω η ∇u.∇v dx, ∀u, v ∈ H 1 (Ω) l(v) = Ω f v dx, ∀v ∈ L 2 (Ω) V = {v ∈ H 1 (Ω); v = 0 on Γ left ∪ Γ right }
The bilinear form a(., .) defines a scalar product in V and is related to the energy form. This form is associated to the -div η∇ operator. The approximation of this problem could performed by a standard Lagrange P k continuous approximation.

File 1.12: transmission.cc

Comments

This file is quite similar to those studied in the first sections of this book. Let us comment only the changes. The Dirichlet boundary condition applies no more on the whole boundary ∂Ω but on two parts Γ left and Γ right . On the other boundary parts, an homogeneous Neumann boundary condition is used: since these conditions does not produce any additional terms in the variational formulation, there are also nothing to write in the C++ code for these boundaries. We choose f = 1: this leads to a convenient test-problem, since the exact solution is known when

Ω =]0, 1[ d : u(x) =            x 0 2ε 1 + 3ε 2(1 + ε) -x 0 when x 0 < 1/2 1 -x 0 2 x 0 + 1 -ε 2(1 + ε) otherwise
The field η belongs to a discontinuous finite element P k-1 space denoted by Q h :

string eta_approx = " P " + to_string ( Xh . degree () -1) + " d " ; space Qh ( omega , eta_approx ); field eta ( Qh );

For instance, when argv[2] contains "P2", i.e. k = 2, then the string eta_approx takes value "P1d". Then η is initialized by: eta [ " east " ] = 1; eta [ " weast " ] = epsilon ;

The energy form a is then constructed with η as additional parameter that acts as a integration weight:

form a = integrate ( eta_h * dot ( grad ( u ) , grad ( v )));
Such forms with a additional weight function are called weighted forms in Rheolef.

How to run the program ?

Build the program as usual: make transmission. Then, creates a one-dimensional geometry with two regions:

mkgeo_grid -e 100 -region > line.geo geo line.geo

The trivial mesh generator mkgeo_grid, defines two regions east and west when used with the -region option. This correspond to the situation:

Ω = [0, 1] d , Ω west = Ω ∩ {x 0 < 1/2} and Ω east = Ω ∩ {x 0 > 1/2}.
In order to avoid mistakes with the C++ style indexes, we denote by (x 0 , . . . , x d-1 ) the Cartesian coordinate system in R d . Finally, run the program and look at the solution: As for all the others examples, you can replace P1 by higher-order approximations, change elements shapes, such as q, H or P, and run distributed computations computations with mpirun.

Chapter 2

Fluids and solids computations

2.1 The linear elasticity and the Stokes problems

The linear elasticity problem

Formulation

The total Cauchy stress tensor expresses:

σ(u) = λ div(u).I + 2µD(u) (2.1)
where λ and µ are the Lamé coefficients. Here, D(u) denotes the symmetric part of the gradient operator and div is the divergence operator. Let us consider the elasticity problem for the embankment, in Ω =]0, 1[ d , d = 2, 3. The problem writes: (P ): find u = (u 0 , . . . , u d-1 ), defined in Ω, such that:

-div σ(u) = f in Ω, ∂u ∂n = 0 on Γ top ∪ Γ right u = 0 on Γ left ∪ Γ bottom , u = 0 on Γ front ∪ Γ back , when d = 3 (2.2)
where f = (0, -1) when d = 2 and f = (0, 0, -1) when d = 3. The Lamé coefficients are assumed to satisfy µ > 0 and λ + µ > 0. Since the problem is linear, we can suppose that µ = 1 without any loss of generality. recall that, in order to avoid mistakes with the C++ style indexes, we denote by (x 0 , . . . , x d-1 ) the Cartesian coordinate system in R d . For d = 2 we define the boundaries:

Γ left = {0}×]0, 1[, Γ right = {1}×]0, 1[ Γ bottom = ]0, 1[×{0}, Γ top = ]0, 1[×{1}
and for d = 3:

Γ back = {0}×]0, 1[ 2 , Γ front = {1}×]0, 1[ 2 Γ left = ]0, 1[×{0}×]0, 1[, Γ right = ]0, 1[×{1}×]0, 1[ Γ bottom = ]0, 1[ 2 ×{0}, Γ top = ]0, 1[ 2 ×{1}
These boundaries are represented on Fig. 2.1. The variational formulation of this problem expresses: where

(V F ): find u ∈ V such that: a(u, v) = l(v), ∀v ∈ V, (2.3)
a(u, v) = Ω (λdiv u div v + 2D(u) : D(v)) dx, l(v) = Ω f .v dx, V = {v ∈ (H 1 (Ω)) 2 ; v = 0 on Γ left ∪ Γ bottom }, when d = 2 V = {v ∈ (H 1 (Ω)) 3 ; v = 0 on Γ left ∪ Γ bottom ∪ Γ right ∪ Γ back }, when d = 3

Approximation

We introduce a mesh T h of Ω and for k ⩾ 1, the following finite dimensional spaces:

X h = {v h ∈ (H 1 (Ω)) d ; v h/K ∈ (P k ) d , ∀K ∈ T h }, V h = X h ∩ V
The approximate problem writes:

(V F ) h : find u h ∈ V h such that: a(u h , v h ) = l(v h ), ∀v h ∈ V h

Comments

The space is defined in a separate file 'embankment.icc', since it will be reused in others examples along this chapter:

space Vh ( omega , " P2 " , " vector " );

Note here the multi-component specification "vector" as a supplementary argument to the space constructor. The boundary condition contain a special cases for bi-and tridimensional cases. The right-hand-side f h represents the dimensionless gravity forces, oriented on the vertical axis: the last component of f h is set to -1 as:

fh [d -1] = -1;
The code for the bilinear form a(., .) and the linear one l(.) are closed to their mathematical definitions:

form a = integrate ( lambda * div ( u )* div ( v ) + 2* ddot ( D ( u ) , D ( v ))); field lh = integrate ( dot (f , v ));
Finally, the 1/λ parameter and the multi-field result are printed, using mark labels, thanks to the catchmark stream manipulator. Labels are convenient for post-processing purpose, as we will see in the next paragraph.

How to run the program

Compile the program as usual (see page 16): The triangular mesh has four boundary domains, named left, right, top and bottom. Then, enter:

./embankment square.geo P1 > square-P1.field

The previous command solves the problem for the corresponding mesh and writes the multicomponent solution in the '.field' file format. Run the deformation vector field visualization: The unix manual for the field command is available as:

man field
A specific field component can be also selected for a scalar visualization:

field -comp 0 square-P1.field field -comp 1 square-P1.field

Next, perform a P 2 approximation of the solution:

./embankment square.geo P2 > square-P2.field field square-P2.field -nofill

Finally, let us consider the three dimensional case mkgeo_grid -T 10 > cube.geo ./embankment cube.geo P1 > cube-P1.field field cube-P1.field -stereo field cube-P1.field -stereo -fill

The two last commands show the solution in 3D stereoscopic anaglyph mode. The graphic is represented on Fig. 2.2. The P 2 approximation writes:

./embankment cube.geo P2 > cube-P2.field field cube-P2.field

Computing the stress tensor

Formulation and approximation

The following code computes the total Cauchy stress tensor, reading the Lamé coefficient λ and the deformation field u h from a '.field' file. Let us introduce:

T h = {τ h ∈ (L 2 (Ω)) d×d ; τ h = τ T h and τ h;ij/K ∈ P k-1 , ∀K ∈ T h , 1 ⩽ i, j ⩽ d}
This computation expresses:

find σ h such that: m(σ h , τ ) = b(τ, u h ), ∀τ ∈ T h where m(σ, τ ) = Ω σ : τ dx, b(τ, u) = Ω (2D(u) : τ dx + λdiv(u) tr(τ )) dx,
where tr(τ ) =

Comments

In order to our code stress.cc to apply also for the forthcoming incompressible case λ = +∞, the Lamé coefficient is introduced as 1/λ. Its value is zero in the incompressible case. By this way, the previous code applies for any deformation field, and is not restricted to our embankment problem. The stress tensor is obtained by a direct interpolation of the u h first derivatives. As u h is continuous and piecewise polynomial P k , its derivatives are also piecewise polynomials with degree k -1, but discontinuous at inter-element boundaries : this approximation is denoted as P k-1,d . Thus, the stress tensor belongs to the space T h with the P k-1,d element. First, compile the program: make stress

How to run the program

The visualization for the stress tensor as ellipses writes:

./stress < square-P1.field > square-stress-P1.field ./stress < square-P2.field > square-stress-P2.field field square-stress-P1.field -proj field square-stress-P2.field -proj

This visualization based on paraview requires the TensorGlyph feature, available since paraview-5.0. Recall that the stress, as a derivative of the deformation, is P0 (resp. P1d) and discontinuous when the deformation is P1 (resp. P2) and continuous. The approximate stress tensor field is projected as a continuous piecewise linear space, using the -proj option. Conversely, the 3D visualization bases on ellipsoids:

./stress < cube-P1.field > cube-stress-P1.field field cube-stress-P1.field -proj -stereo You can observe a discontinuous constant or piecewise linear representation of the approximate stress component σ 01 (see Fig. 2.4):

field square-stress-P1.field -comp 01 field square-stress-P2.field -comp 01 -elevation field square-stress-P2.field -comp 01 -elevation -stereo

Note that the -stereo implies the paraview render: this feature available with paraview. The approximate stress field can be also projected on a continuous piecewise space:

field square-stress-P2.field -comp 01 -elevation -proj

The tridimensional case writes simply (see Fig. 2.4):

./stress < cube-P1.field > cube-stress-P1.field ./stress < cube-P2.field > cube-stress-P2.field field cube-stress-P1.field -comp 01 -stereo field cube-stress-P2.field -comp 01 -stereo and also the P1-projected versions write:

field cube-stress-P1.field -comp 01 -stereo -proj field cube-stress-P2.field -comp 01 -stereo -proj

These operations can be repeated for each σ ij components and for both P1 and P2 approximation of the deformation field.

Mesh adaptation

The main principle of the auto-adaptive mesh writes [START_REF] Hecht | BAMG: bidimensional anisotropic mesh generator[END_REF][START_REF] Borouchaki | Mailleur bidimensionnel de Delaunay gouverné par une carte de métriques[END_REF][START_REF] Castro-Diaz | Anisotropic unstructured mesh adaption for flow simulations[END_REF][START_REF] Vallet | Génération de maillages anisotropes adaptés, application à la capture de couches limites[END_REF][START_REF] Roquet | Errors estimate for a viscoplastic fluid by using Pk finite elements and adaptive meshes[END_REF]:

din >> omega; uh = solve(omega); for (unsigned int i = 0; i < n; i++) { ch = criterion(uh); omega = adapt(ch); uh = solve(omega); }

The initial mesh is used to compute a first solution. The adaptive loop compute an adaptive criterion, denoted by ch, that depends upon the problem under consideration and the polynomial approximation used. Then, a new mesh is generated, based on this criterion. A second solution on an adapted mesh can be constructed. The adaptation loop converges generally in roughly 5 to 20 iterations. Let us apply this principle to the elasticity problem.

Comments

The criterion is here:

c h = |u h | when using P 1 (σ(u h ) : D(u h )) 1/2 when using P 2
The elasticity_criterion function compute it as return interpolate ( Xh , norm ( uh )); when using P 1 , and as return interpolate ( T0h , sqrt (2* norm2 ( D ( uh )) + lambda * sqr ( div ( uh )))); when using P 2 . The sqr function returns the square of a scalar. Conversely, the norm2 function returns the square of the norm. In the min program, the result of the elasticity_criterion function is send to the adapt function:

field ch = elasticity_criterion ( lambda , uh ); omega = adapt ( ch , options );

The adapt_option declaration is used by Rheolef to send options to the mesh generator. The err parameter controls the error via the edge length of the mesh: the smaller it is, the smaller the edges of the mesh are. In our example, is set by default to one. Conversely, the hmin parameter controls minimal edge length. The compilation command writes:

How to run the program

make embankment_adapt
The mesh loop adaptation is initiated from a bamg mesh (see also appendix A.2.1). Note that the '.gz' suffix is automatically assumed by the geo and the field commands. For a piecewise quadratic approximation:

./embankment_adapt square P2 5e-3

Then, the visualization writes:

geo square-005.geo field square-005.field -nofill

A one-dimensional mesh adaptive procedure is also possible: gmsh -1 line.mshcad -format msh2 -o line.msh msh2geo line.msh > line.geo geo line.geo ./embankment_adapt line P2 1e-3 geo line-005.geo field line-005.field -comp 0 -elevation

The three-dimensional extension of this mesh adaptive procedure is in development. (S) find u = (u 0 , . . . , u d-1 ) and p defined in Ω such that:

The Stokes problem

div(2D(u))

+ ∇p = 0 in Ω, -div u = 0 in Ω, u = (1, 0) on Γ top , u = 0 on Γ left ∪ Γ right ∪ Γ bottom , ∂u 0 ∂n = ∂u 1 ∂n = u 2 = 0 on Γ back ∪ Γ front when d = 3,
where D(u) = (∇u + ∇u T )/2. The boundaries are represented on Fig. 2.1, page 44.

The variational formulation of this problem expresses:

(V F S) find u ∈ V(1) and p ∈ L 2 0 (Ω) such that: a(u, v) + b(v, p) = 0, ∀v ∈ V(0), b(u, q) = 0, ∀q ∈ L 2 0 (Ω),
where

a(u, v) = Ω 2D(u) : D(v) dx, b(v, q) = - Ω div(v) q dx. V(α) = {v ∈ (H 1 (Ω)) 2 ; v = 0 on Γ left ∪ Γ right ∪ Γ bottom and v = (α, 0) on Γ top }, when d = 2, V(α) = {v ∈ (H 1 (Ω)) 3 ; v = 0 on Γ left ∪ Γ right ∪ Γ bottom , v = (α, 0, 0) on Γ top and v 2 = 0 on Γ back ∪ Γ front }, when d = 3, L 2 0 (Ω) = {q ∈ L 2 (Ω); Ω q dx = 0}.

Approximation

The [START_REF] Hood | A numerical solution of the Navier-Stokes equations using the finite element technique[END_REF] finite element approximation of the Stokes problem is considered. We introduce a mesh T h of Ω and the following finite dimensional spaces:

X h = {v ∈ (H 1 (Ω)) d ; v /K ∈ (P 2 ) d , ∀K ∈ T h }, V h (α) = X h ∩ V(α), Q h = {q ∈ L 2 (Ω)) ∩ C 0 ( Ω); q /K ∈ P 1 , ∀K ∈ T h },
The approximate problem writes:

(V F S) h find u h ∈ V h (1) and p ∈ Q h such that: a(u h , v) + b(v, p h ) = 0, ∀v ∈ V h (0), b(u h , q) = 0, ∀q ∈ Q h . ( 2

Comments

The spaces and boundary conditions and grouped in specific functions, defined in file 'cavity.h'. This file is suitable for a future re-usage.

Next, forms are defined as usual, in file 'stokes_cavity.cc'. The problem admits the following matrix form:

a trans(b) b 0 uh ph = 0 0
An initial value for the pressure field is provided:

field ph ( Qh , 0);
The solve call to the Stokes problem writes:

problem_mixed stokes (a , b ); stokes . solve ( field ( Xh ,0) , field ( Qh ,0) , uh , ph );

The two first arguments of the solve member function represents the zero right-hand-side of the problem. For two-dimensional geometries (d = 2), this system is solved by a direct method (see Saramito, 2016b, p. 41). Conversely, for tridimensional geometries (d = 3), it is solved by the preconditioned conjugate gradient algorithm (see Saramito, 2016b, p. 56). In that case, the preconditioner is by default the mass matrix mp for the pressure space: as showed by [START_REF] Klawonn | An optimal preconditioner for a class of saddle point problems with a penalty term[END_REF], the number of iterations need by the conjugate gradient algorithm to reach a given precision is then independent of the mesh size. For more details, see the Rheolef reference manual related to mixed solvers, available on the web site and via the unix command:

man problem_mixed

How to run the program

We assume that the previous code is contained in the file 'stokes_cavity.cc'. Then, compile the program as usual (see page 16): make stokes_cavity and enter the commands:

Computing the vorticity

Formulation and approximation

When d = 2, we define [Girault and Raviart, 1986, page 30] for any distributions ϕ and v:

curl ϕ = ∂ϕ ∂x 1 , - ∂ϕ ∂x 0 , curl v = ∂v 1 ∂x 0 - ∂v 0 ∂x 1 ,
and when d = 3:

curl v = ∂v 2 ∂x 1 - ∂v 1 ∂x 2 , ∂v 0 ∂x 2 - ∂v 2 ∂x 0 , ∂v 1 ∂x 0 - ∂v 0 ∂x 1
Let u be the solution of the Stokes problem (S). The vorticity is defined by:

ω = curl u when d = 2, ω = curl u when d = 3.
Since the approximation of the velocity is piecewise quadratic, we are looking for a discontinuous piecewise linear vorticity field that belongs to:

Y h = {ξ ∈ L 2 (Ω); ξ /K ∈ P 1 , ∀K ∈ T h }, when d = 2 Y h = {ξ ∈ (L 2 (Ω)) 3 ; ξ i/K ∈ P 1 , ∀K ∈ T h }, when d = 3
The approximate variational formulation writes:

ω h ∈ Y h , Ω ω h ξ dx = Ω curl u h ξ dx, ∀ξ ∈ Y h when d = 2, ω ∈ Y h , Ω ω h .ξ dx = Ω curl u h .ξ dx, ∀ξ ∈ Y h when d = 3.
File 2.9: vorticity.cc string grad_approx = " P " + to_string ( Xh . degree () -1) + " d " ;

string valued = ( uh . get_geo (). dimension () == 3) ? " vector " : " scalar " ;

space Lh ( uh . get_geo () , grad_approx , valued ); field curl_uh = lazy_interpolate ( Lh , curl ( uh ));

dout << catchmark ( " w " ) << curl_uh ;

}

Comments

As for the stress tensor (see stress.cc, page 48), the vorticity is obtained by a direct interpolation of the u h first derivatives and its approximation is discontinuous at inter-element boundaries. and you observe a discontinuous piecewise linear representation of the approximate vorticity. Also, the vorticity presents two sharp peaks at the upper corners of the driven cavity: the vorticity is unbounded and the peaks will increase with mesh refinements. This singularity of the solution is due to the boundary condition for the first component of the velocity u 0 that jumps from zero to one at the corners. The approximate vorticity field can also be projected on a continuous piecewise linear space, using the -proj option (See Fig. 2.7 left):

How to run the program

./vorticity < square.field | field -elevation -stereo -nofill -./vorticity < square.field | field -elevation -stereo -proj -For d = 3, the whole vorticity vector can also be visualized (See Fig. 2.7 right):

./vorticity < cube.field | field -proj -velocity -stereo -

In the previous command, the -proj option has been used: since the 3D render has no support for discontinuous piecewise linear fields, the P1-discontinuous field is transformed into a P1-continuous one, thanks to a L 2 projection. P1 The following command shows the second component of the vorticity vector, roughly similar to the bidimensional case.

./vorticity < cube.field | field -comp 1 -./vorticity < cube.field | field -comp 1 -proj -

Computing the stream function

Formulation and approximation

When d = 3, the stream function is a vector-valued field ψ that satisfies [Girault and Raviart, 1986, page 90]: curl ψ = u and div ψ = 0. From the identity:

curl curl ψ = -∆ψ + ∇(div ψ)
we obtain the following characterization of ψ :

-∆ ψ = curl u in Ω, ψ = 0 on Γ back ∪ Γ front ∪ Γ top ∪ Γ bottom , ∂ψ ∂n = 0 on Γ left ∪ Γ right .
When d = 2, the stream function ψ is a scalar-valued field the solution of the following problem [Girault and Raviart, 1986, page 88]:

-∆ ψ = curl u in Ω, ψ = 0 on ∂Ω.
File 2.10: streamf_cavity.cc ./streamf_cavity < cube.field | field -velocity -scale 10 -

The second component of the stream function is showed by:

./streamf_cavity < cube.field | field -comp 1 -

The combined representation of Fig. 2.8.right has been obtained in two steps. First, enter:

./streamf_cavity < cube.field | field -comp 1 -noclean -noexecute -name psi1 -./streamf_cavity < cube.field | field -velocity -scale 10 -

The -noclean -noexecute options cause the creation of the '.vtk' file for the second component, without running the paraview visualization. Next, in the paraview window associated to the whole stream function, select the File->Open menu and load 'psi1.vtk' and click on the green button Apply. Finally, select the Filters/Common/Contours menu: the isosurface appears.

Observe that the 3D stream function is mainly represented by its second component.

Nearly incompressible elasticity and the stabilized Stokes problems

The incompressible elasticity problem

Formulation

Let us go back to the linear elasticity problem. When λ becomes large, this problem is related to the incompressible elasticity and cannot be solved as it was previously done. To overcome this difficulty, the pressure is introduced :

p = -λdiv u
and the problem becomes:

(E) find u and p defined in Ω such that:

div(2D(u))

+ ∇p = f in Ω, -div u - 1 λ p = 0 in Ω, +B.C.
The variational formulation of this problem expresses:

(V F E) find u ∈ V (1) and p ∈ L 2 (Ω) such that: a(u, v) + b(v, p) = m(f , v), ∀v ∈ V (0), b(u, q) -c(p, q) = 0, ∀q ∈ L 2 0 (Ω), where m(u, v) = Ω u.v dx, a(u, v) = Ω D(u) : D(v) dx, b(v, q) = - Ω div(v) q dx. c(p, q) = 1 λ Ω p q dx. V = {v ∈ (H 1 (Ω)) 2 ; v = 0 on Γ lef t ∪ Γ bottom }
When λ becomes large, we obtain the incompressible elasticity problem, that coincides with the Stokes problem.

Approximation

As for the Stokes problem, the [START_REF] Hood | A numerical solution of the Navier-Stokes equations using the finite element technique[END_REF] finite element approximation is considered. We introduce a mesh T h of Ω and the following finite dimensional spaces:

X h = {v ∈ (H 1 (Ω)); v /K ∈ (P 2 ) 2 , ∀K ∈ T h }, V h (α) = X h ∩ V, Q h = {q ∈ L 2 (Ω)) ∩ C 0 ( Ω); q /K ∈ P 1 , ∀K ∈ T h },
The approximate problem writes:

(V F E) h find u h ∈ V h (1) and p ∈ Q h such that: a(u h , v) + b(v, p h ) = 0, ∀v ∈ V h (0), b(u h , q) -c(p, q) = 0, ∀q ∈ Q h .
File 2.

Comments

The problem admits the following matrix form:

a trans(b) b -c uh ph = lh 0
The problem is similar to the Stokes one (see page 55). This system is solved by: problem_mixed elasticity (a , b , c ); elasticity . solve ( lh , field ( Qh ,0) , uh , ph );

For two-dimensional problems, a direct solver is used by default. In the three-dimensional case, an iterative algorithm is the default: the preconditioned conjugate gradient. The preconditioner is here the mass matrix mp for the pressure. As showed by [START_REF] Klawonn | An optimal preconditioner for a class of saddle point problems with a penalty term[END_REF], the number of iterations need by the conjugate gradient algorithm to reach a given precision is then independent of the mesh size and is uniformly bounded when λ becomes small, i.e. in the incompressible case. We assume that the previous code is contained in the file 'incompressible-elasticity.cc'. The visualization is performed as usual: see section 2.1.1, page 45. Compare the results on Fig. 2.9, obtained for λ = +∞ with those of Fig. 2.2, page 46, obtained for λ = 1. Finally, the stress computation and the mesh adaptation loop is left as an exercise to the reader.

How to run the program

2.2.2

The P 1 b -P 1 element for the Stokes problem

Formulation and approximation

Let us go back to the Stokes problem. In section 2.1.4, page 53, the Taylor-Hood finite element was considered. Here, we turn to the mini-element proposed by [START_REF] Arnold | A stable finite element for the Stokes equations[END_REF], also well-known as the P1-bubble element. This element is generally less precise than the Taylor-Hood one, but becomes popular, mostly because it is easy to implement in two and three dimensions and furnishes a P 1 approximation of the velocity field. Moreover, this problem develops some links with stabilization technique and will presents some new Rheolef features.

We consider a mesh T h of Ω ⊂ R d , d = 2, 3 composed only of simplicial elements: triangles when d = 2 and tetrahedra when d = 3. The following finite dimensional spaces are introduced:

X (1) h = {v ∈ (H 1 (Ω)) d ; v /K ∈ (P 1 ) d , ∀K ∈ T h }, B h = {β ∈ (C 0 ( Ω)) d ; β /K ∈ B(K) d , ∀K ∈ T h } X h = X (1) h ⊕ B h V h (α) = X h ∩ V(α), Q h = {q ∈ L 2 (Ω)) ∩ C 0 ( Ω); q /K ∈ P 1 , ∀K ∈ T h },
where B(K) = vect(λ 1 × . . . × λ d+1 ) and λ i are the barycentric coordinates of the simplex K. The B(K) space is related to the bubble local space. The approximate problem is similar to (2.4), page 54, up to the choice of finite dimensional spaces.

Remark that the velocity field splits in two terms:

u h = u (1) h +u (b) h , where u (1) h ∈ X (1)
h is continuous and piecewise linear, and u

(b)
h ∈ B h is the bubble term. We consider the abrupt contraction geometry:

Ω =]-L u , 0[×]0, c[ ∪ [0, L d [×]0, 1[
where c ⩾ 1 stands for the contraction ratio, and L u , L d > 0, are the upstream and downstream tube lengths. The boundary conditions on u = (u 0 , u 1 ) for this test case are: u 0 = u poiseuille and u 1 = 0 on Γ upstream u = 0 on Γ wall ∂u 0 ∂x 1 = 0 and u 1 = 0 on Γ axis ∂u ∂n = 0 on Γ downstream where

Γ upstream = {-L u }×]0, c[ Γ downstream = {L d }×]0, 1[ Γ axis = ]-L u , L d [×{0} Γ wall = ]-L u , 0[×{c} ∪ {0}×]1, c[ ∪ ]0, L d [×{1}
The matrix structure is similar to those of the Taylor-Hood element (see section 2.1.4, page 53). Since X h = X

(1)

h ⊕ B h , any element u h ∈ X h can be written as a sum u h = u 1,h + u b,h where u 1,h ∈ X (1) h and u b,h ∈ B h . Remark that a(u 1,h , v b,h ) = 0, ∀u 1,h ∈ X (1) h , ∀v b,h ∈ B h .
Thus, the form a(., .) defined over X h × X h writes simply as the sum of the forms a 1 (., .) and a b (., .), defined over

X (1) h × X (1)
h and B h × B h respectively. Finally, the form b(., .) defined over X h × Q h writes as the sum of the forms b 1 (., .) and b b (., .), defined over X

(1) h × Q h and B h × Q h respectively. Then, the linear system admits the following block structure :

  A 1 0 B T 1 0 A b B T b B 1 B b 0     U 1 U b P   =   L 1 L b L p  
An alternative and popular implementation of this element eliminates the unknowns related to the bubble components (see e.g. Abdalass, 1987, page 24). Remark that, on any element K ∈ T h , any bubble function v K that belongs to B(K) vanishes on the boundary of K and have a compact support in K. Thus, the A b matrix is block-diagonal. Moreover, A b is invertible and U b writes :

U b = A -1 b (B T b p -L b )
As A b is block-diagonal, its inverse can be efficiently inverted at the element level during the assembly process. Then, U b can be easily eliminated from the system that reduces to:

A 1 B T 1 B 1 -C U 1 P = L 1 Lp where Lp = L p -A -1 b L p and C = B b A -1 b B T b .
Remarks that the matrix structure is similar to those of the nearly incompressible elasticity (see 2.2.1, page 2.2.1). This reduced matrix formulation of the P 1 b -P 1 element is similar to the direct P 1 -P 1 stabilized element, proposed by [START_REF] Brezzi | On the stabilization of finite element approximation of the Stokes equations[END_REF].

File 2.12: stokes_contraction_bubble.cc # include " rheolef . h " using namespace rheolef ; using namespace std ; # include " contraction . h " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); geo omega ( argv [1]); space X1h = contraction :: velocity_space ( omega , " P1 " ); space Bh ( omega , " bubble " , " vector " ); space Qh ( omega , " P1 " ); trial u1 ( X1h ) , ub ( Bh ) , p ( Qh ); test v1 ( X1h ) , vb ( Bh ) , q ( Qh ); form b1 = integrate ( -div ( u1 )* q ); form bb = integrate ( -div ( ub )* q ); The file 'contraction.h' contains code for the velocity and stream function boundary conditions. Without loss of generality, we assume that the half width of the downstream channel is assumed to be equal to one. The Poiseuille velocity upstream boundary condition u_upsteam is then scaled such that the downstream average velocity is equal to one. By this way, the flow rate in the half upstream and downstream channel are also equal to one. The stream function is defined up to a constant: we assume that it is equal to -1 on the axis of symmetry: by this way, it is equal to zero on the wall. The file 'contraction.h' also contains a treatment of the axisymmetric variant of the geometry: this case will be presented in the next paragraph. Note also the automatic computation of the geometric coordinate system and contraction ratio c from the input mesh, as: In the axisymmetric coordinate system, there is a specific definition of the stream function, together with the use of a variant of the curl operator, denoted as bcurl in Rheolef.

field lh = integrate ( dot ( uh , bcurl ( xi )));

The axisymmetric case will be presented in the next section. By this way, our code is able to deal with both Cartesian and axisymmetric geometries. The stream function ψ (see also section 2.1.6) is computed and visualized as: make streamf_contraction ./streamf_contraction < contraction-P1.field > contraction-P1-psi.field field contraction-P1-psi.field field contraction-P1-psi.field -n-iso 15 -n-iso-negative 10 -bw

The P 1 stream function is represented on Fig. 2.10.center. The stream function is zero along the wall and the line separating the main flow and the vortex located in the outer corner of the contraction. Thus, the isoline associated to the zero value separates the main flow from the vortex.

In order to observe this vortex, an extra -n-iso-negative 10 option is added: ten isolines are drawn for negatives values of ψ, associated to the main flow, and n_iso-10 for the positives values, associated to the vortex.

A similar computation based on the Taylor-Hood P 2 -P 1 element is implemented in stokes_contraction.cc.

The code is similar, up to the boundary conditions, to stokes_cavity.cc (see page 54): thus it is not listed here but is available in the Rheolef example directory. make stokes_contraction ./stokes_contraction contraction.geo > contraction-P2.field field contraction-P2.field -velocity ./streamf_contraction < contraction-P2.field > contraction-P2-psi.field field contraction-P2-psi.field -n-iso-negative 10 -bw

The associated P 2 stream function is represented on Fig. 2.10.bottom. Observe that the two solutions are similar and that the vortex activity, defined as ψ max , is accurately computed with the two methods (see also Saramito, 1990, Fig. 5.11.a, page 143).

field contraction-P1-psi.field -max field contraction-P2-psi.field -max Recall that the stream function is negative in the main flow and positive in the vortex located in the outer corner of the contraction. Nevertheless, the Taylor-Hood based solution is more accurate : this is perceptible on the graphic, in the region where the upstream vortex reaches the boundary.

Axisymmetric geometries

Axisymmetric geometries are fully supported in Rheolef: the coordinate system is associated to the geometry description, stored together with the mesh in the '.geo' and this information is propagated in spaces, forms and fields without any change in the code. Thus, a code that works in plane a 2D plane geometry is able to support a 3D axisymmetric one without changes. A simple axisymmetric geometry writes: mkgeo_grid -t 10 -zr > square-zr.geo more square-zr.geo Remark the additional line in the header:

coordinate_system zr

The axis of symmetry is denoted as z while the polar coordinates are (r, θ). By symmetry, the problem is supposed to be independent upon θ and the computational domain is described by (x 0 , x 1 ) = (z, r). Conversely, in some cases, it could be convenient to swap the order of the coordinates and use (r, z): this feature is obtained by the -rz option: mkgeo_grid -t 10 -rz > square-rz.geo more square-rz.geo Axisymmetric problems uses L 2 functional space equipped with the following weighted scalar product

(f, g) = Ω f (z, r) g(z, r) r drdz
and all usual bilinear forms support this weight. Thus, the coordinate system can be chosen at run time and we can expect an efficient source code reduction.

The axisymmetric stream function and stress tensor

In the axisymmetric case, the velocity field u = (u z , u r ) can be expressed in terms of the Stokes stream function ψ by (see Batchelor Batchelor, 1967, p.453 andWikipedia, 2012):

u = (u z , u r ) = 1 r ∂ψ ∂r , - 1 r ∂ψ ∂z (2.5)
Recall that in the axisymmetric case:

curl ψ = 1 r ∂(rψ) ∂r , - ∂ψ ∂z
Thus, from this definition, in axisymmetric geometries u ̸ = curl ψ and the definition of ψ differs from the 2D plane or 3D cases (see section 2.1.6, page 58).

Let us turn to a variational formulation in order to compute ψ from u. For any ξ ∈ H 1 (Ω), let us multiply (2.5) by v = (∂ r ξ, -∂ z ξ) and then integrate over Ω with the r dr dz weight. For any known u velocity field, the problem writes:

(P): find ψ ∈ Ψ(ψ Γ ) such that a(ψ, ξ) = l(ξ), ∀ξ ∈ Ψ(0)
where we have introduced the following bilinear forms: The iopt.ignore_sys_coord alows us to drops the r integration weight, i.e. replace r dr dz by dr dz when computing the a(., .) form. Conversely, l involves the bcurl operator defined as:

a(ψ, ξ) = Ω ∂ψ
bcurl ξ = ∂ξ ∂r , - ∂ξ ∂z
It is is closely related but differs from the standard curl operator:

curl ξ = 1 r ∂(rξ) ∂r , - ∂ξ ∂z
The bcurl operator is a specific notation introduced in Rheolef: it coincides with the usual curl operator except for axisymmetric geometries. In tht case, it refers to the Batchelor trick, suitable for the computation of the stream function.

As an example, let us reconsider the contraction geometry (see section 2.2.2, page 62), extended in the axisymmetric case. In that case, the functional space is defined by:

Ψ(ψ Γ ) = {φ ∈ H 1 (Ω); φ = ψ Γ on Γ upstream ∪ Γ wall ∪ Γ axis } with ψ Γ =    ψ poiseuile on Γ upstream 0 on Γ wall -1 on Γ axis
This space corresponds to the imposition of Dirichlet boundary conditions on Γ upstream , Γ wall and Γ axis and a Neumann boundary condition on Γ downstream .

The following unix commands generate the axisymmetric geometry:

gmsh -2 contraction.mshcad -format msh2 -o contraction.msh msh2geo -zr contraction.msh > contraction-zr.geo more contraction-zr.geo geo contraction-zr.geo The previous code stokes_contraction.cc and streamf_contraction.cc are both reused as:

ψ max = 1.84 × 10 -3
./stokes_contraction contraction-zr.geo > contraction-zr-P2.field ./streamf_contraction < contraction-zr-P2.field > contraction-zr-P2-psi.field field contraction-zr-P2-psi.field -n-iso-negative 10 -bw

The solution is represented on Fig. 2.11: it slightly differs from the 2D Cartesian solution, as computed in the previous section (see Fig. 2.10). The vortex size is smaller but its intensity ψ max = 1.84 × 10 -3 is higher. Despite the stream functions looks like similar, the plane solutions are really different, as we can observe from a cut of the first component of the velocity along the axis (see Fig. 2.12):

field contraction-P2.field -comp 0 -cut -normal 0 1 -origin 0 1e-15 -gnuplot field contraction-zr-P2.field -comp 0 -cut -normal 0 1 -origin 0 1e-15 -gnuplot The 1e-15 argument replace the zero value, as the mesh intersection cannot yet be done exactly on the boundary. Note that the stokes_contraction_bubble.cc can be also reused in a similar way:

./stokes_contraction_bubble contraction-zr.geo > contraction-zr-P1.field ./streamf_contraction < contraction-zr-P1.field > contraction-zr-P1-psi.field field contraction-zr-P1-psi.field -n-iso-negative 10 -bw There is another major difference with axisymmetric problems: the rate of deformation tensor writes:

τ = 2D(u) =   τ zz τ rz 0 τ rz τ rr 0 0 0 τ θθ   0 1 2 3 4 -8 -4 0 2 u 0 (z, 0) z axisymetric cartesian -2 -1 0 -8 -4 0 2 τ θθ (z, 0) z Figure 2
.12: Solution of the plane and axisymmetric Stokes problem in the abrupt contraction: cut along the axis of symmetry: (left): u 0 ; (right) τ θθ .

Thus, there is an additional non-zero component τ θθ that is automatically integrated into the computations in Rheolef. The incompressibility relation leads to tr(τ ) = τ zz + τ rr + τ θθ = 0.

Here σ tot = -p.I + τ is the total Cauchy stress tensor (by a dimensionless procedure, the viscosity can be taken as one). By reusing the stress.cc code (see page 48) we are able to compute the tensor components: make stress ./stress < contraction-zr-P1.field > contraction-zr-P1-tau.field

The visualization along the axis of symmetry for the τ θθ component is obtained by (see Fig. 2.12):

field contraction-zr-P1-tau.field -comp 22 -proj -cut -normal 0 1 -origin 0 1e-15 -gnuplot

Recall that the τ zz and τ rr components are obtained by the -comp 00 and -comp 11 options, respectively. The non-zero values along the axis of symmetry expresses the elongational effects in the entry region of the abrupt contraction.

[New] Slip boundary conditions

Formulation

We consider an approximation of the Stokes problem with slip boundary conditions. As a test case, we consider the flow around a circular obstacle, as represented on Fig. 2.13. We assume a permanent flow and: due to the symmetries versus upstream/downstream and with respect to the horizontal axis, the computational domain reduces to the quarter of the geometry. This problem writes [START_REF] Verfürth | Finite element approximation of incompressible Navier-Stokes equations with slip boundary condition[END_REF]:

x 1 x 0 0 1 Γ obstacle Γ wall Γ axis L c 1 Γ downstream Ω Γ vaxis
Γ wall ∪ Γ axis ∪ Γ obstacle : u.n = 0 and σ nt = 0 Γ vaxis : u t = 0 and σ nn = 0 Γ downstream : u = (1, 0) (P ): find u and p, defined in Ω, such that

                   σ = -pI + 2D(u) in Ω -div σ = 0 in Ω -div u = 0 in Ω u.n = 0 and σ nt = 0 on Γ wall ∪ Γ axis ∪ Γ obstacle u t = 0 and σ nn = 0 on Γ vaxis u = e 0 on Γ downstream (2.6a) (2.6b) (2.6c) (2.6d) (2.6e) (2.6f)
with the notation v t = v -(v.n)n, τ nn = (τ n).n and τ nt = τ n -τ nn n for any vector v and tensor τ . Observe that Γ wall , Γ axis and Γ vaxis are parallel to the coordinate axis: the corresponding slip boundary condition writes also

u d-1 = 0 and σ i,d-1 = 0 on Γ wall ∪ Γ axis , 1 ⩽ i ⩽ d -2 u i = 0 and σ 0,0 = 0 on Γ vaxis , 1 ⩽ i ⩽ d -1
It remains one slip boundary condition on the curved boundary domain Γ obstacle : imposing such a boundary condition is the main difficulty of this problem. There are mainly three approaches for the imposition of this boundary condition: (i) the regularization ; (ii) the Lagrange multiplier weak imposition ; (iii) the strong imposition. The main drawback of the Lagrange multiplier weak imposition approach is the discretization of the Lagrange multiplier λ, that should satisfy the infsup condition [START_REF] Verfürth | Finite element approximation of incompressible Navier-Stokes equations with slip boundary condition[END_REF], 1991[START_REF] Liakos | Discretization of the Navier-Stokes equations with slip boundary condition[END_REF][START_REF] Caglar | Weak imposition of boundary conditions for the Navier-Stokes equations by a penalty method[END_REF]]. An alternative is to introduce stabilization terms (Verfürth, 1991, p. 621, eqn (4.1)), but the resulting problem is no more symmetric. The strong imposition [START_REF] Verfürth | Finite element approximation of steady Navier-Stokes equations with mixed boundary conditions[END_REF] requires some modifications of the finite element basis along the slip boundary: this promising feature is in development in the Rheolef library. The rest of this section focuses on the regularization approach. The main idea of the regularization approach is to replace the slip boundary condition (2.6d) on the curved boundary domain Γ obstacle by Robin one:

σ nt + ε -1 u.n = 0 on Γ obstacle
where ε > 0 is the regularization parameter. It leads to the following variational formulation:

(F V ) ε : find u ∈ V (1) and p ∈ L 2 (Ω) such that a(u, v) + b(v, p) = 0, ∀v ∈ V (0) b(u, q) = 0, ∀q ∈ L 2 (Ω) with a(u, v) = Ω 2D(u) : 2D(v) dx + ε -1 ∂Ω (u.n)(v.n) ds b(v, q) = - Ω q div v dx V (α) = v ∈ H 1 (Ω) d / v = αe 0 on Γ downstream and u i = 0 on Γ vaxis , 1 ⩽ i ⩽ d -1 and u d-1 = 0 on Γ wall ∪ Γ axis }

Approximation

The curved boundary ∂Ω is replaced polynomial approximation ∂T h . Then, a natural procedure would be to replace the the normal n on ∂Ω by the normal n h on ∂T h in the previous expression of the bilinear form a. This approach do not converge in general and this counter-intuitive feature is called the Babuška paradox, see e.g. Verfürth [1985, p. 473]. We have to deal with either the exact normal n or a more accurate approximation n h of n. In the present case, as the exact normal n is known, we use it.

Otherwise, the space V (α) is completely standard, for any α ∈ R and can be approximated by classical Lagrange finite elements. Thus, the [START_REF] Hood | A numerical solution of the Navier-Stokes equations using the finite element technique[END_REF] finite element approximation of the Stokes problem is considered. The present implementation 'stokes_obstacle_slip_regul.cc' supports both the 2D Cartesian and the 3D axisymmetric cases, so the 3D Cartesian case is not implemented here. Note that the 2D Cartesian case corresponds to a 3D cylindrical obstacle while the 3D axisymmetric case corresponds to a spherical obstacle. The 'streamf_obstacle_slip_move.cc' computes the stream function the modified velocity field u h = e 0 -u h relative to the moving obstacle. Let us turn to the cut of the relative velocity along the horizontal and vertical axis, named respectively axis and vaxis by the mesh:

field obstacle-zr.field -domain vaxis -comp 0 -gnuplot -elevation field obstacle-zr.field -domain axis -comp 0 -gnuplot -elevation

Observe on Fig. 2.15.left that the relative velocity is negative on the top of the obstacle. Indeed, when the obstacle moves right, the fluid moves from the front of the obstacle, rotates around the obstacle and goes to the back. Thus, the fluid moves in the negatives direction when it is on the top of the obstacle. Also, observe that the fluid is more accelerated when it flows around a cylinder than around a sphere. Fig. 2.15.right shows that the perturbation caused by the fluid decreases faster for a sphere than for a cylinder.

Time-dependent problems

2.4.1 The heat equation

Formulation Let T > 0, Ω ⊂ R d , d = 1, 2, 3 and f defined in Ω.
The heat problem writes:

(P ): find u, defined in Ω×]0, T [, such that ∂u ∂t -∆u = f in Ω×]0, T [, u(0) = 0 in Ω, u(t) = 0 on ∂Ω×]0, T [.
where f is a known function. In the present example, we consider f = 1.

Approximation

Let ∆t > 0 and t n = n∆t, n ⩾ 0. The problem is approximated with respect to time by the following first-order implicit Euler scheme:

u n+1 -u n ∆t -∆u n+1 = f (t n+1 ) in Ω
where u n ≈ u(n∆t) and u (0) = 0. The variational formulation of the time-discretized problem writes:

(V F ) n : Let u n being known, find u n+1 ∈ H 1 0 (Ω) such that a (u n+1 , v) = l (n) (v), ∀v ∈ H 1 0 (Ω).
where

a(u, v) = Ω (uv + ∆t ∇u.∇v) v dx l (n) (v) = Ω (u n + ∆t f (t n+1 )) v dx
This is a Poisson-like problem. The discretization with respect to space of this problem is similar to those presented in section 1.1.1, page 14.

File 2.17: heat.cc

The convection-diffusion problem

Formulation

Let T > 0 and ν > 0. The convection-diffusion problem writes:

(P ): find ϕ, defined in Ω×]0, T [, such that ∂ϕ ∂t + u.∇ϕ -ν∆ϕ + σϕ = 0 in Ω×]0, T [ ϕ(0) = ϕ 0 in Ω ϕ(t) = ϕ Γ (t) on ∂Ω×]0, T [
where u, σ ⩾ 0, ϕ 0 and ϕ Γ being known. Note the additional u.∇ operator.

Time approximation

This problem is approximated by the following first-order implicit Euler scheme:

ϕ n+1 -ϕ n • X n ∆t -ν∆ϕ n+1 + σϕ n+1 = 0 in Ω where ∆t > 0, ϕ n ≈ ϕ(n∆t) and ϕ (0) = ϕ 0 . Let t n = n∆t, n ⩾ 0. The term X n (x)
is the position at t n of the particle that is in x at t n+1 and is transported by u n . Thus, X n (x) = X(t n , x) where X(t, x) is the solution of the differential equation

dX dt = u(X(t, x), t) p.p. t ∈ ]t n , t n+1 [, X(t n+1 , x) = x.
Then X n (x) is approximated by the first-order Euler approximation

X n (x) ≈ x -∆t n n (x).
This algorithm has been introduced by O. Pironneau (see e.g. [START_REF] Pironneau | Méthode des éléments finis pour les fluides[END_REF], and is known as the method of characteristic in the finite difference context and as the Lagrange-Galerkin in the finite element one. The efficient evaluation of ϕ h • X n (x) in an unstructured mesh involves a hierarchical d-tree (quadtree, octree) data structure for the localization of the element K of the mesh that contains x. When d = 3 requires also sophisticated geometric predicates to test whether x ∈ K without rounding errors, and avoid to conclude that no elements contains a point x close to ∂K up to rounding errors. This problems is addressed in Rheolef based on the cgal library.

The following code implements the classical rotating Gaussian hill test case (see e.g. [START_REF] Rui | A second order characteristic finite element scheme for convection diffusion problems[END_REF].

Comments

The characteristic variable X implements the localizer X n (x):

characteristic X ( -delta_t * uh );

Combined with the compose function, it perform the composition ϕ h • X n . The right-hand side is then computed by using the integrate function:

field lh = integrate ( compose ( phi_h , X )* psi , iopt );
Note the additional iopt argument to the integrate function. By default, when this argument is omitted, a Gauss quadrature formulae is assumed, and the number of point is computed such that it integrate exactly 2k + 1 polynomials, where k is the degree of polynomials in X h . The Gauss-Lobatto quadrature formule is recommended for Lagrange-Galerkin methods. Recall that this choice of quadrature formulae guaranties inconditionnal stability at any polynomial order. Here, we specifies a Gauss-Lobatto quadrature formulae that should be exact for k order polynomials. The bilinear form is computed via the same quadrature formulae:

form a = integrate ( c1 * phi * psi + c2 * dot ( grad ( phi ) , grad ( psi )) , iopt );

A test case is described by [START_REF] Pironneau | Stability and convergence of a galerkin-characteristics finite element scheme of lumped mass type[END_REF]: we take Ω =] -2, 2[ d and T = 2π. This problem provides an example for a convection-diffusion equation and a known analytical solution:

ϕ(t, x) = exp -λt -r(t)|x -x 0 (t)| 2
where λ = 4ν/t 0 ⩾ 0 with t 0 > 0 and ν ⩾ 0, x 0 (t) is the moving center of the hill and r(t) = 1/(t 0 + 4νt). The source term is time-dependent: σ(t) = λ -2dνr(t) and has been adjusted such that the right-hand side is zero. The moving center of the hill x 0 (t) is associated to the velocity field u(t, x) as: Note the use of a class-function phi for the implementation of ϕ(t) as a function of x. Such programming style has been introduced in the standard template library [Musser and Saini, 1996b], which is a part of the standard C++ library. By this way, for a given t, ϕ(t) can be interpolated as an usual function on a mesh.

d u(t, x) x 0 (t) 1 1/(2π) t/(2π) -1/2 2 (y, -x) (-cos(t)/2, sin(t)/2) 3 (y, -x, 0) (-cos(t)/2, sin(t)/2, 0) File 2.19: rotating-hill.h struct u { point operator () ( const point & x ) const { return ( d == 1) ? point ( u0 ) : point ( x [1] , -x [0]); } u ( size_t d1 ) : d ( d1 ) , u0 (0.5/ acos ( Float ( -1))) {} protected : size_t d ; Float u0 ; }; struct phi { Float operator () ( const point & x ) const { return exp ( -4* nu *( t / t0 ) -dist2 (x , x0t ())/( t0 +4* nu * t )); } phi ( size_t d1 , Float nu1 , Float t1 =0) : d ( d1 ) , nu ( nu1 ) , t ( t1 ) , u0 (0.5/ acos ( Float ( -1))) , x0 ( -0.5 ,0) {} static Float sigma ( size_t d , Float nu1 , Float t =0) { return 4* nu1 / t0 -2* d * nu1 /( t0 + 4* nu1 * t ); } point x0t () const { if ( d == 1) return point ( x0 [0] + u0 * t ); return point ( x0 [0]* cos ( t ) + x0 [1]* sin ( t ) , -x0 [0]* sin ( t ) + x0 [1]* cos ( t )); } point d_x0t_dt () const { if ( d == 1)

How to run the program

We assume that the previous code is contained in the file 'convect.cc'. Then, compile the program as usual (see page 16): make convect and enter the commands: Running the one-dimensional test case:

mkgeo_grid -e 500 -a -2 -b 2 > line2.geo ./convect line2.geo P1 > line2.branch branch line2.branch -gnuplot Note the hill that moves from x = -1/2 to x = 1/2. Since the exact solution is known, it is possible to analyze the error: Float nu ; din >> catchmark ( " nu " ) >> nu ; branch get ( " t " ," phi " ); branch put ( " t " ," phi_h " ," pi_h_phi " ); derr << " # t \ terror_l2 \ terror_linf " << endl ; The numerical error ϕ h -π h (ϕ) is computed as:

field pi_h_phi = interpolate ( Xh , phi (d , nu , t )); field eh = phih -pi_h_phi ;
and its L 2 norm is printed on the standard error. Observe the use of the branch class as both input and output field stream. make convect_error ./convect_error < line2.branch > line2-cmp.branch branch line2-cmp.branch -gnuplot

The instantaneous L 2 (Ω) norm is printed at each time step and the total error in L

2 (]0, T [; L 2 (Ω))
is finally printed at the end of the stream. A P2 approximation can be used as well:

∥ϕ h -π h (ϕ)∥ L 2 (L 2 ) ∥ϕ h -π h (ϕ)∥ L ∞ (L ∞ ) 0.
(left) in L 2 (L 2 ) norm; (right) in L ∞ (L ∞ ) norm.
./convect line2.geo P2 > line2.branch branch line2.branch -gnuplot ./convect_error < line2.branch > line2-cmp.branch On Fig. 2.18.left we observe the L 2 (L 2 ) convergence versus h for the P 1 and P 2 elements when d = 1: the errors reaches a plateau that decreases versus ∆t. On Fig. 2.18.right the L ∞ (L ∞ ) norm of the error presents a similar behavior. Since the plateau are equispaced, the convergence versus ∆t is of first order. These computation was performed for a convection-diffusion problem with ν = 10 -2 . The pure transport problem (ν = 0, without diffusion) computation is obtained by:

./convect line2.geo P1 0 > line2.branch branch line2.branch -gnuplot

Let us turn to the two-dimensional test case:

mkgeo_grid -t 80 -a -2 -b 2 -c -2 -d 2 > square2.geo ./convect square2.geo P1 > square2.branch branch square2.branch
The visualization and animation are similar to those of the head problem previously presented in paragraph 2.4.1. Go to the WrapByScalar entry in pipeline brower and adjust eventually the scale factor, e.g. to 3. Then, play the animation and observe the rotating hill. The result is shown on Fig. 2.17. The error analysis writes:

./convect_error < square2.branch > square2-cmp.branch branch square2-cmp.branch -nofill -bw -elevation

From the paraview menu, you can visualize simultaneously both the approximate solution and the Lagrange interpolate of the exact one. First, in the pipeline brower go to the WrapByScalar entry and adjust the scale factor, e.g. to 3 and click on Apply. Next, go first to the File->Open menu and select in the /tmp the square2-cmp-..vtk and click on Apply. In the Filter->Alphabetical menu, select WrapByScalar. In the Properties panel, go to the Scalars entry and select pi_h_phi, to the coloring entry and select also pi_h_phi, adjust the scale factor to 3. and click on Apply. Next, in the same panel, in the Representation entry, choose wireframe. You are ready to click on the video play button, at the top of the window. Observe the difference between the solution and its approximation. See also the paraview documentation for more. For serious problem, the characteristic method has been superseded by the discontinuous Galerkin one, that will be presented in chapter 4, page 147. You are strongly encouraged to definitively turn to discontinuous Galerkin method for convection dominant and pure transport problems.

Finally, the three-dimensional case:

mkgeo_grid -T 15 -a -2 -b 2 -c -2 -d 2 -f -2 -g 2 > cube2.geo ./convect cube2.geo P1 > cube2.branch
The visualization is similar to the two-dimensional case: branch cube2.branch branch cube2.branch -volume (N S): find u = (u 0 , . . . , u d-1 ) and p defined in Ω×]0, T [ such that:

The Navier-Stokes equations

Re ∂u ∂t + u.∇u -div(2D(u)) + ∇p = 0 in Ω×]0, T [, -div u = 0 in Ω×]0, T [, u(t = 0) = 0 in Ω × {0, T }, u = (1, 0) on Γ top ×]0, T [, u = 0 on (Γ left ∪ Γ right ∪ Γ bottom )×]0, T [, ∂u 0 ∂n = ∂u 1 ∂n = u 2 = 0 on (Γ back ∪ Γ front )×]0, T [ when d = 3,
where D(u) = (∇u + ∇u T )/2. This nonlinear problem is the natural extension of the linear Stokes problem, as presented in paragraph 2.5, page 84. The boundaries are represented on Fig. 2.1, page 44.

Time approximation

Let ∆t > 0. Let us consider the following backward second order scheme, for all ϕ ∈ C 2 ([0, T ]) :

dϕ dt (t) = 3ϕ(t) -4ϕ(t -∆t) + ϕ(t -2∆t) 2∆t + O(∆t 2 )
The problem is approximated by the following second-order implicit scheme (BDF2):

Re 3u n+1 -4u n • X n + u n-1 • X n-1 2∆t -div(2D(u n+1 )) + ∇p n+1 = 0 in Ω, -div u n+1 = 0 in Ω, u n+1 = (1, 0) on Γ top , u n+1 = 0 on Γ left ∪ Γ right ∪ Γ bottom , ∂u n+1 0 ∂n = ∂u n+1 1 ∂n = u n+1 2 = 0 on Γ back ∪ Γ front when d = 3,
where, following [Boukir et al., 1997, Fourestey and[START_REF] Fourestey | A second-order time-accurate ALE Lagrange-Galerkin method applied to wind engineering and control of bridge profiles[END_REF]]:

X n (x) = x -∆t u * (x) X n-1 (x) = x -2∆t u * (x) u * = 2u n -u n-1
It is a second order extension of the method previously introduced in paragraph 2.4.2 page 79. The scheme defines a second order recurrence for the sequence (u n ) n⩾-1 , that starts with u -1 = u 0 = 0.

Variational formulation

The variational formulation of this problem expresses:

(N S) ∆t : find u n+1 ∈ V(1) and p n+1 ∈ L 2 0 (Ω) such that: a(u n+1 , v) + b(v, p n+1 ) = m(f n , v), ∀v ∈ V(0), b(u n+1 , q) = 0, ∀q ∈ L 2 0 (Ω),
where

f n = Re 2∆t 4 u n • X n -u n-1 • X n and a(u, v) = 3Re 2∆t Ω u.v dx + Ω 2D(u) : D(v) dx
and b(., .) and V(α) was already introduced in paragraph 2.1.4, page 53, while studying the Stokes problem.

Space approximation

The [START_REF] Hood | A numerical solution of the Navier-Stokes equations using the finite element technique[END_REF] finite element approximation of this generalized Stokes problem was also considered in paragraph 2.1.4, page 53. We introduce a mesh T h of Ω and the finite dimensional spaces X h , V h (α) and Q h . The approximate problem writes:

(N S) ∆t,h : find u n+1 h ∈ V h (1) and p n+1 ∈ Q h such that: a(u n+1 h , v) + b(v, p n+1 h ) = m(f n h , v), ∀v ∈ V h (0), b(u n+1 h , q) = 0, ∀q ∈ Q h . (2.7)
where

f n h = Re 2∆t 4 u n h • X n -u n-1 h • X n
The problem reduces to a sequence resolution of a generalized Stokes problems.

Comments

The code performs a computation by using adaptive mesh refinement, in order to capture recirculation zones. The adapt_option declaration is used by rheolef to send options to the mesh generator. The code reuse the file 'cavity.h' introduced page 54. This file contains two functions that defines boundary conditions associated to the cavity driven problem.

The criteria function computes the adaptive mesh refinement criteria:

c h = (Re|u h | 2 + 2|D(u h )| 2 ) 1/2
The criteria function is similar to those presented in the 'embankment_adapt.cc' example. The mesh loop adaptation is initiated from a bamg mesh (see also appendix A. The program performs a computation with Re = 100. By default the time step is ∆t = 0.05 and the computation loops for five mesh adaptations. At each time step, the program prints an approximation of the time derivative, and stops when a stationary solution is reached. The mpirun -np 8 prefix allows a parallel and distributed run while the time one returns the real and the user times used by the computation. The speedup could be estimated here by the ratio user/real: it is ideally close to the number of processors. These prefixes are optional and you can omit the mpirun one if you are running with a sequential installation of Rheolef. Then, we visualize the 'square-005.geo' adapted mesh and its associated solution:

How to run the program

geo square-005.geo field square-005.field.gz -velocity

The representation of the stream function writes: make streamf_cavity zcat square-005.field.gz | ./streamf_cavity | field -bw -n-iso-negative 10 -

The programs 'streamf_cavity.cc', already introduced page 59, is here reused. The last options of the field program draws isocontours of the stream function using lines, as shown on Fig. 2.19. The zero isovalue separates the main flow from recirculations, located in corners at the bottom of the cavity. For Re = 400 and 1000 the computation writes:

./navier_stokes_cavity square.geo 400 ./navier_stokes_cavity square.geo 1000

The visualization of the cut of the horizontal velocity along the vertical median line writes: field square-005.field.gz -comp 0 -cut -normal -1 0 -origin 0.5 0 -gnuplot field square-005.field.gz -comp 1 -cut -normal 0 1 -origin 0 0.5 -gnuplot Fig. 2.21 compare the cuts with data from [START_REF] Ghia | High Re solutions for incompressible flow using the Navier-Stokes equations and a multigrid method[END_REF], table 1 and 2 (see also [START_REF] Gupta | A new paradigm for solving Navier-Stokes equations: streamfunction-velocity formulation[END_REF]. Observe that the solution is in good agreement with these previous computations. For higher Reynolds number, [START_REF] Shen | Hopf bifurcation of the unsteady regularized driven cavity flow[END_REF] showed in 1991 that the flow converges to a stationary state for Reynolds numbers up to 10 000; for Reynolds numbers larger than a critical value 10 000 < Re 1 < 10 500 and less than another critical value 15 000 < Re 2 < 16 000, these authors founded that the flow becomes periodic in time which indicates a Hopf bifurcation; the flow loses time periodicity for Re ≥ Re 2 . Ould [START_REF] Ould | Couplage de méthodes numériques en simulation directe d'écoulements incompressibles[END_REF] founded a loss of stationnarity between 10 000 and 20 000. [START_REF] Auteri | Numerical investigation on the stability of singular driven cavity flow[END_REF] estimated the critical value for the apparition of the first instability to Re 1 ≈ 8018. [START_REF] Erturk | Numerical solutions of 2-D steady incompressible driven cavity flow at high Reynolds numbers[END_REF] computed steady driven cavity solutions up to Re ⩽ 21 000. This result was infirmed by Gelhard, Lube, [START_REF] Gelhard | Stabilized finite element schemes with LBB-stable elements for incompressible flows[END_REF]: these authors estimated Re 1 close to 8000, in agreement with [START_REF] Auteri | Numerical investigation on the stability of singular driven cavity flow[END_REF]. The 3D driven cavity has been investigated in [START_REF] Minev | A characteristic/finite element algorithm for the 3-D Navier-Stokes equations using unstructured grids[END_REF] by the method of characteristic (see also [START_REF] Melchior | Analysis of preconditioned iterative solvers for incompressible flow problems[END_REF] for 3D driven cavity computations). In conclusion, the exploration of the driven cavity at large Reynolds number is a fundamental challenge in computational fluid dynamics. Note that, instead of using a time-dependent scheme, that requires many time steps, it is possible to directly compute the stationary solution of the Navier-Stokes problem, thanks to a nonlinear solver. This alternative approach is presented in section 4.5, page 185, based on the discontinuous Galerkin method. The discontinuous Galerkin method is much more robust and accurate than the method of characteristics and is recomanded for serious problems.

Re

Chapter 3

Advanced and highly nonlinear problems

Equation defined on a surface

This chapter deals with equations defined on a closed hypersurface. We present three different numerical methods: the direct resolution of the problem on an explicit surface mesh generated independently of Rheolef, the direct resolution on a surface mesh generated by Rheolef from a volume mesh, and finally a level set type method based on a volume mesh in an h-narrow band containing the surface. This last method allows one to define hybrid operators between surface and volume-based finite element fields. These methods are demonstrated on two model problems and two different surfaces.

Let us consider a closed surface Γ ∈ R d , d = 2 or 3 and Γ is a connected C 2 surface of dimension d -1 with ∂Γ = 0. We first consider the following problem:

(P 1) find u, defined on Γ such that:

u -∆ s u = f on Γ (3.1)
where f ∈ L 2 (Γ). For all function u defined on Γ, ∆ s denotes the Laplace-Beltrami operator:

∆ s u = div s (∇ s u)
where ∇ s and div s are the tangential derivative and the surface divergence along Γ, defined respectively, for all scalar field φ and vector field v by:

∇ s φ = (I -n ⊗ n) ∇φ div s v = (I -n ⊗ n) : ∇v
Here, n denotes a unit normal on Γ.

We also consider the following variant of this problem: (P 2) find u, defined on Γ such that:

-∆ s u = f on Γ (3.2)
This second problem is similar to the first one: the Helmholtz operator I -∆ s has been replaced by the Laplace-Beltrami one -∆ s . In that case, the solution is defined up to a constant: if u is a solution, then u + c is also a solution for any constant c ∈ R. Thus, we refers to (P 1) as the Helmholtz-Beltrami problem and to (P 2) as the Laplace-Beltrami one.

Approximation on an explicit surface mesh

The Helmholtz-Beltrami problem

Tanks to the surface Green formula (see appendix A.1.3), the variational formulation of problem (P 1) writes:

(V F 1): find u ∈ H 1 (Γ) such that: a(u, v) = l(v), ∀v ∈ H 1 (Γ)
where for all u, v ∈ H 1 (Γ),

a(u, v) = Γ (u v + ∇ s u.∇ s v) ds l(v) = Γ f v ds
Let k ⩾ 1 and consider a k-th order curved surface finite element mesh Γ h of Γ. We define the space W h :

W h = v h ∈ H 1 (Γ h ); v | S ∈ P k , ∀S ∈ Γ h
The approximate problem writes:

(V F 1) h : find u h ∈ W h such that: a(u h , v h ) = l(v h ), ∀v h ∈ W h

Comments

The problem involves the Helmholtz operator and thus, the code is similar to 'neumann-nh.cc' presented page 32. Let us comments the only differences:

form a = integrate ( u * v + dot ( grad_s ( u ) , grad_s ( v )));
The form refers to the grad_s operator instead of the grad one, since only the coordinates related to the surface are involved.

field lh = integrate ( f ( d )* v );
The right-hand-side does not involve any boundary term, since the surface Γ is closed: the boundary domain ∂Γ = ∅. As test problem, the surface Γ is the unit circle when d = 2 and the unit sphere when d = 3. The data f has been chosen as in Deckelnick et al. [2009, p. 17]. This choice is convenient since the exact solution is known. Recall that the spherical coordinates (ρ, θ, ϕ) are defined from the Cartesian ones (x 0 , x 1 , x 2 ) by:

ρ = x 2 0 + x 2 1 + x 2 2 , ϕ = arccos (x 2 /ρ) , θ =    arccos x 0 / x 2 0 + x 2 1 when x 1 ⩾ 0 2π -arccos x 0 / x 2 0 + x 2 1 otherwise File 3.2: sphere.icc struct p { Float operator () ( const point & x ) const { if ( d == 2) return 26*( pow ( x [0] ,5) -10* pow ( x [0] ,3)* sqr ( x [1]) + 5* x [0]* pow ( x [1] ,4)); else return 3* sqr ( x [0])* x [1] -pow ( x [1] ,3); } p ( size_t d1 ) : d ( d1 ) {} protected : size_t d ; }; struct f { Float operator () ( const point & x ) const { if ( d == 2) return _p ( x )/ pow ( norm ( x ) , 5

How to run the program

The program compile as usual: make helmholtz_s

A mesh of a circle is generated by: mkgeo_ball -s -e 100 > circle.geo geo circle -gnuplot

The mkgeo_ball is a convenient script that generates a mesh with the gmsh mesh generator. Then, the problem resolution writes:

./helmholtz_s circle P1 > circle.field field circle.field field circle.field -elevation

The tridimensional case is similar:

mkgeo_ball -s -t 10 > sphere.geo geo sphere.geo -stereo ./helmholtz_s sphere.geo P1 > sphere.field field sphere.field field sphere.field -stereo

The solution is represented on Fig . 3.1.left. ./helmholtz_s circle-P3 P3 > circle-P3.field field circle-P3.field -elevation -gnuplot

Note that both the curved geometry and the finite element are second order. The tridimensional counterpart writes simply:

mkgeo_ball -s -t 10 -order 3 > sphere-P3.geo geo sphere-P3.geo -gnuplot ./helmholtz_s sphere-P3 P3 > sphere-P3.field field sphere-P3.field field sphere-P3.field -stereo

The solution is represented on Fig . 3.1).right-bottom. The graphical representation is not yet able to represent the high-order approximation: each elements is subdivided and a piecewise linear representation is used in each sub-elements.

10 -8 Since the exact solution is known, the error can be computed: this is done by the program helmholtz_s_error.cc. This file is not presented here, as it is similar to some others examples, but can be founded in the Rheolef example directory. Figure 3.2 plots the error in various norms versus element size for different isoparametric approximations.

10 -6 10 -4 10 -2 10 -2 10 -1 ∥u h -π h (u)∥ 0,2,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 10 -8 10 -6 10 -4 10 -2 10 -2 10 -1 ∥u h -π h (u)∥ 0,∞,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 10 -8 10 -6 10 -4 10 -2 10 0 10 -2 10 -1 |u h -π h (u)| 1,2,Ω 1 = k 2 3 h k = 1 k = 2 k = 3

The Laplace-Beltrami problem

This problem has been introduced in (3.2), page 93. While the treatment of the Helmholtz-Beltrami problem was similar to the Helmholtz problem with Neumann boundary conditions, here, the treatment of the Laplace-Beltrami problem is similar to the Laplace problem with Neumann boundary conditions: see section 1.4, page 35. Note that for both problems, the solution is defined up to a constant. Thus, the linear problem has a singular matrix. The 'laplace_s.cc' code is similar to the 'neumann-laplace.cc' one, as presented in section 1.4. The only change lies one the definition of the right-hand side. As test problem, the surface Γ is the a torus when d = 3. The data f has been chosen as in Olshanskii et al. [2009, p. 3355]. This choice is convenient since the exact solution is known.

]) + sqr ( x [1])) -sqr ( R ))); phi = atan2 ( x [1] , x [0]); theta = atan2 ( x [2] , sqrt ( sqr ( x [0]) + sqr ( x [1])) -R ); } struct u_exact { Float operator () ( const point & x ) const { Float rho ,
Let R and r denotes the large and small torus radii, respectively. The torus coordinates (ρ, θ, ϕ) are defined linked to the Cartesian ones by:

  x 0 x 1 x 2   = R   cos(ϕ) sin(ϕ) 0   + ρ   cos(ϕ) cos(θ) sin(ϕ) cos(θ) sin(θ)  
Here ρ is the distance from the point to the circle in the x 0 x 1 plane around 0 with radius R, θ is the angle from the positive (x 0 , x 1 , 0) to x 0 and ϕ is the angle from the positive x 0 axis to (x 0 , x 1 , 0).

How to run the program ?

The surface mesh of the torus is generated by: gmsh -2 torus.mshcad -format msh2 -o torus.msh msh2geo torus.msh > torus.geo geo torus.geo -stereo

The 'torus.mshcad' is not presented here: it can be founded in the Rheolef example directory. Then, the computation and visualization writes: make laplace_s ./laplace_s torus.geo P1 > torus.field field torus.field field torus.field -stereo For a higher-order approximation:

gmsh -2 -order 2 torus.mshcad -format msh2 -o torus-P2.msh msh2geo torus-P2.msh > torus-P2.geo geo torus-P2.geo -gnuplot ./laplace_s torus-P2.geo P2 > torus-P2.field field torus-P2.field -stereo

The solution is represented on Fig. 3.3. By editing 'torus.mshcad' and changing the density of discretization, we can improve the approximate solution and converge to the exact solution. Due to a bug [Saramito, 2012b] in the current gmsh version 2.5.1 the convergence is not optimal O(h k ) for higher values of k.

Building a surface mesh from a level set function

The previous method is limited to not-too-complex surface Γ, that can be described by a regular finite element surface mesh Γ h . When the surface change, as in a time-dependent process, complex change of topology often occurs and the mesh Γ h can degenerate or be too complex to be efficiently meshed. In that case, the surface is described implicitly as the zero isosurface, or zero level set, of a function:

Γ = {x ∈ Λ; ϕ(x) = 0}
where Λ ⊂ R d is a bounding box of the surface Γ.

The following code automatically generates the mesh Γ h of the surface described by the zero isosurface of a discrete ϕ h ∈ X h level set function:

Γ h = {x ∈ Λ; ϕ h (x) = 0}
where X h is a piecewise affine functional space over a mesh T h of Λ:

X h = {φ ∈ L 2 (Λ) ∩ C 0 (Λ); φ /K ∈ P 1 , ∀K ∈ T h }
The polynomial approximation is actually limited here to first order: building higher order curved finite element surface meshes from a level set function is planed for the future versions of Rheolef.

Finally, a computation, as performed in the previous paragraph can be done using Γ h . We also point out the limitations of this approach. The computation of the previous paragraph can be reused:

./helmholtz_s circle.geo P1 | field -paraview -Note that, while the bounding box mesh was uniform, the intersected mesh could present arbitrarily small edge length (see also Fig. 3.4):

geo -min-element-measure circle.geo geo -max-element-measure circle.geo

Let us turn to the d = 3 case: geo -min-element-measure -max-element-measure sphere.geo

mkgeo_grid -T 20 -a -2 -b 2 -c -2 -d 2 -f -2 -g 2 > cube2
Nevertheless, and surprisingly, [START_REF] Olshanskii | On surface meshes induced by level set functions[END_REF] recently showed that the finite element method converges on these irregular intersected families of meshes. This approach can be extended to the Laplace-Beltrami problem on a torus:

sed -e 's/sphere/torus/' < level_set_sphere.cc > level_set_torus.cc make level_set_torus ./level_set_torus cube2.geo | geo -upgrade -> torus.geo geo torus.geo -stereo ./laplace_s torus.geo P1 | field -Note that the intersected mesh is also irregular:

geo -min-element-measure -max-element-measure torus.geo

The banded level set method

The banded level set method presents the advantages of the two previous methods without their drawback: it applies to very general geometries, as described by a level set funtion, and stronger convergence properties, as usual finite element methods. The previous intersection mesh can be circumvented by enlarging the surface Γ h to a band β h containing all the intersected elements of T h (see [START_REF] Olshanskii | A finite element method for elliptic equations on surfaces[END_REF][START_REF] Abouorm | Méthodes mathématiques pour les écoulements sur des surfaces[END_REF][START_REF] Dicko | Méthodes mathématiques pour les écoulements sur des surfaces[END_REF]:

β h = {K ∈ T h ; K ∩ Γ h ̸ = ∅}
Then, we introduce B h the piecewise affine functional space over β h :

B h = {v ∈ L 2 (β h ) ∩ C 0 (β h ); v /K ∈ P 1 , ∀K ∈ T h }
The problem is extended from Γ h to β h as:

(V F ) h : find u h ∈ B h such that: a(u h , v h ) = l(v h ), ∀v h ∈ B h
where, for all u, v ∈ B h ,

a(u, v) = Γ h (u v + ∇ s u.∇ s v) ds l(v) = Γ h f v ds for all u h , v h ∈ B h .

Comments

The band is build directly from the level set function as:

band gamma_h ( phi_h );

The band structure is a small class that groups the surface mesh Γ h , available as gamma_h.level_set(), and the β h mesh, available as gamma_h.band(). It also manages some correspondence between both meshes. Then, the space of piecewise affine functions over the band is introduced:

space Bh ( gamma_h . band () , " P1 " );

Next, the bilinear form is computed by using the integrate function, with the band gamma_h as a domain-like argument:

form a = integrate ( gamma_h , u * v + dot ( grad_s ( u ) , grad_s ( v )));

The right-hand side also admits the gamma_h argument:

field lh = integrate ( gamma_h , f ( d )* v );
Recall that summations for both forms and right-hand side will be performed on Γ h , represented by gamma_h.level_set(), while the approximate functional space is B h . Due to this summation on Γ h instead of β h , the matrix of the system is singular [START_REF] Olshanskii | A finite element method for elliptic equations on surfaces[END_REF][START_REF] Olshanskii | A finite element method for surface PDEs: matrix properties[END_REF][START_REF] Abouorm | Méthodes mathématiques pour les écoulements sur des surfaces[END_REF]] and the MINRES algorithm has been chosen to solve the linear system:

minres ( a . uu () , uh . set_u () , lh . u () , eye () , sopt );

The eye() argument represents here the identity preconditioner, i.e. no preconditioner at all. It has few influence of the convergence properties of the matrix and could be replaced by another simple one: the diagonal of the matrix diag(a.uu()) without sensible gain of performance:

minres ( a . uu () , uh . set_u () , lh . u () , diag ( a . uu ()) , sopt );

See the reference manual for more about minres, e.g. on the Rheolef web site or as unix manual man minres

How to run the program

The compilation and run writes:

make helmholtz_band_iterative mkgeo_grid -T 20 -a -2 -b 2 -c -2 -d 2 -f -2 -g 2 > cube-20.geo
./helmholtz_band_iterative cube-20.geo > sphere-band.field

The run generates also two meshes (see Fig. 3.5): the intersection mesh and the band around it.

The solution is here defined on this band: this extension has no interpretation in terms of the initial problem and can be restricted to the intersection mesh for visualization purpose: make proj_band ./proj_band < sphere-band.field | field -

The 'proj_band.cc' is presented below. The run generates also the Γ h mesh (see Fig. 3.5), required for the visualization. The two-dimensional case is obtained simply by replacing the 3D bounding box by a 2D one: The iterative algorithm previously used for solving the linear system is not optimal: for 3D problems on a surface, the bidimensionnal connectivity of the sparse matrix suggests that a direct sparse factorization would be much more efficient.

mkgeo_grid -t 20 -a -2 -b 2 -c -2 -d 2 >
Recall that ϕ h = 0 on Γ h . Thus, if u h ∈ B h is solution of the problem, then u h +αϕ h|β h ∈ B h is also solution for any α ∈ R, where ϕ h|β h ∈ B h denotes the restriction of the level set function ϕ h ∈ X h on the band β h . Thus there is multiplicity of solutions and the matrix of the problem is singular. The direct resolution is still possible on a modified linear system with additional constraints in order to recover the unicity of the solution. We impose the constraint that the solution u h should be othogonal to ϕ h|β h ∈ B h . In some special cases, the band is composed of several connected components (see Fig. 3.6): this appends when a vertex of the bounding box mesh belongs to Γ h . In that case, the constraint should be expressed on each connected component. Fig. 3.6 shows also the case when a full side of an element is included in Γ h : such an element of the band is called isolated.

Comments

The management of the special sides and vertices that are fully included in Γ h is perfomed by: Bh . block ( " isolated " ); Bh . unblock ( " zero " );

The addition of linear constraints is similar to the 'neumann-laplace.cc' code, as presented in section 1.4:

form A = {{ a , trans ( b )} , { b , 0 }};
Here b is a vector<field>, i.e. a vector of linear constraints, one per connected component of the band β h .

How to run the program

The commands are similar to the previous iterative implementation, just replacing helmholtz_band_iterative by helmholtz_band. This approach could be also adapted to the Laplace-Beltrami problem on the torus.

File 3.9: laplace_band.cc field phi_h_cci ( Bh , 0);

phi_h_cci [ cci ] = phi_h_band [ cci ]; b [ i ] = phi_h_cci ; } form A = {{ a , trans ( b ) , c } , { b , 0 , 0 } , { trans ( c ) ,

Comments

The code is similar to the previous one helmholtz_band.cc. Since the solution is defined up to a constant, an additional linear constraint has to be inserted:

Γ h u h dx = 0
This writes: (P): find u, defined in Ω such that:

-div η |∇u| 2 ∇u = f in Ω u = 0 on ∂Ω where η : z ∈ R + -→ z p-2 2 ∈ R + .
Several variants of the η can be considered: see Saramito [2016b] for practical and useful examples: this problem represents a pipe flow of a non-Newtonian power-law fluid. Here p ∈]1, +∞[ and f are known. For the computational examples, we choose f = 1. When p = 2, this problem reduces to the linear Poisson problem with homogeneous Dirichlet boundary conditions. Otherwise, for any p > 1, the nonlinear problem is equivalent to the following minimization problem:

(MP): find u ∈ W 1,p 0 (Ω) such that: u = arg min v∈W 1,p 0 (Ω) 1 2 Ω H |∇v| 2 dx - Ω f v dx,
where H denotes the primitive of η:

H(z) = z 0 η(z) dz = 2z p p
Here W 1,p 0 (Ω) denotes the usual Sobolev spaces of functions in W 1,p (Ω) We also assume that f ∈ W -1,p (Ω), where W -1,p 0 (Ω) denotes the dual space of W 1,p 0 (Ω) that vanishes on the boundary [Brezis, 1983, p. 118]. The variational formulation of this problem expresses:

(VF): find u ∈ W 1,p 0 (Ω) such that:

a(u; u, v) = l(v), ∀v ∈ W 1,p 0 (Ω)
where a(., .) and l(.) are defined for any u 0 , u, v ∈ W 1,p (Ω) by

a(u 0 ; u, v) = Ω η |∇u 0 | 2 ∇u.∇v dx, ∀u, v ∈ W 1,p 0 (Ω) (3.3) l(v) = Ω f v dx, ∀u, v ∈ L 2 (Ω) (3.4)
The quantity a(u; u, u) 1/p = ∥∇u∥ 0,p,Ω induces a norm in W 1,p 0 , equivalent to the standard norm. The form a(.; ., .) is bilinear with respect to the two last variable and is related to the energy form.

The fixed-point algorithm

Principe of the algorithm

This nonlinear problem is then reduced to a sequence of linear subproblems by using the fixed-point algorithm. The sequence u (n) n⩾0 is defined by recurrence as:

• n = 0: let u (0) ∈ W 1,p 0 (Ω) be known. • n ⩾ 0: suppose that u (n) ∈ W 1,p 0 (Ω) is known and find u * ∈ W 1,p 0 (Ω) such that: a u (n) ; u * , v = l(v), ∀v ∈ W 1,p 0 (Ω)
and then set

u (n+1) = ωu * + (1 -ω) * u (n)
Here ω > 0 is the relaxation parameter: when ω = 1 we obtain the usual un-relaxed fixed point algorithm. For stiff nonlinear problems, we will consider the under-relaxed case n) denotes the operator that solve the previous linear subproblem for a given u (n) . Since the solution u satisfies u = G(u), it is a fixed-point of G.

0 < ω < 1. Let u (n+1) = G u (
Let us introduce a mesh T h of Ω and the finite dimensional space X h of continuous piecewise polynomial functions and V h , the subspace of X h containing elements that vanishes on the boundary of Ω:

X h = {v h ∈ C 0 0 Ω ; v h/K ∈ P k , ∀K ∈ T h } V h = {v h ∈ X h ; v h = 0 on ∂Ω}
where k = 1 or 2. The approximate problem expresses: suppose that u

(n) h ∈ V h is known and find u * h ∈ V h such that: a u (n) h ; u * h , v h = l(v h ), ∀v h ∈ V h
By developing u * h on a basis of V h , this problem reduces to a linear system. Remarks the usage of the compose, norm2 and grad library functions. The weight η ∇u

(n) h 2 is
represented by the compose(eta(p),norm2(grad(uh))) sub-expression. This weight is evaluated on the fly at the quadrature nodes during the assembly process implemented by the integrate function. Also, notice the distinction between u h , that represents the value of the solution at step n, and the trial u and test v functions, that represents any elements of the function space X h . These functions appear in the dot(grad(u),grad(v)) sub-expression. The η function is implemented separately, in file named eta.h in order to easily change its definition. The derivative member function is not yet used here: it is implemented for a forthcoming application (the Newton method). Note the guards that check for division by zero and send a message related to the mesh: this will be commentated in the next paragraph.

Finally, the fixed-point algorithm is initiated with u (0) as the solution of the linear problem associated to p = 2, i.e. the standard Poisson problem with Dirichlet boundary conditions. The triangular mesh has a boundary domain named boundary.

./p_laplacian_fixed_point square.geo P1 1.5 > square.field

Run the field visualization:

field square.field -elevation -stereo field square.field -cut -origin 0.5 0.5 -normal 1 1 -gnuplot

The first command shows an elevation view of the solution (see Fig. 3.7) while the second one shows a cut along the first bisector x 0 = x 1 . Observe that the solution becomes flat at the center when p decreases. The p = 2 case, corresponding to the linear case, is showed for the purpose of comparison.

There is a technical issue concerning the mesh: the computation could failed on some mesh that presents at least one triangle with two edges on the boundary: The computation stops and claims a division by zero: the three nodes of such a triangle, the three nodes are on the boundary, where u h = 0 is prescribed: thus ∇u h = 0 uniformly inside this element. Note that this failure occurs only for linear approximations: the computation works well on such meshes for P k approximations with k ⩾ 2. While the mkgeo_grid generates uniform meshes that have such triangles, the mkgeo_ugrid calls the gmsh generator that automatically splits the triangles with two boundary edges. When using bamg, you should consider the -splitpbedge option.

Convergence properties of the fixed-point algorithm

The fixed-point algorithm prints also r n , the norm of the residual term, at each iteration n, and the convergence rate v n = log 10 (r n /r 0 )/n. The residual term of the non-linear variational formulation is defined by:

r (n) h ∈ V h and m r (n) h , v h = a u (n) h ; u (n) h , v h -l(v h ), ∀v h ∈ V h
where m(., .) denotes the L 2 scalar product. Clearly, u

h is a solution if and only if r This relation expresses that the residual term r h is obtained by solving a linear system involving the mass matrix.

It remains to choose a good norm for estimating this residual term. For the corresponding continuous formulation, we have:

r = -div η |∇u| 2 ∇u -f ∈ W -1,p (Ω)
Thus, for the continuous formulation, the residual term may be measured with the W -1,p (Ω)

norm. It is defined, for all φ ∈ W -1,p (Ω), by duality:

∥φ∥ -1,p,Ω = sup φ∈W 1,p 0 (Ω) v̸ =0 ⟨φ, v⟩ ∥v∥ 1,p,Ω = sup v∈W 1,p 0 (Ω) ∥v∥1,p,Ω=1
⟨φ, v⟩ where ⟨., .⟩ denotes the duality bracked between W 1,p 0 (Ω) and W -1,p (Ω). By analogy, let us introduce the discrete W -1,p (Ω) norm, denoted as ∥.∥ -1,h , defined by duality for all φ h ∈ V h by:

∥φ h ∥ -1,h = sup v h ∈V h ∥v h ∥1,p,Ω=1 ⟨φ h , v h ⟩
The dual of space of the finite element space V h is identified to V h and the duality bracket is the Euclidean scalar product of R dim(V h ) . Then, ∥φ h ∥ -1,h is the largest absolute value of components of φ h considered as a vector of R dim(V h ) . With the notations of the Rheolef library, it simply writes:

Float r = rh.u().max_abs() observe that the convergence becomes easier when p approaches p = 2, where the problem is linear.

10 -15 10 -10 10 -5 1 0 25 50 r (n) h -1,h p = 3/2 n h = 1/10 h = 1/20 h = 1/30 h = 1/40 h = 1/50 10 -15 10 -10 10 -5 1 0 25 50 r (n) h -1,h p = 3/2 n k = 1 k = 2 k = 3 k = 4 k = 5
In that case, the convergence occurs in one iteration. Nevertheless, it appears two limitations.

From one hand, when p → 3 the convergence starts to slow down and p ⩾ 3 cannot be solved by this algorithm (it will be solved later in this chapter). From other hand, when p → 1, the convergence slows down too and numerical rounding effets limits the convergence: the machine precision canot be reached. Let us introduce the convergence rate v n = log 10 (r n /r 0 )/n it tends to This study shows that the residual term of the fixed point algorithm behaves as:

r n ≈ r 0 |p -2| n

Improvement by relaxation

The relaxation parameter can improve the fixed-point algorithm: for instance, for p = 3 and ω = 0.5 we get a convergent sequence:

./p_laplacian_fixed_point square.geo P1 3 0.5 > square.field

Observe on Fig. 3.10 the effect on the relaxation parameter ω upon the convergence rate v: for p < 2 it can improve it and for p > 2, it can converge when p > 3. For each p, there is clearly an optimal relaxation parameter, denoted by ω opt . A simple fit shows that (see Fig. Let us denote vopt the corresponding rate of convergence. Fig. 3.10.top-right shows that the convergence is dramatically improved when p > 2 while the gain is less pronounced when p < 2. Coveniently replacing the extra parameter ω on the command line byleads to compute automatically ω = ω opt : the fixed-point algorithm is always convergent with an optimal convergent rate, e.g.:

./p_laplacian_fixed_point square.geo P1 4.0 -> square.field

There is no way to improve more the fixed point algorithm: the next paragraph shows a different algorithm that dramatically accelerates the computation of the solution.

The Newton algorithm

Principe of the algorithm An efficient alternative to the fixed-point algorithm is to solve the nonlinear problem (P ) by using the Newton algorithm. Let us consider the following operator:

F : W 1,p 0 (Ω) -→ W -1,p (Ω) u -→ F (u) = -div η |∇u| 2 ∇u -f
The F operator computes simply the residual term and the problem expresses now as: find u ∈ W 1,p 0 (Ω) such that F (u) = 0. The Newton algorithm reduces the nonlinear problem into a sequence of linear subproblems: the sequence u (n) n⩾0 is classically defined by recurrence as:

• n = 0: let u (0) ∈ W 1,p 0 (Ω) be known.

• n ⩾ 0: suppose that u (n) is known, find δu (n) , defined in Ω, such that:

F ′ u (n) δu (n) = -F u (n)
and then compute explicitly:

u (n+1) := u (n) + δu (n)
The notation F ′ (u) stands for the Fréchet derivative of F , as an operator from W -1,p (Ω) into W 1,p 0 (Ω). For any r ∈ W -1,p (Ω), the linear tangent problem writes: find δu ∈ W 1,p 0 (Ω) such that:

F ′ (u) δu = -r
After the computation of the Fréchet derivative, we obtain the strong form of this problem:

(LT ): find δu, defined in Ω, such that

-div η |∇u| 2 ∇(δu) + 2η ′ |∇u| 2 {∇u.∇(δu)} ∇u = -r in Ω δu = 0 on ∂Ω where η ′ (z) = 1 2 (p -2)z p-4 2 , ∀z > 0
This is a Poisson-like problem with homogeneous Dirichlet boundary conditions and a non-constant tensorial coefficient. The variational form of the linear tangent problem writes:

(V LT ): find δu ∈ W 1,p 0 (Ω) such that a 1 (u; δu, δv) = l 1 (v), ∀δv ∈ W 1,p 0 (Ω)
where the a 1 (.; ., .) is defined for any u, δu, δv ∈ W 1,p 0 (Ω) by:

a 1 (u; δu, δv) = Ω η |∇u| 2 ∇(δu).∇(δv) + 2η ′ |∇u| 2 {∇u.∇(δu)} {∇u.∇(δv)} dx l 1 (v) = - Ω r v dx
For any ξ ∈ R d let us denote by ν(ξ) the following d × d matrix:

ν(ξ) = η |ξ| 2 I + 2η ′ |ξ| 2 ξ ⊗ ξ
where I stands for the d-order identity matrix. Then the a 1 expresses in a more compact form:

a 1 (u; δu, δv) = Ω (ν(∇u)∇(δu)) .∇(δv) dx
Clearly a 1 is linear and symmetric with respect to the two last variables.

File 3.13: p_laplacian_newton.cc

Comments

The Newton algorithm is implemented in a generic way, for any F function, by the newton function of the Rheolef library. The reference manual for the newton generic function is available online:

man newton
The function F and its derivative F ′ are provided by a template class argument. Here, the p_laplacian class describes our F function, i.e. our problem to solve: its interface is defined in the file 'p_laplacian.h' and its implementation in 'p_laplacian1.icc' and 'p_laplacian2.icc'. The introduction of the class p_laplacian will allow an easy exploration of some variants of the Newton algorithm for this problem, as we will see in the next section. The residual term F (u h ) is computed by the member function residual while the resolution of F ′ (u h )δu h = M r h is performed by the function derivative_solve. The derivative F ′ (u h ) is computed separately by the function update_derivative:

a1 = integrate ( dot ( compose ( nu < eta >( eta ( p ) , d ) , grad ( uh ))* grad ( u ) , grad ( v )));
Note that the a 1 (u; ., .) bilinear form is a tensorial weighted form, where ν = ν(∇u) is the weight tensor. The tensorial weight ν is inserted as (ν∇u).∇v in the variational expression for the integrate function. As the tensor ν is symmetric, the bilinear form a 1 (., .) is also symmetric. The linear system involving the derivative F ′ (u h ) is solved by the p_laplacian member function derivative_solve. Finally, applying the generic Newton method requires a stopping criteria on the residual term: this is the aim of the member function dual_space_norm. The three last member functions are not used by the Newton algorithm, but by its extension, the damped Newton method, that will be presented later. The program prints at each iteration n, the residual term r n in discrete L 2 (Ω) norm. Convergence occurs in less than ten iterations: it dramatically improves the previous algorithm (see Fig. 3.11).

Observe that the slope is no more constant in semi-log scale: the convergence rate accelerates and the slope tends to be vertical, the so-called super-linear convergence. This is the major advantage of the Newton method. Figs. 3.12.top-left and. 3.12.top-bottom shows that the algorithm converge when p ⩾ 3 and that the convergence properties are independent of the mesh size h and the polynomial order k. There are still two limitations of the method. From one hand, the Newton algorithm is no more independent of h and k when p ⩽ 3/2 and to tends to diverges in that case when h tends to zero (see Fig. 3.12.bottom-left). From other hand, when p becomes large (see Fig. 3.12.bottom-right), an overshoot in the convergence tends to increase and destroy the convergence, due to rounding problems. In order to circumvent these limitations, another strategy is considered in the next section: the damped Newton algorithm.

r (n) h -1,h p = 3 n k = 1 k = 2 k = 3 k = 4 k =

The damped Newton algorithm

Principe of the algorithm

The Newton algorithm diverges when the initial u (0) is too far from a solution, e.g. when p is not at the vicinity of 2. Our aim is to modify the Newton algorithm and to obtain a globally convergent algorithm, i.e to converge to a solution for any initial u (0) . By this way, the algorithm should converge for any value of p ∈]1, +∞[. The basic idea is to decrease the step length while maintaining the direction of the original Newton algorithm:

u (n+1) := u (n) + λ n δu (n)
where λ (n) ∈]0, 1] and δu (n) is the direction from the Newton algorithm, given by:

F ′ u (n) δu (n) = -F u (n)
Let V a Banach space and let T : V → R defined for any v ∈ V by:

T (v) = 1 2 ∥C -1 F (v)∥ 2 V ,
where C is some non-singular operator, easy to invert, used as a non-linear preconditioner. The simplest case, without preconditioner, is C = I. The T function furnishes a measure of the residual term in L 2 norm. The convergence is global when for any initial u (0) , we have for any n ⩾ 0:

T u (n+1) ⩽ T u (n) + α T ′ u (n) , u (n+1) -u (n) V ′ ,V (3.5)
where ⟨., .⟩ V ′ ,V is the duality product between V and its dual V ′ , and α ∈]0, 1[ is a small parameter. Note that

T ′ (u) = {C -1 F ′ (u)} * C -1 F (u)
where the superscript * denotes the adjoint operator, i.e. the transpose matrix the in finite dimensional case. In practice we consider α = 10 -4 and we also use a minimal step length λ min = 1/10 in order to avoid too small steps. Let us consider a fixed step n ⩾ 0: for convenience the n superscript is dropped in u (n) and δu (n) . Let g : R → R defined for any λ ∈ R by:

g(λ) = T (u + λδu)
Then :

g ′ (λ) = ⟨T ′ (u + λδu), δu⟩ V ′ ,V = ⟨C -1 F (u + λδu), F ′ (u + λδu)C -1 δu⟩ V,V ′
where the superscript * denotes the adjoint operator, i.e. the transpose matrix the in finite dimensional case. The practical algorithm for obtaining λ was introduced first in [J. [START_REF] Jr | Numerical methods for unconstraint optimization and nonlinear equations[END_REF] and is also presented in [Press et al., 1997, p. 385]. The step length λ that satisfy (3.5) is computed by using a finite sequence λ k , k = 0, 1 . . . with a second order recurrence:

• k = 0 : initialization λ 0 = 1. If (3.5) is satisfied with u + λ 0 d then let λ := λ 0 and the sequence stop here.

• k = 1 : first order recursion. The quantities g(0) = f (u) et g ′ (0) = ⟨f ′ (u), d⟩ are already computed at initialization. Also, we already have computed g(1) = f (u + d) when verifying whether (3.5) was satisfied. Thus, we consider the following approximation of g(λ) by a second order polynomial:

g1 (λ) = {g(1) -g(0) -g ′ (0)}λ 2 + g ′ (0)λ + g(0)
After a short computation, we find that the minimum of this polynomial is:

λ1 = -g ′ (0) 2{g(1) -g(0) -g ′ (0)}
Since the initialization at k = 0 does not satisfy (3.5), it is possible to show that, when α is small enough, we have λ1 ⩽ 1/2 and λ1 ≈ 1/2. Let λ 1 := max(λ min , λ1 ). If (3.5) is satisfied with u + λ 1 d then let λ := λ 1 and the sequence stop here.

• k ⩾ 2 : second order recurrence. The quantities g(0) = f (u) et g ′ (0) =⟩f ′ (u), d⟨ are available, together with λ k-1 , g(λ k-1 ), λ k-2 and g(λ k-2 ). Then, g(λ) is approximated by the following third order polynomial:

gk (λ) = aλ 3 + bλ 2 + g ′ (0)λ + g(0)
where a et b are expressed by:

a b = 1 λ k-1 -λ k-2     1 λ 2 k-1 - 1 λ 2 k-2 - λ k-2 λ 2 k-1 λ k-1 λ 2 k-2     g(λ k-1 ) -g ′ (0)λ k-1 -g(0) g(λ k-2 ) -g ′ (0)λ k-2 -g(0)
The minimum of gk (λ) is

λk = -b + b 2 -3ag ′ (0) 3a
Let λ k = min(1/2 λ k , max( λk /10, λk+1 ) in order for λ k to be at the same order of magnitude as λ k-1 . If (3.5) is satisfied with u + λ k d then let λ := λ k and the sequence stop here.

The sequence (λ k ) k⩾0 is strictly decreasing: when the stopping criteria is not satisfied until λ k reaches the machine precision ε mach then the algorithm stops with an error.

= I i.e. T (u) = ∥F (u)∥ 2 V ′ /2 is showed in file damped-newton.h. The gradient at λ = 0 is T ′ (u) = F ′ (u) * F (u)
and the slope at λ = 0 is:

g ′ (0) = ⟨T ′ (u), δu⟩ V ′ ,V = ⟨F (u), F ′ (u)δu⟩ V ′ ,V ′ = -∥F (u)∥ 2 V ′
The 'p_laplacian_damped_newton.cc' is the application program to the p-Laplacian problem together with the ∥.∥ L 2 (Ω) discrete norm for the function T .

Running the program

r (n) h -1,h p = 3/2, k = 1 n k = 1 k = 2 k = 3 k = 4 k =
r (n) h -1,h h = 1/50, k = 1 n p = 3 p = 4 p = 5 p = 6 p = 7

Error analysis

While there is no simple explicit expression for the exact solution in the square Ω =]0, 1[ 2 , there is one when considering Ω as the unit circle: Note, in the file 'p_laplacian_error.cc', the usage of the integrate function, together with a quadrature formula specification, for computing the errors in L p norm and W 1,p semi-norm. Note also the flexibility of expressions, mixing together fields as uh and functors, as u_exact. The whole expression is evaluated by the integrate function at quadrature points inside each element of the mesh. By this way, the error analysis investigation becomes easy: make p_laplacian_error mkgeo_ball -t 10 -order 2 > circle-10-P2.geo ./p_laplacian_damped_newton circle-10-P2.geo P2 1.5 | ./p_laplacian_error

u(x) = (p -1) 2 -1 p-1 p 1 -x 2 0 + x 2 1 p p-1) 10 -8 10 -6 10 -4 10 -2 10 -2 10 -1 1 ∥u -u h ∥ 0,p,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 10 -8 10 -6 10 -4 10 -2 10 -2 10 -1 1 ∥u -u h ∥ 0,∞,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 10 -6 10 -4 10 -2 1 10 -2 10 -1 1 |∇(u -u h )| 0,p,Ω 1 = k 2 3 h k = 1 k = 2 k = 3
We can vary both the mesh size and the polynomial order and the error plots are showed on Fig. 3.15 for both the L 2 , L ∞ norms and the W 1,p semi-norm. Observe the optimal error behavior: the slopes in the log-log scale are the same as those obtained by a direct Lagrange interpolation of the exact solution.

Continuation and bifurcation methods

This chapter is an introduction to continuation and bifurcation methods with Rheolef. We consider a model nonlinear problem that depends upon a parameter. This problem is inspired from application to combustion. Solutions exists for a limited range of this parameter and there is a limit point: beyond this limit point there is no more solution. Our first aim is to compute the branch of solutions until this limit point, thanks to the continuation algorithm. Moreover, the limit point is a turning point for the branch of solutions: there exists a second branch of solutions, continuing the first one. Our second aim is to compute the second branch of solutions after this limit point with the Keller continuation algorithm. For simplicity in this presentation, the discretization is in one dimension: the extension to high order space dimension is immediate.

Problem statement and the Newton method

Let us consider the following model problem (see Paumier, 1997, p. 59 or Crouzeix andRappaz, 1990, p. 2), defined for all λ ∈ R:

(P ): find u, defined in Ω such that

-∆u + λ exp(u) = 0 in Ω u = 0 on ∂Ω
In order to apply a Newton method to the whole problem, let us introduce:

F (λ, u) = -∆u + λ exp(u)
Then, the Gâteau derivative at any (λ, u) ∈ R × H 1 0 (Ω) is given by:

∂F ∂u (λ, u).(v) = -∆v + λ exp(u)v, ∀v ∈ H 1 0 (Ω)

Error analysis and multiplicity of solutions

In one dimension, when Ω =]0, 1[, the problem can be solved explicitly [Paumier, 1997, p. 59]:

• when λ ⩽ 0 the solution is parameterized by α ∈]0, π/2[ and:

λ = - 8α 2 cos 2 (α) u(x) = 2 log cos(α) cos(α(1 -2x)) , x ∈]0, 1[ • when 0 ⩽ λ ⩽ λ c
there is two solutions. The smallest one is parameterized by α ∈]0, α c ] and: and the largest by α ∈]α c , +∞[ with:

λ = 8α 2 cosh 2 (α) u(x) = 2 log cosh(α) cosh(α(1 -2x)) , x ∈]0, 1[
• when λ > λ c there is no more solution.

The critical parameter value λ c = 8α 2 c / cosh 2 (α c ) where α c is the unique positive solution to tanh(α) = 1/α. The following code compute α c and λ c by using a Newton method. The lambda2alpha function converts λ into α. When 0 < λ < λ c , there is two solutions to the equation 8 (α/ cosh(α))

2 = λ and thus we specify with the Boolean is_upper which one is expected. Then α is computed by a dichotomy algorithm. The Newton method fails when the parameter λ is greater to some critical value λ c,h that depends upon the mesh size. Moreover, while the approximate solution is close to the exact one for moderate λ = 1.57289546593186, the convergence seems to be slower at the vicinity of λ c . In the next section, we compute accurately λ c,h for each mesh and observe the convergence of λ c,h to λ c and the convergence of the associated approximate solution to the exact one.

The Euler-Newton continuation algorithm

The Euler-Newton continuation algorithm writes [Paumier, 1997, p. 176]:

algorithm 1 (continuation) • n = 0: Let (λ 0 , u 0 ) be given. Compute u0 = - ∂F ∂u (λ 0 , u 0 ) -1 ∂F ∂λ (λ 0 , u 0 )
• n ⩾ 0: Let (λ n , u n ) and un being known.

1) First choose a step ∆λ n and set λ n+1 = λ n + ∆λ n .

2) Then, perform a prediction by computing

w 0 = u n -∆λ n ∂F ∂u (λ n , u n ) -1 ∂F ∂λ (λ n , u n )
3) Then, perform a correction step: for all k ⩾ 0, with w k being known, compute

w k+1 = w k - ∂F ∂u (λ n+1 , w k ) -1 F (λ n+1 , w k ) At convergence of the correction loop, set u n+1 = w ∞ . 4) Finally, compute un+1 = - ∂F ∂u (λ n+1 , u n+1 ) -1 ∂F ∂λ (λ n+1 , u n+1 )
The step ∆λ n can be chosen from a guest ∆λ * = ∆λ n-1 by adjusting the contraction ratio κ(∆λ * ) of the Newton method. Computing the two first iterates w 0, * and w 1, * with the guest step ∆λ * and λ * = λ n + ∆λ * we have:

κ(∆λ * ) = ∂F ∂u (λ * , w 1, * ) -1 F (λ * , w 1, * ) ∂F ∂u (λ * , w 0, * ) -1 F (λ * , w 0, * )
As the Newton method is expected to converge quadratically for small enough step, we get a practical expression for ∆λ n [Paumier, 1997, p. 185]:

κ 0 ∆λ n ≈ κ(∆λ * ) ∆λ 2 *
where κ 0 ∈]0, 1[ is the chosen reference for the contraction ratio, for instance κ 0 = 1/2. The last command lists all the computations preformed by the continuation algorithm. The last

0 1 0 1 2 3 λ c 4 ∥u h ∥ 0,∞,Ω λ h = 1/160 h = 1/10
Figure 3.17: Combustion problem: ∥u h ∥ 0,∞,Ω vs λ when h = 1/10 and 1/160.

recorded computation is associated to the limit point denoted and denoted as λ c,h , says at index 21:

Let us visualize the solution u h at the limit point and compute its maximum

∥u h ∥ 0,∞,Ω = u h (1/2):
branch line-10.branch -extract 21 -branch | fieldbranch line-10.branch -extract 21 -branch | field -max -Fig. 3.17 plots ∥u h ∥ 0,∞,Ω versus λ for various meshes. Fig. 3.18 plots its convergence to λ c and also the convergence of the corresponding appoximate solution u h to the exact one u, associated to λ c . Observe that |λ c,h -λ c | converges to zero 10 -10 10 -5 10 -1 1 10 -8 10 -6 10 -4 10 -2 1 of the determinant of the Jacobean ∂F ∂u (λ, u h (λ)) versus λ c,h -λ: it tends to zero at the vicinity of λ = λ c and thus, the Newton method reaches increasing difficulties to solve the problem. Note that the determinant has been normalized by its value when λ = 0, i.e. det ∂F ∂u (0, u h (0)) : all the curves tend to superpose on a unique master curve and the asymptotic behavior is independent of h. More precisely, Fig. 3.19 suggests a 1/2 slope in logarithmic scale and thus

1 10 -3 10 -2 10 -1 1 |λ c,h -λ c | 2 4 6 = 2k h k = 1 k = 2 k = 3 10 -8 10 -4 1 10 -3 10 -2 10 -1 1 ∥∇(u h -u)∥ 0,2,Ω 1 2 3 = k h k = 1 k = 2 k = 3
det ∂F ∂u (λ, u h (λ)) det ∂F ∂u (0, u h (0)) 1/2 λ c,h -λ h = 1/10 h = 1/20 h = 1/40 h = 1/80 h = 1/160
det ∂F ∂u (λ, u h (λ)) det ∂F ∂u (0, u h (0)) ≈ C (λ c,h -λ) 1/2
where C ≈ 0.52 when k = 1. This behavior explains that the Newton method is unable to reach the limit point λ c .

Beyond the limit point : the Keller algorithm

Note that the continuation method stops to the limit point (see Fig. 3.17) while the the branch continues: the limit point is a turning point for the branch of solutions. Especially, for each λ ∈]0, λ c [ there are two solutions and only one has been computed. Keller proposed a method to follow the branch beyond a turning point and this method is presented here. The main idea is to parameterize the branch (λ, u(λ)) by a curvilinear abscissa s as (λ(s), u(s)). In order to have the count of unknown and equations we add a normalization equation:

N (s, λ(s), u(s)) = 0 F (λ(s), u(s)) = 0
where N is a given normalization function. For the normalization function, Keller proposed to choose, when (s, λ, u) is at the vicinity of (s n , λ(s n ), u(s n )) the one following orthogonal norms:

• The orthogonal norm:

N n (s, χ = (λ, u)) = (χ ′ (s n ), χ -χ(s n )) -(s -s n ) = λ ′ (s n ) (λ -λ(s n )) + (u ′ (s n ), u -u(s n )) V -(s -s n ) (3.6a)
• The spherical norm:

N n (s, χ = (λ, u)) = ∥χ -χ n ∥ 2 -|s -s n | 2 = |λ -λ n | 2 + ∥u -u n ∥ 2 V -|s -s n | 2 (3.6b)
The orthogonal norm induces a pseudo curvilinear arc-length s, measured on the tangent at s = s n .

The spherical norm measures is simply a distance between (s, χ) and (s n , χ n ) (see also Paumier, 1997, pp. 179-180 and the corresponding Fig. 5.2). We add the subscript n to N in order to emphasize that N depends upon both

(λ(s n ), u(s n )) and (λ ′ (s n ), u ′ (s n )) For any s ∈ R and χ = (λ, u) ∈ R × V we introduce: F n (s, χ) = N n (s, χ) F (χ) and F n (s, χ) = N n (s, χ) F (χ)
Then, the Keller problem with the orthogonal norm reduces to find, for any

s ∈ R, χ(s) ∈ R × V such that F n (s, χ(s)) = 0 (3.7a)
Conversely, the Keller problem with the spherical norm reduces to find, for any s ∈ R, χ(s) ∈ R×V such that

F n (s, χ(s)) = 0 (3.7b)
Both problems falls into the framework of the previous paragraph, when F is replaced by either F n or F n . Then, for any s and χ = (λ, u), the partial derivatives are:

∂F n ∂s (s, χ) = -1 0 ∂F n ∂χ (s, χ) =    ∂N n ∂χ (s, χ) F ′ (s, χ)    =    λ ′ (s n ) u ′ (s n ) ∂F ∂λ (λ, u) ∂F ∂u (λ, u)    and ∂ F n ∂s (s, χ) = -2(s -s n ) 0 ∂ F n ∂χ (s, χ) =   2(χ -χ n ) T F ′ (χ)   =    2(λ -λ n ) 2(u -u n ) T ∂F ∂λ (λ, u) ∂F ∂u (λ, u)   
Let us focus on the orthogonal norm case, as the spherical one is similar. The continuation algorithm of the previous paragraph is able to follows the branch of solution beyond the limit point and explore the second part of the branch. Let us compute λ ′ (s n ) and u ′ (s n ). By differentiating (3.7) with respect to s, we get:

∂F n ∂s (s, χ(s)) + ∂F n ∂χ (s, χ(s)).(χ ′ (s)) = 0
that writes equivalently

∂N n ∂s (s, χ(s)) + ∂N n ∂χ (s, χ(s)).(χ ′ (s)) = 0 F ′ (s, χ(s)).(χ ′ (s)) = 0
Using the expression 3.6 for N n we obtain:

-1 + λ ′ (s n )λ ′ (s) + (u ′ (s n ), u ′ (s)) = 0 (3.8) ∂F ∂λ (λ(s), u(s)) λ ′ (s) + ∂F ∂u (λ(s), u(s)).(u ′ (s)) = 0 (3.9)
Here (., .) denotes the scalar product of the V space for u. Let us choose s = s n , for any n ⩾ 0: we obtain

|λ ′ (s n )| 2 + ∥u ′ (s n )∥ 2 = 1 ∂F ∂λ (λ n , u n ) λ ′ (s n ) + ∂F ∂u (λ n , u n ).(u ′ (s n )) = 0
where we use the notations λ n = λ(s n ) and u n = u(s n ), and where ∥.∥ denotes the norm of the V space. Thus

χ ′ (s n ) = λ ′ (s n ) u ′ (s n ) = 1   1 + ∂F ∂u (λ n , u n ) -1 ∂F ∂λ (λ n , u n ) 2   1/2   1 - ∂F ∂u (λ n , u n ) -1 ∂F ∂λ (λ n , u n )  
The previous relation requires ∂F ∂u (λ n , u n ) to be nonsingular, e.g. the computation is not possible at a singular point (λ n , u n ). For a singular point, suppose that n ⩾ 1 and that both (λ n , u n ), (λ n-1 , u n-1 ) and ( λn-1 , un-1 ) are known. By differentiating (3.7) at step n -1 we get the equivalent of (3.8)-(3.9) at step n -1 that is then evaluated for s = s n . We get:

λ ′ (s n-1 )λ ′ (s n ) + (u ′ (s n-1 ), u ′ (s n )) = 1 ∂F ∂λ (λ n , u n ) λ ′ (s n ) + ∂F ∂u (λ n , u n ).(u ′ (s n )) = 0 that writes equivalently λ ′ (s n-1 ) u ′ (s n-1 ) ∂F ∂λ (λ n , u n ) ∂F ∂u (λ n , u n ) λ ′ (s n ) u ′ (s n ) = 1 0 (3.10)
The matrix involved in the left hand side is exactly the Jacobean of F n-1 evaluated at point χ n = (λ n , u n ). This Jacobean is expected to be nonsingular at a simple limit point. Thus, at the first step, we suppose that the initial point (λ 0 , u 0 ) is non-singular and we compute ( λ0 , u0 ). Then, at the begining of the n-th step, n ⩾ 1, of the Keller continuation algorithm, we suppose that both (λ n-1 , u n-1 ) and ( λn-1 , un-1 ) are known. We consider the problem F n-1 (s, χ(s)) = 0. Here, F n-1 (s, χ) is completely defined at the vicinity of (s n-1 , λ n-1 , u n-1 ). The step control procedure furnishes as usual a parameter step ∆s n-1 and we set s n = s n-1 + ∆s n-1 . The Newton method is performed and we get (λ n , u n ). Finaly, we compute λn and un from (3.10).

Recall that the function F n-1 depends upon n and should be refreshed at the begining of each iteration by using the values ( λn-1 , un-1 ).

The Keller continuation algorithm writes:

algorithm 2 (Keller continuation)

• n = 0: Let (s 0 , χ 0 = (λ 0 , u 0 )) be given. The recurrence requires also χ0 and its orientation ε 0 ∈ {-1, +1}: they could either be given or computed. When computing ( χ0 , ε 0 ), the present algorithm supposes that (λ 0 , u 0 ) is a regular point: on a singular point, e.g. a bifurcation one, there a several possible directions, and one should be chosen. Then, choose ε = ±1 and compute χ0 in three steps:

du dλ (λ 0 ) = - ∂F ∂u (λ 0 , u 0 ) -1 ∂F ∂λ (λ 0 , u 0 ) c = 1 + du dλ (λ 0 ) -1/2 χ0 def = ( λ0 , u0 ) T = c 1, du dλ (λ 0 ) T • n ⩾ 0: Let (s n , χ n = (λ n , u n ))
, χn = ( λn , un ) and ε n being known.

1) First choose a step ∆s n and set s n+1 = s n + ∆s n , as in the classical continuation algorithm 2) Then, perform a prediction, as usual:

y 0 = χ n + ε n ∆s n χn
3) Also as usual, do a correction loop: for all k ⩾ 0, y k being known, compute

y k+1 = y k - ∂F n ∂χ (s n+1 , y k ) -1 F n (s n+1 , y k )
At convergence of the correction loop, set χ n+1 = y ∞ . This Newton correction loop can be replaced by a damped Newton one.

4) Check : if n ⩾ 1, compute the following angle cosinus:

c 1 = (χ n+1 -χ n , χ n -χ n-1 ) = (λ n+1 -λ n )(λ n -λ n-1 ) + (u n+1 -u n , u n -u n-1 ) V c 2 = ( χn , χ n+1 -χ n ) = ( λn , λ n+1 -λ n ) + ( un , u n+1 -u n ) V
When either c 1 ⩽ 0 or c 2 ⩽ 0, then decreases ∆s n and go back at step 1. Otherwise the computation of χ n+1 is validated.

5) Finally, compute χn+1 = ( λn+1 , un+1 ) as:

χn+1 = - ∂F n ∂χ (s n+1 , χ n+1 ) -1 ∂F n ∂s (s n+1 , χ n+1 ) If ε n ( χn+1 , χn ) ⩾ 0 then set ε n+1 = ε n else ε n+1 = -ε n .
The Keller algorithm with the spherical norm is simply obtained by replacing F n by F n Both algorithm variants still require to save χn and ε n at each step for restarting nicely with the same sequence of computation. The only drawback is that, at a restart of the algorithm, we skip the first Check step, and its possible to go back at the first iterate if ∆s 0 is too large. A possible remedy is, when restarting, to furnish two previous iterates, namely χ -1 and χ 0 , together with χ0 : χ -1 is used only for the Check of a possible change of direction. [START_REF] Howell | Computation of viscoelastic fluid flows using continuation methods[END_REF] suggested that the Keller algorithm with spherical norm is more robust that its variant with orthogonal one. [START_REF] Howell | Computation of viscoelastic fluid flows using continuation methods[END_REF] reported that [...] the spherical constraint N 2 is much more efficient than the orthogonal constraint N 1 , as N 2 required only one step of length 0.01 to exceed the target value, while N 1 required 25, with 8 additional convergence failures.

[...] spherical constraint was seen to be more efficient than an orthogonal constraint in a region of high curvature of the solution manifold, while both constraints performed similarly in regions of low or moderate curvature. The last command scans the file line-20.branch containing the branch of solutions (λ(s), u(s)) and compute some useful informations for graphical representations. Observe on Fig. 3.20.left the full branch of solutions when λ ⩾ 0, with the limit point and the upper part of the branch. Compare it with Fig. 3.17, where the continuation algorithm was limited to the lower part part of the branch. Next, in order to vizualise the last computed solution, enter:

Discontinuous Galerkin methods

Linear first-order problems

The aim of this chapter is to introduce to discontinuous Galerkin methods within the Rheolef environment. For some recent presentations of discontinuous Galerkin methods, see di Pietro and Ern [2012] for theoretical aspects and [START_REF] Hesthaven | Nodal discontinuous Galerkin methods[END_REF] for algorithmic and implementation.

The stationary transport equation

The steady scalar transport problem writes:

(P ): find ϕ, defined in Ω, such that

u.∇ϕ + σϕ = f in Ω ϕ = ϕ Γ on ∂Ω -
where u, σ > 0, f and ϕ Γ being known. Note that this is the steady version of the unsteady diffusion-convection problem previously introduced in section 2.4.2, page 79 and when the diffusion coefficient ν vanishes. Here, the ∂Ω -notation is the upstream boundary part, defined by

∂Ω -= {x ∈ ∂Ω; u(x).n(x) < 0}
Let us suppose that u ∈ W 1,∞ (Ω) d and introduce the space:

X = {φ ∈ L 2 (Ω); (u.∇)φ ∈ L 2 (Ω) d } and, for all ϕ, φ ∈ X a(ϕ, φ) = Ω (u.∇ϕ φ + σ ϕ φ) dx + ∂Ω max (0, -u.n) ϕ φ ds l(φ) = Ω f φ dx + ∂Ω max (0, -u.n) ϕ Γ φ ds
Then, the variational formulation writes:

(F V ): find ϕ ∈ X such that a(ϕ, φ) = l(φ), ∀φ ∈ X
Note that the term max(0, -u.n) = (|u.n| -u.n)/2 is positive and vanishes everywhere except on ∂Ω -. Thus, the boundary condition ϕ = ϕ Γ is weakly imposed on ∂Ω -via the integrals on the boundary. The discontinuous finite element space is defined by:

X h = {φ h ∈ L 2 (Ω); φ h|K ∈ P k , ∀K ∈ T h }
where k ⩾ 0 is the polynomial degree. Note that X h ̸ ⊂ X and that the ∇ϕ h term has no more sense for discontinuous functions ϕ h ∈ X h . Following di Pietro and Ern [2012, p. 14], we introduce the broken gradient ∇ h as a convenient notation:

(∇ h ϕ h ) |K = ∇(ϕ h|K ), ∀K ∈ T h Thus Ω u.∇ h ϕ h φ h dx = K∈T h K u.∇ϕ h φ h dx, ∀ϕ h , φ h ∈ X h
This leads to a discrete version a h of the bilinear form a, defined for all ϕ h , φ h ∈ X h by (see e.g. di Pietro and Ern, 2012, p. 57, eqn. (2.34)):

a h (ϕ h , φ h ) = Ω (u.∇ h ϕ h φ h + σϕ h φ h ) dx + ∂Ω max (0, -u.n) ϕ h φ h ds + S∈S (i) h S -u.n [[ϕ h ]] { {φ h } } + α 2 |u.n| [[ϕ h ]] [[φ h ]] ds
The last term involves a sum over S (i)

h , the set of internal sides of the mesh T h . Each internal side

K + S K - n = n -= -n + on S n - n + ϕ - h ϕ + h Figure 4
.1: Discontinuous Galerkin method: an internal side, its two neighbor elements and their opposite normals.

S ∈ S (i) h

has two possible orientations: one is choosen definitively. In practice, this orientation is defined in the '.geo' file containing the mesh, where all sides are listed, together with their orientation. Let n the normal to the oriented side S: as S is an internal side, there exists two elements K -and K + such that S = ∂K -∩ ∂K + and n is the outward unit normal of K -on ∂K -∩ S and the inward unit normal of K + on ∂K + ∩ S, as shown on Fig. 4.1. For all ϕ h ∈ X h , recall that ϕ h is in general discontinuous across the internal side S. We define on S the inner value ϕ - h = ϕ h|K-of ϕ h as the restriction ϕ h|K-of ϕ h in K -along ∂K -∩ S. Conversely, we define the outer value ϕ + h = ϕ h|K+ . We also denote on S the jump

[[ϕ h ]] = ϕ - h -ϕ + h and the average { {ϕ h } } = (ϕ - h + ϕ + h )/2.
The last term in the definition of a h is pondered by a coefficient α ⩾ 0. Choosing α = 0 correspond to the so-called centered flux approximation, while α = 1 is the upwinding flux approximation. The case α = 1 and k = 0 (piecewise constant approximation) leads to the popular upwinding finite volume scheme. Finally, the discrete variational formulation writes:

(F V ) h : find ϕ h ∈ X h such that a h (ϕ h , φ h ) = l(φ h ), ∀φ h ∈ X h
The following code implement this problem in the Rheolef environment. for all k ⩾ 0, which is optimal. A theoretical O h k+1/2 error bound was shown by [START_REF] Johnson | An analysis of the discontinuous Galerkin method for a scalar hyperbolic equation[END_REF]. The present numerical results confirm that these theoretical error bounds can be improved for some families of meshes, as pointed out by [START_REF] Richter | An optimal-order error estimate for the discontinuous galerkin method[END_REF], that showed a O h k+1 optimal bound for the transport problem. This result was recently extended by Cockburn et al. [2010a], while [START_REF] Peterson | A note on the convergence of the discontinuous Galerkin method for a scalar hyperbolic equation[END_REF] showed that the estimate O h k+1/2 is sharp for general families of quasi-uniform meshes.

∥ϕ -ϕ h ∥ L 2 1 = k + 1 5 = k + 1 h k = 0 k = 1 k = 2 k = 3 k = 4 10 -15 10 -10 10 -5 1 10 -2 10 -1 ∥ϕ -ϕ h ∥ L ∞ 1 = k + 1 5 = k + 1 h k = 0 k = 1 k = 2 k = 3 k = 4

[New] The time-dependent transport equation

Problem statement

The time-dependent transport equation is involved in many problems of mathematical physics.

One of these problem concerns a moving domain, transported by a velocity field. Let us denote, at any time t ⩾ 0 by ω(t) ⊂ R d , d = 2, 3, a bounded moving domain and by Γ(t) = ∂ω(t) its boundary, called the interface. Let Ω ⊂ R d be the bounded computational domain. We assume that it contains at any time t ⩾ 0 the moving domain ω(t). A function ϕ : [0, ∞[×Ω → R is a level set for the moving domain if and only if Γ(t) = {x ∈ Ω / ϕ(t, x) = 0} for any t ⩾ 0. For a given velocity field u, associated to the motion, the level set function is defined as the solution of the following time dependent transport problem:

(P ): find ϕ, defined in ]0, ∞[×Ω such that    ∂ϕ ∂t + u.∇ϕ = 0 in ]0, ∞[×Ω ϕ(t = 0) = ϕ 0 in Ω (4.1a) (4.1b)
where ϕ 0 is given and represents the initial shape ω(0). Here, we assume a divergence free velocity field, such that the volume of the moving domain is conserved. This is a linear hyperbolic problem.

The level set method for describing moving interfaces was introduced by Osher and Sethian [1988] (see also [START_REF] Sethian | Level set methods and fast marching methods[END_REF]. Note that several choices are possible for the function ϕ: the only requirement being that a fixed isocontour of ϕ coincides with the front at each time t. A common choice is the signed distance from the front: e.g. ω(t) is the part where ϕ(t, .) is negative and ϕ(t, x) = -dist(Γ(t), x) for all x ∈ ω(t). Fig. 4.4, page 151, represents in elevation such a signed distance level set function: the interface Γ, the thick black line, corresponds to the Zalesak slotted disk, that will be our benchmark in the next section.

Approximation

The evolution transport equation (4.1a) is then discretized with respect to time. di Pietro et al.

[2006] and [START_REF] Marchandise | A quadrature-free discontinuous Galerkin method for the level set equations[END_REF] used an explicit and strong stability preserving Runge-Kutta method [START_REF] Gottlieb | Strong stability-preserving high-order time discretization methods[END_REF]. Here, we propose to use a high order implicit scheme based on the following backward differentiation formula (BDF):

∂ϕ ∂t (t) = 1 ∆t p i=0 α p,i ϕ(t-i∆t) + O (∆t p )
where ∆t > 0 is the time step, p ⩾ 1 is the order of the scheme and (α p,i ) 0⩽i⩽p are the p + 1 coefficients of the formula. When p = 1, the scheme coincides with the usual implicit Euler method. For 1 ⩽ p ⩽ 2, the scheme is unconditionally stable, for 3 ⩽ p ⩽ 6, the scheme is almost unconditionally stable while when p > 6, the scheme is unstable and cannot be used (see e.g. Süli and Mayers, 2003, p. 349). The coefficients when p ⩽ 6 are given in table 4.1 and the file 'bdf.icc' implements this table. This file it is not listed here but is available in the Rheolef example directory. When the time step n < p, the scheme is started by using the BDF(n) formula instead and we introduce p n = min(p, n) for convenience. The discretization with respect to space follows the method developed in the previous section 4.1.1. Let us introduce the following linear and bilinear form, defined for all φ, ξ ∈ X h by

p\i 0 1 2 3 4 5 6 1 1 -1 2 3/2 -2
a n (φ, ξ) = Ω α pn,0 ∆t φ ξ + u(t n ).∇ h φ ξ dx + ∂Ω max(0, -u(t n ).n) φ ξ ds + S∈S (i) h S [[φ]] |u(t n ).n| 2 [[ξ]] -u(t n ).n { {ξ} } ds l n (ξ) = - pn i=1 α pn,i ∆t Ω ϕ (n-i) h ξdx (4.2a) (4.2b)
When n = 0 we set ϕ (0) h = π h (ϕ 0 ) and when n ⩾ 1, the time approximation ϕ

(n) h
is defined by a p n -order recurrence as the solution of the following linear problem:

(P ) h : find ϕ (n) h ∈ X h such that a n ϕ (n) h , ξ h = l n (ξ h ), , ∀ξ h ∈ X h
Finally, at each time step, the problem reduces to a linear system.

[New] Example: the Zalesak slotted disk

The Zalesak [1979, p. 350] slotted disk in rotation is a widely used benchmark for comparing the performances of interface capturing methods. The radius of the disk is 0.15 and its center is (0.5, 0.75) The width of the slot is 0.05 and its length is 0.25. This slotted disk is rotated around the barycenter (0.5, 0.5) of the computational domain Ω = [0, 1] 2 at velocity u(x 0 , x 1 ) = (-(x 1 -1/2)/2, (x 0 -1/2)/2), such that the angular velocity curl u = 1 is constant. Note that the slotted disk returns to its initial position after a period t f = 4π. The presentation of this section is mainly inspired from Ta et al. [2016], that used Rheolef. The following code implement the previous BDF scheme for this benchmark.

How to run the program

Let us first generate a mesh for the Ω = ]0, 1[ 2 geometry with h = 1/100 and then run the code with a k = 2 discontinuous Galerkin method and a BDF (3) scheme: mkgeo_ugrid -t 50 > square.geo make zalesak_dg time mpirun -np 8 ./zalesak_dg square P2d > square-P2d.branch

The computation could take about ten minutes, depending upon your computer: there are 1000 time steps by default ; a prompt shows the step advancement until 1000. The time and mpirun -np 8 prefixes are optional and you should omit them if you are running a sequential installation of Rheolef. Then, the visualization writes: branch square-P2d.branch -iso 0 -bw

The slotted disk appears at his initial position. Then, click on the video play button, at the top of the window: the disk starts to rotate. Fig. 4.5 compares the initial disk position with the final one after one period when h = 1/100 and 6000 time steps. Observe the dramatic efficiency of the combination of the discontinuous Galerkin method and the high-order time scheme. The corresponding solution could be directly observed as a video from the following link (3 Mo): http://www-ljk.imag.fr/membres/Pierre.Saramito/rheolef/zalesak-100-P2d-6000.mp4 Moreover, when using higher order polynomials and schemes, e.g. for k ⩾ 3, the changes are no more perceptible and the disk after one period fits the initial shape. The error between the two shapes could also be evaluated, and the convergence versus mesh and polynomial degree could be checked: see [START_REF] Ta | An implicit high order discontinuous Galerkin level set method for two-phase flow problems[END_REF] for more details.

[New] Example: the Leveque vortex-in-box

The LeVeque [1996, p. 653] vortex-in-box is also another widely used benchmark. This example tests the ability of the scheme to accurately resolve thin filaments on the scale of the mesh which can occur in swirling and stretching flows. An initial shape is deformed by a non-constant velocity field given by:

u(t, x) =              cos(πt/t f ) sin 2 (πx 0 ) sin(2πx 1 ) -sin(2πx 0 ) sin 2 (πx 1 ) when d = 2 cos(πt/t f )   2 sin 2 (πx 0 ) sin(2πx 1 ) sin(2πx 2 ) -sin(2πx 0 ) sin 2 (πx 1 ) sin(2πx 2 ) -sin 2 (πx 0 ) sin(2πx 1 ) sin(2πx 2 )   when d = 3
At the half-period t = t f /2, the initial data is quite deformed and the flow slows down and reverses direction in such a way that the initial data should be recovered at time t f . This gives a very useful test problem since we then know the true solution at time t f even though the flow field has a quite complicated structure. Here we use t f = 8 when d = 2 and t f = 3 when d = 3. The initial shape is a circle of radius 0.15 placed at (0.5, 0.75) when d = 2 and a sphere of radius 0.15 placed at (0.35, 0.35, 0.35) when d = 3. The tridimensional flow field was first proposed by LeVeque [1996, p. 662] and the corresponding initial shape described by Enright et al. [2002, p. 112]. The computational domain is Ω =]0, 1[ d and note that the flow field u vanishes on ∂Ω. where n max is the number of time steps. Observe that u is here time-dependent. Then a n , as given by (4.2a), is also dependent upon n, and a n can no more be factored one time for all, as it was done for the Zalesak case. The file 'leveque.h' included here implements both the u and phi0 class-functions for the flow field and the initial data ϕ 0 associated to the initial circular shape, respectively. This file it is not listed here but is available in the Rheolef example directory. Recall that u vanishes on ∂Ω. Then, all boundary terms for a n and ℓ n , involved in (4.2a)-(4.2b), are here omitted.

How to run the program

Compilation and run writes: mkgeo_ugrid -t 100 > square.geo make leveque_dg mirun -np 8 ./leveque_dg square P2d 6000 > square-P2d.branch

The computation could take about two hours, depending upon your computer: a prompt shows the advancement for the 6000 time steps. The mpirun -np 8 prefix is optional and you should omit it if you are running a sequential installation of Rheolef. Then, the visualization writes:

branch square-P2d.branch -iso 0 -bw

As for the Zalesak case, the solution is represented by an animation with paraview. The video could be directly observed from the link (7 Mo):

http://www-ljk.imag.fr/membres/Pierre.Saramito/rheolef/leveque-100-P2d-6000.mp4

Fig. 4.6.left represents the solution when h = 1/100 and 6000 time steps at the half-period t = t f /2, when the deformation is maximal. Conversely, Fig. 4.6.right represents it when t = t f , when the shape recovers its initial position. Observe the good correspondence between the final and the initial shapes, which is represented in red.

Nonlinear first-order problems

Abstract setting

The aim of this paragraph is to study the discontinuous Galerkin discretization of scalar nonlinear hyperbolic equations. This section presents the general framework and discretization tools while the next section illustrates the method for the Burgers equation.

Problem statement

A time-dependent nonlinear hyperbolic problem writes in general form [di Pietro and Ern, 2012, p. 99]:

(P ): find u, defined in ]0, T [×Ω, such that

∂u ∂t + div f (u) = 0 in ]0, T [×Ω (4.3a) u(t = 0) = u 0 in Ω (4.3b) f (u).n = Φ(n; u, g) on ]0, T [×∂Ω (4.3c)
where f (v).ν otherwise (4.3d)

T > 0, Ω ⊂ R d , d = 1,
Note that, with this general formalism, the linear transport problem considered in the previous section 4.1.1 corresponds to (see e.g. di Pietro and Ern, 2012, p. 104:

f (u) = au (4.4a) Φ(n; u, v) = a.n u + v 2 + |a.n| 2 (u -v) (4.4b)

Space discretization

In this section, we consider first the semi-discretization with respect to space while the problem remains continuous with respect to time. The semi-discrete problem writes in variational form [di Pietro and Ern, 2012, p. 100]:

(P ) h : find u h ∈ C 1 ([0, T ], X h ) such that Ω ∂u h ∂t v h dx - Ω f (u h ).∇ h v h dx + S∈S (i) h S Φ(n; u - h , u + h )[[v h ]] ds + ∂Ω Φ(n; u h , g)v h ds = 0, ∀v h ∈ X h u h (t = 0) = π h (u 0 )
where π h denotes the Lagrange interpolation operator on X h and others notations has been introduced in the previous section.

For convenience, we introduce the discrete operator G h , defined for all u h , v h ∈ X h by

Ω G h (u h )v h dx = - Ω f (u h ).∇ h v h dx + S∈S (i) h S Φ(n; u - h , u + h )[[v h ]] ds + ∂Ω Φ(n; u h , g)v h ds(4.5)
For a given u h ∈ X h , we also define the linear form g h as

g(v h ) = Ω G h (u h )v h dx
As the matrix M , representing the L 2 scalar product in X h , is block-diagonal, it can be easily inverted at the element level, and for a given u h ∈ X h , we have G(u h ) = M -1 g h . Then, the problem writes equivalently as a set of coupled nonlinear ordinary differential equations.

(P ) h : find u h ∈ C 1 ([0, T ], X h ) such that ∂u h ∂t + G h (u h ) = 0

Time discretization

Let ∆t > 0 be the time step. The previous nonlinear ordinary differential equations are discretized by using a specific explicit Runge-Kutta with intermediates states [START_REF] Shu | Efficient implementation of essentially non-oscillatory shock-capturing schemes[END_REF][START_REF] Gottlieb | Total variation diminishing Runge-Kutta schemes[END_REF][START_REF] Gottlieb | Strong stability-preserving high-order time discretization methods[END_REF]. This specific variant of the usual Runge-Kutta scheme, called strong stability preserving, is suitable for avoiding possible spurious oscillations of the approximate solution when the exact solution has a poor regularity. Let u n h denotes the approximation of u h at time t n = n∆t, n ⩾ 0. Then u n+1 h is defined by recurrence:

u n,0 h = u n h u n,i h = i-1 j=0 α i,j u n,j h -∆t β i,j G h u n,j h , 1 ⩽ i ⩽ p u n+1 h = u n,p h
where the coefficients satisfy α i,j ⩾ 0 and β i,j ⩾ 0 for all 1 ⩽ i ⩽ p and 0 ⩽ j ⩽ i -1, and i-1 j=0 α i,j = 1 for all 1 ⩽ i ⩽ p. Note that when p = 1 this scheme coincides with the usual explicit Euler scheme. For a general p ⩾ 1 order scheme, there are p -1 intermediate states u n,i h , i = 1 . . . p -1. Computation of the coefficients α i,j and β i,j can be founded in [START_REF] Shu | Efficient implementation of essentially non-oscillatory shock-capturing schemes[END_REF][START_REF] Gottlieb | Total variation diminishing Runge-Kutta schemes[END_REF][START_REF] Gottlieb | Strong stability-preserving high-order time discretization methods[END_REF] and are grouped in file 'runge_kutta_ssp.icc' of the examples directory for convenience.

Slope limiters

Slope limiters are required when the solution develops discontinuities: this is a very classical feature of most solutions of nonlinear hyperbolic equations. A preliminary version of the slope limiter proposed by Cockburn [1998, p. 208] is implemented in Rheolef: this preliminary version only supports the d = 1 dimension and k = 1 polynomial degree. Recall that the k = 0 case do not need any limiter. More general implementation will support the d = 2, 3 and k ⩾ 2 cases in the future. The details of the limiter implementation is presented in this section: the impatient reader, who is interested by applications, can jump to the next section, devoted to the Burgers equation. Fig. 4.7 shows the d+1 neighbor elements K i , i = 0 . . . d around an element d. Let S i = ∂K ∩∂K i , i = 0 . . . d be the i-th side of K. We denote by x K , x Ki ad x Si the barycenters of these elements and sides, i = 0 . . . d. When d = 2, the barycenter x Si of the edge belongs to the interior of a triangle (x K , x Ki , x K J i,1 ) for exactly one of the two possible J i,1 ̸ = i and 0 ⩽ J i,1 ⩽ d. When d = 3, the barycenter x Si of the face belongs to the interior of a tetrahedron (x K , x Ki , x K J i,1 , x K J i,2 ) for exactly one pair (J i,1 , J i,2 ), up to a permutation, of the three possible pairs J i,1 , J i,2 ̸ = i and 0 ⩽ J i,1 , J i,2 ⩽ d. Let us denote J i,0 = i. Then, the vector ----→

x K x Si decompose on the basis

K K 2 x K0 x S0 K 1 K 0 x K x K1
x K2 J(0, 1) = 1

( ------→ x K x K J i,k ) 0⩽k⩽d-1 as ----→ x K x Si = d-1 k=0 α i,k ------→ x K x K J i,k (4.6)
where α i,k ⩾ 0, k = 0 . . . d -1. Let us consider now the patch ω K composed of K and its d neighbors:

ω K = K ∪ K 0 ∪ . . . ∪ K d
For any affine function ξ ∈ P 1 (ω K ) over this patch, let us denote

δ K,i (ξ) = d-1 k=0 α i,k ξ(x K J i,k ) -ξ(x K ) , i = 0 . . . d -1 = ξ(x Si ) -ξ(x K ) from (4.6)
In other terms, δ K,i (ξ) represents the departure of the value of ξ at x Si from its average ξ(x K on the element K.

Let now (φ i ) 0⩽i⩽d-1 denote the Lagrangian basis in K associated to the set of nodes (x Si ) 0⩽i⩽d-1 :

φ i (x Sj ) = δ i,j , 0 ⩽ i, j ⩽ d -1 d-1 i=0 φ i (x) = 1, ∀x ∈ K
The affine function ξ ∈ P 1 (ω K ) expresses on this basis as

ξ(x) = ξ(x K ) + d-1 i=0 δ K,i (ξ) φ i (x), ∀x ∈ K Let now u h ∈ P 1d (T h ).
On any element K ∈ T h , let us introduce its average value:

ūK = 1 meas(K) K u h (x) dx
and its departure from its average value:

ũK (x) = u h|K (x) -ūK , ∀x ∈ K Note that u h ̸ ∈ P 1 (ω K ). Let us extends δ K,i to u h as δ K,i (u h ) = d-1 k=0 α i,k ūK J i,k -ūK , i = 0 . . . d -1 Since u h ̸ ∈ P 1 (ω K ), we have ũK (x K J i,k ) ̸ = δ K,i (u h ) in general.
The idea is then to capture oscillations by controlling the departure of the values ũK (x K J i,k ) from the values δ K,i (u h ). Thus, associate to u h ∈ P 1d (T h ) the quantities

∆ K,i (u h ) = minmod TVB ũK (x K J i,k ), θδ K,i (u h )
for all i = 0 . . . d -1 and where θ ⩾ 1 is a parameter of the limiter and

minmod TVB (a, b) = a when |a| ⩽ M h 2 minmod(a, b) otherwise
where M > 0 is a tunable parameter which can be evaluated from the curvature of the initial datum at its extrema by setting

M = sup x∈Ω,∇u0(x)=0 |∇ ⊗ ∇u 0 | (4.7)
Introduced by [START_REF] Shu | TVB boundary treatment for numerical solutions of conservation laws[END_REF], the basic idea is to deactivate the limiter when space derivatives are of order h 2 . This improves the limiter behavior near smooth local extrema. The Then, for all i = 0 . . . d -1 we define

r K (u h ) = d-1 j=0 max(0, -∆ K,j (u h )) d-1 j=0 max(0, ∆ K,j (u h )) ⩾ 0 ∆K,i (u h ) = min(1, r K (u h )) max(0, ∆ K,i (u h )) -min(1, 1/r K (u h )) max(0, -∆ K,i (u h )), i = 0 . . . d -1 when r K (u h ) ̸ = 0
Finally, the limited function Λ h (u h ) is defined element by element for all element K ∈ T h for all x ∈ K by

Λ h (u h ) |K (x) =            ūK + d-1 i=1 ∆ K,i (u h ) φ i (x) when r K (u h ) = 0 ūK + d-1 i=1 ∆K,i (u h ) φ i (x) otherwise
Note that there are two types of computations involved in the limiter: one part is independent of u h and depends only upon the mesh: J i,k and α i,k on each element. It can be computed one time for all. The other part depends upon the values of u h . Note that the limiter preserves the average value of u h on each element K and also the functions that are globally affine on the patch ω K . Also we have, inside each element K and for all side index i = 0 . . . d -1:

Λ h (u h ) |K (x Si ) -ūK ⩽ max |∆ K,i (u h )|, | ∆K,i (u h )| ⩽ |∆ K,i (u h )| ⩽ u h|K (x Si ) -ūK
It means that, inside each element, the gradient of the P 1 limited function is no larger than that of the original one. The limiter on an element close to the boundary should takes into account the inflow condition, see [START_REF] Cockburn | The Runge-Kutta local projection discontinuous Galerkin finite element method for conservation laws. IV. the multidimensional case[END_REF].

Example: the Burgers equation

As an illustration, let us consider now the test with the one-dimensional (d = 1) Burgers equation for a propagating slant step (see e.g. Carey and Jianng, 1988, p. 87) in Ω =]0, 1[. We have f (u) = u 2 /2, for all u ∈ R. In that case, the Godunov flux (4.3d), introduced page 157, can be computed explicitly for any ν = (ν 0 ) ∈ R d and a, b ∈ R:

Φ(ν; a, b) = ν 0 min a 2 , b 2 /2 when ν 0 ⩾ 0 and a ⩽ b or ν 0 ⩽ 0 and a ⩾ b ν 0 max a 2 , b 2 /2 otherwise

Computing an exact solution

An exact solution is useful for testing numerical methods. The computation of such an exact solution for the one dimensional Burgers equation is described by [START_REF] Harten | Uniformly high order accurate essentially non-oscillatory schemes[END_REF]. The authors consider first the problem with a periodic boundary condition: This nonlinear relation can be solved by a Newton algorithm. Then, for x ∈]-1, 0[, the solution is completed by symmetry: w(t, x) = -w(t, -x). Finally, the general solution for any α, β and γ = 0 writes u(t, x) = α + w(βt, x -αt + γ). File 'harten.h' implements this approach. The included file 'harten0.h' is not shown here but is available in the example directory.

(P ): find u : ]0, T [×]-1, 1[ -→ R such that ∂u ∂t + ∂ ∂x u 2 2 = 0 in ]0, T [×] -1, 1[ u(t = 0, x) = α + β sin(πx + γ), a.e. x ∈] -1, 1[ u(t, x = -1) = u(t, x =

Comments

Note that the constant M , used by the limiter in (4.7), can be explicitly computed for this solution: M = βπ 2 . The animation of this exact solution is performed by the following commands: make harten_show mkgeo_grid -e 2000 -a -1 -b 1 > line2.geo ./harten_show line2 P1 1000 2.5 > line2-exact.branch branch line2-exact -gnuplot ./burgers_dg line2-200.geo P1d 1000 2.5 > line2-200-P1d.branch branch line2-200-P1d.branch -gnuplot Fig. 4.9 plots the error vs h for k = 0 and k = 1. Fig. 4.9.a plots in a time interval [0, T ] with T = 1/π, before the chock that occurs at t = 2/π. In that interval, the solution is regular and the error approximation behaves as O(h k+1 ). The time interval has been chosen sufficiently small for the error to depend only upon h. Fig. 4.9.b plots in a larger time interval [0, T ] with T = 5/2, that includes the chock. Observe that the error behaves as O(h) for both k = 0 and 1. This is optimal when k = 0 but not when k = 1. This is due to the loss of regularity of the exact solution that presents a discontinuity; A similar observation can be found in [START_REF] Zhong | A simple weighted essentially nonoscillatory limiter for Runge-Kutta discontinuous galerkin methods[END_REF], table 4.1. 10 -1

0.5 1 1.5 -1 0 1 u(t, x) (a) t = 0 x 0.5 1 1.5 -1 0 1 (b) t = 1/2 x exact P 0 0.5 1 1.5 -1 0 1 (c) t = 2/π x exact P 0 0.5 1 1.5 -1 0 1 u(t, x) (d) t = 0, 75 x exact P 0 0.5 1 1.5 -1 0 1 u(t, x) (e) t = 1 x exact P 0 0.5 1 1.5 -1 0 1 u(t, x) (f
10 -3 10 -2 10 -1 ∥u -u h ∥ L ∞ (0,T ;L 1 ) (a) T = 2/π 0.96 1.9 h k = 0 k = 1 10 -3 10 -2 10 -1 10 -3 10 -2 10 -1 ∥u -u h ∥ L ∞ (0,T ;L 1 ) (b) T = 5/2 0.85 1 h k = 0 k = 1

Scalar second-order problems

The Poisson problem with Dirichlet boundary conditions

The Poisson problem with non-homogeneous Dirichlet boundary conditions has been already introduced in volume 1, section 1.1.12, page 24:

(P ): find u, defined in Ω, such that

-∆u = f in Ω u = g on ∂Ω
where f and g are given.

The discontinuous finite element space is defined by:

X h = {v h ∈ L 2 (Ω); v h|K ∈ P k , ∀K ∈ T h }
where k ⩾ 1 is the polynomial degree. As elements of X h do not belongs to H 1 (Ω), due to discontinuities at inter-elements, we introduce the broken Sobolev space:

H 1 (T h ) = {v ∈ L 2 (Ω); v |K ∈ H 1 (K), ∀K ∈ T h } such that X h ⊂ H 1 (T h ).
We introduce the folowing bilinear form a h (., .) and linear for l h (.), defined for all u, v ∈ H 1 (T h ) by (see e.g. di Pietro and Ern, 2012, p. 125 and 127, eqn. (4.12)):

a h (u, v) = Ω ∇ h u.∇ h v dx + S∈S h S (κ s [[u]] [[v]] -{ {∇ h u.n} } [[v]] -[[u]] { {∇ h v.n} }) ds (4.8) l h (v) = Ω f u dx + ∂Ω (κ s g v -g ∇ h v.n) ds (4.9)
The last term involves a sum over S h , the set of all sides of the mesh T h , i.e. the internal sides and the boundary sides. By convenience, the definition of the jump and average are extended to all boundary sides as [[u]] = { {u} } = u. Note that, as for the previous transport problem, the Dirichlet boundary condition u = g is weakly imposed on ∂Ω via the integrals on the boundary. Finally, κ s > 0 is a stabilization parameter on a side S. The stabilization term associated to κ s is present in order to achieve coercivity: it penalize interface and boundary jumps. A common choice is κ s = β h -1 s where β > 0 is a constant and h s is a local length scale associated to the current side S. One drawnback to this choice is that it requires the end user to specify the numerical constant β. From one hand, if the value of this parameter is not sufficiently large, the form a h (., .) is not coercive and the approximate solution develops instabilities an do not converge [START_REF] Epshteyn | Estimation of penalty parameters for symmetric interior penalty Galerkin methods[END_REF]. From other hand, if the value of this parameter is too large, its affect the overall efficiency of the iterative solver of the linear system: the spectral condition number of the matrix associated to a h (., .) grows linearly with this paramater [START_REF] Castillo | Performance of discontinuous Galerkin methods for elliptic PDEs[END_REF]. An explicit choice of penalty parameter is proposed [START_REF] Shahbazi | An explicit expression for the penalty parameter of the interior penalty method[END_REF]:

κ s = β ϖ s where β = (k + 1)(k + d)/d and ϖ s =        meas(∂K) meas(K) when S = K ∩ ∂Ω is a boundary side max meas(∂K 0 ) meas(K 0 ) , meas(∂K 1 ) meas(K 1 ) when S = K 0 ∩ K 1 is an internal side
Note that ϖ s scales as h -1 s . Now, the computation of the penalty parameter is fully automatic and the convergence of the method is always guaranted to converge. Moreover, this choice has been founded to be sharp and it preserves the optimal efficiency of the iterative solvers. Finally, the discrete variational formulation writes:

(F V ) h : find u h ∈ X h such that a h (u h , v h ) = l h (v h ), ∀v h ∈ X h
The following code implement this problem in the Rheolef environment.

Comments

The penalty() pseudo-function implements the computation of ϖ s in Rheolef. The right-hand side f and g are given by (1.4), volume 1, page 25. In that case, the exact solution is known. Running the one-dimensional case writes: make dirichlet_dg mkgeo_grid -e 10 > line.geo ./dirichlet_dg line P1d | field -./dirichlet_dg line P2d | field - 10 -10 The space H 1 (T h ) is equiped with the norm ∥.∥ 1,h , defined for all v ∈ H 1 (T h by di Pietro and Ern [2012, p. 128]:

-1 0 1 0 0.5 1 h = 1/10 x u(x) u h (x) -1 0 1 0 0.5 1 h = 1/20 x u(x) u h (x)
10 -5 1 10 -2 10 -1 ∥u -u h ∥ 0,Ω 2 = k + 1 5 = k + 1 h k = 1 k = 2 k = 3 k = 4 10 -15 10 -10 10 -5 1 10 -2 10 -1 ∥u -u h ∥ ∞,Ω 2 = k + 1 5 = k + 1 h k = k = k = k = 10 -10 10 -5 1 10 -2 10 -1 ∥u -u h ∥ 1,h 1 = k 4 = k h k = 1 k = 2 k = 3 k = 4
∥v∥ 2 1,h = ∥∇ h v∥ 2 0,Ω + S∈S h S h -1 s [[v]] 2 ds
The code cosinusprod_error_dg.cc compute the error in these norms. This code it is not listed here but is available in the Rheolef example directory. The computation of the error writes: make cosinusprod_error_dg ./dirichlet_dg square P1d | cosinusprod_error_dg Fig. 4.11 plots the error u -u h in L 2 , L ∞ and the ∥.∥ 1,h norms. The L 2 and L ∞ error norms behave as O h k+1 for all k ⩾ 0, while the ∥.∥ 1,h one behaves as O h k , which is optimal.

The Helmholtz problem with Neumann boundary conditions

The Poisson problem with non-homogeneous Neumann boundary conditions has been already introduced in volume 1, section 1.2, page 32:

(P ): find u, defined in Ω, such that u -∆u = f in Ω ∂u ∂n = g on ∂Ω
where f and g are given. We introduce the folowing bilinear form a h (., .) and linear for l h (.), defined for all u, v ∈ H 1 (T h ) by (see e.g. di Pietro and Ern, 2012, p. 127, eqn. (4.16)):

a h (u, v) = Ω (u v + ∇ h u.∇ h v) dx (4.10) + S∈S (i) h S (βϖ s [[u]] [[v]] -{ {∇ h u.n} } [[v]] -[[u]] { {∇ h v.n} }) ds (4.11) l h (v) = Ω f u dx + ∂Ω g v ds (4.12)
Let us comment the changes between these forms and those used for the Poisson problem with Dirichlet boundary conditions. The Poisson operator -∆ has been replaced by the Helmholtz one I -∆ in order to have an unique solution. Remark also that the sum is performed in (4.8) for all internal sides in S (i) h , while, in (4.8), for Dirichlet boundary conditions, it was for all sides in S h , i.e. for both boundary and internal sides. Also, the right-hand-side linear form l h (.). do no more involves any sum over sides. Finally, the discrete variational formulation writes:

(F V ) h : find u h ∈ X h such that a h (u h , v h ) = l h (v h ), ∀v h ∈ X h
The following code implement this problem in the Rheolef environment.

Comments

The right-hand side f and g are given by (1.5), volume 1, page 25. In that case, the exact solution is known. Running the program is obtained from the non-homogeneous Dirichlet case, by replacing dirichlet_dg by neumann_dg.

[New] Heterogeneous diffusion

The problem with with non-constant diffusion coefficients has already been introduced in section 4.3.3, page 171 when studying continuous approximations. It writes (P ): find u defined in Ω such that:

-div(η∇u) = f in Ω u = 0 on Γ left ∪ Γ right ∂u ∂n = 0 on Γ top ∪ Γ bottom when d ⩾ 2 ∂u ∂n = 0 on Γ front ∪ Γ back when d = 3
where f is a given source term. We consider here the important special case when the diffusion coefficient η is piecewise constant:

η(x) = ε when x ∈ Ω west 1 when x ∈ Ω east
where (Ω west , Ω east ) is a partition of Ω in two parts (see Fig. 1.10,page 38). This is the socalled transmission problem: the solution and the flux are continuous on the interface Γ 0 = ∂Ω east ∩ ∂Ω west between the two domains where the problem reduce to a constant diffusion one:

u Ωwest = u Ωeast on Γ 0 ε ∂u /Ωwest ∂n = ∂u Ωeast ∂n on Γ 0
Following [START_REF] Dryja | On discontinuous Galerkin methods for elliptic problems with discontinuous coefficients[END_REF], we use the discontinuous Galerkin with diffusion-dependent weights to formulate the consistency and symmetry terms in the discrete bilinear form and we penalize interface and boundary jumps using a diffusion-dependent parameter scaling as the harmonic mean of the diffusion coeffcient. As pointed out by di Pietro and Ern [2012, p. 150], this a penalty strategy is particularly important in heterogeneous diffusion-convection problems where the diffusion coeffcient takes locally small values leading to advection-dominated regimes. In this context, the exact solution exhibits sharp inner layers which, in practice, are not resolved by the underlying meshes, so that excessive penalty at such layers triggers spurious oscillations. Using the harmonic mean of the diffusion coeffcient to penalize jumps turns out to tune automatically the amount of penalty and thereby avoid such oscillations.

The weighted average is defined for any function v and on any side S ∈ S (i)

h by { {v} } ω = ω K0,S v |K0 + ω K1,S v |K1
where K 0 , K 1 ∈ T h such that S = K 0 ∩ K 1 and where the two weights ω K0,S , ω K1,S express

ω K0,S = η |K0 η |K0 + η |K1 and ω K1,S = η |K1 η |K0 + η |K1
Note that ω K0,S + ω K1,S = 1. On a boundary side S ⊂ ∂Ω" we set { {v} } ω = v. The bilinear form a h (., .) and linear for l h (.) are obtained by simply using the weighted average { {.} } ω instead of { {.} } and taking into accound upon te mixed Dirichlet and Neumann boundary condition. For all u, v ∈ H 1 (T h ), they are given by (see e.g. di Pietro and Ern, 2012, p. 155, eqn. (4.64)):

a h (u, v) = Ω η∇ h u.∇ h v dx + S∈S (i) h ∪Γ d S (η s κ s [[u]] [[v]] -{ {η∇ h u.n} } w [[v]] -{ {η∇ h v.n} } w [[u]]) ds l h (v) = Ω f u dx + Γ d (κ s g v -g ∇ h v.n) ds
where Γ d = Γ left ∪ Γ right denote, for convenience, the boundary domain corresponding to the nonhomogeous Dirichlet boundary condition, η s = 2/(1/η |K0 + 1/η |K1 ) is the geometric mean of the diffusion coefficient on an internal side and κ s = β ϖ s is the stabilization, as introduced in the previous section 4.3.1. Finally, the discrete variational formulation writes:

(F V ) h : find u h ∈ X h such that a h (u h , v h ) = l h (v h ), ∀v h ∈ X h
The following code implement this problem in the Rheolef environment. .12 plots the one-dimensional solution when k = 1 for two meshes. Observe that the jumps at inter-element nodes decreases very fast with mesh refinement and are no more perceptible on the plots. Recall that the Dirichlet boundary conditions at x = 0 and x = 1 is only weakly imposed: the corresponding jump at the boundary is small on the finer mesh. When k ⩾ 2, the approximate solution coincides with the interpolation of the exact one, since the exact solution is piecewise quadratic and the interface of discontinuity coincides with internal mesh sides.

Nonlinear scalar hyperbolic problems with diffusion

A time-dependent nonlinear second order problem with nonlinear first order dominated terms problem writes:

(P ): find u, defined in ]0, T [×Ω, such that

∂u ∂t + div f (u) -ε∆u = 0 in ]0, T [×Ω (4.13a) u(t = 0) = u 0 in Ω (4.13b) u = g on ]0, T [×∂Ω (4.13c)
where ε > 0, T > 0, Ω ⊂ R d , d = 1, 2, 3 and the initial condition u 0 being known. The function f : R -→ R d is also known and supposed to be continuously differentiable. The initial data u 0 , defined in Ω, and the boundary one, g, defined on ∂Ω are given. Comparing (4.13a)-(4.13c) with the non-diffusive case (4.3a)-(4.3c) page 157, the second order term has been added in (4.13a) and the upstream boundary condition has been replaced by a Dirichlet one (4.13c).

Example: the Burgers equation with diffusion

Problem statement and its exact solution Our model problem in this chapter is the one-dimensional Burgers equation. It was introduced in section 4.2.3, page 161 with the choice f (u) = u 2 /2, for all u ∈ R. Equation (4.13a) admits an exact solution The solution is represents on Fig. 4.13. Here x 0 represent the position of the front at t = 0 and ε is a characteristic width of the front. The initial and boundary condition are chosen such that u(t, x) is the solution of (4.13a)-(4.13c).

0 1 2 -1 0 1 u(t, x) x t = 0 t = 1
u(t, x) = 1 -tanh x -x 0 -t 2ε (4.14)
10 -5

10 -4 10 -3 10 -2 10 -1 10 -6 10 -5 10 -4 10 -3 10 -2 10 -1 Fig. 4.14.a plots the error versus ∆t for the semi-implicit scheme when k = 1 and 2, and for h = 2/50. The time step for which the error becomes independent upon ∆t and depends only upon h is of about ∆t = 10 -3 when k = 1 and of about 10 -5 when k = 2. This approach is clearly inefficient for high order polynomial k and a hiher order time scheme is required. Fig. 4.14.b plots the error versus ∆t for the Runge-Kutta semi-implicit scheme with p = 3, k = 1 and h = 2/200. The scheme is clearly only first-order, which is still unexpected. More work is required...

∥u -u h ∥ L ∞ (0,T ;L 2 ) (a) k = 1, h = 2/50 1 ∆t k = 1 k = 2 10 -5 10 -4 10 -3 10 -2 10 -1 10 -5 10 -4 10 -3 10 -2 10 -1 ∥u -u h ∥ L ∞ (0,T ;L 2 ) (b) k = 1, h = 2/400 1 2 3 ∆t p = 1 p = 2 p = 3

Space discretization

The discontinuous finite element space is defined by:

X h = {v h ∈ L 2 (Ω); v h|K ∈ P k , ∀K ∈ T h }
where k ⩾ 1 is the polynomial degree. As elements of X h do not belongs to H 1 (Ω), due to discontinuities at inter-elements, we introduce the broken Sobolev space:

H 1 (T h ) = {v ∈ L 2 (Ω); v |K ∈ H 1 (K), ∀K ∈ T h } such that X h ⊂ H 1 (T h ).
As for the Dirichlet problem, introduce the folowing bilinear form a h (., .) and linear for l h (.), defined for all u, v ∈ H 1 (T h ) by (see e.g. di Pietro and Ern, 2012, p. 125 and 127, eqn. (4.12)):

a h (u, v) = Ω ∇ h u.∇ h v dx + S∈S h S (κ s [[u]] [[v]] -{ {∇ h u.n} } [[v]] -[[u]] { {∇ h v.n} }) ds(4.15) ℓ h (v) = ∂Ω (κ s g v -g ∇ h v.n) ds (4.16)
The semi-discrete problem writes in variational form [di Pietro and Ern, 2012, p. 100]:

(P ) h : find u h ∈ C 1 ([0, T ], X h ) such that Ω ∂u h ∂t v h dx Ω G h (u h ) v h dx + ε a h (u h , v h ) = ε ℓ h (v h ), ∀v h ∈ X h u h (t = 0) = π h (u 0 )
where G h has been introduced in (4.5), page 157.

Time discretization

Explicit Runge-Kutta scheme is possible for this problem but it leads to an excessive Courant-Friedrichs-Levy condition for the time step ∆t, that is required to be lower than an upper bound that varies in O(h 2 ). The idea here is to continue to explicit the first order nonlinear terms and implicit the linear second order terms. Semi-implicit second order Runge-Kutta scheme was first introduced by [START_REF] Ascher | Implicit-explicit Runge-Kutta methods for timedependent partial differential equations[END_REF] and then extended to third and fourth order by [START_REF] Calvo | Linearly implicit Runge-Kutta methods for advectionreaction-diffusion equations[END_REF]. Wang, Shu, and Zhang [2015a,b] applied it in the context of the discontinuous Galerkin method. The finite dimensional problem can be rewritten as

(P ) h : find u h ∈ C 1 ([0, T ], X h ) such that ∂u h ∂t + G h (t, u h ) + A h (t, u h ) = 0, ∀t ∈]0, T [ u h (t = 0) = π h (u 0 )
where G h has been introduced in (4.5), page 157 and A h denotes the diffusive term. The semiimplicit Runge-Kutta scheme with p ⩾ 0 intermediate steps writes at time step t n :

u n,0 h = u n h (4.17a) u n,i h = u n h -∆t i j=1 α i,j A h t n,j , u n,j h -∆t i-1 j=0 αi,j G h t n,j , u n,j h , i = 1, . . . , p(4.17b) u n+1 h = u n h -∆t p i=1 β i A h t n,i , u n,i h -∆t p i=0 βi G h t n,i , u n,i h (4.17c) where u n,i h 1⩽i⩽p are the p ⩾ 1 intermediate states, t n,i = t n + γ i ∆t, γ i = i j=1 α i,j = i-1
j=0 αi,j , and (α i,j ) 0⩽i,j⩽p , (α i,j ) 0⩽i,j⩽p , (β i ) 0⩽i⩽p and ( βi ) 0⩽i⩽p are the coefficients of the scheme [START_REF] Ascher | Implicit-explicit Runge-Kutta methods for timedependent partial differential equations[END_REF][START_REF] Calvo | Linearly implicit Runge-Kutta methods for advectionreaction-diffusion equations[END_REF], Wang et al., 2015a]. At each time step, have to solve p linear systems. From (4.17b) we get for all i = 1, . . . , p:

(I + ∆t α i,i A h (t n,i )) u n,i h = u n h -∆t i-1 j=1 α i,j A h t n,j , u n,j h -∆t i-1 j=0 αi,j G h t n,j , u n,j h
Note that when the matrix coefficients of A h (t, .) are indepencdent of t, the matrix involved on the right-hand-side of the previous equation can be factored one time for all. The included file 'runge_kutta_semiimplicit.icc' is not shown here but is available in the example directory.

Running the program

0 1 2 -1 0 1 u(t, x) x t = 0 t = 1 0 1 2 -1 0 1 u(t, x) x t = 0 t = 1

Fluids and solids computations revisited

The linear elasticity problem

The elasticity problem (2.2) has been introduced in volume 1, section 2.1.1, page 43.

(P ): find u such that

-div (λdiv(u).I + 2D(u)) = f in Ω u = g on ∂Ω
where λ ⩾ -1 is a constant and f , g given. This problem is a natural extension to vector-valued field of the Poisson problem with Dirichlet boundary conditions. The variational formulation writes:

(F V ) h : find u ∈ V(g) such that a(u, v) = l h (v), ∀v ∈ V(0)
where

V(g) = {v ∈ H 1 (Ω) d ; v = g on ∂Ω} a(u, v) = Ω (λ div(u) div(v) + 2D(u) : D(v)) dx l(v) = Ω f .v dx
The discrete variational formulation writes:

(F V ) h : find u h ∈ X h such that a h (u h , v h ) = l h (v h ), ∀v h ∈ X h
where

X h = {v h ∈ L 2 (Ω) d ; v h|K ∈ P d k , ∀K ∈ T h } a h (u, v) = Ω (λ div h (u) div h (v) + 2D h (u) : D h (v)) dx + S∈S h S (βϖ s [[u]].[[v]] -[[u]].{ {λdiv h (v)n + 2D h (v)n} } -[[v]].{ {λdiv h (u)n + 2D h (u)n} }) ds l h (v) = Ω f .v dx + ∂Ω g. (βϖ s v -λdiv h (v)n -2D h (v)n) ds
where k ⩾ 1 is the polynomial degree in X h .

Comments

The data are given when d = 2 by: g(x) = -cos(πx 0 ) sin(πx 1 ) sin(πx 0 ) cos(πx 1 ) and f = 2π 2 g (4.18)

This choice is convenient since the exact solution is known u = g. This benchmark solution was proposed by [START_REF] Taylor | On the decay of vortices in a viscous fluid[END_REF] in the context of the Stokes problem. Note that the solution is independent of λ since div(u) = 0. As the exact solution is known, the error can be computed. The code elasticity_taylor_error_dg.cc and its header file taylor_exact.h compute the error in L 2 , L ∞ and energy norms. These files are not listed here but are available in the Rheolef example directory. The computation writes: (P ): find u and p, defined in Ω, such that

-div(2D(u)) + ∇p = f in Ω, -div u = 0 in Ω, u = g on ∂Ω
where f and g are given. This problem is the extension to divergence free vector fields of the elasticity problem. The variational formulation writes:

(V F ) h find u ∈ V(g) and p ∈ L 2 (Ω) such that: a(u, v) + b(v, p) = l(v), ∀v ∈ V(0), b(u, q) = 0, ∀q ∈ L 2 (Ω) (4.19)
where

V(g) = {v ∈ H 1 (Ω) d ; v = g on ∂Ω} a(u, v) = Ω 2D(u) : D(v) dx b(u, q) = - Ω div(u) q dx l(v) = Ω f .v dx
The discrete variational formulation writes:

(V F ) h find u h ∈ X h and p h ∈ Q h such that: a h (u h , v h ) + b h (v h , p h ) = l h (v h ), ∀v h ∈ X h , b h (u h , q h ) -c h (p h , q h ) = k h (q), ∀q h ∈ Q h . (4.20)
The discontinuous finite element spaces are defined by:

X h = {v h ∈ L 2 (Ω) d ; v h|K ∈ P d k , ∀K ∈ T h } Q h = {q h ∈ L 2 (Ω) d ; q h|K ∈ P d k , ∀K ∈ T h }
where k ⩾ 1 is the polynomial degree. Note that velocity and pressure are approximated by the same polynomial order. This method was introduced by Cockburn et al. [2002] and some recent theoretical results can be founded in di Pietro and Ern [2010]. The forms are defined for all u, v ∈ H 1 (T h ) d and q ∈ L 2 (Ω) by (see e.g. di Pietro and Ern, 2012, p. 249):

a h (u, v) = Ω 2D h (u) : D h (v) dx + S∈S h S (βϖ s [[u]].[[v]] -[[u]].{ {2D h (v)n} } -[[v]].{ {2D h (u)n} }) ds b h (u, q) = Ω u.∇ h q dx - S∈S (i) h S { {u} }.n [[q]] ds c h (p, q) = S∈S (i) h S h s [[p]] [[q]] ds l h (v) = Ω f .v ds + ∂Ω g. (βϖ s v -2D h (v) n) ds k h (q) = ∂Ω g.n q ds
The stabilization form c h controls the pressure jump across internal sides. This stabilization term is necessary when using equal order polynomial approximation for velocity and pressure. The definition of the forms is grouped in a subroutine: it will be reused later for the Navier-Stokes problem.

File 4.17: stokes_dirichlet_dg.icc + integrate ( " internal_sides " , -dot ( average ( u ) , normal ())* jump ( q ) , iopt ); kh = integrate ( " boundary " , dot ( g () , normal ())* q , iopt );

Comments

The data are given when d = 2 by (4.18). This choice is convenient since the exact solution is known u = g and p = 0. The code stokes_taylor_error_dg.cc compute the error in L 2 , L ∞ and energy norms. This code it is not listed here but is available in the Rheolef example directory. The computation writes: (P ): find u and p, defined in Ω, such that

Re (u.∇)u -div(2D(u)) + ∇p = f in Ω, -div u = 0 in Ω, u = g on ∂Ω
Note that, when Re > 0, the problem is nonlinear, due to the inertia term u.∇u. When Re = 0 the problem reduces to the linear Stokes problem, presented in the previous section/ The variational formulation of this nonlinear problem writes:

(F V ): find u ∈ V(g) and p ∈ L 2 (Ω) such that Re t(u; u, v) + a(u, v) + b(v, p) = l(v), ∀v ∈ V(0), b(u, q) = 0, ∀q ∈ L 2 (Ω)
where the space V(g) and forms a, b and l are given as in the previous section 4.4.2 for the Stokes problem and the trilinear form t(.; ., .) is given by:

t(w; u, v) = Ω ((w.∇)u).v dx 4.5.2 The discrete problem Let t(w; u, u) = Ω (w.

∇u).u dx

Observe that, for all u, w ∈ H 1 (Ω) d we have

Ω (w.∇u).u dx = d-1 i,j=0 Ω u i w j ∂ j (u i ) dx = d-1 i,j=0
-

Ω u i ∂ j (u i w j ) dx + ∂Ω u 2 i w j n j dx = d-1 i,j=0
-

Ω u i ∂ j (u i ) w j dx - Ω u 2 i ∂ j (w j ) dx + ∂Ω u 2 i w j n j dx = - Ω (w.∇u).u dx - Ω div(w) |u| 2 dx + ∂Ω w.n |u| 2 ds (4.21) Thus t(w; u, u) = Ω (w.∇u).u dx = - 1 2 Ω div(w) |u| 2 dx + 1 2 ∂Ω w.n |u| 2 ds
When div(w) = 0, the trilinear form t(.; ., .) reduces to a boundary term: it is formally skewsymmetric. The skew-symmetry of t is an important property: let (v, q) = (u, p) as test functions in (F V ). We obtain:

a(u, u) = l(u)
In other words, we obtain the same energy balance as for the Stokes flow and inertia do not contribute to the energy balance. This is an important property and we aim at obtaining the same one at the discrete level. As the discrete solution u h is not exactly divergence free, following Temam, we introduce the following modified trilinear form:

t * (w; u, v) = Ω (w.∇u) .v + 1 2 div(w) u.v dx - 1 2 ∂Ω (w.n) u.v ds, ∀u, v, w ∈ H 1 (Ω) d
This form integrates the non-vanishing terms and we have:

t * (w; u, u) = 0, ∀u, w ∈ H 1 (Ω) d
When the discrete solution is not exactly divergence free, it is better to use t * than t.

The discontinuous finite element spaces X h and Q h and forms a h , b h , c h , l h and k h are defined as in the previous section. Let us introduce t * h , the following discrete trilinear form, defined for all u h , v h , w h ∈ X h :

t * h (w h ; u h , v h ) = Ω (w h .∇ h u h ) .v h + 1 2 div h (w h ) u h .v h dx - 1 2 ∂Ω (w h .n) u h .v h ds
Note that t * h is similar to t * : the gradient and divergence has been replaced by their broken counterpart in the first term. As X h ̸ ⊂ H 1 (Ω) d , the skew-symmetry property is not expected to be true at the discrete level. Then

t * h (w h ; u h , u h ) = K∈T h K (w h .∇u h ) .u h + 1 2 div(w h ) |u h | 2 dx - 1 2 ∂Ω (w h .n) |u h | 2 ds
As the restriction of u h and w h to each K ∈ T h belongs to H 1 (K) d , we have, using a similar integration by part:

K (w h .∇u h ).u h dx = - 1 2 K div(w h ) |u h | 2 dx + 1 2 ∂K (w h .n) |u h | 2 ds Thus t * h (w h ; u h , u h ) = 1 2 K∈T h ∂K (w h .n) |u h | 2 ds - 1 2 ∂Ω (w h .n) |u h | 2 ds
The terms on boundary sides vanish while those on internal sides can be grouped:

t * h (w h ; u h , u h ) = 1 2 S∈S (i) h S [[|u h | 2 w h ]].n ds The jump term [[(u h .v h ) w h ]]
.n is not easily manageable and could be developed. A short computation shows that, for all scalar fields ϕ, φ we have on any internal side the following identity:

[[ϕφ]] = [[ϕ]]{ {φ} } + { {ϕ} }[[φ]] (4.22) { {ϕφ} } = { {ϕ} }{ {φ} } + 1 4 [[ϕ]][[φ]] (4.23) Then t * h (w h ; u h , u h ) = 1 2 S∈S (i) h S { {w h } }.n [[|u h | 2 ]] + [[w h ]].n { {|u h | 2 } } ds = S∈S (i) h S { {w h } }.n ([[u h ]].{ {u h } }) + 1 2 [[w h ]].n { {|u h | 2 } } ds
Thus, as expected, the skew-symmetry property is no more satisfied at the discrete level, due to the jumps of the fields at the inter-element boundaries. Following the previous idea, we introduce the following modified discrete trilinear form:

t h (w h ; u h , v h ) = t * h (w h ; u h , v h ) - S∈S (i) h S { {w h } }.n ([[u h ]].{ {v h } }) + 1 2 [[w h ]].n { {u h .v h } } ds = Ω (w h .∇ h u h ) .v h + 1 2 div h (w h ) u h .v h dx - 1 2 ∂Ω (w h .n) u h .v h ds - S∈S (i) h S { {w h } }.n ([[u h ]].{ {v h } }) + 1 2 [[w h ]].n { {u h .v h } } ds (4.24)
This expression has been proposed by di Pietro and Ern [2010, p. 22], eqn (72) (see also di Pietro and Ern, 2012, p. 272, eqn (6.57)). The boundary term introduced in t h may be compensated in the right-hand side:

l * h (v) := l h (v) - Re 2 ∂Ω (g.n) g.v h ds
Note that the boundary term introduced in t h is compensated in the right-hand side l * h . The discrete problem is

(F V ) h : find u h ∈ X h and p ∈ Q h such that Re t h (u h ; u h , v h ) + a h (u h , v h ) + b h (v h , p h ) = l * h (v h ), ∀v h ∈ X h , b h (u h , q h ) -c h (p h , q h ) = k h (q), ∀q h ∈ Q h (4.25)
The simplest approach for solving the discrete problem is to consider a fixed-point algorithm. The sequence u

(k) h k⩾0
is defined by recurrence as:

• k = 0: let u (0) h ∈ X h being known. • k ⩾ 0: let u (k-1) h ∈ X h given. Find u (k) h ∈ X h and p (k) h ∈ Q h such that Re t h u (k-1) h ; u (k) h , v h + a h u (k) h , v h + b h v h , p (k) h = l * h (v h ), ∀v h ∈ X h , b h u (k) h , q h -c h p (k) h , q h = k h (q), ∀q h ∈ Q h .
At each step k ⩾ 0, this algorithm involves a linear subproblem of Stokes-type.

Comments

The data are given when d = 2 by (4.18). This choice is convenient since the exact solution is known u = g and p = -(Re/4)(cos(2πx 0 ) + cos(2πx 1 )). The code navier_stokes_taylor_error_dg.cc compute the error in L 2 , L ∞ and energy norms. This code it is not listed here but is available in the Rheolef example directory. The computation writes: make navier_stokes_taylor_dg navier_stokes_taylor_error_dg ./navier_stokes_taylor_dg square P1d 10 10 | ./navier_stokes_taylor_error_dg ./navier_stokes_taylor_dg square P2d 10 10 | ./navier_stokes_taylor_error_dg

A conservative variant

Remark the identity div(u ⊗ u) = (u.∇)u + div(u) u

The momentum conservation can be rewritten in conservative form and the problem writes:

( P ): find u and p, defined in Ω, such that

div(Re u ⊗ u -2D(u)) + ∇p = f in Ω, -div u = 0 in Ω, u = g on ∂Ω
Note the Green formulae (see volume 1, appendix A.1.2, page 279):

Ω div(u ⊗ u).v dx = - Ω (u ⊗ u) : ∇v dx + ∂Ω (u.n) (u.v) ds
The variational formulation is:

( F V ): find u ∈ V(g) and p ∈ L 2 (Ω) such that Re t(u; u, v) + a(u, v) + b(v, p) = l(v), ∀v ∈ V(0), b(u, q) = 0, ∀q ∈ L 2 (Ω)
where the forms t and lh are given by:

t(w; u, v) = - Ω (w ⊗ u) : ∇v dx l(v) = l(v) -Re ∂Ω (g.n) (g.v) ds
Note that the right-hand side l contains an additional term that compensates those coming from the integration by parts. Then, with v = u:

t(w; u, u) = - Ω (w ⊗ u) : ∇u dx = Ω div(w ⊗ u).u dx - ∂Ω (w ⊗ u) : (u ⊗ n) dx = Ω (((u.∇)w).u + div(u) (u.w)) dx - ∂Ω (u.n) (u.w) dx
From an integration by part similar to (4.21):

Ω (u.∇w).u dx = - Ω (u.∇u).w dx - Ω div(u) (u.w) dx + ∂Ω (u.n) (u.w) ds
The term (u.∇w).u do not reapper after the integration by parts: instead, it appears (u.∇u).w. Thus, the structure of the t trilinear form do not permit a general skew-symmetry property as it was the case for t. It requires the three arguments to be the same:

t(u; u, u) = Ω ((u.∇)u).u + div(u) |u| 2 dx - ∂Ω (u.n) |u| 2 dx
Using (4.21) with w = u leads to:

Ω ((u.∇)u).u dx = - 1 2 Ω div(u) |u| 2 dx + 1 2 ∂Ω (u.n) |u| 2 ds (4.26) Then t(u; u, u) = 1 2 Ω div(u) |u| 2 dx - 1 2 ∂Ω (u.n) |u| 2 ds
When working with velocities that are not divergence-free, a possible modification of the trilinear form t is to consider

t * (w; u, v) = t(w; u, v) - 1 2 Ω div(v) (u.w) dx + 1 2 ∂Ω (v.n) (u.w) ds = - Ω (w ⊗ u) : D(v) + 1 2 div(v) (u.w) dx + 1 2 ∂Ω (v.n) (u.w) ds
Then we have

t * (u; u, u) = 0, ∀u ∈ H 1 (Ω) d
The new variational formulation is:

( F V ) * : find u ∈ V(g) and p ∈ L 2 (Ω) such that Re t * (u; u, v) + a(u, v) + b(v, p) = l(v), ∀v ∈ V(0), b(u, q) = 0, ∀q ∈ L 2 (Ω)
One can easily check that when (u, p) is a solution of ( F V ) * , then (u, p) is a solution of ( F V ) with p = p + Re|u|/2. The apparition of the kinetic energy term Re|u|/2 in the modified pressure field p is due to the introduction of the div(v) (u.w) term in the trilinear form t * . At the discrete level, let us define for all u h , v h , w h ∈ X h :

t * h (w h ; u h , v h ) = - Ω (w h ⊗ u h ) : ∇ h v h + 1 2 div h (v h ) (u h .w h ) dx + 1 2 ∂Ω (v h .n) (u h .w h ) ds
Note that t * h is similar to t * : the gradient and divergence has been replaced by their broken counterpart in the first term. As X h ̸ ⊂ H 1 (Ω) d , the skew-symmetry property is not expected to be true at the discrete level. Then

t * h (u h ; u h , u h ) = - Ω (u h ⊗ u h ) : ∇ h u h + 1 2 div h (u h ) |u h | 2 dx + 1 2 ∂Ω (u h .n) |u h | 2 ds
Next, using (4.26) in each K, and then developing thanks to (4.22)-(4.23), we get

t * h (u h ; u h , u h ) = 1 2 ∂Ω (u h .n) |u h | 2 ds - 1 2 K∈T h ∂K (u h .n) |u h | 2 ds = - 1 2 S∈S (i) h S [[(u h .n) |u h | 2 ]] ds = - 1 2 S∈S (i) h S ({ {u h } }.n) [[|u h | 2 ]] + ([[u h ]].n) { {|u h | 2 } } ds = - S∈S (i) h S ({ {u h } }.n) ({ {u h } }.[[u h ]]) + 1 2 ([[u h ]].n) { {|u h | 2 } } ds
The idea is to integrate this term in the definition of a discrete th . One of the possibilities is The discrete problem is

th (w h ; u h , v h ) = t * h (w h ; u h , v h ) + S∈S (i) h S ({ {u h } }.n) ({ {w h } }.[[v h ]]) + 1 2 { {u h .w h } } ([[v h ]].n) ds = - Ω (w h ⊗ u h ) : ∇ h v h + 1 2 div h (v h ) (u h .w h ) dx + 1 2 ∂Ω (v h .n) (u h .w h ) ds + S∈S (i) h S ({ {u h } }.n) ({ {w h } }.[[v h ]]) + 1 2 { {u h .w h } } ([[v h ]].n) ds (
( F V ) h : find u h ∈ X h and p ∈ Q h such that Re th (u h ; u h , v h ) + a h (u h , v h ) + b h (v h , ph ) = l * h (v h ), ∀v h ∈ X h , b h (u h , q h ) -c h (p h , q h ) = k h (q), ∀q h ∈ Q h
A simple test program is obtained by replacing in navier_stokes_taylor_dg.cc the include inertia.h by inertia_cks.icc. The compilation and run are similar.

Newton solver

The discrete problems (F V ) h can be put in a compact form:

F (u h , p h ) = 0
where F is defined in variational form:

⟨F (u h , p h ), (v h , q h )⟩ = Re t h (u h ; u h , v h ) + a h (u h , v h ) + b h (v h , p h ) -l * h (v h ) b h (u h , q h ) -c h (p h , q h ) -k h (q)
for all (v h , q h ) ∈ X h × Q h . Note that, after some minor modifications in the definition of F , this method could also applies for the locally conservative formulation ( F V ) h . The previous formulation is simply the variational expression of F (u h , p h ) = 0. The Newton method defines the sequence u

(k) h k⩾0
by recurrence as:

• k = 0: let u (0) h ∈ X h being known. • k ⩾ 0: let u (k-1) h ∈ X h given. Find δu h ∈ X h and δp h ∈ Q h such that F ′ u (k-1) h , p (k-1) h .(δu h , δp h ) = -F u (k-1) h , p (k-1) h
and then defines u

(k) h = u (k-1) h + δu h and p (k) h = p (k-1) h + δp h
At each step k ⩾ 0, this algorithm involves a linear subproblem involving the Jacobean F ′ that is defined by its variational form:

⟨F ′ u (k-1) h , p (k-1) h .(δu h , δp h ), (v h , q h )⟩ = Re (t h (δu h ; u h , v h ) + t h (u h ; δu h , v h )) + a h (δu h , v h ) + b h (v h , δp h ) b h (δu h , q h ) -c h (δp h , q h )

Comments

The implementation of the Newton method follows the generic approach introduced in volume 1, section 3.2.3, page 119. For that purpose we define a class navier_stokes_dg. The member functions of the class are defined in two separate files.

Upwinding

The skew symmetry property is generalized to the requirement that t h be non-dissipative (see di Pietro and Ern, 2012, p. 282, eqn (6.68)):

t h (w h ; u h , u h ) ⩾ 0, ∀w h , u h ∈ X h
A way to satisfy this property is to add an upwinding term in t h :

th (w h ; u h , v h ) := t h (w h ; u h , v h ) + s h (w h ; u h , v h ) with s h (w h ; u h , v h ) = 1 2 S∈S (i) h S |{ {w h } }.n| ([[u h ]].[[v h ]]) ds
We aim at using a Newton method. We replace t h by its extension th containing the upwind terms in the definition of F , and then we compute its Jacobean F ′ . As the absolute value is not differentiable, the functions s h , th and then F are also not differentiable with respect to w h . Nevertheless, the absolute value is convex and we can use some concepts of the subdifferential calculus. Let us introduce the multi-valued sign function:

sgn(x) =    {1} when x > 0 [-1, 1] when x = 0 {-1} when x < 0
Then, the subdifferential of the absolute value function is sgn(x) and for all δw h , w h , u h , v h ∈ X h , we define a generalization of the partial derivative as A multi-valued Jacobean F ′ is then defined:

∂s h ∂w h (w h ; u h , v h ).(δw h ) = 1 2 S∈S (i) h S sgn({ {w h } }.n) ({ {δw h } }.n) ([[u h ]].[[v h ]]) ds
⟨F ′ u (k-1) h , p (k-1) h .(δu h , δp h ), (v h , q h )⟩ = Re    t h (δu h ; u h , v h ) + t h (u h ; δu h , v h ) + ∂s h ∂w h (u h ; u h , v h ).(δu h ) + s h (u h ; δu h , v h ) 0    +   a h (δu h , v h ) + b h (v h , δp h ) b h (δu h , q h ) -c h (δp h , q h )  
We are able to extend the Newton method to the F function that allows a multi-valued subdifferential F ′ . During iterations, we can choose any of the available directions in the subdifferential. One the possibilities is then to replace the multi-valued sign function by a single-value one: The program navier_stokes_cavity_newton_upw_dg.cc is obtained by replacing in navier_stokes_taylor_newton_dg.cc the string navier_stokes_dg by navier_stokes_upw_dg (two occurrences: in the includes and then in the definition of F). Also replace the include taylor.h by cavity_dg.h that defines the boundary conditions. The compilation and run are similar.

sgn(x) = 1 when x ⩾ 0 -1 when x < 0
make navier_stokes_cavity_newton_upw_dg streamf_cavity mkgeo_grid -t 80 > square.geo ./navier_stokes_cavity_newton_upw_dg square P1d 500 1e-15 100 > square-500.field field square-500.field -proj -field | ./streamf_cavity | \ field -bw -n-iso 30 -n-iso-negative 20 -

It could take about one minute of CPU, depending on your computer. Computations for higher Reynolds numbers are performed by continuation. Starting from a previous computation at Re = 500, we compute it at Re = 1000 as:

./navier_stokes_cavity_newton_upw_dg square P1d 1000 1e-15 100 square-500.field \ > square-1000.field field square-1000.field -proj -field | ./streamf_cavity | \ field -bw -n-iso 30 -n-iso-negative 20 -Then, for Re = 1500:

./navier_stokes_cavity_newton_upw_dg square P1d 1500 1e-15 100 square-1000.field \ > square-1500.field field square-1500.field -proj -field | ./streamf_cavity | \ field -bw -n-iso 30 -n-iso-negative 20 -By this way, computations of solutions can be performed until Re = 25 000 without problems. Note that, from Re ≈ 10 000, these solution are no more stable with respect to time, but are valid solution of the stationary Navier-Stokes problem and can be interpreted as timed averaged solutions. See also at the end of section 2.5 page 84 for a discussion about the loss of stationary of the solution. In conclusion, the discontinuous Galerkin method is much more robust and accurate than the characteristic method of section 2.5 when looking at stationary solutions of the Navier-Stokes equations. Moreover, this approach could also be easily exended to the non-stationary case by adding a time derivative term and a BDF time approximation, associated to a fully implicit approach.

Re

The augmented Lagrangian algorithm

Principe of the algorithm

The problem writes as a minimization one:

min u∈H 1 (Ω) J(u)
where

J(u) = C f 1 + n ∂Ω |u| 1+n ds + S ∂Ω |u| ds + 1 2 Ω |∇u| 2 dx - Ω f u dx
This problem is solved by using an augmented Lagrangian algorithm. The auxiliary variable γ = u |∂Ω is introduced together with the Lagrangian multiplier λ associated to the constraints u |∂Ω -γ = 0. For all r > 0, let:

L((u, γ); λ) = C f 1 + n ∂Ω |γ| 1+n ds + S ∂Ω |γ| ds + 1 2 Ω |∇u| 2 dx - Ω f u dx + ∂Ω λ (u -γ) ds + r 2 ∂Ω |u -γ| 2 ds
An Uzawa-like minimization algorithm writes:

• k = 0: let λ (0) and γ (0) arbitrarily chosen.

• k ⩾ 0: let λ (k) and γ (k) being known.

u (k+1) := arg min v∈H 1 (Ω) L((v, γ (k) ); λ (k) ) γ (k+1) := arg min δ∈L ∞ (∂Ω) L((u (k+1) , δ); λ (k) ) λ (k+1) := λ (k) + ρ u (k+1) -γ (k+1) on ∂Ω
The descent step ρ is chosen as ρ = r for sufficiently large r. The Lagrangian L is quadratic in u and thus the computation of u (k+1) reduces to a linear problem. The non-linearity is treated when computing γ (k+1) . This operation is performed point-by-point on ∂Ω by minimizing: k+1) is given. This problem is convex and its solution is unique. The solution has the form:

γ := arg min δ∈R C f |δ| 1+n 1 + n + r|δ| 2 2 + S|δ| -ξ δ where ξ = λ (k) + r u (
γ = P n,r (ξ) def = 0 when |ξ| ⩽ S ϕ n,r (|ξ| -S) sgn(ξ) otherwise (5.2)
where ϕ n,r (x) = f -1 n,r (x) and f n,r is defined for all y > 0 by: and then compute explicitely γ (k+1) and λ (k+1) :

f n,r (y) = C f y n + r y (5.
γ (k+1) := P n,r λ (k) + r u (k+1) on ∂Ω λ (k+1) := λ (k) + r u (k+1) -γ (k+1) on ∂Ω
This algorithm reduces the nonlinear problem to a sequence of linear and completely standard Poisson problems with a Robin boundary condition and some explicit computations. At convergence, λ = -∂u ∂n and γ = u on ∂Ω.

Note that the solution satisfies the following variational formulation:

Ω ∇u .∇v dx + ∂Ω v λ ds = Ω f v dx, ∀v ∈ H 1 (Ω) ∂Ω u γ ds - ∂Ω P n,0 (λ) γ ds = 0, ∀γ ∈ L ∞ (∂Ω)
This formulation is the base of the computation of the residual test used for the stopping criteria. As analysed by [START_REF] Roquet | Stick-slip transition capturing by using an adaptive finite element method[END_REF], when S ⩽ 0.382, the fluid slips at the wall, when 0.382 < S < 0.674, the fluid partially sticks and when S ⩾ 0.674 the fluid completely sticks.

Remark that the velocity is not zero along the boundary: there is a stick-slip transition point.

The velocity along along the 0x 0 axis and the top boundary are available as (see Fig. u(x 0 , 1) field square.field -normal 0 1 -origin 0 0 -cut -gnuplot field square.field -domain top -elevation -gnuplot

x 0 n = 1.5 n = 1.0 n = 0.5 0 0.6 1 0 0.5 1 λ(x 0 , 1) = - ∂u ∂x 1 (x 0 , 1) x 0 n = 1.5 n = 1.0 n = 0.5
The corresponding Lagrange multiplier λ on the boundary can also be viewed as:

field square.field -mark lambda -elevation

The file 'yield_slip_residue.cc' implement the computation of the full set of residual terms of the initial problem. This file it is not listed here but is available in the Rheolef example directory. The computation of residual terms is obtained by: make yield_slip_residue ./yield_slip_residue < square.field

Observe that the residual terms of the initial problem are of about 10 -10 , as required by the stopping criterion. Fig. 5.3 plots the max of the relative error for the λ h variable: this quantity is used as stopping criterion. Observe that it behaves asymptotically as 1/k for larges meshes, with a final acceleration to machine precision. Note that these convergence properties could be dramatically improved by using a Newton method, as shown in the next section.

Newton algorithm

Reformulation of the problem

The idea of this algorithm first proposed by [START_REF] Alart | Méthode de Newton généralisée en mécanique du contact[END_REF] in the context of contact and friction problems. At convergence, the augmented Lagrangian method solve the following problem: (P ) r : find u, defined in Ω, and λ, defined on ∂Ω, such that

-∆u = f in Ω ∂u ∂n + λ = 0 on ∂Ω u -P n,r (λ + r u) = 0 on ∂Ω
The solution is independent upon r ∈ R and this problem is equivalent to the original one. In order to diagonalize the non-linearity in P n,r (.), let us introduce β = λ + r u. The problem becomes: (P ) r : find u, defined in Ω, and β, defined on ∂Ω, such that

-∆u = f in Ω ∂u ∂n -r u + β = 0 on ∂Ω u -P n,r (β) = 0 on ∂Ω

Variational formulation

Consider the following forms:

m(u, v) = Ω u v dx, , ∀u v ∈ L 2 (Ω) a(u, v) = Ω ∇u .∇v dx -r ∂Ω u v ds, ∀u, v ∈ H 1 (Ω) b(v, γ) = Ω v γ ds, ∀γ ∈ L 2 (∂Ω), ∀v ∈ H 1 (Ω) c(β, γ) = Ω P n,r (β) γ ds, ∀β ∈ L ∞ (∂Ω), ∀γ ∈ L 2 (∂Ω) Remark that, since Ω ⊂ R 2 , from the Sobolev embedding theorem, if u ∈ H 1 (Ω) then u |∂Ω ∈ L ∞ (∂Ω).
Then, all integrals have sense. The variational formulation writes:

(F V ): find u ∈ H 1 (Ω) and β ∈ L ∞ (∂Ω) such that a(u, v) + b(v, β) = m(f, v), ∀v ∈ H 1 (Ω) b(u, γ) -c(β, γ) = 0, ∀γ ∈ L 2 (∂Ω)
Let M , A and B the operators associated to forms m, a, b and c. The problem writes also as:

A B * B -C u β = M f 0
where B * denotes the formal adjoint of B. The bilinear form a is symmetric positive definite when r ∈]0, C f [. Then A is non-singular and let A -1 denotes its inverse. The unknown u can be eliminated: u = A -1 (M f -B T β) and the problem reduces to:

find β ∈ L ∞ (∂Ω) such that F (β) = 0 where F (β) = C(β) + BA -1 B * β -BA -1 M f
This problem is a good candidate for a Newton method:

F ′ (β)δβ = C ′ (β)δβ + BA -1 B * δβ
where C ′ (β) is associated to the bilinear form:

c 1 (β; γ, δ) = Ω P ′ n,r (β) γ δ ds, ∀β ∈ L ∞ (∂Ω), ∀γ, δ ∈ L 2 (∂Ω)
where, for all ξ ∈ R:

P ′ n,r (ξ) = 0 when |ξ| ⩽ S ϕ ′ n,r (|ξ| -S) otherwise (5.4)
Recall that, for all ζ > 0, ϕ n,r (ζ) = f -1 n,r (ζ) where f n,r (y) = C f y n + r y, for all y > 0. Then

ϕ ′ n,r (ζ) = 1 f ′ n,r (f -1 n,r (ζ)) = 1 f ′ n,r (ϕ n,r (ζ)) = 1 r + n C f {ϕ n,r (ζ)} -1+n
(5.5)

When n = 1 we simply have:

ϕ ′ 1,r (ζ) = 1 C f + r
. When r = 0, for any n > 0 we have

ϕ ′ n,0 (ζ) = ζ -1+1/n n C 1/n f .
File 5.6: d_projection_dx.h File 5.7: yield_slip_damped_newton.cc u depends only of r, equation (5.1a) becomes:

- 1 r ∂ r (r∂ r u) = 1
and then, from the symmetry, u(r) = c -r 2 /4, where c is a constant to determine from the boundary condition. On the boundary r = 1 we have ∂ n u = ∂ r u = -1/2. When S ⩾ 1/2 the fluid sticks at the wall and when S > 1/2 we have from (5.1b):

-C f u n -S = 1 2
From the previous expression u(r), taken for r = 1 we obtain the constant c and then:

u(r) = 1 -r 2 4 + max(0, 1/2 -S) C f 1/n , 0 ⩽ r ⩽ 1
The error computation is implemented in the files 'yield_slip_error.cc' and 'yield_slip_circle.h': it is not listed here but is available in the Rheolef example directory.

The error can be computed (see Fig. 5.5):

10 -8 10 -6

10 -4 10 -2 It appears that the discrete formulation develops optimal convergence properties versus mesh refinement for k ⩾ 1 in H 1 , L 2 and L ∞ norms.

10 -2 10 -1 1 ∥u -u h ∥ 0,2,Ω 2 = k + 1 3 4 h k = 1 k = 2 k = 3 10 -8 10 -6 10 -4 10 -2 10 -2 10 -1 1 ∥u -u h ∥ 0,∞,Ω 2 = k + 1 3 4 h k = k = k = 10 -6 10 -4 10 -2 1 10 -2 10 -1 1 |∇(u -u h )| 0,2,Ω 1 = k 2 3 h k = 1 k = 2 k = 3 10 -8 10 -6 10 -4 10 -2 10 -2 10 -1 1 ∥λ -λ h ∥ 0,2,∂Ω 2 = k + 1 3 4 h k = k = k =

Viscoplastic fluids

Problem statement

Viscoplastic fluids develops an yield stress behavior (see e.g. Saramito, 2016b, Saramito and[START_REF] Saramito | Progress in numerical simulation of yield stress fluid flows[END_REF]. [START_REF] Mosolov | Variational methods in the theory of the fluidity of a viscousplastic medium[END_REF][START_REF] Mosolov | On stagnant flow regions of a viscous-plastic medium in pipes[END_REF][START_REF] Batchelor | An introduction to fluid dynamics[END_REF] first investigated the flow of a viscoplastic in a pipe with an arbitrarily cross section. Its numerical investigation by augmented Lagrangian methods was first performed by [START_REF] Saramito | An adaptive finite element method for viscoplastic fluid flows in pipes[END_REF], [START_REF] Roquet | An adaptive finite element method for viscoplastic flows in a square pipe with stick-slip at the wall[END_REF]. The Mosolov problem [START_REF] Saramito | An adaptive finite element method for viscoplastic fluid flows in pipes[END_REF] writes: (P ): find σ and u, defined in Ω, such that

div σ = -f in Ω (5.6a) u = 0 on ∂Ω (5.6b) |σ| ⩽ Bi when ∇u = 0 σ = |∇u| -1+n ∇u + Bi ∇u |∇u| otherwise    in Ω (5.6c)
where Bi ⩾ 0 is the Bingham number and n > 0 is a power-law index. The computational domain Ω represents the cross-section of the pipe. In the bidimensional case d = 2 and when f is constant, this problem describes the stationary flow of an Herschel-Bulkley fluid in a general pipe section Ω.

Let Ox 2 be the axis of the pipe and Ox 0 x 1 the plane of the section Ω. The vector-valued field σ represents the shear stress components (σ 0,1 , σ 0,2 ) while u is the axial component of velocity along Ox 3 . When Bi = 0, the problem reduces to the nonlinear p-Laplacian problem. When n = 1 the fluid is a Bingham fluid. When n = 1 and Bi = 0, the problem reduces to the linear Poisson one with σ = ∇u.

The augmented Lagrangian algorithm

This problem writes as a minimization of an energy:

u = arg min v∈W 1,p 0 (Ω) J(v) (5.7a)
where

J(v) = 1 1 + n Ω |∇v| 1+n dx + Bi Ω |∇v| dx - Ω f v dx (5.7b)
This problem is solved by using an augmented Lagrangian algorithm. The auxiliary variable γ = ∇u is introduced together with the Lagrangian multiplier σ associated to the constraint ∇u -γ = 0. For all r > 0, let:

L((v, γ); σ) = 1 1 + n Ω |γ| 1+n dx+Bi Ω |γ| dx- Ω f v dx+ Ω σ.(∇u-γ) dx+ r 2 Ω |∇u-γ| 2 dx
An Uzawa-like minimization algorithm writes:

• k = 0: let λ (0) and γ (0) arbitrarily chosen.

• k ⩾ 0: let λ (k) and γ (k) being known.

u (k+1) := arg min v∈W 1,p (Ω) L((v, γ (k) ); σ (k) ) γ (k+1) := arg min δ∈L 2 (Ω) d L((u (k+1) , δ); σ (k) ) σ (k+1) := σ (k) + ρ ∇u (k+1) -γ (k+1) in Ω
The descent step ρ is chosen as ρ = r for sufficiently large r. The Lagrangian L is quadratic in u and thus the computation of u (k+1) reduces to a linear problem. The non-linearity is treated when computing γ (k+1) . This operation is performed point-by-point in Ω by minimizing:

γ := arg min δ∈R d |δ| 1+n 1 + n + r|δ| 2 2 + Bi|δ| -ξ.δ
where ξ = σ (k) + r ∇u (k+1) is given. This problem is convex and its solution is unique. The solution has the form:

γ = P n,r (ξ) def =    0 when |ξ| ⩽ S ϕ n,r (|ξ| -S) ξ |ξ| otherwise (5.8)
where ϕ n,r (x) = f -1 n,r (x) has been introduced in (5.2) page 204 in the context of the yield slip problem together with the scalar projector. Finally, the Uzawa-like minimization algorithm [START_REF] Saramito | An adaptive finite element method for viscoplastic fluid flows in pipes[END_REF] writes:

• k = 0: let σ (0) and γ (0) arbitrarily chosen.

• k ⩾ 0: let σ (k) and γ (k) being known, find u (k+1) such that -r∆u (k+1) = f + div σ (k) -rγ (k) in Ω u (k+1) = 0 on ∂Ω and then compute explicitly γ (k+1) and σ (k+1) : γ (k+1) := P n,r σ (k) + r∇u (k+1) (5.9)

σ (k+1) := σ (k) + r ∇u (k+1) -γ (k+1)
Here r > 0 is a numerical parameter. This algorithm reduces the nonlinear problem to a sequence of linear and completely standard Poisson problems and some explicit computations. For convenience, this algorithm is implemented as the solve function member of a class: For convenience, the order of the update of the three variables u, γ and σ has been rotated: by this way, the algorithm starts with initial values for u and σ. instead of γ and σ. Observe that the projection step (5.9) is implemented by using the interpolate operator: this projection step interprets as point-wise at Lagrange nodes instead as a numerical resolution of the element-wise minimization problem. Note that, for the lowest order k = 1, these two approaches are strictly equivalent, while, when k ⩾ 2, the numerical solution obtained by this algorithm is no more solution of the discrete version of the saddle-point problem for the Lagrangian L. Nevertheless, the numerical solution is founded to converge to the exact solution of the initial problem (5.6a)-(5.6c): this will be checked here in a forthcoming section, dedicated to the error analysis. Observe also that the stopping criterion for breaking the loop bases on the max of the relative error for the σ h variable. For this algorithm, this stopping criterion guaranties that all residual terms of the initial problem are also converging to zero, as it will be checked here. Moreover, this stopping criterion is very fast to compute while the full set of residual terms of the initial problem would take more computational time inside the loop.

The class declaration contains all model parameters, loop controls, form and space variables, together with some pre-and post-treatments: The main program read parameters from the command line and performs an optional mesh adaptation loop. This implementation supports any n > 0, any continuous piecewise polynomial P k , k ⩾ 1 and also isoparametric approximations for curved boundaries.

Running the program

Compile the program as usual:

make mosolov_augmented_lagrangian mkgeo_grid -a -1 -b 1 -c -1 -d 1 -t 10 > square.geo ./mosolov_augmented_lagrangian square.geo P1 0.4 1 field -mark u square.field -elevation Observe on Fig. 5.6.left the central region where the velocity is constant. A cut of the velocity field along the first bisector is obtained by: field -mark u square.field -cut -origin 0 0 -normal 1 1 -gnuplot Observe on Fig. 5.6.right the small regions with zero velocity, near the outer corner of the square pipe section. This region is really small but exists This question will be revisited in the next section dedicated to auto-adaptive mesh refinement. The file 'mosolov_residue.cc' implement the computation of the full set of residual terms of the initial problem. This file it is not listed here but is available in the Rheolef example directory. The computation of residual terms is obtained by: make mosolov_residue zcat square.field.gz | ./mosolov_residue Observe that the residual terms of problem (5.6a)-(5.6c) are of about 10 -10 , as required by the stopping criterion. Fig. 5.7 plots the max of the relative error for the σ h variable: this quantity is used as stopping criterion. Observe that it behaves asymptotically as 1/k for large iteration number k. Note that these convergence properties could be dramatically improved by using a Newton method, as shown by Saramito [2016a].

Finally, computation can be performed for any n > 0, any polynomial order k ⩾ 1 and in a distributed environment for enhancing performances on larger meshes:

mkgeo_grid -a -1 -b 1 -c -1 -d 1 -t 40 > square-40.geo mpirun -np 8 ./mosolov_augmented_lagrangian square-40.geo P2 0.4 0.5 field -mark u square-40.field -elevation

The computation could take about ten minutes. The mpirun -np 8 prefix is optional and you should omit it if you are running a sequential installation of Rheolef.

Mesh adaptation

An important improvement can be obtained by using mesh adaptation, as shown in [START_REF] Saramito | An adaptive finite element method for viscoplastic fluid flows in pipes[END_REF][START_REF] Roquet | An adaptive finite element method for Bingham fluid flows around a cylinder[END_REF], 2008]: with a well chosen criterion, rigid regions, where the velocity is constant, can be accurately determined with reasonable mesh sizes. This is especially true for obtaining an accurate determination of the shape of the small regions with zero velocity in the outer corner of the pipe section. In order to reduce the computational time, we can reduce the pipe section flow to only a sector, thanks to symmetries (see Fig. The unyielded zones, associated to negative values, appear in cold colors. Conversely, the yielded ones are represented by warm colors. A combined representation of the solution can be obtained by the following command: bash mkview_mosolov sector-010.field.gz

The shell script mkview_mosolov invokes mosolov_yield_surface and then directly builds the view shown on Fig. 5.8 in the paraview graphic render. Please, click to deselect the show box option for completing the view. A cut of the velocity field along the first bisector is obtained by: that Γ h could converge to Γ with mesh refinement: our aim is to check this conjecture. Let us introduce the area between Γ h and Γ as a L 1 measure of the distance between them: 10 -4

dist(Γ, Γ h ) = Ω δ (|σ h | -Bi, |σ| -Bi) dx
10 -2 1 10 -2 10 -1 ∥u -u h ∥ 1,2,Ω 1 = min(k, 1/n) 2 2 h k = 1 k = 2 k = 3 10 -6 10 -4 10 -2 1 10 -2 10 -1 ∥u -u h ∥ 0,∞,Ω 2 = min(k + 1, 1/n) 2 h k = 1 k = 2 k = 3 10 -3 10 -2 10 -1 10 -2 10 -1 ∥σ -σ h ∥ 0,2,Ω 1 1 h k = 1 k = 2 k = 3 5 × 10 -2 10 -1 5 × 10 -1 10 -2 10 -1 ∥σ -σ h ∥ 0,∞,Ω 3/4 h k = 1 k = 2 k = 3
dist(Γ, Γ h ) 1 h k = 1 k = 2 k = 2 h = 1/10 h = 1/20 h = 1/40 exact

Viscoelastic fluids

A tensor transport equation

The aim of this chapter is to introduce to the numerical resolution of equations involving tensor derivatives by using discontinuous approximations. See Saramito [2013b, chap. 4] for an introduction to tensor derivatives and in section 4.1.1 of the present book, page 147, for discontinuous Galerkin methods.

The tensor derivative of a symmetric tensor σ is defined by:

D a σ Dt = ∂σ ∂t + (u.∇)σ + σg a (u) + g T a (u)σ, (5.10)
where u is a given velocity field,

g a (u) = (1 -a) ∇u -(1 + a) ∇u T /2 (5.11)
is a generalized velocity grandient and a ∈ [-1, 1] is the parameter of the tensorderivative. Problems involving tensor derivatives appear in viscoelasticity (polymer solution and polymer melt, see e.g. Saramito, 2016b), in fluid-particle suspension modeling (see e.g. [START_REF] Ozenda | A new rate-independent tensorial model for suspensions of non-colloidal rigid particles in newtonian fluids[END_REF], in turbulence modeling (R ij -ϵ models) or in liquid crystals modeling. Let Ω ⊂ R d be a bounded open domain.

The time-dependent tensor transport problem writes:

(P ): find σ, defined in ]0, T [×Ω, such that

D a σ Dt + νσ = χ in ]0, T [×Ω σ = σ Γ on ]0, T [×∂Ω - σ(0) = σ 0 in Ω
where σ is the tensor valued unknown and ν > 0 is a constant that represents the inverse of the Weissenberg number. Also T > 0 is a given final time, the data χ, σ Γ and σ 0 are known and ∂Ω - denotes the upstream boundary (see section 4.1.1, page 147).

The steady version of the tensor transport problem writes:

(S): find σ, defined in Ω, such that

u.∇)σ + σg a (u + g T a (u)σ + νσ = χ in Ω σ = σ Γ on ∂Ω -
A sufficient condition this problem to be well posed is [START_REF] Saramito | Numerical simulation of viscoelastic fluid flows using incompressible finite element method and a θ-method[END_REF][Saramito, , 2013b]]:

u ∈ W 1,∞ (Ω) d and 2ν -∥div u∥ 0,∞,Ω -2a∥D(u)∥ 0,∞,Ω > 0
Note that this condition is always satisfied when div u = 0 and a = 0. We introduce the space:

X = {τ ∈ L 2 (Ω) d×d s ; (u.∇)τ ∈ L 2 (Ω) d×d s } and, for all σ, τ ∈ X a(σ, τ ) = Ω (u.∇)σ + σg a (u) + g T a (u)σ + ν σ : τ dx + ∂Ω max (0, -u.n) σ : τ ds l(τ ) = Ω χ : τ dx + ∂Ω max (0, -u.n) σ Γ : τ ds
Then, the variational formulation of the steady problem writes:

(F V ): find σ ∈ X such that a(σ, τ ) = l(τ ), ∀τ ∈ X
Note that the term max(0, -u.n) = (|u.n| -u.n)/2 is positive and vanishes everywhere except on ∂Ω -. Thus, the boundary condition ϕ = ϕ Γ is weakly imposed on ∂Ω -via the integrals on the boundary. We aim at adapting the discontinuous Galerkin method to this problem. The discontinuous finite element space is defined by:

X h = {τ h ∈ L 2 (Ω) d×d s ; τ h|K ∈ P k , ∀K ∈ T h }
where k ⩾ 0 is the polynomial degree. Note that X h ̸ ⊂ X and that the ∇τ h term has no more sense for discontinuous functions τ h ∈ X h . We introduce the broken gradient ∇ h as a convenient notation:

(∇ h τ h ) |K = ∇(τ h|K ), ∀K ∈ T h Thus Ω ((u.∇ h )σ h ) : τ h dx = K∈T h K ((u.∇)σ h ) : τ h dx, ∀σ h , τ h ∈ X h
This leads to a discrete version a h of the bilinear form a, defined for all σ h , τ h ∈ X h by:

a h (σ h , τ h ) = t h (u; σ h , τ h ) + ν Ω σ h : τ h dx t h (u; σ h , τ h ) = Ω (u.∇ h )σ h + σg a (u) + g T a (u)σ : τ h dx + ∂Ω max (0, -u.n) σ h : τ h ds + S∈S (i) h S -u.n [[σ h ]] : { {τ h } } + α 2 |u.n| [[σ h ]] : [[τ h ]] ds (5.12) (F V ) h : find σ h ∈ X h such that a h (σ h , τ h ) = l(τ h ), ∀τ h ∈ X h
The following code implement this problem in the Rheolef environment.

Running the program

Let d = 2 and Ω =] -1/2, 1/2[ 2 . We consider the rotating field u = (-x 2 , x 1 ). A particular solution of the time-dependent problem with zero right-hand side is given by:

σ(x, t) = 1 2 exp -νt - (x 1 -x 1,c (t)) 2 + (x 2 -x 2,c (t)) 2 r 2 0 × 1 + cos(2t) sin(2t) sin(2t) 1 -cos(2t)
where x 1,c (t) = x1,c cos(t) -x2,c sin(t) and x 2,c (t) = x1,c sin(t) + x2,c cos(t) with r 0 > 0 and (x 1,c , x2,c ) ∈ R 2 . The initial condition is chosen as σ 0 (x) = σ(0, x). This exact solution is implemented in the file 'transport_tensor_exact.icc'. This file it is not listed here but is available in the Rheolef example directory. For the steady problem, the right-hand side could be chosen as χ = -∂σ ∂t and then t = t 0 is fixed. The numerical tests correspond to ν = 3, r 0 = 1/10, (x 1,c , x2,c ) = (1/4, 0) and a fixed time t 0 = π/8. make transport_tensor_dg mkgeo_grid -t 80 -a -0.5 -b 0.5 -c -0.5 -d 0.5 > square2.geo ./transport_tensor_dg square2 P1d > square2.field field square2.field -comp 00 -elevation field square2.field -comp 01 -elevation

The computation could also be performed with any Pkd, with k ⩾ 0.

Error analysis

The file 'transport_tensor_error_dg.cc' implement the computation of the error between the approximate solution σ h and the exact one σ. This file it is not listed here but is available in the 10 -8 10 -6

10 -4 Rheolef example directory. The computation of the error is obtained by: make transport_tensor_error_dg ./transport_tensor_error_dg < square2.field

10 -2 1 10 -3 10 -2 10 -1 ∥σ h -σ∥ 0,2,Ω 1 = k + 1 2 3 4 h k = 0 k = 1 k = 2 k = 3
The error is plotted on Fig. 5.12 for various mesh size h and polynomial order k: observe the optimality of the convergence properties. For k = 4 and on the finest mesh, the error saturates at about 10 -8 , due to finite machine precision effects. In the next chapter, transport tensor approximation are applied to viscoelastic fluid flow computations.

The Oldroyd model

We consider the following viscoelastic fluid flow problem (see e.g. Saramito, 2016b, chap. 4):

(P ): find τ , u and p defined in ]0, T [×Ω such that

W e D a τ Dt + τ -2αD(u) = 0 in ]0, T [×Ω (5.13a) Re ∂u ∂t + u.∇u -div ( τ + 2(1 -α)D(u) -p.I) = 0 in ]0, T [×Ω (5.13b) -div u = 0 in ]0, T [×Ω (5.13c) τ = τ Γ on ]0, T [×∂Ω -(5.13d) u = u Γ on ]0, T [×∂Ω (5.13e) τ (0) = τ 0 and u(0) = u 0 in Ω (5.13f)
where τ 0 , u 0 , τ Γ and u Γ are given. The first equation corresponds to a generalized Oldroyd model [START_REF] Oldroyd | On the formulation of rheological equations of states[END_REF]: when a = -1 we obtain the Oldroyd-A model, when a = 1, the Oldroyd-B model, and when a ∈ ] -1, 1[ a generalization of these two models. The dimensionless number W e ⩾ 0 is the Weissenberg number: this is the main parameter for this problem. The dimensionless Reynolds number Re ⩾ 0 is often chosen small: as such fluids are usually slow, the u.∇u inertia term is also neglected here for simplicity. The parameter α ∈ [0, 1] represent a retardation. When α = 1 we obtain the Maxwell model, that is a reduced version of the Oldroyd one. The total Cauchy stress tensor is expressed by:

σ tot = -p I + 2(1 -α)D(u) + τ (5.14)

The θ-scheme algorithm

The θ-scheme is considered for the time discretization [START_REF] Saramito | Numerical simulation of viscoelastic fluid flows using incompressible finite element method and a θ-method[END_REF] (see also Saramito, 2016b, chap. 4): this leads to a semi-implicit splitting algorithm that defines a sequence (τ (n) , u (n) , p n ) n⩾0 as

• n = 0: set (τ (0) , u (0) ) = (τ 0 , u 0 ) and p 0 arbitrarily chosen.

• n ⩾ 0: let (τ (n) , u (n) ) being known, then (τ (n+1) , u (n+1) , p (n+1 ) is defined in three sub-steps.

* sub-step 1: compute explicitly:

γ = u (n) .∇τ (n) + τ (n) M a u (n) + M T a u (n) τ (n) f = λu (n) + div c 1 τ (n) + c 2 γ
where

c 1 = W e W e + θ∆t and c 2 = - W eθ∆t W e + θ∆t
Then determine (u (n+θ) , p (n+θ) ) such that λu (n+θ) -div 2ηD u (n+θ) + ∇p (n+θ) = f in Ω (5.15a)

-div u (n+θ) = 0 in Ω (5.15b) u = u Γ ((n + θ)∆t) on ∂Ω (5.15c) and finaly, compute explictely

τ (n+θ) = c 1 τ (n) + c 2 γ + 2c 3 D u (n+θ) (5.
u (n+1-θ) = 1 -θ θ u (n+θ) - 1 -2θ θ u (n) ξ = c 4 τ n+θ + 2c 5 D u (n+θ)
and then find τ (n+1-θ) such that

u (n+1-θ) .∇τ (n+1-θ) + τ (n+1-θ) M a u (n+1-θ) + M T a u (n+1-θ) τ (n+1-θ)
+ ντ (n+1-θ) = ξ in Ω (5.16a)

τ (n+1-θ) = τ Γ ((n + 1 -θ)∆t) on ∂Ω - (5.16b) where ν = 1 (1 -2θ)∆t , c 4 = 1 (1 -2θ)∆t - 1 W e and c 5 = α W e
* sub-step 3 is obtained by replacing n and n + θ by n + 1 -θ and n + 1, respectively.

Thus, sub-step 1 and 2 reduces to two similar generalized Stokes problems while sub-step 3 involves a stress transport problem. Here ∆t > 0 and θ ∈]0, 1/2[ are numerical parameters. A good choice is [START_REF] Saramito | Operator splitting in viscoelasticity[END_REF]. This algorithm was first proposed by [START_REF] Saramito | Simulation numérique d'écoulements de fluides viscoélastiques par éléments finis incompressibles et une méthode de directions alternées[END_REF] and extended [Saramito, 1995] to Phan-Thien and Tanner viscoelastic models. See also [START_REF] Singh | Finite-element simulation of the start-up problem for a viscoelastic fluid in an eccentric rotating cylinder geometry using a third-order upwind scheme[END_REF] for another similar approach in the context of FENE viscoelastic models. [START_REF] Scurtu | Stability analysis and numerical simulation of non-Newtonian fluids of Oldroyd kind[END_REF] presented some benchmarks of this algorithm while [START_REF] Chrispell | A fractional step θ-method approximation of time-dependent viscoelastic fluid flow[END_REF] presented a numerical analysis of its convergence properties. The main advantage of this time-depend algorithm is its flexibility: while most time-dependent splitting algorithms for viscoelastic are limited to α ⩽ 1/2 (see e.g. [START_REF] Pan | On the simulation of a time-dependent cavity flow of an Oldroyd-B fluid[END_REF], here the full range α ∈]0, 1] is available. Let us introduce the finite element spaces:

θ = 1-1/ √ 2 [
T h = {τ h ∈ (L 2 (Ω)) d×d s ; τ h|K ∈ (P 1 ) d×d s , ∀K ∈ T h } X h = {v h ∈ (H 1 (Ω)) d ; τ h|K ∈ (P 2 ) d , ∀K ∈ T h } Q h = {q h ∈ L 2 (Ω) ; q h|K ∈ P 1 , ∀K ∈ T h }
Note the discontinuous approximation of pressure: it presents a major advantage, as div(X h ) ⊂ Q h , it leads to an exact divergence-free approximation of the velocity: for any field v h ∈ X h satisfying Ω q h div(v h ) dx = 0 for all q h ∈ Q h , we have div v h = 0 point-wise, everywhere in Ω. The pair (X h , Q h ) is known as the [START_REF] Scott | Norm estimates for a maximal right inverse of the divergence operator in spaces of piecewise polynomials[END_REF] lowest-order finite element approximation. This is a major advantage when dealing with a transport equation. The only drawback is that the pair (X h , Q h ) does not satisfy the inf-sup condition for an arbitrary mesh. There exists a solution to this however: [START_REF] Arnold | Quadratic velocity/linear pressure Stokes elements[END_REF] proposed a macro element technique applied to the mesh that allows satisfying the inf-sup condition: for any triangular finite element mesh, it is sufficient to split each triangle in three elements from its barycenter (see also [START_REF] Saramito | On a modified non-singular log-conformation formulation for Johnson-Segalman viscoelastic fluids[END_REF]. Note that the macro element technique extends to quadrilateral meshes [START_REF] Arnold | Quadratic velocity/linear pressure Stokes elements[END_REF] and to the three-dimensional case [START_REF] Zhang | A new family of stable mixed finite elements for the 3D Stokes equations[END_REF]. By this way, the approximate velocity field satisfies exactly the incompressibility constraint: this is an essential property for the operator splitting algorithm to behave correctly, combining stress transport equation with a divergence-free velocity approximation. The tensor transport term is discretized as in the previous chapter, by using the t h trilinear form introduced in (5.12) page 231. The bilinear forms b, c, d are defined by:

b(σ h , v h ) = Ω σ h : D(v h ) dx c(u h , v h ) = Ω D(u h ) : D(v h ) dx d(u h , q h ) = Ω div(u h ) q h dx
Let T , B, C, D and M be the discrete operators (i.e. the matrix) associated to the forms t h , b, c, d and the L 2 scalar product in T h . Assume that a stationnary state is reached for the discretized algorithm. Then, (5.15a)-(5.15d) writes

W e T τ h + M τ h -2αB T u h = 0 B c 1 τ h + M -1 T τ h + 2ηCu h + D T p h = 0 Du h = 0
Note that (5.16a)-(5.16b) reduces also to the first equation of the previous system. Expanding the coefficients, combining the two previous equations, and using C = BM -1 B T , we obtain the system characterizing the stationary solution of the discrete version of the algorithm:

W e T τ h + M τ h -2αB T u h = 0 Bτ h + 2(1 -α)Cu h + D T p h = 0 Du h = 0
Note that this is exactly the discretized version of the stationary equation1 . In order to check that the solution reaches a stationary state, the residual terms of this stationary equations are computed at each iteration, together with the relative error between two iterates. Float theta ,lambda ,eta ,nu ,c1 ,c2 ,c3 ,c4 ,c5 ; problem_mixed stokes ; };

# include " old royd_ theta_ schem e1 . h " # include " old royd_ theta_ schem e2 . h " # include " old royd_ theta_ schem e3 . h "

x 0 -L u x 1 1 (0, 0) L d Γ u Γ d Γ w Γ s c Figure 5
.13: The Oldroyd problem in the abrupt contraction: shematic view of the flow domain.

Poiseuille flow for a plane pipe with half width c:

u 0 (x 1 ) = ū 1 - x 1 c 2 γ(x 1 ) = u ′ 0 (x 1 ) = - 2ū x 1 c 2 τ 00 (x 1 ) = 2αW e γ2 (x 1 ) τ 01 (x 1 ) = τ 10 (x 1 ) = α γ(x 1 ) τ 11 (x 1 ) = 0
where ū denotes the maximal velocity of the Poiseuille flow. Without loss of generality, thanks to a dimensional analysis, it can be adjused with the contraction ratio c for obtaining a flow rate equal to one:

[New] Stress diffusion

The tensor diffusion variant of a viscoelastic model introduces an additional second order diffusive term in the differential equation for σ, see section 5.3.1. It develops nice theoretical properties, see e.g. [START_REF] Lukáčová-Medvidová | Global existence result for the generalized Peterlin viscoelastic model[END_REF], [START_REF] Málek | Thermodynamics of viscoelastic rate-type fluids with stress diffusion[END_REF]. Let us consider the following variant of the tensor transport problem previously introduced in section 5.3.1, page 230, by adding a diffusion term:

(P ): find σ, defined in ]0, T [×Ω, such that

D a σ Dt + νσ -ε∆σ = χ in ]0, T [×Ω σ = σ Γ on ]0, T [×∂Ω - σ(0) = σ 0 in Ω
where ε ⩾ 0 is the diffusion parameter. Observe that when ε = 0, this problem reduces to the usual one, without diffusion, as introduced in section 5.3.1. The steady version of the tensor transport problem writes:

(S): find σ, defined in Ω, such that

u.∇)σ + σg a (u + g T a (u)σ + νσ -ε∆σ = χ in Ω σ = σ Γ on ∂Ω - We introduce the forms defined for all σ, τ ∈ H 1 (Ω) d×d s by a(σ, τ ) = Ω (u.∇)σ + σg a (u) + g T a (u)σ + ν σ : τ dx + ∂Ω max (0, -u.n) σ : τ ds + Ω ε∇σ : ∇τ dx l(τ ) = Ω χ : τ dx + ∂Ω max (0, -u.n) σ Γ : τ ds
Then, the variational formulation of the steady problem writes:

(F V ): find σ ∈ X such that a(σ, τ ) = l(τ ), ∀τ ∈ H 1 (Ω) d×d s
The discontinuous finite element space is then defined by:

X h = {τ h ∈ H 1 (Ω) d×d s ; τ h|K ∈ P k , ∀K ∈ T h }
where k ⩾ 0 is the polynomial degree. The discrete version a h of the bilinear form a is defined for all σ h , τ h ∈ X h by:

a h (σ h , τ h ) = t h (u; σ h , τ h ) + εd h (u; σ h , τ h ) + ν Ω σ h : τ h dx t h (u; σ h , τ h ) = Ω (u.∇ h )σ h + σg a (u) + g T a (u)σ : τ h dx + ∂Ω max (0, -u.n) σ h : τ h ds + S∈S (i) h S -u.n [[σ h ]] : { {τ h } } + α 2 |u.n| [[σ h ]] : [[τ h ]] ds d h (u; σ h , τ h ) = Ω ∇ h σ h : ∇ h τ h dx + S∈S h S (κ s [[σ h ]] : [[τ h ]] -[[σ h ]] : { {∇ h τ h n} } -[[τ h ]] : { {∇ h σ h n} }) ds l h (σ h ) = Ω χ : τ dx + ∂Ω max (0, -u.n) σ Γ : τ ds + ε ∂Ω (κ s σ Γ : τ -σ Γ : (∇ h τ n) + τ : (∇σ Γ n)) ds
where σ Γ is given and κ s = β ϖ s is the stabilisation parameter, with β = (k + 1)(k + d)/d and ϖ s is the penalisation, see section 4.3.1, page 167.

(F V ) h : find σ h ∈ X h such that a h (σ h , τ h ) = l h (τ h ), ∀τ h ∈ X h
The following code implement this problem in the Rheolef environment.

Running the program

Let d = 2 and Ω =] -1/2, 1/2[ 2 . We consider the rotating field u = (-x 2 , x 1 ). A particular solution of the time-dependent problem with zero right-hand side is given by:

σ(x, t) = 1 2 exp -νt - (x 1 -x 1,c (t)) 2 + (x 2 -x 2,c (t)) 2 r 2 0 × 1 + cos(2t) sin(2t) sin(2t) 1 -cos(2t)
where x 1,c (t) = x1,c cos(t) -x2,c sin(t) and x 2,c (t) = x1,c sin(t) + x2,c cos(t) with r 0 > 0 and (x 1,c , x2,c ) ∈ R 2 . The form h is chosen with σ Γ = σ. This exact solution is implemented in the file 'diffusion_transport_tensor_exact.icc'. This file it is not listed here but is available in the Rheolef example directory. For the steady problem, the right-hand side could be chosen as χ = -∂σ ∂t and then t = t 0 is fixed. The numerical tests correspond to ν = 3, r 0 = 1/10, (x 1,c , x2,c ) = (1/4, 0) and a fixed time t 0 = π/8. make diffusion_transport_tensor_dg mkgeo_grid -t 80 -a -0.5 -b 0.5 -c -0.5 -d 0.5 > square2.geo ./diffusion_transport_tensor_dg square2 P1d > square2.field field square2.field -comp 00 -elevation field square2.field -comp 01 -elevation

The computation could also be performed with any Pkd, with k ⩾ 0.

Error analysis

10 -6 10 -4 10 -2 10 -3 10 -2 10 -1 ∥σ h -σ∥ L 2 2 3 4 h Figure 5
.17: Diffusion-diffusion tensor problem: convergence versus mesh size.

The file 'diffusion_transport_tensor_error_dg.cc' implement the computation of the error between the approximate solution σ h and the exact one σ. This file it is not listed here but is available in the Rheolef example directory. The computation of the error is obtained by: make diffusion_transport_tensor_error_dg ./diffusion_transport_tensor_error_dg < square2.field

The error is plotted on Fig. 5.17 for various mesh size h and polynomial order k: observe the optimality of the convergence properties.

Chapter 6

[New] Hybrid discontinuous methods

This chapter is still in active development.

The Raviart-Thomas element

The aim of this chapter is to introduce to the Raviart-Thomas element [START_REF] Raviart | A mixed finite element method for 2-nd order elliptic problems[END_REF] for building an approximation of the H(div, Ω) space.

There is a subtle issue. The Rheolef implementation choice for this element bases on internal interpolation nodes instead of moments. This choice leads to more efficient computation of degrees of freedom, but the standard Lagrange interpolation π h no more satisfies the comutation diagram and optimal error in the H(div, Ω) norm. Instead of the Lagrange interpolation π h , we propose a projection operator, that satisfies these desired properties. We start building this projection operator for a piecewise discontinuous version of this element: it allows one to build a projection that requires only local operations and converges optimaly. Moreover, the piecewise discontinuous Raviart-Thomas approximation is used during the post-processing stage of the hybrid discontinuous Galekin method, that will be developped in a forthcoming chapter. Let

V h = v h ∈ L 2 (Ω) d ; v h|K ∈ RT k (K), ∀K ∈ T h Q h = q h ∈ L 2 (Ω) ; q h|K ∈ P k , ∀K ∈ T h
Here, V h represents the space of discontinuous and piecewise k-th order Raviart-Thomas RT k vector-valued functions while Q h is the space of piecewise discontinuous polynomials.

Let π Q h denote the L 2 projection from L 2 (Ω) into Q h . For all p ∈ L 2 (Ω), it is defined as π Q h (p) = p h ∈ Q h ,
where q h is the solution of the following quadratic minimization problem:

p h = arg inf q h ∈Q h Ω (p -q h ) 2 dx
Its solution is characterized as the unique solution of the following linear system, expressed in variational form:

(P 1 ): find p h ∈ Q h such that Ω p h q h dx = Ω p q h dx, ∀q h ∈ Q h
Following Roberts and Thomas [Roberts and Thomas, 1991, p. 551-552], our aim is to define π V h as the L 2 projection from H(div, Ω) into V h and satisfying the following commuting property:

H(div, Ω) L 2 (Ω) V h Q h div π V h π Q h div i.e. div(π V h (u)) = π Q h (div u), ∀u ∈ H(div, Ω) (6.1a)
In [Roberts and Thomas, 1991, p. 553], theorem 6.3, this projection operator then satisfies an optimal error bound in the H(div, Ω) norm, i.e.:

∥u -π V h (u)∥ 0,2,Ω + ∥div(u -π V h (u))∥ 0,2,Ω = O(h k+1 ) (6.1b)
Remark that the Lagrange interpolation operator π h from H(div, Ω) to V h do not necessarily satisfy the commuting property (6.1a). Indeed, this depends upon the way the Raviart-Thomas internal degrees of freedom are chosen and implemented. When internal degrees of freedom are chosen as integrals over polynomials of degree ℓ ⩽ k -1, e.g. as in [Roberts and Thomas, 1991, p. 551], eqn (6.8), then the Lagrange interpolation π h satisfies both (6.1a) and (6.1b), as shown [START_REF] Roberts | Mixed and hybrid methods[END_REF], theorem 6.1 and 6.3. In practice, it is more efficient to choose for all the internal degrees of freedom of the Raviart-Thomas some values of the function on a set of internal points: this implementation choice has been chosen in Rheolef. In that case, the Lagrange interpolation π h neither satisfies the commutation (6.1a) nor the bound (6.1b). More precisely, the Lagrange interpolation error is optimal in L 2 norm only while its divergence converges sub-optimally. Thus, with the present choice of the internal degrees of freedom, there is a need to explicitly compute the projection π V h that satisfies both (6.1a) and (6.1b). For all u ∈ H(div, Ω), this projection is defined as the L 2 projection of u under the constraint (6.1a):

π V h (u) = arg inf v h ∈V h ∥u -v h ∥ 2 0,2,Ω subject to div(v v ) = π Q h (div u)
Then, u h = π V h (u) ∈ V h is equivalently characterized as the solution of the following saddle-point problem:

(u h , p h ) = arg inf v h ∈V h arg sup q h ∈Q h L(v h , q h )
where the Lagrangian L is defined, for all

(v h , q h ) ∈ V h × Q h , by L(v h , q h ) = Ω |u -v h | 2 + q h div(u -v h ) dx
The saddle-point of L is characterized as the unique solution of a linear system, expressed in variational form. Moreover, since both V h and Q h are spaces of piecewise discontinuous functions, the linear system writes as a collection of local linear systems on each element.

(P ): find (u h , p h ) ∈ V h × Q h such that, on each element K ∈ T h , we have K (u h .v h + p h div v h )dx = K u.v h dx (6.2a) K q h div u h dx = K q h div u dx (6.2b) for all (v h , q h ) ∈ V h × Q h .
Observe that q h represents the Lagrange multiplier associated to the commutation constraint (6.2b), which is equivalent to (6.1a).

-15

10 -10

10 -5 1 10 -3 10 -2 10 -1 1 ∥u -P V h (u)∥ 0,2,Ω 1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -15 10 -10 10 -5 1 10 -3 10 -2 10 -1 1 ∥div(u -P V h (u))∥ 0,2,Ω 1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -15 10 -10 10 -5 1 10 -3 10 -2 10 -1 1 ∥u -π h (u)∥ 0,2,Ω 1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -15 10 -10 10 -5 1 10 -3 10 -2 10 -1 1 ∥div(u -π h (u))∥ 0,2,Ω 1 2 3 = k h k = 0 k = 1 k = 2 k = 3
Figure 6.1: Raviart-Thomas approximation: π V h projection (top) and π h interpolation (bottom) errors in L 2 norm for the approximation and its divergence.

Hybrid discontinuous Galerkin (HDG) methods

The aim of this chapter is to introduce to hybridization of discontinuous Galerkin methods within the Rheolef environment. For a review of hybridizable discontinuous Galerkin methods, see Nguyen et al. [2011]. The hybridization technique allows an efficient finite element implementation of many problems of importance, such as the Navier-Stokes one. Let us start by some model problems. (P ): find σ and u, defined in Ω, such that

The Poisson problem

         σ -∇u = 0 in Ω div(σ) = -f in Ω u = g d on Γ d σ.n = g n on Γ n (6.3a) (6.3b) (6.3c) (6.3d)
Let us multiply (6.3a) by a test function τ and integrate by parts on any element K:

K (σ.τ + div(τ ) u) dx - ∂K (τ .n) u ds = 0
In the discontinuous Galerkin method, the trace of u on ∂K will be discontinuous across the inter-element boundaries. The hybridization replaces this trace by a new independent variable, denoted as λ, that is only definied on sides of the mesh:

K (σ.τ + div(τ ) u) dx - ∂K (τ .n) λ ds = 0 (6.4a)
The λ variable will be uni-valued on boundary inter-elements and accounts strongly for the boundary condition: λ = g d on Γ d . Then, let us multiply (6.3b) by a test function v with a zero average value on K:

K div(σ) v dx = - K f v dx
In order to weakly impose the condition u = λ on ∂K, we add a penalization term:

K div(σ) v dx -βh n ∂K h n (u -λ) v ds = - K f v dx (6.4b)
Here, h denotes the local mesh size in the element K. The two constants β > 0 and n ∈ R are respectively a penalization coefficient and power index. Following [START_REF] Cockburn | Superconvergent discontinuous Galerkin methods for second-order elliptic problems[END_REF], we consider the three cases n = 0, 1 and -1. We have three unknowns σ, u and λ and only the two equations (6.4a) and (6.4b). For the problem to be complete, we add an equation for λ. Observe that (6.4b) writes equivalently, after a second integration by part on K:

- K σ.∇v dx + ∂K (σ.n -βh n (u -λ)) v ds = - K f v dx
The quantity involved in the integral on ∂K is denoted as σ = σ -βh n (u -λ) n and refered as the numerical flux across inter-element boundaries. As an additional equation, we impose the continuity of the normal component of this numerical flux. On the Γ n boundary domain, the normal component of the numerical flux is imposed to be the prescribed flux g n , while the Dirichlet condition λ = g d is precribed on the Γ d boundary domain:

[[σ -βh n (u -λ) n]].n = 0 on S, ∀S ∈ S (i) h (6.5a) σ.n -βh n (u -λ) = g n on Γ n (6.5b) λ = g d on Γ d (6.5c)
For an internal side S = ∂K + ∩ ∂K -∈ S (i) h

between two elements K 1 , K 2 ∈ T h , relation (6.5a) writes:

σ + .n + -βh n (u + -λ) + σ -.n --βh n (u --λ) = 0 on S
where σ ± and u ± are the trace on S of σ and u in K ± and n ± are the outer normal of K ± on S. Since S is oriented, let us choose without loss of generality n = n -= -n + . Then, the previous relation writes:

(σ --σ + ) .n -βh n (u -+ u + ) + 2βh n λ = 0 on S ⇐⇒ [[σ]].n -2βh n ({ {u} } -λ) = 0 on S
where we have used the jump and average across the internal side S. The previous relation, together with (6.5c) and (6.5c), writes in variational form:

S (i) h ([[σ]].n -2βh n ({ {u} } -λ)) µ ds + ∂Ω (σ.n -βh n (u -λ)) µ ds = Γn g n µ ds (6.6)
for all test function µ, defined on all internal sides of S (i)

h and on all sides of the boundary domain Γ n and that vanishes on all sides of the boundary domain Γ d . Grouping (6.4a), (6.4b) and (6.6), we obtain the discrete variational formulation:

(F V ) h : find (σ h , u h , λ h ) ∈ T h × X h × M h (g d ) such that Ω σ.τ dx + Ω div h (τ ) u dx - S (i) h ([[τ ]].n) λ ds - ∂Ω (τ .n) λ ds = 0 Ω div h (σ) v dx -β K∈T h ∂K h n u v ds + S (i) h 2βh n { {v} } λ ds + ∂Ω βh n v λ ds = - Ω f v dx S (i) h (2βh n { {u} } -[[σ]].n) µ ds + ∂Ω (βh n u -σ.n) µ ds - S (i) h 2βh n λ µ ds - ∂Ω βh n λ µ ds = - Γn g n µ ds for all (τ h , v h , τ h ) ∈ T h × X h × M h (0), where
T h = τ ∈ L 2 (Ω) d ; τ |K ∈ (P k ) d , ∀K ∈ T h X h = v ∈ L 2 (Ω) ; v |K ∈ P k , ∀K ∈ T h M h = µ ∈ L 2 (S h ) ; µ |S ∈ P k , ∀S ∈ S h M h (g d ) = µ ∈ M h ; µ |S = π h (g d ), ∀S ⊂ Γ d
and k ⩾ 0 is the polynomial degree. This is a symmetric system with a mixed structure. Let:

a h ((σ, u), (τ , v)) = Ω (σ.τ + div h (τ ) u + div h (σ) v) dx -β K∈T h ∂K h n u v ds b h ((τ , v), µ) = S (i) h (-[[τ ]].n + 2βh n { {v} }) µ ds + ∂Ω (-τ .n + βh n { {v} }) µ ds c h (λ, µ) = S (i) h 2βh n λ µ ds + ∂Ω βh n λ µ ds ℓ h (τ , v) = - Ω f v dx k h (µ) = - Γn g n µ ds
Then, the variational formulation writes equivalently:

(F V ) h : find (σ h , u h , λ h ) ∈ T h × X h × M h (g d ) such that a h ((σ, u), (τ , v)) + b h ((τ , v), λ) = ℓ h (τ , v) b h ((σ, u), µ) -c h (λ, µ) = k h (µ) for all (τ h , v h , τ h ) ∈ T h × X h × M h (0). Let χ h = (σ h , u h
). This linear symmetric system admits the following matrix structure:

A B T B -C χ h λ h = F G
A carreful study shows that the A matrix has a block-diagonal structure at the element level and can be easily inverted on the fly during the assembly process. The matrix structure writes equivalently:

⇐⇒ Aχ h + B T λ h = F Bχ h -Cλ h = G ⇐⇒ χ h = A -1 (F -B T λ h ) (C + BA -1 B T )λ h = BA -1 F -G
The second equation is solved first: the only remaining unknown is the Lagrange multiplier λ h , in a linear system involving the Schur complement matrix S = C + BA -1 B T . Then, the two variables χ h = (σ h , u h ) are simply obtained by a direct computation. 10 -4 The right-hand-side f and the Dirichlet boundary condition g has been chosen such that the exact solution is given by:

10 -2 1 10 -3 10 -2 10 -1 1 ∥u -u h ∥ 0,2,Ω n = 1 1 2 3 = k h k = 0 k = 1 k = 2 k = 3 10 -12 10 -10 10 -8 10 -6 10 -4 10 -2 1 10 -3 10 -2 10 -1 1 ∥u -u h ∥ 0,2,Ω n = 0 1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -12 10 -10 10 -8 10 -6 10 -4 10 -2 1 10 -3 10 -2 10 -1 1 ∥u -u h ∥ 0,2,Ω n = -1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -12 10 -10 10 -8 10 -6 10 -4 10 -2 1 10 -3 10 -2 10 -1 1 ∥∇u -σ h ∥ 0,2,Ω n = 1 1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -12 10 -10 10 -8 10 -6 10 -4 10 -2 1 10 -3 10 -2 10 -1 1 ∥∇u -σ h ∥ 0,2,Ω n = 0 1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3 10 -12 10 -10 10 -8 10 -6 10 -4 10 -2 1 10 -3 10 -2 10 -1 1 ∥∇u -σ h ∥ 0,2,Ω n = -1 1 2 3 = k h k = 0 k = 1 k = 2 k = 3
u(x) = d-1 i=0 sin(πx i )
The files 'sinusprod_dirichlet.h', that defines the data f and g, and 'sinusprod_error_hdg.cc', that compute the error in various norms, are not listed here but are available in the Rheolef example directory.

How to run the program

The compilation and run write: make dirichlet_hdg mkgeo_grid -t 10 > square.geo ./dirichlet_hdg square.geo P1d > square.field field square.field -elevation field square.field -elevation -mark lambda field square.field -velocity -mark sigma make sinusprod_error_hdg ./sinusprod_error_hdg < square.field Fig. 6.2 plots the errors vs h and k for a two dimensional geometry. Observe that the approximation u h converges optimaly, as h k+1 , in the L 2 norm for any k ⩾ 0 when the power index n = 1. When n = 1, the convergence is suboptimal, as h k only and note that the lowest order approximation k = 0 is not convergent. When n = -1, the convergence is optimal, as h k+1 , only when k ⩾ 1, while the lowest order approximation k = 0 is not convergent. The approximation σ h of the gradient converges optimaly, as h k+1 , for both n = 0 and 1, while it is suboptimal, as h k , when n = -1. All these results are consistent with the approxiamtion theory of the HDG method, see [START_REF] Cockburn | Superconvergent discontinuous Galerkin methods for second-order elliptic problems[END_REF] andtables 2, 3, 6. 6.2.2 Superconvergence of the Lagrange multiplier Let π M h denote the L 2 projection from L 2 (S h ) into M h . We consider the special case of computing the projection π M h (u) ∈ M h of the restriction to S h of an element u ∈ L 2 (S h ). It is defined as

10 -16 10 -12 10 -8 10 -4 1 10 -3 10 -2 10 -1 1 ∥π Mh (u) -λ h ∥ 0,2,Sh n = 1 2 3 4 5 = k + 2 h k = 0 k = 1 k = 2 k = 3 10 -16 10 -12 10 -8 10 -4 1 10 -3 10 -2 10 -1 1 ∥π Mh (u) -λ h ∥ 0,2,Sh n = 0 1 3 4 5 = k + 2 h k = 0 k = 1 k = 2 k = 3 10 -16 10 -12 10 -8 10 -4 1 10 -3 10 -2 10 -1 1 ∥π Mh (u) -λ h ∥ 0,2,Sh n = -1 2 3 4 = k + 1 h k = 0 k = 1 k = 2 k = 3
π M h (u) = arg inf µ h ∈M h 1 2 S∈S h S (u -µ h ) 2 ds
The following bilinear forms are introduced:

m s (λ, µ) = S∈S h S λ µ ds k h (µ) = S∈S h S u µ ds
Then, the projection reduces to:

find λh = π M h (u) ∈ M h such that m s ( λh , µ h ) = k h (µ h ), ∀µ h ∈ M h
The result of projection operator can be obtained by a resolution of a linear system. Following [START_REF] Cockburn | A superconvergent LDG-hybridizable Galerkin method for second-order elliptic problems[END_REF][Cockburn et al., , p. 1896]], in order to measure the error on the set of sides S h of the mesh, we introduce the mesh-dependent norm ∥.∥ 0,2,S h , defined for all µ ∈ L 2 (S h ) by

∥µ∥ 2 0,2,S h = S∈S h S h S µ 2 ds
where h S is a characteristic length on the side S ∈ S h . Fig. 6.3 plots the difference π M h (u) -λ h in this mesh-dependent norm. In agrement with the theoretical results [START_REF] Cockburn | A superconvergent LDG-hybridizable Galerkin method for second-order elliptic problems[END_REF][Cockburn et al., , p. 1896]], we observe the superconvergence of the multiplier λ h to the L 2 projection π M h (u). More precisely, when n = 1 the order of convergence is k + 2 for any k ⩾ 0. When n = 0, the superconvergence occurs only when k ⩾ 1 and when n = -1 there is no superconvergence. This error is also computed by the code 'sinusprod_error_hdg.cc'. 10 -4 The superconvergence of the piecewise average values of the solution obtained by the hybrid discontinuous Galerkin method was first observed in [START_REF] Cockburn | A superconvergent LDG-hybridizable Galerkin method for second-order elliptic problems[END_REF][START_REF] Cockburn | Superconvergent discontinuous Galerkin methods for second-order elliptic problems[END_REF] and then exploited for many postprocessing application (see e.g. Nguyen et al. [2011]). The file 'dirichlet_hdg_average.icc' compute ūh = πh (u h , λ h ), the averaged solution, defined by (see [START_REF] Cockburn | A superconvergent LDG-hybridizable Galerkin method for second-order elliptic problems[END_REF], eqn (2.9b)):

Superconvergence of the piecewise averaged solution

1 10 -3 10 -2 10 -1 1 ∥π h (u) -ūh ∥ 0,2,Ω n = 1 2 3 4 5 6 = k + 2 h k = 0 k = 1 k = 2 k = 3 k = 4 10 -16 10 -12 10 -8 10 -4 1 10 -3 10 -2 10 -1 1 ∥π h (u) -ūh ∥ 0,2,Ω n = 0 1 3 4 6 = k + 2 h k = 0 k = 1 k = 2 k = 3 k = 4 10 -16 10 -12 10 -8 10 -4 1 10 -3 10 -2 10 -1 1 ∥π h (u) -ūh ∥ 0,2,Ω n = -1 2 3 5 = k + 1 h k = 0 k = 1 k = 2 k = 3 k = 4
πh (u h , λ h ) =            1 d S⊂∂K λ h when k = 0 1 meas(K) K u h dx when k ⩾ 1
The file 'sinusprod_error_hdg_average.cc' that compute the error ūh -πh (u) is not listed here but is available in the Rheolef example directory. The computation of the error is obtained by: make dirichlet_hdg dirichlet_hdg_average sinusprod_error_hdg_average mkgeo_grid -t 10 > square.geo ./dirichlet_hdg square.geo P1d | dirichlet_hdg_average | \ ./sinusprod_error_hdg_average Observe on Fig. 6.4 that, when n = 1 and for any k ⩾ 0, we obtain ūh -πh (u) of order k + 2. This is a remarkable result since u h is piecewise polynomial of order k and is expected to converge at order k + 1. When n = 0, for any k ⩾ 1 we also observe this superconvergence while, when k = 0, the average value converges only at first order. Finaly, when n = -1, for any k ⩾ 1 we do no more observe These observations are consistent with those of [Cockburn et al., 2009, p. 16] (see also [START_REF] Cockburn | A superconvergent LDG-hybridizable Galerkin method for second-order elliptic problems[END_REF][Cockburn et al., , p. 1613]]).

Improving the solution by local postprocessing

By combining the approximation σ h of the gradient ∇u, that converges at rate k + 1 (see Fig. 6.2), with the average ūh that super-converges at rate k + 2 (see Fig. 6.4), it is then possible, by a local integration inside each element, to obtain a new approximation u * h , that is piecewise discontinuous polynomial of order k + 1, and that converges at rate k + 2. The postprocess step is nothing than the resolution of the following local Neumann problem in any element K ∈ T h (see [Cockburn et al., 2010b[Cockburn et al., , p. 1360]], eqn (5.1)):

(P * ): find u * , defined in K, such that              -∆u * = f in K ∂u * ∂n = σ h .n on ∂K K u * dx = K ūh dx
where σ h and ūh are given by the previous resolution.

For any β ∈ R, let us introduce the following functional space:

X * K (β) = v ∈ H 1 (K) ; K v dx = β
Then, the variational formulation of the problem writes:

(F V * ): find u * ∈ X K K ūh dx such that K ∇u * .∇v * dx = K f v * dx + ∂K σ h .n v * ds, ∀v * ∈ X K (0)
The linear constraint for the imposition of the average value is not easy to impose in X K (β). Indeed, X K (β) is not a vectorial space when β ̸ = 0. Following the methodology previously introduced for the Neumann boundary conditions for the Laplace operator, we introduce a Lagrange multiplier denoted here as ζ, which is constant inside each element K.

Finally, the postprocessing step compute the approximation u * h , when σ h and u h are known,as:

(F V * ) h : find (u * h , ζ h ) ∈ X * h × Z h such that, on each element K ∈ T h , we have          K ∇u * h .∇v * h dx + K v * h ζ h dx = K f v * h dx + ∂K σ h .n v * h ds, ∀v * h ∈ X * h K u * h ξ h dx = K ūh ξ h dx, ∀ξ h ∈ X * h where X * h = v ∈ L 2 (Ω) ; v |K ∈ P k+1 , ∀K ∈ T h Z h = ξ ∈ L 2 (Ω) ; ξ |K ∈ P 0 , ∀K ∈ T h Let a * h (u, ζ; v, ξ) = Ω (∇ h u.∇ h v + v ζ + u ξ) dx ℓ * h (v, ξ) = Ω (f v + ūh ξ) dx + K∈T h ∂K (σ h .n) v ds
The second step writes in this abstract setting:

(F V * ) h : find (u * h , ζ * h ) ∈ X * h × Z h such that a * h (u * h , ζ h ; v * h , ξ h ) = ℓ * h (v * h , ξ h ), ∀(v * h , ξ h ) ∈ X * h × Z h
Note that the matrix associated to the bilinear form a * h is symmetric and block-diagonal: it can thus be easily be inverted on the fly at the element level. The present postprocessing stage was first introduced in [Cockburn et al., 2010b[Cockburn et al., , p. 1360]], eqn (5.1) as a replacement and a simplification of those previously introduced in Cockburn et al. [2008,2009]. The following code implement this postprocessing.

./dirichlet_hdg square.geo P1d > square.field ./dirichlet_hdg_post < square.field > square-post.field field square-post.field -elevation Note the dramatic improvement of the post-treated solution, when compared with the original one, that could be observed with: field square.field -elevation This improvement could be accurately quantified by the error analysis:

./sinusprod_error_hdg < square.field ./sinusprod_error_hdg < square-post.field

The results are shown on Fig. 6.5. When n = 1, observe that, for any k ⩾ 0, the error for the post-treated solution u * h converges to zero at rate k + 2 in L 2 norm, which is optimal, since u * h is a piecewise k + 1 degree polynomial. When n = 0, this result is obtained only for k ⩾ 1 while, when n = -1, the convergence is suboptimal.

Improving the gradient with the Raviart-Thomas element

Let (σ h , u h , λ h ) be the solution of problem (F V ) h . This solution is considered here as known. Observe that the normal component of the numerical flux σ h .n = σ h .n -βh n (u h -λ h ) is continuous across any inter-element boundaries. Indeed, relation (6.5a) is imposed weakely in the variational formulation (F V ) h , with a Lagrange multiplier µ h ∈ M h which is piecewise polynomial of degree k. Since σ h is also piecewise polynomial of degree k, the discrete version of (6.5a) is also satisfied strongly:

σ h .n = [[σ h -βh n (u h -λ h ) n]].n = 0 on S, ∀S ∈ S (i) h
Since any element of H(div, Ω) presents the continuity of its normal component across any interelement boundaries, is possible to define a new H(div, Ω) conform approximation of σ, denoted as σh , which satisfies σ h .n = σ h .n on any internal sides. Similarly to (6.5a), σh also should satisfy a discrete version of (6.5c)-(6.5c) i.e. σ h .n is equals to g n on Γ n and to σ h .n -βh n (u h -g d ) on Γ d . It is characterized as the unique element σh ∈ Th satisfying in any element K ∈ T h the following local variational formulation [Cockburn et al., 2010b[Cockburn et al., , p. 1360

]: K σh .γ h dx = K σ h .γ h dx, ∀γ h ∈ Gh ∂K ( σh .n) μh ds = ∂K (σ h .n -βh n (u h -λ h )) μh ds, ∀μ h ∈ Mh
where we have introduced the finite dimensional spaces

Th = τ h ∈ L 2 (Ω) d ; τ h|K ∈ RT k (K), ∀K ∈ T h Wh = γh ∈ L 2 (Ω) d ; γh|K ∈ P k-1 (K), ∀K ∈ T h Mh = K∈T h τ |∂K .n ; τ ∈ RT k (K) = K∈T h S⊂∂K P k (S) (6.7)
The space Th contains discontinuous and piecewise k-th order Raviart-Thomas RT k polynomial vector-valued functions. The space Mh contains, inside each element, the normal trace of functions of Th . Note that elements of Mh are piecewise P k on all sides S ⊂ ∂K. Moreover, for all internal side S ∈ S (i)

h , the elements of Mh are bi-valued, due to the discontinuity of elements of τ ∈ Th .

Finally, Wh contains piecewise discontinuous polynomial of degree k-1. By convention, when k = 0, then the space Wh is empty. Observe that dim( Th ) = dim( Wh ) + dim( Mh ) and that the previous local variational problem is well-posed. Let

ãh ( σh ; [γ h , μh ]) = Ω σh .γ h dx + K∈T h S⊂∂K S ( σh .n) μh ds lh ([γ h , μh ]) = Ω σ h .γ h dx + K∈T h ∂K (σ h .n -βh n (u h -λ h )) μh ds
For known (σ h , u h , λ h ), the postprocessing of the gradient writes:

( F V ) h : find σh ∈ Th such that ãh ( σh , [γ h , μh ]) = lh ([γ h , μh ]) for all (γ h , μh ) ∈ Wh × Mh .
A carreful study shows that the matrix associated with the ãh bilinear form has a block-diagonal structure at the element level and can be efficiently inverted on the fly during the assembly process. This property is due to the usage of discontinuous Raviart-Thomas approximation space Th . Moreover, since the normal component of σh is equal to the numerical flux σ h .n which is continuous across inter-element boundaries this is also the case for σh .n and finally σh ∈ H(div, Ω). string approx = ( k == 0) ? " empty " : " P " + to_string (k -1)+ " d " ;

space Tht ( omega , " RT " + to_string ( k )+ " d " );

space Wht ( omega , approx , " vector " ); mkgeo_grid -t 10 > square.geo ./dirichlet_hdg square.geo P1d > square.field ./dirichlet_hdg_post_rt < square.field > square-rt.field field square-rt.field -velocity -mark sigmat make sinusprod_error_hdg_post_rt ./sinusprod_error_hdg_post_rt < square-rt.field Fig. 6.6 plots the errors vs h and k for a two dimensional geometry. Observe that, when n = 1, the approximation σh of the gradient converges to ∇u with a k + 1 rate in H(div norm, with: ∥τ ∥ 2 div,2,Ω = ∥τ ∥ 2 0,2,Ω + ∥div(τ )∥ 2 0,2,Ω for any τ ∈ H(div, Ω). It means that div( σh ) converges to ∆u with a k + 1 rate in both L 2 norm. This is optimal with respect to the classical interpolation results for the k-th order Raviart-Thomas element (see section 6.1, page 249). When n = 0, the convergence is also optimal while, when n = -1 it is suboptimal.

n u h σ h u * h σh 1 k k + 1 k + 2 k + 1 0 k + 1 k + 1 1, k = 0 k + 2, k ⩾ 0 k + 1 -1 0, k = 0 k + 1, k ⩾ 0 k 0, k = 0 k + 1, k ⩾ 0 k Table 6
.1: Hybrid discontinuous Galerkin method: convergence order versus k for n ∈ {1, 0, -1}.

Fig. 6.1 summarizes the convergence orders versus the mesh size h in terms of k and n. Observe that n = 1 allows one to obtain an optimal convergence of both the the post-processed solution u * h and its gradient σh for any polynomial degree k ⩾ 0. When n = 0, it is optimal only for k ⩾ 1 while when n = -1 it is suboptimal. Thus the HDG method and its postprocessed stage could be considered as a whole. It allows, by solving a linear system for the k-th piecewise polynomial approximation of the Lagrange multiplier only, to obtain a k+2 order approximation of the solution in L 2 and a k+1 approximation of its gradient in H(div).

Hybrid high order (HHO) methods

The aim of this chapter is to introduce to hybrid high order (HHO) methods within the Rheolef environment. For a review of hybrid high order methods, and its link to hybrid discontinuous Galerkin (HDG) methods, see [START_REF] Cockburn | Bridging the hybrid high-order and hybridizable discontinuous Galerkin methods[END_REF]. Let us start by some model problems.

The diffusion problem

Let us consider an anisotropic diffusion problem with homogeneous Dirichlet conditions:

(P ): find u, defined in Ω, such that -div(A∇u) = f in Ω u = 0 on ∂Ω (6.8a) (6.8b)

where the right-hand-side f and the diffusion A are given functions. The diffusion is assumed to be bounded, symmetric, uniformly positive definite matrix-valued function. Observe that when A = I, the problem reduces to the usual Poisson problem with homogeneous Dirichlet conditions.

The reconstruction operator

The cornerstone of the HHO method is the reconstruction operator. Let k ⩾ 0 and ℓ ∈ {k-1, k, k+1} be two integers and let us introduce the following finite element spaces:

X h = v h ∈ L 2 (Ω) ; v h|K ∈ P ℓ , ∀K ∈ T h M h = µ h ∈ L 2 (S h ) ; µ h|S ∈ P k , ∀S ∈ S h X * h = v * h ∈ L 2 (Ω) ; v * h|K ∈ P k+1 , ∀K ∈ T h
The reconstruction operator [Cockburn et al., 2016, p. 637] is defined by

r h : X h × M h -→ X * h (u h , λ h ) -→ u * h = r h (u h , λ h ) where u * h ∈ X *
h is characterized by a collection of local constrained minimization problems, associated to local Neumann problems similar to those previously introduced for the HDG method, in subsection 6.2.4, page 259:

u * h = arg inf v * h ∈X * h 1 2 Ω |∇ h (v * h -u h )| 2 A dx - K∈T h ∂K (λ h -u h ) (A∇v * h ) .n ds subject to K v * h dx = K u h dx, ∀K ∈ T h
For any symmetric definite positive matrix c, we denote by |.| c the anisotropic norm in R d defined by |ξ| 2 c = ξ.(cξ) for all ξ ∈ R d . The constraint corresponds to the closure for the local Neumann problems, as otherwise the solution would be defined up to a constant in each element ∀K ∈ T h . This constrained minimization problem is not convenient for the numerical resolution: we prefer to express it as a saddle-point problem by introducing a Lagrange multiplier ζ h ∈ Z h with Z h = ξ h ∈ L 2 (Ω) ; ξ h|K ∈ P 0 , ∀K ∈ T h

The corresponding Lagrangian writes

L γ (u * , ζ) = 1 2 Ω |∇ h (u * -u h )| 2 A dx - K∈T h ∂K (λ h -u h ) (A∇u * ) .n ds + Ω (u * -u h ) ζ dx - Ω γ 2 ζ 2 dx (6.9)
Observe that the first two terms of the Lagrangian correspond to the minimization functional. The third term is associated to the constraint with its associated Lagrangian multiplier. When γ = 0, the fourth term vanishes and thus, the saddle-point of the Lagrangian is equivalent to the previous constrained minimization problem. The fourth term, when the augmentation parameter γ > 0 will be discussed later: in that case, L γ is related to the augmented Lagrangian. The saddle-point problem expresses:

(u * h , ζ h ) = arg inf v * h ∈X * h sup ξ h Z h L γ (v * h , ξ h )
Since L γ is differentiable, its saddle point is also characterized as the unique solution of the following collection of local variational problems:

(F V * ) h : let (u h , λ h ) ∈ X h × M h being given, find (u * h , ζ h ) ∈ X * h × Z h such that          K ∇u * h . (A∇v * h ) dx + K v * h ζ h dx = K ∇u h . (A∇v * h ) dx + ∂K (λ h -u h ) (A∇v * h ) .n ds K u * h ξ h dx - K γζ h ξ h dx = K u h ξ h dx
for all K ∈ T h and all (v * h , ξ h ) ∈ X * h × Z h . Observe that, for any K ∈ T h , we can choose the test function v * h as equal to 1 in K and zero elsewhere in Ω. Then, the first equation leads to ζ h = 0 in K. Since this could be repeated for any K ∈ T h , we obtain ζ h = 0. As a consequence, the term factored by γ ⩾ 0 has no influence upon the solution (u * h , ζ h ) which is independent upon γ: in this sense, this is not a penalization parameter, but an augmented Lagrangian parameter. Up to now, we assume γ > 0: we will show how it facilitates the numerical resolution of the system. Let, for all u * , v ∈ X

(F V * ) h : let (u h , λ h ) ∈ X h × M h being given, find (u * h , ζ h ) ∈ X * h × Z h such that a * (u * h , v * h ) + b * (v * h , ζ h ) = ǎ(u h , v * h ) + e * (v * h , λ h ), ∀v * h ∈ X * h b * (u * h , ξ h ) -c * (ζ h , ξ h ) = b(u h , ξ h ), ∀ξ h ∈ Z h
By identifying the bilinear forms and the associated matrix, the previous linear problem also expreses in matrix-vector form:

a * b T * b * -c * u * h ζ h = ǎ e * b 0 u h λ h
A carreful study shows that the matrix on the left-hand-side has a block-diagonal structure at the element level and its inverse can be easily constructed explicitly by inverting on the fly the element matrix during the assembly process. Then, the result of reconstruction operator can be obtained at low computational cost, by simple matrix-vector multiplication.

A further improvement can be obtained. Observe that the matrix on the left-hand-side is symmetric but definite: at the element level, it admits both positive and negative eigenvalues, due to the saddle point structure.

Expanding the previous linear system, we obtain

a * u * h + b T * ζ h = ǎu h + e T * λ h b * u * h -c * ζ h = bu h
Since the c * matrix is diagonal, when choosing γ > 0, the ζ unknown could be eliminated at the element level:

ζ h = c -1 * (b * u * h -bu h ) u * h = S -1
How to run the program

The compilation and run write: make reconstruction_hho sinusprod_error_hho_reconstruction mkgeo_grid -t 10 > square.geo ./reconstruction_hho square.geo P1d P1d | ./sinusprod_error_hho_reconstruction

The code 'reconstruction_hho.cc' first computes u h and λ h as L 2 projections on X h and M h , respectively, of a given function:

u(x) = d-1 i=0 sin(πx i )
Then, it builds the reconstruction u * h = r h (u h , λ h ) and output the result.

Next, the code 'sinusprod_error_hho_reconstruction.cc' shows the L 2 and H 1 error for the reconstruction u * h . The files 'sinusprod.h', 'diffusion_isotropic.h', and 'sinusprod_error_hho_reconstruction.cc', that defines u and A, and that compute the errors, respectively, are not listed here but is available in the Rheolef example directory. Fig. 6.7 plots the error versus mesh size h and the polynomial order k: the convergence order is k + 2 in the L 2 norm and k + 1 in the H 1 one, as expected (see [START_REF] Cockburn | Bridging the hybrid high-order and hybridizable discontinuous Galerkin methods[END_REF], eqn (2.9) or di [START_REF] Di Pietro | Hybrid high-order methods for variable-diffusion problems on general meshes[END_REF], eqn (3)).

The projections

Let π X h denotes the L 2 projection from L 2 (Ω) into X h . For all u * ∈ L 2 (Ω), it is defined as π X h (u * ) = ǔh ∈ X h , where ǔh is the solution of the following quadratic minimization problem:

ǔh = arg inf vh ∈X h 1 2 Ω (u * -vh ) 2 dx
Let us consider the special case of computing the projection ǔh = π X h (u * h ) ∈ X h of an element u * h ∈ X * h . The following bilinear forms are introduced:

m(ǔ, v) = Ω ǔ v dx d * (u * , v) = Ω u * v dx
Then, the projection reduces to: let u * h ∈ X * h being given, find ǔh ∈ X h such that m(ǔ h , vh ) = d * (u * h , vh ), ∀v h ∈ X h Note that the matrix associated to the bilinear form m from X h × X h to R has a block-diagonal structure at the element level and can be easily inverted on the fly during the assembly process. Then, the result of projection operator can be obtained by simple matrix-vector multiplication. Let us reintroduce the following space Mh , already defined in (6.7), page 262, in the context of the HDG method: Here also, the matrix associated to the bilinear form m s from Mh × Mh to R has a block-diagonal structure at the element level and can be easily inverted on the fly during the assembly process.

Then, the result of projection operator can be obtained by simple matrix-vector multiplication.

The discrete problem statement

The discretization of the diffusion problem (6.8a)-(6.8b) by the hybrid high-order (HHO) method [Cockburn et al., 2016, p. 639] is expressed here as a minimization problem:

(u h , λ h ) = arg min

v h ∈X h max µ h ∈M h (0) L 1 (v h , µ h ) with L 1 (u, λ) = Ω 1 2 |∇ h r h (u, λ)| 2 A -f u dx + 1 2 K∈T h S⊂∂K S β h -1 S π Mh {u -λ + (I -π X h ) r h (u, λ)} 2 ds M h (0) = µ h ∈ M h ; µ h|S = 0, ∀S ⊂ ∂Ω
In the definition of L 1 , the first term is related to the consistency and the second one to the stabilization, with a β h -1 S penalization factor (see [Cockburn et al., 2016, p. 637], eqns (2.4)-(2.5)), while h S denotes a local mesh characteristic length in the side S ∈ S h . Here β > 0 is the penalization parameter, which is a constant independent of the mesh size h. The space M h (0) for the Lagrange multiplier λ h is introduced in order to impose the homogeneous Dirichlet condition (6.8b) as a constraint. The expression of L 1 is not convenient for practical implementation, as it involves both the reconstruction operator r h and the projections π X h and π Mh . Let us introduce the reconstruction u * h = r h (u h , µ h ) ∈ X * h as an auxilliary variable. The constraint u * h -r h (u h , µ h ) = 0 is imposed via a Lagrange multiplier v * h ∈ X * h . Both the two additional variables u * h and v * h have a constrained average value and we also introduce two associated Lagrangian multipliers: one is denoted by ζ 1,h ∈ Z h , associated to the imposition of a zero element-wise average value for u * h -u h . the second, ζ 2,h ∈ Z h , is associated to the imposition of a zero element-wise average value for v * h .

Similarly to the augmented Lagrangian (6.9), we introduce a new Lagrangian:

L 2 (u, u * ; λ, v * , ζ 1 , ζ 2 ) = Ω 1 2 |∇ h u * | 2 A -f u dx + 1 2 K∈T h S⊂∂K S β h -1 S π Mh {u -λ + u * -π X h (u * )} 2 ds + Ω ∇ h (u * -u). (A∇ h v * ) dx + K∈T h ∂K (u -λ) (A∇v * ) .n ds + Ω (u * -u) ζ 1 + v * ζ 2 - α h -2 2 ζ 2 1 -ζ 2 2 dx
In the last term, also have introduced the augmented Lagrangian term with coefficient α > 0, as introduced in the previous paragraph on the reconstruction operator. The previous problem in terms of L 1 can be equivalently expressed as a saddle point for L 2 , with six unknowns:

(u h , u * h ; λ h , v * h , ζ 1,h , ζ 2,h ) = arg inf v h ∈ X h v * h ∈ X * h sup µ h ∈ M h (0) w * h ∈ X * h ξ 1,h ∈ Z h ξ 2,h ∈ Z h L 2 (v h , v * h ; µ h , w * h , ξ 1,h , ξ 2,h )
The reconstruction operator r h has been eliminated, but the previous expression of L 2 still involves the two projectors π X h and π Mh . These explicit calls to the projectors are not convenient for the practical implementation. Let us introduce the two auxiliary variables ǔh = π X h (u * h ) ∈ X h and δh = π Mh (u -λ + u * h -ǔh ) ∈ Mh as two constraints and the two corresponding Lagrangian multipliers, vh ∈ X h and γh ∈ Mh , respectively. Then, we obtain the following Lagrangian: L(u, u * , ǔ, δ; λ, v

; µ) ∈ X * h × Z h × Mh 2 × X 3 h × M h (0)
. The h subscripts for the unknowns and test functions have been omitted for simplicity in the variational expression. This system could appear as complex. But observe that all discretization are piecewise discontinuous at the element level except those for λ h ∈ M h (0). Then, all variables except this one could be eliminated at the element level. In order to process to this elimination, the previous variational formulation is rearranged as a matrix block structure: The following subexpression will be frequently involved: As usual, the right-hand-side f and the Dirichlet boundary condition g has been chosen such that the exact solution is given by: u(x) = continuous Lagrange solution. While increasing the polynomial order k, the slope of convergence of the error versus h appears to be higher than its counterpart with the classical Lagrange continuous approximation (dotted lines). Thus, the HHO method appears to be asymptotically more efficient when h → 0 i.e. large meshes and high CPU times. Nevertheless, the constant in front of this asymptotical HHO method is higher than its counterpart with the classical Lagrange continuous approximation, and thus, when the mesh is medium or small, the classical method is still faster. The constant of the HHO method is due to algebraic manipulations, such as assembly and matrix-matrix products at the element level: it could certainly be decreased by a more efficient implementation of the HHO method, and this perspective will be explorated in the future.

                    u * ζ 1 v * ζ 2 δ γ ǔ v u
Then, multiplying the first equation of (2.2) by an arbitrarily test-function v ∈ V and then integrate over Ω :

- i,j=0 σ i,j τ i,j for any tensors σ and τ , and that u ⊗ v dotes the τ i,j = u i v j tensor, vectors u and v. Remark that τ : (u ⊗ v) = (τ v).u = The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque". Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, L A T E X input format, SGML or XML using a publicly available DTD, and standardconforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machinegenerated HTML produced by some word processors for output purposes only. The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

Verbatim Copying

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies.

Copying in Quantity

If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you • Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

• Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.

• Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties -for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

Combining Documents

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."

Collections of Documents

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".

If -branch, 134, 140, 237 -bw, 150, 152 -extract, 134, 140, 237 -gnuplot, 175 -iso, 150, 152 -toc, 134, 140, 237 -umax, 175 -umin, 175 -volume, 75, 80 -vtk, 150 convect, 77 field, 13 -, 15 -bw, 13, 64, 67, 85, 101 -comp, 43, 46, 67, 68, 85 -cut, 67, 68, 85, 110, 204 -domain, 204 -elevation, 13, 45, 74, 101, 110, 204 -fill, 43 -gnuplot, 13, 14, 67, 68, 85, 110, 204 -gray, 13 -mark, 52 -max, 65, 86, 134 -min, 86 -n-iso, 64, 219 -n-iso-negative, 64, 67, 85, 219, 237 -noclean, 56 -noexecute, 56 -nofill, 13, 42, 48 -normal, 67, 68, 85, 110, 204 -origin, 67, 68, 85, 110, 204 -proj, 45, 219 -scale, 58 -stereo, 13, 15, 43, 45, 46, 91, 101 -velocity, 52, 85 -volume, 16, 22 geo, 13 -cut, 15 -fill, 15 -full, 15 -gnuplot, 96 -paraview, 277 -shrink, 15 -stereo, 15, 91 -subdivide, 92 gmsh, 49, 63, 66, 91, 95, 111, 278 gnuplot, 13-15, 36, 43, 74, 77, gzip, 48 library boost, 11 CGAL, computational geometry, MPI, message passing interface, mumps, linear system direct solver, 17 scotch, mesh partition library, 17 STL, standard template library, 77 make, 12 man, 14 mkgeo_ball, 91 -e, 91 -s, 91 -t, 25, 91 mkgeo_contraction, 236 -split, 236 mkgeo_grid, 13, 77, 111 -H, 16 -T, 15, 80 -a, 77 -b, 77 -c, 79 -d, 79 -e, 15 -f, 80 -g, 80 -q, 16 -region, 36 -t, 13 -zr, 65 mkgeo_obstacle, 71 mkgeo_sector, 218 mkgeo_ugrid, 23, 111 mpirun, 18, 37, 85, 150, 152, 218, 219, 237 msh2geo, 63, 278, 279 -zr, 66 paraview, 13, 15, 45, 46, 56, 74, 79, 150, 219 Mosolov,80,181 Poisson,10,20,30,31,73,107,109,163,166,167,199 Stokes,58,80,179,181 combustion

  Xh.block ("boundary"); space Xh (omega, argv[2]); geo omega (argv[1]); environment rheolef (argc, argv); int main (int argc, char** argv) { field uh (Xh); uh ["boundary"] = 0; problem p (a); p.solve (lh, uh); dout ≪ uh; } field lh = integrate (v); trial u (Xh); test v (Xh);

  grad(u) ∇u = ∂u i ∂x j 0⩽i,j<d gradient of a vector field div(u) div(u) = tr(∇u) = d-1 i=0 ∂u i ∂x i divergence of a vector field D(u) D(u) = ∇u + ∇u T /2 symmetric part of the gradient of a vector field Rheolef mathematics description curl(u) curl(u) = ∇ ∧ u curl of a vector field, when d = 3 curl(phi) curl(ϕ) vector field, when d = 2 grad_s(phi) ∇ s ϕ = P ∇ϕ where P = I -n ⊗ n tangential gradient of a scalar grad_s(u) ∇ s u = ∇uP tangential gradient of a vector Ds(u) D s (u) = P D(u)P symmetrized tangential gradient div_s(u) div s (u) = tr(D s (u)) tangential divergence unit outward normal on Γ = ∂Ω normal() n or on an oriented surface Ω or on an internal oriented side S jump(phi) [[ϕ]] = ϕ |K0 -ϕ |K1 ϕ on ∂Ω jump accross side S = ∂K 0 ∩ K 1 see section 4.1.1 page 147 average(phi) { {ϕ} } = (ϕ |K0 + ϕ |K1 )/2 ϕ on ∂Ω average across S = ∂K 0 ∩ K 1 inner(phi) = ϕ |K0 ϕ on ∂Ω inner trace across S = ∂K 0 ∩ K 1 outer(phi) = ϕ |K1 ϕ on ∂Ω outer trace across S = ∂K 0 ∩ K 1 h_local() h K = meas(K) 1/d length scale on an element K penalty() ϖ s = max meas(∂K 0 ) meas(K 0 ) , meas(∂K 1 ) meas(K 1 ) penalty coefficient on S grad_h(phi) (∇ h ϕ) |K = ∇(ϕ |K ), ∀K ∈ T h broken gradient div_h(u) (div h u) |K = div(u |K ), ∀K ∈ T h broken divergence of a vector field Dh(u) (D h (u)) |K = D(u |K ), ∀K ∈ T h broken symmetric part of

  cp -a /usr/share/doc/rheolef-doc/examples . cd examples 1.1.1 Problem statement Let us consider the classical Poisson problem with homogeneous Dirichlet boundary conditions in a domain bounded Ω ⊂ R d , d = 1, 2, 3:

File

  Xh ); test v ( Xh ); form a = lazy_integrate ( dot ( grad ( u ) , grad ( v ))); field lh = lazy_integrate ( v ); field uh ( Xh ); uh [ " boundary " ] = 0; problem p ( a ); p . solve ( lh , uh ); dout << uh ; } 1.1.

  a(u h , v h ) = vh.u vh.b a.uu a.ub a.bu a.bb uh.u uh.b This representation also applies for the linear form l(.): l(v h ) = vh.u vh.b lh.u lh.b Thus, the problem (V F ) h writes now: for any vh.u and where vh.b = 0. After expansion, the problem reduces to find uh.u such that: a.uu * uh.u = l.ua.ub * uh.b

Figure 1

 1 Figure 1.1: Solution of the model problem for d = 2 with the P 1 element: visualization (left) with paraview as filled isocontours ; (right) with gnuplot as unfilled isocontours.

  Figure 1.2: Alternative representations of the solution of the model problem (d = 2 and the P 1 element): (left) in black-and-white; (right) in elevation and stereoscopic anaglyph mode.

Figure 1

 1 Figure 1.3: Red-cyan anaglyph glasses for the stereoscopic visualization.

Figure 1 . 4 :

 14 Figure 1.4: Solution of the model problem for d = 3 and the P 1 element : (left) mesh; (right) isovalue, cut planes and stereo anaglyph renderings.

Figure 1

 1 Figure 1.5: Compared performance between direct and iterative solvers: (left) d = 2; (right) d = 3.

Figure 1 . 6 :

 16 Figure 1.6: Distributed and massively parallel resolution of the model problem with P 1 element: speedup S(p) versus the number of processors p during : (left-right) for d = 2 and 3, respectively ; (top) the assembly phase ; (center-bottom) the solve phase, direct and iterative solvers, respectively.

File}

  Let us chooseΩ ⊂ R d , d = 1, 2, 3 with f (x) = d π 2

File

  const point & x ) const { return d * pi * pi * cos ( pi * x [0])* cos ( pi * x [1])* cos ( pi * x [2]); } f ( size_t d1 ) : d ( d1 ) , pi ( acos ( Float ( -1

  ( min (3*( k +1)+4 , size_t (17))); Float err_u_l2 = sqrt ( integrate ( omega , sqr ( uh -u_exact ( d )) , iopt )); string opts = Xh . get_basis (). option (). stamp (); space Xh1 ( omega , " P " + to_string ( k +1)+ " d " + opts ); field euh = lazy_interpolate ( Xh1 , uh -u_exact ( d )); Float err_u_linf = euh . max_abs (); Float err_u_h1 = sqrt ( integrate ( omega , norm2 ( grad_h ( euh )) , iopt )const point & x ) const { return cos ( pi * x [0])* cos ( pi * x [1])* cos ( pi * x [2]); } u_exact ( size_t d1 ) : d ( d1 ) , pi ( acos ( Float ( -1.0))) {} size_t d ; Float pi ; }; Running the program make dirichlet-nh cosinusprod_error After compilation, run the code by using the command: mkgeo_grid -t 10 > square.geo ./dirichlet-nh square.geo P1 | ./cosinusprod_error

Figure 1 . 7 :File

 17 Figure 1.7: Strait geometry: error analysis in L 2 , L ∞ and H 1 norms.

Figure 1 . 8 :

 18 Figure 1.8: Curved domains (triangles): error analysis in L 2 , L ∞ and H 1 norms.

File

  omega . dimension (); space Xh ( omega , argv [2]); trial u ( Xh ); test v ( Xh ); form a = integrate ( u * v + dot ( grad ( u ) , grad ( v ))); field lh = integrate ( f ( d )* v ) + integrate ( " boundary " , g ( d )* v ); field uh ( Xh ); problem p ( a ); p . solve ( lh , uh ); dout << uh ; } Let us choose Ω ⊂ R d , d = 1, 2, 3 and

  return (1+ d * pi * pi )* sin ( pi * x [0]); case 2: return (1+ d * pi * pi )* sin ( pi * x [0])* sin ( pi * x [1]); default : return (1+ d * pi * pi )* sin ( pi * x [0])* sin ( pi * x [1])* sin ( pi * x [2return -pi *( sin ( pi * x [0]) + sin ( pi * x [1])); default : return -pi *( sin ( pi * x [0])* sin ( pi * x [1]) + sin ( pi * x [1])* sin ( pi * x [2]) + sin ( pi * x [2])* sin ( pi * x [0])); }} g ( size_t d1 ) : d ( d1 ) , pi ( acos ( Float ( -1.0))) {} size_t d ; const Float pi ; };

File

  const point & x ) { return 1; } Float g ( const point & x ) { return -0.5/ d ; } int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); geo omega ( argv [1]); d = omega . dimension (); space Xh ( omega , argv [2]); trial u ( Xh ); test v ( Xh ); form a = integrate ( dot ( grad ( u ) , grad ( v ))); field b = integrate ( v ); field lh = integrate ( f * v ) + integrate ( " boundary " , g * v

Figure 1

 1 Figure 1.10: Transmission problem: the domain Ω partition: (Ω west and Ω east ).

Figure 1 . 11 :

 111 Figure 1.11: Transmission problem with ε = 10 -2 , d = 1, P 1 approximation. to the commands: mkgeo_grid -t 10 -region > square.geo geo square.geo ./transmission square.geo P1 > square.field field square.field -elevation

  Figure 2.1: The boundary domains for the square and the cube.

File

  Xh ); test v ( Xh ); form a = integrate ( lambda * div ( u )* div ( v ) + 2* ddot ( D ( u ) , D ( v ))); field lh = integrate ( dot (f , v )); field uh ( Xh , 0); problem p ( a );

Figure 2 . 2 :

 22 Figure 2.2: The linear elasticity for λ = 1 and d = 2 and d = 3: both wireframe and filled surfaces ; stereoscopic anaglyph mode for 3D solutions.

  field square-P1.field field square-P1.field -nofill It bases on the default paraview render for 2D and 3D geometries. The view is shown on Fig. 2.2. If you are in trouble with paraview, you can switch to the simpler gnuplot render: field square-P1.field -nofill -gnuplot

Figure 2

 2 Figure 2.3: The stress tensor visualization (linear elasticity λ = 1).

Figure 2

 2 Figure 2.4: The σ 01 stress component (linear elasticity λ = 1): d = 2 (top) and d = 3 (bottom) ; P 0 (left) and P 1 discontinuous approximation (right).

File

  i = 0; true ; i ++) { space Xh = embankment_space ( omega , approx ); field uh = elasticity_solve ( Xh , lambda ); odiststream of ( omega . name () , " field " ); of << catchmark ( " lambda " ) << lambda << endl << catchmark ( " u " ) << uh ; if ( i == n_adapt ) break ; field ch = elasticity_criterion ( lambda , uh ); omega = adapt ( ch , options ); odiststream og ( omega . name () , " geo " elasticity_criterion.icc field elasticity_criterion ( Float lambda , const field & uh ) { string grad_approx = " P " + to_string ( uh . get_space (). degree () -1) + " d " ; space Xh ( uh . get_geo () , grad_approx ); if ( grad_approx == " P0d " ) return lazy_interpolate ( Xh , norm ( uh )); space T0h ( uh . get_geo () , grad_approx ); size_t d = uh . get_geo (). dimension (); tensor I = tensor :: eye ( d ); return lazy_interpolate ( T0h , sqrt (2* norm2 ( D ( uh )) + lambda * sqr ( div ( uh )))); }

  Figure 2.5: Adapted meshes: the deformation visualization for P 1 and P 2 approximations.

Formulation

  Let us consider the Stokes problem for the driven cavity in Ω =]0, 1[ d , d = 2, 3. The problem writes:

Figure 2

 2 Figure 2.6: The velocity visualization for d = 2 and d = 3 with stereo anaglyph.

For d = 2 ,

 2 Figure 2.7: The vorticity: elevation view for d = 2 and vector representation for d = 3 (with anaglyph).

Figure 2

 2 Figure 2.8: The stream function visualization: isolines for d = 2, and combined vectors and isonorm surface for d = 3. For d = 2, just enter (see Fig. 2.8 left): make streamf_cavity ./streamf_cavity < square.field | field -bw -

Figure 2 . 9 :

 29 Figure 2.9: The incompressible linear elasticity (λ = +∞) for N = 2 and N = 3.

  form a1 = integrate (2* ddot ( D ( u1 ) , D ( v1 ))); integrate_option iopt ; iopt . invert = true ; form inv_ab = integrate (2* ddot ( D ( ub ) , D ( vb )) , iopt ); form c = bb * inv_ab * trans ( bb ); field u1h = contraction :: velocity_field ( X1h ); field ph ( Qh , 0); problem_mixed stokes ( a1 , b1 , c ); stokes . solve ( field ( X1h ,0) , field ( Qh ,0) , u1h , ph ); dout << catchmark ( " inv_lambda " ) << 0 << endl << catchmark ( " u " ) << u1h << catchmark ( " p " ) << ph ; = true ; form inv_ab = integrate (2* ddot ( D ( ub ) , D ( vb )) , iopt ); Note the usage of the optional parameter iopt to the integrate function. As the form is blocdiagonal, its inverse is computed element-by-element during the assembly process. Next, the C = B b A -1 b B T b form is simply computed as: form c = bb * inv_ab * trans ( bb );

}

  struct psi_upstream : base { psi_upstream ( geo omega ) : base ( omega ) {} Float operator () ( const point & x ) const { Float y = ( x [1]/ base :: c ); if ( base :: cartesian ) { return ( base :: umax * base :: c )*( y *(1 -sqr ( y )/3) -2./3);

  Figure 2.10: Solution of the Stokes problem in the abrupt contraction: (top) the mesh; (center) the P 1 stream function associated to the P 1 b-P 1 element; (bottom) the P 2 stream function associated to the P 2 -P 1 Taylor-Hood element.

Figure 2 . 11 :

 211 Figure 2.11: Solution of the axisymmetric Stokes problem in the abrupt contraction: (top) the P 2 stream function associated to the P 2 -P 1 element; (bottom) comparison with the 2D Cartesian solution (in red).

Figure 2 .

 2 Figure 2.13: Slip boundary conditions for the flow around an obstacle.

File 2 .File

 2 15: stokes_obstacle_slip_regul.cc # include " rheolef . h " using namespace rheolef ; using namespace std ; point n_exact ( const point & x ) { return -x ; } int main ( int argc , char ** argv ) eps )* integrate ( " obstacle " , dot (u , n_exact )* dot (v , n_exact )); form b = integrate ( -div ( u )* q ); field uh ( Xh ,0); uh [0][ " downstream " ] = 1; field ph ( Qh , 0); problem_mixed stokes (a , b ); stokes . solve ( field ( Xh ,0) , field ( Qh ,0) , uh , ph ); dout << catchmark ( " u " ) << uh << catchmark ( " p " ) << ph ; } ( uh . get_space () , e0 -uh ); string approx = " P " + to_string ( uh . get_space (). degree ()); const geo & omega = uh . get_geo (integrate ( dot ( grad ( psi ) , grad ( xi )) , iopt ); field lh = integrate ( dot ( uh , bcurl ( xi ))); problem p ( a ); p . solve ( lh , psi_h ); dout << catchmark ( " psi " ) << psi_h ; } How to run the program

Figure 2 .

 2 Figure 2.14: Slip boundary conditions for the flow around a cylinder (left) and sphere (right): isovalues of the stream function. The run is detailed in the axisymmetric case. The mkgeo_obstacle script generates the mesh of the geometry: mkgeo_obstacle -zr -name obstacle-zr geo obstacle-zr.geo Then the compilation and run writes: make stokes_obstacle_slip_regul ./streamf_obstacle_slip_move ./stokes_obstacle_slip_regul obstacle-zr > obstacle-zr.field field -velocity obstacle-zr.field ./streamf_obstacle_slip_move < obstacle-zr.field | field -bw -n-iso 25 -Observe on Fig. 2.14 that the trajectories, as represented by the stream function, differ in the Cartesian an axisymmetric cases.

Figure 2

 2 Figure 2.15: Slip boundary conditions for the flow around an obstacle: horizontal relative velocity along the two axis: (left) along Ox 1 on the top of the obstacle ; (right) along Ox 0 on the front.

File

  lazy_interpolate ( Xh , phi (d , nu ,0)); characteristic X ( -delta_t * uh ); integrate_option iopt ; iopt . set_family ( integrate_option :: gauss_lobatto ); iopt . set_order ( Xh . degree ()); trial phi ( Xh ); test psi ( Xh ); branch event ( " t " ," phi " ); dout << catchmark ( " nu " ) << nu << endl << event (0 , phi_h ); for ( size_t n = 1; n <= n_max ; n ++) { Float t = n * delta_t ; Float c1 = 1 + delta_t * phi :: sigma (d , nu , t ); Float c2 = delta_t * nu ; form a = integrate ( c1 * phi * psi + c2 * dot ( grad ( phi ) , grad ( psi )) , iopt ); field lh = integrate ( compose ( phi_h , X )* psi , iopt )

  return point ( u0 ); return point ( -x0 [0]* sin ( t ) + x0 [1]* cos ( t ) , -x0 [0]* cos ( t ) -x0 [1]* sin ( t )); } protected : size_t d ; Float nu , t , u0 ; point x0 ; static constexpr Float t0 = 0.2; };

Figure 2 .

 2 Figure 2.17: Animation of the solution of the rotating hill problem.

File 2 .

 2 20: convect_error.cc # include " rheolef . h " using namespace rheolef ; using namespace std ; # include " rotating -hill . h " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); Float tol = ( argc > 1) ? atof ( argv [1]) : 1e -10;

  t = 0 , t_prec = 0; din >> get (t , phi_h ); t_prec = t ) { const space & Xh = phi_h . get_space (); size_t d = Xh . get_geo (). dimension (); field pi_h_phi = lazy_interpolate ( Xh , phi (d , nu , t )); trial phi ( Xh ); test psi ( Xh ); form m = integrate ( phi * psi ); field eh = phi_h -pi_h_phi ; Float err_l2 = sqrt ( m ( eh , eh )); Float err_linf = eh . max_abs (); err_l2_l2 += sqr ( err_l2 )*( t -t_prec ); err_linf_linf = max ( err_linf_linf , err_linf ); dout << put (t , phi_h , pi_h_phi ); derr << t << " \ t " << err_l2 << " \ t " << err_linf << endl ; } derr << " # error_l2_l2 = " << sqrt ( err_l2_l2 ) << endl ; derr << " # error_linf_linf = " << err_linf_linf << endl ; return ( err_linf_linf <= tol ) ? 0 : 1; }

Figure 2

 2 Figure 2.18: Diffusion-convection when d = 1 and ν = 10 -2 : convergence versus h and ∆t for P 1 and P 2 elements: (left) in L 2 (L 2 ) norm; (right) in L ∞ (L ∞ ) norm.

Formulation

  This longer example combines most functionalities presented in the previous examples. Let us consider the Navier-Stokes problem for the driven cavity in Ω =]0, 1[ d , d = 2, 3. Let Re > 0 be the Reynolds number, and T > 0 a final time. The problem writes:

FileComments

  delta_t , field l0h , field & uh , field & ph , size_t & max_iter , Float & tol , odiststream * p_derr =0) { const space & Xh = uh . get_space (); const space & Qh = ph . get_space (); string label = " navier -stokes -" + Xh . get_geo (). name (integrate ( dot (u , v ) , iopt ); form a = integrate (2* ddot ( D ( u ) , D ( v )) + 1.5*( Re / delta_t )* dot (u , v ) , iopt ); form b = integrate ( -div ( u )* q , iopt ); problem_mixed stokes (a , b ); if ( p_derr != 0) * p_derr << " [ " << label << " ] # n | du / dt | " << endl ; field uh1 = uh ; for ( size_t n = 0; true ; n ++) { field uh2 = uh1 ; uh1 = uh ; field uh_star = 2.0* uh1 -uh2 ; characteristic X1 ( -delta_t * uh_star ); characteristic X2 ( -2.0* delta_t * uh_star ); field l1h = integrate ( dot ( compose ( uh1 , X1 ) , v ) , iopt ); field l2h = integrate ( dot ( compose ( uh2 , X2 ) , v ) , iopt ); field lh = l0h + ( Re / delta_t )*(2* l1h -0.5* l2h ); stokes . solve ( lh , field ( Qh ,0) , uh , ph ); field duh_dt = (3* uh -4* uh1 + uh2 )/(2* delta_t ); Float residual = sqrt ( m ( duh_dt , duh_dt )); if ( p_derr != 0) * p_derr << " [ " << label << " ] " << n << " " << residual << endl ; The navier_stokes_solve function is similar to the 'stokes_cavity.cc'. It solves here a generalized Stokes problem and manages a right-hand side f h : characteristic X1 ( -delta_t * uh_star ); characteristic X2 ( -2.0* delta_t * uh_star ); field l1h = integrate ( compose ( uh1 , X1 )* v , iopt ); field l2h = integrate ( compose ( uh2 , X2 )* v , iopt ); field lh = l0h + ( Re / delta_t )*(2* l1h -0.5* l2h );This last computation is similar to those done in the 'convect.cc' example. The generalized Stokes problem is solved by the solver_abtb class. The stopping criterion is related to the stationary solution or the maximal iteration number.

File

  n a vi er _ st ok es _ cr it er i on . icc " # include " cavity . h " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); if ( argc < 2) { cerr << " usage : " << argv [0] << " <geo > <Re > <err > < n_adapt > " << endl ; cavity :: velocity_space ( omega , " P2 " ); space Qh ( omega , " P1 " ); field uh = cavity :: velocity_field ( Xh , 1.0Re , delta_t , fh , uh , ph , max_iter , tol , & derr ); odiststream o ( omega . name () , " field " ); o << catchmark ( " Re " ) << Re << endl << catchmark ( " delta_t " ) << delta_t << endl << catchmark ( " u " ) << uh << catchmark ( " p " ) << ph ; o . close (); if ( i >= n_adapt ) break ; field ch = n av i er _s t ok es _c r it er io n ( Re , uh ); omega = adapt ( ch , options ); o . open ( omega . name () , " geo " ); o << omega ; o . close (); Xh = cavity :: velocity_space ( omega , " P2 " ); Qh = space ( omega , " P1 " ); uh = cavity :: velocity_field ( Xh , 1.023: navier_stokes_criterion.icc field na v ie r_ st o ke s_ cr i te ri on ( Float Re , const field & uh ) { space T0h ( uh . get_geo () , " P1d " ); return lazy_interpolate ( T0h , sqrt ( Re * norm2 ( uh ) + 4* norm2 ( D ( uh )))); }

Re = 100 :

 100 Figure 2.19: Meshes and stream functions associated to the solution of the Navier-Stokes equations for Re = 100 (top) and Re = 400 (bottom).

  Figure 2.20: Meshes and stream functions associated to the solution of the Navier-Stokes equations for Re = 1000.

Figure 2

 2 Figure 2.21: Navier-Stokes: velocity profiles along lines passing thought the center of the cavity, compared with data from Ghia et al. [1982]: (a) u 0 along the vertical line; (b) u 1 along the horizontal line line.

File

  sphere . icc " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); geo gamma ( argv [1]); size_t d = gamma . dimension (); space Wh ( gamma , argv [2]); trial u ( Wh ); test v ( Wh ); form a = integrate ( u * v + dot ( grad_s ( u ) , grad_s ( v )

  const point & x ) { return norm ( x ) -1; }

Figure 3

 3 Figure 3.1: Helmholtz-Beltrami problem: high-order curved surface mesh and its corresponding isoparametric solution: (top) order = 1; (bottom) order = 3. Higher-order isoparametric finite elements can be considered for the curved geometry: mkgeo_ball -s -e 30 -order 3 > circle-P3.geo geo circle-P3.geo -subdivide 10 Observe the curved edges (see Fig .3.1). The -subdivide option allows a graphical representation of the curved edges by subdividing each edge in ten linear parts, since graphical softwares are not yet able to represent curved elements. The computation with the P 3 isoparametric approximation writes:

Figure 3 . 2 :

 32 Figure 3.2: Curved non-polynomial surface: error analysis in L 2 , L ∞ and H 1 norms.

FileFile

  Bh . get_space () , 0); A . set_symmetry ( true ); problem pa ( A ); pa . solve ( Bh , Uh ); dout << Uh [0]; } sqrt ( sqr ( x [0])+ sqr ( x [1])) -sqr ( R )) + sqr ( x [2]) -sqr ( r ); } void g et_ torus_ coord inates ( const point & x , Float & rho , Float & theta , Float & phi ) { static const Float pi = acos ( Float ( -1)); rho = sqrt ( sqr ( x [2]) + sqr ( sqrt ( sqr ( x [0

  theta , phi ; g e t _ torus _coor dinate s (x , rho , theta , phi ); return sin (3* phi )* cos (3* theta + phi )operator () ( const point & x ) const { Float rho , theta , phi ; g e t _ torus _coor dinate s (x , rho , theta , phi ); Float fx = (9* sin (3* phi )* cos (3* theta + phi ))/ sqr ( r ) -( -10* sin (3* phi )* cos (3* theta + phi ) -6* cos (3* phi )* sin (3* theta + phi )) / sqr ( R + r * cos ( theta )) -(3* sin ( theta )* sin (3* phi )* sin (3* theta + phi ))

Figure 3

 3 Figure 3.3: Laplace-Beltrami problem on a torus: high-order curved surface mesh and its corresponding isoparametric solution: (top) order = 1; (bottom) order = 2.

  File 3.5: level_set_sphere.cc # include " rheolef . h " using namespace rheolef ; using namespace std ; # include " sphere . icc " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); geo lambda ( argv [1]); level_set_option opts ; opts . split_to_triangle = ( argc > 2 && argv [2] == std :: string ( " -tq " )) ? false : true ; space Xh ( lambda , " P1 " ); field phi_h = lazy_interpolate ( Xh , phi ); geo gamma = level_set ( phi_h , opts ); dout << gamma ; } Comments All the difficult work of building the intersection mesh Γ h , defined as the zero level set of the ϕ h function, is performed by the level_set function: geo gamma = level_set ( phi_h , opts ); When d = 3, intersected tetrahedra leads to either triangular or quadrangular faces. By default, quadrangular faces are split into two triangles. An optional -tq program flag allows one to conserve quadrangles in the surface mesh: it set the split_to_triangle optional field to false. How to run the program ? After the compilation, generates the mesh of a bounding box Λ = [-2, 2] d of the surface and run the program: make level_set_sphere mkgeo_grid -t 20 -a -2 -b 2 -c -2 -d 2 > square2.geo ./level_set_sphere square2.geo > circle.geo geo circle.geo -gnuplot

Figure 3

 3 Figure 3.4: Building an explicit surface mesh from level set: (top) circle; (center) sphere; (bottom) torus.

  How to run the program make laplace_band mkgeo_grid -T 20 -a -2 -b 2 -c -2 -d 2 -f -2 -g 2 > cube-20.geo ./laplace_band cube-20.geo > torus-band.field ./proj_band < torus-band.field | field -stereo -The solution is represented on Fig. 3.5.bottom.

Figure 3 Figure 3

 33 Figure 3.5: The banded level set method: (top) circle; (center) sphere; (bottom) torus.

  form m = integrate ( u * v ); problem pm ( m ); field uh ( Xh ) , uh_star ( Xh , 0.); uh [ " boundary " ] = uh_star [ " boundary " ] = 0; field lh = integrate ( v ); dirichlet ( lh , uh ); derr << " # n r v " << endl ; Float r = 1 , r0 = 1; size_t n = 0; do { form a = integrate ( compose ( eta ( p ) , norm2 ( grad ( uh )))* dot ( grad ( u ) , grad ( v ))); field mrh = a * uh -lh ; field rh ( Xh , 0); pm . solve ( mrh , rh ); r = rh . max_abs (); if ( n == 0) { r0 = r ; } Float v = ( n == 0) ? 0 : log10 ( r0 / r )/ n ; derr << n << " " << r << " " << v << endl ; if ( r <= tol || n ++ >= max_it ) break ; problem p ( a ); p . solve ( lh , uh_star ); uh = w * uh_star + (1 -w )* uh ; } while ( true ); dout << catchmark ( " p " ) << p << endl << catchmark ( " u " ) << uh ; return ( r <= tol ) ? 0 : 1; } Comments The implementation with Rheolef involves a weighted forms: the tensor-valued weight η ∇u (n) h 2 is inserted in the variational expression passed to the integrate function. The construction of the weighted form a(.; ., .) writes:form a = integrate( compose ( eta ( p ) , norm2 ( grad ( uh )))* dot ( grad ( u ) , grad ( v )));

File 3. 11 :

 11 eta.h struct eta { Float operator () ( const Float & z ) const { check_macro ( z != 0 || p > 2 , " eta : division by zero ( HINT : check mesh ) " ); return pow (z , (p -2)/2); } Float derivative ( const Float & z ) const { check_macro ( z != 0 || p > 4 , " eta ': division by zero ( HINT : check mesh ) " ); return 0.5*( p -2)* pow (z , (p -4)/2); } eta ( const Float & q ) : p ( q ) {} Float p ; };

File 3. 12 :

 12 dirichlet.icc void dirichlet ( const field & lh , field & uh ) { const space & Xh = lh . get_space (); trial u ( Xh ); test v ( Xh ); form a = integrate ( dot ( grad ( u ) , grad ( v ))); problem p ( a ); p . solve ( lh , uh ); } Running the program Compile the program, as usual: make p_laplacian_fixed_point and enter the commands: mkgeo_ugrid -t 50 > square.geo geo square.geo

Figure 3

 3 Figure 3.7: The p-Laplacian for d = 2: elevation view for p = 1.25 (left), p = 2 (center) and p = 2.5 (right).

  For clarity, let us drop temporarily the n index of the current iteration. The field r h ∈ V h can be extended as a field r h ∈ X h with vanishing components on the boundary. The previous relation writes, after expansion of the bilinear forms and fields on the unknown and blocked parts (see page 16 for the notations): m.uu*rh.u = a.uu*uh.u + a.ub*ub.b -lh.u rh.b = 0

Figure 3

 3 Figure 3.8: The fixed-point algorithm on the p-Laplacian for d = 2: when p = 3/2, independence of the convergence properties of the residue (top-left) with mesh refinement; (top-right) with polynomial order P k ; when h = 1/50 and k = 1, convergence (bottom-left) for p > 2 and (bottomright) for p < 2.

Fig 3

 3  shows that the residual term decreases exponentially versus n, since the slope of the plot in semi-log scale tends to be strait. Moreover, observe that the slope is independent of the mesh size h. Also, by virtue of the previous careful definition of the residual term and its corresponding norm, all the slopes falls into a master curve. These invariance properties applies also to the polynomial approximation P k : Fig 3.8.top-right shows that all the curves tends to collapse when k increases. Thus, the convergence properties of the algorithm are now investigated on a fixed mesh h = 1/50 and for a fixed polynomial approximation k = 1. Fig 3.8.bottom-left and 3.8.bottom-right show the convergence versus the power-law index p: observe that the convergence becomes easier when p approaches p = 2, where the problem is linear. In that case, the convergence occurs in one iteration. Nevertheless, it appears two limitations. From one hand, when p → 3 the convergence starts to slow down and p ⩾ 3 cannot be solved by this algorithm (it will be solved later in this chapter). From other hand, when p → 1, the convergence slows down too and numerical rounding effets limits the convergence: the machine precision canot be reached. Let us introduce the convergence rate v n = log 10 (r n /r 0 )/n it tends to

  Figure 3.9: The fixed-point algorithm on the p-Laplacian for d = 2: (left) convergence rate versus p; (right) convergence rate versus p in semi-log scale. a constant, denoted as v and: r n ≈ r 0 × 10 -v n . Observe on Fig 3.9.left that v tends to +∞ when p = 2, since the system becomes linear and the algorithm converge in one iteration. Observe also that v tends to zero for p = 1 and p = 3 since the algorithm diverges. Fig 3.9.right shows the same plot in semi-log scale and shows that v behaves as: v ≈ -log 10 |p -2|. This study shows that the residual term of the fixed point algorithm behaves as:

v

  Figure 3.10: The fixed-point algorithm on the p-Laplacian for d = 2: effect of the relaxation parameter ω (top-left) when p < 2; (top-right) when p > 2; (bottom-left) optimal ω opt ; (bottomright) optimal vopt .

  File 3.15: p_laplacian1.icc # include " eta . h " # include " nu . h " # include " dirichlet . icc " p_laplacian :: p_laplacian ( Float p1 , const geo & omega , string approx ) : p ( p1 ) , Xh () , lh () , m () , pm () , a1 () , pa1 () { Xh = space ( omega , approx ); Xh . block ( " boundary " ); trial u ( Xh ); test v ( Xh ); lh = integrate ( v ); m = integrate ( u * v ); pm = problem ( m ); } field p_laplacian :: initial () const { field uh ( Xh , 0); dirichlet ( lh , uh ); return uh ; } field p_laplacian :: residue ( const field & uh ) const { trial u ( Xh ); test v ( Xh ); form a = integrate ( compose ( eta ( p ) , norm2 ( grad ( uh )))* dot ( grad ( u ) , grad ( v ))); field mrh = a * uh -lh ; mrh . set_b () = 0; return mrh ; } void p_laplacian :: update_derivative ( const field & uh ) const { size_t d = Xh . get_geo (). dimension (); trial u ( Xh ); test v ( Xh ); a1 = integrate ( dot ( compose ( nu < eta >( eta ( p ) , d ) , grad ( uh ))* grad ( u ) , grad ( v ))); pa1 = problem ( a1 ); } field p_laplacian :: derivative_solve ( const field & rh ) const { field delta_uh ( Xh ,0); pa1 . solve ( rh , delta_uh ); return delta_uh ; }

File 3 .

 3 16: p_laplacian2.icc field p_laplacian :: deriv ative _trans _mult ( const field & mrh ) const { field rh ( Xh , 0); pm . solve ( mrh , rh ); field mgh = a1 * rh ; mgh . set_b () = 0; return mgh ; } Float p_laplacian :: space_norm ( const field & uh ) const { return sqrt ( m ( uh , uh )); } Float p_laplacian :: dual_space_norm ( const field & mrh ) const { field rh ( Xh , 0); pm . solve ( mrh , rh ); return sqrt ( dual ( mrh , rh )); } The ν function is implemented for a generic η function, as a class-function that accept as template agument another class-function. File 3.17: nu.h template < class Function > struct nu { tensor operator () ( const point & grad_u ) const { Float x2 = norm2 ( grad_u ); Float a = f ( x2 ); Float b = 2* f . derivative ( x2 ); tensor value ; for ( size_t i = 0; i < d ; i ++) { value (i , i ) = a + b * grad_u [ i ]* grad_u [ i ]; for ( size_t j = 0; j < i ; j ++) value (j , i ) = value (i , j ) = b * grad_u [ i ]* grad_u [ j square.geo P1 3 > square.field field square.field -elevation -stereo

Figure 3 . 11 :

 311 Figure 3.11: The Newton algorithm on the p-laplacian for d = 2: comparison with the fixed-point algorithm.

Figure 3 . 12 :

 312 Figure 3.12: The Newton algorithm on the p-Laplacian for d = 2: (top-left) comparison with the fixed-point algorithm; when p = 3, independence of the convergence properties of the residue (topleft) with mesh refinement; (top-right) with polynomial order P k ; (bottom-left) mesh-dependence convergence when p < 2; (bottom-right) overshoot when p > 2.

File

  > 4) ? atof ( argv [4]) : eps ; size_t max_iter = ( argc > 5) ? atoi ( argv [5]) : 500; derr << " # P -Laplacian problem by damped Newton : " << endl << " # geo = " << omega . name () << endl << " # approx = " << approx << endl << " # p = " << p << endl ; p_laplacian F (p , omega , approx ); field uh = F . initial (); int status = damped_newton (F , uh , tol , max_iter , & derr ); dout << catchmark ( " p " ) << p << endl << catchmark ( " u " ) << uh ; return status ; }CommentsThe damped_newton function implements the damped Newton algorithm for a generic T (u) function, i.e. a generic nonlinear preconditioner. This algorithms use a backtrack strategy implemented in the file 'newton-backtrack.h' of the Rheolef library. The simplest choice of the identity preconditioner C

Figure 3 .

 3 Figure 3.13: The p-Laplacian for d = 2: elevation view for p = 1.15 (left) and p = 7 (right).

Figure 3 .

 3 Figure 3.14: The damped Newton algorithm on the p-Laplacian for d = 2: when p = 1.5 and h = 1/50, convergence properties of the residue (top-left) with mesh refinement; (top-right) with polynomial order P k ; (bottom-left) convergence when p < 2; (bottom-right) when p > 2.

Figure 3 .File

 3 Figure 3.15: The p-Laplacian for d = 2: error analysis.

FileFile

  geo & omega = geo () , string approx = " " ); void reset ( const geo & omega , string approx ); field initial ( std :: string restart = " " ); idiststream & get ( idiststream & is , field & uh ); odiststream & put ( odiststream & os , const field & uh ) const ; string parameter_name () const { return " lambda " ; } float_type parameter () const { return lambda ; } void set_parameter ( float_type lambda1 ) { lambda = lambda1 ; } bool stop ( const field & xh ) const { return xh . max_abs () > 10; } field residue ( const field & uh ) const ; form derivative ( const field & uh ) const ; field d e r i v a t i v e _ v e r s u s _ p a r a m e t e r ( const field & uh ) const ; problem :: determinant_type update_derivative ( const field & uh ) const ; field derivative_solve ( const field & mrh ) const ; field d erivat ive_t rans_m ult ( const field & mrh ) const ; field massify ( const field & uh ) const { return m * uh ; } field unmassify ( const field & uh ) const ; float_type space_dot ( const field & xh , const field & yh ) const ; float_type dual_space_dot ( const field & mrh , const field & msh ) const ; 23: combustion2.icc field combustion :: residue ( const field & uh ) const { test v ( Xh ); field mrh = integrate ( dot ( grad ( uh ) , grad ( v )) -lambda * exp ( uh )* v derivative ( const field & uh ) const { trial du ( Xh ); test v ( Xh ); return integrate ( dot ( grad ( du ) , grad ( v )) -lambda * exp ( uh )* du * v : d e r i v a t i v e _ v e r s u s _ p a r a m e t e r ( const field & uh ) const { test v ( Xh ); return -integrate ( exp ( uh )* v ); } field combustion :: derivative_solve ( const field & rh ) const : space_dot ( const field & xh , const field & yh ) const { return m ( xh , yh ); } Float combustion :: dual_space_dot ( const field & mrh , const field & msh ) const { return dual ( unmassify ( mrh ) , msh ); } residue = tol ; size_t n_iter = max_iter ; damped_newton (F , uh , residue , n_iter , & derr ); F . put ( dout , uh ); return ( residue <= sqrt ( tol )) ? 0 : 1; } Let us choose α = 1/2 and λ = 8(α/ cosh(α)) 2 ≈ 1.57289546593186. Compilation and run are: make combustion_newton mkgeo_grid -e 10 > line-10.geo ./combustion_newton line-10 P1 1.57289546593186 > line-10.field field line-10.field

File

  const Float & a ) const { return tanh ( a ) -1/ a ; } void update_derivative ( const Float & a ) const { _f1 = 1/ sqr ( cosh ( a )) + 1/ sqr ( a ); } Float derivative_solve ( const Float & r ) const { return r / _f1 ; } Float dual_space_norm ( const Float & r ) const { return abs ( r newton ( alpha_c_fun () , ac , tol , max_iter ); return ac ; } Float lambda_c () { Float ac = alpha_c (); return 8* sqr ( ac / cosh ( ac )); } File 3.26: lambda_c.cc # include " rheolef . h " using namespace rheolef ; using namespace std ; # include " lambda_c . h " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); dout << setprecision ( numeric_limits < Float >:: digits10 ) << " alpha_c = " << alpha_c () << endl << " lambda_c = " << lambda_c () << endl ; } Compilation and run write: make lambda_c ./lambda_c and then α c ≈ 1.19967864025773 and λ c ≈ 3.51383071912516. The exact solution and its gradient at the limit point are computed by the following functions: File 3.27: combustion_exact.icc # include " lambda2alpha . h " struct u_exact { Float operator () ( const point & x ) const { return 2* log ( cosh ( a )/ cosh ( a *(1 -2* x [0]))); } u_exact ( Float lambda , bool is_upper ) ) ( const point & x ) const { return point (4* a * tanh ( a *(1 -2* x [0]))); } grad_u ( Float lambda , bool is_upper ) : a ( lambda2alpha ( lambda , is_upper )) {} grad_u ( Float a1 ) : a ( a1 ) {} Float a ; };

File 3 .FileFloat

 3 Figure 3.16: Combustion problem: (left) α = 1/2. (right) near α c .

File

  ( numeric_limits < Float >:: digits10 ) << " # continuation in lambda : " << endl << " # geo = " << omega . name () << endl << " # approx = " << approx << endl << " # dlambda_ini = " << opts . ini_delta_parameter << endl << " # dlambda_min = " << opts . min_delta_parameter << endl << " # dlambda_max = " << opts . max_delta_parameter << endl << " # tol = " << opts . tol << endl ; combustion F ( omega , approx ); field uh = F . initial (); F . put ( dout , uh ); continuation (F , uh , & dout , & derr , opts ); } Then, the program is compiled and run as: make combustion_continuation mkgeo_grid -e 10 > line-10.geo ./combustion_continuation line-10 > line-10.branch branch line-10.branch -toc

Figure 3 .

 3 Figure 3.18: Combustion problem: (left) convergence of |λ c,h -λ c | vs h ; (right) convergence of |u h -u| vs h at the limit point.as O(h 2k ) while |u h -u| = O(h k ). When k = 3, the convergence of λ c,h slows down around 10 -9 : this is due to the stopping criterion of the Newton method that detects automatically the propagation of rounding effects in the resolution of linear systems. Observe on Fig.3.19 the plot

Figure 3 .

 3 Figure 3.19: Combustion problem: det ∂F ∂u (λ, u h ) versus λ c,h -λ for various h and k = 1.

Figure 3

 3 Figure 3.20: Combustion problem: (left) ∥u h ∥ 0,∞,Ω vs λ when h = 1/10 and 1/80. The full branch of solutions when λ ⩾ 0, with the limit point and the upper part of the branch. (right) solution of the upper branch when λ = 10 -2 .

  branch line-20.branch -toc branch line-20.branch -extract 41 -branch | ./combustion_error 1 Please, replace 41 by the last computed index on the branch. Fig. 3.20.right represents this solution and compares it ith the exact one. Observe the excellent agreement. File 3.32: combustion_keller_post.cc # include " rheolef . h " using namespace rheolef ; using namespace std ; # include " combustion . h " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); string metric ; din >> catchmark ( " metric " ) >> metric ; keller < combustion > F ( combustion () , metric ); keller < combustion >:: value_type xh , dot_xh ; dout << noverbose << setprecision ( numeric_limits < Float >:: digits10 ) << " # metric " << metric << endl << " # s lambda umax det ( mantissa , base , exp ) | u | | grad ( u )| | residue | " << endl ; for ( size_t n = 0; F . get ( din , xh ); ++ n ) { problem :: determinant_type det ; if ( n > 0 || metric != " spherical " ) det = F . update_derivative ( xh ); const space & Xh = xh . second . get_space (); trial u ( Xh ); test v ( Xh ); form a = integrate ( dot ( grad ( u ) , grad ( v ))) , m = integrate ( u * v ); const combustion & F0 = F . get_problem (); field mrh = F0 . residue ( xh . second ); dout << F . parameter () << " " << xh . first << " " << xh . second . max_abs () << " " << det . mantissa << " " << det . base << " " << det . exponant << " " << sqrt ( m ( xh . second , xh . second )) << " " << sqrt ( a ( xh . second , xh . second ))<< " " << sqrt ( F0 . dual_space_dot ( mrh , mrh ))

File

  Fig. 4.2 plots the solution when d = 1 and k = 0: observe that the boundary condition ϕ = 1 at x 0 = 0 is only weakly satisfied. It means that the approximation ϕ h (0) tends to 1 when h tends to zero. Fig.4.3 plots the error ϕ -ϕ h in L 2 and L ∞ norms: these errors behave as O h k+1 for all k ⩾ 0, which is optimal. A theoretical O h k+1/2 error bound was shown by[START_REF] Johnson | An analysis of the discontinuous Galerkin method for a scalar hyperbolic equation[END_REF]. The present numerical results confirm that these theoretical error bounds can be improved for some families of meshes, as pointed out by[START_REF] Richter | An optimal-order error estimate for the discontinuous galerkin method[END_REF], that showed a O h k+1 optimal bound for the transport problem. This result was recently extended byCockburn et al.

Figure 4

 4 Figure 4.2: The discontinuous Galerkin method for the transport problem when k = 0 and d = 1.

Figure 4 . 3 :

 43 Figure 4.3: The discontinuous Galerkin method for the transport problem: convergence when d = 2.

Figure 4 . 4 :

 44 Figure 4.4: Zalesak slotted disk: elevation view of the interpolated level set function (upside-down), together with its zero level set, in black thick line.

Figure 4

 4 Figure 4.5: Zalesak slotted disk: superposition of the initial disk (black) and after a period (red). Polynomial degree k = 2, time step ∆t = 4π/6000, implicit BDF(3) scheme with a fixed mesh h = 1/100. On the right: zoom.

File

  ( argc > 4) ? string ( argv [4]) == " true " : false ; size_t p = ( argc > 5) ? atoi ( argv [5]) : min ( Xh . degree ()+1 , bdf :: pmax ); size_t d = omega . dimension (); Float tf = u :: period () , delta_t = tf / n_max ; trial phi ( Xh ); test xi ( Xh ); branch event ( " t " ," phi " ); vector < field > phi_h ( p +1); phi_h [0] = phi_h [1] = lazy_interpolate ( Xh , phi0 ( d )); dout << event (0 , phi_h [0]); for ( size_t n = 1; n <= n_max ; n ++) { Float t = n * delta_t ; if ( n % 10 == 0) derr << " [ " << n << " ] " ; size_t pn = min (n , p ); form an = integrate (( bdf :: alpha [ pn ][0]/ delta_t * phi + dot ( u (d , t ) , grad_h ( phi )))* xi ) + integrate ( " internal_sides " , -dot ( u (d , t ) , normal ())* jump ( phi )* average ( xi ) + 0.5* abs ( dot ( u (d , t ) , normal ()))* jump ( phi )* jump ( xi )); field rhs ( Xh , 0); for ( size_t i = 1; i <= pn ; i ++) rhs += ( bdf :: alpha [ pn ][ i ]/ delta_t )* phi_h [ i ]; field lh = integrate ( rhs * xi ); problem pb ( an ); pb . solve ( lh , phi_h [0]); check_macro ( phi_h [0]. max_abs () < 100 , " BDF failed --HINT : decrease delta_t " ); if (! strip || n == n_max ) dout << event (t , phi_h [0]); for ( size_t i = min (p , pn +1); i >= 1; i --) phi_h [ i ] = phi_h [i -1]; } derr << endl ; } Comments Numerical computations are performed on the time interval [0, T ] with a time step ∆t = T /n max

Figure 4 . 6 :

 46 Figure 4.6: Leveque vortex-in-box: approximation with h = 1/100, k = 2, p = 3 and ∆t = 4π/6000. (left) solution at half period : the deformation is maximal ; (right) after a full period : comparison with the initial shape, in red.

  2, 3 and the initial condition u 0 being known. As usual, n denotes the outward unit normal on the boundary ∂Ω. The function f : R -→ R d is also known and supposed to be continuously differentiable. The initial data u 0 , defined in Ω, and the boundary one, g, defined on ∂Ω are given. The function Φ, called the Godunov flux associated to f , is defined, for all ν ∈ R d and a, b ∈ R, by Φ(ν; a, b)

Figure 4

 4 Figure 4.7: Limiter: the neighbors elements and the middle edge points.

  minmod function is defined by minmod(a, b) = sgn(a) min(|a|, |b|) when sgn(a) = sgn(b) 0 otherwise

  File 4.4: burgers.icc point f ( const Float & u ) { return point ( sqr ( u )/2); } File 4.5: burgers_flux_godunov.icc Float phi ( const point & nu , Float a , Float b ) { if (( nu [0] >= 0 && a <= b ) || ( nu [0] <= 0 && a >= b )) return nu [0]* min ( sqr ( a ) , sqr ( b ))/2; else return nu [0]* max ( sqr ( a ) , sqr ( b ))/2; }

  1) a.e. t ∈]0, T [ where α, β and γ are real parameters. Let us denote w the solution of the problem when β = 1 and α = γ = 0; i.e. with the initial condition w(t = 0, x) = sin(πx), a.e. x ∈] -1, 1[. For any x ∈ [0, 1[ and t > 0, the solution w = w(t, x) satisfies the characteristic relation w = sin(π(x -wt))

FileFloat

  >= -1 && xs <= 1 , " invalid xs = " << xs ); return a + b * h0 ( point ( xs )); } harten ( Float t1 =0 , Float a1 =1 , Float b1 =0.5 , Float c1 =0): h0 ( b1 * t1 ) , t ( t1 ) , a ( a1 ) , b ( b1 ) , c ( c1 ) {} Float M () const { Float pi = acos ( -1.0); return sqr ( pi )* b ; } Float min () const { return a -b ; } n = 0; n <= nmax ; ++ n ) { Float t = n * tf / nmax ; field pi_h_u = lazy_interpolate ( Xh , harten (t ,a ,b , c )); dout << even (t , pi_h_u ); } }

Fig. 4 .

 4 Fig. 4.8 shows the solution u for α = 1, β = 1/2 and γ = 0. It is regular until t = 2/π (Fig. 4.8.c) and then develops a chock for t > 2/π (Fig. 4.8.d). After its apparition, this chock interacts with the expansion wave in ] -1, 1[: this brings about a fast decay of the solution (Figs. 4.8.e and f). Fig. 4.8 plots also a numerical solution: its computation is the aim of the next section.

Figure 4

 4 Figure 4.8: Harten's exact solution of the Burgers equation (α = 1, β = 1/2, γ = 0). Comparison with the P 0 approximation (h = 1/100, RK-SSP(3)).

Figure 4 . 9 :

 49 Figure 4.9: Burgers equation: error between the P 0 approximation and the exact solution of the Harten's problem (α = 1, β = 1/2, γ = 0): (a) before chock, with T = 1/π; (b) after chock, with T = 5/2.

File

  int argc , char ** argv ) { environment rheolef ( argc , argv ); geo omega ( argv [1]); space Xh ( omega , argv [2]); size_t d = omega . dimension (); size_t k = Xh . degree (); Float beta = ( k +1)*( k + d )/ Float ( d ); trial u ( Xh ); test v ( Xh ); form a = integrate ( dot ( grad_h ( u ) , grad_h ( v ))) + integrate ( " sides " , beta * penalty ()* jump ( u )* jump ( v ) -jump ( u )* average ( dot ( grad_h ( v ) , normal ())) -jump ( v )* average ( dot ( grad_h ( u ) , normal ()))); field lh = integrate ( f ( d )* v ) + integrate ( " boundary " , beta * penalty ()* g ( d )* v -g ( d )* dot ( grad_h ( v ) , normal ())); a . uu (). s et_def inite_ posit ive ( true ); field uh ( Xh ); problem p ( a ); p . solve ( lh , uh ); dout << uh ; }

Figure 4 .

 4 Figure 4.10: The discontinuous Galerkin method for the Poisson problem when k = 1 and d = 1.Fig.4.10 plots the one-dimensional solution when k = 1 for two meshes. Observe that the jumps at inter-element nodes decreases very fast with mesh refinement and are no more perceptible on the

Figure 4 . 11 :

 411 Figure 4.11: The discontinuous Galerkin method for the Poisson problem: convergence when d = 2.

File

  int argc , char ** argv ) { environment rheolef ( argc , argv ); geo omega ( argv [1]); space Xh ( omega , argv [2]); size_t d = omega . dimension (); size_t k = Xh . degree (); Float beta = ( k +1)*( k + d )/ Float ( d ); trial u ( Xh ); test v ( Xh ); form a = integrate ( u * v + dot ( grad_h ( u ) , grad_h ( v ))) + integrate ( " internal_sides " , beta * penalty ()* jump ( u )* jump ( v ) -jump ( u )* average ( dot ( grad_h ( v ) , normal ())) -jump ( v )* average ( dot ( grad_h ( u ) , normal ()))); field lh = integrate ( f ( d )* v ) + integrate ( " boundary " , g ( d )* v ); field uh ( Xh ); problem p ( a ); p . solve ( lh , uh ); dout << uh ; }

File 4. 11 :

 11 Fig.4.12 plots the one-dimensional solution when k = 1 for two meshes. Observe that the jumps at inter-element nodes decreases very fast with mesh refinement and are no more perceptible on the plots. Recall that the Dirichlet boundary conditions at x = 0 and x = 1 is only weakly imposed: the corresponding jump at the boundary is small on the finer mesh. When k ⩾ 2, the approximate solution coincides with the interpolation of the exact one, since the exact solution is piecewise quadratic and the interface of discontinuity coincides with internal mesh sides.

Figure 4 . 12 :

 412 Figure 4.12: The discontinuous Galerkin method for the transmission problem with ε = 10 -2 , d = 1, P 1d approximation.

Figure 4 .

 4 Figure 4.13: An exact solution for the Burgers equation with diffusion (ε = 10 -1 , x 0 = -1/2).

File

Figure 4 .

 4 Figure 4.14: Convergence of the first order semi-implicit scheme for the Burgers equation with diffusion (ϵ = 0.1, T = 1). (a) first order semi-implicit scheme ; (b) Runge-Kutta semi-implicit scheme with p = 3.

File

  ru n g e_ k u tt a _ se m i im p l ic i t . icc " # include " b u rg er s _d if fu s io n_ ex a ct . h " # undef NEUMANN # include " b u r g e r s _ d i f f u s i o n _ o p e r a t o r s . icc " int main ( int argc , char ** argv ) > 5) ? atof ( argv [5]) : 1; size_t p = ( argc > 6) ? atoi ( argv [6]) : min ( k +1 , rk :: pmax ); Float delta_t = tf / nmax ; size_t d = omega . dimension (); Float beta = ( k +1)*( k + d )/ Float ( d ); trial u ( Xh ); test v ( Xh ); form m = integrate ( u * v ); beta * penalty ()* jump ( u )* jump ( v ) -jump ( u )* average ( dot ( grad_h ( v ) , normal ())) -jump ( v )* average ( dot ( grad_h ( u ) , normal ())))); vector < problem > pb ( p +1); for ( size_t i = 1; i <= p ; ++ i ) { form ci = m + delta_t * rk :: alpha [ p ][ i ][ i ]* a ; pb [ i ] = problem ( ci ); } vector < field > uh ( p +1 , field ( Xh ,0)); uh [0] = lazy_interpolate ( Xh , u_init ( epsilon )); branch even ( " t " ," u " ); dout << catchmark ( " epsilon " ) << epsilon << endl << even (0 , uh [0]); for ( size_t n = 0; n < nmax ; ++ n ) { Float tn = n * delta_t ; Float t = tn + delta_t ; field uh_next = uh [0] -delta_t * rk :: tilde_beta [ p ][0]*( inv_m * gh ( epsilon , tn , uh [0] , v )); for ( size_t i = 1; i <= p ; ++ i ) { Float ti = tn + rk :: gamma [ p ][ i ]* delta_t ; field rhs = m * uh [0] -delta_t * rk :: tilde_alpha [ p ][ i ][0]* gh ( epsilon , tn , uh [0] , v ); for ( size_t j = 1; j <= i -1; ++ j ) { Float tj = tn + rk :: gamma [ p ][ j ]* delta_t ; rhs -= delta_t *( rk :: alpha [ p ][ i ][ j ]*( a * uh [ j ] -lh ( epsilon , tj , v )) + rk :: tilde_alpha [ p ][ i ][ j ]* gh ( epsilon , tj , uh [ j ] , v )); } rhs += delta_t * rk :: alpha [ p ][ i ][ i ]* lh ( epsilon , ti , v ); pb [ i ]. solve ( rhs , uh [ i ]); uh_next -= delta_t *( inv_m *( rk :: beta [ p ][ i ]*( a * uh [ i ] -lh ( epsilon , ti , v )) + rk :: tilde_beta [ p ][ i ]* gh ( epsilon , ti , uh [ i ] , v ))); } uh_next = limiter ( uh_next ); dout << even ( tn + delta_t , uh_next ); uh [0] = uh_next ; } }

Figure 4 .

 4 Figure 4.15: Burgers equation with a small diffusion (ε = 10 -3 ). Third order in time semi-implicit scheme with P 1d element. (left) without limiter ; (right) with limiter.Running the program writes with h = 2/400 and ε = 10 -2 writes:

File

  integrate ( lambda * div_h ( u )* div_h ( v ) + 2* ddot ( Dh ( u ) , Dh ( v ))) + integrate ( omega . sides () , beta * penalty ()* dot ( jump ( u ) , jump ( v )) -lambda * dot ( jump ( u ) , average ( div_h ( v )* normal ())) -lambda * dot ( jump ( v ) , average ( div_h ( u )* normal ())) -2* dot ( jump ( u ) , average ( Dh ( v )* normal ())) -2* dot ( jump ( v ) , average ( Dh ( u )* normal ()))); field lh = integrate ( dot ( f () , v )) + integrate ( omega . boundary () , beta * penalty ()* dot ( g () , jump ( v )) -lambda * dot ( g () , average ( div_h ( v )* normal ())) -2* dot ( g () , average ( Dh ( v )* normal ())

File

  make elasticity_taylor_dg elasticity_taylor_error_dg mkgeo_grid -t 10 > square.geo ./elasticity_taylor_dg square P1d | ./elasticity_taylor_error_dg ./elasticity_taylor_dg square P2d | ./elasticity_taylor_error_dg 4.4.2 The Stokes problem Let us consider the Stokes problem for the driven cavity in Ω =]0, 1[ d , d = 2, 3. The problem has been introduced in volume 1, section 2.1.4, page 53.

  void s tokes_dirichlet_dg ( const space & Xh , const space & Qh , form & a , form & b , form & c , form & mp , field & lh , field & kh , dot ( jump ( v ) , average ( Dh ( u )* normal ())) , iopt ); lh = integrate ( dot ( f () , v ) , iopt ) + integrate ( " boundary " , beta * penalty ()* dot ( g () , v ) -2* dot ( g () , Dh ( v )* normal ()) , iopt ); b = integrate ( dot (u , grad_h ( q )) , iopt )

  problem has been already introduced in volume 1, section 4.5 page 185. Here we consider the stationary version of this problem. Let Re ⩾ 0 be the Reynolds number. The problem writes:

File

  ( grad_h ( u )* w , v ) + 0.5* div_h ( w )* dot (u , v ) , iopt ) + integrate ( " boundary " , -0.5* dot (w , normal ())* dot (u , v ) , iopt ) + integrate ( " internal_sides " , -dot ( average ( w ) , normal ())* dot ( jump ( u ) , average ( v )) -0.5* dot ( jump ( w ) , normal ()) *( dot ( average ( u ) , average ( v )) + 0.25* dot ( jump ( u ) , jump ( v ))) , iopt ); } field inertia_fix_rhs ( test v , integrate_option iopt = integrate_option ()) { return integrate ( " boundary " , -0.5* dot ( g () , normal ())* dot ( g () , v ) , iopt ); }

File

  es_dirichlet_dg ( Xh , Qh , a , b , c , mp , lh , kh ); field uh ( Xh , 0) , ph ( Qh , 0); problem_mixed stokes (a , b , c ); stokes . set_metric ( mp ); stokes . solve ( lh , kh , uh , ph ); trial u ( Xh ); test v ( Xh ); form a1 = a + Re * inertia ( uh , u , v ); lh += Re * inertia_fix_rhs ( v ); derr << " # k r as " << endl ; for ( size_t k = 0; k < max_iter ; ++ k ) { stokes = problem_mixed ( a1 , b , c ); stokes . set_metric ( mp ); stokes . solve ( lh , kh , uh , ph ); form th = inertia ( uh , u , v ); a1 = a + Re * th ; field rh = a1 * uh + b . trans_mult ( ph ) -lh ; derr << k << " " << rh . max_abs () << " " << th ( uh , uh ) << endl ; } dout << catchmark ( " Re " ) << Re << endl << catchmark ( " u " ) << uh << catchmark ( " p " ) << ph ; }

  4.27) This expression was proposed by di Pietro and Ern [2010, p. 21], eqn (73) (see also di Pietro and Ern, 2012, p. 282) following and original idea introduced in Cockburn et al. [2005].

File

  dot ( trans ( grad_h ( v ))* w , u ) -0.5* div_h ( v )* dot (u , w ) , iopt ) + integrate ( " internal_sides " , dot ( average ( u ) , normal ())* dot ( jump ( v ) , average ( w )) + 0.5* dot ( jump ( v ) , normal ()) *( dot ( average ( u ) , average ( w )) + 0.25* dot ( jump ( u ) , jump ( w ))) , iopt ) + integrate ( " boundary " , 0.5* dot (v , normal ())* dot (u , w ) , iopt )boundary " , -dot ( g () , normal ())* dot ( g () , v ) , iopt ); }

File

  Re , omega , approx ); navier_stokes_dg :: value_type xh = F . initial ( restart ); int status = damped_newton (F , xh , tol , max_iter , & derr ); dout << catchmark ( " Re " ) << Re << endl << catchmark ( " u " ) << xh [0] << catchmark ( " p " ) << xh [1]; return status ; }

FileFloat

  const geo & omega , string approx ) : Re ( Re1 ) , Xh () , Qh () , iopt () , a0 () , b () , c () , mu () , mp () , lh0 () , lh () , kh () , pmu () , pmp () , a1 () , stokes1 () { Xh = space ( omega , approx , " vector " ); Qh = space ( omega , approx ); iopt . set_family ( integrate_option :: gauss ); iopt . set_order (2* Xh . degree ()+1); s to k es_dirichlet_dg( Xh , Qh , a0 , b , c , mp , lh0 , kh , iopt ); trial u ( Xh ); test v ( Xh ); lh = lh0 + Re * inertia_fix_rhs (v , iopt ); mu = integrate ( dot (u , v ) , iopt ); pmu = problem ( mu ); pmp = problem ( mp ); } navier_stokes_dg :: value_type navier_stokes_dg :: initial ( string restart ) const { value_type xh = { field ( Xh , 0) , field ( Qh , 0) }; [1]. get_space () == Qh , " unexpected " << xh [0]. get_space (). name () << " approximation in file \" " << restart << " \" ( " << Xh . name () << " expected ) " ); } derr << " # continuation : from Re = " << Re0 << " to " << Re << endl ; residue ( const value_type & xh ) const { trial u ( Xh ); test v ( Xh ); form a = a0 + Re * inertia ( xh [0] , u , v , iopt ); value_type mrh = { a * xh [0] + b . trans_mult ( xh [1]) -lh , b * xh [0] -c * xh [1] -kh }; return mrh ; } void navier_stokes_dg :: update_derivative ( const value_type & xh ) const { trial u ( Xh ); test v ( Xh ); a1 = a0 + Re *( inertia ( xh [0] , u , v , iopt ) + inertia (u , xh [0] , v , iopt )deriva tive_ trans_ mult ( const value_type & mrh ) const { value_type rh = { field ( Xh ) , field ( Qh ) }; pmu . solve ( mrh [0] , rh [0]); pmp . solve ( mrh [1] , rh [1]); value_type mgh = { a1 . trans_mult ( rh [0]) + b . trans_mult ( rh [1]) , b * rh [0] -c * rh [1] }; return mgh ; } File 4.25: navier_stokes_dg2.icc Float navier_stokes_dg :: space_norm ( const value_type & xh ) const { return sqrt ( mu ( xh [0] , xh [0]) + mp ( xh [1] , xh [1])); } Float navier_stokes_dg :: dual_space_norm ( const value_type & mrh ) const { value_type rh = { field ( Xh ,0) , field ( Qh ,0) }; pmu . solve ( mrh [0] , rh [0]); pmp . solve ( mrh [1] , rh [1]); return sqrt ( dual ( rh [0] , mrh [0]) + dual ( rh [1] , mrh [1])); } make navier_stokes_taylor_newton_dg navier_stokes_taylor_error_dg ./navier_stokes_taylor_newton_dg square P2d 1000 | ./navier_stokes_taylor_error_dg 4.5.5 Application to the driven cavity benchmark

FileFigure 4

 4 Figure 4.16: The discontinuous Galerkin method for the Navier-Stokes problem on the driven cavity benchmark when k = 1 and d = 2: convergence of the damped Newton algorithm.

File 4 .

 4 27: inertia_upw.icc # include " sgn . icc " form inertia_upw ( field w , trial u , test v , integrate_option iopt = integrate_option ()) { return integrate ( " internal_sides " , 0.5* abs ( dot ( average ( w ) , normal ()))* dot ( jump ( u ) , jump ( v )compose ( sgn , dot ( average ( w ) , normal ())) * dot ( average ( dw ) , normal ())* dot ( jump ( u ) , jump ( v ))); }

File 4 .

 4 28: sgn.icc Float sgn ( Float x ) { return ( x >= 0) ? 1 : -1; } File 4.29: navier_stokes_upw_dg.h # include " navier_stokes_dg . h " struct navier_stokes_upw_dg : navier_stokes_dg { typedef Float float_type ; typedef navier_stokes_dg :: value_type value_type ; n a v i er_stokes_upw_dg ( Float Re , const geo & omega , string approx ); value_type residue ( const value_type & uh ) const ; void update_derivative ( const value_type & uh ) const ;

Figure 4 .

 4 Figure 4.17: The discontinuous Galerkin method for the Navier-Stokes problem on the driven cavity benchmark when k = 1 (80 × 80 grid): stream function isovalues for various Re.

Figure 4 .

 4 Figure 4.18: The discontinuous Galerkin method for the Navier-Stokes problem on the driven cavity benchmark when k = 1 (80 × 80 grid): stream function isovalues for various Re (cont.).

Figure 4 .

 4 Figure 4.19: The discontinuous Galerkin method for the Navier-Stokes problem on the driven cavity benchmark when k = 1 (80 × 80 grid): stream function isovalues for various Re (cont.).

  operator () ( const Float & x ) const { if ( fabs ( x ) <= a ) return 0; return ( x > 0) ? _phi (x -a ) : -_phi ( -x -a ); } projection ( Float a1 , Float n =1 , Float c =1 , Float r =0) : a ( a1 ) , _phi (n ,c , r ) {} Float a ; phi _phi ; };

File

  y i e l d _ s l i p _ a u g m e n t e d _ l a g r a n g i a n . icc " # include " poisson_robin . icc " int main ( int argc , char ** argv ) integrate ( v ); field uh = poisson_robin ( Cf , omega [ " boundary " ] , lh ); space Wh ( omega [ " boundary " ] , Xh . get_approx ()); field lambda_h = Cf * uh [ " boundary " ]; int status = y i e l d _ s l i p _ a u g m e n t e d _ l a g r a n g i a n (S , n , Cf , omega [ " boundary " ] , lh , lambda_h , uh , tol , max_iter , r ); dout << setprecision ( numeric_limits < Float >:: digits10 ) << catchmark ( " S " ) << S << endl << catchmark ( " n " ) << n << endl << catchmark ( " Cf " ) << Cf << endl << catchmark ( " r " ) << r << endl << catchmark ( " u " ) << uh << catchmark ( " lambda " ) << lambda_h ; return status ; } File 5.4: poisson_robin.icc field poisson_robin ( Float Cf , const geo & boundary , const field & lh ) { const space & Xh = lh . get_space (); trial u ( Xh ); test v ( Xh ); form a = integrate ( dot ( grad ( u ) , grad ( v ))) + Cf * integrate ( boundary , u * v ); field uh ( Xh ); problem p ( a ); p . solve ( lh , uh ); return uh ; } make yield_slip_augmented_lagrangian mkgeo_grid -a -1 -b 1 -c -1 -d 1 -t 50 > square.geo ./yield_slip_augmented_lagrangian square.geo P1 0.6 1 > square.field Also you can replace P1 by P2. The solution can be represented in elevation view (see Fig. 5.1): field square.field -elevation -stereo

Figure 5 . 2 :

 52 Figure 5.2: The yield slip problem for S = 0.6: cut of the velocity (left) along the 0x 0 axis ; (center) along the boundary ; (right) cut of the normal stress λ along the boundary.

Figure 5

 5 Figure 5.3: The convergence of the augmented Lagrangian algorithm for the yield slip problem with S = 0.6 and n = 1 and P 1 polynomial approximation.

  ( x ) <= a ) return 0; if ( n == 1) return 1/( c + r ); if ( r == 0) return pow ( fabs ( x ) -a , -1+1/ n )/( n * pow (c ,1/ n )); return 1/( r + n * c * pow ( _phi ( fabs ( x ) -a ) , -1+ n )); } d_projection_dx ( Float a1 , Float n1 =1 , Float c1 =1 , Float r1 =0) : a ( a1 ) , n ( n1 ) , c ( c1 ) , r ( r1 ) , _phi ( n1 , c1 , r1 ) {} Float a ,n ,c , r ; phi _phi ; };

Figure 5 . 4 :

 54 Figure 5.4: The convergence of the damped Newton algorithm for the yield slip problem (S = 0.6): (top-left) n = 0.5; (top-right) n = 0.9; (bottom-left) n = 1; (bottom-right) n = 1.5.

Figure 5 . 5 :

 55 Figure 5.5: The yield slip problem: error analysis.

File

File 5. 12 :

 12 mosolov_augmented_lagrangian1.icc # include " vector_projection . h " int m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n :: solve ( field & sigma_h , field & uh ) const { test v ( Xh ); derr << " # k residue " << endl ; for ( size_t k = 0; true ; ++ k ) { field grad_uh = inv_mt *( b * uh ); auto c = compose ( vector_projection ( Bi ,n ,1 , r ) , norm ( sigma_h + r * grad_uh )); field gamma_h = lazy_interpolate ( Th , c *( sigma_h + r * grad_uh )); field delta_sigma_h = r *( grad_uh -gamma_h ); sigma_h += delta_sigma_h ; Float residue = delta_sigma_h . max_abs (); derr << k << " " << residue << endl ; if ( residue <= tol || k >= max_iter ) { derr << endl << endl ; return ( pow ( residue ,3) <= tol ) ? 0 : 1; } field rhs = (1/ r )*( lh -integrate ( dot ( sigma_h -r * gamma_h , grad ( v )))); pa . solve ( rhs , uh ); } }

File 5 .

 5 13: mosolov_augmented_lagrangian.h struct m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n : adapt_option { m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n (); void reset ( geo omega , string approx ); void initial ( field & sigma_h , field & uh ) const ; int solve ( field & sigma_h , field & uh ) const ; void put ( odiststream & out , field & sigma_h , field & uh ) const ; m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n 1 . icc " # include " m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n 2 . icc " File 5.15: mosolov_augmented_lagrangian.cc # include " rheolef . h " using namespace std ; using namespace rheolef ; # include " m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n . h " int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); m o s o l o v _ a u g m e n t e d _ l a g r a n g i a n pb ; = " -AbsError " ; field sigma_h , uh ; for ( size_t i = 0; true ; i ++) { pb . reset ( omega , approx ); pb . initial ( sigma_h , uh ); int status = pb . solve ( sigma_h , uh ); odiststream out ( omega . name () , " field " ); pb . put ( out , sigma_h , uh ); if ( i == n_adapt ) break ;space T0h ( sigma_h . get_geo () , " P " + to_string ( sigma_h . get_space (). degree ())+ " d " ); field ch = lazy_interpolate( T0h , sqrt ( abs ( dot ( sigma_h , grad ( uh )))

Figure 5

 5 Figure 5.6: The augmented Lagrangian algorithm on the Mosolov problem with Bi = 0.4 and n = 1: (left) the velocity field in elevation view (h = 1/30); (right) velocity cut along the first bisector for various h.

Figure 5

 5 Figure 5.7: The augmented Lagrangian algorithm on the Mosolov problem with Bi = 0.4 and n = 1: residue versus iteration k for various h.

Figure 5

 5 Fig. 5.11.right shows the result: the yield surface error converges as O(h) for any k ⩾ 0. Recall that the yield surface is the zero isosurface of the level set function ϕ(x = |σ h (x| -Bi. Its visualization, shown on Fig. 5.11.left, is provided by the following commands: make mosolov_yield_surface zcat circle-P2-10.field.gz | ./mosolov_yield_surface | \ field --proj P1 -n-iso 10 -n-iso-negative 5

Figure 5

 5 Figure5.9: Auto-adaptive meshes for the Mosolov problem: evolution of the mesh size (left) and the minimal edge length during the adaptation loop.

Figure 5 .

 5 Figure 5.10: The augmented Lagrangian algorithm on the Mosolov problem with Bi = 0.2 and n = 1/2: error versus mesh paremeter h for various polynomial order k.

Figure 5 . 11 :

 511 Figure 5.11: The augmented Lagrangian algorithm on the Mosolov problem with Bi = 0.2 and n = 1/2: (left) convergence of the yield surface versus mesh parameter h for various polynomial order k ; (right) visualization of the yield surface (P 1 approximation).

Figure 5 . 12 :

 512 Figure 5.12: Tranport tensor problem: convergence versus mesh size.

  α)W e + θ∆t W e + θ∆t and c 3 = αθ∆t W e + θ∆t * sub-step 2: (τ (n+θ) , u (n+θ) ) being known, compute explictely

Figure 5 Figure 5 Figure 5

 555 Figure 5.14: The Oldroyd problem in the axisymmetric contraction: stream function for W e = 0.1, 0.3 and 0.7, from top to bottom.

  Let us consider the Poisson problem with mixed Dirichlet and Neumann boundary conditions:(P ): find u, defined in Ω, such that -∆u = f in Ω u = g d on Γ d ∂u ∂n = g n on Γ n where ∂Ω = Γ d ∪ Γ n ,and the interior of the two boundary domains Γ d and Γ n are disjoints. The data f , g d and g n are given. Let us introduce the gradient σ = ∇u as an independent variable. The problem writes equivalently (see e.g. Nguyen et al. [2011]):

File

  Mh . get_geo ()[ " boundary " ] , approx ); size_t d = omega . dimension (); size_t k = Xh . degree (); trial x ( Yh ) , lambda ( Mh ); test y ( Yh ) , mu ( Mh ); auto sigma = x [0] , u = x [1]; auto tau = y [0] , v = y [1]; integrate_option iopt ; iopt . invert = true ; auto coef = beta * pow ( h_local () , n ); form inv_a = integrate ( dot ( sigma , tau ) + u * div_h ( tau ) + v * div_h ( sigma ) -on_local_sides ( coef * u * v ) , iopt ); form b = integrate ( " internal_sides " , ( -dot ( jump ( sigma ) , normal ()) + 2* coef * average ( u ))* mu ) + integrate ( " boundary " , ( -dot ( sigma , normal ()) + coef * u )* mu ); form c = integrate ( " internal_sides " , 2* coef * lambda * mu ) + integrate ( " boundary " , coef * lambda * mu ); field lh = integrate ( -f ( d )* v ); field kh ( Mh ,0) , lambda_h ( Mh ,0); lambda_h [ " boundary " ] = lazy_interpolate ( Wh , g ( d )); form s = c + b * inv_a * trans ( b ); field rh = b *( inv_a * lh ) -kh ; problem p ( s ); p . solve ( rh , lambda_h ); field xh = inv_a *( lh -b . trans_mult ( lambda_h )); dout << catchmark ( " n " ) << n << endl << catchmark ( " beta " ) << beta << endl << catchmark ( " u " ) << xh [1] << catchmark ( " lambda " ) << lambda_h << catchmark ( " sigma " ) << xh [0

Figure 6 . 2 :

 62 Figure 6.2: Hybrid discontinuous Galerkin method: Poisson problem with Dirichlet boundary conditions in 2D geometry. Convergence vs h and k for the approximation of the solution u h and of its gradient σ h . (left) n = 1 ; (center) n = 0 ; (right) n = -1.

Figure 6 . 3 :

 63 Figure 6.3: Hybrid discontinuous Galerkin method: Poisson problem with Dirichlet boundary conditions in 2D geometry. Super-convergence vs h and k for the Lagrange multiplier λ h to the L 2 projection on M h of the exact solution. (left) n = 1 ; (center) n = 0 ; (right) n = -1.

Figure 6 . 4 :

 64 Figure 6.4: Hybrid discontinuous Galerkin method: Poisson problem with Dirichlet boundary conditions in 2D geometry. Super-convergence vs h and k for the piecewise average ūh of the approximate solution. (left) n = 1 ; (center) n = 0 ; (right) n = -1.

Figure 6 . 6 :

 66 Figure 6.6: Solution post-processing of the hybrid discontinuous Galerkin method: Poisson problem with Dirichlet boundary conditions in 2D geometry. Convergence vs h and k for the posttreated gradient σh approximate solution. (left) n = 1 ; (center) n = 0 ; (right) n = -1.

  * h , ζ, ξ ∈ Z * h , u ∈ X h and λ ∈ M h : a * (u * , v * ) = Ω ∇ h u * . (A∇ h v * ) dx (6.10a) b * (u * , ξ) = Ω u * ξ dx (6.10b) c * (ζ, ξ) = Ω γ ζ ξ dx (6.10c) ǎ(u, v * ) = Ω ∇ h u. (A∇ h v * ) dx -K∈T h ∂K u (A∇ h v * ) .n ds b(u, ξ) = Ω u ξ dx e * (u * , µ) = K∈T h ∂K µ (A∇ h u * ) .n dsThen, the previous reconstruction problem writes:

τ

  |∂K .n ; τ ∈ RT k (K) = K∈T h S⊂∂K P k (S)Let π Mh denote the L 2 projection into Mh . We consider the special case of computing the projec-tion δh = π Mh (u * h ) ∈ Mh of an element u * h ∈ X * h . It isdefined as δh h is bi-valued and P k+1 on all internal side while its projection δh = π Mh (u * h ) ∈ Mh is also bi-valued but only P k . The following bilinear forms are introduced: projection reduces to: let u * h ∈ X * h being given, find δh ∈ Mh such that m( δh , φh ) = d(u * h , φh ), ∀ φh ∈ Mh

∇

  All the associated matrix are symmetric definite positive, and then invertible, except a * , which is only symmetric positive but has a zero eigenvalue. The second group corresponds to rectangular matrix:b * (u * , ξ) h u. (A∇ h w * ) dx -K∈T h ∂K u (A∇ h w * ) .n dsThese two groups admit a block-diagonal structure at the element level, due to the piecewise discontinuous character of the trial and test functions. In the following third group, bilinear forms corresponds to rectangular matrix with non-block-diagonal structure, due to the inter-element continuity of µ ∈ M h:e * (v * , µ) = K∈T h ∂K µ (A∇ h v * ) .n ds ẽ(γ, µ) = K∈T h ∂K γ µ dsLet us process to the elimination of all the unknowns except λ h . For simplicity, the matrix subequations are designated by the corresponding test-function surrounded by parenthesis, such as (w * ) for the first one. Let us start by eliminating some variables related to projections: from (y), ( w) and ( φ), we get, respectively:ǔ = m -1 d * u *

FFile

  d * -d m -1 d *Next, let us turn to variables related to the reconstruction. from (ξ 1 ) and (w * ), we get: we obtain successively:ζ 1 = c -1 * (b * u * -du) u * = S -1Back-substituting in (6.12d)-(6.12e):D T (6.12j)It remains to express δ in terms of u and λ. From (κ) and (6.12a):mδ -D * u * -du + ẽT λ = 0Left-multiplying by c m-1 and substituting (6.12h), we getδ = M -1 ẼT u + F T λ M = c + D S -1 * -S -1 * a * T -1 a * S -1 * D T = e * T -1 a * S -1 * D T -ẽ m-1 c (6.12k)Replacing in (6.12j), we getAu + B T λ = ℓ with A = A c + A s A s = Ẽ M -1 ẼT B = F M -1 ẼT -e * T -1 R (6.12l)Here, A c represents the consistency part of the operator A while A s is the stabilization part, i.e. the penalization. Finally, (µ) becomesBu + Cλ = 0 with C = e * T -1 e T * + F M -1 F T 12l)-(6.12m), we get u = A -1 (ℓ -B T λ) Sλ = f with S = C -BA -1 B T f = -BA -1 ℓThe following code implements this technique:

Figure 6 Figure 6

 66 Figure 6.8: Hybrid hight-order (HHO) method: error vs h and k for the Poisson problem. The compilation and run write: make dirichlet_hho mkgeo_grid -t 10 > square.geo ./dirichlet_hho square.geo P1d > square.field field square.field -elevation field square.field -elevation -mark u field square.field -elevation -mark lambda Observe the better behavior of the u * h approximate solution, obtained by reconstruction, when compared with the original one u. The error versus the mesh refinement h and the polynomial orer k is plotted on Fig. 6.8. These numerical experiments confirm the theoretical predictions (see e.g. Pietro and Droniou [2020], pages 65 and 68):∥u * h -u∥ 0,2,Ω = O(h k+2 ) ∥∇ h (u * h -u)∥ 0,2,Ω = O(h k+1 )Fig.6.9 plots the L 2 error for u * h versus the CPU time required to its computation for various mesh refinement h and polynomial order k. It compares it with the L 2 error for obtaining the P k+1

Ω

  div(σ(u)).v dx = Ω f .v dx, ∀v ∈ V The next step is to invoke an integration by part:Ω div τ.v dx + Ω τ : D(v) dx = ∂Ω τ : (v ⊗ n) ds, ∀τ ∈ L 2 (Ω) d×d , ∀v ∈ V Recall that div τ denotes d-1 j=0 ∂ j τ i,j0⩽i<d, i.e. the vector whose component are the divergence of each row of τ . Also, σ : τ denote the double contracted product d-1

  τ i,j u i v j . Choosing τ = σ(u) in the previous equation leads to:Ω σ(u) : D(v) dx = ∂Ω (σ(u) n).v ds + Ω f .v dx, ∀v ∈ VSince our test-function v vanishes on Γ d and the solution satisfies the homogeneous Neumann boundary condition σ(u) n = 0 on Γ n , the integral over ∂Ω is zero and the problem becomes:Ω σ(u) : D(v) dx = Ω f .v dx, ∀v ∈ VFrom the definition of σ(u) in (2.1) page 43 we have:σ(u) : D(v) = λ div(u) (I : D(v)) + 2µD(u) : D(v) = λ div(u) div(v) + 2µD(u) : D(v)and the previous relation becomes: Ω λdiv(u) div(v) dx + Ω 2µD(u) : D(v) dx =

  The

	bamg -g square.bamgcad -o square.bamg
	bamg2geo square.bamg square.dmn > square.geo
	./embankment_adapt square P1 2e-2

last command line argument is the target error. The code performs a loop of five mesh adaptations: the corresponding meshes are stored in files, from square-001.geo.gz to square-005.geo.gz, and the associated solutions in files, from square-001.field.gz to square-005.field.gz. The additional '.gz' suffix expresses that the files are compressed using gzip. geo square-005.geo field square-005.field -nofill

  The boundary conditions in this example are related to an abrupt contraction geometry with a free surface. The corresponding mesh 'contraction.geo' can be easily build from the geometry description file 'contraction.mshcad', which is provided in the example directory of the Rheolef distribution. The building mesh procedure is presented with details in appendix A.2, page A.2.

		File 2.14: streamf_contraction.cc
	# include " rheolef . h "
	using namespace rheolef ; gmsh -2 contraction.mshcad -format msh2 -o contraction.msh using namespace std ;
	msh2geo contraction.msh > contraction.geo # include " contraction . h "
	int main ( int argc , char ** argv ) { geo contraction.geo environment rheolef ( argc , argv );
	field uh ; The mesh is represented on Fig. 2.10.top. Then, the computation and the visualization writes: din >> uh ;
	const geo & omega = uh . get_geo ();
	size_t d = omega . dimension (); make stokes_contraction_bubble Float c = omega . xmax ()[1]; ./stokes_contraction_bubble contraction.geo > contraction-P1.field string approx = " P " + to_string ( uh . get_space (). degree ());
	field contraction-P1.field -velocity space Ph = contraction :: streamf_space ( omega , approx );
	field psi_h = contraction :: streamf_field ( Ph );
	integrate_option iopt ; The visualization of the velocity field brings few informations about the properties of the flow. iopt . ignore_sys_coord = true ; The stream function is more relevant for stationary flow visualization. const space & Xh = uh . get_space ();
	trial psi ( Ph ) , u ( Xh );
	test	xi ( Ph ) , v ( Xh );
	form a = ( d == 3) ? integrate ( ddot ( grad ( psi ) , grad ( xi )))
		: integrate ( dot ( grad ( psi ) , grad ( xi )) , iopt );
	field lh = integrate ( dot ( uh , bcurl ( xi )));
	problem p ( a );
	p . solve ( lh , psi_h );
	dout << catchmark ( " psi " ) << psi_h ;

}

Note the usage of the optional parameter iopt to the integrate function.

iopt . ignore_sys_coord = true ;

  File->save animation menu and enter as file name square and as file type avi. The animation file square.avi can now be started from any video player, such as vlc: vlc square.avi For the tridimensional case, the animation feature is similar:

	# include " rheolef . h " using namespace rheolef ; using namespace std ; int main ( int argc , char ** argv ) { environment rheolef ( argc , argv ); geo omega ( argv [1]); size_t n_max = ( argc > 2) ? atoi ( argv [2]) : 100; Float delta_t = 0.5/ n_max ; space Xh ( omega , " P1 " ); Xh . block ( " boundary " ); trial u ( Xh ); test v ( Xh ); form a = integrate ( u * v + delta_t * dot ( grad ( u ) , grad ( v ))); problem p ( a ); field uh ( Xh , 0); branch event ( " t " ," u " ); dout << event (0 , uh ); for ( size_t n = 1; n <= n_max ; n ++) { field rhs = uh + delta_t ; field lh = integrate ( rhs * v ); p . solve ( lh , uh ); dout << event ( n * delta_t , uh ); } } Comments Note the use of the branch class: branch event ( " t " ," u " ); this is a wrapper class that is used here to print the branch of solution (t n , u n ) n⩾0 , on the standard output in the '.branch' file format. An instruction as: dout << event (t , uh ); is equivalent to the formatted output dout << catchmark ( " t " ) << t << endl << catchmark ( " u " ) << uh ; How to run the program We assume that the previous code is contained in the file 'heat.cc'. Then, compile the program as usual (see page 16): Figure 2.16: Animation of the solution of the heat problem. For a one dimensional problem, enter the commands: mkgeo_grid -e 100 > line.geo ./heat line.geo > line.branch The previous commands solve the problem for the corresponding mesh and write the solution in the field-family file format '.branch'. For a bidimensional one: mkgeo_grid -t 10 > square.geo ./heat square.geo > square.branch For a tridimensional one: mkgeo_grid -T 10 > box.geo ./heat box.geo > box.branch How to run the animation branch line.branch A gnuplot window appears. Enter q to exit the window. For a bidimensional case, simply enter: branch square.branch -elevation A window appears, that looks like a video player. Then, click on the video play button, at the top of the window. To generate an animation file, go to the branch box.branch branch box.branch -volume
	make heat

  While the bounding box mesh was uniform, the triangular elements obtained by intersecting the 3D bounding box mesh with the level set function can present arbitrarily irregular sizes and shapes (see also Fig.3.4):

	.geo
	./level_set_sphere cube2.geo | geo -upgrade -> sphere.geo
	geo sphere.geo -stereo
	./helmholtz_s sphere.geo P1 | field -

  Table 4.1: BDF(p) schemes: the α p,i coefficients, 1 ⩽ p ⩽ 6, 1 ⩽ i ⩽ p.

				1/2
	3	11/6	-3 3/2 -1/3
	4	25/12 -4	3	-4/3	1/4
	5	137/60 -5	5	-10/3 5/4 -1/5
	6	147/60 -6 15/2 -20/3 15/4 -6/5 1/6

  , ζ 1 , ζ 2 , v, γ) = -ǔ -δ) γ dsand the previous minimization problem can be equivalently expressed as a saddle point one with ten unknowns:(u h , u * h , ǔh , δh ; λ h , v * h , ζ 1,h , ζ 2,h , vh , γh ) = arg inf Mh L(w h , w * h , wh , φh ; µ h , y * h , ξ 1,h , ξ 2,h , yh , κh )Since L is differentiable and quadratic, its saddle point is characterized as the unique solution of a variational and linear problem:-u).(A∇ h y * ) + ∇ h (w * -w).(A∇ h v * )} dx + K∈T h S⊂∂K S{u (A∇y * ).n + w (A∇v * ).n} ds+ -u)ξ 1 + (w * -w)ζ 1 + v * ξ 2 + y * ζ 2 -α h -2 (ζ 1 ξ 1 -ζ 2 ξ 2 ) dx +

						β h -1 S δ φ ds
				K∈T h S⊂∂K S
	+
		Ω	1 2	|∇ h u * | 2 A -f u dx +	1 2	K∈T h S⊂∂K S	β h -1 S	δ2 ds
		+
					α h -2 2	ζ 2 1 -ζ 2 2	dx
		+
		sup
	w h ∈ X h w * h ∈ X * h	µ h ∈ M h (0) y * h ∈ X *
	wh ∈ X h
	φh ∈ Mh

* Ω ∇ h (u * -u). (A∇ h v * ) dx + K∈T h ∂K (u -λ) (A∇v * ) .n ds + Ω (u * -u) ζ 1 + v * ζ 2 -Ω (u * -ǔ) v dx + K∈T h S⊂∂K S (u -λ + u * h ξ 1,h Z h ξ 2,h Z h yh ∈ X h κh ∈ (F V ) h : find (u * h , ζ 1,h , δh ; v * h , ζ 2,h , γh ; ǔh , vh , u h ; λ) ∈ X * h × Z h × Mh 2 × X 3 h × M h (0) such that Ω ∇ h u * .(A∇ h w * ) dx -Ω f w dx + Ω {∇ h (u * Ω (u * Ω {(u * -ǔ)y + (w * -w)v} dx + K∈T h S⊂∂K S (u + u * -ǔ -δ)κ + (w + w * -w -φ)γ dx -K∈T h S⊂∂K S {λ (A∇y * ).n + µ (A∇v * ).n} ds -K∈T h S⊂∂K S (λ κ + µ γ) ds = 0

for all (w * h , ξ 1,h , φh ; y * h , ξ 2,h , κh ; wh , yh , w h

  you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

	List of commands
	bamg2geo, 277
	bamg, 48, 84, 277
	-splitpbedge, 111
	branch, 77

The original θ-scheme presented by[START_REF] Saramito | Numerical simulation of viscoelastic fluid flows using incompressible finite element method and a θ-method[END_REF] has an additional relaxation parameter ω. The present version correspond to ω = 1. When ω ̸ = 1, the stationary solution still depends slightly upon ∆t, as the stationary system do not simplifies completely.

Ωf .v dx, ∀v ∈ V This is exactly the variational formulation (2.3), page 43.A.1.3 The Green formula on a surfaceLet Γ a closed and orientable surface of R d , d = 2, 3 and n its unit normal. From[START_REF] Laadhari | On the equilibrium equation for a generalized biological membrane energy by using a shape optimization approach[END_REF], appendix C we have the following integration by part:Γ div s v ξ ds + Γ v.∇ s ξ ds = Γ v.n ξ div n ds for all ξ ∈ H 1 (Γ) and v ∈ H 1 (Γ) d .Note that div n represent the surface curvature. Next, we

File 3.22: combustion1.icc combustion :: combustion ( const geo & omega , string approx ) : lambda (0) , Xh () , m () , pm () , a1 () , pa1 () , event ( " lambda " ," u " ) { if ( approx != " " ) reset ( omega , approx );

Comments

Numerical computations are performed on the time interval [0, t f ] with a time step ∆t = t f /n max where n max is the number of time steps. Since d = 2, a direct method is preferable (see section 1.1.10 and Fig. 1.5). Observe that u is here independent upon t. Then a n , as given by (4.2a), is independent upon n when n ⩾ p, and a n can be factored one time for all n ⩾ p. The file 'zalesak.h' included here implements the phi0 and phi_exact class-functions representing the exact solution ϕ(t) of level set function for the slotted disk, together with the u class-function for the velocity field. This file it is not listed here but is available in the Rheolef example directory.

Recall that the BDF(p) scheme is unconditionally stable when p ∈ {1, 2} and almost unconditionally stable when p ∈ {3, . . . , 6} (see e.g. Süli and Mayers, 2003, p. 349). Then, when an instability is detected, an issue for decreasing the time step is generated and the computation is stopped.

Numerical resolution

When replacing the periodic boundary condition with a inflow one, associated with the boundary data g, we choose g to be the value of the exact solution of the problem with periodic boundary conditions: g(t, x) = α + w(βt, x -αt) for x ∈ {-1, 1}. -integrate ( dot ( compose (f , uh [ j ]) , grad_h ( v )))

+ integrate ( " internal_sides " , compose ( phi , normal () , inner ( uh [ j ]) , outer ( uh

Comments

The Runge-Kutta time discretization combined with the discontinuous Galerkin space discretization is implemented for this test case. The P 0 approximation is performed by the following commands:

Chapter 5

Complex fluids

This part presents in details the practical computational aspects of numerical modeling with complex fluids. Most of the examples involve only few lines of code: the concision and readability of codes written with Rheolef is certainly a major key-point of this environment. The theoretical background for complex fluids an associated numerical methods can be found in the textbook by the present author [Saramito, 2016b]. We start with yield slip boundary condition as a preliminary problem. Slip at the wall occurs in many applications with complex fluids. This problem is solved both by augmented Lagrangian and Newton methods. Then, viscoplastic fluids are introduced and an augmented Lagrangian method is presented. A prelinary for viscoelastic fluids problems is the linear tensor transport equation: it is solved by a discontinuous Galerkin method. Finally, viscoelastic fluids problems are solved by an operator splitting algorithm, the θ-scheme.

Yield slip at the wall

Problem statement

The problem of a Newtonian fluid with yield slip at the wall and flowing in a pipe [START_REF] Roquet | Stick-slip transition capturing by using an adaptive finite element method[END_REF] writes: (P ): find u, defined in Ω, such that

Here, S ⩾ 0 and C f > 0 are respectively the yield slip and the friction coefficient while n > 0 is a power-law index. The computational domain Ω represents the cross-section of the pipe and u is the velocity component along the axis of the pipe. The right-hand side f is a given constant, and without loss of generality, we can suppose f = 1 : the parameters are S, C f and n. When S = 0 and n = 1, the problem reduces to a Poisson problem with homogeneous Robin boundary condition that depend upon C f .

Observe that f ′ n,r (y) = nC f y -1+n + r > 0 when r > 0: the function is strictly increasing and is thus invertible. When n = 1 then f n,r is linear and ϕ 1,r (x) = x/(C f + r). When n = 1/2 this problem reduces to a second order polynomial equation and the solution is also explicit:

In general, when n > 0 and r > 0, the solution is no more explicit. We consider the Newton method:

• i = 0: Let y 0 being given.

• i ⩾ 0: Suppose y i being known and compute

File 5.2: phi.h In the present implementation, in order to avoid too large steps, the Newton step is damped when y i+1 becomes negative. The Uzawa algorithm writes:

• k = 0: let λ (0) and γ (0) arbitrarily chosen.

• k ⩾ 0: let λ (k) and γ (k) being known, find u (k+1) , defined in Ω, such that Observe also that the stopping criterion for breaking the loop bases on the max of the relative error for the λ h variable. For this algorithm, this stopping criterion guaranties that all residual terms of the initial problem are also converging to zero, as it will be checked here. Moreover, this stopping criterion is very fast to compute while the full set of residual terms of the initial problem would take more computational time inside the loop. Assume that the previous code is contained in the file 'yield-slip-augmented-lagrangian.cc'.

Running the program

Compile and run the program as usual:

File 5.9: yield_slip1.icc Observe on Fig. 5.4.a and 5.4.b that the convergence is super-linear and mesh-independent when n = 1/2 and n = 0.9. For mesh-independent convergence of the Newton method, see e.g. the p-Laplacian example, Fig. 3.15, page 129. When n = 0.9, observe that the convergence depends slightly upon the mesh for rough meshes while it becomes asymptotically mesh independent for fine meshes. When n ⩾ 1, the convergence starts to depend also upon the mesh . Recall that when n ⩾ 1, the problem becomes non-differentiable and the convergence of the Newton method is no more assured. Nevertheless, in that case, the convergence is clearly faster (about 100 times faster) than the corresponding one with the augmented Lagrangian algorithm on the same problem (see Fig. 5.3, page 209) and moreover there is no saturation of the residual terms on large meshes.

Error analysis

Assume that the previous code is contained in the file 'yield-slip-augmented-lagrangian.cc'.

When Ω is the unit circle, the exact solution is known. In polar coordinates (r, θ), as the solution

Error analysis

Theoretical error bounds for this problem can be found in [START_REF] Roquet | Errors estimate for a viscoplastic fluid by using Pk finite elements and adaptive meshes[END_REF]. In order to study the error between the numerical solution and the exact solution of the Mosolov problem, let us investigate a case for which the exact solution can be explicitly expressed. We consider the special case of a flow of a viscoplastic fluid in a circular pipe. The pressure is expressed by p(z) = -f z.

The velocity has only one nonzero component along the 0z axis, denoted as u(r) for simplicity.

Conversely, the symmetric tensor σ has only one non-zero rz component, denoted as σ(r). Thanks to the expression of the tensor-divergence operator in axisymmetric coordinates [Bird et al., 1987, p. 588], the problem reduces to : (P) : find σ(r) and u(r),

Let Σ = f R/2 be a representative stress and U a representative velocity such that K(U/R) n = Σ.

Then, we consider the following change of unknown:

The system reduces to a problem with only two parameters n and the Bingham number Bi = 2σ 0 /(f R), that measures the ratio between the yield stress and the load. Since there is no more ambiguity, we omit the tildes : (P) : find σ and u,

Remark that the solution is even : u(-r) = u(r). We get σ(r) = -r and the yield stress criterion leads to u(x) = 0 when |r| ⩽ Bi: the load is weaker than the yield stress and the flow is null. When Bi > 1 the solution is u = 0. Otherwise, when |r| > Bi, we get |u ′ (r)| n + Bi = |r| and finally, with the boundary conditions and the continuity at r = ±Bi :

When n = 1, the second derivative of the solution is discontinuous at r = Bi and its third derivative is not square integrable. For any n > 0, an inspection of the integrability of the square of the solution derivatives shows that u ∈ H 1+1/n (] -1, 1[, r dr) at the best.

File 5.17: mosolov_exact_circle.h

When computing on a circular pipe section, the exact solution is known and it is also possible to compute the error: this is implemented in the file 'mosolov_error.cc'. This file it is not listed here but is available in the Rheolef example directory. The error analysis is obtained by: make mosolov_error mkgeo_ball -order 2 -t 10 > circle-P2-10.geo ./mosolov_augmented_lagrangian circle-P2-10.geo P2 0.2 0.5 zcat circle-P2-10.field | ./mosolov_error Note that we use an high order isoparametric approximation of the flow domain for tacking into account the the curved boundaries. Observe on Fig. 5.10 that both the error in H 1 norm for the velocity u behaves as O(h s ) with s = min(k, 2). This is optimal, as, from interpolation theory [Brenner and Scott, 2002, p. 109], we have:

Then, the convergence rate of the error in H 1 norm versus the mesh size is bounded by 1/n for any polynomial order k. The rate for the error in L ∞ norm for for the velocity u is min(k + 1, 1/n), for any k ⩾ 1 and n > 0. For the stress σ, the error in L 2 norm behaves as O(h) for any polynomial order and, in L ∞ norm, the rate is weaker, of about 3/4. Finally, for n = 1/2 there is no advantage of using polynomial order more than k = 2 with quasi-uniform meshes. Conversely, for n = 1, we obtains that there is no advantage of using polynomial order more than k = 1 with quasi-uniform meshes. This limitation can be circumvented by combining mesh adaptation with high order polynomials [START_REF] Roquet | Errors estimate for a viscoplastic fluid by using Pk finite elements and adaptive meshes[END_REF][START_REF] Saramito | An adaptive finite element method for viscoplastic fluid flows in pipes[END_REF].

Error analysis for the yield surface

The limit contour separating the rigid zones are expressed as a level set of the stress norm:

This contour is called the yield surface and its exact value is known from the exact solution σ(x) = x in the circle:

Recall the stress σ h converges in L ∞ norm, thus, there is some hope that its point-wise values converge. As these point-wise values appears in the definition of the yield surface, this suggests This command generates a mesh for the axisymmetric 4:1 abrupt contraction with upstream and downstream length L u = L d = 20. Such high lengths are required for the Poiseuille flow to be fully developped at upstream and downstream for large values of W e. The 3 first argument of mkgeo_contraction is a number that characterizes the mesh density: when increasing, the average edge length decreases. Then, the program is started: make oldroyd_contraction mpirun -np 8 ./oldroyd_contraction contraction.geo 0.1 10 0.01 > contraction.branch

The program computes stationnary solutions by increasing W e with the time-dependent algorithm.

It performs a continuation algorithm, using solution at a lowest W e as initial condition. The reccurence starts from an the Newtonian solution associated to W e = 0. The others model parameters for this classical benchmark are fixed here as α = 8/9 and a = 1 (Oldroyd-B model).

The computation can take a while as there are two loops: one outer, on W e, and the other inner on time, and there are two generalized Stokes subproblem and one tensorial transport one to solve at each time iteration. The inner time loop stops when the relative error is small enough. Thus, the parallel run, when available, is a major advantage: it is obtained by adding mpirun -np 8 at the begining of the command line. Recall that the time scheme is conditionnaly stable: the time step should be small enough for the algorithm to converge to a stationnary solution. When the solver fails, it restarts with a smaller time step. Note that the present solver can be dramatically improved: by using a Newton method, as shown by [START_REF] Saramito | On a modified non-singular log-conformation formulation for Johnson-Segalman viscoelastic fluids[END_REF], it is possible to directly reach the stationnary solution, but such more sophisticated implementation is out of the scope of the present documentation.

The visualization of the stream function writes:

branch contraction.branch -toc branch contraction.branch -extract 3 -branch > contraction-We-0.3.field make streamf_contraction field -mark u contraction-We-0.3.field -field | ./streamf_contraction > psi.field field psi.field -n-iso 15 -n-iso-negative 10 field psi.field -n-iso 15 -n-iso-negative 10 -bw

The file 'streamf_contraction.cc' has already been studied in section 2.2.2, in the context of a Newtonian fluid. The result is shown on Fig. 5.14. The vortex growths with W e: this is the major effet observed on this problem. Observe the two color maps representation: positive values of the stream functions are associated to the vortex and negatives values to the main flow region. The last command is a black-and-white variant view.

The vortex activity is obtained by: field psi.field -max

Recall that the minimal value of the stream function is -1, thanks to the dimensionless procedure used here. Cuts along the axis of symmetry are obtained by: field contraction-We-0.3.field -domain axis -mark u -comp 0 -elevation -gnuplot field contraction-We-0.3.field -domain axis -mark tau -comp 00 -elevation -gnuplot field contraction-We-0.3.field -domain axis -mark tau -comp 11 -elevation -gnuplot field contraction-We-0.3.field -domain axis -mark tau -comp 22 -elevation -gnuplot These cuts are plotted on Fig. 5.16. Observe the overshoot of the velocity along the axis when W e > 0 while this effect is not perceptible when W e = 0. Also, the normal extra stress τ zz growth dramatically in the entry region.

Let us introduce the following forms:

The previous problem writes equivalently in abstract form:

Note that the matrix associated to the bilinear form a is symmetric and block-diagonal: it can thus be efficiently inverted on the fly at the element level during the assembly process. The following code implement this efficient approach. The program 'commute_rt.cc' compute both the projection π V h (u) and the standard Lagrange interpolation π h (u), while 'commute_rtd_error.cc' performs the computation of the corresponding errors. The file 'cosinus_vector.h' furnishes the function used for the present test:

These two last files are not listed here but are available in the Rheolef example directory. Observe on Fig. 6.1 that the error for the projection π V h (u) and its divergence behave as O(h k+1 ), which is optimal. Conversely, the error for the Lagrange interpolation π h (u) is sub-optimal for the divergence.

In conclusion, the projection π V h should be used instead of the interpolation π h when we want to build an optimal Raviart-Thomas approximation.

How to run the program

The compilation and run write: make dirichlet_hdg dirichlet_hdg_post ./sinusprod_error_hdg mkgeo_grid -t 10 > square.geo 10 -4

Technical appendices

A.1 How to write a variational formulation ?

The major key-point for using Rheolef is to put the problem in variational form. Then this variational form can be efficiently translated into C++ language. This appendix is dedicated to readers who are not fluent with variational formulations and some related functional analysis tools.

A.1.1 The Green formula

Let us come back to the model problem presented in section 1.1.1, page 14, equations (1.1)-(1.2) and details how this problem is transformed into (1.3).

Let H 1 0 (Ω) the space of functions whose gradient square has a finite sum over Ω and that vanishes on ∂Ω:

H 1 0 (Ω) = {v ∈ L 2 (Ω); ∇v ∈ L 2 (Ω) d and v = 0 on ∂Ω} We start by multiplying (1.1) by an arbitrarily test-function v ∈ H 1 0 (Ω) and then integrate over Ω :

-

The next step is to invoke an integration by part, the so-called Green formula:

Since our test-function v vanishes on the boundary, the integral over ∂Ω is zero and the problem becomes:

This is exactly the variational formulation (1.3), page 14.

A.1.2 The vectorial Green formula

In this section, we come back to the linear elasticity problem presented in section 2.1.1, page 43, equations (2.1)-(2.2) and details how this problem is transformed into (2.3). Let Γ d (resp. Γ n ) denotes the parts of the boundary ∂Ω related to the homogeneous Dirichlet boundary condition u = 0 (resp. the homogeneous Neumann boundary condition σ(u) n = 0). We suppose that ∂Ω = Γ d ∩ Γ n . Let us introduce the following functional space:

This formula is the starting point for all variational formulations of problems defined on a surface (see chapter 3.1).

A.2 How to prepare a mesh ?

Since there is many good mesh generators, Rheolefdoes not provide a built-in mesh generator.

There are several ways to prepare a mesh for Rheolef.

We present here several procedures: by using the bamg bidimensional anisotropic mesh generator, written by [START_REF] Hecht | BAMG: bidimensional anisotropic mesh generator[END_REF], and the gmsh mesh generator, suitable when d = 1, 2 and 3, and written by [START_REF] Geuzaine | Gmsh: a three-dimensional finite element mesh generator with built-in pre-and post-processing facilities[END_REF].

A.2.1 Bidimensional mesh with bamg

We first create a 'square.bamgcad' file: This presents the mesh it in a graphical form, usually with paraview. You can switch to the gnuplot render:

geo square -gnuplot

A finer mesh could be generated by: bamg -coef 0.5 -g square.bamgcad -o square-0.5.bamg

A.2.2 Unidimensional mesh with gmsh

The simplest unidimensional mesh is a line: This is an uniform mesh with element size h = 0.1. We refer to the gmsh documentation [START_REF] Geuzaine | Gmsh: a three-dimensional finite element mesh generator with built-in pre-and post-processing facilities[END_REF] for the complete file format description. Next, enter the mesh generator commands: gmsh -2 square.mshcad -format msh2 -o square.msh Then, enter the translation command: msh2geo square.msh > square.geo This command creates a 'square.geo' file. Look at the mesh via the command: geo square Remark that the domain names, defined in the .mshcad file, are included in the gmsh .msh input file and are propagated in the .geo by the format conversion. Copyright © 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

A.2.4 Tridimensional mesh with gmsh

Preamble

The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

Applicability and Definitions

This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

Modifications

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

• Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

• List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).

• State on the Title page the name of the publisher of the Modified Version, as the publisher.

• Preserve all the copyright notices of the Document.

• Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

• Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.

• Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.

• Include an unaltered copy of this License.

• Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

• Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

• In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

Aggregation With Independent Works

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.

Translation

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License.

In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.

Termination

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

Future Revisions of This License

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. ,11,41,45,57,58,80,50,58,59,64,230 P2,11,15,41,45,57,80,181 Pk,11,245,258 bubble,58 discontinuous trace,258,265 discontinuous,35,44,45,53,143,148,150,226,241,11,15,37 isoparametric,92 mixed,50 geometry curved,23,221 isoparametric,23,258 argc,argv,command ,10,20,35,39,49,56,80,107,115,163,166,167,179,181,199,261 mixed,56,59,66 Neumann,28,31,35,39 '.field' multi-component field, 42 '.geo' mesh, 13, 63, 65, 277-279 '.gz' gzip compressed file, 48 '.mshcad' gmsh geometry, 49, 63, 66, 95, 278 '.msh' gmsh mesh, 49, 63, 66, 278 '.vtk' vtk