A D2Q9 lattice Boltzmann fluid simulation core for MoonBit.
git clone https://github.com/zhsyutt/moonbit-lbm.git
cd moonbit-lbm
moon update
moon fmt --check
moon check --target all --deny-warn
moon test --target all --deny-warn
moon run cmd/main///|
import {
"zhsyutt/moonbit-lbm" @lbm,
}moon run cmd/mainlet simulation = @lbm.Simulation::new(
size=@lbm.Size::new(width=128, height=48),
options=@lbm.SimulationOptions::new(
model=@lbm.CollisionModel::bgk(omega=1.0),
boundary=@lbm.BoundaryMode::BounceBack,
force_x=0.000001,
),
)
simulation.set_box_walls()
simulation.set_uniform(rho=1.0, ux=0.0, uy=0.0)
simulation.run(500)
let report = simulation.report(name="channel")| Area | Main modules |
|---|---|
| Lattice and solver | constants.mbt, lattice.mbt, solver.mbt, advanced_solver.mbt, collision_models.mbt |
| Geometry and boundaries | geometry.mbt, geometry_boundaries.mbt, boundary_schemes.mbt, boundary_map.mbt |
| Fields and analysis | grid.mbt, field_calculus.mbt, flow_derivatives.mbt, analysis_advanced.mbt |
| Scalar transport | scalar_transport.mbt, scalar_analysis.mbt, scalar_pipeline.mbt |
| Persistence and export | checkpoint.mbt, export_*.mbt, reporting.mbt |
| Verification and studies | benchmarks.mbt, benchmark_*.mbt, numerical_checks.mbt, scheduler.mbt, sweep.mbt |
| Runnable entry point | cmd/main |
moon run cmd/mainmoon fmt --check
moon check --target all --deny-warn
moon test --target all --deny-warn
moon info
git diff --exit-codepub(all) suberror CheckpointError {
InvalidHeader
InvalidRecord(String)
InvalidSize
InvalidPayload
}pub(all) struct BenchmarkComparison {
l2_delta : Double
relative_l2 : Double
linf_delta : Double
mass_delta : Double
} derive(Debug)pub(all) struct BenchmarkGate {
max_l2 : Double
max_linf : Double
max_mass_drift : Double
} derive(Debug)fn BenchmarkGate::new(max_l2~ : Double, max_linf~ : Double, max_mass_drift~ : Double) -> BenchmarkGatepub(all) struct BenchmarkReport {
name : String
cells : Int
steps : Int
l2_error : Double
linf_error : Double
mass_drift : Double
mean_speed : Double
stable : Bool
} derive(Debug)pub(all) struct BenchmarkStatistics {
count : Int
stable_count : Int
mean_l2 : Double
mean_linf : Double
min_speed : Double
max_speed : Double
quality_score : Double
} derive(Debug)pub(all) struct BoundaryDiagnostics {
solid_cells : Int
fluid_cells : Int
exposed_faces : Int
corner_cells : Int
periodic_safe : Bool
} derive(Debug)pub(all) struct BoundarySpec {
kind : BoundaryKind
value_x : Double
value_y : Double
density : Double
} derive(Debug)pub(all) struct ConfigAudit {
valid : Bool
model_name : String
viscosity : Double
recommended_dt : Double
relaxation_margin : Double
max_mach : Double
} derive(Debug)pub(all) struct ConvergenceHistory {
capacity : Int
samples : Array[ConvergenceSample]
} derive(Debug)fn ConvergenceHistory::push(self : ConvergenceHistory, step~ : Int, residual~ : Double, mass~ : Double) -> Unitfn Field2D::statistics_masked(self : Field2D, mask~ : DomainMask, include_solid? : Bool) -> FieldStatisticspub(all) struct FieldStatistics {
count : Int
sum : Double
mean : Double
minimum : Double
maximum : Double
variance : Double
l2_norm : Double
} derive(Debug)pub(all) struct MaskReport {
total_cells : Int
solid_cells : Int
fluid_cells : Int
solid_fraction : Double
} derive(Debug)pub(all) struct MemoryEstimate {
cells : Int
distribution_bytes : Int
next_bytes : Int
mask_bytes : Int
scalar_field_bytes : Int
vector_field_bytes : Int
total_bytes : Int
} derive(Debug)pub(all) struct NumericalHealth {
finite : Bool
positive_density : Bool
mass_residual : Double
max_mach : Double
min_density : Double
max_density : Double
pass : Bool
} derive(Debug)pub(all) struct ParameterSweep {
omegas : Array[Double]
steps : Int
boundary : BoundaryMode
} derive(Debug)fn ParameterSweep::new(omegas~ : Array[Double], steps~ : Int, boundary? : BoundaryMode) -> ParameterSweeppub(all) struct RunPlan {
steps : Int
sample_every : Int
record_initial : Bool
stop_on_unstable : Bool
} derive(Debug)pub(all) struct RunSummary {
steps : Int
samples : Int
final_mass : Double
final_max_speed : Double
converged : Bool
stopped_early : Bool
} derive(Debug)fn ScalarSolver::new(size~ : Size, diffusivity~ : Double, dt~ : Double, boundary? : ScalarBoundary) -> ScalarSolverfn Simulation::sample_component(self : Simulation, axis~ : Axis, index~ : Int, component~ : String) -> Array[Double]fn Simulation::sample_line_csv(self : Simulation, axis~ : Axis, index~ : Int, component~ : String) -> Stringfn Simulation::set_cell(self : Simulation, x~ : Int, y~ : Int, rho~ : Double, ux~ : Double, uy~ : Double) -> Unitfn Simulation::set_pressure_outlet(self : Simulation, x~ : Int, density~ : Double, ux? : Double, uy? : Double) -> Unitfn Simulation::set_velocity_inlet(self : Simulation, x~ : Int, ux~ : Double, uy~ : Double, rho? : Double) -> Unitpub(all) struct SimulationOptions {
model : CollisionModel
boundary : BoundaryMode
force_x : Double
force_y : Double
density_floor : Double
max_mach : Double
} derive(Debug)fn SimulationOptions::new(model~ : CollisionModel, boundary? : BoundaryMode, force_x? : Double, force_y? : Double, density_floor? : Double, max_mach? : Double) -> SimulationOptionspub(all) struct Stability {
min_rho : Double
max_rho : Double
max_speed : Double
mass : Double
has_nan : Bool
recommended : Bool
} derive(Debug)pub(all) struct StatisticsAccumulator {
count : Int
sum : Double
sum_squares : Double
minimum : Double
maximum : Double
} derive(Debug)pub(all) struct SweepResult {
omega : Double
steps : Int
mass : Double
max_speed : Double
stable : Bool
health_pass : Bool
} derive(Debug)fn VectorField2D::blend(self : VectorField2D, other : VectorField2D, weight~ : Double) -> VectorField2Dfn abs_double(value : Double) -> Doublefn bounce_direction(direction : Int) -> Intfn clamp_double(value : Double, low~ : Double, high~ : Double) -> Doublefn clamp_int(value : Int, low~ : Int, high~ : Int) -> Intfn collide_distribution(distribution : ArrayView[Double], rho~ : Double, ux~ : Double, uy~ : Double, model~ : CollisionModel) -> Array[Double]fn cylinder_wake(width~ : Int, height~ : Int, radius? : Int, omega? : Double, inlet_velocity? : Double) -> Latticefn equilibrium(d : Int, rho : Double, ux : Double, uy : Double) -> Doublefn equilibrium_error(distribution : ArrayView[Double], rho~ : Double, ux~ : Double, uy~ : Double) -> Doublefn finite_or(value : Double, fallback~ : Double) -> Doublefn force_limit_from_density(density~ : Double, max_mach~ : Double) -> Doublefn lerp(a : Double, b : Double, t : Double) -> Doublefn mach_number(ux~ : Double, uy~ : Double) -> Doublefn nearly_zero(value : Double, tolerance? : Double) -> Boolfn periodic_coordinate(value : Int, extent : Int) -> Intfn relaxation_from_viscosity(viscosity : Double) -> Doublefn relaxation_is_stable(omega : Double) -> Boolfn safe_divide(numerator : Double, denominator : Double, fallback~ : Double) -> Doublefn scalar_diffusion_time(length~ : Double, diffusivity~ : Double) -> Doublefn scalar_finite_or(value : Double, fallback~ : Double) -> Doublefn scalar_peclet_number(velocity~ : Double, length~ : Double, diffusivity~ : Double) -> Doublefn smoothstep(edge0~ : Double, edge1~ : Double, value~ : Double) -> Doublefn speed_limit_from_mach(max_mach~ : Double) -> Doublefn stable_relaxation_range() -> (Double, Double)fn trace_streamline(velocity : VectorField2D, start~ : Point, step_size~ : Double, max_steps~ : Int) -> Array[Point]fn viscosity_from_relaxation(omega : Double) -> DoubleA D2Q9 lattice Boltzmann fluid simulation core for MoonBit.