dolfin documentation · 2019-04-02 · dolfin documentation, release 2016.2.0.dev0 4.1.1equation...

37
DOLFIN Documentation Release 2016.2.0.dev0 FEniCS Project June 30, 2016

Upload: others

Post on 11-Jul-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN DocumentationRelease 2016.2.0.dev0

FEniCS Project

June 30, 2016

Page 2: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential
Page 3: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

Contents

1 Installation 3

2 Using DOLFIN 5

3 Getting help 7

4 Demo documentation 9

5 API documentation 21

6 Developer resources 23

7 Indices and tables 33

i

Page 4: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

ii

Page 5: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

This documentation is under development

Contents:

Contents 1

Page 6: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

2 Contents

Page 7: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 1

Installation

1.1 Quick start

1.2 Building from source

1.2.1 Dependencies

3

Page 8: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

4 Chapter 1. Installation

Page 9: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 2

Using DOLFIN

Under development

5

Page 10: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

6 Chapter 2. Using DOLFIN

Page 11: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 3

Getting help

Under development

7

Page 12: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

8 Chapter 3. Getting help

Page 13: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 4

Demo documentation

Under development

Todo

Give some structure to the demos, e.g. beginner, advanced, linear nonlinear, etc.

4.1 Poisson equation

This demo is implemented in a single Python file, demo_poisson.py, which contains both the variational formsand the solver.

This demo illustrates how to:

• Solve a linear partial differential equation

• Create and apply Dirichlet boundary conditions

• Define Expressions

• Define a FunctionSpace

• Create a SubDomain

The solution for 𝑢 in this demo will look as follows:

9

Page 14: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

4.1.1 Equation and problem definition

The Poisson equation is the canonical elliptic partial differential equation. For a domain Ω ⊂ R𝑛 with boundary𝜕Ω = Γ𝐷 ∪ Γ𝑁 , the Poisson equation with particular boundary conditions reads:

−∇2𝑢 = 𝑓 in Ω,

𝑢 = 0 on Γ𝐷,

∇𝑢 · 𝑛 = 𝑔 on Γ𝑁 .

Here, 𝑓 and 𝑔 are input data and 𝑛 denotes the outward directed boundary normal. The most standard variational formof Poisson equation reads: find 𝑢 ∈ 𝑉 such that

𝑎(𝑢, 𝑣) = 𝐿(𝑣) ∀ 𝑣 ∈ 𝑉,

where 𝑉 is a suitable function space and

𝑎(𝑢, 𝑣) =

∫Ω

∇𝑢 · ∇𝑣 d𝑥,

𝐿(𝑣) =

∫Ω

𝑓𝑣 d𝑥 +

∫Γ𝑁

𝑔𝑣 d𝑠.

The expression 𝑎(𝑢, 𝑣) is the bilinear form and 𝐿(𝑣) is the linear form. It is assumed that all functions in 𝑉 satisfy theDirichlet boundary conditions (𝑢 = 0 on Γ𝐷).

In this demo, we shall consider the following definitions of the input functions, the domain, and the boundaries:

• Ω = [0, 1] × [0, 1] (a unit square)

• Γ𝐷 = (0, 𝑦) ∪ (1, 𝑦) ⊂ 𝜕Ω (Dirichlet boundary)

• Γ𝑁 = (𝑥, 0) ∪ (𝑥, 1) ⊂ 𝜕Ω (Neumann boundary)

• 𝑔 = sin(5𝑥) (normal derivative)

• 𝑓 = 10 exp(−((𝑥− 0.5)2 + (𝑦 − 0.5)2)/0.02) (source term)

10 Chapter 4. Demo documentation

Page 15: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

4.1.2 Implementation

This description goes through the implementation (in demo_poisson.py) of a solver for the above describedPoisson equation step-by-step.

First, the dolfin module is imported:

from dolfin import *

We begin by defining a mesh of the domain and a finite element function space 𝑉 relative to this mesh. As the unitsquare is a very standard domain, we can use a built-in mesh provided by the class UnitSquareMesh. In order tocreate a mesh consisting of 32 x 32 squares with each square divided into two triangles, we do as follows

