|
| 1 | +# Opt model |
| 2 | + |
| 3 | +```@meta |
| 4 | +CurrentModule = Junimo |
| 5 | +``` |
| 6 | + |
| 7 | +## Description |
| 8 | + |
| 9 | +`OptModel` is built on eco-evolutionary optimality principles to simulate how vegetation gross primary productivity (GPP) responds to climate and atmospheric CO₂. It integrates optimal stomatal conductance theory, optimal Ci/Ca theory, and the coordination theory, treating stomatal conductance (gs), intercellular CO₂ ratio, and maximum rate of Ribulose-1,5-bisphosphate carboxylase/ oxygenase (Rubisco) carboxylation (Vcmax) as outcomes of a carbon gain versus water cost trade-off, which enables analytical solutions for key variables. Driven by LAI and climate forcings (temperature, precipitation, potential evapotranspiration, VPD, radiation, elevation, and CO₂), the model requires only a small number of parameters (i.e., b). It can compute GPP, gs, Vcmax, and marginal water-use efficiency, among others. Compared with empirical formulations, `OptModel` is parsimonious and physically interpretable, better capturing responses to climate variability and elevated CO₂, and it scales well across sites and regions (Hu et al., 2025). |
| 10 | + |
| 11 | +## Examples |
| 12 | + |
| 13 | +```@example |
| 14 | +using Junimo |
| 15 | +using CairoMakie |
| 16 | +using CSV, DataFrames |
| 17 | +
|
| 18 | +root_dir = joinpath(@__DIR__, "..", "..", "..", "..") # hide |
| 19 | +# root_dir = "." |
| 20 | +data_path = joinpath(root_dir, "data", "BE-Vie_8day") |
| 21 | +df = CSV.read(data_path, DataFrame) |
| 22 | +
|
| 23 | +begin |
| 24 | + Ta = df.Tavg # [°C] |
| 25 | + Precip = df.Prcp # [mm] |
| 26 | + PET = df.PET # [mm] |
| 27 | + PAR = (df.Rs * 0.4) * 4.6 # [W m-2] -> [umol m-2 s-1] |
| 28 | + LAI = df.LAI # [m2 m-2] |
| 29 | + VPD = df.VPD # [kPa] |
| 30 | + elv = df.elv # [m] |
| 31 | + Ca = df.co2 # [ppm] |
| 32 | + b = df.b # [-] |
| 33 | +
|
| 34 | + res = OptModel.(Ta, Precip, PET, PAR, LAI, VPD, elv, Ca, b) |
| 35 | + GPP_Opt = getindex.(res, 1) |
| 36 | +end |
| 37 | +
|
| 38 | +begin |
| 39 | + yobs, ysim = df.GPP_obs, GPP_Opt |
| 40 | + fig = Figure(; size=(300, 300)) |
| 41 | + ax = Axis( |
| 42 | + fig[1, 1], titlefont = :regular, |
| 43 | + xlabel = "Observed GPP (gC/m2/day)", ylabel = "OptModel GPP (gC/m2/day)", |
| 44 | + rightspinevisible = false, topspinevisible = false, |
| 45 | + xgridvisible = false, ygridvisible = false |
| 46 | + ) |
| 47 | + scatter!(ax, yobs, ysim; markersize=10, color=:lightblue) |
| 48 | + lines!(ax, [0, 15], [0, 15]; color=:red, linestyle=:dash, linewidth=2) |
| 49 | + show_gof!( |
| 50 | + ax, 0.1, 14.9, yobs, ysim; metrics=["R2", "RMSE", "PBIAS"], |
| 51 | + n=3, align=(:left, :top), color=:black |
| 52 | + ) |
| 53 | + xlims!(ax, 0, 15) |
| 54 | + ylims!(ax, 0, 15) |
| 55 | + fig |
| 56 | +end |
| 57 | +``` |
| 58 | + |
| 59 | +## APIs |
| 60 | + |
| 61 | +```@docs |
| 62 | +OptModel |
| 63 | +fraction_of_photosynthetically_active_radiation |
| 64 | +soil_moisture_constraint_factor |
| 65 | +surface_pressure |
| 66 | +photorespiratory_compensation_point |
| 67 | +effective_michaelis_menten_coefficient_of_rubisco |
| 68 | +marginal_water_use_efficiency |
| 69 | +``` |
0 commit comments