Beispiel #1
0
 def Vp(self, Vpmax, Cm, Kp):
     # PEP carboxylation rate, that is the rate of C4 acid generation
     Vp = (Cm * Vpmax) / (Cm + Kp / U(1, 'atm'))
     Vpr = U(80, 'umol/m^2/s CO2'
             )  # PEP regeneration limited Vp, value adopted from vC book
     Vp = clip(Vp, 0, Vpr)
     return Vp
Beispiel #2
0
class Weight:
    CO2 = U(44.0098, 'g / umol')
    C = U(12.0107, 'g / umol')
    CH2O = U(30.031, 'g / umol')
    H2O = U(18.01528, 'g / umol')

    C_to_CH2O_ratio = C / CH2O # 0.40
Beispiel #3
0
 def temperature_dependence_rate(self, Ea, T, Tb=U(25, 'degC')):
     R = U(8.314, 'J/K/mol')  # universal gas constant (J K-1 mol-1)
     #HACK handle too low temperature values during optimization
     Tk = clip(T, lower=0, unit='degK')
     Tbk = clip(Tb, lower=0, unit='degK')
     try:
         return np.exp(Ea * (T - Tb) / (Tbk * R * Tk))
     except ZeroDivisionError:
         return 0
Beispiel #4
0
    class S(System):
        @derive(unit='m')
        def a(self):
            return 2 * self.x

        @derive(unit='m')
        def b(self):
            return self.x + U(1, 'm')

        @optimize(lower=U(0, 'm'), upper=U(2, 'm'), unit='m')
        def x(self):
            return self.a - self.b
Beispiel #5
0
def test_unit():
    class S(System):
        @derive(unit='m')
        def a(self):
            return 2
        @derive(unit='s')
        def b(self):
            return 1
        @derive(unit='m/s')
        def c(self):
            return self.a / self.b
    s = instance(S)
    assert s.a == U(2, 'm') and s.b == U(1, 's') and s.c == U(2, 'm/s')
Beispiel #6
0
def test_parameter():
    class S(System):
        a = parameter(1, unit='m')
        b = parameter(1, unit='m')
        c = parameter(1, unit='m')
        d = parameter(1, unit='m')
        e = parameter(1)
        @parameter(unit='m')
        def f(self, ff='1m'):
            return self.a + ff
    s = instance(S, config={'S': {'a': 2, 'b': '2', 'c': '2m', 'd': '200cm', 'e': '2m'}})
    assert s.a == s.b == s.c == s.d == s.e == U(2, 'm')
    assert s.f == U(3, 'm')
Beispiel #7
0
    def temperature_adjustment(
            self,
            w='weather',
            s='stomata',
            # see Campbell and Norman (1998) pp 224-225
            # because Stefan-Boltzman constant is for unit surface area by denifition,
            # all terms including sbc are multilplied by 2 (i.e., gr, thermal radiation)
            lamda=U(44.0, 'kJ/mol'),  # KJ mole-1 at 25oC
            Cp=U(
                29.3, 'J/mol/degC'
            ),  # thermodynamic psychrometer constant and specific heat of air (J mol-1 C-1)
            epsilon=0.97,
            sbc=U(5.6697e-8,
                  'J/m^2/s/degK^4'),  # Stefan-Boltzmann constant (W m-2 K-4)
    ):
        T_air = w.T_air
        Tk = T_air.to('degK')
        PFD = w.PPFD
        P_air = w.P_air
        Jw = self.ET_supply

        gha = s.boundary_layer_conductance * (
            0.135 / 0.147
        )  # heat conductance, gha = 1.4*.135*sqrt(u/d), u is the wind speed in m/s} Mol m-2 s-1 ?
        gv = s.total_conductance_h2o
        gr = 4 * epsilon * sbc * Tk**3 / Cp * 2  # radiative conductance, 2 account for both sides
        ghr = gha + gr
        thermal_air = epsilon * sbc * Tk**4 * 2  # emitted thermal radiation
        psc = Cp / lamda  # psychrometric constant (C-1)
        psc1 = psc * ghr / gv  # apparent psychrometer constant

        PAR = U(PFD.to('umol/m^2/s Quanta').magnitude / 4.55,
                'J/m^2/s')  # W m-2
        # If total solar radiation unavailable, assume NIR the same energy as PAR waveband
        NIR = PAR
        scatt = 0.15
        # shortwave radiation (PAR (=0.85) + NIR (=0.15) solar radiation absorptivity of leaves: =~ 0.5
        # times 2 for projected area basis
        R_abs = (1 - scatt) * PAR + scatt * NIR + 2 * (epsilon * sbc * Tk**4)

        # debug dt I commented out the changes that yang made for leaf temperature for a test. I don't think they work
        if Jw == 0:
            # (R_abs - thermal_air - lamda * gv * w.VPD / P_air) / (Cp * ghr + lamda * w.saturation_slope * gv) # eqn 14.6a
            # eqn 14.6b linearized form using first order approximation of Taylor series
            return (psc1 /
                    (w.saturation_slope + psc1)) * ((R_abs - thermal_air) /
                                                    (ghr * Cp) - w.VPD /
                                                    (psc1 * P_air))
        else:
            return (R_abs - thermal_air - lamda * Jw) / (Cp * ghr)
