use crate::types::Real;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FdmSchemeType {
Hundsdorfer,
Douglas,
CraigSneyd,
ModifiedCraigSneyd,
ImplicitEuler,
ExplicitEuler,
MethodOfLines,
TrBDF2,
CrankNicolson,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct FdmSchemeDesc {
pub scheme_type: FdmSchemeType,
pub theta: Real,
pub mu: Real,
}
impl FdmSchemeDesc {
pub fn new(scheme_type: FdmSchemeType, theta: Real, mu: Real) -> Self {
FdmSchemeDesc {
scheme_type,
theta,
mu,
}
}
pub fn douglas() -> Self {
FdmSchemeDesc::new(FdmSchemeType::Douglas, 0.5, 0.0)
}
pub fn implicit_euler() -> Self {
FdmSchemeDesc::new(FdmSchemeType::ImplicitEuler, 0.0, 0.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn douglas_carries_the_cpp_parameters() {
let desc = FdmSchemeDesc::douglas();
assert_eq!(desc.scheme_type, FdmSchemeType::Douglas);
assert_eq!(desc.theta, 0.5);
assert_eq!(desc.mu, 0.0);
}
#[test]
fn implicit_euler_carries_the_cpp_parameters() {
let desc = FdmSchemeDesc::implicit_euler();
assert_eq!(desc.scheme_type, FdmSchemeType::ImplicitEuler);
assert_eq!(desc.theta, 0.0);
assert_eq!(desc.mu, 0.0);
}
#[test]
fn every_scheme_type_is_constructible() {
let types = [
FdmSchemeType::Hundsdorfer,
FdmSchemeType::Douglas,
FdmSchemeType::CraigSneyd,
FdmSchemeType::ModifiedCraigSneyd,
FdmSchemeType::ImplicitEuler,
FdmSchemeType::ExplicitEuler,
FdmSchemeType::MethodOfLines,
FdmSchemeType::TrBDF2,
FdmSchemeType::CrankNicolson,
];
for scheme_type in types {
let desc = FdmSchemeDesc::new(scheme_type, 0.25, 0.75);
assert_eq!(desc.scheme_type, scheme_type);
assert_eq!(desc.theta, 0.25);
assert_eq!(desc.mu, 0.75);
}
}
#[test]
fn the_two_ported_factories_differ() {
assert_ne!(FdmSchemeDesc::douglas(), FdmSchemeDesc::implicit_euler());
}
}