# Firedrake + icepack via conda Install [Firedrake](https://www.firedrakeproject.org/) and [icepack](https://icepack.github.io/) into a self-contained conda environment with **no system packages required** beyond conda itself. ## How it works This is a hybrid conda + pip approach: - **conda** provides all the difficult-to-compile native dependencies: PETSc (with MUMPS, hypre, SuperLU, etc.), MPI, HDF5, BLAS/LAPACK, compilers, and the C toolchain needed for Firedrake's JIT compilation. - **pip** installs Firedrake and its Python ecosystem (UFL, FIAT, TSFC, PyOP2, loopy) from git, since these are not on conda-forge. - **Activation scripts** automatically set `PETSC_DIR`, `CC=mpicc`, `HDF5_MPI=ON`, and other environment variables when you `conda activate` so that Firedrake's runtime code generation compiles against the conda-provided libraries. The key insight is that conda-forge's PETSc is built with all the external packages Firedrake needs, and PETSc installed in "prefix" mode (`PETSC_DIR=$CONDA_PREFIX`, no `PETSC_ARCH`) is compatible with how Firedrake discovers PETSc at runtime. ## Prerequisites - **conda** or **mamba** — [Install miniforge](https://github.com/conda-forge/miniforge) (recommended) or [miniconda](https://docs.conda.io/en/latest/miniconda.html) - **Git** — needed to clone Firedrake repositories - ~5 GB disk space for the full environment - ~15 minutes for setup (mostly downloading conda packages) No `sudo`, no system package manager, no Docker required. ## Installation ```bash git clone firedrake-conda cd firedrake-conda bash setup.sh ``` By default this creates a conda environment named `firedrake` with Firedrake release **2025.10.2**. Both can be customised: ```bash # Custom environment name bash setup.sh my-firedrake # Environment at a specific path (uses conda -p) bash setup.sh ./envs/firedrake bash setup.sh ~/projects/icesheet/env # Change Firedrake version bash setup.sh firedrake main bash setup.sh firedrake 2025.10.1 # Or parameterize using environment variables (takes precedence over commandline arguments) FIREDRAKE_ENV=~/fd FIREDRAKE_REF=2025.10.2 bash setup.sh ``` The script will: 1. Create a conda environment (named or at a path) with all native dependencies 2. Set up activation scripts for the environment variables 3. Clone Firedrake and icepack with visible git progress 4. pip-install them, patching out conda-provided deps (petsc4py, mpi4py, h5py) to avoid build failures ## Usage ```bash conda activate firedrake python ``` ```python import firedrake import icepack # Everything works as documented in icepack tutorials mesh = firedrake.Mesh("glacier.msh") Q = firedrake.FunctionSpace(mesh, "CG", 2) V = firedrake.VectorFunctionSpace(mesh, "CG", 2) model = icepack.models.IceStream() solver = icepack.solvers.FlowSolver(model) u = solver.diagnostic_solve(velocity=u0, thickness=h, ...) ``` The environment variables (`PETSC_DIR`, `CC`, `HDF5_MPI`, etc.) are automatically set when you `conda activate firedrake` and restored when you deactivate. ## Verification ```bash conda activate firedrake python verify.py ``` This tests environment variables, library linking, Python imports, JIT compilation, a Poisson solve, and icepack model instantiation. If something fails, run the diagnostic script for detailed information: ```bash bash diagnose.sh ``` ## Troubleshooting ### `pip install firedrake` fails to build extensions This usually means the C compiler can't find PETSc headers. Check that: ```bash echo $PETSC_DIR # should be $CONDA_PREFIX echo $CC # should be mpicc mpicc --version # should work and show conda's compiler ``` If these aren't set, deactivate and reactivate: ```bash conda deactivate conda activate firedrake ``` ### Import errors about missing symbols (`libpetsc.so`) This means a Python extension was linked against a different PETSc than the one in the conda env. Fix by rebuilding the offending package: ```bash pip cache purge pip install --force-reinstall --no-binary :all: --no-build-isolation petsc4py ``` ### `h5py` MPI errors h5py must be built with MPI support. The conda environment provides this, but if pip reinstalls h5py it may pull a non-MPI wheel. Force the conda version: ```bash conda install -c conda-forge "h5py=*=mpi_mpich_*" ``` ### JIT-compiled kernels segfault This usually means the JIT compiler is using the system compiler instead of conda's `mpicc`. Verify: ```bash which mpicc # should be in $CONDA_PREFIX/bin/ mpicc -show # should reference $CONDA_PREFIX libraries ``` ### Updating To update Firedrake and icepack while keeping conda dependencies: ```bash conda activate firedrake # Pull latest sources (or checkout a different tag) cd ~/.firedrake-conda/clones/firedrake git fetch --tags origin git checkout 2025.10.2 # or: git checkout main && git pull cd ~/.firedrake-conda/clones/icepack && git pull --progress # Reinstall using the constraints file pip install --upgrade --no-build-isolation \ -c $CONDA_PREFIX/constraints.txt \ ~/.firedrake-conda/clones/firedrake ~/.firedrake-conda/clones/icepack ``` To update all conda dependencies (then regenerate constraints): ```bash conda update --all -n firedrake # Re-run setup.sh to regenerate constraints.txt ``` ## What conda provides vs what pip provides | Package | Source | Why | |---------|--------|-----| | PETSc + petsc4py | conda-forge | Complex build with MUMPS, hypre, etc. | | SLEPc + slepc4py | conda-forge | Must match PETSc version | | mpich + mpi4py | conda-forge | MPI ABI consistency | | HDF5 + h5py | conda-forge | Must be MPI-enabled | | compilers (gcc/clang) | conda-forge | Runtime JIT needs consistent ABI | | BLAS/LAPACK | conda-forge | Linked by PETSc | | numpy, scipy, sympy | conda-forge | Standard scientific Python | | islpy | conda-forge | Has compiled C extension | | **firedrake** | **pip (git)** | Not on conda-forge | | fenics-ufl | pip (git, via firedrake) | Firedrake tracks development branch | | firedrake-fiat | pip (git, via firedrake) | Firedrake's own fork | | tsfc, pyop2, finat | pip (via firedrake) | Part of Firedrake monorepo | | loopy | pip (via firedrake) | Code generation stack | | libsupermesh | pip (git) | Small C lib, builds against conda MPI | | **icepack** | **pip (git)** | Pure Python, depends on firedrake | ## Platform support | Platform | Status | Notes | |----------|--------|-------| | Linux x86_64 | Primary | Best tested | | macOS ARM64 (Apple Silicon) | Supported | Uses clang from conda | | macOS x86_64 (Intel) | Untested | Should work but Firedrake dropped official support | | Linux aarch64 | Should work | conda-forge has ARM builds | | Windows (WSL2) | Should work | Via WSL2's Linux environment | ## Files ``` firedrake-conda/ ├── environment.yml # Conda env spec (all native deps) ├── setup.sh # One-command setup script ├── verify.py # Post-install verification ├── diagnose.sh # Detailed diagnostics for debugging └── README.md ```