コード例 #1
0
 def update_water_storage(self, tolerance=1E-08):
     """ Calculate root and top soil plant available water and runoff.
     
     Soil drainage is estimated using a "leaky-bucket" approach with two
     soil layers. In reality this is a combined drainage and runoff 
     calculation, i.e. "outflow". There is no drainage out of the "bucket" 
     soil. 
     
     Returns:
     --------
     outflow : float
         outflow [mm d-1]
     """
     # reduce transpiration from the top soil if it is dry
     trans_frac = (self.params.fractup_soil * self.state.wtfac_topsoil)
     
     # Total soil layer
     self.state.pawater_topsoil += (self.fluxes.erain -
                                   (self.fluxes.transpiration *
                                    trans_frac) -
                                    self.fluxes.soil_evap)
     
     
     self.state.pawater_topsoil = clip(self.state.pawater_topsoil, min=0.0,
                                       max=self.params.wcapac_topsoil) 
     
     # Total root zone
     previous = self.state.pawater_root
     self.state.pawater_root += (self.fluxes.erain -
                                 self.fluxes.transpiration -
                                 self.fluxes.soil_evap)
     
     # calculate runoff and remove any excess from rootzone
     if self.state.pawater_root > self.params.wcapac_root:
         runoff = self.state.pawater_root - self.params.wcapac_root
         self.state.pawater_root -= runoff 
     else:
         runoff = 0.0
     
     if float_le(self.state.pawater_root, 0.0):
         self.fluxes.transpiration = 0.0
         self.fluxes.soil_evap = 0.0
         self.fluxes.et = self.fluxes.interception
      
     self.state.pawater_root = clip(self.state.pawater_root, min=0.0,
                                    max=self.params.wcapac_root)
     
     
     self.state.delta_sw_store = self.state.pawater_root - previous
     
     return runoff 
コード例 #2
0
ファイル: water_balance.py プロジェクト: joathert/pygday
    def update_water_storage(self, tolerance=1e-08):
        """ Calculate root and top soil plant available water and runoff.
        
        Soil drainage is estimated using a "leaky-bucket" approach with two
        soil layers. In reality this is a combined drainage and runoff 
        calculation, i.e. "outflow". There is no drainage out of the "bucket" 
        soil. 
        
        Returns:
        --------
        outflow : float
            outflow [mm d-1]
        """
        # reduce transpiration from the top soil if it is dry
        trans_frac = self.params.fractup_soil * self.state.wtfac_topsoil

        # Total soil layer
        self.state.pawater_topsoil += (
            self.fluxes.erain - (self.fluxes.transpiration * trans_frac) - self.fluxes.soil_evap
        )

        self.state.pawater_topsoil = clip(self.state.pawater_topsoil, min=0.0, max=self.params.wcapac_topsoil)

        # Total root zone
        previous = self.state.pawater_root
        self.state.pawater_root += self.fluxes.erain - self.fluxes.transpiration - self.fluxes.soil_evap

        # calculate runoff and remove any excess from rootzone
        if self.state.pawater_root > self.params.wcapac_root:
            runoff = self.state.pawater_root - self.params.wcapac_root
            self.state.pawater_root -= runoff
        else:
            runoff = 0.0

        if float_le(self.state.pawater_root, 0.0):
            self.fluxes.transpiration = 0.0
            self.fluxes.soil_evap = 0.0
            self.fluxes.et = self.fluxes.interception

        self.state.pawater_root = clip(self.state.pawater_root, min=0.0, max=self.params.wcapac_root)

        self.state.delta_sw_store = self.state.pawater_root - previous

        return runoff
