use sciforge::hub::domain::meteorology::radiation::{
planck_function, radiative_forcing_co2, solar_constant, solar_zenith_angle,
stefan_boltzmann_flux,
};
use sciforge::hub::prelude::constants::SIGMA_SB;
pub const PRE_INDUSTRIAL_CO2_PPM: f64 = 280.0;
pub const CLIMATE_SENSITIVITY_K: f64 = 3.0;
pub const EARTH_ALBEDO: f64 = 0.306;
pub struct ClimateState {
pub co2_ppm: f64,
pub ch4_ppb: f64,
pub global_mean_temp_k: f64,
pub albedo: f64,
}
impl ClimateState {
pub fn pre_industrial() -> Self {
Self {
co2_ppm: PRE_INDUSTRIAL_CO2_PPM,
ch4_ppb: 722.0,
global_mean_temp_k: 287.0,
albedo: EARTH_ALBEDO,
}
}
pub fn current() -> Self {
Self {
co2_ppm: 421.0,
ch4_ppb: 1912.0,
global_mean_temp_k: 288.2,
albedo: EARTH_ALBEDO,
}
}
pub fn co2_radiative_forcing(&self) -> f64 {
radiative_forcing_co2(self.co2_ppm, PRE_INDUSTRIAL_CO2_PPM)
}
pub fn equilibrium_warming(&self) -> f64 {
let forcing = self.co2_radiative_forcing();
CLIMATE_SENSITIVITY_K * forcing / 3.7
}
pub fn outgoing_longwave_radiation(&self) -> f64 {
stefan_boltzmann_flux(self.global_mean_temp_k)
}
pub fn absorbed_solar_radiation(&self) -> f64 {
solar_constant() * (1.0 - self.albedo) / 4.0
}
pub fn energy_imbalance(&self) -> f64 {
self.absorbed_solar_radiation() - self.outgoing_longwave_radiation()
}
pub fn effective_emission_temperature(&self) -> f64 {
let s = solar_constant();
((s * (1.0 - self.albedo)) / (4.0 * SIGMA_SB)).powf(0.25)
}
pub fn greenhouse_effect_k(&self) -> f64 {
self.global_mean_temp_k - self.effective_emission_temperature()
}
}
pub fn solar_zenith(latitude_deg: f64, declination_deg: f64, hour_angle_deg: f64) -> f64 {
solar_zenith_angle(latitude_deg, declination_deg, hour_angle_deg)
}
pub fn planck_spectral_radiance(wavelength_m: f64, temperature_k: f64) -> f64 {
planck_function(wavelength_m, temperature_k)
}
pub fn co2_doubling_forcing() -> f64 {
radiative_forcing_co2(560.0, 280.0)
}