use rscm_core::component::{
Component, InputState, OutputState, RequirementDefinition, RequirementType,
};
use rscm_core::errors::RSCMResult;
use rscm_core::timeseries::{FloatValue, Time};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CO2ERFParameters {
pub erf_2xco2: FloatValue,
pub conc_pi: FloatValue,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CO2ERF {
parameters: CO2ERFParameters,
}
impl CO2ERF {
pub fn from_parameters(parameters: CO2ERFParameters) -> Self {
Self { parameters }
}
}
#[typetag::serde]
impl Component for CO2ERF {
fn definitions(&self) -> Vec<RequirementDefinition> {
vec![
RequirementDefinition::new(
"Atmospheric Concentration|CO2",
"ppm",
RequirementType::Input,
),
RequirementDefinition::new(
"Effective Radiative Forcing|CO2",
"W / m^2",
RequirementType::Output,
),
]
}
fn solve(
&self,
_t_current: Time,
_t_next: Time,
input_state: &InputState,
) -> RSCMResult<OutputState> {
let erf = self.parameters.erf_2xco2 / 2.0_f64.log10()
* (1.0
+ (input_state.get_latest("Atmospheric Concentration|CO2")
- self.parameters.conc_pi)
/ self.parameters.conc_pi)
.log10();
Ok(HashMap::from([(
"Effective Radiative Forcing|CO2".to_string(),
erf,
)]))
}
}