# Create mesh and define function spacemesh = UnitSquareMesh(32, 32)V = FunctionSpace(mesh, "Lagrange", 1)

The second argument to FunctionSpace is the finite element family, while the third argument specifies the poly-nomial degree. Thus, in this case, our space V consists of first-order, continuous Lagrange finite element functions (orin order words, continuous piecewise linear polynomials).

Next, we want to consider the Dirichlet boundary condition. A simple Python function, returning a boolean, can beused to define the subdomain for the Dirichlet boundary condition (Γ𝐷). The function should return True for thosepoints inside the subdomain and False for the points outside. In our case, we want to say that the points (𝑥, 𝑦) suchthat 𝑥 = 0 or 𝑥 = 1 are inside on the inside of Γ𝐷. (Note that because of rounding-off errors, it is often wise to insteadspecify 𝑥 < 𝜖 or 𝑥 > 1 − 𝜖 where 𝜖 is a small number (such as machine precision).)

# Define Dirichlet boundary (x = 0 or x = 1)def boundary(x):

return x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS

Now, the Dirichlet boundary condition can be created using the class DirichletBC. A DirichletBC takes threearguments: the function space the boundary condition applies to, the value of the boundary condition, and the partof the boundary on which the condition applies. In our example, the function space is V, the value of the boundarycondition (0.0) can represented using a Constant and the Dirichlet boundary is defined immediately above. Thedefinition of the Dirichlet boundary condition then looks as follows:

# Define boundary conditionu0 = Constant(0.0)bc = DirichletBC(V, u0, boundary)

Next, we want to express the variational problem. First, we need to specify the trial function 𝑢 and the test function𝑣, both living in the function space 𝑉 . We do this by defining a TrialFunction and a TestFunction on thepreviously defined FunctionSpace V.

Further, the source 𝑓 and the boundary normal derivative 𝑔 are involved in the variational forms, and hence wemust specify these. Both 𝑓 and 𝑔 are given by simple mathematical formulas, and can be easily declared using theExpression class. Note that the strings defining f and g use C++ syntax since, for efficiency, DOLFIN will generateand compile C++ code for these expressions at run-time.

With these ingredients, we can write down the bilinear form a and the linear form L (using UFL operators). Insummary, this reads

# Define variational problemu = TrialFunction(V)v = TestFunction(V)f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=2)g = Expression("sin(5*x[0])", degree=2)a = inner(grad(u), grad(v))*dxL = f*v*dx + g*v*ds

4.1. Poisson equation 11

Page 16: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

Now, we have specified the variational forms and can consider the solution of the variational problem. First, we needto define a Function u to represent the solution. (Upon initialization, it is simply set to the zero function.) AFunction represents a function living in a finite element function space. Next, we can call the solve function withthe arguments a == L, u and bc as follows:

# Compute solutionu = Function(V)solve(a == L, u, bc)

The function u will be modified during the call to solve. The default settings for solving a variational problem havebeen used. However, the solution process can be controlled in much more detail if desired.

A Function can be manipulated in various ways, in particular, it can be plotted and saved to file. Here, we outputthe solution to a VTK file (using the suffix .pvd) for later visualization and also plot it using the plot command:

# Save solution in VTK formatfile = File("poisson.pvd")file << u

# Plot solutionplot(u, interactive=True)

4.2 Singular Poisson

This demo is implemented in a single Python file, demo_singular-poisson.py, which contains both the varia-tional forms and the solver.

This demo illustrates how to:

• Solve a linear partial differential equation

• Apply non-zero Neumann boundary conditions

• Define Expressions

• Define a FunctionSpace

• Use the Krylov solver

• Solve singular problems

The solution for 𝑢 in this demo will look as follows:

12 Chapter 4. Demo documentation

Page 17: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

4.2.1 Equation and problem definition

The Poisson equation is the canonical elliptic partial differential equation. For a domain Ω ∈ R𝑛 with boundaryΓ = 𝜕Ω, the Poisson equation with pure Neumann boundary conditions reads:

−∇2𝑢 = 𝑓 in Ω

∇𝑢 · 𝑛 = 𝑔 on Γ

