#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct IntegratorConfig {
pub abs_tol: f64,
pub rel_tol: f64,
pub initial_step: Option<f64>,
pub min_step: Option<f64>,
pub max_step: Option<f64>,
pub step_safety_factor: Option<f64>,
pub min_step_scale_factor: Option<f64>,
pub max_step_scale_factor: Option<f64>,
pub max_step_attempts: usize,
pub fixed_step_size: Option<f64>,
}
impl Default for IntegratorConfig {
fn default() -> Self {
Self {
abs_tol: 1e-6,
rel_tol: 1e-3,
initial_step: None,
min_step: Some(1e-12),
max_step: Some(900.0),
step_safety_factor: Some(0.9),
min_step_scale_factor: Some(0.2),
max_step_scale_factor: Some(10.0),
max_step_attempts: 10,
fixed_step_size: None,
}
}
}
impl IntegratorConfig {
pub fn fixed_step(step_size: f64) -> Self {
Self {
fixed_step_size: Some(step_size),
..Default::default()
}
}
pub fn adaptive(abs_tol: f64, rel_tol: f64) -> Self {
Self {
abs_tol,
rel_tol,
fixed_step_size: None,
..Default::default()
}
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = IntegratorConfig::default();
assert_eq!(config.abs_tol, 1e-6);
assert_eq!(config.rel_tol, 1e-3);
assert_eq!(config.initial_step, None);
assert_eq!(config.min_step, Some(1e-12));
assert_eq!(config.max_step, Some(900.0));
assert_eq!(config.step_safety_factor, Some(0.9));
assert_eq!(config.min_step_scale_factor, Some(0.2));
assert_eq!(config.max_step_scale_factor, Some(10.0));
assert_eq!(config.max_step_attempts, 10);
assert_eq!(config.fixed_step_size, None);
}
#[test]
fn test_fixed_step_config() {
let config = IntegratorConfig::fixed_step(0.1);
assert_eq!(config.fixed_step_size, Some(0.1));
assert_eq!(config.abs_tol, 1e-6);
assert_eq!(config.rel_tol, 1e-3);
}
#[test]
fn test_adaptive_config() {
let config = IntegratorConfig::adaptive(1e-9, 1e-6);
assert_eq!(config.abs_tol, 1e-9);
assert_eq!(config.rel_tol, 1e-6);
}
}