2#include "../framework/constants.h"
4#include "../math/roots/onedim/dekker.h"
53 double air_temperature,
61 double constexpr coef_forced = 0.147;
62 double constexpr coef_free = 0.055;
65 double const gbv_forced = coef_forced * sqrt(windspeed / lw);
66 double const gbv_free = coef_free * pow(std::abs(delta_t) / lw, 0.25);
69 double const gbv_leaf = std::max(gbv_forced, gbv_free);
72 return g_to_mass(p, gbv_leaf, air_temperature + delta_t);
131 double air_temperature,
140 double const leaftemp = air_temperature + delta_t;
141 double const Tak = air_temperature + conversion_constants::celsius_to_kelvin;
142 double const Tlk = leaftemp + conversion_constants::celsius_to_kelvin;
147 double constexpr cf = 4.322e-3;
148 double constexpr ce = 1.6361e-3;
149 double constexpr ct = 0.378;
152 double const gbv_forced = cf * pow(Tak, 0.56) *
153 sqrt((Tak + 120) * windspeed / (lw * p));
158 auto check_leaf_gbv_free = [=](
double const gbv_free) {
160 double const eb = (gsv * esTl + gbv_free * ea) / (gsv + gbv_free);
163 double const Tvdiff = Tlk / (1.0 - ct * eb / p) -
164 Tak / (1.0 - ct * ea / p);
167 double const new_gbv_free =
168 ce * pow(Tlk, 0.56) * sqrt((Tlk + 120) / p) *
169 pow(std::abs(Tvdiff) / lw, 0.25);
171 return gbv_free - new_gbv_free;
178 root_finding::dekker solver(500, 1e-12, 1e-12);
180 root_finding::result_t result = solver.solve(
188 if (!root_finding::is_successful(result.flag)) {
189 throw std::runtime_error(
190 "gbv_free solver reports failed convergence with termination flag:\n " +
191 root_finding::flag_message(result.flag));
195 double const gbv_free = result.root;
198 return std::max(gbv_forced, gbv_free);
262 double WindSpeedHeight
270 constexpr double kappa = 0.41;
271 constexpr double ZetaCoef = 0.026;
272 constexpr double ZetaMCoef = 0.13;
273 constexpr double dCoef = 0.77;
276 CanopyHeight = std::min(CanopyHeight, 0.98 * WindSpeedHeight);
279 const double Zeta = ZetaCoef * CanopyHeight;
280 const double Zetam = ZetaMCoef * CanopyHeight;
281 const double d = dCoef * CanopyHeight;
285 const double ga0 = pow(kappa, 2) * WindSpeed;
286 const double ga1 = log((WindSpeedHeight + Zeta - d) / Zeta);
287 const double ga2 = log((WindSpeedHeight + Zetam - d) / Zetam);
288 const double gbv = ga0 / (ga1 * ga2);
291 return std::max(gbv, minimum_gbw);
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 leaf_boundary_layer_conductance_nikolov(double air_temperature, double delta_t, double ea, double gsv, double lw, double windspeed, double p)
Calculates the conductance for water vapor flow from the leaf across its boundary layer using a model...
double canopy_boundary_layer_conductance_thornley(double CanopyHeight, double WindSpeed, double minimum_gbw, double WindSpeedHeight)
Calculates the conductance for water vapor flow from the canopy across its boundary layer using a mod...
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 saturation_vapor_pressure(double air_temperature)
Determine saturation water vapor pressure (Pa) from air temperature (degrees C) using the Arden Buck ...