0% found this document useful (0 votes)
28 views7 pages

BE Getfem Laplacian Py

getfem

Uploaded by

ncqkhtpkhw
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views7 pages

BE Getfem Laplacian Py

getfem

Uploaded by

ncqkhtpkhw
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

ISAE - MAE Année 2023-2024

Applied Mathematics
A. Ammar, F. Deluzet, A. Estana, M. Fournié, N. Renon

BE : GetFEM++ using Python Interface (Linux system)

1 Problem
The goal of the work is to implement the approximation by finite element method of the Laplacian
equation with source term f given on a square domain Ω = [0, 1] × [0, 1] with Dirichlet boundary condition :

−∆u = f, (x, y) ∈ Ω,
u = g, (x, y) ∈ ∂Ω.

2 Introduction to GetFEM++
GetFEM++ is basically a generic C++ finite element library which aims to offer the widest range of
finite element methods and elementary matrix computations for the approximation of linear or non-linear
problems, possibly in hybrid form and possibly coupled. The dimension of the problem is arbitrary and
may be a parameter of the problem. GetFEM++ offers a description of models in the form of bricks whose
objective is to enable reusability of the approximations made. The system of bricks, is used to assemble
components such as standard models (elasticity in small and large deformations, Helmholtz problem, scalar
elliptic problem ...), components representing the boundary conditions (Neumann, Dirichlet, Fourier-Robin,
contact, friction...), also components representing constraints (incompressibility, removing rigid motions ...)
and coupling components for coupled models. A documentation of the library can be found to the address

http ://getfem.org/userdoc/index.html

GetFEM++ proposed three interfaces (with Scilab, Matlab and Python) that allow to use of the main
features of the software without the need of C++ programming and allowing graphical post-processing. For
that work, we are going to use the Python interface. The documentation can be found to the address

http ://getfem.org/python/index.html

GetFEM++ has only a (very) experimental meshing procedure (and produces regular meshes). It is
therefore often necessary to import meshes. The formats currently supported are Gid, Gmsh and Emc2. For
that work, we consider simple domain then the generation of regular meshes is trivial under the library,
however we are going to use the most popular free software Gmsh.

System environment.
We suggest to use Linux system. Then you have to open a Terminal to manage everything. To move into
your workspace you have the commands ls, cd and so on. Getfem library, Pyhton modules (numpy), Gmsh
and Paraview softwares necessary to do the BE are already installed on your system.

How to use python interface ?


There is several manner to run a python source file, using a dedicated editor (with ”run button”) or
you can create a text file with extension .py for example test.py and call python test.py. If you want
to run commands line-by-line you can first call python alone (RETURN keyborad) and then you can enter
your commands (with RETURN keyboard). In that mode you can use exec(open("./test.py").read())
to run test.py and type quit() to quit the interface mode. An other solution is to use a dedicated editor
like spyder. We suggest to use it for that BE.
Practical aspect (configuration) under python.

At school, all variables environments can be load with the commands (in a terminal) :
module load anaconda3/2023
conda init
open a new terminal
module load anaconda3/2023
module load getfem/5.4.2-mumps
module load gmsh/4.10.0

Perhaps there are slight differences in the call for example module load getfem/5.4.2 instead of
module load getfem, ... use tabulation key on the keyboard to obtain the list of available modules.

The python interface is available via a python module getfem.py. In order to use the interface you have
to load it (under python) with import getfem

To use spyder, the editor must be called after loading the variable environment in the same terminal.

3 The Laplacian problem - step by step


This example studied in this BE shows the basic usage of GetFEM++, on the the canonical problem that
corresponds to solve the Laplacian, on a square, with the Dirichlet condition u = g(x) on the boundary of
the domain. This code is inspired by the example demo_step_by_step.py that is given in the GetFEM++
distribution in the directory interface/tests/python/.
Becareful sometimes, when you copy and paste some command from on pdf or website some bad caracters
are reported. It is the case in particulart for ’, ‘ or ".
You can download file demo_step_by_step.py on LMS and modify it to do some tests and verify if you
arrive to modify something like you want.

