use sciforge::hub::prelude::constants::{EARTH_MASS, EARTH_RADIUS, G};
pub const OMEGA_EARTH: f64 = crate::OMEGA_EARTH;
pub fn coriolis_parameter(latitude_deg: f64) -> f64 {
let lat_rad = latitude_deg.to_radians();
2.0 * OMEGA_EARTH * lat_rad.sin()
}
pub fn geostrophic_wind_speed(
pressure_gradient_pa_per_m: f64,
latitude_deg: f64,
air_density: f64,
) -> f64 {
let f = coriolis_parameter(latitude_deg);
if f.abs() < 1e-10 {
return f64::INFINITY;
}
pressure_gradient_pa_per_m / (air_density * f.abs())
}
pub fn gradient_wind_speed(
pressure_gradient: f64,
radius_m: f64,
latitude_deg: f64,
air_density: f64,
) -> f64 {
let f = coriolis_parameter(latitude_deg);
let term = f * f * radius_m * radius_m / 4.0 + radius_m * pressure_gradient / air_density;
if term < 0.0 {
return 0.0;
}
-f * radius_m / 2.0 + term.sqrt()
}
pub fn thermal_wind_shear(
temp_gradient_k_per_m: f64,
mean_temp_k: f64,
latitude_deg: f64,
delta_p: f64,
mean_p: f64,
) -> f64 {
let g0 = G * EARTH_MASS / (EARTH_RADIUS * EARTH_RADIUS);
let f = coriolis_parameter(latitude_deg);
if f.abs() < 1e-10 {
return 0.0;
}
if mean_temp_k.abs() < 1e-10 || mean_p.abs() < 1e-10 {
return 0.0;
}
-(g0 / (f * mean_temp_k)) * temp_gradient_k_per_m * delta_p / mean_p
}
pub fn ekman_spiral_depth(eddy_viscosity: f64, latitude_deg: f64) -> f64 {
let f = coriolis_parameter(latitude_deg);
if f.abs() < 1e-10 {
return f64::INFINITY;
}
std::f64::consts::PI * (2.0 * eddy_viscosity / f.abs()).sqrt()
}
pub fn beaufort_to_m_s(beaufort: u8) -> f64 {
0.836 * (beaufort as f64).powf(1.5)
}
pub fn wind_chill_temperature(temp_c: f64, wind_speed_km_h: f64) -> f64 {
13.12 + 0.6215 * temp_c - 11.37 * wind_speed_km_h.powf(0.16)
+ 0.3965 * temp_c * wind_speed_km_h.powf(0.16)
}