Installation
Tip
The two procedures that have actually been run are the source build in Installing on an Apple-silicon Mac (a Linux VM on an Apple-silicon Mac, verified end to end) and its Linux equivalent in Installing on a Linux machine (same script; verified on ARM64 only). A conda package of the DAFoam stack is planned but its recipes have never been built.
DAFoam links against a source-built OpenFOAM, so there are no PyPI wheels for it. This package therefore has two layers:
Layer |
Contains |
Installed with |
|---|---|---|
compiled stack |
OpenFOAM v2506 + AD libraries, DAFoam, PETSc, MPI |
built from source with |
Python |
|
pip (git for the lab packages) |
Volume-mesh deformation uses IDWarp-JAX, which is pure Python/JAX, so
the Fortran IDWarp (and the CGNS build behind it) is not needed. It remains available as warper="idwarp";
its optional recipes are in recipes/.
Anything that runs DAFoam needs Linux. The pure-Python parts, and the whole test suite, also work on macOS.
1. Full install: build DAFoam from source
Apple-silicon Mac: Installing on an Apple-silicon Mac (a Lima Linux VM, then the Linux procedure inside it).
Linux (Ubuntu 24.04): Installing on a Linux machine.
Both end with python -m csdl_dafoam.doctor (also installed as csdl-dafoam-doctor), which prints which components import and whether the
OpenFOAM environment is loaded. A fully working install shows [ok] for every row.
Conda (experimental, not yet available)
environment.yml creates the Python side of the environment (MPI, PETSc, JAX, the lab packages, this repository) with
conda env create -f environment.yml; it does not contain DAFoam or OpenFOAM. The recipes for those in
recipes/ were written from DAFoam’s installation guide and have not been
built; the source build revealed they are incomplete (see Verification status). Publishing a source-built OpenFOAM package to the lsdolab
channel also needs a decision on size and licensing (DAFoam and OpenFOAM are GPL-3.0).
2. Python-only install (no DAFoam)
Enough to use the geometry parameterization, the atmosphere model, to read the code, and to run the test suite:
pip install -r requirements-lab.txt # csdl_alpha, modopt, idwarp-jax from LSDOlab's git
pip install -e ".[geometry,opt,test]" # incl. OpenSQP's qpsolvers, quadprog, highspy
pytest
requirements-lab.txt exists because csdl_alpha, the lab’s modopt and idwarp-jax are not on PyPI. Do not
pip install modopt from PyPI; that is an unrelated package.
Importing csdl_dafoam never requires DAFoam, PETSc or MPI. Setting up a DAFoam run without them raises an
ImportError that points back here.
3. Building the DAFoam packages yourself
Needs rattler-build on Linux x86-64 and a few hours:
rattler-build build -r recipes/openfoam-dafoam -c lsdolab -c conda-forge
rattler-build build -r recipes/dafoam -c ./output -c lsdolab -c conda-forge
rattler-build build -r recipe -c ./output -c lsdolab -c conda-forge
Then point environment.yml at the local channel by adding - file:///path/to/csdl_dafoam/output ahead of
lsdolab in its channels: list. The OpenFOAM build compiles OpenFOAM twice (original and reverse-mode AD),
needs about 10 GB of scratch space, and three of its source hashes are placeholders to fill in with
scripts/recipe_hashes.sh. See recipes/README.md.
Publishing to the channel is a manual GitHub Actions dispatch (.github/workflows/conda-stack.yml) and should
only follow a local build that passed its recipe tests.
macOS
DAFoam itself (the flow and adjoint solver) is Linux-only; nobody has published a macOS or ARM-Linux build, and the
conda recipes here target linux-64. What does run on an Apple-silicon Mac:
everything in section 2 (geometry, IDWarp-JAX, OpenSQP, the whole test suite, the examples against the fake solver);
native OpenFOAM v2506 from OpenFOAM.app, for validating meshes and cases with OpenFOAM’s own tools:
brew tap gerlero/openfoam brew install --cask gerlero/openfoam/openfoam@2506 # arm64, macOS 14+; installs to /Applications pip install -e ".[test]" && pytest -m openfoam # warped meshes vs OpenFOAM's checkMesh
csdl_dafoam.foam_check.check_meshfinds it automatically (theopenfoam2506launcher) and applies DAFoam’s mesh-check criteria. OpenFOAM.app installs OpenFOAM inside a read-only, case-sensitive disk image mounted on demand; add your own solvers to$FOAM_USER_APPBIN.
For a real DAFoam solve from a Mac, the route that has been run end to end is an ARM64 Linux VM (Lima, Apple’s hypervisor, native
speed, no emulation) with DAFoam built from source by scripts/vm/install_dafoam_ubuntu.sh: see scripts/vm/README.md. On an
M5 Max the build took a few hours, and the airfoil examples then run in the VM. Alternatives are a Linux machine or DAFoam’s
official Docker image dafoam/opt-packages (amd64 only, so emulated on Apple silicon).
4. Running
DAFoam decomposes the mesh to match the MPI rank count, so the case must be prepared for the number of ranks
you run. The examples do this for you (csdl_dafoam.cases.prepare_case); for your own cases, set
numberOfSubdomains in system/decomposeParDict to the -np value.
mpirun -np 4 python examples/airfoil_analysis.py
Versions
The build script, recipes and environment.yml follow DAFoam v5.1.1’s tested set: OpenFOAM v2506, PETSc 3.21, mpi4py >= 4,
NumPy >= 2, Python >= 3.11 (3.12 used), OpenMPI 4.1. The interface itself calls only DAFoam
methods that exist unchanged in v4.0.4 and v5.1.1.
Troubleshooting
ImportError: Could not import 'dafoam'The compiled stack is not installed or the environment is not activated. Run
python -m csdl_dafoam.doctor.ImportError: qpsolvers cannot be imported(orquadprog,highspy)OpenSQP, the default optimizer, solves QP subproblems with these.
pip install -e ".[opt]", or pick--optimizer PySLSQP. (modOpt’s ownopensqpextra lists onlyqpsolvers.)DAFoam mesh check failedDAFoam’s
checkMeshrejected the (warped) mesh and wrote the failed mesh into the case directory. Usually the optimizer asked for too large a design step; tighten the design-variable bounds or scaling. Passcheck_mesh=Falsetobuild_airfoil_modelonly to debug.DAFoam primal solution failedThe flow solve did not complete. Inspect the solver log and residuals in the case directory.
- Numbers of ranks differ from
numberOfSubdomains DAFoam aborts at start-up. Re-run
prepare_case(or fixdecomposeParDict).- macOS or Windows:
NameError: name 'global_functions' is not defined lsdo_function_spacesparallelizes surface projection with a process pool that needs theforkstart method.csdl_dafoamprojects serially by default, so this only appears if you passnum_workers > 1throughprojection_options.