Initial commit
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user