A C++20 finite-element simulator for elastic deformation of solid bodies. Loads surface or volume meshes, tetrahedralizes them via TetGen, and integrates them under gravity, contact, and constraints — co-rotational or Stable Neo-Hookean material → implicit Newton step → collision response.
elastic::World (positions, velocities, masses, tets,
│ force model, gravity, ground plane, pins)
▼
per render frame: N substeps of the integrator
│
├─ semi-implicit (symplectic) Euler — explicit, CFL-limited (Δt ≲ h/c)
└─ implicit Euler / Crank–Nicolson — θ-blended, Newton solve with a
│ sparse inner solve (LDLT or CG); stable at large Δt
│ (Baraff & Witkin, SIGGRAPH 1998)
▼
assemble internal forces from the active model
│ edge springs · co-rotational linear FEM (Müller & Gross 2004)
│ · Stable Neo-Hookean (Smith, de Goes, Kim 2018) with an
│ SPD-projected Hessian (Teran et al. 2005) for robust Newton
▼
apply constraints
│ static Dirichlet pins via symmetric DOF elimination
│ (zero row/col, 1 on the diagonal) — exact, no huge-mass hack
▼
resolve collisions
│ infinite ground plane · self-collision via an AABB BVH with
│ continuous collision detection (Bridson, Fedkiw, Anderson 2002)
▼
updated World ──► Polyscope viewer (apps) or measurement (tests)
State is value-typed end to end: a whole simulation lives in one
elastic::World, copied or moved like any struct, with no globals. All
vectorised state is column-major 3 × N (Eigen-native), so kernels get
contiguous buffers without copies.
The integrators are in core/src/solver/{semi_implicit_euler,implicit_euler}.cpp;
material models in core/src/fem/{corotational,stable_neo_hookean}.cpp and
core/src/edge_springs.cpp; surface→tet meshing in core/src/mesh/; contact
in core/src/collision/; and the state container in
core/include/elastic/world.hpp. A Doxyfile is included for API docs:
doxygen Doxyfile # writes HTML to docs/doxygen/Requires CMake ≥ 3.24, a C++20 compiler, and (on macOS) the Xcode command
line tools. OpenMP is used to parallelise the per-element kernels — on Apple
Clang install Homebrew's libomp (the build hints at /opt/homebrew/opt/libomp
and falls back to single-threaded if it is missing).
brew install libomp # macOS, for OpenMP
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir buildEigen 3.4, libigl 2.5 (with the TetGen wrapper), Polyscope 2.3, and doctest 2.4.11 are pinned and fetched at configure time via FetchContent — no system install needed.
GUI demos (Polyscope viewer with ImGui parameter sliders):
./build/apps/falling_jello/falling_jello # co-rotational FEM cube
./build/apps/falling_blob/falling_blob mesh.obj # load + tetrahedralize a surface mesh (.obj/.stl/.ply)
./build/apps/verification_viewer/verification_viewer # hanging-bar / cantilever / eigenfrequency setupsHeadless tests (doctest + the analytic benchmarks below):
./build/tests/elastic_tests # or: ctest --test-dir build
./build/tests/elastic_tests --no-skip # also runs the gated convergence sweepsThe solver is checked against closed-form elasticity results, not just other
code. (tests/; the gated sweeps that produce the convergence tables run
under --no-skip.)
| Benchmark | Closed-form reference | Result |
|---|---|---|
| Hanging bar, axial self-weight (ν = 0) | δ = ρgL²/2E (exact in 3D) | ~0.5 % error, resolution-independent — the linear axial field is represented exactly by constant-strain tets |
| Cantilever under self-weight | Bernoulli–Euler tip deflection | ~0.80·BE at 1025 verts; converges monotonically toward BE under aspect-matched h-refinement |
| Free–free longitudinal modes | Tₙ = 2L / (n·c), c = √(E/ρ) | within ~3 % at the resolved modes; period error tracks the predicted O((kₙh)²) tet dispersion |
- Large stable timesteps. Implicit Euler / Crank–Nicolson with a Newton solve removes the explicit CFL limit; θ is selectable (backward Euler damps toward equilibrium, Crank–Nicolson preserves ringing).
- Verified against analytic references. The hanging-bar axial case lands at ~0.5 % with no resolution dependence, exactly as theory predicts for a linear strain field on constant-strain tets — a clean, non-tautological correctness anchor.
- Robust hyperelasticity. Stable Neo-Hookean stays well-behaved under element inversion via a closed-form SPD projection of the Hessian; it shares one force-model interface with the co-rotational model.
- Exact static constraints. Pinned vertices are eliminated from the linear system (symmetric row/column elimination), so anchors hold exactly — no Δt²·g drift from the common pin-by-huge-mass trick.
- Graphics-free core. The simulation library has no rendering dependency;
per-element kernels are OpenMP-parallel, and a Doxygen build is wired into
ctestso public-API docs cannot drift out of sync with the code.
- Linear tets lock in bending. Plain constant-strain tetrahedra under-predict bending: the cantilever reaches only ~0.80·BE at 1025 vertices and approaches the true 3D answer slowly. Closing the gap needs quadratic or hexahedral elements, not more linear tets — deferred.
- Constraints are implicit-only and static. Dirichlet pins are honoured by the implicit integrator alone; the semi-implicit stepper ignores them, and animated / moving handles (prescribed non-zero velocity) are not implemented — the elimination assumes Δv = 0.
- Limited contact. Collision handles an infinite ground plane and self-collision only; arbitrary obstacles (sphere/box/SDF or triangle-soup) are not yet supported, and ground response is frictionless (restitution only).
- Explicit path is CFL-bound. Semi-implicit Euler is conditionally stable (Δt ≲ h/c); stiff materials need the implicit integrator or many substeps.
- One material model at a time. A
Worldruns springs or FEM, not a mix.
Implementation basis:
- Sifakis, E. and Barbič, J. FEM Simulation of 3D Deformable Solids. SIGGRAPH 2012 Courses. https://viterbi-web.usc.edu/~jbarbic/femdefo/ — the continuum-mechanics and FEM-on-tets foundation the headers follow.
- Müller, M. and Gross, M. Interactive Virtual Materials. Graphics Interface 2004, pp. 239–246. — the co-rotational linear FEM model.
- Baraff, D. and Witkin, A. Large Steps in Cloth Simulation. SIGGRAPH '98, pp. 43–54. — the implicit-Euler + sparse-solve integrator structure.
- Smith, B., de Goes, F., and Kim, T. Stable Neo-Hookean Flesh Simulation. ACM TOG 37(2):12, 2018. — the inversion-stable hyperelastic model.
- Teran, J., Sifakis, E., Irving, G., and Fedkiw, R. Robust Quasistatic Finite Elements and Flesh Simulation. SCA 2005, pp. 181–190. — the SPD Hessian projection behind the Newton solve.
- Si, H. TetGen, a Delaunay-Based Quality Tetrahedral Mesh Generator. ACM TOMS 41(2):11, 2015. — surface→tet meshing (via libigl).
- Bridson, R., Fedkiw, R., and Anderson, J. Robust Treatment of Collisions, Contact and Friction for Cloth Animation. SIGGRAPH '02, pp. 594–603. — the continuous-collision / self-collision techniques.
Further reading (alternative methods, not used in the current solver):
- Hu, Y., Schneider, T., Wang, B., Zorin, D., and Panozzo, D. Fast Tetrahedral Meshing in the Wild. ACM TOG 39(4), 2020.
- Macklin, M., Müller, M., and Chentanez, N. XPBD: Position-Based Simulation of Compliant Constrained Dynamics. MIG 2016.
- Bouaziz, S., Martin, S., Liu, T., Kavan, L., and Pauly, M. Projective Dynamics: Fusing Constraint Projections for Fast Simulation. ACM TOG 33(4), 2014.
Closed-form references for the verification benchmarks:
- Young, W. C. and Budynas, R. G. Roark's Formulas for Stress and Strain. 7th ed., McGraw-Hill, 2002. — cantilever and hanging-bar static cases.
- Blevins, R. D. Formulas for Natural Frequency and Mode Shape. Van Nostrand Reinhold, 1979. — longitudinal free–free eigenfrequencies.
- Irvine, T. An Introduction to Shock and Vibration Response Spectra. 2019. https://www.vibrationdata.com/tutorials2/Tom_book_12_1_19.pdf — corroboration of the longitudinal-rod result.
Tools and libraries:
- Sharp, N. et al. Polyscope. polyscope.run — the GUI for every demo app.
- Jacobson, A., Panozzo, D., et al. libigl. libigl.github.io — mesh I/O and the TetGen wrapper.
- Guennebaud, G., Jacob, B., et al. Eigen v3. eigen.tuxfamily.org — dense and sparse linear algebra throughout.
Free for personal, academic, and research use. No warranty. No commercial use.
