Skip to content

Commit ea04e98

Browse files
committed
fix pmodel gpp for c4
1 parent d04abc1 commit ea04e98

File tree

6 files changed

+58
-22
lines changed

6 files changed

+58
-22
lines changed

src/standalone/Vegetation/Canopy.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ end
222222
toml_dict::CP.ParamDict;
223223
is_c3 = clm_photosynthesis_parameters(domain.space.surface).is_c3,
224224
cstar = toml_dict["pmodel_cstar"],
225-
β = toml_dict["pmodel_β"],
225+
β_c3 = toml_dict["pmodel_β_c3"],
226+
β_c4 = toml_dict["pmodel_β_c4"],
226227
temperature_dep_yield = true,
227228
ϕ0_c3 = toml_dict["pmodel_ϕ0_c3"],
228229
ϕ0_c4 = toml_dict["pmodel_ϕ0_c4"],
@@ -239,7 +240,8 @@ Constructs a P-model (an optimality model for photosynthesis) using default para
239240
240241
The following default parameters (from the TOML file) are used:
241242
- cstar = 0.41 (unitless) - 4 * dA/dJmax, assumed to be a constant marginal cost (Wang 2017, Stocker 2020)
242-
- β = 146 (unitless) - Unit cost ratio of Vcmax to transpiration (Stocker 2020)
243+
- β_c3 = 146 (unitless) - Unit cost ratio of Vcmax to transpiration for C3 plants (Stocker 2020)
244+
- β_c4 = 146/9 ≈ 16.222 (unitless) - Unit cost ratio of Vcmax to transpiration for C4 plants (pyrealm)
243245
- ϕ0_c3 = 0.052 (unitless) - constant intrinsic quantum yield. Skillman (2008)
244246
- ϕ0_c4 = 0.057 (unitless) - constant intrinsic quantum yield. Skillman (2008)
245247
- ϕa0_c3 = 0.352*0.087 (unitless) - constant term in quadratic intrinsic quantum yield (Stocker 2020)
@@ -255,7 +257,8 @@ function PModel{FT}(
255257
toml_dict::CP.ParamDict;
256258
is_c3 = clm_photosynthesis_parameters(domain.space.surface).is_c3,
257259
cstar = toml_dict["pmodel_cstar"],
258-
β = toml_dict["pmodel_β"],
260+
β_c3 = toml_dict["pmodel_β_c3"],
261+
β_c4 = toml_dict["pmodel_β_c4"],
259262
temperature_dep_yield = true,
260263
ϕ0_c3 = toml_dict["pmodel_ϕ0_c3"],
261264
ϕ0_c4 = toml_dict["pmodel_ϕ0_c4"],
@@ -269,7 +272,8 @@ function PModel{FT}(
269272
) where {FT <: AbstractFloat}
270273
parameters = ClimaLand.Canopy.PModelParameters(
271274
cstar,
272-
β,
275+
β_c3,
276+
β_c4,
273277
temperature_dep_yield,
274278
ϕ0_c3,
275279
ϕ0_c4,

src/standalone/Vegetation/optimal_lai.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ function call_update_optimal_LAI(p, Y, t, current_date; canopy, dt, local_noon)
557557
P_air,
558558
p.canopy.biomass.vpd_gs,
559559
ca,
560+
is_c3,
560561
),
561562
)
562563

src/standalone/Vegetation/pmodel.jl

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ $(DocStringExtensions.FIELDS)
1717
Base.@kwdef struct PModelParameters{FT <: AbstractFloat}
1818
"Constant describing cost of maintaining electron transport (unitless)"
1919
cstar::FT
20-
"Ratio of unit costs of transpiration and carboxylation (unitless)"
21-
β::FT
20+
"Ratio of unit costs of transpiration and carboxylation for C3 plants (unitless)"
21+
β_c3::FT
22+
"Ratio of unit costs of transpiration and carboxylation for C4 plants (unitless)"
23+
β_c4::FT
2224
"A boolean flag indicating if the quantum yield is a function of temperature or not"
2325
temperature_dep_yield::Bool
2426
"Temp-independent intrinsic quantum yield. (unitless); C3"
@@ -112,6 +114,13 @@ Base.eltype(::PModelConstants{FT}) where {FT} = FT
112114
Base.broadcastable(x::PModelParameters) = tuple(x)
113115
Base.broadcastable(x::PModelConstants) = tuple(x)
114116

