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,131 @@
// Mesh refinement algorithms
use crate::error::{CfdError, CfdResult};
/// Refinement strategy
#[derive(Debug, Clone, Copy)]
pub enum RefinementStrategy {
/// Uniform refinement - refine all cells
Uniform,
/// Adaptive refinement based on error indicators
Adaptive,
/// Refine specific regions
Regional,
}
/// Refinement criteria
#[derive(Debug, Clone)]
pub struct RefinementCriteria {
/// Maximum allowed error per cell
pub max_error: f64,
/// Minimum cell size
pub min_cell_size: f64,
/// Maximum cell size
pub max_cell_size: f64,
/// Maximum refinement levels
pub max_levels: usize,
}
impl Default for RefinementCriteria {
fn default() -> Self {
Self {
max_error: 1e-3,
min_cell_size: 1e-6,
max_cell_size: 1e6,
max_levels: 10,
}
}
}
/// Adaptive mesh refinement implementation
pub struct AdaptiveRefinement {
criteria: RefinementCriteria,
current_level: usize,
}
impl AdaptiveRefinement {
/// Create new adaptive refinement
#[must_use]
pub fn new(criteria: RefinementCriteria) -> Self {
Self {
criteria,
current_level: 0,
}
}
/// Check if refinement is needed
#[must_use]
pub fn needs_refinement(&self, error: f64, cell_size: f64, current_level: usize) -> bool {
error > self.criteria.max_error
&& cell_size > self.criteria.min_cell_size
&& current_level < self.criteria.max_levels
}
/// Mark cells for refinement based on error indicators
pub fn mark_cells_for_refinement(
&self,
errors: &[f64],
cell_sizes: &[f64],
cell_levels: &[usize],
) -> CfdResult<Vec<usize>> {
if errors.len() != cell_sizes.len() || errors.len() != cell_levels.len() {
return Err(CfdError::mesh(
"Error, cell size, and level arrays must have same length",
));
}
let mut marked_cells = Vec::new();
for (i, (&error, (&size, &level))) in errors
.iter()
.zip(cell_sizes.iter().zip(cell_levels.iter()))
.enumerate()
{
if self.needs_refinement(error, size, level) {
marked_cells.push(i);
}
}
Ok(marked_cells)
}
/// Compute gradient-based error indicator
pub fn compute_gradient_error_indicator(
&self,
velocity_field: &[nalgebra::Vector3<f64>],
) -> CfdResult<Vec<f64>> {
let mut errors = Vec::with_capacity(velocity_field.len());
for velocity in velocity_field {
// Use velocity magnitude as a simple gradient indicator
// In practice, this would be computed from actual velocity gradients
let error = velocity.magnitude();
errors.push(error);
}
Ok(errors)
}
/// Compute residual-based error indicator
pub fn compute_residual_error_indicator(
&self,
momentum_residuals: &[f64],
continuity_residuals: &[f64],
) -> CfdResult<Vec<f64>> {
if momentum_residuals.len() != continuity_residuals.len() {
return Err(CfdError::mesh(
"Momentum and continuity residual arrays must have same length",
));
}
let mut errors = Vec::with_capacity(momentum_residuals.len());
for (&mom_res, &cont_res) in momentum_residuals.iter().zip(continuity_residuals.iter()) {
// Combine momentum and continuity residuals using L2 norm
let combined_error = (mom_res * mom_res + cont_res * cont_res).sqrt();
errors.push(combined_error);
}
Ok(errors)
}
}