///|
pub(all) struct CflReport {
  recommended_dt : Double
  max_displacement : Double
  stable : Bool
} derive(Debug, ToJson)

///|
pub fn assess_pic_cfl(
  grid : Grid1D,
  maximum_speed~ : Double,
  dt~ : Double,
  safety_factor~ : Double,
) -> CflReport {
  let recommended = stable_pic_dt(grid, maximum_speed, safety_factor)
  let displacement = maximum_speed.abs() * dt.abs()
  {
    recommended_dt: recommended,
    max_displacement: displacement,
    stable: recommended > 0.0 && dt.abs() <= recommended,
  }
}

///|
pub fn assess_vlasov_cfl(config : VlasovConfig) -> CflReport {
  let maximum_speed = if config.velocity_min.abs() > config.velocity_max.abs() {
    config.velocity_min.abs()
  } else {
    config.velocity_max.abs()
  }
  let recommended = if maximum_speed == 0.0 {
    0.0
  } else {
    config.grid.dx / maximum_speed
  }
  {
    recommended_dt: recommended,
    max_displacement: maximum_speed * config.dt.abs(),
    stable: recommended > 0.0 && config.dt.abs() <= recommended,
  }
}

///|
pub fn cfl_ratio(report : CflReport) -> Double {
  if report.recommended_dt == 0.0 {
    0.0
  } else {
    report.max_displacement / report.recommended_dt
  }
}