1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
pub struct HeatWave { pub max_temperature_c: f64, pub duration_days: u32, pub relative_humidity_percent: f64, } impl HeatWave { pub fn heat_index_c(&self) -> f64 { let t = self.max_temperature_c; let rh = self.relative_humidity_percent; let t_f = t * 9.0 / 5.0 + 32.0; let hi_f = -42.379 + 2.04901523 * t_f + 10.14333127 * rh - 0.22475541 * t_f * rh - 6.83783e-3 * t_f * t_f - 5.481717e-2 * rh * rh + 1.22874e-3 * t_f * t_f * rh + 8.5282e-4 * t_f * rh * rh - 1.99e-6 * t_f * t_f * rh * rh; (hi_f - 32.0) * 5.0 / 9.0 } pub fn wet_bulb_temperature_c(&self) -> f64 { let t = self.max_temperature_c; let rh = self.relative_humidity_percent; t * (0.151977 * (rh + 8.313659_f64).sqrt()).atan() + (t + rh).atan() - (rh - 1.676331).atan() + 0.00391838 * rh.powf(1.5) * (0.023101 * rh).atan() - 4.686035 } pub fn danger_level(&self) -> &'static str { let hi = self.heat_index_c(); if hi >= 54.0 { "Extreme danger" } else if hi >= 41.0 { "Danger" } else if hi >= 32.0 { "Extreme caution" } else if hi >= 27.0 { "Caution" } else { "Normal" } } pub fn excess_mortality_factor(&self) -> f64 { let threshold = 30.0; if self.max_temperature_c <= threshold { 1.0 } else { 1.0 + 0.03 * (self.max_temperature_c - threshold) * self.duration_days as f64 } } } pub fn saturation_vapor_pressure_pa(temp_c: f64) -> f64 { 610.78 * (17.27 * temp_c / (temp_c + 237.3)).exp() } pub fn dew_point_c(temp_c: f64, relative_humidity: f64) -> f64 { let a = 17.27; let b = 237.3; let alpha = a * temp_c / (b + temp_c) + (relative_humidity / 100.0).ln(); b * alpha / (a - alpha) }