a small and manageable library which nevertheless encompasses a wide
range of numerical methods and techniques and in particular reduced order
methods such as the reduced basis method.

a software that follows closely the mathematical abstractions
associated with partial differential equations (PDE) and in
particular the finite element mathematical framework and
variational formulations.

a library that offers solving strategies that scales up to
thousands and even tens of thousands of cores.

a library entirely in C++ allowing to create C++ complex and typically
non-linear multi-physics applications currently in industry, physics and
health-care.

Laplacian problem in an arbitrary geometry, defining forms and solving

tic();autol=form1(_test=Vh);l=integrate(_range=elements(mesh),_expr=f*id(v));l+=integrate(_range=markedfaces(mesh,"Robin"),_expr=r_2*id(v));l+=integrate(_range=markedfaces(mesh,"Neumann"),_expr=n*id(v));toc("l");tic();autoa=form2(_trial=Vh,_test=Vh);a=integrate(_range=elements(mesh),_expr=mu*gradt(u)*trans(grad(v)));a+=integrate(_range=markedfaces(mesh,"Robin"),_expr=r_1*idt(u)*id(v));a+=on(_range=markedfaces(mesh,"Dirichlet"),_rhs=l,_element=u,_expr=g);//! if no markers Robin Neumann or Dirichlet are present in the mesh then//! impose Dirichlet boundary conditions over the entire boundaryif(!mesh->hasAnyMarker({"Robin","Neumann","Dirichlet"}))a+=on(_range=boundaryfaces(mesh),_rhs=l,_element=u,_expr=g);toc("a");

Feel++ uses C++14 compilers such as GCC6 and Clang. Currently it is not mandatory to have a C++14 stantard library but it will be soon.

There used to be a major compatibility issue between llvm/clang and GCC
compilers since GCC5 released the ABI tag which makes it impossible to compile
Feel++ using llvm/clang with GCC5 or GCC6 standard libraries for a
time. Please see the following table to understand the working C++ compiler /
C++ standard library combinations.

Table 1. Table C++ compilers and standard libraries combinations

Compiler

Standard Library

clang (3.6, 3.7, 3.8)

libstdc++ 4.9

clang

libc++ (corresponding clang version)

clang (3.8(requires patches), 3.9)

libstdc++ 6

GCC 6

libstdc++ 6

GCC 6.2.1 seems to be problematic on debian/testing — the tests in the testsuite fail. — GCC 6.3.1 or GCC 6.2.0 don’t have any problems.

Other than C++14 compilers, Feel++ requires only a few tools and libraries, namely CMake, Boost C++ libraries and an MPI implementation such as open-mpi or mpich. The table below provides information regarding the minimum and maximum version supported. A — means it has not necessarily been tested with the latest version but we do not expect any issues. Note that for MPI, an implementation with MPI-IO support would be best.

Homebrew is a free/open source software introduced to simplify the installation of other free/open source software on MacOS X. Homebrew is distributed under the BSD 2 Clause (NetBSD) license. For more information, visit their website.

To install the latest version of Homebrew, simply
visit their website and follow the instructions. Each new package Homebrew installs is built into an intermediate place called the Cellar (usually /usr/local/Cellar) and
then the packages are symlinked into /usr/local (default).

Homebrew base command is brew. Here is a list of base available commands:

brew doctor: Check if the system has any problem with the current installation of Homebrew;

brew install mypackage: This command installs the package mypackage;

brew install [--devel|--HEAD] mypackage: These options respectively installs either the development version or the HEAD version of the package mypackage, if such versions are specified in the Formula file;

A Formula is a Ruby script format specific to Homebrew. It allows to describe the installation process of a package. Feel++ uses specific Formulae that you can get in the Feel++ github repository: feelpp/homebrew-feelpp.

If you want to customize the compilation process for a dependency (Set debug mode, Remove checking steps, Remove the link with certain libraries, etc.), you can access to the building options with the info flag. For exemple, with open-mpi:

MacPorts is an open-source community projet which aims to design an easy-to-use system for compiling, installing and upgrading open-source software on Mac OS X operating system. It is distributed under BSD License and facilitate the access to thousands of ports (software) without installing or compiling open-source software. MacPorts provides a single software tree which includes the latest stable releases of approximately 17700 ports targeting the current Mac OS X release (10.9). If you want more information, please visit their website.

To install the latest version of MacPorts, please go
to Installing
MacPorts page and follow the instructions. The simplest way is to
install it with the Mac OS X Installer using the pkg file
provided on their website. It is recommended that you install X11 (X Window System) which is normally used to display X11 applications.
If you have installed with the package installer (MacPorts-2.x.x.pkg) that means MacPorts will be installed in
/opt/local. From now on, we will suppose that macports has
been installed in /opt/local which is the default MacPorts
location. Note that from now on, all tools installed by MacPorts will be installed in /opt/local/bin or /opt/local/sbin
for example (that’s here you’ll find gcc4.7 or later e.g
/opt/local/bin/g++-mp-4.7 once being installed).

