// Production-ready Computational Fluid Dynamics library for RustyTorch // with GPU acceleration using cudarc 0.17.3 //#![deny(missing_docs)] // Temporarily disabled for development #![allow(clippy::module_name_repetitions)] //! # RTX CFD - Computational Fluid Dynamics for `RustyTorch` //! //! A production-ready CFD library with full GPU acceleration for solving incompressible //! and compressible fluid flow problems. This crate provides: //! //! - **Mesh Management**: Structured and unstructured grids with adaptive refinement //! - **Solvers**: SIMPLE, PISO algorithms for incompressible flows //! - **Lattice Boltzmann**: D2Q9 and D3Q19 methods for complex geometries //! - **Discretization**: Finite Volume Method (FVM) and Finite Difference Method (FDM) //! - **Boundary Conditions**: Comprehensive BC support for all flow types //! - **Turbulence Models**: k-ε and k-ω SST models //! - **GPU Acceleration**: Custom CUDA kernels for maximum performance //! //! ## Quick Start //! //! ```rust //! use rtx_cfd::{CfdConfig, init}; //! //! // Initialize the CFD library //! let config = CfdConfig::new() //! .with_density(1000.0) //! .with_viscosity(1e-6); //! //! // Calculate Reynolds number //! let re = config.reynolds_number(); //! println!("Reynolds number: {}", re); //! //! // Initialize library //! let _ = init(); //! ``` //! //! ## Features //! //! - `cuda`: Enable NVIDIA GPU acceleration via cudarc //! - `metal`: Enable Apple Metal GPU acceleration (macOS only) //! - `metal4`: Enable Metal 4 features (requires macOS 26+) //! - `rtx-integration`: Integration with RTX tensor and memory systems /// Error types and result definitions for CFD operations pub mod error; /// Core traits for CFD components (solvers, fields, mesh entities) pub mod traits; // pub mod field; /// Discretization schemes (FVM, FDM, TVD limiters) pub mod discretization; /// GPU kernels for CFD computations pub mod kernels; /// Mesh generation and management pub mod mesh; /// CFD solvers and algorithms pub mod solvers; // pub mod boundary; /// GPU backend abstraction (CUDA/Metal) pub mod compute; /// Turbulence models (k-ε, Smagorinsky, wall functions) pub mod turbulence; // pub mod lbm; // pub mod utils; // Re-export core types for convenience pub use error::{CfdError, CfdResult}; pub use traits::{ BoundaryCondition, BoundaryConditionType, CfdSolver, FluidField, MeshEntity, MeshEntityType, SolverParameters, TimeIntegrator, TurbulenceModel, TurbulenceParameters, }; /// CFD simulation configuration #[derive(Debug, Clone)] pub struct CfdConfig { /// Grid dimensions pub nx: usize, pub ny: usize, pub nz: usize, /// Domain size pub lx: f64, pub ly: f64, pub lz: f64, /// Time step pub dt: f64, /// Physical properties pub density: f64, /// Dynamic viscosity pub viscosity: f64, /// Reference velocity pub reference_velocity: f64, /// Reference length pub reference_length: f64, /// Enable GPU acceleration pub use_gpu: bool, /// CUDA device ID pub device_id: i32, /// Memory pool size for GPU allocations (bytes) pub gpu_memory_pool_size: usize, } impl Default for CfdConfig { fn default() -> Self { Self { nx: 64, ny: 64, nz: 1, lx: 1.0, ly: 1.0, lz: 1.0, dt: 0.001, density: 1.0, // kg/m³ (water at STP) viscosity: 1e-3, // Pa·s (water at STP) reference_velocity: 1.0, // m/s reference_length: 1.0, // m use_gpu: true, device_id: 0, gpu_memory_pool_size: 1024 * 1024 * 1024, // 1 GB } } } impl CfdConfig { /// Create a new CFD configuration #[must_use] pub fn new() -> Self { Self::default() } /// Set fluid density #[must_use] pub fn with_density(mut self, density: f64) -> Self { self.density = density; self } /// Set fluid viscosity #[must_use] pub fn with_viscosity(mut self, viscosity: f64) -> Self { self.viscosity = viscosity; self } /// Set reference velocity for non-dimensionalization #[must_use] pub fn with_reference_velocity(mut self, velocity: f64) -> Self { self.reference_velocity = velocity; self } /// Set reference length for non-dimensionalization #[must_use] pub fn with_reference_length(mut self, length: f64) -> Self { self.reference_length = length; self } /// Enable or disable GPU acceleration #[must_use] pub fn with_gpu(mut self, use_gpu: bool) -> Self { self.use_gpu = use_gpu; self } /// Set CUDA device ID #[must_use] pub fn with_device_id(mut self, device_id: i32) -> Self { self.device_id = device_id; self } /// Set GPU memory pool size #[must_use] pub fn with_gpu_memory_pool_size(mut self, size: usize) -> Self { self.gpu_memory_pool_size = size; self } /// Calculate Reynolds number #[must_use] pub fn reynolds_number(&self) -> f64 { self.density * self.reference_velocity * self.reference_length / self.viscosity } /// Check if flow is laminar (Re < 2300 for pipe flow) #[must_use] pub fn is_laminar(&self) -> bool { self.reynolds_number() < 2300.0 } /// Check if flow is turbulent (Re > 4000 for pipe flow) #[must_use] pub fn is_turbulent(&self) -> bool { self.reynolds_number() > 4000.0 } /// Validate configuration parameters pub fn validate(&self) -> CfdResult<()> { if self.density <= 0.0 { return Err(CfdError::invalid_parameter("Density must be positive")); } if self.viscosity <= 0.0 { return Err(CfdError::invalid_parameter("Viscosity must be positive")); } if self.reference_velocity <= 0.0 { return Err(CfdError::invalid_parameter( "Reference velocity must be positive", )); } if self.reference_length <= 0.0 { return Err(CfdError::invalid_parameter( "Reference length must be positive", )); } if self.device_id < 0 { return Err(CfdError::invalid_parameter( "Device ID must be non-negative", )); } if self.gpu_memory_pool_size == 0 { return Err(CfdError::invalid_parameter( "GPU memory pool size must be positive", )); } Ok(()) } } /// Initialize the CFD library with GPU support pub fn init() -> CfdResult<()> { tracing::info!("Initializing RTX CFD library"); #[cfg(feature = "cuda")] { // Check for CUDA devices and initialize if available match initialize_cuda() { Ok(device_info) => { tracing::info!("CUDA initialized successfully: {}", device_info); } Err(e) => { tracing::warn!("CUDA initialization failed, falling back to CPU: {}", e); tracing::info!("Running in CPU-only mode"); } } } #[cfg(not(feature = "cuda"))] { tracing::info!("Running in CPU-only mode"); } Ok(()) } #[cfg(feature = "cuda")] fn initialize_cuda() -> CfdResult { use crate::kernels::CudaKernelManager; // Create a test configuration to check CUDA availability let test_config = CfdConfig::default().with_device_id(0); // Try to create a kernel manager to test CUDA initialization match CudaKernelManager::new(&test_config) { Ok(_manager) => Ok("CUDA device initialized successfully".to_string()), Err(e) => Err(CfdError::gpu_error(&format!( "Failed to initialize CUDA: {}", e ))), } } /// Check if CUDA is available and working #[must_use] pub fn cuda_available() -> bool { #[cfg(feature = "cuda")] { initialize_cuda().is_ok() } #[cfg(not(feature = "cuda"))] { false } } /// Get CUDA device information if available pub fn cuda_device_info() -> CfdResult { #[cfg(feature = "cuda")] { let test_config = CfdConfig::default().with_device_id(0); let _manager = crate::kernels::CudaKernelManager::new(&test_config)?; Ok(CudaDeviceInfo { device_count: 1, // Simplified for now device_name: "CUDA Device".to_string(), memory_total: test_config.gpu_memory_pool_size, compute_capability: (7, 5), // Default assumption }) } #[cfg(not(feature = "cuda"))] { Err(CfdError::not_implemented( "CUDA not available in this build", )) } } /// CUDA device information #[derive(Debug, Clone)] pub struct CudaDeviceInfo { /// Number of CUDA devices pub device_count: usize, /// Device name pub device_name: String, /// Total GPU memory in bytes pub memory_total: usize, /// Compute capability (major, minor) pub compute_capability: (i32, i32), } /// Get library version information #[must_use] pub fn version() -> &'static str { env!("CARGO_PKG_VERSION") } /// Get build information #[must_use] pub fn build_info() -> BuildInfo { BuildInfo { version: version(), features: get_features(), cuda_support: cfg!(feature = "cuda"), rtx_integration: false, // cfg!(feature = "rtx-integration"), } } /// Build information structure #[derive(Debug, Clone)] pub struct BuildInfo { /// Library version pub version: &'static str, /// Enabled features pub features: Vec<&'static str>, /// CUDA support enabled pub cuda_support: bool, /// RTX integration enabled pub rtx_integration: bool, } fn get_features() -> Vec<&'static str> { let features = Vec::new(); #[cfg(feature = "cuda")] features.push("cuda"); // #[cfg(feature = "rtx-integration")] // features.push("rtx-integration"); features } #[cfg(test)] mod tests { use super::*; #[test] fn test_cfd_config_default() { let config = CfdConfig::default(); assert_eq!(config.density, 1.0); assert_eq!(config.viscosity, 1e-3); assert!(config.use_gpu); } #[test] fn test_cfd_config_builder() { let config = CfdConfig::new() .with_density(1000.0) .with_viscosity(1e-6) .with_reference_velocity(10.0) .with_gpu(false); assert_eq!(config.density, 1000.0); assert_eq!(config.viscosity, 1e-6); assert_eq!(config.reference_velocity, 10.0); assert!(!config.use_gpu); } #[test] fn test_reynolds_number() { let config = CfdConfig::new() .with_density(1.0) .with_viscosity(1e-3) .with_reference_velocity(1.0) .with_reference_length(1.0); assert_eq!(config.reynolds_number(), 1000.0); } #[test] fn test_flow_regime() { let laminar_config = CfdConfig::new() .with_density(1.0) .with_viscosity(1.0) .with_reference_velocity(1.0) .with_reference_length(1.0); assert!(laminar_config.is_laminar()); let turbulent_config = CfdConfig::new() .with_density(1.0) .with_viscosity(1e-6) .with_reference_velocity(10.0) .with_reference_length(1.0); assert!(turbulent_config.is_turbulent()); } #[test] fn test_config_validation() { let valid_config = CfdConfig::default(); assert!(valid_config.validate().is_ok()); let invalid_config = CfdConfig::default().with_density(-1.0); assert!(invalid_config.validate().is_err()); } #[test] fn test_version() { assert!(!version().is_empty()); } #[test] fn test_build_info() { let info = build_info(); assert!(!info.version.is_empty()); } }