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 PREINDUSTRIALCO2PPM: f64 = 280.0;
pub const CLIMATESENSITIVITYK: f64 = 3.0;
pub const EARTHALBEDO: f64 = 0.306;
pub struct ClimateState {
pub co2ppm: f64,
pub ch4ppb: f64,
pub globalmeantempk: f64,
pub albedo: f64,
}
impl ClimateState {
pub fn preindustrial() -> Self {
Self {
co2ppm: PREINDUSTRIALCO2PPM,
ch4ppb: 722.0,
globalmeantempk: 287.0,
albedo: EARTHALBEDO,
}
}
pub fn current() -> Self {
Self {
co2ppm: 421.0,
ch4ppb: 1912.0,
globalmeantempk: 288.2,
albedo: EARTHALBEDO,
}
}
pub fn co2radiativeforcing(&self) -> f64 {
radiative_forcing_co2(self.co2ppm, PREINDUSTRIALCO2PPM)
}
pub fn equilibriumwarming(&self) -> f64 {
let forcing = self.co2radiativeforcing();
CLIMATESENSITIVITYK * forcing / 3.7
}
pub fn outgoinglongwaveradiation(&self) -> f64 {
stefan_boltzmann_flux(self.globalmeantempk)
}
pub fn absorbedsolarradiation(&self) -> f64 {
solar_constant() * (1.0 - self.albedo) / 4.0
}
pub fn energyimbalance(&self) -> f64 {
self.absorbedsolarradiation() - self.outgoinglongwaveradiation()
}
pub fn effectiveemissiontemperature(&self) -> f64 {
let s = solar_constant();
((s * (1.0 - self.albedo)) / (4.0 * SIGMA_SB)).powf(0.25)
}
pub fn greenhouseeffectk(&self) -> f64 {
self.globalmeantempk - self.effectiveemissiontemperature()
}
}
pub fn solarzenith(latitudedeg: f64, declinationdeg: f64, hourangledeg: f64) -> f64 {
solar_zenith_angle(latitudedeg, declinationdeg, hourangledeg)
}
pub fn planck_spectral_radiance(wavelengthm: f64, temperaturek: f64) -> f64 {
planck_function(wavelengthm, temperaturek)
}
pub fn co2doublingforcing() -> f64 {
radiative_forcing_co2(560.0, 280.0)
}