Since only Neumann conditions are applied, 𝑢 is only determined up to a constant by the above equations. An additionconstraint is thus required, for instance ∫

𝑢d𝑥 = 0

The most standard variational form of the Poisson equation reads: find 𝑢 ∈ 𝑉 such that

𝑎(𝑢, 𝑣) = 𝐿(𝑣) ∀ 𝑣 ∈ 𝑉,

where 𝑉 is a suitable function space and

𝑎(𝑢, 𝑣) =

∫Ω

∇𝑢 · ∇𝑣 d𝑥,

𝐿(𝑣) =

∫Ω

𝑓𝑣 d𝑥 +

∫Γ

𝑔𝑣 d𝑠.

The expression 𝑎(𝑢, 𝑣) is the bilinear form and 𝐿(𝑣) is the linear form.

If we make the Ansatz that 𝑢 can be expressed as a linear combination of the basis functions of 𝑉 , and discretize theequation, we can write our problem as a linear system:

𝐴𝑈 = 𝑏,

where 𝑈 gives the coefficient for the basis functions expressing 𝑢.

Since we have pure Neumann boundary conditions, the matrix 𝐴 is singular. There exists a non-trival vector 𝑒 suchthat

𝐴𝑒 = 0.

4.2. Singular Poisson 13

Page 18: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

span 𝑒 is the null space of A. Consequently, the matrix 𝐴 is rank deficient and the right-hand side vector 𝑏 may failto be in the column space of 𝐴. We therefore need to remove the components of 𝑏 that do not lie in the column spaceto make the system solvable.

In this demo, we shall consider the following definitions of the input functions, the domain, and the boundaries:

• Ω = [0, 1] × [0, 1] (a unit square)

• Γ = 𝜕Ω (boundary)

• 𝑔 = − sin(5𝑥) (normal derivative)

• 𝑓 = 10 exp(−((𝑥− 0.5)2 + (𝑦 − 0.5)2)/0.02) (source term)

4.2.2 Implementation

This description goes through the implementation (in demo_singular-poisson.py) of a solver for the abovedescribed Poisson equation step-by-step.

First, the dolfin module is imported:

from dolfin import *

Then, we check that dolfin is configured with the backend called PETSc, since it provides us with a wide range ofmethods used by KrylovSolver. We set PETSc as our backend for linear algebra.

# Test for PETScif not has_linear_algebra_backend("PETSc"):

info("DOLFIN has not been configured with PETSc. Exiting.")exit()

parameters["linear_algebra_backend"] = "PETSc"

We begin by defining a mesh of the domain and a finite element function space 𝑉 relative to this mesh. We use abuilt-in mesh provided by the class UnitSquareMesh. In order to create a mesh consisting of 64× 64 squares witheach square divided into two triangles, we do as follows:

# Create mesh and define function spacemesh = UnitSquareMesh(64, 64)V = FunctionSpace(mesh, "CG", 1)

Now, we need to specify the trial functions (the unknowns) and the test functions on the space 𝑉 . This can be doneusing a TrialFunction and a TestFunction as follows:

u = TrialFunction(V)v = TestFunction(V)

Further, the source 𝑓 and the boundary normal derivative 𝑔 are involved in the variational forms, and hence wemust specify these. Both 𝑓 and 𝑔 are given by simple mathematical formulas, and can be easily declared using theExpression class. Note that the strings defining f and g use C++ syntax since, for efficiency, DOLFIN will generateand compile C++ code for these expressions at run-time.

f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=2)g = Expression("-sin(5*x[0])", degree=2)

With 𝑢, 𝑣, 𝑓 and 𝑔, we can write down the bilinear form 𝑎 and the linear form 𝐿 (using UFL operators).

a = inner(grad(u), grad(v))*dxL = f*v*dx + g*v*ds

14 Chapter 4. Demo documentation

Page 19: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

In order to transform our variational problem into a linear system we need to assemble the coefficient matrix A and theright-side vector b. We do this using the function assemble:

# Assemble systemA = assemble(a)b = assemble(L)

We specify a Vector for storing the result by defining a Function.

# Solution Functionu = Function(V)

