use crate::solver::{GmresConfigF64, SolverType};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SchwarzVariant {
Additive,
Multiplicative,
}
#[derive(Debug, Clone)]
pub struct SchwarzPmlConfig {
pub variant: SchwarzVariant,
pub num_subdomains: usize,
pub overlap_fraction: f64,
pub pml_wavelengths: f64,
pub pml_power: usize,
pub pml_target_reflection: f64,
pub max_iterations: usize,
pub tolerance: f64,
pub local_solver: SolverType,
pub local_gmres: GmresConfigF64,
pub verbosity: usize,
}
impl Default for SchwarzPmlConfig {
fn default() -> Self {
Self {
variant: SchwarzVariant::Additive,
num_subdomains: 4,
overlap_fraction: 0.1,
pml_wavelengths: 1.0,
pml_power: 2,
pml_target_reflection: 1e-6,
max_iterations: 50,
tolerance: 1e-8,
local_solver: SolverType::GmresIlu,
local_gmres: GmresConfigF64 {
max_iterations: 500,
restart: 30,
tolerance: 1e-10,
print_interval: 0,
},
verbosity: 0,
}
}
}
impl SchwarzPmlConfig {
pub fn for_wavenumber(k: f64) -> Self {
let num_subdomains = if k > 30.0 {
8
} else if k > 15.0 {
6
} else {
4
};
Self {
num_subdomains,
..Default::default()
}
}
pub fn fast() -> Self {
Self {
max_iterations: 20,
tolerance: 1e-6,
local_gmres: GmresConfigF64 {
max_iterations: 200,
restart: 20,
tolerance: 1e-8,
print_interval: 0,
},
..Default::default()
}
}
pub fn accurate() -> Self {
Self {
max_iterations: 100,
tolerance: 1e-10,
pml_wavelengths: 1.5,
pml_target_reflection: 1e-8,
local_gmres: GmresConfigF64 {
max_iterations: 1000,
restart: 50,
tolerance: 1e-12,
print_interval: 0,
},
..Default::default()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = SchwarzPmlConfig::default();
assert_eq!(config.num_subdomains, 4);
assert_eq!(config.variant, SchwarzVariant::Additive);
assert!(config.tolerance > 0.0);
}
#[test]
fn test_for_wavenumber() {
let low = SchwarzPmlConfig::for_wavenumber(5.0);
assert_eq!(low.num_subdomains, 4);
let mid = SchwarzPmlConfig::for_wavenumber(20.0);
assert_eq!(mid.num_subdomains, 6);
let high = SchwarzPmlConfig::for_wavenumber(40.0);
assert_eq!(high.num_subdomains, 8);
}
}