3.1 Create a Mesh object


The first step is to create a Mesh object.

• First issue :
It is possible to create simple structured meshes or unstructured meshes for simple geometries
(see getfem.Mesh(’generate’, mesher-object mo, scalar h)). For this example, we just consider some
nodes associated to a regular mesh whose nodes are {xi=0,···10,j=0··· ,10 } :

# import basic modules


import getfem as gf
import numpy as np

# creation of a simple triangular mesh


m = gf.Mesh(’triangles grid’, np.arange(0,1.1,0.1), np.arange(0,1.1,0.1))

• Second issue : which is the more constructive one.


It is possible to import a mesh constructed by an other software. For example, to construct a simple mesh
with gmsh-format (extension .msh), you can use the software gmsh using GUI-interface or using a script
(text file) containing all informations required to construct the mesh.
You can download from LMS such script file square.geo into a specific
directory.
You can open this file with any text editor and you have to understand
the rule of each command to arrive to modify it if necessary.
You have to go into that directory and type into a new Terminal
gmsh square.geo
This action that corresponds to define the Geometry (see the figure
on the right) is equivalent to open gmsh (alone) and to use scroll-bar
File ... Open ...
Then you have to clic on the triangle in front of Mesh in the left part of
the gmsh-window to obtain the corresponding Menu (see the figure on
the right).
Next step : clic on 2D into this window to see the mesh.

You can obtain some informa-


tions on the mesh opening the
window Statistics into the
Tools Menu. For example you
can observe that the mesh has
513 nodes.

Next step corresponds to save the mesh using the File Menu. If the script is called square.geo you
must recover on the disk the corresponding mesh called square.msh. Becarful, a simple clic into the left
menu on Save can create a good mesh but Getfem can have some trouble to use it. To be more efficient, you
can use Export, you select the format *.msh, you specify the name of the output with the good extension
.msh and Save. The last pop-up Menu asks you which format-version you want. Select Version 2 ASCII
and save to create on the disk the mesh square.msh (see the following figures)

An other
issue corresponds to uncomment the three lines to create directly on the disk the mesh with the good name
#Mesh.Algorithm = 6;
#Mesh 2;
#Save "square.msh";
Finally, in the Terminal (where Python turns with Getfem import) you can use the following command
to import the mesh using
m=gf.Mesh(’import’,’gmsh’,’square.msh’)

Notice that in the construction of the mesh you have given 4 flags 10-20-30-40 to identify the left-down-
right-up boundary parts. These integers of your choice into the (geo-file) will be used in the assembling step.
You will have to use exactly the same integer for a given location.

3.2 Selection of the Finite Element (P1 , P2 , Qk , ... )


The next step is to create a MeshFem object. This one links a mesh with a set of FEM

# create a MeshFem of for a field of dimension 1 (i.e. a scalar field)


mf = gf.MeshFem(m, 1)
# assign the P2 fem to all convexes of the MeshFem
mf.set_fem(gf.Fem(’FEM_PK(2,2)’))

The first instruction builds a new MeshFem object, the second argument specifies that this object will
be used to interpolate scalar fields (since the unknown u is a scalar field). The second instruction assigns
the P2 FEM to every convex (each basis function is a polynomial of degree 2). As P2 is a polynomial FEM,
you can view the expression of its basis functions on the reference convex :

# view the expression of its basis functions on the reference convex


print gf.Fem(’FEM_PK(2,2)’).poly_str()

3.3 Selection of the integration method used for assembling step


Now, in order to perform numerical integrations on mf, we need to build a MeshIm object

# an exact integration will be used


mim = gf.MeshIm(m, gf.Integ(’IM_TRIANGLE(3)’))

The integration method will be used to compute the various integrals on each element : here we choose
to perform exact computations (no quadrature formula), which is possible since the geometric transfor-
mation of these convexes from the reference convex is linear (this is true for all simplexes, and this is
also true for the parallelepipeds of our regular mesh, but it is not true for general quadrangles), and the
chosen FEM is polynomial. Hence it is possible to analytically integrate every basis function/product of
basis functions/gradients/etc. There are many alternative FEM methods and integration methods (see User
Documentation).
Note however that in the general case, approximate integration methods are a better choice than exact
integration methods.

