forked from 1b-agent/fieldcraft-upstream
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 <2501648+jyviko@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
55 files changed
+3800
-64
No files matched your search
@@ -0,0 +1,107 @@
|
||||
//! ModelCraft's lattice Boltzmann flow solver (CPU).
|
||||
//!
|
||||
//! It solves a fluid step of the model ([`modelcraft_model::Procedure::Fluid`]) in its fluid
|
||||
//! domain: weakly compressible, isothermal, Newtonian flow on a uniform grid of cubic cells that
|
||||
//! fills the domain's box, less the cells inside the obstacle bodies.
|
||||
//!
|
||||
//! - [`voxel`]: which cells the obstacles take, decided with exact predicates from the
|
||||
//! face-tagged boundary surface, and which face each wall link meets.
|
||||
//! - [`setup`]: the step in lattice units, the time step, and the stability limits.
|
||||
//! - [`flow`]: the D3Q19 two-relaxation-time scheme with Guo forcing, halfway bounce-back
|
||||
//! walls (moving walls after Ladd), slip faces, Zou–He inlets and outlets, and the
|
||||
//! momentum-exchange force on every wall.
|
||||
//! - [`solve`]: the time loop, output frames and force histories in model units.
|
||||
//!
|
||||
//! # Sources
|
||||
//! - T. Krüger, H. Kusumaatmaja, A. Kuzmin, O. Shardt, G. Silva, E. M. Viggen, *The Lattice
|
||||
//! Boltzmann Method: Principles and Practice*, Springer 2017 (velocity sets, equilibria, units,
|
||||
//! stream–collide, bounce-back, forcing, boundary conditions).
|
||||
//! - Y. H. Qian, D. d'Humières, P. Lallemand, *Lattice BGK models for Navier–Stokes equation*,
|
||||
//! EPL 17(6):479, 1992 (D3Q19).
|
||||
//! - I. Ginzburg, F. Verhaeghe, D. d'Humières, *Two-relaxation-time lattice Boltzmann scheme:
|
||||
//! about parametrization, velocity, pressure and mixed boundary conditions*, Commun. Comput.
|
||||
//! Phys. 3(2):427–478, 2008 (TRT and the parameter Λ).
|
||||
//! - Z. Guo, C. Zheng, B. Shi, *Discrete lattice effects on the forcing term in the lattice
|
||||
//! Boltzmann method*, PRE 65:046308, 2002 (body force).
|
||||
//! - A. J. C. Ladd, *Numerical simulations of particulate suspensions via a discretized Boltzmann
|
||||
//! equation. Part 1*, JFM 271:285–309, 1994 (bounce-back, moving walls, momentum exchange).
|
||||
//! - R. Mei, D. Yu, W. Shyy, L.-S. Luo, *Force evaluation in the lattice Boltzmann method
|
||||
//! involving curved geometry*, PRE 65:041203, 2002 (momentum exchange).
|
||||
//! - Q. Zou, X. He, *On pressure and velocity boundary conditions for the lattice Boltzmann BGK
|
||||
//! model*, Phys. Fluids 9(6):1591–1598, 1997; M. Hecht, J. Harting, J. Stat. Mech. 2010,
|
||||
//! P01018 (the D3Q19 transverse correction).
|
||||
//! - P. Lallemand, L.-S. Luo, *Theory of the lattice Boltzmann method: dispersion, dissipation,
|
||||
//! isotropy, Galilean invariance, and stability*, PRE 61:6546, 2000 (stability limits).
|
||||
//! - H. Edelsbrunner, E. P. Mücke, *Simulation of Simplicity*, ACM TOG 9(1):66–104, 1990;
|
||||
//! J. R. Shewchuk 1997 (exact predicates, through `modelcraft_mesh::predicates`).
|
||||
//!
|
||||
//! No code of any lattice Boltzmann package was read; everything is written from these papers and
|
||||
//! the book.
|
||||
//!
|
||||
//! # Determinism
|
||||
//! Double precision, fixed loop orders, no threads and no parallel reductions: the same model
|
||||
//! gives the same result bit for bit on every platform, wasm included.
|
||||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
||||
#![forbid(unsafe_code)]
|
||||
// Population arrays are indexed by cell and direction counts fixed when they are allocated.
|
||||
#![allow(clippy::needless_range_loop)]
|
||||
|
||||
pub mod flow;
|
||||
pub mod lattice;
|
||||
pub mod setup;
|
||||
pub mod solve;
|
||||
pub mod voxel;
|
||||
|
||||
pub use flow::{Flow, Group};
|
||||
pub use setup::{Obstacle, Setup, fluid_step};
|
||||
pub use solve::{FluidResult, FluidStats, ForceHistory, Frame, run, solve_fluid};
|
||||
pub use voxel::Grid;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("invalid input: {0}")]
|
||||
Invalid(String),
|
||||
#[error("not found: {0}")]
|
||||
NotFound(String),
|
||||
#[error("limit reached: {0}")]
|
||||
Limit(String),
|
||||
/// The run diverged.
|
||||
#[error("unstable: {0}")]
|
||||
Unstable(String),
|
||||
#[error(transparent)]
|
||||
Model(#[from] modelcraft_model::Error),
|
||||
#[error(transparent)]
|
||||
Mesh(#[from] modelcraft_mesh::Error),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Caps on a run's size and work; a run beyond any of them is refused before it starts.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Limits {
|
||||
pub max_cells: u64,
|
||||
pub max_steps: u64,
|
||||
/// Fluid cells times time steps.
|
||||
pub max_cell_updates: u64,
|
||||
/// The memory the output frames may take.
|
||||
pub max_frame_bytes: u64,
|
||||
}
|
||||
|
||||
impl Limits {
|
||||
/// 16 million cells: about 5 GB of populations in double precision.
|
||||
pub const MAX_CELLS: u64 = 16_000_000;
|
||||
pub const MAX_STEPS: u64 = 10_000_000;
|
||||
pub const MAX_CELL_UPDATES: u64 = 1_000_000_000_000;
|
||||
pub const MAX_FRAME_BYTES: u64 = 2_000_000_000;
|
||||
}
|
||||
|
||||
impl Default for Limits {
|
||||
fn default() -> Self {
|
||||
Limits {
|
||||
max_cells: Limits::MAX_CELLS,
|
||||
max_steps: Limits::MAX_STEPS,
|
||||
max_cell_updates: Limits::MAX_CELL_UPDATES,
|
||||
max_frame_bytes: Limits::MAX_FRAME_BYTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user