pub struct JupiterStorm {
pub maxwindspeedms: f64,
pub centralpressurehpa: f64,
pub radiuskm: f64,
pub latitudedeg: f64,
}
impl JupiterStorm {
pub fn greatredspot() -> Self {
Self {
maxwindspeedms: 180.0,
centralpressurehpa: 700.0,
radiuskm: 12000.0,
latitudedeg: -23.0,
}
}
pub fn ovalba() -> Self {
Self {
maxwindspeedms: 150.0,
centralpressurehpa: 850.0,
radiuskm: 5000.0,
latitudedeg: -33.0,
}
}
pub fn whiteovals() -> Self {
Self {
maxwindspeedms: 120.0,
centralpressurehpa: 900.0,
radiuskm: 4000.0,
latitudedeg: -40.0,
}
}
pub fn kineticenergydensity(&self) -> f64 {
0.5 * *crate::ONEBARDENSITY * self.maxwindspeedms * self.maxwindspeedms
}
pub fn vorticityestimate(&self) -> f64 {
if self.radiuskm.abs() < 1e-10 {
return 0.0;
}
2.0 * self.maxwindspeedms / (self.radiuskm * 1000.0)
}
pub fn rossbydeformationradius(&self) -> f64 {
let f = 2.0 * crate::OMEGAJUPITER * (self.latitudedeg.to_radians()).sin();
let nh = 500.0;
if f.abs() < 1e-10 {
return f64::INFINITY;
}
nh / f.abs()
}
pub fn windatradius(&self, rkm: f64) -> f64 {
let rm = self.radiuskm;
let vm = self.maxwindspeedms;
vm * (rm / rkm) * (-(rkm - rm).powi(2) / (2.0 * rm * rm)).exp()
}
pub fn potentialintensityms(internalheatingwm2: f64, tropopausetempk: f64) -> f64 {
let ckcd = 0.9;
let enthalpydiff = internalheatingwm2 * 1000.0;
let sstk = crate::ONEBARTEMPK;
let efficiency = (sstk - tropopausetempk).abs() / sstk;
(ckcd * efficiency * enthalpydiff).sqrt()
}
}
pub fn fujitascale(windspeedms: f64) -> &'static str {
let mph = windspeedms * 2.23694;
if mph >= 261.0 {
"EF5"
} else if mph >= 201.0 {
"EF4"
} else if mph >= 136.0 {
"EF3"
} else if mph >= 111.0 {
"EF2"
} else if mph >= 86.0 {
"EF1"
} else if mph >= 65.0 {
"EF0"
} else {
"Sub-EF"
}
}
pub fn capelayer(parceltempk: f64, envtempk: f64, dz: f64) -> f64 {
if envtempk.abs() < 1e-10 {
return 0.0;
}
*crate::SURFACEGRAVITY * ((parceltempk - envtempk) / envtempk).max(0.0) * dz
}
pub fn capeintegrated(
parceltempk: f64,
envsurfacetempk: f64,
envlapseratekperm: f64,
dzm: f64,
nlayers: u32,
) -> f64 {
let moistlapse = 0.0015;
let mut capetotal = 0.0;
let mut abovelfc = false;
for layer in 0..nlayers {
let z = (layer as f64 + 1.0) * dzm;
let tparcel = parceltempk - moistlapse * z;
let tenv = envsurfacetempk - envlapseratekperm * z;
if tparcel > tenv {
abovelfc = true;
capetotal += capelayer(tparcel, tenv, dzm);
} else if abovelfc {
break;
}
}
capetotal
}