Skip to main content

A benchmark suite for differentiable physics solvers

Project description

logo

Mosaic: a benchmark suite for differentiable physics solvers

Mosaic measures gradient quality, computational cost, and solver compatibility across 14 differentiable physics solvers in 4 domains. Each solver is packaged as a Tesseract container exposing a uniform apply / vjp interface, enabling cross-solver comparison regardless of language or AD backend.

Why Mosaic?

Differentiable physics solvers unlock gradient-based optimization for topology optimization, aerodynamic design, optimal control, and solver-in-the-loop ML. But the practical cost of obtaining correct gradients is largely undocumented: solvers span multiple languages and AD frameworks, runtime overhead varies by orders of magnitude, and subtle numerical issues (ill-conditioned Jacobians, chaotic divergence, floating-point truncation) can silently corrupt gradients. Mosaic provides a standardized, solver-agnostic evaluation that surfaces these practically relevant differences so practitioners can make informed choices.

Overview of Mosaic: diverse solver backends are wrapped behind a uniform containerized interface (Tesseract), enabling cross-solver comparison on shared benchmark tasks across different physical domains.

ID Domain Optimization task Solvers
H Heat transfer Conductivity inversion deal.II, FEniCS, Firedrake, JAX-FEM, torch-fem
S Structural mechanics Compliance minimization (SIMP) deal.II, FEniCS, Firedrake, JAX-FEM, TopOpt.jl
F2 Incompressible fluids (2D) Inflow optimization (drag) JAX-CFD, PhiFlow, INS.jl, XLB, PICT, Warp-NS, OpenFOAM
F3 3D Navier-Stokes Initial condition recovery PhiFlow, XLB, PICT, Warp-NS, Exponax, INS.jl, OpenFOAM

๐Ÿ“Š Browse the latest benchmark results โ†’

Per-domain pages with every plot, solver rankings, and the full evaluation protocol, refreshed on each release: Navierโ€“Stokes 2D ยท Navierโ€“Stokes 3D ยท Structural mechanics ยท Heat transfer


Paper reproduction: if you're here to reproduce the results from our paper, see the v0.1+paper-repro tag which contains the figure-generation code, pinned dependencies, and step-by-step instructions.

Jump to your use case:


Run the benchmarks

Requires Python >= 3.10, Docker, and (for GPU solvers) the NVIDIA Container Toolkit.

Platform note: We strongly recommend Linux with Docker Engine for the best experience. Docker Desktop on macOS and Windows runs containers inside a VM, which adds significant overhead to solver execution and can surface ARM-related compatibility issues on Apple Silicon. If you're on macOS or Windows, consider using a Linux VM or WSL 2 with Docker Engine installed natively inside it.

git clone https://github.com/pasteurlabs/mosaic && cd mosaic
uv sync          # or: pip install -e .
mosaic run       # builds containers, runs experiments, generates plots

A single-problem run with --debug (reduced grid sizes) finishes in minutes and is a good way to verify your setup:

$ mosaic run -p thermal-mesh --suites forward --debug
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ problem: thermal-mesh โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ build โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  deal.II          โ†’ dealii_heat_thermal_mesh:latest     (3.6s)
  FEniCS           โ†’ fenics_heat_thermal_mesh:latest     (3.2s)
  Firedrake        โ†’ firedrake_heat_thermal_mesh:latest  (2.4s)
  JAX-FEM          โ†’ jax_fem_thermal_mesh:latest         (5.1s)
  torch-fem        โ†’ torch_fem_thermal_mesh:latest       (4.8s)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   suite: forward โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  5 experiment(s) queued, 5 solver(s) registered
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ experiment: baseline [1/5] โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  deal.II done in 0.8s
  FEniCS done in 1.2s
  Firedrake done in 1.5s
  JAX-FEM done in 2.3s
  torch-fem done in 1.1s
...
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ summary โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ณโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”“
โ”ƒ problem      โ”ƒ forward โ”ƒ
โ”กโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ•‡โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”ฉ
โ”‚ thermal-mesh โ”‚   ok    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Inspect results