117+
"""
118+
get_beta(is_c3, β_c3, β_c4)
119+
120+
Returns the appropriate β (cost ratio) based on whether the plant is C3 or C4.
121+
"""
122+
get_beta(is_c3, β_c3, β_c4) = ifelse(is_c3 == one(is_c3), β_c3, β_c4)
123+
115124
"""
116125
PModelConstants(toml_dict::CP.ParamDict;
117126
Kc25 = toml_dict["pmodel_Kc25"],
@@ -336,7 +345,8 @@ function compute_full_pmodel_outputs(
336345
is_c3 = FT(1),
337346
) where {FT}
338347
# Unpack parameters
339-
(; cstar, β) = parameters
348+
(; cstar, β_c3, β_c4) = parameters
349+
β = get_beta(is_c3, β_c3, β_c4)
340350

341351
# Unpack constants
342352
(;
@@ -507,7 +517,8 @@ function update_optimal_EMA(
507517
) where {FT}
508518
if local_noon_mask == FT(1.0)
509519
# Unpack parameters
510-
(; cstar, β, α) = parameters
520+
(; cstar, β_c3, β_c4, α) = parameters
521+
β = get_beta(is_c3, β_c3, β_c4)
511522

512523
# Unpack constants
513524
(;
@@ -670,7 +681,8 @@ function set_historical_cache!(p, Y0, model::PModel, canopy)
670681

671682
parameters_init = PModelParameters(
672683
cstar = parameters.cstar,
673-
β = parameters.β,
684+
β_c3 = parameters.β_c3,
685+
β_c4 = parameters.β_c4,
674686
temperature_dep_yield = parameters.temperature_dep_yield,
675687
ϕ0_c4 = parameters.ϕ0_c4,
676688
ϕ0_c3 = parameters.ϕ0_c3,
@@ -1400,7 +1412,8 @@ function compute_A0_daily(
14001412
PPFD::FT,
14011413
βm::FT,
14021414
) where {FT}
1403-
(; cstar, β) = parameters
1415+
(; cstar, β_c3, β_c4) = parameters
1416+
β = get_beta(is_c3, β_c3, β_c4)
14041417
(; R, Kc25, Ko25, To, ΔHkc, ΔHko, Drel, ΔHΓstar, Γstar25, Mc, oi, ρ_water) =
14051418
constants
14061419

@@ -1429,17 +1442,18 @@ function compute_A0_daily(
14291442
end
14301443

14311444
"""
1432-
compute_chi(pmodel_parameters, pmodel_constants, T, P_air, VPD, ca)
1445+
compute_chi(pmodel_parameters, pmodel_constants, T, P_air, VPD, ca, is_c3=FT(1))
14331446
14341447
Compute the optimal ratio of intercellular to ambient CO2 (chi = ci/ca) using P-model.
14351448
14361449
# Arguments
1437-
- `pmodel_parameters`: P-model parameters (including beta)
1450+
- `pmodel_parameters`: P-model parameters (including β_c3 and β_c4)
14381451
- `pmodel_constants`: P-model constants (including Gamma_star25, Kc25, Ko25, etc.)
14391452
- `T::FT`: Temperature (K)
14401453
- `P_air::FT`: Atmospheric pressure (Pa)
14411454
- `VPD::FT`: Vapor pressure deficit (Pa)
14421455
- `ca::FT`: Ambient CO2 mixing ratio (mol/mol)
1456+
- `is_c3::FT`: C3 (1) or C4 (0) flag (default: C3)
14431457
14441458
# Returns
14451459
- `chi::FT`: Optimal ci/ca ratio (dimensionless), typically 0.7-0.85
@@ -1451,8 +1465,10 @@ function compute_chi(
14511465
P_air::FT,
14521466
VPD::FT,
14531467
ca::FT,
1468+
is_c3::FT = FT(1),
14541469
) where {FT}
1455-
(; β) = pmodel_parameters
1470+
(; β_c3, β_c4) = pmodel_parameters
1471+
β = get_beta(is_c3, β_c3, β_c4)
14561472
(; R, Kc25, Ko25, To, ΔHkc, ΔHko, Drel, ΔHΓstar, Γstar25, oi, ρ_water) =
14571473
pmodel_constants
14581474

