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 scripts/vm/install_dafoam_ubuntu.sh (about 2 hours, unattended); conda packages are planned

Python

csdl_dafoam itself, csdl_alpha, lsdo_geo, lsdo_function_spaces, modopt, idwarp-jax

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

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_mesh finds it automatically (the openfoam2506 launcher) 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 (or quadprog, highspy)

OpenSQP, the default optimizer, solves QP subproblems with these. pip install -e ".[opt]", or pick --optimizer PySLSQP. (modOpt’s own opensqp extra lists only qpsolvers.)

DAFoam mesh check failed

DAFoam’s checkMesh rejected 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. Pass check_mesh=False to build_airfoil_model only to debug.

DAFoam primal solution failed

The 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 fix decomposeParDict).

macOS or Windows: NameError: name 'global_functions' is not defined

lsdo_function_spaces parallelizes surface projection with a process pool that needs the fork start method. csdl_dafoam projects serially by default, so this only appears if you pass num_workers > 1 through projection_options.