Metadata-Version: 2.5
Name: rabbit-fem-mpi
Version: 2026.11.0
Summary: A lightweight MOOSE distribution packaging thermal and solid mechanics
Author: scepticalrabbit (Lloyd Fletcher)
License-Expression: LGPL-2.1
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: gmsh>=4.13.0
Requires-Dist: patchelf>=0.17; sys_platform != 'win32'
Requires-Dist: ziglang>=0.16.0
Provides-Extra: test
Requires-Dist: netcdf4>=1.6; extra == 'test'
Requires-Dist: numpy>=1.24; extra == 'test'
Requires-Dist: pytest>=8.0.0; extra == 'test'
Description-Content-Type: text/markdown

<p align="center">
    <img src="https://raw.githubusercontent.com/Computer-Aided-Validation-Laboratory/rabbit-fem/main/images/logo_rabbitfem.png" alt="Rabbit FEM Logo" width="620">
</p>

<p align="center"><strong>An easy to install, pre-compiled and portable MOOSE distribution for thermo-mechanical finite element simulation.</strong></p>

<p align="center">
    <a href="https://pypi.org/project/rabbit-fem/"><img src="https://img.shields.io/pypi/v/rabbit-fem?label=PyPI" alt="PyPI version"></a>
    <a href="https://pypi.org/project/rabbit-fem/"><img src="https://img.shields.io/badge/python-3.11+-3776AB?logo=python&logoColor=white" alt="Supported Python versions"></a>
    <a href="https://ziglang.org/download/"><img src="https://img.shields.io/badge/Zig-0.16.0-F7A41D?logo=zig&logoColor=white" alt="Zig version"></a>
    <a href="https://github.com/Computer-Aided-Validation-Laboratory/rabbit-fem/actions/workflows/linux_build_and_test.yml"><img src="https://img.shields.io/github/actions/workflow/status/Computer-Aided-Validation-Laboratory/rabbit-fem/linux_build_and_test.yml?branch=main&label=Linux" alt="Linux Tests"></a>
    <a href="https://github.com/Computer-Aided-Validation-Laboratory/rabbit-fem/actions/workflows/macos_build_and_test.yml"><img src="https://img.shields.io/github/actions/workflow/status/Computer-Aided-Validation-Laboratory/rabbit-fem/macos_build_and_test.yml?branch=main&label=macOS" alt="macOS Tests"></a>
    <a href="https://github.com/Computer-Aided-Validation-Laboratory/rabbit-fem/actions/workflows/windows_build_and_test.yml"><img src="https://img.shields.io/github/actions/workflow/status/Computer-Aided-Validation-Laboratory/rabbit-fem/windows_build_and_test.yml?branch=main&label=Windows" alt="Windows Tests"></a>
    <a href="https://github.com/Computer-Aided-Validation-Laboratory/rabbit-fem/actions/workflows/mpi_build_and_test.yml"><img src="https://img.shields.io/github/actions/workflow/status/Computer-Aided-Validation-Laboratory/rabbit-fem/mpi_build_and_test.yml?branch=main&label=MPI" alt="MPI Tests"></a>
    <a href="https://github.com/Computer-Aided-Validation-Laboratory/rabbit-fem/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Computer-Aided-Validation-Laboratory/rabbit-fem" alt="LGPL-2.1 license"></a>
</p>