mosaic status                        # per-experiment completion table
mosaic status -p ns-grid -f          # single domain with failure reasons
mosaic status --format md > report.md
mosaic status --format json > snap.json

Pick which solvers run

-s (alias --solvers) takes either a flat CSV applied as a union across every problem, or a per-problem map for finer control:

# Flat CSV โ€” each problem keeps only the listed solvers that exist
# there; problems with zero matches are skipped.
mosaic run -s OpenFOAM,XLB,deal.II,JAX-FEM

# Per-problem map โ€” explicit picks per domain.
mosaic run -s "ns-grid=XLB,jax-cfd;structural-mesh=Firedrake,JAX-FEM"

Re-run a subset

After an initial pass, mosaic run --only <state[,โ€ฆ]> re-executes only the cells currently in the given state and leaves fresh-ok cells alone. Useful for iterating on a single solver or recovering from a partial failure without redoing everything.

mosaic run --only failed              # re-run only failed cells
mosaic run --only failed,stale        # plus anything the harness/source has invalidated
mosaic run --only missing             # first-time runs only
mosaic run -s PhiFlow --only excluded # re-check after dropping an exclusion

States: failed, anom, missing, stale, excluded. Combinable with -p / --suites / -e / -s for finer scoping.


Use Tesseracts in your own code

Every solver in Mosaic is a standalone Tesseract that you can call from your own research code โ€” no benchmark harness required.

Install

# Shared schemas (only deps: pydantic + tesseract-core)
pip install -e mosaic/mosaic_shared

# For containerised usage (recommended): also install tesseract-jax
pip install tesseract-core tesseract-jax jax

Option A: Local (no Docker)

Fastest for prototyping. Requires the solver's native Python dependencies.

import numpy as np
from tesseract_core import Tesseract
from mosaic_shared.problems.navier_stokes_grid.schemas import make_vortex_ic

ic = make_vortex_ic(N=64, seed=42)
inputs = {"v0": ic, "viscosity": np.array([0.01], dtype=np.float32), "steps": 50}

t = Tesseract.from_tesseract_api(
    "mosaic/tesseracts/navier-stokes-grid/exponax/tesseract_api.py"
)
outputs = t.apply(inputs)

Option B: Via container (requires Docker, fully isolated)

Works for every solver regardless of language. Build the image once, then use it from JAX:

$ tesseract build mosaic/tesseracts/navier-stokes-grid/exponax
import jax
import jax.numpy as jnp
from tesseract_core import Tesseract
from tesseract_jax import apply_tesseract
from mosaic_shared.problems.navier_stokes_grid.schemas import make_vortex_ic

ic = make_vortex_ic(N=64, seed=42)
inputs = {"v0": ic, "viscosity": jnp.array([0.01]), "steps": 50}

with Tesseract.from_image("exponax_navier_stokes_grid:latest") as t:
    outputs = apply_tesseract(t, inputs)
    grad_v0 = jax.grad(lambda v0: jnp.mean(
        apply_tesseract(t, {**inputs, "v0": v0})["result"] ** 2
    ))(inputs["v0"])

See Standalone Usage for the full guide (GPU usage, mesh-based solvers, common gotchas) and the Solver Reference for the per-solver catalog with image names.

Programmatic API

Mosaic also exposes a Python API for running evaluations without the CLI:

from mosaic import get_config, PROBLEMS

cfg = get_config("ns-grid")           # Problem for 2-D Navier-Stokes
print(cfg.solver_names)               # available solver backends

# Each (suite, experiment) is registered on the Problem as an Experiment
# closure. Invoke one directly with a {solver_name: image_tag} mapping:
tags = {s.name: s.image_tag for s in cfg.solvers}
results = cfg.experiments["gradient/fd_check"].fn(cfg, tags)

Available top-level imports: PROBLEMS, get_config, Problem, SolverSpec, IcSpec, and the shared suite-kernel modules forward, gradient, cost, optimization (from mosaic.benchmarks.problems.shared).