3.4 Boundary condition


Now we have to find the boundary of the domain, in order to set a Dirichlet condition. A mesh object
has the ability to store some sets of convexes and convex faces. These sets (called ”regions”) are accessed
via an integer (flags).
• If you have construct your mesh under Getfem, you have to define such flags #id

# detect the border of the mesh


border = m.outer_faces()
# mark it as boundary #42
m.set_region(42, border)
Here we find the faces of the convexes which are on the boundary of the mesh (i.e. the faces which are
not shared by two convexes).
The array border has two rows, on the first row is a convex number, on the second row is a face number
(which is local to the convex, there is no global numbering of faces). Then this set of faces is assigned to the
region number 42 (this is an arbitrary number - flag).

• If you have used Gmsh then this step is already done during the construction of the mesh. In our
example, you have given 4 flags with the integers 10, 20, 30, 40 that play the same rule as 42 in
previous presentation (42 is used for all the boundary contrary to the present case where we split the
boundary into 4 parts).

3.5 The weak formulation (problem dependant)


The model (to collapse all informations)
At this point, we just have to describe the model and run the solver to get the solution. The model
is created with the Model constructor. A model is basically an object which build a global linear system
(tangent matrix for non-linear problems) and its associated right hand side. Typical modifications are in-
sertion of the stiffness matrix for the problem considered (linear elasticity, laplacian, etc), handling of a set
of constraints, Dirichlet condition, addition of a source term to the right hand side etc. The global tangent
matrix (matrix of the linear system) and its right hand side are stored in the model structure.

Let us build a problem with an easy exact solution. To construct such problem, we can choice u(x, y) =
x(x − 1) − y(y − 1) and compute ∆u. We verify that −∆u = 0. So, to have a PDE with that solution, we
can consider the following PDE (that we are going to solve numerically) :

 −∆u = 0 on Ω = [0; 1] × [0; 1],

u = x(x − 1) − y(y − 1) on ∂Ω,


(of course you know the corresponding exact solution u(x, y) = x(x − 1) − y(y − 1)).
Now, we are going to use step by step the finite element library. We start with an empty real model

# empty real model


md = gf.Model(’real’)

(a model is either ’real’ or ’complex’). And we declare that u is an unknown of the system on the finite
element method mf by

# declare that "u" is an unknown of the system


# on the finite element method ‘mf‘
md.add_fem_variable(’u’, mf)

Now, we add a generic elliptic brick, which handles −∇ · (A : ∇u) = . . . problems, where A can be a
scalar field, a matrix field, or an order 4 tensor field. By default, A = 1. Then there are at least two manner
to add it on our main variable u with

# add generic elliptic brick on "u"


md.add_Laplacian_brick(mim, ’u’);

or instead of this command we can use the more interesting one directly inspired by the weak
formulation, see the Documentation for more details
md.add_linear_term(mim, ’Grad_u:Grad_Test_u’)
Next we add a Dirichlet condition on the domain boundary

# add Dirichlet condition


g = mf.eval(’x*(x-1) - y*(y-1)’)
md.add_initialized_fem_data(’DirichletData’, mf, g)

These lines define a data of the model which represents the value of the Dirichlet condition.

• If you use Getfem mesher you can use :


md.add_Dirichlet_condition_with_multipliers(mim, ’u’, mf, 42, ’DirichletData’)

• If you have import square.msh (Gmsh mesher) you can use :


md.add_Dirichlet_condition_with_multipliers(mim, ’u’, mf, 1, ’DirichletData’)
md.add_Dirichlet_condition_with_multipliers(mim, ’u’, mf, 2, ’DirichletData’)
md.add_Dirichlet_condition_with_multipliers(mim, ’u’, mf, 3, ’DirichletData’)
md.add_Dirichlet_condition_with_multipliers(mim, ’u’, mf, 4, ’DirichletData’)

These lines add a Dirichlet condition to the variable u on the boundary number 42 (or on the bondaries
identify by the numbers 1, 2, 3, 4). The Dirichlet condition is imposed with Lagrange multipliers. A MeshFem
argument is also required, as the Dirichlet condition u = g is imposed in a weak form
Z Z
u(x)v(x) = g(x)v(x) ∀v
Γ Γ

where v is taken in the space of multipliers given by here by mf.


Another possibility is to use a penalization or by elimination (see Documentation).

A source term can be added with (uncommented) the following lines

# add source term


#f = mf.eval(’0’)
#md.add_initialized_fem_data(’VolumicData’, mf, f)
#md.add_source_term_brick(mim, ’u’, ’VolumicData’)

The source term is equal to 0 in our example, so it is not necessary to uncomment these commands.

3.6 Solve the linear system and export the solution


It only remains now to launch the solver. The linear system is assembled and solve with the instruction

# solve the linear system


md.solve()
# main unknown
u = md.variable(’u’)

Then export solution under a specific format. The most popular in the VTK format. The output file
can be load using Paraview software.

# export computed solution using vtk format (you can load it with Paraview)
mf.export_to_vtk(’u.vtk’,u,’Computed solution’)

An other export (which is not necessary) can be done using

# export computed solution using gmsh format (you can load it with Gmsh)
mf.export_to_pos(’u.pos’,u,’Computed solution’)
4 TODO for the BE
The goal is to understand all commands used to construct the mesh (*.geo) and to implement the finite
element method under Pytrhon using Getfem Library.

You don’t have to give a report and no mark will be associated to the BE on Getfem
(BE1 and BE2). However, if you arrive to understand the manipulations and results that you
obtain, it is a good training for the final classical exam. Making tests can give you the ans-
wers to questions that you have. Don’t hesitate to discuss with the other students and teachers.

Bellow, find some suggestions :

• Solve the same PDE on the same domain (square) with Dirichlet boundary conditions

−∆u = f where f (x, y) = −(2(x2 + y 2 ) − 2x − 2y + 20x3 ).

Verify that u(x, y) = y(y − 1)x(x − 1) + x4 is a solution.


Remark : This expression can be used to impose boundary conditions.
• Based on the previous PDF, study the accuracy of the finite element method by computing the error
between the exact solution (that you know in the present test) and numerical solution that depends on the
mesh size h. To do that, you can compute the error introduced by the Finite Element Method according to
different norms L2 , H 1 , with the commands

# Errors
L2error = gf.compute(mf, u-g, ’L2 norm’, mim)
H1error = gf.compute(mf, u-g, ’H1 norm’, mim)
print ’Error in L2 norm : ’, L2error
print ’Error in H1 norm : ’, H1error
# export data into vtk-format and view with external Paraview
mfu.export_to_vtk(’sol.vtk’, g,’Exact solution’,u,’Computed solution’)
# or export data into gmsh-format and view with external gmsh
mfu.export_to_pos(’sol.pos’, g,’Exact solution’,u,’Computed solution’)

Make some tests for different meshes where the size of the mesh h tends to zero (use the most interesting
mesher). Plot on a same figure the errors according to h in log-log representation. What do you observe ? Is
it in accordance with the results given in course (see slides) ?

• Change the finite element for example use P4 and observe the number of unknowns that you have
comparing to the P1 or P2 cases.

• Compare the accuracy of the solution for a given mesh using 2 different families of finite element P1
and P2 for example (keep the same mesh).

• Instead of triangular mesh create a quadrangular mesh using the syntax ’FEM_QK(2,2)’ under Get-
fem or create a quadrangular mesh under gmsh before import. For the same number of nodes between a
triangular mesh and a quadrangular mesh coupled with P1 or Q1 , what is the most accurate ?

• If you impose Dirichlet boundary conditions with multiplier or with penalization, which is the most
accurate ?

• Do you arrive to consider Neumann boundary condition ?

• Do you arrive to consider a source term which is not equal to 0 ? · · · · · · · · · · · · · · · · · · · · ·

You might also like