Beispiel #8
0
    def stomatal_conductance(self,
                             g0,
                             g1,
                             gb,
                             m,
                             A_net,
                             CO2,
                             RH,
                             drb,
                             gamma=U(10, 'umol/mol')):
        Cs = CO2 - (drb * A_net / gb)  # surface CO2 in mole fraction
        Cs = clip(Cs, lower=gamma)

        a = m * g1 * A_net / Cs
        b = g0 + gb - a
        c = (-RH * gb) - g0
        #hs = max(np.roots([a, b, c]))
        #hs = scipy.optimize.brentq(lambda x: np.polyval([a, b, c], x), 0, 1)
        #hs = scipy.optimize.fsolve(lambda x: np.polyval([a, b, c], x), 0)
        hs = quadratic_solve_upper(a, b, c)
        #hs = clip(hs, 0.1, 1.0) # preventing bifurcation: used to be (0.3, 1.0) for C4 maize

        #FIXME unused?
        #T_leaf = l.temperature
        #es = w.vp.saturation(T_leaf)
        #Ds = (1 - hs) * es # VPD at leaf surface
        #Ds = w.vp.deficit(T_leaf, hs)

        gs = g0 + (g1 * m * (A_net * hs / Cs))
        gs = clip(gs, lower=g0)
        return gs
Beispiel #9
0
def test_optimize_with_unit():
    class S(System):
        @derive(unit='m')
        def a(self):
            return 2 * self.x

        @derive(unit='m')
        def b(self):
            return self.x + U(1, 'm')

        @optimize(lower=U(0, 'm'), upper=U(2, 'm'), unit='m')
        def x(self):
            return self.a - self.b

    s = instance(S)
    assert s.x == U(1, 'm')
    assert s.a == s.b == U(2, 'm')
Beispiel #10
0
 def optical_air_mass_number(self, elevation_angle):
     t_s = clip(elevation_angle, lower=0, unit='rad')
     #FIXME need to do max(0.0001, sin(t_s))?
     try:
         #FIXME check 101.3 is indeed in kPa
         return self.atmospheric_pressure / (U(101.3, 'kPa') * sin(t_s))
     except:
         return 0
Beispiel #11
0
 def hour_angle_at_horizon(self):
     c = self._cos_hour_angle(angle=U(90, 'deg'))
     # in the polar region during the winter, sun does not rise
     if c > 1:
         return 0
     # white nights during the summer in the polar region
     elif c < -1:
         return 180
     else:
         return degrees(arccos(c))
Beispiel #12
0
def test_nounit():
    class S(System):
        @derive(unit='m')
        def a(self):
            return 1
        @derive(nounit='a')
        def b(self, a):
            return a
    s = instance(S)
    assert isinstance(s.a, U.registry.Quantity)
    assert s.a == U(1, 'm')
    assert not isinstance(s.b, U.registry.Quantity)
    assert s.b == 1
Beispiel #13
0
def test_nounit_with_alias():
    class S(System):
        @derive(alias='aa', unit='m')
        def a(self):
            return 1
        @derive(alias='bb', nounit='aa')
        def b(self, aa):
            return aa
    s = instance(S)
    assert isinstance(s.aa, U.registry.Quantity)
    assert s.aa == U(1, 'm')
    assert not isinstance(s.bb, U.registry.Quantity)
    assert s.bb == 1
Beispiel #14
0
 def leaf_angle_coeff(self, zenith_angle):
     elevation_angle = U(90, 'deg') - zenith_angle
     #FIXME need to prevent zero like sin_beta / cot_beta?
     a = elevation_angle.to('rad')
     t = zenith_angle.to('rad')
     # leaf angle distribution parameter
     x = self.leaf_angle_factor
     return {
         # When Lt accounts for total path length, division by sin(elev) isn't necessary
         LeafAngle.spherical:
         1 / (2 * sin(a)),
         LeafAngle.horizontal:
         1,
         LeafAngle.vertical:
         1 / (tan(a) * pi / 2),
         LeafAngle.empirical:
         0.667,
         LeafAngle.diaheliotropic:
         1 / sin(a),
         LeafAngle.ellipsoidal:
         sqrt(x**2 + tan(t)**2) / (x + 1.774 * (x + 1.182)**-0.733),
     }[self.leaf_angle]