コード例 #3
0
ファイル: plant_growth.py プロジェクト: kelvinn/GDAY
    def calc_carbon_allocation_fracs(self, nitfac):
        """Carbon allocation fractions to move photosynthate through the plant.

        Parameters:
        -----------
        nitfac : float
            leaf N:C as a fraction of 'Ncmaxfyoung' (max 1.0)

        Returns:
        --------
        alleaf : float
            allocation fraction for shoot
        alroot : float
            allocation fraction for fine roots
        albranch : float
            allocation fraction for branches
        alstem : float
            allocation fraction for stem
       
        References:
        -----------
        Corbeels, M. et al (2005) Ecological Modelling, 187, 449-474.
        McMurtrie, R. E. et al (2000) Plant and Soil, 224, 135-152.
        
        """
        if self.control.alloc_model == "FIXED":
        
            self.fluxes.alleaf = (self.params.c_alloc_fmax + nitfac *
                                 (self.params.c_alloc_fmax - 
                                 self.params.c_alloc_fmin))
            
            self.fluxes.alroot = (self.params.c_alloc_rmax + nitfac *
                                 (self.params.c_alloc_rmax - 
                                 self.params.c_alloc_rmin))

            self.fluxes.albranch = (self.params.c_alloc_bmax + nitfac *
                                   (self.params.c_alloc_bmax - 
                                   self.params.c_alloc_bmin))
        
            # allocate remainder to stem
            self.fluxes.alstem = (1.0 - self.fluxes.alleaf - 
                                  self.fluxes.alroot - 
                                  self.fluxes.albranch)
            
            self.fluxes.alcroot = self.params.c_alloc_cmax * self.fluxes.alstem
            self.fluxes.alstem -= self.fluxes.alcroot
            
        elif self.control.alloc_model == "GRASSES":
            
            # if combining grasses with the deciduous model this calculation
            # is done only during the leaf out period. See above.
            if not self.control.deciduous_model:
                self.calculate_growth_stress_limitation()
            
            # figure out root allocation given available water & nutrients
            # hyperbola shape to allocation
            min_root_alloc = 0.4
            self.fluxes.alroot = (self.params.c_alloc_rmax * 
                                  min_root_alloc / 
                                 (min_root_alloc + 
                                 (self.params.c_alloc_rmax - 
                                  min_root_alloc) * 
                                  self.state.prev_sma))
            
            self.fluxes.alstem = 0.0
            self.fluxes.albranch = 0.0
            self.fluxes.alcroot = 0.0
            self.fluxes.alleaf = (1.0 - self.fluxes.alroot)
            
        elif self.control.alloc_model == "ALLOMETRIC":
            
            if not self.control.deciduous_model:
                self.calculate_growth_stress_limitation()
            else:
                # reset the buffer at the end of the growing season
                self.sma.reset_stream()
                
            # figure out root allocation given available water & nutrients
            # hyperbola shape to allocation
            min_root_alloc = 0.1
            self.fluxes.alroot = (self.params.c_alloc_rmax * 
                                  min_root_alloc / 
                                 (min_root_alloc + 
                                 (self.params.c_alloc_rmax - 
                                  min_root_alloc) * 
                                  self.state.prev_sma))
            
            #self.fluxes.alroot = (self.params.c_alloc_rmin + 
            #                    (self.params.c_alloc_rmax - 
            #                     self.params.c_alloc_rmin) * 
            #                     self.state.prev_sma)
            
            
            # Calculate tree height: allometric reln using the power function 
            # (Causton, 1985)
            self.state.canht = (self.params.heighto * 
                                self.state.stem**self.params.htpower)

            # LAI to stem sapwood cross-sectional area (As m-2 m-2) 
            # (dimensionless)
            # Assume it varies between LS0 and LS1 as a linear function of tree
            # height (m) 
            arg1 = self.state.sapwood * const.TONNES_AS_KG * const.M2_AS_HA
            arg2 = self.state.canht * self.params.density * self.params.cfracts
            sap_cross_sec_area = arg1 / arg2
            
            if not self.control.deciduous_model:
                leaf2sap = self.state.lai / sap_cross_sec_area
            else:
                leaf2sap = self.state.max_lai / sap_cross_sec_area

            # Allocation to leaves dependant on height. Modification of pipe 
            # theory, leaf-to-sapwood ratio is not constant above a certain 
            # height, due to hydraulic constraints (Magnani et al 2000; Deckmyn
            # et al. 2006).
            
            if float_le(self.state.canht, self.params.height0):
                leaf2sa_target = self.params.leafsap0
            elif float_ge(self.state.canht, self.params.height1):
                leaf2sa_target = self.params.leafsap1
            else:
                arg1 = self.params.leafsap0
                arg2 = self.params.leafsap1 - self.params.leafsap0
                arg3 = self.state.canht - self.params.height0
                arg4 = self.params.height1 - self.params.height0
                leaf2sa_target = arg1 + (arg2 * arg3 / arg4) 
                
            self.fluxes.alleaf = self.alloc_goal_seek(leaf2sap, leaf2sa_target, 
                                                      self.params.c_alloc_fmax, 
                                                      self.params.targ_sens) 
            
            
            # Allocation to branch dependent on relationship between the stem
            # and branch
            target_branch = (self.params.branch0 * 
                             self.state.stem**self.params.branch1)
            self.fluxes.albranch = self.alloc_goal_seek(self.state.branch, 
                                                       target_branch, 
                                                       self.params.c_alloc_bmax, 
                                                       self.params.targ_sens) 
            
            coarse_root_target = (self.params.croot0 * 
                                  self.state.stem**self.params.croot1)
            self.fluxes.alcroot = self.alloc_goal_seek(self.state.croot, 
                                                       coarse_root_target, 
                                                       self.params.c_alloc_cmax, 
                                                       self.params.targ_sens) 
            
            self.fluxes.alstem = (1.0 - self.fluxes.alroot - 
                                        self.fluxes.albranch - 
                                        self.fluxes.alleaf -
                                        self.fluxes.alcroot)
            
            
            # allocation to stem is the residual
            #self.fluxes.alstem = (1.0 - self.fluxes.alroot - 
            #                            self.fluxes.albranch - 
            #                            self.fluxes.alleaf)
            #self.fluxes.alcroot = 0.2 * self.fluxes.alstem
            #self.fluxes.alstem -= self.fluxes.alcroot
            
            # Because I have allowed the max fracs sum > 1, possibility
            # stem frac would be negative. Perhaps the above shouldn't be 
            # allowed...? But this will stop wood allocation in such a 
            # situation.
            #if self.fluxes.alstem < 0.0:
            #    extra = self.fluxes.alstem
            #    self.fluxes.alstem = 0.0
            #    self.fluxes.alleaf -= extra
            
            # minimum allocation to leaves - without it tree would die, as this
            # is done annually.
            if self.control.deciduous_model:
                if self.fluxes.alleaf < 0.1:
                    min_leaf_alloc = 0.1
                    self.fluxes.alstem -= min_leaf_alloc
                    self.fluxes.alleaf = min_leaf_alloc
            
        else:
            raise AttributeError('Unknown C allocation model')
        
        #print self.fluxes.alleaf, self.fluxes.alstem, self.fluxes.albranch, \
        #       self.fluxes.alroot, self.state.prev_sma, self.state.canht
        
        
        
        # Total allocation should be one, if not print warning:
        total_alloc = (self.fluxes.alroot + self.fluxes.alleaf + 
                       self.fluxes.albranch + self.fluxes.alstem + 
                       self.fluxes.alcroot)
        if float_gt(total_alloc, 1.0):
            raise RuntimeError, "Allocation fracs > 1"