Installation#
This page describes a source-based installation of the current CutFEMx stack:
FEniCSx 0.11 release packages: Basix, UFL, FFCx, and DOLFINx
runintgen0.1CutCells 0.4
CutFEMx 0.2
The commands below assume a Unix-like shell and an activated conda environment.
They avoid user-specific paths; all installation prefixes are taken from the
active environment through $CONDA_PREFIX.
Prerequisites#
You need:
Python 3.10 or newer
a C++20 compiler
CMake and
pkg-configMPI and PETSc through the same environment used by DOLFINx
pip,scikit-build-core, andnanobind
For a conda-forge environment, create and activate an environment first:
Choose any environment name and keep it active for all install steps:
conda create -n <env-name> -c conda-forge python=3.13
conda activate <env-name>
Install the common build and runtime dependencies:
conda install -c conda-forge \
c-compiler cxx-compiler cmake ninja pkg-config pip \
mpi mpich mpi4py petsc petsc4py \
hdf5 libadios2 pugixml spdlog boost-cpp \
parmetis libscotch ptscotch kahip \
numpy scipy matplotlib pyvista pytest \
scikit-build-core nanobind cffi
If you use OpenMPI instead of MPICH, install a consistent MPI/PETSc stack from conda-forge and keep the same environment active for every build step.
Real and complex scalar builds#
The CutFEMx MatrixCSR/runtime assembly path is templated for all supported PDE
scalar types (float32, float64, complex64, complex128) on either
float32 or float64 mesh geometry. PETSc is different: a PETSc installation
is built for exactly one scalar mode and one real precision. PETSc-backed
assembly and solvers therefore require an environment whose petsc, petsc4py,
DOLFINx, and CutFEMx builds all use the PETSc scalar type you want to solve
with.
The commands above install the usual real-valued, double-precision PETSc stack.
For a complex128 PETSc setup, create a separate environment and request the
complex PETSc and petsc4py variants before building DOLFINx:
conda create -n <complex-env-name> -c conda-forge python=3.13
conda activate <complex-env-name>
conda install -c conda-forge \
c-compiler cxx-compiler cmake ninja pkg-config pip \
mpi mpich mpi4py "petsc=*=complex*" "petsc4py=*=complex*" \
hdf5 libadios2 pugixml spdlog boost-cpp \
parmetis libscotch ptscotch kahip \
numpy scipy matplotlib pyvista pytest \
scikit-build-core nanobind cffi
If the solver cannot find a matching petsc4py build with the wildcard above,
query conda-forge for the available build strings and select the build that is
compiled against complex PETSc:
conda search -c conda-forge petsc petsc4py
Verify the scalar mode before building any FEniCSx component from source:
python - <<'PY'
import numpy as np
from petsc4py import PETSc
print("PETSc scalar:", PETSc.ScalarType)
assert np.issubdtype(np.dtype(PETSc.ScalarType), np.complexfloating)
assert np.dtype(PETSc.RealType) == np.dtype(np.float64)
PY
For a complex64 PETSc setup, PETSc must be configured for complex scalars and
single real precision, and DOLFINx/petsc4py must be built against that same
PETSc. If conda-forge does not provide a matching single-precision complex
variant for your platform, build PETSc, petsc4py, DOLFINx, and CutFEMx from
source in one environment. Verify it with:
python - <<'PY'
import numpy as np
from petsc4py import PETSc
print("PETSc scalar:", PETSc.ScalarType)
print("PETSc real:", PETSc.RealType)
assert np.dtype(PETSc.ScalarType) == np.dtype(np.complex64)
assert np.dtype(PETSc.RealType) == np.dtype(np.float32)
PY
Then follow the same source build steps below. Build DOLFINx, runintgen, CutCells, and CutFEMx in this complex environment. Reusing DOLFINx or CutFEMx artifacts built against a different PETSc scalar or precision environment is not supported.
Before building packages from source, keep CMake and Python discovery tied to the active environment:
export CONDA_PREFIX="${CONDA_PREFIX:?activate the conda environment first}"
export CMAKE_PREFIX_PATH="$CONDA_PREFIX"
export PYTHONNOUSERSITE=1
export CC="$CONDA_PREFIX/bin/clang"
export CXX="$CONDA_PREFIX/bin/clang++"
On macOS with the conda-forge C++ toolchain, DOLFINx 0.11 may also require:
export CMAKE_ARGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=13.4"
export CXXFLAGS="-D_LIBCPP_ENABLE_EXPERIMENTAL -D_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB -D_LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM -D_LIBCPP_HAS_NO_INCOMPLETE_PSTL"
On Linux, or with a compiler toolchain that does not need these libc++
workarounds, omit the CMAKE_ARGS and CXXFLAGS lines. If clang/clang++
are not the compiler names in your environment, set CC and CXX to the
compiler wrappers installed in the active conda environment.
Install FEniCSx#
CutFEMx currently targets the FEniCSx 0.11 source release stack:
Basix:
v0.11.0UFL:
2026.1.0FFCx:
v0.11.0DOLFINx:
v0.11.0
UFL uses calendar-style release tags; its latest tag is 2026.1.0 rather than
a v0.11.0 tag. These versions match the dependency bounds declared by
DOLFINx and FFCx v0.11.0.
Verify the upstream tags if needed:
git ls-remote --exit-code --tags https://github.com/FEniCS/basix.git refs/tags/v0.11.0
git ls-remote --exit-code --tags https://github.com/FEniCS/ufl.git refs/tags/2026.1.0
git ls-remote --exit-code --tags https://github.com/FEniCS/ffcx.git refs/tags/v0.11.0
git ls-remote --exit-code --tags https://github.com/FEniCS/dolfinx.git refs/tags/v0.11.0
Fetch the tagged sources:
mkdir -p fenicsx-0.11
cd fenicsx-0.11
git clone --branch v0.11.0 --depth 1 https://github.com/FEniCS/basix.git
git clone --branch 2026.1.0 --depth 1 https://github.com/FEniCS/ufl.git
git clone --branch v0.11.0 --depth 1 https://github.com/FEniCS/ffcx.git
git clone --branch v0.11.0 --depth 1 https://github.com/FEniCS/dolfinx.git
Install Basix, UFL, and FFCx from those checkouts:
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade --force-reinstall --no-deps ./basix ./ufl ./ffcx
DOLFINx needs its C++ core and Python interface. Follow the DOLFINx source installation workflow for your platform, using the same active environment as the install prefix. In a source checkout this has the following shape:
cd dolfinx
cmake -G Ninja -S cpp -B cpp/build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" \
-DCMAKE_PREFIX_PATH="$CONDA_PREFIX"
cmake --build cpp/build
cmake --install cpp/build
python -m pip install --check-build-dependencies --no-build-isolation --no-deps \
./python
cd ../..
Verify the FEniCSx installation:
python - <<'PY'
import basix
import dolfinx
import ffcx
import ufl
print("Basix:", basix.__version__)
print("DOLFINx:", dolfinx.__version__)
print("FFCx:", ffcx.__version__)
print("UFL:", ufl.__version__)
PY
Install runintgen#
Install runintgen after Basix, UFL, and FFCx so it builds against the same
headers and Python packages:
git clone https://github.com/sclaus2/runintgen.git
cd runintgen
python -m pip install --no-build-isolation --no-deps --force-reinstall .
cd ..
Verify:
python - <<'PY'
import runintgen
print("runintgen:", getattr(runintgen, "__version__", "installed"))
PY
Install CutCells#
CutCells provides the geometric cutting backend used by CutFEMx. The Python wrapper builds against an installed CutCells C++ CMake package, so install the C++ core into the active environment before building the Python package.
git clone https://github.com/sclaus2/cutcells.git CutCells
cd CutCells
cmake -G Ninja -S cpp -B cpp/build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX" \
-DCMAKE_PREFIX_PATH="$CONDA_PREFIX" \
-DCUTCELLS_WITH_ALGOIM=ON
cmake --build cpp/build
cmake --install cpp/build
python -m pip install --no-build-isolation --no-deps --force-reinstall \
./python
cd ..
Verify:
python - <<'PY'
import cutcells
print("CutCells:", getattr(cutcells, "__version__", "installed"))
PY
Install CutFEMx#
Install CutFEMx last, after FEniCSx, runintgen, and CutCells are available in the same environment:
git clone https://github.com/sclaus2/CutFEMx.git
cd CutFEMx
env CONDA_PREFIX="$CONDA_PREFIX" \
CMAKE_PREFIX_PATH="$CONDA_PREFIX" \
PYTHONNOUSERSITE=1 \
CC="$CONDA_PREFIX/bin/clang" \
CXX="$CONDA_PREFIX/bin/clang++" \
CMAKE_ARGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=13.4 -DCUTCELLS_WITH_ALGOIM=ON" \
CXXFLAGS="-D_LIBCPP_ENABLE_EXPERIMENTAL -D_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB -D_LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM -D_LIBCPP_HAS_NO_INCOMPLETE_PSTL" \
python -m pip install --no-build-isolation --no-deps --force-reinstall .
Use the same active conda environment and pip flags for runintgen,
CutCells/python, and CutFEMx. If the build variables above are already
exported, the shorter python -m pip install ... form is equivalent. Omit
-DCUTCELLS_WITH_ALGOIM=ON only if you intentionally want to build without the
optional Algoim quadrature backend.
--no-build-isolation is required because CutFEMx must use the active
FEniCSx/MPI/PETSc/runintgen stack and DOLFINx wrapper headers. --no-deps
prevents pip from replacing the pinned FEniCSx packages with incompatible
release packages.
Verify:
python - <<'PY'
import cutcells
import cutfemx
import dolfinx
import runintgen
print("DOLFINx:", dolfinx.__version__)
print("runintgen:", getattr(runintgen, "__version__", "installed"))
print("CutCells:", getattr(cutcells, "__version__", "installed"))
print("CutFEMx:", getattr(cutfemx, "__version__", "installed"))
PY
Build the documentation#
Install the documentation dependencies from the CutFEMx repository root:
python -m pip install -r docs/requirements.txt
Build the HTML documentation:
cd docs
env LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 MPLCONFIGDIR=.matplotlib-cache \
python -m sphinx -b html . _build/html
If sphinx-build is already on your PATH, the shorter command is enough:
make html
The generated site is written to docs/_build/html/index.html.
Common issues#
DOLFINx or Basix cannot be found by CMake#
Make sure the same conda environment is active for all steps and pass the active prefix to CMake:
cmake -DCMAKE_PREFIX_PATH="$CONDA_PREFIX" ...
pip tries to replace FEniCSx packages#
Use --no-deps when installing runintgen, CutCells, and CutFEMx from source.
The FEniCSx packages must stay on the same tagged stack.
Build isolation cannot find MPI or DOLFINx headers#
Use --no-build-isolation. The builds need the compiler, MPI, PETSc, DOLFINx,
and Basix from the active environment.