port installed: This action displays all ports installed and their versions, variants and activation status. You can also use the -v option to also display the platform and CPU architecture(s) for which the ports were built, and any variants which were explicitly negated.

sudo port upgrade mypackage: This action updgrades installed ports and their dependencies when a Portfile in the repository has been updated. To avoid the upgrade of a port’s dependencies, use the option -n.

A Portfile is a TCL script which usually contains simple
keyword values and TCL expressions. Each package/port has a
corresponding Portfile but it’s only a part of a port description.
Feel++ provides some mandatory Portfiles for its compilation which are either not available in MacPorts or are buggy but Feel++ also provides some Portfiles which are already available in MacPorts such as gmsh or petsc. They usually provide either some fixes to ensure Feel++ works properly or new version not yet available in MacPorts. These Portfiles are installed in ports/macosx/macports.

It might take some time (possibly an entire day) to compile all the requirements for Feel++ to compile properly. If you have several cores on your MacBook Pro, iMac or MacBook, we suggest that you configure macports to use all or some of them.

To do that uncomment the following line in the file
/opt/local/etc/macports/macports.conf

buildmakejobs 0 $\#$ all the cores

At the end of the sudo port install feel++, you have all
dependencies installed. To build all the Makefile, \cmake is
automatically launched but can have some libraries may not be found but they are not mandatory for build Feel++, only the features related to the missing libraries will be missing.

Missing ports

cmake can build Makefiles even if some packages are missing (latex2html, VTK …​). It’s not necessary to install them but you can complete the installation with MacPorts, cmake will find them by itself once they have been installed.

you can speed up the make process by passing the option -j<N> where N is the number of concurrent make sub-processes. It compiles N files at a time and respect dependencies. For example -j4 compiles 4 C++ files at a time.

Be aware that Feel++ consumes memory. The Feel++ library compile with 2Go of RAM. But to be more comfortable, 4Go or more would be best. The more, the better.

If you encounter issues with Feel++, you can run the testsuite and send the resulting report. Feel++ has more than 300 tests running daily on our servers. Most of the tests are run both in sequential and in parallel.

Container based technologies are revolutionizing development,
deployment and execution of softwares. Containers encapsulate a
software and allow to run seamlessly on different platforms — clusters, workstations, laptops — The developer doesn’t have to worry
about specific environments and users spend less time in configuring
and installing the software. Containers appear to be lightweight
virtual machines (VMs) — they are started in a fraction of a second — but they, in fact, have important differences.

One of the differences is the isolation process. The VMs share only
the hypervisor, the OS and hardware whereas containers may share,
between each other, large parts of filesystems rather than having
copies. Another difference is that, unlike in VMs, processes in a
container are similar to native processes and they do not incur the
overhead due to the VM hypervisor. The figure below illustrates these
fundamental differences. We see in particular that the applications 2
and 3 are sharing lib 2 without redundancy.

Figure 1. Figure : VMs vs Containers

Docker is a container technology providing:

an engine to start and stop containers,

a user friendly interface from the creation to the distribution of containers and

a hub — cloud service for container distribution — that provides publicly a huge number of containers to download and avoid duplicating work.

is fully baked and tested software providing a reliable platform to work with. Releases are not frequent.

beta channel

offers cutting edge features and experimental versions of the Docker Engine. This is a continuation of the initial Beta program of Docker to experiment with the latest features in development. It incurs far more instabilities than the stable channel but releases are done frequently — possibly several releases per month.

In the latter we shall consider only installing and using the stable channel.

The support for Mac and Windows as Host OS was recently released and Docker Inc provides installation processes Docker For Mac and Docker for Windows which are the recommended way of installing Docker on these platforms.

On Linux, Docker is a priviledged binary, you need to prefix all your commands with sudo, e.g. on Ubuntu. You need first to belong to the docker group with the following command on Ubuntu

$ sudo usermod -aG docker

It creates the docker group if it doesn’t already exist and adds the current user to the docker group. Then you need to log out and log in again. Similar process is available on other distributions. You need also to restart the docker service

$ sudo service docker restart

From now on, we omit the sudo command when using Docker for the sake of brevity.

Adding a user to the docker group has security implications. On a shared machine, you should consider reading the Docker security page.

We now check your installation by running docker version
To make sure everything is installed correctly and working, try running the docker version command. You should see something like the following on Linux or Mac.

We have called the docker run command which takes care of executing
containers. We passed the argument feelpp/feelpp-env which is a
Feel++ Ubuntu 16.10 container with the required programming
and execution environment for Feel++.

feelpp/ in feelpp/feelpp-env provides the organization name (or namespace) of the image and feelpp-env is the image name. Note also that Docker specifies a more complete name feelpp/feelpp-env:latest including the tag name :latest. We will see later how we defined the latest tag at the Feel++ organization. See Feel++ Container System for more details.

This may take a while depending on your internet connection but
eventually you should see something like

The first line tells us that there is no local copy of this Feel++
image. Docker checks automatically online on the
Docker Hub if an image is available.

Once the image is downloaded, Docker launches the container and
executes the command we provided echo 'Hello World!' from inside the
container. The result of the command is showed on the last line of the
output log above.