`rabbit-fem` is a lightweight, standalone Python distribution of the [MOOSE](https://mooseframework.inl.gov/) (Multiphysics Object-Oriented Simulation Environment) finite element framework, tailored specifically for **thermal**, **solid mechanics**, and **contact** simulation.

Packaged as a self-contained Python wheel, `rabbit-fem` provides a drop-in `rabbit` command line executable and Python dataset API that runs MOOSE simulations without requiring external MOOSE or libMesh system installations.

---

## Key Features

- **Focused Thermo-Mechanical Physics**: Preconfigured with `SolidMechanics`, `HeatTransfer`, `Contact` modules.
- **Self-Contained & Relocatable**: Ships stripped binaries and shared libraries with relocatable linkage (`$ORIGIN` RPATHs on Linux, `@loader_path` on macOS, fully static executable on Windows) and zero external MOOSE dependency at runtime.
- **Drop-In CLI**: Execute MOOSE input files using `rabbit input.i` or `rabbit -i input.i`.
- **Packaged Simulation Datasets**: Includes standard benchmarks and Gmsh geometry scripts accessible directly through Python.
- **Zig Toolchain Orchestration**: Compiled and linked using `zig cc` / `zig c++` via `ziglang`.

---

## Installation

Install from PyPI:

```bash
# Using pip
pip install rabbit-fem

# Using uv
uv pip install rabbit-fem
```

Or install a locally built wheel (see [Build from Source](#build-from-source)):

```bash
# Using pip
pip install dist/rabbit_fem-*.whl

# Using uv
uv pip install dist/rabbit_fem-*.whl
```

Requires Python 3.11+ (CI builds and tests with Python 3.13).

### Serial and MPI variants

The default `rabbit-fem` wheel needs no system MPI installation and supports
shared-memory threading across all platforms (Linux, macOS, and Windows) with
`rabbit simulation.i --n-threads=N`. Only one variant may be installed at a time.

For multi-rank runs on Linux with OpenMPI, install the OpenMPI variant:

```bash
pip install rabbit-fem-mpi
```

```bash
mpirun -n 4 rabbit simulation.i
```

The Linux MPI variants additionally ship the `MFEM` finite element backend
(parallel Nédélec/Maxwell and diffusion problems via `MFEMProblem`;
see `src/rabbit/sims/mfem/`). Upstream MOOSE supports MFEM only with
MPI, so the serial wheel excludes it.

For clusters and systems whose MPI is MPICH rather than OpenMPI,
install the MPICH variant instead (Linux only):

```bash
pip install rabbit-fem-mpich
```

```bash
mpiexec.mpich -n 4 rabbit simulation.i
```

The explicit `mpiexec.mpich`/`mpirun.mpich` names keep working
regardless of the machine's MPI default (`update-alternatives`);
on MPICH-only systems bare `mpirun` resolves to the same launcher.
On machines without working InfiniBand, export
`UCX_TLS=tcp,self,sm` before running, otherwise MPICH's UCX layer
can abort during `MPI_Init` (`ibv_create_srq() failed`).

### Runtime system requirements

The serial wheel is fully self-contained on all platforms. The MPI
variants link the MPI ecosystem at runtime, which must be installed
separately (the launcher version must match the runtime):

- **Linux (OpenMPI variant / `rabbit-fem-mpi`)**: OpenMPI runtime — `sudo apt-get install -y openmpi-bin`
- **Linux (MPICH variant / `rabbit-fem-mpich`)**: MPICH runtime — `sudo apt-get install -y mpich`
- **Windows (`rabbit-fem-mpi`)**: Install the [Microsoft MPI runtime](https://learn.microsoft.com/en-us/message-passing-interface/microsoft-mpi) and use its `mpiexec.exe`. This build does not include MFEM.

For a Windows MPI wheel built by CI, download the `rabbit-fem-windows-mpi-wheel`
artifact and install it in a clean environment. Once this wheel is published,
`pip install rabbit-fem-mpi` can install it directly on Windows:

```powershell
$wheel = (Get-ChildItem .\rabbit_fem_mpi-*-win_amd64.whl | Select-Object -First 1).FullName
pip install $wheel
mpiexec -n 2 rabbit simulation_mpi.i
```

---

## Usage

### 1. Running Simulations with the `rabbit` CLI

Execute any MOOSE `.i` input file directly from your terminal:

```bash
# Run a packaged thermo-mechanical benchmark directly
rabbit -i $(python -c "from rabbit.sims import cube_thermomech_input_path, EElemType; print(cube_thermomech_input_path(EElemType.HEX8))")

# Or run any local MOOSE simulation
rabbit simulation.i
```

Useful flags (forwarded to the MOOSE application):

```bash
rabbit --version
rabbit --help
```

Parallelise on one machine with shared-memory threads (serial wheel):

```bash
rabbit simulation.i --n-threads=4
```

Run multi-rank with the MPI variant (use `mpiexec` on Windows, see above):

```bash
mpirun -n 4 rabbit simulation.i
```

The packaged MOOSE examples in `src/rabbit/sims/` have separate solver inputs.
Regular `.i` files select SMP solver settings; `_mpi.i` files select MPI
settings. Each solver include contains its complete preconditioner and
executioner setup. The CLI and Python runner honor that selection without
injecting a PETSc preconditioner. MFEM examples require the MPI wheel.

The cube SMP inputs use ILU/GMRES, while the MPI inputs use Hypre/GMRES.
The meshes are small, so either one MPI rank with four threads or four MPI
ranks can be used to check the MPI solver. For one rank with four threads:

```bash
rabbit cube_thermomech_HEX8.i --n-threads=4
rabbit cube_thermomech_HEX8_mpi.i --n-threads=4
```

For four ranks, use `mpirun -n 4 rabbit cube_thermomech_HEX8_mpi.i`.
In Python, select the MPI input with
`cube_thermomech_input_path(EElemType.HEX8, mpi=True)`; the dogbone,
plate tensile, monoblock, and STC input path helpers also accept `mpi=True`.

### 2. Python Dataset and Simulation Runner API

`rabbit-fem` packages simulation files and provides helpers to locate inputs, generate meshes with Gmsh, and execute solves:

```python
from rabbit.sims import (
    EElemType,
    cube_thermomech_input_path,
    run_rabbit,
)

# Locate packaged HEX8 thermo-mechanical cube input
input_file = cube_thermomech_input_path(EElemType.HEX8)

# Execute rabbit on the simulation
result = run_rabbit(input_file)
print("Simulation completed with return code:", result.returncode)
```

---

## Examples

Runnable example scripts demonstrating Gmsh mesh generation and MOOSE simulation execution are located in [`src/rabbit/examples/`](src/rabbit/examples/):

- [`ex0_cube.py`](src/rabbit/examples/ex0_cube.py) — 3D thermo-mechanical cube benchmark on structured HEX8 elements.
- [`ex1_dogbone.py`](src/rabbit/examples/ex1_dogbone.py) — 2D tensile dogbone mesh generation in Gmsh and linear elastic solve.
- [`ex2_tensile_plate.py`](src/rabbit/examples/ex2_tensile_plate.py) — 2D plate with a central hole mesh in Gmsh and elastic tension solve.
- [`ex3_stc_thermal.py`](src/rabbit/examples/ex3_stc_thermal.py) — 3D single thermal component (STC) with radiation and temperature-dependent conductivity.
- [`ex4_monoblock_thermomech.py`](src/rabbit/examples/ex4_monoblock_thermomech.py) — 3D monoblock fusion component mesh generation and coupled thermo-mechanical solve.

Run any example with:

```bash
uv run python src/rabbit/examples/ex0_cube.py
uv run python src/rabbit/examples/ex1_dogbone.py
```

---

## Testing

Run the full test suite from the repository root:

```bash
# Entire suite (unit, simulation, relocatability, gold regression)
pytest test/ -v

# Or via the build orchestrator (same suite)
uv run python build_rabbit.py --test
```

The suite includes:

- **Simulation tests** (`test/test_simulations.py`) — execute packaged benchmarks (cube, dogbone, plate) and verify Exodus output is produced.
- **Relocatability tests** — verify the staged binary carries no hardcoded build-tree paths and runs from an isolated directory.
- **Gold regression tests** (`test/test_cube_gold.py`) — run every `cube_thermomech_*` element case (HEX8/20/27, TET4/10/14) and compare mesh, nodal fields (temperature, displacement, strain), and postprocessors against committed snapshots in [`test/gold/`](test/gold/) within floating point tolerance. Field data is read with the minimal vendored Exodus II reader in [`src/rabbit/exodus.py`](src/rabbit/exodus.py).

After an intentional physics change, regenerate the gold snapshots locally and commit the result:

```bash
PYTHONPATH=src python scripts/generate_cube_gold.py --force
```

Every CI build workflow additionally runs a **clean-venv smoke test** on the already-built wheel: it installs `dist/*.whl` into a fresh virtual environment outside the repo with build environment variables stripped, checks `rabbit --version`, audits linkage for missing libraries, and executes a real HEX8 solve. This catches missing bundled shared libraries that the build-tree test suite cannot see.

---

## Build from Source

### Overview

`rabbit-fem` builds on **Linux** (Ubuntu 22.04+ or compatible), **native Windows** (x86_64), and **macOS** (Apple Silicon and Intel) using the Zig C/C++ compiler from `ziglang==0.16.0`. Compilation is split into five discrete, cacheable stages (also mirrored by the CI dependency caches):

```mermaid
flowchart TD
    S1["Stage 1: PETSc<br/><code>--build-petsc</code>"] --> S2["Stage 2: libMesh<br/><code>--build-libmesh</code>"]
    S2 --> S3["Stage 3: WASP & HIT<br/><code>--build-wasp</code>"]
    S3 --> S4["Stage 4: MOOSE Config<br/><code>--configure-moose</code>"]
    S4 --> S5["Stage 5: Rabbit & Wheel<br/><code>--wheel --test</code>"]
```

| OS | Build driver | Output wheel |
|---|---|---|
| Linux x86_64 | `build_rabbit.py` | `manylinux_2_38_x86_64` |
| Windows x86_64 | `install_dependencies_windows.ps1` + `build_rabbit.py --wheel-only` | `win_amd64` |
| macOS arm64 / x86_64 | `build_rabbit.py` | `macosx_14_0_arm64` / `macosx_13_0_x86_64` |

Upstream MOOSE sources are pinned (`moose_version.txt` plus the `moose_deps.txt` lock for PETSc/libMesh/WASP) so rebuilds are reproducible.

---

### Linux Build & Testing

#### Prerequisites (Linux)

- **OS**: Linux x86_64 (Ubuntu 22.04+ or compatible)
- **System packages**: `build-essential`, `gfortran`, `libopenmpi-dev`, `openmpi-bin`, `patchelf`, `libtirpc-dev`, `libomp-dev`, `libglu1-mesa`
- **Python**: Python 3.11+ with [`uv`](https://docs.astral.sh/uv/)

```bash
sudo apt-get update && sudo apt-get install -y \
    build-essential gfortran libopenmpi-dev openmpi-bin patchelf libtirpc-dev libomp-dev libglu1-mesa

# Set up Python environment
uv venv .venv
uv pip install ziglang==0.16.0 wheel packaging pyyaml jinja2 pytest gmsh numpy netCDF4
```

#### Step 1: Upstream MOOSE Dependencies

Compile all dependencies at once:

```bash
uv run python build_rabbit.py --moose
```

Or execute individual stages independently:

```bash
uv run python build_rabbit.py --build-petsc
uv run python build_rabbit.py --build-libmesh
uv run python build_rabbit.py --build-wasp
uv run python build_rabbit.py --configure-moose
```

#### Step 2: Build Rabbit, Stage Artifacts & Package Wheel

Compiles RabbitApp with the Zig toolchain, strips symbols, rewrites RPATHs with `patchelf`, packages the `.whl` into `dist/`, and runs tests:

```bash
uv run python build_rabbit.py --wheel --test
```

---

### Windows Build & Testing

#### Prerequisites (Windows)

1. **Python 3.11+** (with [`uv`](https://docs.astral.sh/uv/)):
   ```powershell
   winget install astral-sh.uv
   ```
2. **Git Long Paths**:
   ```powershell
   git config --global core.longpaths true
   ```
3. **MSYS2** (used strictly for Unix shell utilities and GNU Make needed by PETSc/libMesh/MOOSE configure and build scripts; compilation itself is handled by Zig):
   ```powershell
   winget install --id MSYS2.MSYS2 --source winget
   C:\msys64\usr\bin\pacman.exe -S --needed --noconfirm make diffutils patch python m4 git cmake
   ```

#### 1-Step Automated Windows Build

Run the automated PowerShell build script from the repository root:

```powershell
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1
```

This script:
- Creates and sets up `.venv` with `uv`.
- Installs Python dependencies (`ziglang`, `packaging`, `pyyaml`, `jinja2`, `pytest`, `gmsh`, `wheel`, `numpy`, `netCDF4`).
- Configures and builds **PETSc**, **libMesh**, **WASP**, and the **MOOSE** framework using the Zig C/C++ compiler.
- Compiles and links `rabbit-opt.exe` with Heat Transfer, Solid Mechanics, Contact, Ray Tracing, and Shifted Boundary Method.
- Stages `rabbit.exe` into `src/rabbit/bin/` and executes the simulation test suite.

#### Running Tests on Windows

Once the environment and binary are built, you can run the test suite in several ways:

1. **Using `uv run`** (Recommended):
   ```powershell
   uv run pytest test/ -v
   ```
   or using the build script:
   ```powershell
   uv run python build_rabbit.py --test
   ```

2. **Using `.venv` directly**:
   ```powershell
   $env:PYTHONPATH = "src"
   .\.venv\Scripts\python.exe -m pytest test/ -v
   ```

#### Building the Standalone Windows Wheel

To package the staged executable into a distributable wheel:

```powershell
uv run python build_rabbit.py --wheel-only --test
```

This generates `dist/rabbit_fem-*-py3-none-win_amd64.whl` (fully self-contained, ~56 MB).

#### Windows PowerShell Stages

`scripts/install_dependencies_windows.ps1` accepts the `-Stage` parameter:

```powershell
# Build individual stages
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage petsc
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage libmesh
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage wasp
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage moose
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage rabbit
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage test

# Full pipeline
powershell -ExecutionPolicy Bypass -File scripts\install_dependencies_windows.ps1 -Stage all
```

---

### macOS Build & Testing

#### Prerequisites (macOS)

- **OS**: macOS on Apple Silicon (arm64) or Intel (x86_64)
- **Homebrew packages**: `open-mpi`, `gcc`, `llvm`, `libomp`, `libpng`, `hdf5-mpi`, `bison`, `flex`, `pkgconf`, `cmake`
- **Python**: Python 3.11+ with [`uv`](https://docs.astral.sh/uv/)

```bash
brew install open-mpi gcc llvm libomp libpng hdf5-mpi bison flex pkgconf cmake

# Set up Python environment
uv venv .venv
uv pip install ziglang==0.16.0 wheel packaging pyyaml jinja2 pytest gmsh numpy netCDF4
```

#### Build Stages

The macOS build follows the same five stages as Linux, driven by `build_rabbit.py` (macOS-specific compiler flags and portability patches live in `scripts/build/darwin.py` and `patches/macos/`):

```bash
# Individual stages
uv run python build_rabbit.py --build-petsc
uv run python build_rabbit.py --build-libmesh
uv run python build_rabbit.py --build-wasp
uv run python build_rabbit.py --configure-moose

# Build Rabbit, package wheel, and test
uv run python build_rabbit.py --wheel --test
```

---

### `build_rabbit.py` Command Reference

| Command / Flag | Description |
|---|---|
| `--build-petsc` | Build only upstream PETSc dependency stage |
| `--build-libmesh` | Build only upstream libMesh dependency stage |
| `--build-wasp` | Build only upstream WASP parser and HIT utility stage |
| `--configure-moose` | Run only MOOSE framework configuration stage (`MooseConfig.h`) |
| `--moose [PATH]` | Build all upstream MOOSE dependencies (PETSc, libMesh, WASP) |
| `--setup-wrappers` | Generate only compiler wrapper scripts in `.zig_wrappers/` |
| `[default]` | Compile Rabbit and stage relocatable binaries in `src/rabbit/` |
| `--wheel` | Compile Rabbit, stage artifacts, and build wheel in `dist/` |
| `--wheel-only` | Package existing staged artifacts into `dist/*.whl` without recompiling |
| `--test` / `--tests` | Run pytest simulation and relocatability test suite (`test/`) |
| `--all` | Full pipeline: MOOSE build, Rabbit build, staging, wheel, and tests |
| `--mpi` | Build the MPI variant (produces the `rabbit-fem-mpi` wheel) |
| `--no-mpi` | Build the serial/SMP variant (default) |

Alternatively, `zig build` delegates to the same orchestrator (`build.zig` runs `build_rabbit.py` with the default Rabbit build step):

```bash
zig build
```

---

## License

`rabbit-fem` is distributed under the GNU Lesser General Public License v2.1 (LGPL-2.1), matching the MOOSE framework license. See [`LICENSE`](LICENSE) for details.
