2#include "../framework/constants.h"
6#include "../math/roots/onedim/dekker.h"
26 double const epsilon_s,
28 double const leaf_temperature
32 double const R_l = epsilon_s * physical_constants::stefan_boltzmann *
33 pow(conversion_constants::celsius_to_kelvin + leaf_temperature, 4);
49 double const air_pressure,
50 double const air_temperature,
51 double const leaf_temperature,
52 double const leaf_width,
53 double const wind_speed
58 leaf_temperature - air_temperature,
69 double const air_pressure,
70 double const air_temperature,
71 double const Delta_rho,
72 double const epsilon_s,
74 double const gbw_canopy,
77 double const leaf_temperature,
78 double const leaf_width,
80 double const stomatal_conductance,
81 double const wind_speed
85 double const gsw =
g_to_mass(air_pressure, stomatal_conductance, leaf_temperature);
101 double const Phi_N =
calculate_Phi_N(epsilon_s, J_a, leaf_temperature);
102 double const pm_top = Phi_N / gw - lambda * Delta_rho;
103 double const pm_bottom = lambda * (s + gamma * (1.0 + gbw / gsw));
105 double const leaf_temperature_new = air_temperature + pm_top / pm_bottom;
107 return leaf_temperature - leaf_temperature_new;
148 double absorbed_longwave_energy,
149 double absorbed_shortwave_energy,
151 double air_temperature,
154 double relative_humidity,
155 double stomatal_conductance,
160 double constexpr epsilon_s = 1.0;
163 double const c_p =
TempToCp(air_temperature);
167 double const s =
TempToSFS(air_temperature);
170 double const gamma = rho_ta * c_p / lambda;
173 double const p_w_air = p_w_sat_air * relative_humidity;
175 double const rho_w_air =
179 double const rho_w_sat =
182 double const Delta_rho = rho_w_sat - rho_w_air;
185 double const J_a = absorbed_shortwave_energy + absorbed_longwave_energy;
190 auto check_leaf_temp_partial = [=](
double const leaf_temperature) {
203 stomatal_conductance,
209 double constexpr delta_temp = 50;
211 root_finding::dekker solver{500, 1e-12, 1e-12};
213 root_finding::result_t result = solver.solve(
214 check_leaf_temp_partial,
215 air_temperature + 0.9 * delta_temp,
216 air_temperature - delta_temp,
217 air_temperature + delta_temp
221 if (!root_finding::is_successful(result.flag)) {
222 throw std::runtime_error(
223 "leaf_temperature solver reports failed convergence with termination flag:\n " +
224 root_finding::flag_message(result.flag));
228 double const leaf_temperature = result.root;
231 double const gsw =
g_to_mass(air_pressure, stomatal_conductance, leaf_temperature);
241 double const gbw_molecular =
g_to_molecular(air_pressure, gbw, leaf_temperature);
243 double const Phi_N =
calculate_Phi_N(epsilon_s, J_a, leaf_temperature);
244 double const Delta_T = leaf_temperature - air_temperature;
245 double const E = (Delta_rho + s * Delta_T) * gw;
246 double const H = rho_ta * c_p * Delta_T * gbw;
247 double const storage = Phi_N - H - lambda * E;
250 double const RH_canopy = (rho_w_air + E / gbw_canopy) / rho_w_sat;
254 double const EPen = (s * Phi_N + lambda * gamma * gbw * Delta_rho) /
255 (lambda * (s + gamma));
258 double constexpr dryness_coefficient = 1.26;
259 double const EPries = dryness_coefficient * s * Phi_N /
260 (lambda * (s + gamma));
265 double constexpr cf = 1e3 / physical_constants::molar_mass_of_water;
double leaf_boundary_layer_conductance_campbell(double air_temperature, double delta_t, double lw, double windspeed, double p)
Calculates the conductance for water vapor flow from the leaf across its boundary layer using a model...
double sequential_conductance(double const conductance_1, double const conductance_2)
Calculates the total conductance across two sequential gas paths.
double g_to_molecular(double const pressure, double const conductance, double const temperature)
Convert a conductance value from a "mass" basis (in units of m / s) to a "molecular" basis (in units ...
double g_to_mass(double const pressure, double const conductance, double const temperature)
Convert a conductance value from a "molecular" basis (in units of mol / m^2 / s) to a "mass" basis (i...
double check_leaf_temp(double const air_pressure, double const air_temperature, double const Delta_rho, double const epsilon_s, double const gamma, double const gbw_canopy, double const J_a, double const lambda, double const leaf_temperature, double const leaf_width, double const s, double const stomatal_conductance, double const wind_speed)
Calculates a difference in leaf temperature; this function will return zero only if leaf temperature ...
energy_balance_outputs leaf_energy_balance(double absorbed_longwave_energy, double absorbed_shortwave_energy, double air_pressure, double air_temperature, double gbw_canopy, double leaf_width, double relative_humidity, double stomatal_conductance, double wind_speed)
Calculates leaf-level temperature and transpiration rate for a leaf within a canopy using a Penman-Mo...
double calculate_Phi_N(double const epsilon_s, double const J_a, double const leaf_temperature)
Calculates the total energy available to the leaf for transpiration and sensible heat loss,...
double calculate_gbw_leaf(double const air_pressure, double const air_temperature, double const leaf_temperature, double const leaf_width, double const wind_speed)
Calculates the leaf boundary layer conductance using the Nikolov model.
double TempToSFS(double air_temperature)
Determine the derivative of saturation water vapor density with respect to temperature at a particula...
double saturation_vapor_pressure(double air_temperature)
Determine saturation water vapor pressure (Pa) from air temperature (degrees C) using the Arden Buck ...
double TempToCp(double air_temperature)
Determine the specific heat capacity of dry air at constant pressure (c_p) at a particular value of a...
double dry_air_density(const double air_temperature, const double air_pressure)
Calculate the density of dry air from temperature and pressure using the ideal gas law.
double vapor_density_from_pressure(double density_of_dry_air, double total_pressure, double vapor_pressure)
Use Equation 14.5a from Thornley & Johnson (1990) to calculate water vapor density from water vapor p...
double water_latent_heat_of_vaporization_henderson(double temperature)
Determine the latent heat of vaporization of water from its temperature.