Next, we specify the iterative solver we want to use, in this case a PETScKrylovSolverwith the conjugate gradient(CG) method, and attach the matrix operator to the solver.

# Create Krylov solversolver = PETScKrylovSolver("cg")solver.set_operator(A)

We impose our additional constraint by removing the null space component from the solution vector. In order to dothis we need a basis for the null space. This is done by creating a vector that spans the null space, and then defining abasis from it. The basis is then attached to the matrix A as its null space.

# Create vector that spans the null space and normalizenull_vec = Vector(u.vector())V.dofmap().set(null_vec, 1.0)null_vec *= 1.0/null_vec.norm("l2")

# Create null space basis object and attach to PETSc matrixnull_space = VectorSpaceBasis([null_vec])as_backend_type(A).set_nullspace(null_space)

Orthogonalization of b with respect to the null space makes sure that it doesn’t contain any component in the nullspace.

null_space.orthogonalize(b);

Finally we are able to solve our linear system

solver.solve(u.vector(), b)

and plot the solution

plot(u, interactive=True)

4.3 Poisson equation (C++)

This demo illustrates how to:

• Solve a linear partial differential equation

• Create and apply Dirichlet boundary conditions

• Define Expressions

• Define a FunctionSpace

• Create a SubDomain

4.3. Poisson equation (C++) 15

Page 20: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

The solution for 𝑢 in this demo will look as follows:

4.3.1 Equation and problem definition

The Poisson equation is the canonical elliptic partial differential equation. For a domain Ω ⊂ R𝑛 with boundary𝜕Ω = Γ𝐷 ∪ Γ𝑁 , the Poisson equation with particular boundary conditions reads:

−∇2𝑢 = 𝑓 in Ω,

𝑢 = 0 on Γ𝐷,

∇𝑢 · 𝑛 = 𝑔 on Γ𝑁 .

Here, 𝑓 and 𝑔 are input data and 𝑛 denotes the outward directed boundary normal. The most standard variational formof Poisson equation reads: find 𝑢 ∈ 𝑉 such that

𝑎(𝑢, 𝑣) = 𝐿(𝑣) ∀ 𝑣 ∈ 𝑉,

where 𝑉 is a suitable function space and

𝑎(𝑢, 𝑣) =

∫Ω

∇𝑢 · ∇𝑣 d𝑥,

𝐿(𝑣) =

∫Ω

𝑓𝑣 d𝑥 +

∫Γ𝑁

𝑔𝑣 d𝑠.

The expression 𝑎(𝑢, 𝑣) is the bilinear form and 𝐿(𝑣) is the linear form. It is assumed that all functions in 𝑉 satisfy theDirichlet boundary conditions (𝑢 = 0 on Γ𝐷).

In this demo, we shall consider the following definitions of the input functions, the domain, and the boundaries:

• Ω = [0, 1] × [0, 1] (a unit square)

• Γ𝐷 = (0, 𝑦) ∪ (1, 𝑦) ⊂ 𝜕Ω (Dirichlet boundary)

• Γ𝑁 = (𝑥, 0) ∪ (𝑥, 1) ⊂ 𝜕Ω (Neumann boundary)

• 𝑔 = sin(5𝑥) (normal derivative)

• 𝑓 = 10 exp(−((𝑥− 0.5)2 + (𝑦 − 0.5)2)/0.02) (source term)

16 Chapter 4. Demo documentation

Page 21: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

4.3.2 Implementation

The implementation is split in two files: a form file containing the definition of the variational forms expressed in UFLand a C++ file containing the actual solver.

Running this demo requires the files: main.cpp, Poisson.ufl and CMakeLists.txt.

UFL form file

The first step is to define the variational problem at hand. We define the variational problem in UFL terms in a separateform file Poisson.ufl. We begin by defining the finite element:

element = FiniteElement("Lagrange", triangle, 1)

The first argument to FiniteElement is the finite element family, the second argument specifies the domain, whilethe third argument specifies the polynomial degree. Thus, in this case, our element element consists of first-order,continuous Lagrange basis functions on triangles (or in order words, continuous piecewise linear polynomials ontriangles).

Next, we use this element to initialize the trial and test functions (𝑢 and 𝑣) and the coefficient functions (𝑓 and 𝑔):

