use crate::temporal::calendar::SECONDS_PER_DAY;
use sciforge::hub::prelude::biology::plant_biology::{farquhar_c3, vcmax_temperature_response};
use sciforge::hub::prelude::constants::elements::atomic_mass;
pub struct Vegetation {
pub name: &'static str,
pub leaf_area_index: f64,
pub max_photosynthesis_umol_m2_s: f64,
pub root_depth_m: f64,
pub carbon_stock_kgc_m2: f64,
}
impl Vegetation {
pub fn photosynthesis_rate(&self, co2_ppm: f64, light_umol_m2_s: f64, temp_c: f64) -> f64 {
let temp_k = temp_c + crate::CELSIUS_TO_KELVIN;
let vcmax = vcmax_temperature_response(self.max_photosynthesis_umol_m2_s, 65_330.0, temp_k);
let ci = co2_ppm * 0.7;
let jmax = vcmax * 1.67;
let j = jmax * light_umol_m2_s / (light_umol_m2_s + 2.1 * jmax);
farquhar_c3(vcmax, ci, 42.75, 404.9, 278.4, 210.0, j, 1.0)
}
pub fn canopy_photosynthesis(&self, leaf_rate: f64) -> f64 {
leaf_rate * self.leaf_area_index * (1.0 - (-0.5 * self.leaf_area_index).exp())
}
pub fn transpiration_mm_day(&self, vpd_kpa: f64, stomatal_conductance: f64) -> f64 {
stomatal_conductance * vpd_kpa * self.leaf_area_index * SECONDS_PER_DAY / 1000.0
}
pub fn npp_kgc_m2_yr(&self, gpp_umol_m2_s: f64) -> f64 {
let carbon_kg_per_umol = atomic_mass(6) * 1e-6;
let gpp_kgc = gpp_umol_m2_s * carbon_kg_per_umol * 1e-3 * crate::SECONDS_PER_YEAR;
gpp_kgc * 0.5
}
pub fn carbon_residence_time_yr(&self, npp: f64) -> f64 {
self.carbon_stock_kgc_m2 / npp
}
}
pub fn tropical_broadleaf() -> Vegetation {
Vegetation {
name: "Tropical Broadleaf",
leaf_area_index: 6.0,
max_photosynthesis_umol_m2_s: 40.0,
root_depth_m: 3.0,
carbon_stock_kgc_m2: 18.0,
}
}
pub fn temperate_grassland() -> Vegetation {
Vegetation {
name: "Temperate Grassland",
leaf_area_index: 2.5,
max_photosynthesis_umol_m2_s: 25.0,
root_depth_m: 1.5,
carbon_stock_kgc_m2: 0.7,
}
}
pub fn coniferous_forest() -> Vegetation {
Vegetation {
name: "Coniferous Forest",
leaf_area_index: 4.5,
max_photosynthesis_umol_m2_s: 15.0,
root_depth_m: 2.0,
carbon_stock_kgc_m2: 12.0,
}
}
pub fn beer_lambert_light_extinction(light_above: f64, lai: f64, extinction_coeff: f64) -> f64 {
light_above * (-extinction_coeff * lai).exp()
}