The carbohydrate model is an optional feature in the PlantArchitecture plugin that simulates carbon allocation and its effects on plant growth dynamics. When enabled, the model mechanistically tracks carbohydrate pools in each shoot, accumulates photosynthate produced by leaves, accounts for maintenance and growth respiration costs, and dynamically adjusts growth rates based on carbon availability. This provides a physiologically-based mechanism to simulate source-sink relationships and carbon-limited growth.
Important architectural note: Carbohydrate pools are calculated and maintained at the whole-shoot level, not at the individual phytomer level. This is a key distinction from other functional-structural plant models such as L-Peach, which track carbohydrate concentrations at the phytomer (or metamer) level. In the Helios carbohydrate model, all phytomers within a shoot share a common carbon pool, and the carbon concentration is uniform across all internodes in that shoot. This simplification reduces computational cost while still capturing the essential dynamics of carbon allocation and shoot-to-shoot transfer within the plant architecture.
The model integrates with the Photosynthesis plugin to accumulate leaf-level net photosynthesis as a carbon source, and uses this carbon to support organ construction, maintenance respiration, and radial growth. When carbon becomes limiting, the model can slow or stop growth, abort organs (flowers, fruits, or entire shoots), and redistribute carbon between shoots to maintain plant viability.
Key features of the carbohydrate model include:
The carbohydrate model is disabled by default. To enable it, call the PlantArchitecture::enableCarbohydrateModel() method before or after building plant instances:
The model can be disabled at any time using PlantArchitecture::disableCarbohydrateModel(). Once enabled, the model automatically operates during each call to PlantArchitecture::advanceTime().
The behavior of the carbohydrate model is controlled by a comprehensive set of parameters stored in the CarbohydrateParameters structure. Parameters can be set for individual plants or groups of plants using PlantArchitecture::setPlantCarbohydrateModelParameters().
Parameters in the CarbohydrateParameters structure are organized into several categories. Default values are based on almond trees (Prunus dulcis).
| Category | Parameter | Default Value | Units | Description |
|---|---|---|---|---|
| Stem/Wood Properties | ||||
| stem_density | 675000 | g/m³ | Density of mature internode wood tissue. | |
| stem_carbon_percentage | 0.457 | - | Fraction of stem dry weight that is carbon. | |
| initial_density_ratio | 0.25 | - | Ratio of initial internode carbon density to mature density (0-1). | |
| maturity_age | 120 | days | Age at which internode reaches full mature density. | |
| shoot_root_ratio | 3 | - | Ratio of shoot biomass to root biomass. Used to partition carbon for belowground growth. | |
| Leaf Properties | ||||
| SLA | 0.0244 | m²/g | Specific leaf area (leaf area per unit dry mass). | |
| leaf_carbon_percentage | 0.453 | - | Fraction of leaf dry weight that is carbon. | |
| Flower Properties | ||||
| total_flower_cost | 8.33e-4 | mol C | Carbon cost to construct a single flower. | |
| Fruit Properties | ||||
| fruit_density | 525000 | g/m³ | Density of fruit tissue. | |
| fruit_carbon_percentage | 0.475 | - | Fraction of fruit dry weight that is carbon. | |
| Respiration Rates | ||||
| r_m_w_20 | 5.25164e-05 | mol C/mol C/day | Daily maintenance respiration rate for stem (woody) tissue at 20 degC, as a fraction of stem carbon content. | |
| r_m_r_20 | 5.25164e-03 | mol C/mol C/day | Daily maintenance respiration rate for root tissue at 20 degC, as a fraction of root carbon content. Note this is 100x the stem rate. | |
| growth_respiration_fraction | 0.211 | - | Fraction of total carbon used during growth that goes toward respiration rather than structure. | |
| Organ Abortion Thresholds | ||||
| carbohydrate_abortion_threshold | 0.1 | g C/g DW | Carbon concentration threshold below which fruits/flowers may be aborted. | |
| carbohydrate_pruning_threshold | 0.025 | g C/g DW | Carbon concentration threshold below which entire shoots may be pruned. | |
| bud_death_threshold_days | 2 | days | Duration of time below abortion threshold before fruits/flowers are aborted. | |
| branch_death_threshold_days | 5 | days | Duration of time below pruning threshold before shoots are removed. | |
| Growth Modulation Thresholds | ||||
| carbohydrate_phyllochron_threshold | 0.05 | g C/g DW | Carbon concentration below which phyllochron (leaf emergence rate) is slowed. | |
| carbohydrate_vegetative_break_threshold | 0.05 | g C/g DW | Carbon concentration below which vegetative bud break probability is reduced. | |
| carbohydrate_growth_threshold | 0.2 | g C/g DW | Carbon concentration below which radial growth rate is reduced. | |
| Carbon Transfer | ||||
| carbohydrate_transfer_threshold_down | 0.025 | g C/g DW | Minimum carbon concentration required for a shoot to export carbon downward to parent shoots. | |
| carbohydrate_transfer_threshold_up | 0.04 | g C/g DW | Minimum carbon concentration required for a shoot to export carbon upward to child shoots. | |
| carbon_conductance_down | 0.95 | - | Conductance coefficient for carbon transfer from child shoots to parent shoots (0-1). Typically larger than upward conductance. | |
| carbon_conductance_up | 0.475 | - | Conductance coefficient for carbon transfer from parent shoots to child shoots (0-1). Typically smaller than downward conductance. | |
Parameters are set using the PlantArchitecture::setPlantCarbohydrateModelParameters() method. Default parameter values are used unless explicitly modified:
Parameters can also be set for multiple plants simultaneously:
Before growing a plant with the carbohydrate model enabled, carbon pools must be initialized. This sets the initial carbon concentration in each shoot based on the volume of its internodes. Three initialization methods are available:
The carbon pool for each shoot is calculated as:
\[ \text{carbohydrate_pool} = C_{\text{conc}} \times V_{\text{internode}} \]
where \(C_{\text{conc}}\) is the specified concentration (mol C/m³) and \(V_{\text{internode}}\) is the total volume of internodes in the shoot (m³).
Important Notes:**
The primary source of carbon in the model is leaf-level net photosynthesis calculated by the Photosynthesis plugin. The model reads primitive data labeled "net_photosynthesis" from leaf primitives, which should be in units of μmol CO₂ m⁻² s⁻¹.
During each call to PlantArchitecture::advanceTime(), the model:
If the "net_photosynthesis" data is not present on leaf primitives (e.g., Photosynthesis plugin not run), the model issues a warning and continues without adding photosynthate. This allows for testing of the model's carbon sink and transfer mechanisms independently.
Carbon from the carbohydrate pool is consumed by three main processes:
Maintenance respiration represents the carbon cost of maintaining existing tissue. It is calculated separately for shoot (stem) and root tissues:
\[ R_{\text{maint}} = (r_{\text{stem}} \times C_{\text{stem}} + r_{\text{root}} \times C_{\text{root}}) \times \Delta t \]
where:
Stem carbon content is calculated from internode volume and carbon density, which increases with age according to:
\[ \rho_C(t) = \rho_{C,\text{initial}} + (\rho_{C,\text{mature}} - \rho_{C,\text{initial}}) \times \min\left(1, \frac{t}{t_{\text{maturity}}}\right) \]
where \(\rho_{C,\text{initial}} = \rho_{C,\text{mature}} \times \text{initial_density_ratio}\).
For dormant shoots, maintenance respiration is reduced by 80% (multiplied by 0.2).
Growth respiration represents the carbon cost of synthesizing new tissue. It is calculated each time new organs are created or existing organs grow:
Leaf Construction:**
\[ C_{\text{leaf}} = \frac{0.1\,f_{\text{leaf,C}}}{M_C \times \text{SLA}} \times A_{\text{leaf}} \]
where \(f_{\text{leaf,C}}\) is the leaf carbon percentage, \(M_C\) is the molecular weight of carbon (12 g/mol), and \(A_{\text{leaf}}\) is leaf area (m²).
Stem Construction:**
\[ C_{\text{stem}} = \frac{\rho_{\text{stem}} \times f_{\text{stem,struct,C}}}{M_C} \times \Delta V_{\text{stem}} \]
where \(\rho_{\text{stem}}\) is stem density (g/m³), \(f_{\text{stem,struct,C}}\) is the stem structural carbon percentage (stem_structural_carbon_percentage = stem_carbon_percentage - stem_carbohydrate_percentage \(\approx\) 0.334, not the full stem_carbon_percentage of 0.457), and \(\Delta V_{\text{stem}}\) is the change in stem volume (m³).
Flower Construction:**
\[ C_{\text{flower}} = C_{\text{flower,total}} \times N_{\text{flowers}} \]
Fruit Construction:**
\[ C_{\text{fruit}} = \frac{\rho_{\text{fruit}} \times f_{\text{fruit,C}}}{M_C} \times \Delta V_{\text{fruit}} \]
Root Allocation:**
Root construction costs are added to the above-ground costs using the shoot-root ratio:
\[ C_{\text{total}} = C_{\text{shoot}} \times \left(1 + \frac{1}{\text{shoot_root_ratio}}\right) \]
When the ShootParameters::girth_area_factor parameter is non-zero, internodes increase in radius over time based on downstream leaf area. This radial growth requires carbon, which is subtracted from the carbohydrate pool. If the carbohydrate concentration is below the carbohydrate_growth_threshold, radial growth is reduced proportionally to carbon availability.
Carbon can be transferred between shoots within a plant to redistribute resources from carbon-rich to carbon-limited shoots. The transfer mechanism is bidirectional and gradient-driven, allowing carbon to flow in either direction based on concentration differences. Importantly, both upward (parent-to-child) and downward (child-to-parent) transfers occur simultaneously during each timestep, with the net flow direction determined by the concentration gradient and the asymmetric conductance parameters.
This shoot-to-shoot transfer mechanism represents vascular transport of mobile carbohydrates (primarily sucrose) through the phloem. The conductance parameters can be tuned to match species-specific transport characteristics and the asymmetry between source-to-sink (upward) and sink-to-source (downward) flows.
Parent shoots can export carbon to their child shoots when the parent's carbon concentration exceeds the carbohydrate_transfer_threshold_up. This transfer represents the flow of photosynthate from established shoots to developing distal branches. The amount of carbon transferred depends on:
The transfer is calculated as:
\[ \Delta C_{\text{transfer}} = \min\left(\Delta C_{\text{demand}}, C_{\text{available}} \times f_{\text{child}}\right) \]
where the demand is:
\[ \Delta C_{\text{demand}} = k_{\text{up}} \times \Delta C \times V_{\text{transfer}} \times f_{\text{child}} \times \Delta t \]
and:
Key features of upward transfer:
Child shoots can export carbon to their parent shoot when the child's concentration exceeds both the carbohydrate_transfer_threshold_down and the parent's concentration. This transfer represents the mobilization of carbohydrates from productive distal branches back to the main stem, which is characteristic of mature branches with high photosynthetic capacity.
The downward transfer is simpler than upward transfer, with each child shoot transferring independently to its parent:
\[ \Delta C_{\text{transfer}} = \min\left(\Delta C_{\text{demand}}, C_{\text{available}}\right) \]
where:
\[ \Delta C_{\text{demand}} = k_{\text{down}} \times (C_{\text{child}} - C_{\text{parent}}) \times V_{\text{child}} \times \Delta t \]
and:
Key features of downward transfer:
During each timestep, both upward and downward transfers are evaluated and executed. This means that carbon can simultaneously flow:
The net flow direction in any parent-child pair depends on:
This bidirectional mechanism allows the plant to dynamically redistribute carbon throughout its architecture in response to local carbon availability, mimicking the complex source-sink dynamics of real plant vascular systems. Photosynthetically productive regions naturally become sources that export carbon, while growing regions with high respiration costs become sinks that import carbon.
The carbohydrate model dynamically adjusts growth rates based on carbon availability, providing a mechanistic link between carbon supply and plant development.
The phyllochron (time between successive leaf emergences) can be increased above its minimum value when carbon becomes limiting. The instantaneous phyllochron is calculated as:
\[ \tau_{\text{phyl}} = \max\left(\tau_{\text{min}}, \frac{\tau_{\text{min}}}{r_{\text{carbon}} \times \Delta t}\right) \]
where \(\tau_{\text{min}}\) is the phyllochron_min parameter from ShootParameters, \(\Delta t\) is the timestep (days), and \(r_{\text{carbon}}\) is the carbon availability ratio:
\[ r_{\text{carbon}} = \frac{C_{\text{pool}}}{C_{\text{threshold}} \times \rho_{\text{stem}} \times V_{\text{shoot}} / M_C} \]
where \(C_{\text{pool}}\) is the current carbon pool (mol C), \(C_{\text{threshold}}\) is the carbohydrate_phyllochron_threshold (g C/g DW), \(\rho_{\text{stem}}\) is the stem density (g/m³), \(V_{\text{shoot}}\) is the shoot volume (m³), and \(M_C\) is the molecular weight of carbon (12 g/mol).
When carbon is abundant (ratio above 1.0), the phyllochron equals its minimum value (maximum growth rate). As carbon becomes limiting, the phyllochron increases, slowing the rate of leaf production. Note that the phyllochron adjustment is timestep-dependent, with smaller timesteps resulting in stronger adjustment.
Similarly, internode elongation is reduced when carbon is below the carbohydrate_growth_threshold. However, this modulation is currently not explicitly implemented in the code - elongation continues at the specified rate, but the construction costs are still subtracted from the carbon pool.
When carbon concentration falls below the carbohydrate_growth_threshold, radial growth (girth increase) is slowed. The radial growth rate is scaled by the carbon availability ratio:
\[ \frac{dr}{dt} = \frac{dr}{dt}\bigg|_{\text{max}} \times \max\left(0.05, r_{\text{carbon}}\right) \]
where the carbon availability ratio \(r_{\text{carbon}}\) is calculated as described above. Growth is never reduced below 5% of the maximum rate (minimum scaling factor of 0.05).
The probability that a vegetative bud will break and produce a new shoot can be reduced when carbon is limiting. If the carbon concentration is below the carbohydrate_vegetative_break_threshold, the bud break probability is scaled linearly:
\[ P_{\text{break}} = P_{\text{base}} \times \frac{C_{\text{conc}}}{C_{\text{threshold}}} \]
where \(P_{\text{base}}\) is the base bud break probability from ShootParameters and \(C_{\text{threshold}}\) is the carbohydrate_vegetative_break_threshold. This allows the plant to suppress branching when carbon reserves are low.
When carbon stress persists, the model can abort individual organs or prune entire shoots to reduce carbon demand and maintain plant viability. This represents a plant's ability to shed organs under resource limitation.
If a shoot's carbon concentration falls below the carbohydrate_abortion_threshold for longer than bud_death_threshold_days, fruits and flowers are progressively aborted:
This continues until either:
If carbon stress is more severe and persists longer, entire shoots can be pruned. When a shoot's carbon concentration falls below the carbohydrate_pruning_threshold for longer than branch_death_threshold_days, the entire shoot is removed using PlantArchitecture::pruneBranch().
Note that the pruning threshold is typically much lower than the abortion threshold (default 0.01 vs 0.1 g C/g DW), and the time threshold is longer (default 5 vs 2 days). This ensures that pruning only occurs under severe, prolonged carbon stress.
In addition to time-based thresholds, shoots are immediately pruned if:
These conditions indicate that the shoot has become a pure carbon sink with no prospect of recovery.
When the carbohydrate model is enabled, an optional output data field can be activated to visualize carbon concentrations:
This creates object data labeled "carbohydrate_concentration" with type float on internode tube objects. The value represents the carbon concentration in units of mol C/m³:
\[ C_{\text{conc}} = \frac{C_{\text{pool}}}{V_{\text{shoot}}} \]
The concentration is constant along each shoot (all internodes in a shoot have the same value) and is zero for non-internode organs (leaves, petioles, flowers, fruit).
This data can be used to: