Initial commit

This commit is contained in:
redclawsystems
2026-03-04 00:08:42 +00:00
commit 4d88dc0584
4449 changed files with 1556714 additions and 0 deletions
@@ -0,0 +1,189 @@
//! Incompressible flow solvers
//!
//! This module implements pressure-velocity coupling algorithms for incompressible flows:
//! - SIMPLE (Semi-Implicit Method for Pressure Linked Equations)
//! - PISO (Pressure-Implicit with Splitting of Operators)
//! - SIMPLER (SIMPLE Revised)
use crate::{CfdConfig, CfdError, CfdResult};
// use nalgebra::{DMatrix, DVector};
// use std::collections::HashMap;
/// Boundary conditions
pub mod boundary_conditions;
/// Flow field data structures
pub mod flow_field;
/// PISO algorithm implementation
pub mod piso;
/// GPU-accelerated PISO algorithm implementation
#[cfg(feature = "cuda")]
pub mod piso_gpu;
/// SIMPLE algorithm implementation
pub mod simple;
/// GPU-accelerated SIMPLE algorithm implementation
#[cfg(feature = "cuda")]
pub mod simple_gpu;
// Re-export main types
pub use boundary_conditions::{
BoundaryCondition, BoundaryConditions, BoundaryLocation, BoundaryType,
};
pub use flow_field::FlowField;
pub use piso::{PisoParameters, PisoResult, PisoSolver};
#[cfg(feature = "cuda")]
pub use piso_gpu::PisoGpuSolver;
pub use simple::{SimpleParameters, SimpleResult, SimpleSolver};
#[cfg(feature = "cuda")]
pub use simple_gpu::SimpleGpuSolver;
/// Common solver parameters
#[derive(Debug, Clone)]
pub struct SolverParameters {
/// Maximum number of iterations
pub max_iterations: usize,
/// Convergence tolerance
pub tolerance: f64,
/// Time step size
pub time_step: f64,
/// Under-relaxation factors
pub relaxation: RelaxationFactors,
}
/// Under-relaxation factors for stability
#[derive(Debug, Clone)]
pub struct RelaxationFactors {
/// Pressure relaxation factor (typically 0.2-0.8)
pub pressure: f64,
/// Velocity relaxation factor (typically 0.5-0.8)
pub velocity: f64,
/// Turbulence relaxation factor
pub turbulence: f64,
}
impl Default for SolverParameters {
fn default() -> Self {
Self {
max_iterations: 1000,
tolerance: 1e-6,
time_step: 0.001,
relaxation: RelaxationFactors::default(),
}
}
}
impl Default for RelaxationFactors {
fn default() -> Self {
Self {
pressure: 0.3,
velocity: 0.7,
turbulence: 0.5,
}
}
}
/// Common solver result information
#[derive(Debug, Clone)]
pub struct SolverResult {
/// Whether the solver converged
pub converged: bool,
/// Number of iterations performed
pub iterations: usize,
/// Final residual norm
pub final_residual: f64,
/// Residual history
pub residual_history: Vec<f64>,
/// Computational time
pub solve_time: std::time::Duration,
}
/// Pressure-velocity coupling algorithms
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CouplingAlgorithm {
/// Semi-Implicit Method for Pressure Linked Equations
Simple,
/// Pressure-Implicit with Splitting of Operators
Piso,
/// SIMPLE Revised
Simpler,
}
/// Common trait for incompressible solvers
#[async_trait::async_trait]
pub trait IncompressibleSolver {
/// Solver-specific parameters
type Parameters;
/// Solver-specific result
type Result;
/// Create new solver instance
fn new(config: CfdConfig, params: Self::Parameters) -> CfdResult<Self>
where
Self: Sized;
/// Solve one time step
async fn solve_time_step(
&mut self,
flow_field: &mut FlowField,
boundary_conditions: &BoundaryConditions,
dt: f64,
) -> CfdResult<Self::Result>;
/// Solve to steady state
async fn solve(
&mut self,
flow_field: &mut FlowField,
boundary_conditions: &BoundaryConditions,
) -> CfdResult<Self::Result>;
/// Get solver configuration
fn config(&self) -> &CfdConfig;
/// Get solver parameters
fn parameters(&self) -> &Self::Parameters;
}
/// Utility functions for incompressible solvers
pub mod utils {
use super::{CfdError, CfdResult};
/// Compute Courant number
#[must_use]
pub fn compute_courant_number(u_max: f64, v_max: f64, dx: f64, dy: f64, dt: f64) -> f64 {
let u_cfl = u_max * dt / dx;
let v_cfl = v_max * dt / dy;
(u_cfl * u_cfl + v_cfl * v_cfl).sqrt()
}
/// Compute viscous CFL number
#[must_use]
pub fn compute_viscous_cfl(nu: f64, dx: f64, dy: f64, dt: f64) -> f64 {
nu * dt * (1.0 / (dx * dx) + 1.0 / (dy * dy))
}
/// Check stability criteria
pub fn check_stability(courant: f64, viscous_cfl: f64) -> CfdResult<()> {
if courant > 1.0 {
return Err(CfdError::physics(format!(
"Convective CFL condition violated: CFL = {courant:.3} > 1.0"
)));
}
if viscous_cfl > 0.5 {
return Err(CfdError::physics(format!(
"Viscous CFL condition violated: CFL_visc = {viscous_cfl:.3} > 0.5"
)));
}
Ok(())
}
/// Compute Reynolds number based on flow conditions
#[must_use]
pub fn compute_reynolds_number(
u_characteristic: f64,
length_characteristic: f64,
kinematic_viscosity: f64,
) -> f64 {
u_characteristic * length_characteristic / kinematic_viscosity
}
}