test/standalone/Vegetation/test_pmodel.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ Constructs the parameter structure for the P-Model
6262
"""
6363
function PModelParameters(inputs::Dict{String, Any}, FT)
6464
# these are default values used in Stocker 2020, Scott and Smith 2022
65-
β = FT(inputs["beta"])
65+
β_c3 = FT(inputs["beta"])
66+
β_c4 = FT(inputs["beta"]) / FT(9)
6667
cstar = FT(0.41)
6768

6869
# handle temperature-dependent quantum yield
@@ -82,7 +83,8 @@ function PModelParameters(inputs::Dict{String, Any}, FT)
8283

8384
return ClimaLand.Canopy.PModelParameters(;
8485
cstar,
85-
β,
86+
β_c3,
87+
β_c4,
8688
temperature_dep_yield,
8789
ϕ0_c3,
8890
ϕ0_c4,
@@ -271,7 +273,8 @@ end
271273
toml_dict = LP.create_toml_dict(FT)
272274
parameters = ClimaLand.Canopy.PModelParameters(
273275
cstar = FT(0.41),
274-
β = FT(146),
276+
β_c3 = FT(146),
277+
β_c4 = FT(146 / 9),
275278
temperature_dep_yield = true,
276279
ϕ0_c3 = FT(0.052),
277280
ϕ0_c4 = FT(0.057),

toml/default_parameters.toml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,21 @@ tag = "ConstantResetAlbedo"
223223

224224
# P model parameters
225225
["pmodel_cstar"]
226-
value = 0.43
226+
value = 0.41
227227
type = "float"
228228
description = "4 * dA/dJmax, assumed to be a constant marginal cost (Wang 2017, Stocker 2020)"
229229
tag = "PModelParameters"
230230

231-
["pmodel_β"]
232-
value = 51
231+
["pmodel_β_c3"]
232+
value = 146
233233
type = "float"
234-
description = "Unit cost ratio of Vcmax to transpiration (Stocker 2020)"
234+
description = "Unit cost ratio of Vcmax to transpiration for C3 plants (Stocker 2020)"
235+
tag = "PModelParameters"
236+
237+
["pmodel_β_c4"]
238+
value = 16.222222222222222
239+
type = "float"
240+
description = "Unit cost ratio of Vcmax to transpiration for C4 plants (146/9, pyrealm)"
235241
tag = "PModelParameters"
236242

237243
["pmodel_ϕ0_c3"]

toml/uncalibrated_parameters.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,16 @@ type = "float"
202202
description = "4 * dA/dJmax, assumed to be a constant marginal cost (Wang 2017, Stocker 2020)"
203203
tag = "PModelParameters"
204204

205-
["pmodel_β"]
205+
["pmodel_β_c3"]
206206
value = 146
207207
type = "float"
208-
description = "Unit cost ratio of Vcmax to transpiration (Stocker 2020)"
208+
description = "Unit cost ratio of Vcmax to transpiration for C3 plants (Stocker 2020)"
209+
tag = "PModelParameters"
210+
211+
["pmodel_β_c4"]
212+
value = 16.222222222222222
213+
type = "float"
214+
description = "Unit cost ratio of Vcmax to transpiration for C4 plants (146/9, pyrealm)"
209215
tag = "PModelParameters"
210216

211217
["pmodel_ϕ0_c3"]

0 commit comments

Comments
 (0)