Exemplo n.º 1
0
    def main(self,
             tair,
             par,
             vpd,
             wind,
             pressure,
             Ca,
             doy,
             hod,
             lat,
             lon,
             LAI,
             rnet=None):
        """
        Parameters:
        ----------
        tair : float
            air temperature (deg C)
        par : float
            Photosynthetically active radiation (umol m-2 s-1)
        vpd : float
            Vapour pressure deficit (kPa, needs to be in Pa, see conversion
            below)
        wind : float
            wind speed (m s-1)
        pressure : float
            air pressure (using constant) (Pa)
        Ca : float
            ambient CO2 concentration
        doy : float
            day of day
        hod : float
            hour of day
        lat : float
            latitude
        lon : float
            longitude
        lai : floar
            leaf area index

        Returns:
        --------
        An : float
            net leaf assimilation (umol m-2 s-1)
        gs : float
            stomatal conductance (mol m-2 s-1)
        et : float
            transpiration (mol H2O m-2 s-1)
        """

        F = FarquharC3(theta_J=0.85,
                       peaked_Jmax=True,
                       peaked_Vcmax=True,
                       model_Q10=True,
                       gs_model=self.gs_model,
                       gamma=self.gamma,
                       g0=self.g0,
                       g1=self.g1,
                       D0=self.D0,
                       alpha=self.alpha)
        P = PenmanMonteith(self.leaf_width, self.SW_abs)

        # set initial values
        dleaf = vpd
        Cs = Ca
        Tleaf = tair
        Tleaf_K = Tleaf + c.DEG_2_KELVIN

        cos_zenith = calculate_solar_geometry(doy, hod, lat, lon)
        zenith_angle = np.rad2deg(np.arccos(cos_zenith))
        elevation = 90.0 - zenith_angle

        # Is the sun up?
        if elevation > 0.0 and par > 50.0:

            iter = 0
            while True:
                (An, gsc) = F.photosynthesis(Cs=Cs,
                                             Tleaf=Tleaf_K,
                                             Par=par,
                                             Jmax25=self.Jmax25,
                                             Vcmax25=self.Vcmax25,
                                             Q10=self.Q10,
                                             Eaj=self.Eaj,
                                             Eav=self.Eav,
                                             deltaSj=self.deltaSj,
                                             deltaSv=self.deltaSv,
                                             Rd25=self.Rd25,
                                             Hdv=self.Hdv,
                                             Hdj=self.Hdj,
                                             vpd=dleaf)

                # Calculate new Tleaf, dleaf, Cs
                (new_tleaf, et, le_et, gbH,
                 gw) = self.calc_leaf_temp(P,
                                           Tleaf,
                                           tair,
                                           gsc,
                                           par,
                                           vpd,
                                           pressure,
                                           wind,
                                           rnet=rnet)

                gbc = gbH * c.GBH_2_GBC
                if gbc > 0.0 and An > 0.0:
                    Cs = Ca - An / gbc  # boundary layer of leaf
                else:
                    Cs = Ca

                if np.isclose(et, 0.0) or np.isclose(gw, 0.0):
                    dleaf = vpd
                else:
                    dleaf = (et * pressure / gw) * c.PA_2_KPA  # kPa

                # Check for convergence...?
                if math.fabs(Tleaf - new_tleaf) < 0.02:
                    break

                if iter > self.iter_max:
                    #raise Exception('No convergence: %d' % (iter))
                    An = 0.0
                    gsc = 0.0
                    et = 0.0
                    break

                # Update temperature & do another iteration
                Tleaf = new_tleaf
                Tleaf_K = Tleaf + c.DEG_2_KELVIN

                iter += 1

            an_canopy = An * LAI
            gsw_canopy = gsc * c.GSC_2_GSW * LAI
            et_canopy = et * LAI
            tcanopy = Tleaf
        else:
            an_canopy = 0.0
            gsw_canopy = 0.0
            et_canopy = 0.0
            tcanopy = tair

        return (an_canopy, gsw_canopy, et_canopy, tcanopy)
