use sciforge::hub::domain::common::constants::SIGMA_SB;
pub struct Lake {
pub name: &'static str,
pub surface_area_km2: f64,
pub max_depth_m: f64,
pub volume_km3: f64,
pub elevation_m: f64,
}
impl Lake {
pub fn mean_depth_m(&self) -> f64 {
self.volume_km3 * 1e9 / (self.surface_area_km2 * 1e6)
}
pub fn shoreline_development_ratio(&self, shoreline_km: f64) -> f64 {
shoreline_km
/ (2.0 * std::f64::consts::PI * (self.surface_area_km2 / std::f64::consts::PI).sqrt())
}
pub fn residence_time_years(&self, outflow_m3_s: f64) -> f64 {
self.volume_km3 * 1e9 / (outflow_m3_s * crate::SECONDS_PER_YEAR)
}
pub fn thermal_stratification_energy_j(&self, surface_temp_c: f64, bottom_temp_c: f64) -> f64 {
let rho = crate::FRESHWATER_DENSITY;
let cp = *crate::CP_FRESHWATER;
let dt = surface_temp_c - bottom_temp_c;
let volume_m3 = self.volume_km3 * 1e9;
0.5 * rho * cp * volume_m3 * dt
}
pub fn evaporation_rate_mm_day(
&self,
air_temp_c: f64,
water_temp_c: f64,
wind_speed_m_s: f64,
humidity: f64,
) -> f64 {
let es_water =
crate::ARM_A * (crate::ARM_B * water_temp_c / (water_temp_c + crate::ARM_C)).exp();
let ea = humidity / 100.0
* crate::ARM_A
* (crate::ARM_B * air_temp_c / (air_temp_c + crate::ARM_C)).exp();
let penman_factor = (es_water - ea) * (1.0 + 0.536 * wind_speed_m_s);
penman_factor * 0.35
}
pub fn longwave_radiation_w_m2(&self, water_temp_c: f64, emissivity: f64) -> f64 {
let t_k = water_temp_c + crate::CELSIUS_TO_KELVIN;
emissivity * SIGMA_SB * t_k.powi(4)
}
}
pub fn baikal() -> Lake {
Lake {
name: "Lake Baikal",
surface_area_km2: 31_722.0,
max_depth_m: 1642.0,
volume_km3: 23_615.0,
elevation_m: 455.5,
}
}
pub fn superior() -> Lake {
Lake {
name: "Lake Superior",
surface_area_km2: 82_100.0,
max_depth_m: 406.0,
volume_km3: 12_100.0,
elevation_m: 183.0,
}
}