#[derive(Debug, Clone)]
pub struct WaveHoltzConfig {
pub steps_per_period: usize,
pub max_iterations: usize,
pub gmres_restart: usize,
pub tolerance: f64,
pub inner_tolerance: f64,
pub inner_max_iterations: usize,
pub use_amg_inner: bool,
pub dispersion_correction: bool,
pub verbosity: usize,
}
impl Default for WaveHoltzConfig {
fn default() -> Self {
Self {
steps_per_period: 10,
max_iterations: 100,
gmres_restart: 30,
tolerance: 1e-10,
inner_tolerance: 1e-12,
inner_max_iterations: 500,
use_amg_inner: true,
dispersion_correction: true,
verbosity: 0,
}
}
}
impl WaveHoltzConfig {
pub fn for_wavenumber(k: f64) -> Self {
let steps = if k > 20.0 {
16
} else if k > 10.0 {
12
} else {
10
};
Self {
steps_per_period: steps,
..Default::default()
}
}
pub fn fast() -> Self {
Self {
steps_per_period: 6,
max_iterations: 50,
gmres_restart: 20,
tolerance: 1e-6,
inner_tolerance: 1e-8,
inner_max_iterations: 200,
use_amg_inner: true,
dispersion_correction: false,
verbosity: 0,
}
}
pub fn accurate() -> Self {
Self {
steps_per_period: 16,
max_iterations: 200,
gmres_restart: 50,
tolerance: 1e-12,
inner_tolerance: 1e-14,
inner_max_iterations: 1000,
use_amg_inner: true,
dispersion_correction: true,
verbosity: 0,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = WaveHoltzConfig::default();
assert_eq!(config.steps_per_period, 10);
assert_eq!(config.max_iterations, 100);
assert!(config.use_amg_inner);
assert!(config.dispersion_correction);
}
#[test]
fn test_for_wavenumber() {
let low = WaveHoltzConfig::for_wavenumber(5.0);
assert_eq!(low.steps_per_period, 10);
let mid = WaveHoltzConfig::for_wavenumber(15.0);
assert_eq!(mid.steps_per_period, 12);
let high = WaveHoltzConfig::for_wavenumber(25.0);
assert_eq!(high.steps_per_period, 16);
}
}