Lab 3.

advertisement
Implementation in FEniCS
Computer Lab 3
FEniCS is a collection of open-source finite element software for solving partial differential equations in any space dimensions and polynomial degrees. The software is written
in a way that the high-level user does not need to get access to its low level sub-projects,
for instance the assembly loops, quadrature points, linear algebra back-ends. Python and
C++ are used as the user interface, where the problem formulations, meshing, boundary
conditions and post-processings can be performed. Below we discuss the implementation
for the Poisson’s equation using the C++ interface. However, one can use the Python
interface if it is preferred.
You will get an access to the unix machines in the department. Then you will have to ssh
into fenics.it.uu.se, create a folder where you will put the files and work with them.
The packages related to FEniCS are all installed in fenics.it.uu.se.
Here are the steps that help you to login to fenics.it.uu.se:
From unix machines:
ssh -X y o u r _ u s e r _ n a m e @ f e n i c s . it . uu . se
From home computers:
ssh y o u r _ u s e r _ n a m e @ l i n n e . it . uu . se
ssh y o u r _ u s e r _ n a m e @ f e n i c s . it . uu . se
Copy a file/folder from fenics.it.uu.se:
scp -r
y o u r _ u s e r _ n a m e @ l i n n e . it . uu . se :~/ p a t h _ t o _ y o u r _ f i l e _ o r _ f o l d e r
Copy a file/folder to fenics.it.uu.se:
scp
y o ur _ f il e _ or _ f ol d e r
y o u r _ u s e r _ n a m e @ l i n n e . it . uu . se :~/ pat h_ to _t he _f ol de r
1
Warming-up with the Poisson’s problem
Consider the following Poisson’s problem:
−∆u = f,
in Ω = {[0, 1] × [0, 1]},
u = 0,
on ΓD = {x1 = 0 or x1 = 1},
∂n u = g,
on ΓN = {x2 = 0 or x2 = 1},
(1)
where the source function and normal derivative are given as follows:
(x1 − 0.5)2 + (x2 − 0.5)2
f = 10 exp −
,
0.02
g = sin(5x1 ).
Detailed implementation steps are documented here:
http://fenicsproject.org/documentation/dolfin/1.4.0/cpp/demo/documented/poisson/
cpp/documentation.html
The followings steps are done to solve the Poisson’s problem in FEniCS. You can skip
these steps and go directly to Task 1.1.
Step 1. Create a txt file and name it Poisson.ufl. Then insert the following variational
formulation of (1) in FEniCS-UFL language:
element = FiniteElement ( " Lagrange " , triangle , 1 )
u = TrialFunction ( element )
v = TestFunction ( element )
f = Coefficient ( element )
g = Coefficient ( element )
a = inner ( grad ( u ) , grad ( v ) ) * dx
L = f * v * dx + g * v * ds
In the above UFL-script *dx denotes integration over the element, which is triangle in
our case, and *ds denotes a boundary integration over the physical boundary ∂Ω. That
means that the second integral is active if the triangle shares an edge with the physical
boundary and in-homogeneous Neumann boundary condition is used, otherwise it is zero.
Step 2. In the command line run
ffc -l dolfin Poisson . ufl
2
Where FEniCS-FFC is called to generate C++ code to assemble local stiffness matrix,
load vector and boundary integrals: Poisson.h.
Step 3. Now create main.cpp that calls classes from FEniCS-DOLFIN, which is a
collection of classes written in C++ that provides the main user interface of FEniCS.
Include FEniCS-DOLFIN and the generated C++ code:
# include < dolfin . h >
# include " Poisson . h "
using namespace dolfin ;
Functions for the source and boundary terms are constructed from the DOFLIN class
Expression:
// Source term ( right - hand side )
class Source : public Expression
{
void eval ( Array < double > & values , const Array < double > & x ) const
{
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 ) const
{
values [ 0 ] = sin ( 5 * x [ 0 ] ) ;
}
};
We need to define subdomains for Dirichlet boundary condition. For example the below
class describes the left and right boundaries in the unit square.
// Sub domain for Dirichlet boundary condition
class Diric hletBo undary : public SubDomain
{
bool inside ( const Array < double > & x , bool on_boundary ) const
{
return x [ 0 ] < DOLFIN_EPS or x [ 0 ] > 1 . 0 - DOLFIN_EPS ;
3
}
};
The main part of the program is the following code. UnitSquareMesh is a class in DOLFIN
that creates the unit square mesh with given number of points in each directions. The
bilinear and linear forms are classes that are automatically generated by FFC from Step
2.
int main ()
{
// Create mesh and function space
UnitSquareMesh mesh ( 32 , 32 ) ;
Poisson : : FunctionSpace V ( mesh ) ;
// Define boundary condition
Constant u0 ( 0 . 0 ) ;
Dir ichlet Bounda ry boundary ;
DirichletBC bc (V , u0 , boundary ) ;
// Define variational forms
Poisson : : BilinearForm a (V , V ) ;
Poisson : : LinearForm L ( V ) ;
Source f ;
dUdN g ;
L.f = f;
L.g = g;
// Compute solution
Function u ( V ) ;
solve ( a = = L , u , bc ) ;
// Save solution in VTK format
File file ( " poisson . pvd " ) ;
file < < u ;
// Plot solution
plot ( u ) ;
interactive () ;
return 0 ;
}
Step 4. Download the cmake configuration file:
4
cp / usr / share / dolfin / demo / documented / poisson / cpp / CMakeLists . txt .
Then do:
cmake .
make
./ demo_possion
Once the program is compiled and run the output will be saved in poisson.pvd, poisson.vtu,
which have the VTK format. There are many powerful commercial and free software
available to visualize the VTK-files. Paraview (www.paraview.org) is one of the powerful, open source, parallel programs that is available for download and installable easily in
many platforms.
Task 1.1. If you are not followed Step 1-4 do the following: download the copy of the
DOLFIN code to solve the Poisson problem:
cp -r / usr / share / dolfin / demo / documented / poisson / cpp / .
Set homogeneous Dirichlet boundary condition on the top and bottom boundaries. And
run:
cd cpp
cmake .
make
./ demo_possion
Visualize your solution using Paraview: change the color-bar, plot the mesh, contour lines,
etc. Run the program after two uniform refinements. (You can change the number of
points in UnitSquareMesh).
Task 1.2. Now change the source function to the one from Assignment 2:
f (x) = 8π 2 sin(2πx1 ) sin(2πx2 ),
Use homogeneous Dirichlet boundary condition for all boundaries and solve the problem.
Use 500 × 500 mesh points and calculate the computation time spent to solve the problem
in your Matlab code and DOLFIN code and report it. For example in C++ it can be
done with the following function:
...
tic () ;
// Here will be your code ...
5
info ( " My code took % f seconds " , toc () ) ;
...
Plot both your Matlab and DOLFIN solutions.
Good luck!
Murtazo
Uppsala, December 2014
6
Download