Source code for pcse.crop.lintul_cassava.leaf_senescence

# -*- coding: utf-8 -*-
# Herman Berghuijs (herman.berghuijs@wur.nl), Allard de Wit (allard.dewit@wur.nl), Tom Schut (tom.schut@wur.nl)
# February 2026

from pcse.base import ParamTemplate, RatesTemplate, SimulationObject, StatesTemplate
from pcse.traitlets import Float
from pcse.util import AfgenTrait

[docs] class leaf_senescence(SimulationObject): """ Class to simulate the growth of green leaf area index. This class calculates the various mechanisms that lead to leaf senescence and, because of that, a reduction of the leaf area index. Green leaf tissue can either die due to 1) Ageing, 2) Leaf shedding in case of too much self shading, 3) severe drought, or 4) nutrient limitation. **Simulation parameters** ================= ============================================== ====== =========================== Name Description Type Unit ================= ============================================== ====== =========================== FASTRANSLO Fraction of senescened leaf dry matterr that is transferred to the storage organs before shedding SCr g DM g-1 DM FRACTLLFENHSH Fraction of maximum leaf age above which leaf shedding is enhanced. SCr - FRACSLATB Fraction of actual specific leaf area to the maximum specific leaf area as a function of temperature sum TCr - LAICR Critical leaf area index above which leaf shedding is induced SCr m2 leaf m-2 ground RDRB Relative death rates of leaves in absence of water and nutrient stress SCr d-1 RDNS Addition factor for leaf death due to nutrient stress SCr d-1 RDRT Relative death rate of leaves due to temperature SCr d-1 RDRSHM Relative death rate of leaves due to self- shading SCr d-1 SLA_MAX Maximum specific leaf area SCr m2 leaf kg-1 leaf TSUMLIFE Temperature sum of leaf life above which leaf senescence due to ageing starts SCr |C| d WCWET Soil moisture content above which oxyen stress occurs. SCr cm3 water cm-3 ground ================= ============================================== ====== =========================== **State variables** ================= ============================================== ====== =========================== Name Description Pbl Unit ================= ============================================== ====== =========================== TSUMCROPLEAFAGE Physiological leaf age N |C| d WLVD Dry weight of senescened leaf dry matter Y g DM m-2 ground WSOFRACTRANSLO Amount of storage organ dry matter produced by translocation of senescenced leaf organ dry matter to storage organs. N g DM m-2 ground ================= ============================================== ====== =========================== **Rate variables** ================= ============================================== ====== =========================== Name Description Pbl Unit ================= ============================================== ====== =========================== DLAI Death rate of leaf area index Y m2 leaf m-2 ground d-1 DLV Death rate of leaf dry matter Y g DM m-2 d-1 RTSUMCROPLEAFAGE Rate of increase of crop physiological age Y |C| RWLVD Rate of increase of dead leaf dry matter Y g DM m-2 d-1 RWSOTRANSLSO Rate of increase of of storage organ dry matter produced by translocation of senescenced leaf organ dry matter to storage organs. Y g DM m-2 d-1 ================= ============================================== ====== =========================== """ class Parameters(ParamTemplate): FRACTLLFENHSH = Float() FRACSLATB = AfgenTrait() FASTRANSLSO = Float() LAICR = Float() RDRB = Float() RDRNS = Float() RDRT = AfgenTrait() RDRSHM = Float() SLA_MAX = Float() TSUMLLIFE = Float() WCWET = Float() class RateVariables(RatesTemplate): DLAI = Float() DLV = Float() RTSUMCROPLEAFAGE = Float() RWLVD = Float() RWSOFASTRANSLSO = Float() SLA = Float() class StateVariables(StatesTemplate): TSUMCROPLEAFAGE = Float() WLVD = Float() WSOFASTRANSLSO = Float() def initialize(self, day, kiosk, parameters): TSUMCROPLEAFAGE = 0. WLVD = 0. WSOFASTRANSLSO = 0. self.kiosk = kiosk self.params = self.Parameters(parameters) self.rates = self.RateVariables(kiosk, publish = [ "DLAI", "DLV", "RTSUMCROPLEAFAGE", "RWLVD", "RWSOFASTRANSLSO", "SLA"]) self.states = self.StateVariables( kiosk, publish=["WLVD"], TSUMCROPLEAFAGE = TSUMCROPLEAFAGE, WLVD = WLVD, WSOFASTRANSLSO = WSOFASTRANSLSO ) def calc_rates(self, day, drv, delt=1): k = self.kiosk p = self.params r = self.rates s = self.states # -------- AGE # The calculation of the physiological leaf age. RTSUMCROPLEAFAGE = k.DTEFF * k.EMERG - (s.TSUMCROPLEAFAGE / delt) * k.PUSHREDIST # Deg. C # Relative death rate due to aging depending on leaf age and the daily average temperature. if s.TSUMCROPLEAFAGE - p.TSUMLLIFE >= 0: RDRDV = p.RDRT(drv.TEMP) else: RDRDV = 0 # -------- SHEDDING # Relative death rate due to self shading, depending on a critical leaf area index at which leaf shedding is # induced. Leaf shedding is limited to a maximum leaf shedding per day. RDRSH1 = p.RDRSHM * (k.LAI-p.LAICR) / p.LAICR # d-1 if (RDRSH1 < 0): RDRSH = 0 # d-1 elif RDRSH1 >= p.RDRSHM: RDRSH = p.RDRSHM # d-1 else: RDRSH = RDRSH1 # -------- DROUGHT # ENSHED triggers enhanced leaf senescence due to severe drought or excessive soil water. It assumes that drought or # excessive water does not affect young leaves. It only affects leaves that have a reached a given fraction of the leaf # age. if k.SM - k.WCSD >= 0: ENHSHED1 = 0 else: ENHSHED1 = 1 if k.SM - p.WCWET >= 0: ENHSHED2 = 1 else: ENHSHED2 = 0 if (s.TSUMCROPLEAFAGE - p.FRACTLLFENHSH * p.TSUMLLIFE) >= 0: ENHSHED3 = 1 else: ENHSHED3 = 0 ENHSHED = max(ENHSHED1, ENHSHED2) * ENHSHED3 # Relative death rate due to severe drought RDRSD = p.RDRB * ENHSHED # d-1 # -------- # -------- NUTRIENT LIMITATION # Leaf death due to nutrient limitation is added on top op the relative death rate due to age, shade # and drought. RDRNS = p.RDRNS * (1-k.NPKI) # d-1 # -------- # Effective relative death rate and the resulting decrease in LAI. Leaf death can only occur, when # the leaves are old enough. if s.TSUMCROPLEAFAGE - p.TSUMLLIFE >= 0: RDR = (max(RDRDV, RDRSH, RDRSD) + RDRNS) else: RDR = 0. DLAI = k.LAI * RDR * (1 - k.DORMANCY) # m2 m-2 d-1 # Fraction of the maximum specific leaf area index depending on the temperature sum of the crop. And its specific leaf # area index. FRACSLACROPAGE = p.FRACSLATB(k.TSUMCROP) SLA = p.SLA_MAX * FRACSLACROPAGE # m2 g-1 DM # The rate of storage root DM production with DM supplied by the leaves before abscission. RWSOFASTRANSLSO = k.WLVG * RDR * p.FASTRANSLSO * (1 - k.DORMANCY) # g storage root DM m-2 d-1 # Decrease in leaf weight due to leaf senesence. DLV = k.WLVG * RDR * (1 - k.DORMANCY) # g leaves DM m-2 d-1 RWLVD = (DLV - RWSOFASTRANSLSO) # g leaves DM m-2 d-1 r.DLAI = DLAI r.DLV = DLV r.RTSUMCROPLEAFAGE = RTSUMCROPLEAFAGE r.RWLVD = RWLVD r.RWSOFASTRANSLSO = RWSOFASTRANSLSO r.SLA = SLA def integrate(self, day, delt = 1): r = self.rates s = self.states s.WLVD += r.RWLVD s.WSOFASTRANSLSO += r.RWSOFASTRANSLSO s.TSUMCROPLEAFAGE += r.RTSUMCROPLEAFAGE