u = TrialFunction(element)v = TestFunction(element)f = Coefficient(element)g = Coefficient(element)

Finally, we define the bilinear and linear forms according to the variational formulation of the equations:

a = inner(grad(u), grad(v))*dxL = f*v*dx + g*v*ds

Before the form file can be used in the C++ program, it must be compiled using FFC by running (on the command-line):

ffc -l dolfin Poisson.ufl

Note the flag -l dolfin which tells FFC to generate DOLFIN-specific wrappers that make it easy to access thegenerated code from within DOLFIN.

cpp program

The main solver is implemented in the main.cpp file.

At the top we include the DOLFIN header file and the generated header file “Poisson.h” containing the variationalforms for the Poisson equation. For convenience we also include the DOLFIN namespace.

#include <dolfin.h>#include "Poisson.h"

using namespace dolfin;

Then follows the definition of the coefficient functions (for 𝑓 and 𝑔), which are derived from the Expression classin DOLFIN

// Source term (right-hand side)class Source : public Expression

void eval(Array<double>& values, const Array<double>& x) const

4.3. Poisson equation (C++) 17

Page 22: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

double dx = x[0] - 0.5;double dy = x[1] - 0.5;values[0] = 10*exp(-(dx*dx + dy*dy) / 0.02);

;

// Normal derivative (Neumann boundary condition)class dUdN : public Expression

void eval(Array<double>& values, const Array<double>& x) constvalues[0] = sin(5*x[0]);

;

The DirichletBoundary is derived from the SubDomain class and defines the part of the boundary to whichthe Dirichlet boundary condition should be applied.

// Sub domain for Dirichlet boundary conditionclass DirichletBoundary : public SubDomain

bool inside(const Array<double>& x, bool on_boundary) constreturn x[0] < DOLFIN_EPS or x[0] > 1.0 - DOLFIN_EPS;

;

Inside the main function, we begin by defining a mesh of the domain. As the unit square is a very standard domain,we can use a built-in mesh provided by the class UnitSquareMesh. In order to create a mesh consisting of 32 x32 squares with each square divided into two triangles, and the finite element space (specified in the form file) definedrelative to this mesh, we do as follows

int main()

// Create mesh and function spaceauto mesh = std::make_shared<UnitSquareMesh>(32, 32);auto V = std::make_shared<Poisson::FunctionSpace>(mesh);

Now, the Dirichlet boundary condition (𝑢 = 0) can be created using the class DirichletBC. A DirichletBCtakes three arguments: the function space the boundary condition applies to, the value of the boundary condition,and the part of the boundary on which the condition applies. In our example, the function space is V, the value ofthe boundary condition (0.0) can represented using a Constant, and the Dirichlet boundary is defined by the classDirichletBoundary listed above. The definition of the Dirichlet boundary condition then looks as follows:

// Define boundary conditionauto u0 = std::make_shared<Constant>(0.0);auto boundary = std::make_shared<DirichletBoundary>();DirichletBC bc(V, u0, boundary);

Next, we define the variational formulation by initializing the bilinear and linear forms (𝑎, 𝐿) using the previouslydefined FunctionSpace V. Then we can create the source and boundary flux term (𝑓 , 𝑔) and attach these to thelinear form.

// Define variational formsPoisson::BilinearForm a(V, V);Poisson::LinearForm L(V);auto f = std::make_shared<Source>();auto g = std::make_shared<dUdN>();

18 Chapter 4. Demo documentation

Page 23: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

L.f = f;L.g = g;

Now, we have specified the variational forms and can consider the solution of the variational problem. First, we needto define a Function u to store the solution. (Upon initialization, it is simply set to the zero function.) Next, we cancall the solve function with the arguments a == L, u and bc as follows:

// Compute solutionFunction u(V);solve(a == L, u, bc);

The function u will be modified during the call to solve. A Function can be manipulated in various ways, inparticular, it can be plotted and saved to file. Here, we output the solution to a VTK file (using the suffix .pvd) forlater visualization and also plot it using the plot command:

// Save solution in VTK formatFile file("poisson.pvd");file << u;

// Plot solutionplot(u);interactive();

return 0;

4.3. Poisson equation (C++) 19

Page 24: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

20 Chapter 4. Demo documentation

Page 25: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 5

API documentation

Under development

21

Page 26: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

22 Chapter 5. API documentation

Page 27: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 6

Developer resources

DOLFIN development takes place on Bitbucket.

6.1 C++ coding style guide

6.1.1 Naming conventions

Class names

Use camel caps for class names:

class FooBar

...;

Function names

Use lower-case for function names and underscore to separate words:

foo();bar();foo_bar(...);

Functions returning a value should be given the name of that value, for example:

class Array:public:

/// Return size of array (number of entries)std::size_t size() const;

;

In the above example, the function should be named size rather than get_size. On the other hand, a functionnot returning a value but rather taking a variable (by reference) and assigning a value to it, should use the get_foonaming scheme, for example:

23

Page 28: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

class Parameters:public:

/// Retrieve all parameter keysvoid get_parameter_keys(std::vector<std::string>& parameter_keys) const;

;

Variable names

Use lower-case for variable names and underscore to separate words:

Foo foo;Bar bar;FooBar foo_bar;

Enum variables and constants

Enum variables should be lower-case with underscore to separate words:

enum Type foo, bar, foo_bar;

We try to avoid using #define to define constants, but when necessary constants should be capitalized:

#define FOO 3.14159265358979

File names

Use camel caps for file names if they contain the declaration/definition of a class. Header files should have the suffix.h and implementation files should have the suffix .cpp:

FooBar.hFooBar.cpp

Use lower-case for file names that contain utilities/functions (not classes).

6.1.2 Miscellaneous

Indentation

Indentation should be two spaces and it should be spaces. Do not use tab(s).

Comments

Comment your code, and do it often. Capitalize the first letter and don’t use punctuation (unless the comment runsover several sentences). Here’s a good example from TopologyComputation.cpp:

// Check if connectivity has already been computedif (connectivity.size() > 0)

return;

24 Chapter 6. Developer resources

Page 29: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

// Invalidate orderingmesh._ordered = false;

// Compute entities if they don't existif (topology.size(d0) == 0)

compute_entities(mesh, d0);if (topology.size(d1) == 0)

compute_entities(mesh, d1);

// Check if connectivity still needs to be computedif (connectivity.size() > 0)

return;

...

Always use // for comments and /// for documentation (see Documenting the interface (Programmer’s reference)).Never use /* ... */, not even for comments that runs over multiple lines.

Integers and reals

Use std::size_t instead of int (unless you really want to use negative integers or memory usage is critical).

std::size_t i = 0;double x = 0.0;

Placement of brackets and indent style

Use the BSD/Allman style when formatting blocks of code, i.e., curly brackets following multiline control statementsshould appear on the next line and should not be indented:

for (std::size_t i = 0; i < 10; i++)

...

For one line statements, omit the brackets:

for (std::size_t i = 0; i < 10; i++)foo(i);

Header file layout

Header files should follow the below template:

// Copyright (C) 2008 Foo Bar//// This file is part of DOLFIN.//// DOLFIN is free software: you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// DOLFIN is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of

6.1. C++ coding style guide 25

Page 30: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.//// Modified by Bar Foo 2008

#ifndef __FOO_H#define __FOO_H

namespace dolfin

class Bar; // Forward declarations here

/// Documentation of class

class Foopublic:

...

private:

...

;

#endif

Implementation file layout

Implementation files should follow the below template:

// Copyright (C) 2008 Foo Bar//// This file is part of DOLFIN.//// DOLFIN is free software: you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// DOLFIN is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.//// Modified by Bar Foo 2008

26 Chapter 6. Developer resources

Page 31: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

#include <dolfin/Foo.h>

using namespace dolfin;

//-----------------------------------------------------------------------------Foo::Foo() : // variable initialization here

...//-----------------------------------------------------------------------------Foo::~Foo()

// Do nothing//-----------------------------------------------------------------------------

The horizontal lines above (including the slashes) should be exactly 79 characters wide.

Including header files and using forward declarations

