Lattice Boltzmann flow on the CPU: model, solver, engine (M12) (#36)

Model: Newtonian fluid materials; fluid domains (box, spacing, conditions on
the box faces, obstacle bodies with conditions on their named faces, initial
velocity, body acceleration); fluid steps with caps. Deck writers refuse
fluid steps; a fluid-only model needs no mesh in model.check; one step
selector (Model::select_step) for every solver.

New L2 crate modelcraft-lbm: D3Q19 two-relaxation-time collision with Guo
forcing; halfway bounce-back walls (moving walls after Ladd), slip faces,
periodic pairs; Zou–He velocity and pressure faces with the D3Q19
transverse correction; obstacles voxelised from the face-tagged boundary
surface with exact predicates and symbolic perturbation; momentum-exchange
forces per box face and per B-rep face; unit conversion, automatic time step
and Mach/tau limits; bounded runs with frames and force histories.

Engine: model.fluid_domain.create/edit/delete, model.fluid_domain.boundary,
solve.fluid (obstacles from the open design or imported surfaces, lowerable
caps), solve.probe for fluid fields and wall force histories. Fluid Domain,
Inlet & Outlet and Lattice Boltzmann toolbar entries are ready.

Verification (analytic): plane Poiseuille exact with Λ = 3/16 and second
order (2.000) with Λ = 1/4; Couette exact with the wall shear; Taylor–Green
decay second order (2.01, 2.00); staircase pipe; Stokes drag of a sphere
array within 1.7% of Hasimoto at R = 6; Zou–He channel; mass conserved to
round-off; bit-for-bit reproducibility. Benchmark: Schäfer–Turek 2D-1.


Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

Co-authored-by: jyviko <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
authored and GitHub committed 2026-10-13 20:03:12 -04:00
1 parent bd55abea7f
commit a17752a49f
55 files changed
+3800 -64

No files matched your search

+39 -1
View File
@@ -24,8 +24,9 @@ crates in strictly lower layers.
| L1 | `modelcraft-fem` | Element kernels shared by every structural solver: the element table (tet4, tet10, wedge6, hex8 full and incompatible modes, hex20 full and reduced), shape functions, quadrature, element stiffness, consistent and lumped mass, body and pressure loads, stresses and their extrapolation, isotropic and orthotropic elasticity, and the uniform-strain (one-point) hex8 and tet4 kinematics, hourglass shape vectors and element frequency bounds of the explicit solver. Pure functions, no solver loop. | started |
| L1 | `modelcraft-decks` | Abaqus input, Nastran bulk data and LS-DYNA keyword readers and writers, to and from `model`. Text out, no file system; `deck.write` saves it. | started |
| L1 | `modelcraft-render` | Display data without a GPU dependency: the visible faces, element edges and nodes of a model, the orbit camera, a CPU rasterizer for headless snapshots, geometry surfaces with their face boundaries, deformed shapes and banded contour plots of nodal results, picking. | started |
| L2 | `modelcraft-solver` | Implicit solver: assembly from the resolved model, boundary conditions, sparse direct solution, linear static and modal analysis, stresses and reactions. The lattice Boltzmann solver (`modelcraft-lbm`) joins this layer. | started |
| L2 | `modelcraft-solver` | Implicit solver: assembly from the resolved model, boundary conditions, sparse direct solution, linear static and modal analysis, stresses and reactions. | started |
| L2 | `modelcraft-explicit` | Explicit dynamics: central-difference time integration with lumped mass, one-point hex8 with hourglass control, nodal-pressure tet4, bulk viscosity, rigid walls, energy account, histories and field frames. | started |
| L2 | `modelcraft-lbm` | Lattice Boltzmann flow solver on the CPU: D3Q19 two-relaxation-time scheme, bounce-back and slip walls, Zou–He inlets and outlets, obstacles voxelised from the face-tagged surface with exact predicates, momentum-exchange forces per face. Uses `mesh` for the predicates and the boundary surface. | started |
| L3 | `modelcraft-fsi` | Fluid–structure coupling between the L2 solvers (later). | planned |
| L4 | `modelcraft-doc` | The document: geometry, mesh, model, results, history. | planned |
| L5 | `modelcraft-io` | `.modelcraft` files (docs/formats/modelcraft.md): text model definition, binary mesh, geometry references with content hashes, the journal; atomic saves; autosave storage for crash recovery. Bytes in, bytes out; the file system only in `fs` and `recovery`. Result files later. | started |
@@ -205,6 +206,43 @@ The first version is geometrically linear with linear elastic materials. Verific
speed, plateau force ρ c v₀ A), the energy balance, bit-for-bit repeatability; in the engine
(`solve.rs`), a cantilever's free-vibration period against `solve.frequency`.
## Lattice Boltzmann solver
`modelcraft-lbm` solves a model's fluid steps (`solve.fluid`; `solve.probe` reads velocity and
pressure at points and wall force histories). Papers are cited in the module docs and in
`docs/solvers/literature.md` (Part I).
1. **Model.** A fluid material (density, Newtonian viscosity), a fluid domain (box, cubic cell
spacing, a condition on each box face: wall, moving wall, slip, velocity inlet with a uniform
or parabolic profile, pressure outlet, periodic pair; obstacle bodies and moving-wall
conditions on their named faces; initial velocity; body acceleration) and a fluid step (end
time or steps, optional time step, frames, the TRT parameter Λ). Deck writers refuse fluid
steps.
2. **Setup.** Lattice units from the spacing, the time step and the density. Without a given
time step the solver keeps the characteristic lattice velocity at 0.05 and τ ≤ 1. A lattice
Mach number above 0.3, τ below 0.505 or a lattice acceleration above 0.01 is refused with the
numbers and what to change; caps on cells, steps, cell updates and frame memory are checked
before anything is allocated.
3. **Grid.** The engine triangulates each obstacle body (or takes an imported surface) and
prepares its `BoundarySurface`; cells whose centres have a positive winding number are solid,
decided with exact `orient2d`/`orient3d` and one symbolic perturbation, so faces through cell
centres and lines through edges are classified consistently.
4. **Stepping.** TRT collision with Guo forcing in place; pull streaming as one shifted copy per
direction with per-link rules for the cells next to walls and box faces; Zou–He on inlet and
outlet layers. Wall links give the momentum exchanged with every box face and B-rep face
(the face of the triangle nearest the link). A non-positive density or a lattice speed above
0.5 stops the run with an error.
5. **Results.** Frames of velocity and gauge pressure per cell (single precision), force
histories per wall and the fluid mass, in model units, stored per step like the implicit
results.
Verification (`crates/lbm/tests/verification.rs`, analytic): plane Poiseuille exact to round-off
with Λ = 3/16 and second order with Λ = 1/4; Couette exact with the wall shear μU/H; Taylor–Green
decay second order; Poiseuille in a staircase pipe; Stokes drag of a simple cubic sphere array
against Hasimoto (1959); a parabolic-inlet, pressure-outlet channel against Poiseuille; mass
conserved to round-off; bit-for-bit reproducibility. `crates/lbm/tests/benchmark.rs` (ignored,
published reference values): Schäfer–Turek 2D-1.
## Commands
Every user-visible action is a `CommandSpec` in `crates/engine/src/cmd/<area>.rs` with a JSON
+4 -4
View File
@@ -5,7 +5,7 @@ Generated from the capability catalogue (`crates/engine/src/catalogue.rs`) by
Every entry is a toolbar button. **Ready** entries run their command; **coming soon** entries are
shown greyed with the roadmap milestone that brings them (ROADMAP.md).
42 ready, 58 coming soon.
45 ready, 55 coming soon.
## Geometry
@@ -90,8 +90,8 @@ shown greyed with the roadmap milestone that brings them (ROADMAP.md).
|---|---|---|---|
| Boundary Conditions | Boundary Condition — Fixed, displacement or symmetry condition on a set or reference point | ready | `model.boundary_condition.create`, `model.boundary_condition.edit`, `model.boundary_condition.delete` |
| Loads | Load — Force, moment, pressure, traction, gravity or body force | ready | `model.load.create`, `model.load.edit`, `model.load.delete` |
| Flow | Fluid Domain — The fluid grid voxelised from the face-tagged surface | coming soon (M12) | |
| Flow | Inlet & Outlet — Velocity inlets, pressure outlets and walls | coming soon (M12) | |
| Flow | Fluid Domain — The box of fluid cells, its fluid, and the obstacle bodies voxelised from their face-tagged surfaces | ready | `model.fluid_domain.create`, `model.fluid_domain.edit`, `model.fluid_domain.delete` |
| Flow | Inlet & Outlet — Velocity inlets, pressure outlets, walls, moving and slip walls, periodic faces | ready | `model.fluid_domain.boundary` |
## Interactions
@@ -123,7 +123,7 @@ shown greyed with the roadmap milestone that brings them (ROADMAP.md).
| Implicit | Frequency — Natural frequencies and mode shapes of a frequency step | ready | `solve.frequency` |
| Explicit | Explicit — Transient dynamics of an explicit step by central differences (contact and erosion coming in M10) | ready | `solve.explicit` |
| Explicit | Blast & Impact — EOS-driven fluids with fluid–structure contact (ALE or SPH) | coming soon (M14) | |
| Fluids | Lattice Boltzmann — Lattice Boltzmann flow on the CPU or the GPU | coming soon (M12) | |
| Fluids | Lattice Boltzmann — Lattice Boltzmann flow of a fluid step on the CPU, with wall forces | ready | `solve.fluid` |
| Fluids | Fluid–Structure — Coupled fluid and structure solve | coming soon (M13) | |
## Results
+29
View File
@@ -1024,3 +1024,32 @@ again in the module docs):
element keeps 1 − 1/n² of the bending energy with n elements through the depth, which predicts
its period with viscous hourglass control to 0.03%.
## Part I: Lattice Boltzmann core (M12, plan L1), as implemented
`modelcraft-lbm` is written from these papers and the book (cited again in its module docs). No
lattice Boltzmann package's code was opened.
- Lattice, equilibrium, units, stream–collide, bounce-back, forcing and boundary conditions:
Krüger et al. 2017 (C1.2); D3Q19 from Qian, d'Humières & Lallemand 1992 (C1.3).
- Collision: two relaxation times, Ginzburg, Verhaeghe & d'Humières 2008 (C2.2). The parameter
Λ = (τ⁺ − ½)(τ⁻ − ½) is the step's `magic` (default 3/16: walls exactly halfway).
- Body force: Guo, Zheng & Shi 2002 (C1.6), split into the symmetric and antisymmetric parts
relaxed with τ⁺ and τ⁻.
- Walls: halfway bounce-back, Ladd's moving-wall term and momentum exchange (Ladd 1994, C3.1);
momentum exchange also after R. Mei, D. Yu, W. Shyy, L.-S. Luo, *Force evaluation in the
lattice Boltzmann method involving curved geometry*, PRE 65:041203, 2002 (DOI not checked).
- Inlets and outlets: Zou & He 1997 (C3.3), with the D3Q19 transverse-momentum correction of
M. Hecht, J. Harting, *Implementation of on-site velocity boundary conditions for D3Q19
lattice Boltzmann simulations*, J. Stat. Mech. 2010, P01018 (DOI not checked).
- Stability limits (Mach ≤ 0.3, τ⁺ ≥ 0.505, runtime speed ≤ 0.5): Sterling & Chen 1996 and
Lallemand & Luo 2000 (C1.5) for the shrinking stable region as τ → ½.
- Voxelisation: Shewchuk's exact `orient2d`/`orient3d` (`modelcraft_mesh::predicates`) with a
symbolic perturbation after H. Edelsbrunner, E. P. Mücke, *Simulation of Simplicity*, ACM TOG
9(1):66–104, 1990; link faces by nearest triangle, C. Ericson, *Real-Time Collision Detection*,
Morgan Kaufmann 2005, §5.1.5.
- Verification: analytic Poiseuille, Couette and Taylor–Green solutions (C8); the Stokes drag of
a simple cubic array of spheres, H. Hasimoto, *On the periodic fundamental solutions of the
Stokes equations and their application to viscous flow past a cubic array of spheres*, JFM
5(2):317–328, 1959, with the higher terms of A. S. Sangani, A. Acrivos, Int. J. Multiphase Flow
8(4):343–360, 1982 (DOIs not checked). Benchmark (published numerical reference values, tagged,
not part of the analytic gate): Schäfer & Turek 1996, 2D-1 (C8).