Beispiel #15
0
    def maximum_electron_transport_rate(self,
                                        T,
                                        T_dep,
                                        N_dep,
                                        Jm25=U(300, 'umol/m^2/s Electron'),
                                        Eaj=U(32800, 'J/mol'),
                                        Sj=U(702.6, 'J/mol/degK'),
                                        Hj=U(220000, 'J/mol')):
        R = U(8.314, 'J/K/mol')

        Tb = U(25, 'degC')
        Tk = T.to('degK')
        Tbk = Tb.to('degK')

        r = Jm25 * N_dep \
                 * T_dep(Eaj) \
                 * (1 + np.exp((Sj*Tbk - Hj) / (R*Tbk))) \
                 / (1 + np.exp((Sj*Tk  - Hj) / (R*Tk)))
        return clip(r, lower=0)
Beispiel #16
0
 def atmospheric_pressure(self, altitude):
     try:
         # campbell and Norman (1998), p 41
         return 101.3 * exp(-U.magnitude(altitude, 'm') / 8200)
     except:
         return 100
Beispiel #17
0
 def leafp_effect(self,
                  LWP='leaf.soil.WP_leaf',
                  sf=U(2.3, '1/MPa'),
                  phyf=U(-2.0, 'MPa')):
     return (1 + np.exp(sf * phyf)) / (1 + np.exp(sf * (phyf - LWP)))
Beispiel #18
0
 def solar_noon(self, LC, ET):
     return U(12, 'hr') - LC - ET
Beispiel #19
0
 def b(self):
     return self.x + U(1, 'm')
Beispiel #20
0
 def Kp(self, Kp25=U(80, 'ubar')):
     return Kp25  # T dependence yet to be determined
Beispiel #21
0
def test_U():
    Q = U.registry.Quantity
    assert U(1) == U('1') == 1
    assert U(1, 'm') == U('1', 'm') == U('1m') == Q(1, 'm')
    assert U(None) == U(None, None) == U(None, 'm') == None
    assert U(1, None) == 1
    assert U(1, '') == Q(1) == Q(1, None) == Q(1, '')
    a = U('1m', 'cm')
    assert a.magnitude == 100 and a.units == Q(1, 'cm').units
    assert U('N') == 'N' != U('1N')
    assert U('abc.def') == 'abc.def'
    assert U(-1) == U('-1') == -1
    assert U(.1) == U('.1') == 0.1
Beispiel #22
0
 def Vcmax(self,
           N_dep,
           T_dep,
           Vcm25=U(50, 'umol/m^2/s CO2'),
           EaVc=U(55900, 'J/mol')):
     return Vcm25 * N_dep * T_dep(EaVc)
Beispiel #23
0
 def Kc(self, T_dep, Kc25=U(650, 'ubar'), Eac=U(59400, 'J/mol')):
     return Kc25 * T_dep(Eac)
Beispiel #24
0
 def dark_respiration(self,
                      T_dep,
                      Rd25=U(2, 'umol/m^2/s O2'),
                      Ear=U(39800, 'J/mol')):
     return Rd25 * T_dep(Ear)
Beispiel #25
0
 def Ko(self, T_dep, Ko25=U(450, 'mbar'), Eao=U(36000, 'J/mol')):
     return Ko25 * T_dep(Eao)
Beispiel #26
0
 def Vpmax(self,
           N_dep,
           T_dep,
           Vpm25=U(70, 'umol/m^2/s CO2'),
           EaVp=U(75100, 'J/mol')):
     return Vpm25 * N_dep * T_dep(EaVp)
Beispiel #27
0
 def co2_mesophyll(self, A_net, w='weather', rvc='stomata.rvc'):
     P = w.P_air / U(100, 'kPa')
     Ca = w.CO2 * P  # conversion to partial pressure
     Cm = Ca - A_net * rvc * P
     #print(f"+ Cm = {Cm}, Ca = {Ca}, A_net = {A_net}, gs = {self.stomata.gs}, gb = {self.stomata.gb}, rvc = {rvc}, P = {P}")
     return clip(Cm, 0, 2 * Ca)
Beispiel #28
0
 def _saturation_slope(self, T, *, b, c):
     return self.es(T) * (b*c)/(c+T)**2 / U(1, 'degC')
Beispiel #29
0
 def bundle_sheath_o2(self, A_net, gbs, Om, alpha=0.0001):
     return alpha * A_net / (0.047 * gbs) * U(
         1, 'atm') + Om  # Bundle sheath O2 partial pressure, mbar