Do not use #include <dolfin.h> or #include <dolfin/dolfin_foo.h> inside the DOLFIN sourcetree. Only include the portions of DOLFIN you are actually using.

Include as few header files as possible and use forward declarations whenever possible (in header files). Put the#include in the implementation file. This reduces compilation time and minimizes the risk of cyclic dependencies.

Explicit constructors

Make all one argument constructors (except copy constructors) explicit:

class Foo

explicit Foo(std::size_t i);;

Virtual functions

Always declare inherited virtual functions as virtual in the subclasses. This makes it easier to spot which functions arevirtual.

class Foo

virtual void foo();virtual void bar() = 0;

;

class Bar : public Foo

virtual void foo();virtual void bar();

;

6.1. C++ coding style guide 27

Page 32: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

6.1.3 Use of libraries

Prefer C++ strings and streams over old C-style char*

Use std::string instead of const char* and use std::istream and std::ostream instead of FILE.Avoid printf, sprintf and other C functions.

There are some exceptions to this rule where we need to use old C-style function calls. One such exception is handlingof command-line arguments (char* argv[]).

Prefer smart pointers over plain pointers

Use std::shared_ptr and std::unique_ptr in favour of plain pointers. Smart pointers reduce the likelihoodof memory leaks and make ownership clear. Use unique_ptr for a pointer that is not shared and shared_ptrwhen multiple pointers point to the same object.

6.2 Documenting the interface (Programmer’s reference)

The DOLFIN Programmer’s Reference is generated for the DOLFIN C++ library and Python module from the sourcecode using the documentation tool Sphinx. This page describes how to generate the DOLFIN documentation locallyand how to extend the contents of the Programmer’s Reference.

6.2.1 How to locally build the DOLFIN documentation

The DOLFIN documentation can be generated and built from the DOLFIN source directly as follows:

• Make sure that Sphinx is installed.

• Build DOLFIN (for instructions, see installation_from_source).

• Build the documentation by running:

make doc

in the DOLFIN build directory.

For make doc to successfully run, the DOLFIN Python module must be installed.

6.2.2 How to improve and extend the DOLFIN Programmer’s reference

The documentation contents are extracted from specially formatted comments (docstring comments) in the sourcecode, converted to reStructuredText, and formatted using Sphinx. The syntax used for these specially formattedcomments is described below.

To document a feature,

1. Add appropriate docstring comments to source files (see Syntax for docstring comments).

2. If you made changes to C++ header files or docstrings in dolfin_dir/dolfin/swig/*.i youshould update the dolfin_dir/dolfin/swig/codeexamples.py file with an example snip-pet if applicable and run the script dolfin_dir/dolfin/swig/generate.py to update thedolfin_dir/dolfin/swig/docstrings.i file.

3. Build the documentation as described in How to locally build the DOLFIN documentation to check the result.

28 Chapter 6. Developer resources

Page 33: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

Syntax for docstring comments

As Sphinx does not allow sections in the markup for class/function documentation, we use italics (*italics*) anddefinition lists to group information. This is to keep the markup as simple as possible since the reST source for thePython documentation of classes and functions will be used ‘as is’ in the docstrings of the DOLFIN module.

Most information can be put in the three sections:

• Arguments, which are formatted using definition lists following this structure:

*Arguments*<name> (<type>)

<description><name2> (<type>)

<description>

For example:

*Arguments*dim (int)

some dimension.d (double)

some value.

• Returns, which is formatted in a similar fashion:

*Returns*<return type>

<description>

For example:

*Returns*int

Some random integer.

• Example, a very small code snippet that shows how the class/function works. It does not necessarily have to bea stand-alone program.

An example of how to document a feature

To make matters more concrete let’s consider the case of writing documentation for the member functionclosest_cell of the DOLFIN Mesh class. The Python interface to this class is generated by Swig and it isnot extended in the Python layer. Writing documentation for other classes and functions in DOLFIN which are notextended or added in the Python layer follow a similar procedure.

The Mesh::closest_cell function is defined in the file dolfin_dir/dolfin/mesh/Mesh.h, and thecomment lines and function definition look as follows:

/// Computes the index of the cell in the mesh which is closest to the/// point query.////// *Arguments*/// point (_Point_)/// A _Point_ object.////// *Returns*/// uint/// The index of the cell in the mesh which is closest to point.