Exemplo n.º 2
0
def main():

    lat = -23.575001
    lon = 152.524994
    doy = 180.0
    #
    ## Met data ...
    #
    (par, tair, vpd) = get_met_data(lat, lon, doy)
    wind = 2.5
    pressure = 101325.0
    Ca = 400.0

    # more realistic VPD
    rh = 40.
    esat = calc_esat(tair)
    ea = rh / 100. * esat
    vpd = (esat - ea) * c.PA_2_KPA
    vpd = np.where(vpd < 0.05, 0.05, vpd)

    #plt.plot(vpd)
    #plt.show()
    #sys.exit()

    ## Parameters
    #
    g0 = 0.001
    g1 = 1.5635  # Puechabon
    D0 = 1.5  # kpa
    Vcmax25 = 60.0
    Jmax25 = Vcmax25 * 1.67
    Rd25 = 2.0
    Eaj = 30000.0
    Eav = 60000.0
    deltaSj = 650.0
    deltaSv = 650.0
    Hdv = 200000.0
    Hdj = 200000.0
    Q10 = 2.0
    gamma = 0.0
    leaf_width = 0.02
    LAI = 3.

    # Cambell & Norman, 11.5, pg 178
    # The solar absorptivities of leaves (-0.5) from Table 11.4 (Gates, 1980)
    # with canopies (~0.8) from Table 11.2 reveals a surprising difference.
    # The higher absorptivityof canopies arises because of multiple reflections
    # among leaves in a canopy and depends on the architecture of the canopy.
    SW_abs = 0.8  # use canopy absorptance of solar radiation

    ##
    ### Run Big-leaf
    ##

    B = BigLeaf(g0,
                g1,
                D0,
                gamma,
                Vcmax25,
                Jmax25,
                Rd25,
                Eaj,
                Eav,
                deltaSj,
                deltaSv,
                Hdv,
                Hdj,
                Q10,
                leaf_width,
                SW_abs,
                gs_model="medlyn")

    An_bl = np.zeros(48)
    gsw_bl = np.zeros(48)
    et_bl = np.zeros(48)
    tcan_bl = np.zeros(48)

    hod = 0
    for i in range(len(par)):

        (An_bl[i], gsw_bl[i], et_bl[i],
         tcan_bl[i]) = B.main(tair[i], par[i], vpd[i], wind, pressure, Ca, doy,
                              hod, lat, lon, LAI)

        hod += 1

    ##
    ### Run 2-leaf
    ##

    T = TwoLeaf(g0,
                g1,
                D0,
                gamma,
                Vcmax25,
                Jmax25,
                Rd25,
                Eaj,
                Eav,
                deltaSj,
                deltaSv,
                Hdv,
                Hdj,
                Q10,
                leaf_width,
                SW_abs,
                gs_model="medlyn")

    An_tl = np.zeros(48)
    gsw_tl = np.zeros(48)
    et_tl = np.zeros(48)
    tcan_tl = np.zeros(48)

    hod = 0
    for i in range(len(par)):

        (An_tl[i], gsw_tl[i], et_tl[i],
         tcan_tl[i]) = T.main(tair[i], par[i], vpd[i], wind, pressure, Ca, doy,
                              hod, lat, lon, LAI)

        hod += 1

    ##
    ### Run 2-leaf opt
    ##

    T = TwoLeafOpt(g0,
                   g1,
                   D0,
                   gamma,
                   Vcmax25,
                   Jmax25,
                   Rd25,
                   Eaj,
                   Eav,
                   deltaSj,
                   deltaSv,
                   Hdv,
                   Hdj,
                   Q10,
                   leaf_width,
                   SW_abs,
                   gs_model="medlyn")

    An_tlo = np.zeros(48)
    gsw_tlo = np.zeros(48)
    et_tlo = np.zeros(48)
    tcan_tlo = np.zeros(48)

    hod = 0
    for i in range(len(par)):

        (An_tlo[i], gsw_tlo[i], et_tlo[i],
         tcan_tlo[i]) = T.main(tair[i], par[i], vpd[i], wind, pressure, Ca,
                               doy, hod, lat, lon, LAI)

        hod += 1

    ##
    ### Run 2-leaf Manon
    ##

    Ao = np.zeros(48)
    gso = np.zeros(48)
    Eo = np.zeros(48)

    Aob = np.zeros(48)
    gsob = np.zeros(48)
    Eob = np.zeros(48)

    hod = 0
    for i in range(len(par)):

        cos_zenith = calculate_solar_geometry(doy, hod, lat, lon)
        zenith_angle = np.rad2deg(np.arccos(cos_zenith))
        elevation = 90.0 - zenith_angle
        if elevation > 0.0 and par[i] > 50.0:

            p = declared_params()

            p.PPFD = par[i]
            p.sw_rad_day = par[i] * c.PAR_2_SW
            p.LAI = LAI
            p.coszen = cos_zenith
            p.VPD = vpd[i]
            p.precip = 0
            p.Tair = tair[i]
            p.Vmax25 = Vcmax25
            p.g1 = g1
            p.CO2 = Ca / 1000 * 101.325
            p.JV = 1.67
            p.Rlref = Rd25
            p.Ej = Eaj
            p.Ev = Eav
            p.deltaSv = deltaSv
            p.deltaSj = deltaSj
            p.max_leaf_width = leaf_width
            p.gamstar25 = 4.33  # 42.75 / 101.25 umol m-2 s-1
            p.Kc25 = 41.0264925  # 404.9 umol m-2 s-1
            p.Ko25 = 28208.88  # 278.4 mmol mol-1
            p.O2 = 21.27825  # 210 *1000. / 101.25 210 mmol mol-1
            p.alpha = 0.3
            p.albedo = 0.2
            p.Egamstar = 37830.0
            p.Ec = 79430.0
            p.Eo = 36380.0
            p.P50 = 2.02  # Puechabon
            p.P88 = 4.17
            p.kmax = 0.862457122856143

            _, _, fscale2can = absorbed_radiation_2_leaves(p)
            p = p.append(pd.Series([np.nansum(fscale2can)], index=['fscale']))

            Eo[i], gso[i], Ao[i], __, __ = solve_std(p, p.fc, photo='Farquhar')

            #"""
            try:
                fstom_opt_psi, Eo[i], gso[i], Ao[i], _, _ = profit_psi(
                    p, photo='Farquhar', res='med', case=2)
                p = p.append(
                    pd.Series([fstom_opt_psi], index=['fstom_opt_psi']))

            except (ValueError, AttributeError):
                (Eo[i], gso[i], Ao[i]) = (0., 0., 0.)

            #"""

        hod += 1

    fig = plt.figure(figsize=(16, 4))
    fig.subplots_adjust(hspace=0.1)
    fig.subplots_adjust(wspace=0.2)
    plt.rcParams['text.usetex'] = False
    plt.rcParams['font.family'] = "sans-serif"
    plt.rcParams['font.sans-serif'] = "Helvetica"
    plt.rcParams['axes.labelsize'] = 14
    plt.rcParams['font.size'] = 14
    plt.rcParams['legend.fontsize'] = 10
    plt.rcParams['xtick.labelsize'] = 14
    plt.rcParams['ytick.labelsize'] = 14

    almost_black = '#262626'
    # change the tick colors also to the almost black
    plt.rcParams['ytick.color'] = almost_black
    plt.rcParams['xtick.color'] = almost_black

    # change the text colors also to the almost black
    plt.rcParams['text.color'] = almost_black

    # Change the default axis colors from black to a slightly lighter black,
    # and a little thinner (0.5 instead of 1)
    plt.rcParams['axes.edgecolor'] = almost_black
    plt.rcParams['axes.labelcolor'] = almost_black

    ax1 = fig.add_subplot(131)
    ax2 = fig.add_subplot(132)
    ax3 = fig.add_subplot(133)

    #ax1.plot(np.arange(48)/2., An_bl, label="Big leaf")
    ax1.plot(np.arange(48) / 2., An_tl, label="Two leaf")
    ax1.plot(np.arange(48) / 2., An_tlo, label="Two leaf Opt")
    ax1.plot(np.arange(48) / 2., Ao, label="Two leaf Manon")
    ax1.legend(numpoints=1, loc="best")
    ax1.set_ylabel("$A_{\mathrm{n}}$ ($\mathrm{\mu}$mol m$^{-2}$ s$^{-1}$)")

    #ax2.plot(np.arange(48)/2., et_bl * c.MOL_TO_MMOL, label="Big leaf")
    ax2.plot(np.arange(48) / 2., et_tl * c.MOL_TO_MMOL, label="Two leaf")
    ax2.plot(np.arange(48) / 2., et_tlo * c.MOL_TO_MMOL, label="Two leaf opt")
    ax2.plot(np.arange(48) / 2., Eo, label="Two leaf Manon")
    ax2.set_ylabel("E (mmol m$^{-2}$ s$^{-1}$)")
    ax2.set_xlabel("Hour of day")

    #ax3.plot(np.arange(48)/2., tcan_bl, label="Tcanopy$_{1leaf}$")
    ax3.plot(np.arange(48) / 2., tcan_tl, label="Tcanopy$_{2leaf}$")
    ax3.plot(np.arange(48) / 2., tair, label="Tair")
    ax3.set_ylabel("Temperature (deg C)")
    ax3.legend(numpoints=1, loc="best")

    ax1.locator_params(nbins=6, axis="y")
    ax2.locator_params(nbins=6, axis="y")

    plt.show()
    fig.savefig("/Users/%s/Desktop/A_E_Tcan.pdf" % (os.getlogin()),
                bbox_inches='tight',
                pad_inches=0.1)
    def main(self,
             tair,
             par,
             vpd,
             wind,
             pressure,
             Ca,
             doy,
             hod,
             lat,
             lon,
             lai,
             rnet=None):
        """
        Parameters:
        ----------
        tair : float
            air temperature (deg C)
        par : float
            Photosynthetically active radiation (umol m-2 s-1)
        vpd : float
            Vapour pressure deficit (kPa, needs to be in Pa, see conversion
            below)
        wind : float
            wind speed (m s-1)
        pressure : float
            air pressure (using constant) (Pa)
        Ca : float
            ambient CO2 concentration
        doy : float
            day of day
        hod : float
            hour of day
        lat : float
            latitude
        lon : float
            longitude
        lai : floar
            leaf area index

        Returns:
        --------
        An : float
            net leaf assimilation (umol m-2 s-1)
        gs : float
            stomatal conductance (mol m-2 s-1)
        et : float
            transpiration (mol H2O m-2 s-1)
        """

        F = FarquharC3(theta_J=0.85,
                       peaked_Jmax=True,
                       peaked_Vcmax=True,
                       model_Q10=True,
                       gs_model=self.gs_model,
                       gamma=self.gamma,
                       g0=self.g0,
                       g1=self.g1,
                       D0=self.D0,
                       alpha=self.alpha)
        P = PenmanMonteith(self.leaf_width, self.SW_abs)

        An = np.zeros(2)  # sunlit, shaded
        gsc = np.zeros(2)  # sunlit, shaded
        et = np.zeros(2)  # sunlit, shaded
        Tcan = np.zeros(2)  # sunlit, shaded

        cos_zenith = calculate_solar_geometry(doy, hod, lat, lon)
        zenith_angle = np.rad2deg(np.arccos(cos_zenith))
        elevation = 90.0 - zenith_angle
        sw_rad = par * c.PAR_2_SW  # W m-2

        # get diffuse/beam frac
        (diffuse_frac, direct_frac) = spitters(doy, sw_rad, cos_zenith)

        # Is the sun up?
        if elevation > 0.0 and par > 50.0:

            (apar, lai_leaf, kb) = calculate_absorbed_radiation_big_leaf(
                par, cos_zenith, lai, direct_frac, diffuse_frac)

            # Calculate scaling term to go from a single leaf to canopy,
            # see Wang & Leuning 1998 appendix C
            scalex = calc_leaf_to_canopy_scalar(lai, kb)

            # initialise values of Tleaf, Cs, dleaf at the leaf surface
            dleaf = vpd
            Cs = Ca
            Tleaf = tair
            Tleaf_K = Tleaf + c.DEG_2_KELVIN

            iter = 0
            while True:
                (An, gsc) = F.photosynthesis(Cs=Cs,
                                             Tleaf=Tleaf_K,
                                             Par=apar,
                                             Jmax25=self.Jmax25,
                                             Vcmax25=self.Vcmax25,
                                             Q10=self.Q10,
                                             Eaj=self.Eaj,
                                             Eav=self.Eav,
                                             deltaSj=self.deltaSj,
                                             deltaSv=self.deltaSv,
                                             Rd25=self.Rd25,
                                             Hdv=self.Hdv,
                                             Hdj=self.Hdj,
                                             vpd=dleaf,
                                             scalex=scalex)

                # Calculate new Tleaf, dleaf, Cs
                (new_tleaf, et, le_et, gbH,
                 gw) = self.calc_leaf_temp(P,
                                           Tleaf,
                                           tair,
                                           gsc,
                                           apar,
                                           vpd,
                                           pressure,
                                           wind,
                                           rnet=rnet,
                                           lai=lai)

                gbc = gbH * c.GBH_2_GBC
                if gbc > 0.0 and An > 0.0:
                    Cs = Ca - An / gbc  # boundary layer of leaf
                else:
                    Cs = Ca

                if math.isclose(et, 0.0) or math.isclose(gw, 0.0):
                    dleaf = vpd
                else:
                    dleaf = (et * pressure / gw) * c.PA_2_KPA  # kPa

                # Check for convergence...?
                if math.fabs(Tleaf - new_tleaf) < 0.02:
                    break

                if iter > self.iter_max:
                    raise Exception('No convergence: %d' % (iter))

                # Update temperature & do another iteration
                Tleaf = new_tleaf
                Tleaf_K = Tleaf + c.DEG_2_KELVIN
                Tcan = Tleaf

                iter += 1

            # scale to canopy: sum contributions from beam and diffuse leaves
            an_canopy = An
            gsw_canopy = gsc * c.GSC_2_GSW
            et_canopy = et
            tcanopy = Tleaf
        else:
            an_canopy = 0.0
            gsw_canopy = 0.0
            et_canopy = 0.0
            tcanopy = tair

        return (an_canopy, gsw_canopy, et_canopy, tcanopy)
Exemplo n.º 4
0
    ### Run Big-leaf
    ##

    C = CoupledModel(g0, g1, D0, gamma, Vcmax25, Jmax25, Rd25, Eaj, Eav,
                     deltaSj, deltaSv, Hdv, Hdj, Q10, leaf_width, SW_abs,
                     gs_model="medlyn")

    An_bl = np.zeros(48)
    gsw_bl = np.zeros(48)
    et_bl = np.zeros(48)
    tcan_bl = np.zeros(48)

    hod = 0
    for i in range(len(par)):

        cos_zenith = calculate_solar_geometry(doy, hod, lat, lon)
        zenith_angle = np.rad2deg(np.arccos(cos_zenith))
        elevation = 90.0 - zenith_angle
        if elevation > 0.0 and par[i] > 50.0:

            (An_bl[i], gsw_bl[i],
             et_bl[i], tcan_bl[i]) = C.main(tair[i], par[i], vpd[i],
                                            wind, pressure, Ca, doy, hod,
                                            lat, lon, LAI)

        hod += 1

    Ao = np.zeros(48)
    gso = np.zeros(48)
    Eo = np.zeros(48)