use super::super::domain::Timestep;
use rust_decimal::Decimal;
use rust_decimal::prelude::ToPrimitive;
pub enum SplittingMethod {
Lie,
Strang,
Yoshida4,
}
pub enum PoissonMethod {
FftPeriodic,
FftIsolated,
Multigrid,
SphericalHarmonics,
Tree,
}
pub enum AdvectionMethod {
SemiLagrangian,
FiniteVolume,
Spectral,
}
pub enum RepresentationKind {
UniformGrid,
Amr,
Sheet,
TensorTrain,
SpectralV,
Hybrid,
}
pub type ExternalPotentialFn = Box<dyn Fn([f64; 3], f64) -> f64 + Send + Sync>;
pub struct OptionalParams {
pub dt: Timestep,
pub cfl_factor: Decimal,
pub dt_min: Decimal,
pub phi_external: Option<ExternalPotentialFn>,
pub splitting_method: SplittingMethod,
pub poisson_method: PoissonMethod,
pub advection_method: AdvectionMethod,
pub representation: RepresentationKind,
pub output_interval: Decimal,
pub diagnostic_interval: Decimal,
pub epsilon_energy: Decimal,
pub epsilon_mass: Decimal,
pub epsilon_casimir: Decimal,
pub epsilon_steady: Decimal,
pub wall_time_limit: Option<Decimal>,
pub checkpoint_interval_secs: Decimal,
pub cosmological: bool,
pub a_init: Decimal,
pub hubble_0: Option<Decimal>,
pub omega_m: Option<Decimal>,
pub omega_lambda: Option<Decimal>,
}
impl OptionalParams {
pub fn cfl_factor_f64(&self) -> f64 {
self.cfl_factor.to_f64().unwrap_or(0.5)
}
pub fn dt_min_f64(&self) -> f64 {
self.dt_min.to_f64().unwrap_or(1e-10)
}
pub fn output_interval_f64(&self) -> f64 {
self.output_interval.to_f64().unwrap_or(0.01)
}
pub fn diagnostic_interval_f64(&self) -> f64 {
self.diagnostic_interval.to_f64().unwrap_or(0.0)
}
pub fn epsilon_energy_f64(&self) -> f64 {
self.epsilon_energy.to_f64().unwrap_or(1e-6)
}
pub fn epsilon_mass_f64(&self) -> f64 {
self.epsilon_mass.to_f64().unwrap_or(0.99)
}
pub fn epsilon_casimir_f64(&self) -> f64 {
self.epsilon_casimir.to_f64().unwrap_or(1e-4)
}
pub fn epsilon_steady_f64(&self) -> f64 {
self.epsilon_steady.to_f64().unwrap_or(1e-8)
}
pub fn wall_time_limit_f64(&self) -> Option<f64> {
self.wall_time_limit.as_ref().and_then(|d| d.to_f64())
}
pub fn a_init_f64(&self) -> f64 {
self.a_init.to_f64().unwrap_or(1.0)
}
}
fn dec(v: f64) -> Decimal {
Decimal::from_f64_retain(v).unwrap_or(Decimal::ZERO)
}
impl Default for OptionalParams {
fn default() -> Self {
Self {
dt: Timestep {
delta_t: Decimal::ZERO,
}, cfl_factor: dec(0.5),
dt_min: dec(1e-10),
phi_external: None,
splitting_method: SplittingMethod::Strang,
poisson_method: PoissonMethod::FftPeriodic,
advection_method: AdvectionMethod::SemiLagrangian,
representation: RepresentationKind::UniformGrid,
output_interval: dec(0.01),
diagnostic_interval: Decimal::ZERO,
epsilon_energy: dec(1e-6),
epsilon_mass: dec(0.99),
epsilon_casimir: dec(1e-4),
epsilon_steady: dec(1e-8),
wall_time_limit: None,
checkpoint_interval_secs: dec(3600.0),
cosmological: false,
a_init: Decimal::ONE,
hubble_0: None,
omega_m: None,
omega_lambda: None,
}
}
}