ORFAS
A nonlinear physics simulation engine written in Rust for soft-tissue biomechanics, built as a reliable alternative to ageing C++ tools.
Context
Soft-tissue simulation for medical applications (surgical planning, haptic feedback, organ digital twins) has relied for decades on C++ tools like SOFA or FEBio. SOFA in particular directly inspired ORFAS, but its C++ plugin architecture makes integrating new components costly. On the Rust side, the ecosystem's most mature FEM library, Fenris, has been inactive since 2022.
ORFAS grew out of that double observation: rebuild a physics simulation engine in Rust, a language designed to rule out an entire class of memory bugs common in scientific computing by construction, with an architecture where every building block (element, material, solver) is interchangeable by design rather than frozen into a class hierarchy.
Overview
ORFAS is organized into four independent building blocks, each published as its own Rust module, that combine to form the full chain — from input data to the visualized result.
The physics engine
The heart of the project doesn't rely on a fixed class hierarchy: every finite element, every material model and every solver is an independent, interchangeable component, thanks to Rust's generic trait system. In practice, any element type can be simulated with any behaviour model and any solver, with no special-case code needed for each combination.
A simulation always follows the same processing chain:
Mesh
Material
Solve
Validation
And that independence shows up at three levels, freely combinable:
Elements
Linear tetrahedronQuadratic tetrahedronHexahedron3D beamShellMaterials
Reference (linear)Isotropic hyperelasticAnisotropic (fibers)ViscoelasticSolvers
StaticImplicit dynamicAny combination across these three families is valid: a shell mesh with an anisotropic material and a dynamic solver works just as natively as a linear elastic tetrahedron in statics.
Element library
| Element | Use case |
|---|---|
| Linear tetrahedron | Quickly generated meshes, moderate accuracy |
| Quadratic tetrahedron | Higher accuracy, validated node-by-node against a reference solver |
| Hexahedron | Structured meshes, no numerical locking |
| 3D beam | Wire-frame structures (Euler-Bernoulli formulation) |
| Shell | Thin surfaces (Bathe & Dvorkin, 1986 formulation) |
Behaviour models
Nine behaviour models span linear elasticity all the way to anisotropic fibrous tissue: Saint-Venant-Kirchhoff, linear elasticity, Neo-Hookean, Mooney-Rivlin, Ogden, Holzapfel-Ogden (anisotropic fibers), and a viscoelastic extension applicable to any of the previous models to capture the viscous behaviour of living tissue.
Solvers
Two solving modes are available: static, via Newton-Raphson iterations (with a cached-tangent variant to speed up convergence), and dynamic, via implicit Euler integration with Rayleigh damping to numerically dissipate energy. Linear systems are solved with preconditioned conjugate gradient, assembled in parallel across cores.
Calibrated biological tissue library
Rather than leaving the user to guess physical parameters, ORFAS ships ten pre-calibrated tissues, each sourced from a published scientific paper and shipped with a confidence interval.
Engineering philosophy
Verify, don't assume. A poorly formulated material model can look visually plausible while silently violating the laws of physics. ORFAS ships a physical consistency checker that automatically tests any behaviour model against eight criteria before allowing it into a simulation — never assume a result is correct just because it "looks right".
Don't parallelize blindly. I tried parallelizing the element-by-element internal force computation, assuming more threads would always be faster. Measured, it wasn't true for that specific step: thread launch overhead outweighed the actual compute time. Kept that part sequential, reserved parallel computing for the global assembly step where the gain is real and measured.
Validation & performance
Rigor doesn't stop at unit tests: every new feature is compared against a known mathematical solution or a recognized reference solver, with the error measured and documented rather than a simple checkbox.
Another cross-check example: when a generic model (Mooney-Rivlin, Ogden) is reduced to the parameters of a known special case, it must fall back exactly onto the corresponding historical model — which it does here, down to machine precision.
Parallel assembly speedup measured on 20 cores, by mesh node count — the ceiling around 10× matches what Amdahl's law predicts.
Interactive viewer
The computation engine ships with an interactive 3D viewer that lets you import a mesh, pick a preset tissue or enter parameters manually, set boundary conditions with a click, run a static or dynamic simulation, and watch the deformation and displacement map update in real time — without writing a single line of code.
Current status
ORFAS is explicitly labelled Pre-Alpha (version 0.8.1, citable via its Zenodo DOI). The roadmap toward 1.0 is laid out theme by theme:
- Export/import — VTU, OBJ, STL, DICOM/NIfTI formats
- Scientific rigor — type-safe physical units, automated error metrics
- Rendering — a dedicated graphics engine, a viewer built for clinical use
- Rigid bodies & contact — FEM-rigid coupling, tissue-tissue and tissue-instrument contact
- Model reduction — reduced bases for real-time simulation
- Dynamic topology — real-time surgical cutting and local remeshing
- Interfaces — Python and WebAssembly bindings
- Real-time & haptics — a 1000 Hz compute loop for haptic feedback
- Stable 1.0 — C/C++ API, integration as a SOFA plugin
A multi-year engineering plan rather than a one-off prototype.