Contribute

Mosaic is designed to grow with the community. There are three ways in, roughly ordered by scope:

  • Tune an existing solver โ€” improve an out-of-the-box configuration. Snapshot mosaic status --format json before/after and include the diff in your PR. See CONTRIBUTING.md for the full workflow.
  • Add a solver to an existing domain โ€” three files under mosaic/tesseracts/<domain>/<solver-name>/. Walkthrough: Add a Solver tutorial.
  • Add a benchmark domain โ€” scaffold with mosaic new-domain <name> --from-template <template>. Walkthrough: Add a Domain tutorial.

CONTRIBUTING.md covers code style, the PR workflow, and how to build the docs locally. For questions and support, visit the Tesseract Forum.

Documentation

  • Getting Started โ€” prerequisites, installation, first benchmark
  • Use Mosaic solvers elsewhere โ€” using individual Tesseracts in your own code
  • Architecture โ€” Tesseract interface, data structures, evaluation protocol
  • Solver Reference โ€” per-solver documentation with numerical methods, AD strategies, and known limitations
  • Add a Solver โ€” step-by-step tutorial with a complete working example
  • Add a Domain โ€” end-to-end walkthrough for a new physics domain

Project structure

mosaic/
  benchmarks/             # evaluation harness (Python package: mosaic.benchmarks)
    cli.py                # command-line interface
    core/                 # runner, config, hardware detection, solver auto-discovery
    problems/             # per-domain packages (ns-grid, ns-3d-grid, structural-mesh, thermal-mesh)
      shared/             # cross-domain suite kernels (forward, gradient, cost, optimization) + plots
    plots/                # plotting infrastructure
  templates/              # task templates for scaffolding new domains
  tesseracts/             # solver backends (each is a Tesseract container)
    mosaic_shared/     # shared Tesseract interface schemas (also pip-installable)
      problems/           # per-domain input/output schemas
      utils/              # comparison metrics, plotting utilities
    navier-stokes-grid/   # JAX-CFD, PhiFlow, XLB, PICT, Warp-NS, etc.
    structural-mesh/      # deal.II, FEniCS, Firedrake, JAX-FEM, TopOpt.jl
    thermal-mesh/         # deal.II, FEniCS, Firedrake, JAX-FEM, torch-fem
  tests/                  # unit tests (run with pytest)
docs/                     # Quarto documentation site

License

Apache 2.0. Individual solver backends retain their upstream licenses, documented per solver in the repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mosaic_bench-0.1.0.tar.gz (536.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mosaic_bench-0.1.0-py3-none-any.whl (632.4 kB view details)

Uploaded Python 3

File details

Details for the file mosaic_bench-0.1.0.tar.gz.

File metadata

  • Download URL: mosaic_bench-0.1.0.tar.gz
  • Upload date:
  • Size: 536.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mosaic_bench-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d62d0b24a631ddefbc4dbb35253eb0b7b50fa95c53a9a8d6c01d9632b8e2d69f
MD5 ac7c0c4314b99d4c9d7410e2b726d828
BLAKE2b-256 88cab78eb1b68ea69f3ae93f57e307ac29b13725b7ac707de6315f292fe70ee8

See more details on using hashes here.

Provenance

The following attestation bundles were made for mosaic_bench-0.1.0.tar.gz:

Publisher: publish.yml on pasteurlabs/mosaic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mosaic_bench-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mosaic_bench-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 632.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mosaic_bench-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 53028edd5d7209a824189672a4b16a95c5f3e326e3ea4925af219f68f944f761
MD5 079ef3809e2800131f318f8a65367beb
BLAKE2b-256 729630213ab6c89e5c0f027ff9420a57cd75142c34f05d23ee2cae2e6af29211

See more details on using hashes here.

Provenance

The following attestation bundles were made for mosaic_bench-0.1.0-py3-none-any.whl:

Publisher: publish.yml on pasteurlabs/mosaic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page