6.2. Documenting the interface (Programmer’s reference) 29

Page 34: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

////// *Example*/// .. code-block:: c++////// UnitSquare mesh(1, 1);/// Point point(0.0, 2.0);/// info("%d", mesh.closest_cell(point));////// output::////// 1dolfin::uint closest_cell(const Point& point) const;

Note that the documentation of a function or class is placed above the definition in the source code. The structure andcontent follow the guidelines in the previous section.

The Point object is a class like Mesh and it is defined in the FEniCS interface. To insert a link to the documentationof this class use leading and trailing underscore i.e., _Point_. When parsing the comment lines this string will besubstituted with either :cpp:class:‘Point‘ or :py:class:‘Point‘ depending on whether documentationfor the C++ or Python interface is being generated. The return type, in this case dolfin::uint, will automaticallybe mapped to the correct Python type when generating the documentation for the Python interface. Note that if youare writing documentation for one of the functions/classes which are added to the Python layer manually you have toadd manually the correct links and types.

The example code uses C++ syntax because it is located in the C++ header file. Translating this code to a correctPython equivalent is rather difficult. It is therefore necessary to add example code using the Python syntax manu-ally. This code should be put in the dolfin_dir/dolfin/swig/codeexamples.py which contains a simpledictionary of example code. The dictionary containing only the example code for the example above should look asfollows:

codesnippets = "Mesh":"dolfin::uint closest_cell(const Point& point) const":""".. code-block:: python

>>> mesh = dolfin.UnitSquare(1, 1)>>> point = dolfin.Point(0.0, 2.0)>>> mesh.closest_cell(point)1

"""

The first dictionary contains dictionaries for all classes with code examples for each function. Note that the full C++function signature has been used to identify the function to which the code example belongs.

After adding the documentation to the Mesh.h file and Python code example to the codeexamples.pyfile, you have to run the script dolfin/dolfin/swig/generate.py to generate thedolfin/dolfin/swig/docstrings.i file and then build DOLFIN to update the docstrings in the dolfinPython module.

Why is the documentation procedure so elaborate?

The procedure for writing documentation might seem cumbersome so let’s have a look at the design considerationswhich have led to this ostensible case of overengineering.

The Python interface is (partially) generated automatically using Swig from the C++ implementation of DOLFIN.Some classes are extended when building (see the dolfin/dolfin/swig/*post.i files) while others are added

30 Chapter 6. Developer resources

Page 35: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

or extended manually in the Python layer defined in dolfin/site-packages/dolfin. While this approachsaves a lot of work when implementing the Python interface it puts some constraints on the way the documentationcan be handled. In addition we have the following design goals for writing and maintaining the documentation:

Avoid duplicate text In many cases the documentation of a feature will be virtually identical for the C++ and Pythoninterfaces, and since the Python interface is generated from the C++ code, the documentation should be in theC++ source code. To avoid that the documentation on these pages and the comments in the source code (andthe implementation itself) diverge, the documentation should be automatically generated from the C++ sourcecode. Therefore the comments should be written using Sphinx markup.

Help in the Python interpreter The documentation of a class/function when running help(dolfin.foo) in thePython interpreter should be identical to what can be found online. In practice this means that we have togenerate the dolfin/dolfin/swig/docstrings.i file using the comments extracted from the C++source before building the Python interface with Swig.

Simple markup Since the documentation is written directly in the C++ source code, we want markup to be simplesuch that we have ‘code with comments’ rather than ‘comments with code’. Another reason for preferringsimple markup is that it is the raw docstring which will be available from the Python interpreter.

6.2. Documenting the interface (Programmer’s reference) 31

Page 36: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

DOLFIN Documentation, Release 2016.2.0.dev0

32 Chapter 6. Developer resources

Page 37: DOLFIN Documentation · 2019-04-02 · DOLFIN Documentation, Release 2016.2.0.dev0 4.1.1Equation and problem definition The Poisson equation is the canonical elliptic partial differential

CHAPTER 7

Indices and tables

• genindex

• modindex

• search

33