use super::super::{
phasespace::PhaseSpaceRepr,
solver::PoissonSolver,
types::{AccelerationField, DensityField, PotentialField},
};
pub fn dynamical_timestep(repr: &dyn PhaseSpaceRepr, g: f64, cfl_factor: f64) -> f64 {
let density = repr.compute_density();
let rho_max = density.data.iter().cloned().fold(0.0_f64, f64::max);
if rho_max <= 0.0 || g <= 0.0 {
return 1e10;
}
let t_dyn = 1.0 / (g * rho_max).sqrt();
cfl_factor * t_dyn
}
pub fn solve_poisson(
repr: &dyn PhaseSpaceRepr,
solver: &dyn PoissonSolver,
g: f64,
) -> (DensityField, PotentialField, AccelerationField) {
let density = repr.compute_density();
let potential = solver.solve(&density, g);
let acceleration = solver.compute_acceleration(&potential);
(density, potential, acceleration)
}
pub fn apply_hypercollision_if_spectral(repr: &mut dyn PhaseSpaceRepr, dt: f64) {
if let Some(spectral) = repr
.as_any_mut()
.downcast_mut::<super::super::algos::spectral::SpectralV>()
{
spectral.apply_hypercollision(dt);
}
}
macro_rules! time_ms {
($timings:expr, $field:ident, $body:expr) => {{
let _t0 = std::time::Instant::now();
let _result = $body;
$timings.$field += _t0.elapsed().as_secs_f64() * 1000.0;
_result
}};
}
macro_rules! report_phase {
($progress:expr, $phase:expr, $step:expr, $total:expr) => {
if let Some(p) = &$progress {
p.set_phase($phase);
p.set_sub_step($step, $total);
}
};
}
#[allow(unused_imports)]
pub(crate) use report_phase;
#[allow(unused_imports)]
pub(crate) use time_ms;