Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

elastic

A tetrahedralized Stanford bunny resting on the ground plane

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.

Pipeline

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/

Build

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 build

Eigen 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.

Usage

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 setups

Headless 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 sweeps

Verification

The 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

Strengths

  • 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 ctest so public-API docs cannot drift out of sync with the code.

Weaknesses

  • 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 World runs springs or FEM, not a mix.

References

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.

License

Free for personal, academic, and research use. No warranty. No commercial use.

About

An elastic-body simulation

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages