Installation
EdelweissFE is developed in a dedicated conda environment. environment.yml declares it, and the committed lockfile
conda-lock.yml pins it exactly: every package, with version, build and checksum, for every supported platform.
The same pinned environment is published as the conda package edelweissfe-dev, versioned by date (the current
version is in conda/edelweissfe-dev/VERSION), so it installs with a single conda create, identically on every
machine and in CI. Nothing changes until a new version is published. Everything, including the free-threaded
(cp314t) Python interpreter, comes from conda packages; pip only builds and installs EdelweissFE itself.
The packages come from conda-forge, except for the few conda-forge does not provide yet, which come from the matthiasneuner/edelweiss channel on prefix.dev:
vtkbuilt for free-threaded Python (conda-forge only builds it for the regular interpreter),autodiff1.1.2 with Eigen 5 support,fastorandamgcl(header-only C++ libraries).
The recipes of that channel are maintained at matthiasneuner/edelweiss-conda-channel.
Supported platforms are Linux (x86-64), macOS 14 or newer (arm64 and x86-64), and Windows (x64).
Ready-to-run package
To run simulations without developing EdelweissFE, install the conda package edelweissfe (released versions,
with Marmot’s public elements and materials and all linear solvers; same platforms as below):
conda create -n edelweissfe -c https\://repo.prefix.dev/matthiasneuner/edelweiss -c conda-forge edelweissfe
It depends on the matching marmot package, pinned exactly: compiled C++ code has no stable interface across
Marmot versions. Both are built with portable compiler flags (no -march=native).
Everything else on this page is for developing EdelweissFE or Marmot, adding (private) Marmot modules, or
compiling for your own CPU. Do that in a separate environment created from edelweissfe-dev, never in one with the
edelweissfe or marmot package installed: a self-built Marmot installed there overwrites files conda manages,
and the packaged EdelweissFE would then run against a library it was not compiled for. Likewise, pip install -e .
on top of the edelweissfe package leaves two copies of EdelweissFE in the environment.
The recipe is conda/edelweissfe/recipe.yaml; the conda workflow builds and tests it (against Marmot’s own
recipe, built from the matching Marmot branch) on every pull request and uploads it for a release tag.
Get conda
A conda installation, e.g. Miniforge. On Linux and macOS:
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
bash Miniforge3-$(uname)-$(uname -m).sh
On Windows, use the Miniforge installer (Miniforge3-Windows-x86_64.exe) and run the commands below in the
Miniforge Prompt. Windows additionally needs the Microsoft C++ compiler: the free
Visual Studio 2022 Build Tools (MSVC v143 toolset)
with the workload Desktop development with C++. The environment’s compilers package only activates it; it cannot
install it. Both can also be installed from a terminal:
winget install CondaForge.Miniforge3
winget install Microsoft.VisualStudio.2022.BuildTools --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
Activating the environment on Windows prints a long list of Visual Studio setup commands; that is the compiler activation and normal.
Create a dedicated environment
Install EdelweissFE into an environment of its own, never into conda’s base environment or one shared with other
projects:
It needs a special interpreter. EdelweissFE runs on the free-threaded (
cp314t) Python build, and many packages built for the regular interpreter cannot be installed alongside it.Its package versions are pinned. The environment is installed exactly as
conda-lock.ymlspecifies. Installing other packages into it changes those versions, and a single package that is not free-threading safe (e.g.pyamg) silently re-enables the GIL for the whole process, disabling the thread-parallel element loops.It can be rebuilt at any time. A dedicated environment can simply be deleted and recreated from the lockfile, which reliably fixes a broken installation;
basecannot be recreated that way.Marmot is built into it.
cmake --installwrites Marmot’s libraries and headers into the environment, where they must not mix with other projects’ builds.
Create it with the pinned environment package:
conda create -n edelweissfe -c https://repo.prefix.dev/matthiasneuner/edelweiss -c conda-forge edelweissfe-dev=2026.11.09 conda activate edelweissfe
This installs exactly the environment of conda-lock.yml for your platform.
Alternatively, from the lockfile. The same environment can be installed from conda-lock.yml in the
repository root with conda-lock, which itself gets a small environment of its
own (not base). This route does not include edelweissfe-dev’s activation script, so set
PIP_NO_BUILD_ISOLATION yourself (last line; see below):
conda create -n conda-lock -c conda-forge conda-lock
conda run -n conda-lock conda-lock install -n edelweissfe conda-lock.yml
conda env config vars set -n edelweissfe PIP_NO_BUILD_ISOLATION=0
conda activate edelweissfe
Note
Do not create the environment from environment.yml directly (conda env create -f environment.yml): that
re-solves it against whatever packages are newest today, which is exactly what the pinned environment avoids.
On Linux and Windows the environment includes Intel MKL, which enables the PARDISO direct solver. MKL does not exist for macOS; there the PARDISO extension is simply not built and the default linear solver falls back to SciPy’s SuperLU.
The commands on this page use Linux/macOS shell syntax. On Windows, set environment variables separately in the
Miniforge Prompt (cmd.exe), e.g. set PYTHON_GIL=0 before run_tests_edelweissfe .\testfiles\edelweiss-only\.
Installation without Marmot
pip install -e .
PYTHON_GIL=0 run_tests_edelweissfe ./testfiles/edelweiss-only/
pip only builds and installs EdelweissFE itself; all dependencies are already in the environment. -e (editable)
makes changes to Python files take effect immediately; rerun the command after changing Cython or C++ sources.
pip builds against the environment’s own setuptools, Cython and NumPy: activating the environment sets
PIP_NO_BUILD_ISOLATION=0 (pip reads it inverted; 0 disables build isolation). Without that, pip would fetch
its own copies from PyPI into a temporary build environment and compile the Cython extensions against those, which
can mismatch the environment’s NumPy at runtime. An environment installed from the lockfile needs the
conda env config vars set step shown above, or pip install --no-build-isolation -e ..
This installation is sufficient for the EdelweissFE-only elements, materials and tests.
Without Marmot, the build output (pip install -v) shows a warning that Marmot was not found, followed by compiler
errors (e.g. fatal error C1083 on Windows) and [FAIL] lines for the three Marmot extensions
(marmotelement.element, marmothypoelastic, marmotgradientenhancedhypoelastic). That is expected: these
extensions are optional and skipped. edelweissfe/built_extensions.log lists the extensions that were built.
Installation with Marmot
Marmot provides the Marmot-backed elements and constitutive models. All of its dependencies (Eigen, autodiff, Fastor) are already in the environment, so only Marmot itself is built from source, into the environment:
git clone --recurse-submodules https://github.com/MAteRialMOdelingToolbox/Marmot/ ../Marmot
cmake -S ../Marmot -B ../Marmot/build -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_PREFIX_PATH=$CONDA_PREFIX \
-DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
cmake --build ../Marmot/build -j
cmake --install ../Marmot/build
On Windows, in the Miniforge Prompt, conda’s headers and libraries are under %CONDA_PREFIX%\Library, and
Marmot is built in the Release configuration:
git clone --recurse-submodules https://github.com/MAteRialMOdelingToolbox/Marmot/ ..\Marmot
cmake -S ..\Marmot -B ..\Marmot\build -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%\Library ^
-DCMAKE_PREFIX_PATH=%CONDA_PREFIX%\Library -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF
cmake --build ..\Marmot\build --config Release --parallel
cmake --install ..\Marmot\build --config Release
Then build EdelweissFE, which picks up Marmot automatically, and validate the installation:
pip install -v -e .
PYTHON_GIL=0 run_tests_edelweissfe ./testfiles/marmot/
PYTHON_GIL=0 run_tests_edelweissfe ./testfiles/edelweiss-only/
Marmot is found in $CONDA_PREFIX (Windows: %CONDA_PREFIX%\Library) by default; set MARMOT_INSTALL_DIR
if it is installed elsewhere. The build records the Marmot installation it used (edelweissfe/marmot_install_dir.txt):
on Linux and macOS, the Marmot extensions find the library there through their embedded library path; on Windows,
import edelweissfe adds its bin directory to the DLL search path. So the extensions always load the Marmot they
were built against, whatever the runtime environment. Rebuild EdelweissFE after moving or reinstalling Marmot
elsewhere.
The extensions are compiled with -march=native by default (no architecture flags on Windows), so a build only runs
on processors like the one it was compiled on. For builds that must run elsewhere, e.g. container images or packages,
set EDELWEISSFE_ARCH_FLAGS (e.g. -march=x86-64-v3, or empty for none). The compile flags are defined in
edelweissfe.utils.extensionbuild, which downstream packages (EdelweissMeshfree) use for their own extensions.
Developing
Python changes take effect immediately (editable install). After changing Cython sources, or after rebuilding and
installing Marmot, rerun pip install -e .. The editable install belongs to one checkout: in a
second checkout or git worktree, use a separate environment, or it silently runs the first checkout’s code. Further:
PYTHON_GIL=0 pytest tests: the pytest suite,sphinx-build -b html doc/source doc/build/html: this documentation.
Changing dependencies
With conda-lock in its own environment (conda create -n conda-lock -c conda-forge conda-lock), edit
environment.yml, re-lock, and update your environment from the lockfile:
conda run -n conda-lock conda-lock lock -f environment.yml --virtual-package-spec virtual-packages.yml
conda run -n conda-lock conda-lock install -n edelweissfe conda-lock.yml
Then set a new version, today’s date, in conda/edelweissfe-dev/VERSION (append .1, .2, … for further
changes on the same day) and in the conda create command of the README (this page reads it from VERSION). Commit everything together;
CI fails if the lockfile is out of date with environment.yml, if it changed without a new version, or if the
documented commands do not show the current version. Once merged into master, CI publishes the new
edelweissfe-dev.
virtual-packages.yml tells conda-lock which system properties (e.g. the minimum macOS version) to assume for each
platform. Platform-specific dependencies use selectors, e.g. - mkl # [linux64].
A weekly CI job re-locks against the newest packages and opens a pull request with a new version, whose CI tests the updated environment before it is merged.
Running with free-threading
Disable the GIL and set the number of threads explicitly:
PYTHON_GIL=0 OMP_NUM_THREADS=8 edelweissfe input.inp
Troubleshooting
The environment behaves differently than on other machines. Make sure it was created from
edelweissfe-dev(or withconda-lock install), not fromenvironment.yml, and thatconda list edelweissfe-devshows the version documented above.CMake finds an unexpected Eigen or other package. CMake also searches its user package registry (
~/.cmake/packages), to which some projects register their build trees. If a package from the environment is rejected (e.g. by a version check), CMake silently falls back to such an entry. Configure with-DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF(as above); the configure output prints the Eigen version and location that was found.The GIL is re-enabled at runtime. Importing any extension module that does not declare free-threading support re-enables the GIL for the whole process, with a
RuntimeWarning. Do not add such packages (e.g.pyamg) to the environment.