Source code for pcse.crop.root_dynamics

# -*- coding: utf-8 -*-
# Copyright (c) 2004-2014 Alterra, Wageningen-UR
# Allard de Wit (allard.dewit@wur.nl), April 2014
from copy import deepcopy

from ..traitlets import Float, Int, Instance, AfgenTrait
from ..decorators import prepare_rates, prepare_states
from ..util import limit, merge_dict
from ..base_classes import ParamTemplate, StatesTemplate, RatesTemplate, \
    SimulationObject, VariableKiosk

#-------------------------------------------------------------------------------
[docs]class WOFOST_Root_Dynamics(SimulationObject): """Root biomass dynamics and rooting depth. Root growth and root biomass dynamics in WOFOST are separate processes, with the only exception that root growth stops when no more biomass is sent to the root system. Root biomass increase results from the assimilates partitioned to the root system. Root death is defined as the current root biomass multiplied by a relative death rate (`RDRRTB`). The latter as a function of the development stage (`DVS`). Increase in root depth is a simple linear expansion over time unti the maximum rooting depth (`RDM`) is reached. **Simulation parameters** ======= ============================================= ======= ============ Name Description Type Unit ======= ============================================= ======= ============ RDI Initial rooting depth SCr cm RRI Daily increase in rooting depth SCr |cm day-1| RDMCR Maximum rooting depth of the crop SCR cm RDMSOL Maximum rooting depth of the soil SSo cm TDWI Initial total crop dry weight SCr |kg ha-1| IAIRDU Presence of air ducts in the root (1) or SCr - not (0) RDRRTB Relative death rate of roots as a function TCr - of development stage ======= ============================================= ======= ============ **State variables** ======= ================================================= ==== ============ Name Description Pbl Unit ======= ================================================= ==== ============ RD Current rooting depth Y cm RDM Maximum attainable rooting depth at the minimum N cm of the soil and crop maximum rooting depth WRT Weight of living roots Y |kg ha-1| DWRT Weight of dead roots N |kg ha-1| TWRT Total weight of roots Y |kg ha-1| ======= ================================================= ==== ============ **Rate variables** ======= ================================================= ==== ============ Name Description Pbl Unit ======= ================================================= ==== ============ RR Growth rate root depth N cm GRRT Growth rate root biomass N |kg ha-1 d-1| DRRT Death rate root biomass N |kg ha-1 d-1| GWRT Net change in root biomass N |kg ha-1 d-1| ======= ================================================= ==== ============ **Signals send or handled** None **External dependencies:** ======= =================================== ================= ============ Name Description Provided by Unit ======= =================================== ================= ============ DVS Crop development stage DVS_Phenology - DMI Total dry matter CropSimulation |kg ha-1 d-1| increase FR Fraction biomass to roots DVS_Partitioning - ======= =================================== ================= ============ """
[docs] class Parameters(ParamTemplate): """Traits-based class for storing rooting depth parameters """ RDI = Float(-99.) RRI = Float(-99.) RDMCR = Float(-99.) RDMSOL = Float(-99.) TDWI = Float(-99.) IAIRDU = Float(-99) RDRRTB = AfgenTrait()
class RateVariables(RatesTemplate): RR = Float(-99.) GRRT = Float(-99.) DRRT = Float(-99.) GWRT = Float(-99.) class StateVariables(StatesTemplate): RD = Float(-99.) RDM = Float(-99.) WRT = Float(-99.) DWRT = Float(-99.) TWRT = Float(-99.)
[docs] def initialize(self, day, kiosk, parvalues): """ :param day: start date of the simulation :param kiosk: variable kiosk of this PCSE instance :param parvalues: `ParameterProvider` object providing parameters as key/value pairs """ self.params = self.Parameters(parvalues) self.rates = self.RateVariables(kiosk, publish="DRRT") self.kiosk = kiosk # INITIAL STATES params = self.params # Initial root depth states rdmax = max(params.RDI, min(params.RDMCR, params.RDMSOL)) RDM = rdmax RD = params.RDI # initial root biomass states FR = self.kiosk["FR"] WRT = params.TDWI * FR DWRT = 0. TWRT = WRT + DWRT self.states = self.StateVariables(kiosk, publish=["RD","WRT","TWRT"], RD=RD, RDM=RDM, WRT=WRT, DWRT=DWRT, TWRT=TWRT)
@prepare_rates def calc_rates(self, day, drv): params = self.params rates = self.rates states = self.states # Increase in root biomass DMI = self.kiosk["DMI"] DVS = self.kiosk["DVS"] FR = self.kiosk["FR"] rates.GRRT = FR * DMI rates.DRRT = states.WRT * params.RDRRTB(DVS) rates.GWRT = rates.GRRT - rates.DRRT # Increase in root depth rates.RR = min((states.RDM - states.RD), params.RRI) # Do not let the roots growth if partioning to the roots # (variable FR) is zero. if FR == 0.: rates.RR = 0. @prepare_states def integrate(self, day, delt=1.0): rates = self.rates states = self.states # Dry weight of living roots states.WRT += rates.GWRT # Dry weight of dead roots states.DWRT += rates.DRRT # Total weight dry + living roots states.TWRT = states.WRT + states.DWRT # New root depth states.RD += rates.RR
class Simple_Root_Dynamics(SimulationObject): """Simple class for linear root growth. Increase in root depth is a simple linear expansion over time until the maximum rooting depth (`RDM`) is reached. **Simulation parameters** ======= ============================================= ======= ============ Name Description Type Unit ======= ============================================= ======= ============ RDI Initial rooting depth SCr cm RRI Daily increase in rooting depth SCr |cm day-1| RDMCR Maximum rooting depth of the crop SCR cm RDMSOL Maximum rooting depth of the soil SSo cm ======= ============================================= ======= ============ **State variables** ======= ================================================= ==== ============ Name Description Pbl Unit ======= ================================================= ==== ============ RD Current rooting depth Y cm RDM Maximum attainable rooting depth at the minimum N cm of the soil and crop maximum rooting depth ======= ================================================= ==== ============ **Rate variables** ======= ================================================= ==== ============ Name Description Pbl Unit ======= ================================================= ==== ============ RR Growth rate root depth N cm ======= ================================================= ==== ============ **Signals send or handled** None **External dependencies:** None """ class Parameters(ParamTemplate): """Traits-based class for storing rooting depth parameters """ RDI = Float(-99.) RRI = Float(-99.) RDMCR = Float(-99.) RDMSOL = Float(-99.) class RateVariables(RatesTemplate): RR = Float(-99.) class StateVariables(StatesTemplate): RD = Float(-99.) RDM = Float(-99.) def initialize(self, day, kiosk, cropdata, soildata): """ :param day: start date of the simulation :param kiosk: variable kiosk of this PCSE instance :param cropdata: dictionary with WOFOST cropdata key/value pairs :param soildata: dictionary with WOFOST soildata key/value pairs """ # Merge cropdata and soildata dictionaries in order to pass them to # the Parameters class. parvalues = merge_dict(cropdata, soildata) self.params = self.Parameters(parvalues) self.rates = self.RateVariables(kiosk) self.kiosk = kiosk # INITIAL STATES params = self.params # Initial root depth states rdmax = max(params.RDI, min(params.RDMCR, params.RDMSOL)) RDM = rdmax RD = params.RDI self.states = self.StateVariables(kiosk, publish=["RD"], RD=RD, RDM=RDM) @prepare_rates def calc_rates(self, day, drv): params = self.params rates = self.rates states = self.states # Increase in root depth rates.RR = min((states.RDM - states.RD), params.RRI) @prepare_states def integrate(self, day, delt=1.0): rates = self.rates states = self.states # New root depth states.RD += rates.RR