If you run the command again, you won’t see the download part and the
command will be executed very fast.

We can ask Docker to give us a shell using the following command

$ docker run -it feelpp/feelpp-env

It provides a shell prompt from inside the container which is very
similar to what you obtain when login with ssh on a remote
machine. The flags -i and -t tell Docker to provide an interactive
session (-i) with a TTY attached (-t).

As we said before the default Host OS is Ubuntu 16.10.
However Docker shines in continuous integration. It provides a large set of operating system to build upon and allows to check the software in various contexts. The FCS takes advantage of Docker to build feelpp-libs for several operating systems provided by feelpp-env and with different compilers any time a commit in the Feel++ repository is done.

Table 7. Table providing the list of supported Host OS

Operating system

version

feelpp-env Tags

Compilers

Ubuntu

16.10

ubuntu-16.10, latest

GCC 6.x, Clang 3.9

Ubuntu

16.04

ubuntu-16.04

GCC 6.x, Clang 3.8

Debian

sid

debian-sid

GCC 6.x, Clang 3.9,4.0

Debian

testing

debian-testing

GCC 6.x, Clang 3.9

If you are interested in testing Feel++ in these systems, you can run these flavors.

You see on the last but one line the directory $HOME/feel mounted on /feel in the Docker image.

Note that mouting a host sub-directory on /feel is
mandatory. If you don’t, the Feel++ applications will exit due to lack
of permissions. If you prefer running inside the docker environment
you can type unset FEELPP_REPOSITORY and then all results from
Feel++ applications will be store in $HOME/feel. But then
you will have to use `rsync or ssh to copy your results out of the
docker image if needed.

\(\partial \Omega_D\), \(\partial \Omega_N\) and \(\partial \Omega_R\) can be empty sets. In the case \(\partial \Omega_D =\partial \Omega_R = \emptyset\), then the solution is known up to a constant.

In the implementation presented later, \(\partial \Omega_D =\partial \Omega_N = \partial \Omega_R = \emptyset\), then we set Dirichlet boundary conditions all over the boundary. The problem then reads like a standard laplacian with inhomogeneous Dirichlet boundary conditions:

We now turn to the finite element approximation using Lagrange finite
element. We assume \(\Omega\) to be a segment in 1D, a polygon in
2D or a polyhedron in 3D. We denote \(V_\delta \subset
H^1(\Omega)\) an approximation space such that \(V_{g,\delta}
\equiv P^k_{c,\delta}\cap H^1_{g,\Gamma_D}(\Omega)\).

Next the discretization setting by first defining Vh=Pch<k>(mesh) \(\equiv P^k_{c,h}\), then elements of Vh and expressions f, n and g given by command line options or configuration file.

autoVh=Pch<2>(mesh);autou=Vh->element("u");automu=doption(_name="mu");autof=expr(soption(_name="functions.f"),"f");autor_1=expr(soption(_name="functions.a"),"a");// Robin left hand side expressionautor_2=expr(soption(_name="functions.b"),"b");// Robin right hand side expressionauton=expr(soption(_name="functions.c"),"c");// Neumann expressionautog=expr(soption(_name="functions.g"),"g");autov=Vh->element(g,"g");

at the following line

autov=Vh->element(g,"g");

v is set to the expression g, which means more precisely that v is the interpolant of g in Vh.

the variational formulation is implemented below, we define the
bilinear form a and linear form l and we set strongly the
Dirichlet boundary conditions with the keyword on using
elimination. If we don’t find Dirichlet, Neumann or Robin in the
list of physical markers in the mesh data structure then we impose
Dirichlet boundary conditions all over the boundary.

autol=form1(_test=Vh);l=integrate(_range=elements(mesh),_expr=f*id(v));l+=integrate(_range=markedfaces(mesh,"Robin"),_expr=r_2*id(v));l+=integrate(_range=markedfaces(mesh,"Neumann"),_expr=n*id(v));toc("l");tic();autoa=form2(_trial=Vh,_test=Vh);a=integrate(_range=elements(mesh),_expr=mu*gradt(u)*trans(grad(v)));a+=integrate(_range=markedfaces(mesh,"Robin"),_expr=r_1*idt(u)*id(v));a+=on(_range=markedfaces(mesh,"Dirichlet"),_rhs=l,_element=u,_expr=g);//! if no markers Robin Neumann or Dirichlet are present in the mesh then//! impose Dirichlet boundary conditions over the entire boundaryif(!mesh->hasAnyMarker({"Robin","Neumann","Dirichlet"}))a+=on(_range=boundaryfaces(mesh),_rhs=l,_element=u,_expr=g);toc("a");tic();//! solve the linear system, find u s.t. a(u,v)=l(v) for all vif(!boption("no-solve"))a.solve(_rhs=l,_solution=u);toc("a.solve");cout<<"||u_h-g||_L2="<<normL2(_range=elements(mesh),_expr=idv(u)-g)<<std::endl;tic();autoe=exporter(_mesh=mesh);e->addRegions();e->add("u",u);e->add("g",v);e->save();toc("Exporter");return0;}