Currently, FEniCS is only working properly on Linux (and maybe Mac) systems. Therefore, custEM was developed and is restricted to Linux up to now. There are two recommended and quite robust ways to install FEniCS, pyGIMLi and TetGen as requirements for custEM:

  1. Installation via conda on Linux systems

  2. Installation on Ubuntu or maybe further (not tested) Linux systems

Alternative installation procedures for FEniCS, i.e., the Docker environment, can be tested by users. However, this is not straightforward and making pyGIMLi available at the same time is tricky.

GitLab repository:

For installation issues and questions please contact the authors:

Important notes:

  • Depending on your computer architecture, it might be necessary to set the following environment vaiable to prevent the MUMPS internal OpenMP

    parallelization via running the command:

—> export OMP_NUM_THREADS=1

If you experience that significantly more processes are used than set in the mpirun call and the computation lasts unreasonably long, not setting this flag is the reason. It might be reasnoable to use a mix of MPI and OpenMP parallelization, in that case test using more than 1 OMP_NUM_THREADS.

  • Running multiple forward simulations at the same time for inversion with

    the MultiFWD class only works with the library “mpich”, not with openmp! With installation option 3, this choice is ensured automatically, otherwise users might specify this dependency during the environment build manually.

Conda installation:

  • custEM conda package available for straightforward installation

  • Successfully tested on: Ubuntu 16.04 and newer, Debian 9 Stretch, Arch Linux, Gentoo, Scientific Linux

  • Complete support of all features with FEniCS versions higher than 2018.1

  • instead of “conda”, the tool “mamba” (conda install mamba) can be used to speed up the complete installation procedure

  1. Install Anaconda or miniconda:

    If not done automatically during installation, don’t forget to add conda to your PATH variable via adding a line in your bashrc file (something like):

    –> export PATH=$HOME/anaconda3/bin:$PATH


    —> export PATH=$HOME/miniconda/bin:$PATH

  2. Add required CONDA channels and install:

    –> conda config --add channels conda-forge --add channels gimli

    Note: It is possible to skip global setting of channels. Instead, add -c gimli -c conda-forge to the create or install commands (see 3.).

  3. Install custEM and requirements (FEnICS, pyGIMLi, TetGen):

    OPTION 1:

    This option is recommended for users working with existing functionalities of custEM. If your work could likely require minor custEM updates from time to time, we recommend OPTION 2.

    —> conda create -n custEM custem

    –> conda activate custEM

    Here, custem is the conda package provided via the gimli channel and custEM is the environment name, which can be modified by users. No setting of paths is required and a stable version of custEM is ensured!

    Examples and tutorials can be downloaded separately from the GitLab repository and placed anywhere on the comptuer architecture.

    OPTION 2:

    This option allows to account for smaller code updates by installing a fixed version of the Third Party dependecies, but using custEM from the GitLab repository and being able to pull most recent versions.

    Download custEM from the GitLab repository by running

    –> git clone

    or by donwloading as zip file from

    To build a conda environement with all the required dependencies for custEM, navigate to the custEM main directory and run

    —> conda env create

    –> conda activate custEM

    —> conda develop .

    With this option, examples and tutorials were downloaded automatically and are available in the custEM main directory.

    OPTION 3:

    Install all dependencies with a fixed version of important third-party libraries with ensured compatibility directly with help of the “yaml.yml” file provided in the custEM main directory of the code repository. Everything else is identical to Option 2.

    —> ``conda env create -f yaml.yml ``

    –> conda activate custEM

    —> conda develop .

Ubuntu (Debian) installation:

  • Successfully tested on: Ubuntu 16.04 LTS and 18.04 LTS, probably works on Debian Linux systems as well.

  • The complete custEM toolbox with all features is supported.

  • FEniCS, pyGIMLi and TetGen need to be installed manually.

  • Only python 3 is supported as third party libraries do not maintain python 2 compatible versions anymore.

  1. Get custEM from zip-file or GitLab repository and add the custEM main directory to the PYTHONPATH. If the custEM repository was installed in the home directory ($HOME), it would be:


    Please note that the correct path must not point to the main repository but the custEM directory in the repository which contains the submodules!

  2. Install FEniCS on Ubuntu ( via:

    –> sudo apt-get install software-properties-common –> sudo add-apt-repository ppa:fenics-packages/fenics –> sudo apt-get update –> sudo apt-get install --no-install-recommends fenics –> sudo apt-get dist-upgrade

  3. Install pyGIMLi on Ubuntu (

    –> curl -Ls | bash

  4. Make your system Python find pyGIMLi by editing the following path variables. In this case, pyGIMLi was installed in the directory: (Note the line breaks!) $HOME/custEM/ThirdParty/gimli_stable:

    –> export PYTHONPATH=${PYTHONPATH}:$HOME/custEM/ThirdParty/




  5. Get TetGen for mesh generation ( and add tetgen to your PATH variable via:

    –> export PATH=$PATH:$HOME/custEM/ThirdParty/tetgen

Further notes

  • It is recommended to add all the export commands to your bashrc file.

  • If custEM was installed via conda, it is recommended to add the ‘-u’ flag after ‘python’ or ‘python3’ in the commmand promt calls to force all prints to appear in time and not delayed, e.g.:

    –> mpirun -n 12 python -u

  • In order to use the provided jupyter notebook tutorials, jupyter needs to be installed after all other steps listed below:

    –> pip install jupyter

  • Computation times might be speed up with reducing the number of mpirun processes (e.g., 8 instead of 32) and enabling OpenMP parallelization during the solution of the system of equations via MUMPS with adjusting the flag OMP_NUM_THREADS, e.g., export OMP_NUM_THREADS=4 instead of 1.