Files
OneCAD-Simulation/crates/lbm/src/lib.rs
T
jyvikoandClaude Opus 5.5 d5bd74570f Rename the project to FieldCraft
Crates fieldcraft-*, binaries fieldcraft and fieldcraft-cli, the .fieldcraft file (format tag
fieldcraft/1, manifest fieldcraft.json), FIELDCRAFT_* environment variables, the MCP server
name, egui widget ids (fc_*), the app icon document FieldCraft.icon and its generated family,
docs and licences. No compatibility shim: no files of the earlier name exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-13 23:51:40 -04:00

110 lines
5.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! FieldCraft's lattice Boltzmann flow solver (CPU).
//!
//! It solves a fluid step of the model ([`fieldcraft_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 `fieldcraft_mesh::predicates`).
//!
//! No code of any lattice Boltzmann package was read; everything is written from these papers and
//! the book.
//!
//! # Determinism
//! Double precision and fixed loop orders. Collision and streaming run on threads by fixed blocks
//! of cells ([`fieldcraft_parallel`]), each cell's update independent of the others; the wall
//! forces and every other sum run in a fixed order on one thread. The same model gives the same
//! result bit for bit on any number of threads and 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] fieldcraft_model::Error),
#[error(transparent)]
Mesh(#[from] fieldcraft_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,
}
}
}