Everything Anvil does.
One small core, a large library, and the machinery to solve, sweep, decompose and serve it. Every feature below is real and shipping. Short examples throughout; the Guide and Wiki go deeper.
Three types you learn once. Everything else composes from them.
Core primitives.
import anvil from anvil import Q, Relation, System # Quantity: a value with units, tracked through every op force = Q(10, "kg") * Q(9.81, "m/s^2") # 98.1 N # Relation: a physics function as a reusable component def kinetic(m, v): return {"KE": Q(0.5*m*v**2, "J")} ke = Relation(kinetic)(m=2, v=3) # {'KE': 9.0 J} # System: wire relations into a solvable graph sys = System("drop") sys.add("m", 2, "kg"); sys.use(kinetic) sys.solve()
Quantity carries units and dimensions; incompatible operations raise instead of silently corrupting a result.
Relation wraps an ordinary function, auto-extracting its inputs and outputs so it can be inspected, unit-checked and reused.
System orders the computation, detects coupling, and picks the solver. No configuration.
SI, imperial, and derived, with full dimensional analysis.
A units engine, not a lookup table.
Automatic propagation
m*a yields newtons without being told.Dimension checks
SI on demand
float(q) gives the SI value; convert between any compatible units.Offset scales
Built-in engineering and science knowledge, callable by name.
A physics library across 33 domains.
# call any built-in relation directly anvil.R.isentropic_ratios(M=2.0, gamma=1.4) anvil.R.von_mises_stress(sigma_x=80e6, sigma_y=20e6, sigma_z=0, tau_xy=30e6, tau_yz=0, tau_zx=0) anvil.R.hohmann_transfer(r1=7000e3, r2=42164e3, mu=3.986e14) anvil.R.nernst_cell_potential(E0=1.10, n=2, T=298.15, Q_rxn=1e-3) # pre-built solvable systems, including full jet-engine cycles tj = anvil.S.turbojet_cycle
Relations are grouped by dot-hierarchical domain and reachable as anvil.R.name or anvil.R.domain.name.
Five domains ship as pre-built Systems, including GasTurb-style turbojet, turbofan, afterburner and turboprop cycles with station tables and T-s / h-s diagrams.
Aero & compressible
Jet & rocket cycles
Astrodynamics & ADCS
Stress & stability
Conduction to HX
Internal flow
Cycles & gases
Classical & state-space
Fatigue & fracture
Fundamentals
General chemistry
Curve fitting
From a single forward pass to optimization over a coupled model.
Solvers, sweeps and studies.
sys = anvil.S.rocket_nozzle.copy() sys.set(P0=10e6, T0=3200) sys.solve() # auto: forward / Gauss-Seidel / Newton sys.sweep("P0", [5e6, 1e7, 2e7], parallel=4) sys.sensitivity(outputs=["thrust"]).summary() sys.optimize("thrust", {"P0": (5e6, 2e7)}, minimize=False)
The solver is chosen for you from the graph structure; you can also force forward, Gauss-Seidel or Newton.
Sweeps run in parallel and export to CSV or JSON; sensitivity ranks normalized influence of each input.
Forward to Newton
ODE / BVP / PDE
Global & local
Parallel parametric
Ranked influence
DOE & UQ
Model-order reduction, a built-in flow solver, and signal analysis.
Advanced numerics, built in.
POD & DMD
Abel transform
2D Euler solver
Spectra & filters
Industry tools wrapped as native relations. Real results only.
Real solvers, wrapped.
XFOIL · SU2
OpenFOAM · gmsh
FEniCSx · NASTRAN
pyNASTRAN and dolfinx.Cantera · CoolProp
poliastro · pykep
NASA CEA · RocketCEA
OpenMDAO · surrogates
No mock fallbacks
Author, isolate and promote relations without touching the global set.
A registry you can build on.
# develop in an isolated project store with anvil.project("study", path="./work") as proj: anvil.push(my_relation, domain="aero") # project only proj.R.my_relation(M=2.0) anvil.R.isentropic_ratios(M=2.0) # globals still visible proj.promote("my_relation") # graduate to global anvil.check("my_relation") # smoke-test any relation
Relations are stored as Python source in a per-project SQLite registry, reconstructed into live callables on demand.
Experiment in a project store, validate with anvil.check, then promote to the global registry when ready.
A calculator and a node-graph builder over the same engine.
The web workbench.
Any relation, unit-aware
500 kPa, read outputs with units and a typeset formula.Node-graph builder
Curated collections
Result tray
HTML & Markdown
Curve fitting
Scratch calculator
Command palette
One command to launch; call it from anywhere.
Start it, then call it.
$ python start_anvil.py # provisions, launches, opens UI $ anvil doctor # what tools are usable here $ anvil serve # start the API server # call a running server from any Python from anvil.client import AnvilClient AnvilClient().solve("isentropic_ratios", M=2.0, gamma=1.4)
The core needs only NumPy and SciPy. One command provisions and launches, no npm, no build step; the web bundle ships prebuilt.
Everything is scriptable and REST-addressable: solve, sweep, and read the registry over HTTP, or export CSV and JSON.
Open source, MIT licensed.
Anvil is free to use, read, fork and extend. The core stays lean, numpy and scipy only, with every heavier tool an optional extra. No accounts, no telemetry, no lock-in.
Read the source →Built to be extended by LLMs.
A relation is plain Python stored as source, so an LLM can author one from a page of equations. Anvil ships a feed-me prompt, docs/RSQ_AUTHORING_PROMPT.md, and a pipeline guide; the physics and chemistry packs were authored this way and validated against textbook values before shipping.