//! Physics-Informed Neural Network Benchmark Backend //! //! This crate provides a simple, pure-Rust implementation of PINNs for benchmarking //! standard PDE problems. It includes: //! //! - Simple MLP network with numerical differentiation //! - AdamW optimizer for training //! - Standard PDE problems (Heat1D, Burgers1D, Poisson2D) //! - Benchmark utilities for accuracy and performance measurement //! //! # Example //! //! ```rust //! use rtx_pinn_benchmark::{ //! error::Result, //! network::MLP, //! problems::{Heat1D, Problem}, //! training::AdamW, //! }; //! //! # fn main() -> Result<()> { //! // Create a problem //! let problem = Heat1D::new(0.01, 1.0)?; //! //! // Create a network //! let mut network = MLP::new(2, vec![32, 32], 1)?; //! network.initialize_xavier(); //! //! // Generate training points //! let collocation_points = problem.collocation_points(1000); //! let boundary_points = problem.boundary_points(100); //! //! # Ok(()) //! # } //! ``` pub mod benchmark; pub mod error; pub mod network; pub mod problems; pub mod training; // Re-export commonly used types pub use error::{PINNError, Result}; pub use network::MLP; pub use problems::{Burgers1D, Heat1D, Poisson2D, Problem}; pub use training::{mse_loss, AdamW, TrainingConfig}; #[cfg(test)] mod tests { use super::*; #[test] fn test_library_basic_workflow() { // Create a problem let problem = Heat1D::new(0.01, 1.0); assert!(problem.is_ok()); // Create a network let network = MLP::new(2, vec![10], 1); assert!(network.is_ok()); } #[test] fn test_library_end_to_end() { // Create problem let problem = Heat1D::new(0.01, 1.0).unwrap(); // Create network let mut network = MLP::new(2, vec![5], 1).unwrap(); network.initialize_xavier(); // Generate points let collocation_points = problem.collocation_points(10); let boundary_points = problem.boundary_points(10); assert_eq!(collocation_points.len(), 10); assert!(!boundary_points.is_empty()); // Forward pass through network for point in &collocation_points { let output = network.forward(point); assert!(output.is_ok()); let output = output.unwrap(); assert_eq!(output.len(), 1); } } #[test] fn test_library_training_setup() { // Create network let mut network = MLP::new(2, vec![5, 5], 1).unwrap(); network.initialize_xavier(); // Create optimizer let weight_shapes: Vec>> = vec![ vec![vec![0.0; 2]; 5], vec![vec![0.0; 5]; 5], vec![vec![0.0; 5]; 1], ]; let bias_shapes: Vec> = vec![vec![0.0; 5], vec![0.0; 5], vec![0.0; 1]]; let optimizer = AdamW::new(0.001, 0.9, 0.999, 0.01, &weight_shapes, &bias_shapes); assert!(optimizer.is_ok()); } #[test] fn test_library_problem_types() { let heat = Heat1D::new(0.01, 1.0); assert!(heat.is_ok()); let burgers = Burgers1D::new(0.01, 1.0); assert!(burgers.is_ok()); let poisson = Poisson2D::new(std::f64::consts::PI); assert!(poisson.is_ok()); } #[test] fn test_library_analytical_solutions() { let heat = Heat1D::new(0.01, 1.0).unwrap(); let points = vec![vec![0.5, 0.0]]; let solution = heat.analytical_solution(&points); assert!(solution.is_some()); let poisson = Poisson2D::new(std::f64::consts::PI).unwrap(); let points = vec![vec![0.5, 0.5]]; let solution = poisson.analytical_solution(&points); assert!(solution.is_some()); } #[test] fn test_library_mse_loss() { let predictions = vec![1.0, 2.0, 3.0]; let targets = vec![1.1, 2.1, 2.9]; let loss = mse_loss(&predictions, &targets); assert!(loss.is_ok()); assert!(loss.unwrap() > 0.0); } #[test] fn test_library_benchmark_config() { use benchmark::BenchmarkConfig; use pinn_benchmark_shared::ProblemType; let config = BenchmarkConfig::new(ProblemType::Heat1D, vec![32, 32], 0.001, 100, 1000, 100); assert!(config.is_ok()); } #[test] fn test_library_compute_accuracy() { use benchmark::compute_accuracy; let predictions = vec![1.0, 2.0, 3.0]; let reference = vec![1.0, 2.0, 3.0]; let result = compute_accuracy(&predictions, &reference); assert!(result.is_ok()); let (l2_error, linf_error) = result.unwrap(); assert!(l2_error < 1e-10); assert!(linf_error < 1e-10); } }