1088 lines
43 KiB
FortranFixed
1088 lines
43 KiB
FortranFixed
!This version of Anet_Final uses resistance instead of conductance. It considers the fact that
|
|
!CO2 from mitochodria (dark respiration and photorespiration) has different diffusion path ways than
|
|
!intercellular CO2
|
|
subroutine Anet_Final(vcmax,jrubp,vtpu,resistwp,resistch,
|
|
&stargamma,kco,co2i,alpha,rd,ilimittype,iminimum,anet,co2c,
|
|
&realizedfjelect)
|
|
implicit none
|
|
!
|
|
!Calculates the net assimilation rate once all parameters are given at measurement conditions
|
|
!------------------ Inputs -----------------------------------
|
|
!ilimittype: limitation types to evaluate
|
|
! 1 = Rubisco,RuBp and TPU limitations
|
|
! 2 = Rubisco and RuBp limitations only
|
|
! 3 = Rubisco and TPU limitations only
|
|
! 4 = RuBp and TPU limitations only
|
|
! 5 = Rubisco limitation only
|
|
! 6 = RuBp limitation only
|
|
! 7 = TPU limitation only
|
|
!vcmax (if ilimittype=1,2,3,5), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!jrubp (if ilimittype=1,2,4,6), electron transport rate (umol m-2 s-1)
|
|
!vtpu (if ilimittype=1,3,4,7), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kco,(if ilimittype=1,2,3,5), Kc(1+O/Ko), (Pa)
|
|
!co2i, intercellular CO2 partial pressure (Pa)
|
|
!alpha, (if ilimittype=1,3,4,7), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!------------------ Outputs ----------------------------------
|
|
!anet: the net assimilation rate (umol m-2 s-1)
|
|
!iminimum, which limitation type is actually present Rubisco (1), RuBp(2), and TPU (3)
|
|
!realizedfjelect: the realized electron transport rate <= jrubp (=when RuBP regeneration limits photosynthesis).
|
|
integer ilimittype,iminimum,idorubisco,idorubp,idotpu
|
|
double precision vcmax,jrubp,vtpu,gmeso,stargamma,kco,co2i,
|
|
&alpha,rd,anet,wc,wj,wp,anetc,anetj,anettpu,term,term1,term2,co2c,
|
|
&co2c_wc,co2c_wj,co2c_wp,rwp,resistwp,rch,resistch,realizedfjelect
|
|
!---------------------------------rwp=dmax1(0.0d0,resistwp)---------------------------------
|
|
anetc=1.0d+20
|
|
anetj=1.0d+20
|
|
anettpu=1.0d+20
|
|
wc=1.0d+10
|
|
wj=1.0d+15
|
|
wp=1.0d+20
|
|
realizedfjelect=-9999.0d0
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
!This way of initialization is deliberate. If co2c <0, the priority of limitation
|
|
!state is Rubisco, RuBP regeneration, TPU
|
|
idorubisco=0
|
|
idorubp=0
|
|
idotpu=0
|
|
iminimum=0
|
|
if(ilimittype.le.3.or.ilimittype.eq.5)then
|
|
idorubisco=1
|
|
endif
|
|
if(ilimittype.le.2.or.ilimittype.eq.4.or.
|
|
& ilimittype.eq.6)then
|
|
idorubp=1
|
|
endif
|
|
if(ilimittype.eq.1.or.ilimittype.eq.3.or.
|
|
& ilimittype.eq.4.or.ilimittype.eq.7)then
|
|
idotpu=1
|
|
endif
|
|
if(idorubisco.eq.1)then
|
|
call findco2c(vcmax,kco,co2i,rd,stargamma,rwp,rch,co2c_wc)
|
|
wc=co2c_wc*vcmax/(co2c_wc+kco)
|
|
anetc=(co2c_wc-stargamma)*vcmax/(co2c_wc+kco)-rd
|
|
endif
|
|
if(idorubp.eq.1)then
|
|
if(stargamma.eq.0.0d0)then
|
|
co2c_wj=co2i+rd*rwp-0.25d0*jrubp*(rwp+rch)
|
|
else
|
|
term1=0.25d0*jrubp
|
|
term2=2.0d0*stargamma
|
|
call findco2c(term1,term2,co2i,rd,stargamma,rwp,rch,co2c_wj)
|
|
endif
|
|
wj=co2c_wj*0.25d0*jrubp/(co2c_wj+2.0d0*stargamma)
|
|
anetj=(co2c_wj-stargamma)*0.25d0*jrubp/
|
|
& (co2c_wj+2.0d0*stargamma)-rd
|
|
endif
|
|
if(idotpu.eq.1)then
|
|
!assumptions:
|
|
!Carboxylation rate cannot be negative. That means, if
|
|
!co2i is less than or equal to (1.0d0+3.0d0*alpha)*stargamma, then
|
|
!the TPU limitation state cannot occur. Under this situation, set wp to infinite
|
|
term1=3.0d0*vtpu
|
|
term2=-(1.0d0+3.0d0*alpha)*stargamma
|
|
call findco2c(term1,term2,co2i,rd,stargamma,rwp,rch,co2c_wp)
|
|
term=co2c_wp-(1.0d0+3.0d0*alpha)*stargamma
|
|
if(term.gt.1.0d-12)then
|
|
wp=co2c_wp*3.0d0*vtpu/term
|
|
anettpu=(co2c_wp-stargamma)*3.0d0*vtpu/term-rd
|
|
else
|
|
co2c_wp=-9999.0d0
|
|
if(alpha.eq.0.0d0)anettpu=3.0d0*vtpu-rd
|
|
endif
|
|
endif
|
|
if(ilimittype.ge.5)then
|
|
if(ilimittype.eq.5)then
|
|
iminimum=1
|
|
anet=anetc
|
|
co2c=co2c_wc
|
|
endif
|
|
if(ilimittype.eq.6)then
|
|
iminimum=2
|
|
anet=anetj
|
|
co2c=co2c_wj
|
|
endif
|
|
if(ilimittype.eq.7)then
|
|
iminimum=3
|
|
anet=anettpu
|
|
co2c=co2c_wp
|
|
endif
|
|
else
|
|
if(wc.lt.wj)then
|
|
if(wc.le.wp)then
|
|
anet=anetc
|
|
co2c=co2c_wc
|
|
iminimum=1
|
|
else
|
|
anet=anettpu
|
|
co2c=co2c_wp
|
|
iminimum=3
|
|
endif
|
|
else
|
|
if(wj.le.wp)then
|
|
anet=anetj
|
|
co2c=co2c_wj
|
|
iminimum=2
|
|
else
|
|
anet=anettpu
|
|
co2c=co2c_wp
|
|
iminimum=3
|
|
endif
|
|
endif
|
|
endif
|
|
if(iminimum.eq.2)then
|
|
realizedfjelect=jrubp
|
|
else
|
|
if(co2c.eq.stargamma)then
|
|
realizedfjelect=0.0d0
|
|
else
|
|
realizedfjelect=
|
|
&(anet+rd)*(4.0d0*co2c+8.0d0*stargamma)/(co2c-stargamma)
|
|
endif
|
|
endif
|
|
return
|
|
end subroutine Anet_Final
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine findco2c(vcmax,kco,co2i,rd,stargamma,rwp,rch,
|
|
&co2c)
|
|
!kco and vcmax are generic and the formulation applies to rubp and tpu too
|
|
implicit none
|
|
double precision vcmax,kco,co2i,rd,stargamma,rwp,rch,co2c,
|
|
&b,c,b24ac,p,q,w
|
|
co2c=-9999.0d0
|
|
b=kco-co2i-rd*rwp+vcmax*(rwp+rch)
|
|
c=-(co2i+rd*rwp)*kco-vcmax*rwp*stargamma
|
|
b24ac=b*b-4.0d0*c
|
|
if(b24ac.ge.0.0d0)then
|
|
co2c=(-b+dsqrt(b24ac))*0.5d0
|
|
! write(*,*)(-b+dsqrt(b24ac))*0.5d0,(-b-dsqrt(b24ac))*0.5d0
|
|
! p=-rd*rwp+vcmax*(rwp+rch)
|
|
! q=rd*rwp*kco+vcmax*rwp*stargamma
|
|
! w=4.0d0*(p*kco+q)
|
|
! if(w.le.0.0d0)then
|
|
! if((kco+co2i-p).le.(-dsqrt(-w)))co2c=(-b-dsqrt(b24ac))*0.5d0
|
|
! endif
|
|
! if((kco+co2i-p).lt.0.0d0)co2c=(-b-dsqrt(b24ac))*0.5d0
|
|
endif
|
|
return
|
|
end
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine der_findco2c(vcmax,kco,co2i,rd,stargamma,rwp,
|
|
&rch,co2c,der_vcmax,der_kco,der_co2i,der_rd,der_stargamma,
|
|
&der_rwp,der_rch)
|
|
!kco and vcmax are generic and the formulation applies to rubp and tpu too
|
|
implicit none
|
|
double precision vcmax,kco,co2i,rd,stargamma,rwp,rch,co2c,
|
|
&b,c,b24ac,p,q,w,fsign,der_vcmax,der_kco,der_co2i,der_rd,
|
|
&der_stargamma,der_rwp,der_rch,term,der_b,der_c
|
|
co2c=-9999.0d0
|
|
der_vcmax=0.0d0
|
|
der_kco=0.0d0
|
|
der_co2i=0.0d0
|
|
der_rd=0.0d0
|
|
der_stargamma=0.0d0
|
|
der_rwp=0.0d0
|
|
der_rch=0.0d0
|
|
b=kco-co2i-rd*rwp+vcmax*(rwp+rch)
|
|
c=-(co2i+rd*rwp)*kco-vcmax*rwp*stargamma
|
|
b24ac=b*b-4.0d0*c
|
|
if(b24ac.ge.0.0d0)then
|
|
fsign=1.0d0
|
|
! p=-rd*rwp+vcmax*(rwp+rch)
|
|
! q=rd*rwp*kco+vcmax*rwp*stargamma
|
|
! w=4.0d0*(p*kco+q)
|
|
! if(w.le.0.0d0)then
|
|
! if((kco+co2i-p).le.(-dsqrt(-w)))fsign=-1.0d0
|
|
! endif
|
|
! if((kco+co2i-p).lt.0.0d0)fsign=-1.0d0
|
|
|
|
term=dsqrt(b24ac)
|
|
co2c=(-b+fsign*term)*0.5d0
|
|
der_b=(-1.0d0+fsign*b/term)*0.5d0
|
|
der_c=-fsign/term
|
|
der_vcmax=der_b*(rwp+rch)-der_c*rwp*stargamma
|
|
der_kco=der_b-der_c*(co2i+rd*rwp)
|
|
der_co2i=-der_b-der_c*kco
|
|
der_rd=-der_b*rwp-der_c*rwp*kco
|
|
der_stargamma=-der_c*vcmax*rwp
|
|
der_rwp=der_b*(vcmax-rd)-der_c*(rd*kco+vcmax*stargamma)
|
|
der_rch=der_b*vcmax
|
|
endif
|
|
return
|
|
end
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine Anet_Final_der(vcmax,jrubp,vtpu,resistwp,
|
|
&resistch,stargamma,kco,co2i,alpha,rd,ilimittype,der_vcmax,
|
|
&der_jrubp,der_vtpu,der_rwp,der_rch,der_stargamma,der_kco,
|
|
&der_alpha,der_rd,der_co2i,anet,co2c,realizedfjelect)
|
|
implicit none
|
|
!Calculates the derivatives of parameters and the net assimilation rate
|
|
!once all parameters are given at measurement conditions.
|
|
!------------------ Inputs -----------------------------------
|
|
!ilimittype: limitation types to evaluate
|
|
! 1 = Rubisco,RuBp and TPU limitations
|
|
! 2 = Rubisco and RuBp limitations only
|
|
! 3 = Rubisco and TPU limitations only
|
|
! 4 = RuBp and TPU limitations only
|
|
! 5 = Rubisco limitation only
|
|
! 6 = RuBp limitation only
|
|
! 7 = TPU limitation only
|
|
!vcmax (if ilimittype=1,2,3,5), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!jrubp (if ilimittype=1,2,4,6), electron transport rate (umol m-2 s-1)
|
|
!vtpu (if ilimittype=1,3,4,7), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kco,(if ilimittype=1,2,3,5), Kc(1+O/Ko), (Pa)
|
|
!co2i, intercellular CO2 partial pressure (Pa)
|
|
!starco2i,(if ilimittype=1,2,3,5), intercellular CO2 partial pressure at which Ac = 0. At this point,
|
|
! chloroplastic CO2 partial pressure equals the intercellular partial pressure (Pa). If less than
|
|
! zero, rd must be an input.
|
|
!alpha, (if ilimittype=1,3,4,7), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, (if ilimittype=4,6,7),mitochondrial respiration in the light (umol m-2 s-1). if starco2i is less than
|
|
!zero, rd must be an input under all limitation types
|
|
!
|
|
!------------------ Outputs ----------------------------------
|
|
!rd, (if ilimittype=1,2,3,5 when starco2i is greater than zero),mitochondrial respiration in the light (umol m-2 s-1)
|
|
!anet: the net assimilation rate (umol m-2 s-1)
|
|
!iminimum, which limitation type is actually present Rubisco (1), RuBp(2), and TPU (3)
|
|
!realizedfjelect: the realized electron transport rate <= jrubp (=when RuBP regeneration limits photosynthesis).
|
|
integer ilimittype,iminimum
|
|
double precision vcmax,jrubp,vtpu,gmeso,stargamma,kco,co2i,
|
|
&alpha,rd,anet,der_vcmax,der_jrubp,der_vtpu,der_rwp,der_rch,
|
|
&der_stargamma,der_kco,der_alpha,der_rd,t1,t2,co2c,rwp,
|
|
&rch,resistwp,resistch,dCc_t1,dCc_t2,dCc_co2i,dCc_rd,
|
|
&dCc_stargamma,der_co2i,der_Cc,der_t1,der_t2,dCc_rwp,dCc_rch,
|
|
&realizedfjelect
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
call Anet_Final(vcmax,jrubp,vtpu,rwp,rch,stargamma,
|
|
&kco,co2i,alpha,rd,ilimittype,iminimum,anet,co2c,
|
|
&realizedfjelect)
|
|
!We now know which limitation type is at work. Calculate the derivatives
|
|
der_vcmax=0.0d0
|
|
der_jrubp=0.0d0
|
|
der_vtpu=0.0d0
|
|
der_rwp=0.0d0
|
|
der_rch=0.0d0
|
|
der_stargamma=0.0d0
|
|
der_kco=0.0d0
|
|
der_alpha=0.0d0
|
|
der_co2i=0.0d0
|
|
der_rd=-1.0d0
|
|
if(iminimum.eq.1)then
|
|
t1=vcmax
|
|
t2=kco
|
|
endif
|
|
if(iminimum.eq.2)then
|
|
t1=0.25d0*jrubp
|
|
t2=2.0d0*stargamma
|
|
endif
|
|
if(iminimum.eq.3)then
|
|
t1=3.0d0*vtpu
|
|
t2=-(1.0d0+3.0d0*alpha)*stargamma
|
|
endif
|
|
der_t1=(co2c-stargamma)/(co2c+t2)
|
|
der_t2=-(co2c-stargamma)*t1/((co2c+t2)*(co2c+t2))
|
|
der_stargamma=-t1/(co2c+t2)
|
|
der_Cc=t1/(co2c+t2)*(1.0d0-(co2c-stargamma)/(co2c+t2))
|
|
der_co2i=der_Cc
|
|
call der_findco2c(t1,t2,co2i,rd,stargamma,rwp,
|
|
&rch,co2c,dCc_t1,dCc_t2,dCc_co2i,dCc_rd,dCc_stargamma,
|
|
&dCc_rwp,dCc_rch)
|
|
der_t1=der_t1+der_Cc*dCc_t1
|
|
der_t2=der_t2+der_Cc*dCc_t2
|
|
der_stargamma=der_stargamma+der_Cc*dCc_stargamma
|
|
der_rd=der_rd+der_Cc*dCc_rd
|
|
der_co2i=der_Cc*dCc_co2i
|
|
der_rwp=der_Cc*dCc_rwp
|
|
der_rch=der_Cc*dCc_rch
|
|
!now change back
|
|
if(iminimum.eq.1)then
|
|
der_vcmax=der_t1
|
|
der_kco=der_t2
|
|
endif
|
|
if(iminimum.eq.2)then
|
|
der_jrubp=der_t1*0.25d0
|
|
der_stargamma=der_stargamma+der_t2*2.0d0
|
|
endif
|
|
if(iminimum.eq.3)then
|
|
der_vtpu=der_t1*3.0d0
|
|
der_stargamma=der_stargamma-der_t2*(1.0d0+3.0d0*alpha)
|
|
der_alpha=-der_t2*3.0d0*stargamma
|
|
endif
|
|
return
|
|
end subroutine Anet_Final_der
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine Anet_Final_der2(vcmax,jrubp,vtpu,resistwp,
|
|
&resistch,stargamma,kco,co2i,alpha,rd,ilimittype,der_vcmax,
|
|
&der_jrubp,der_vtpu,der_rwp,der_rch,der_stargamma,der_kco,
|
|
&der_alpha,der_rd,der_co2i,der2_vcmax,der2_jrubp,der2_vtpu,
|
|
&der2_rwp,der2_rch,der2_stargamma,der2_kco,der2_alpha,
|
|
&der2_rd,der2_co2i,anet,co2c,realizedfjelect)
|
|
implicit none
|
|
!Calculates the derivatives of parameters and the net assimilation rate
|
|
!once all parameters are given at measurement conditions.
|
|
!------------------ Inputs -----------------------------------
|
|
!ilimittype: limitation types to evaluate
|
|
! 1 = Rubisco,RuBp and TPU limitations
|
|
! 2 = Rubisco and RuBp limitations only
|
|
! 3 = Rubisco and TPU limitations only
|
|
! 4 = RuBp and TPU limitations only
|
|
! 5 = Rubisco limitation only
|
|
! 6 = RuBp limitation only
|
|
! 7 = TPU limitation only
|
|
!vcmax (if ilimittype=1,2,3,5), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!jrubp (if ilimittype=1,2,4,6), electron transport rate (umol m-2 s-1)
|
|
!vtpu (if ilimittype=1,3,4,7), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kco,(if ilimittype=1,2,3,5), Kc(1+O/Ko), (Pa)
|
|
!co2i, intercellular CO2 partial pressure (Pa)
|
|
!starco2i,(if ilimittype=1,2,3,5), intercellular CO2 partial pressure at which Ac = 0. At this point,
|
|
! chloroplastic CO2 partial pressure equals the intercellular partial pressure (Pa). If less than
|
|
! zero, rd must be an input.
|
|
!alpha, (if ilimittype=1,3,4,7), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1)
|
|
!
|
|
!------------------ Outputs ----------------------------------
|
|
!anet: the net assimilation rate (umol m-2 s-1)
|
|
!iminimum, which limitation type is actually present Rubisco (1), RuBp(2), and TPU (3)
|
|
!realizedfjelect: the realized electron transport rate <= jrubp (=when RuBP regeneration limits photosynthesis).
|
|
integer ilimittype,iminimum
|
|
double precision vcmax,jrubp,vtpu,resistwp,resistch,
|
|
&stargamma,kco,co2i,alpha,rd,der_vcmax,der_jrubp,der_vtpu,
|
|
&der_rwp,der_rch,der_stargamma,der_kco,der_alpha,der_rd,der_co2i,
|
|
&der2_vcmax,der2_jrubp,der2_vtpu,der2_rwp,der2_rch,der2_stargamma,
|
|
&der2_kco,der2_alpha,der2_rd,der2_co2i,anet,co2c,rwp,rch,t1,t2,t3,
|
|
&der_t1,der_t2,der_Cc,der2_t1,der2_t2,der2_Cc,der2_Cct1,der2_Cct2,
|
|
&der2_Ccstargamma,der2_t2stargamma,der2_Ccrd,dCc_t1,dCc_t2,dCc_rd,
|
|
&dCc2_rd,dCc_stargamma,dCc_rwp,dCc2_rwp,dCc_rch,dCc2_rch,dCc_co2i,
|
|
&dCc2_t1,dCc2_t2,dCc2_co2i,dCc2_stargamma,dCc2_t2stargamma,
|
|
&der2_t2_0,realizedfjelect
|
|
!------------------------------------------------------------------
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
call Anet_Final(vcmax,jrubp,vtpu,rwp,rch,stargamma,
|
|
&kco,co2i,alpha,rd,ilimittype,iminimum,anet,co2c,
|
|
&realizedfjelect)
|
|
!We now know which limitation type is at work. Calculate the derivatives
|
|
!first derivatives
|
|
der_vcmax=0.0d0
|
|
der_jrubp=0.0d0
|
|
der_vtpu=0.0d0
|
|
der_rwp=0.0d0
|
|
der_rch=0.0d0
|
|
der_stargamma=0.0d0
|
|
der_kco=0.0d0
|
|
der_alpha=0.0d0
|
|
der_rd=-1.0d0
|
|
!second derivatives
|
|
der2_vcmax=0.0d0
|
|
der2_jrubp=0.0d0
|
|
der2_vtpu=0.0d0
|
|
der2_rwp=0.0d0
|
|
der2_rch=0.0d0
|
|
der2_stargamma=0.0d0
|
|
der2_kco=0.0d0
|
|
der2_alpha=0.0d0
|
|
der2_rd=0.0d0
|
|
if(iminimum.eq.1)then
|
|
t1=vcmax
|
|
t2=kco
|
|
endif
|
|
if(iminimum.eq.2)then
|
|
t1=0.25d0*jrubp
|
|
t2=2.0d0*stargamma
|
|
endif
|
|
if(iminimum.eq.3)then
|
|
t1=3.0d0*vtpu
|
|
t2=-(1.0d0+3.0d0*alpha)*stargamma
|
|
endif
|
|
der_t1=(co2c-stargamma)/(co2c+t2)
|
|
der_t2=-(co2c-stargamma)*t1/((co2c+t2)*(co2c+t2))
|
|
der_stargamma=-t1/(co2c+t2)
|
|
der_Cc=t1/(co2c+t2)*(1.0d0-(co2c-stargamma)/(co2c+t2))
|
|
der_co2i=der_Cc
|
|
der2_Cc=(2.0d0*t1/((co2c+t2)**2))*
|
|
&((co2c-stargamma)/(co2c+t2)-1.0d0)
|
|
der2_t2=2.0d0*(co2c-stargamma)*t1/((co2c+t2)**3)
|
|
der2_t2_0=der2_t2
|
|
der2_Cct1=(1.0d0-(co2c-stargamma)/(co2c+t2))/(co2c+t2)
|
|
der2_Cct2=(t1/((co2c+t2)**2))*
|
|
&(2.0d0*(co2c-stargamma)/(co2c+t2)-1.0d0)
|
|
der2_Ccstargamma=t1/((co2c+t2)**2)
|
|
der2_t2stargamma=t1/((co2c+t2)**2)
|
|
der2_co2i=der2_Cc
|
|
der2_rd=0.0d0
|
|
der2_t1=0.0d0
|
|
der2_stargamma=0.0d0
|
|
der2_Ccrd=0.0d0
|
|
call der2_findco2c(t1,t2,co2i,rd,stargamma,rwp,rch,co2c,dCc_t1,
|
|
&dCc_t2,dCc_co2i,dCc_rd,dCc_stargamma,dCc_rwp,dCc_rch,dCc2_t1,
|
|
&dCc2_t2,dCc2_co2i,dCc2_rd,dCc2_stargamma,dCc2_rwp,dCc2_rch,
|
|
&dCc2_t2stargamma)
|
|
der_t1=der_t1+der_Cc*dCc_t1
|
|
der_t2=der_t2+der_Cc*dCc_t2
|
|
der_stargamma=der_stargamma+der_Cc*dCc_stargamma
|
|
der_rd=der_rd+der_Cc*dCc_rd
|
|
der_co2i=der_Cc*dCc_co2i
|
|
der_rwp=der_Cc*dCc_rwp
|
|
der_rch=der_Cc*dCc_rch
|
|
der2_t1=
|
|
&2.0d0*der2_Cct1*dCc_t1+der2_Cc*(dCc_t1**2)+der_Cc*dCc2_t1
|
|
der2_t2=der2_t2+
|
|
&2.0d0*der2_Cct2*dCc_t2+der2_Cc*(dCc_t2**2)+der_Cc*dCc2_t2
|
|
der2_rd=der2_Cc*(dCc_rd**2)+der_Cc*dCc2_rd
|
|
der2_rwp=der2_Cc*(dCc_rwp**2)+der_Cc*dCc2_rwp
|
|
der2_rch=der2_Cc*(dCc_rch**2)+der_Cc*dCc2_rch
|
|
der2_co2i=der2_Cc*(dCc_co2i**2)+der_Cc*dCc2_co2i
|
|
if(iminimum.eq.1)then
|
|
der2_stargamma=
|
|
&2.0d0*der2_Ccstargamma*dCc_stargamma+der2_Cc*(dCc_stargamma**2)+
|
|
&der_Cc*dCc2_stargamma
|
|
der_vcmax=der_t1
|
|
der_kco=der_t2
|
|
der2_vcmax=der2_t1
|
|
der2_kco=der2_t2
|
|
endif
|
|
if(iminimum.eq.2)then
|
|
dCc_stargamma=dCc_stargamma+dCc_t2*2.0d0
|
|
dCc2_stargamma=dCc2_stargamma+
|
|
&2.0d0*dCc2_t2stargamma*2.0d0+dCc2_t2*4.0d0
|
|
der_jrubp=der_t1*0.25d0
|
|
der_stargamma=der_stargamma+der_t2*2.0d0
|
|
der2_jrubp=der2_t1*0.25d0*0.25d0
|
|
der2_stargamma=2.0d0*der2_Ccstargamma*dCc_stargamma+
|
|
&der2_Cc*(dCc_stargamma**2)+der_Cc*dCc2_stargamma+
|
|
&4.0d0*(der2_t2stargamma+der2_Cct2*dCc_stargamma)+der2_t2_0*4.0d0
|
|
endif
|
|
if(iminimum.eq.3)then
|
|
t3=-(1.0d0+3.0d0*alpha)
|
|
dCc_stargamma=dCc_stargamma+dCc_t2*t3
|
|
dCc2_stargamma=dCc2_stargamma+
|
|
&2.0d0*dCc2_t2stargamma*t3+dCc2_t2*t3*t3
|
|
der_vtpu=der_t1*3.0d0
|
|
der_stargamma=der_stargamma+der_t2*t3
|
|
der_alpha=-der_t2*3.0d0*stargamma
|
|
der2_vtpu=der2_t1*3.0d0*3.0d0
|
|
der2_stargamma=2.0d0*der2_Ccstargamma*dCc_stargamma+
|
|
&der2_Cc*(dCc_stargamma**2)+der_Cc*dCc2_stargamma+
|
|
&2.0d0*(der2_t2stargamma+der2_Cct2*dCc_stargamma)*t3+
|
|
&der2_t2_0*t3*t3
|
|
der2_alpha=der2_t2*9.0d0*stargamma**2
|
|
endif
|
|
return
|
|
end
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine der2_findco2c(vcmax,kco,co2i,rd,stargamma,rwp,
|
|
&rch,co2c,der_vcmax,der_kco,der_co2i,der_rd,der_stargamma,
|
|
&der_rwp,der_rch,der2_vcmax,der2_kco,der2_co2i,der2_rd,
|
|
&der2_stargamma,der2_rwp,der2_rch,der2_kcostargamma)
|
|
!kco and vcmax are generic and the formulation applies to rubp and tpu too
|
|
!after the transformation factors are applied
|
|
implicit none
|
|
integer iwhichroot
|
|
double precision vcmax,kco,co2i,rd,stargamma,rwp,rch,co2c,
|
|
&der_vcmax,der_kco,der_co2i,der_rd,der_stargamma,der_rwp,
|
|
&der_rch,der2_vcmax,der2_kco,der2_co2i,der2_rd,der2_stargamma,
|
|
&der2_rwp,der2_rch,der2_kcostargamma,derb_vcmax,derb_kco,derb_co2i,
|
|
&derb_rd,derb_stargamma,derb_rwp,derb_rch,derc_vcmax,derc_kco,
|
|
&derc_co2i,derc_rd,derc_stargamma,derc_rwp,derc_rch,b,c,b24ac,
|
|
&term,der_b,der_c,der2_b,der2_c,der2_bc,p,q,w,der2implicit
|
|
co2c=-9999.0d0
|
|
der_vcmax=0.0d0
|
|
der_kco=0.0d0
|
|
der_co2i=0.0d0
|
|
der_rd=0.0d0
|
|
der_stargamma=0.0d0
|
|
der_rwp=0.0d0
|
|
der_rch=0.0d0
|
|
der2_kco=0.0d0
|
|
der2_co2i=0.0d0
|
|
der2_rd=0.0d0
|
|
der2_stargamma=0.0d0
|
|
der2_rwp=0.0d0
|
|
der2_rch=0.0d0
|
|
der2_kcostargamma=0.0d0
|
|
b=kco-co2i-rd*rwp+vcmax*(rwp+rch)
|
|
c=-(co2i+rd*rwp)*kco-vcmax*rwp*stargamma
|
|
derb_vcmax=rwp+rch
|
|
derb_kco=1.0d0
|
|
derb_co2i=-1.0d0
|
|
derb_rd=-rwp
|
|
derb_stargamma=0.0d0
|
|
derb_rwp=vcmax-rd
|
|
derb_rch=vcmax
|
|
derc_vcmax=-rwp*stargamma
|
|
derc_kco=-(co2i+rd*rwp)
|
|
derc_co2i=-kco
|
|
derc_rd=-rwp*kco
|
|
derc_stargamma=-vcmax*rwp
|
|
derc_rwp=-rd*kco-vcmax*stargamma
|
|
derc_rch=0.0d0
|
|
b24ac=b*b-4.0d0*c
|
|
if(b24ac.ge.0.0d0)then
|
|
iwhichroot=1
|
|
! p=-rd*rwp+vcmax*(rwp+rch)
|
|
! q=rd*rwp*kco+vcmax*rwp*stargamma
|
|
! w=4.0d0*(p*kco+q)
|
|
! if(w.le.0.0d0)then
|
|
! if((kco+co2i-p).le.(-dsqrt(-w)))iwhichroot=-1
|
|
! endif
|
|
! if((kco+co2i-p).lt.0.0d0)iwhichroot=-1
|
|
|
|
call der2_simpquadroot(iwhichroot,b,c,co2c,der_b,der_c,der2_b,
|
|
&der2_c,der2_bc)
|
|
der_vcmax=der_b*derb_vcmax+der_c*derc_vcmax
|
|
der_kco=der_b*derb_kco+der_c*derc_kco
|
|
der_co2i=der_b*derb_co2i+der_c*derc_co2i
|
|
der_rd=der_b*derb_rd+der_c*derc_rd
|
|
der_stargamma=der_b*derb_stargamma+der_c*derc_stargamma
|
|
der_rwp=der_b*derb_rwp+der_c*derc_rwp
|
|
der_rch=der_b*derb_rch+der_c*derc_rch
|
|
der2_vcmax=der2implicit(der2_b,der2_c,der2_bc,
|
|
&derb_vcmax,derc_vcmax)
|
|
der2_kco=der2implicit(der2_b,der2_c,der2_bc,derb_kco,derc_kco)
|
|
der2_co2i=der2implicit(der2_b,der2_c,der2_bc,
|
|
&derb_co2i,derc_co2i)
|
|
der2_rd=der2implicit(der2_b,der2_c,der2_bc,derb_rd,derc_rd)
|
|
der2_stargamma=der2implicit(der2_b,der2_c,der2_bc,
|
|
&derb_stargamma,derc_stargamma)
|
|
der2_rwp=der2implicit(der2_b,der2_c,der2_bc,derb_rwp,derc_rwp)
|
|
der2_rch=der2implicit(der2_b,der2_c,der2_bc,derb_rch,derc_rch)
|
|
der2_kcostargamma=
|
|
&der2_bc*derc_stargamma*derb_kco+der2_c*derc_stargamma*derc_kco
|
|
endif
|
|
return
|
|
end
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine der2_simpquadroot(iwhichroot,b,c,root,
|
|
& der_b,der_c,der2_b,der2_c,der2_bc)
|
|
implicit none
|
|
double precision b,c,root,der_b,der_c,b24c,
|
|
& der2_b,der2_c,der2_bc,term
|
|
integer iwhichroot
|
|
!root for x2+bx+c=0
|
|
b24c=b*b-4.0d0*c
|
|
if(b24c.lt.0.0d0)then
|
|
root=-9999.0d0
|
|
der_b=-9999.0d0
|
|
der_c=-9999.0d0
|
|
der2_b=-9999.0d0
|
|
der2_c=-9999.0d0
|
|
der2_bc=-9999.0d0
|
|
else
|
|
term=1.0d0/((b*b-4.0d0*c)*dsqrt(b24c))
|
|
if(iwhichroot.lt.0)then
|
|
root=0.5d0*(-b-dsqrt(b24c))
|
|
der_b=0.5d0*(-1.0d0-b/dsqrt(b24c))
|
|
der_c=1.0d0/dsqrt(b24c)
|
|
der2_b=2.0d0*c*term
|
|
der2_c=2.0d0*term
|
|
der2_bc=-b*term
|
|
else
|
|
root=0.5d0*(-b+dsqrt(b24c))
|
|
der_b=0.5d0*(-1.0d0+b/dsqrt(b24c))
|
|
der_c=-1.0d0/dsqrt(b24c)
|
|
der2_b=-2.0d0*c*term
|
|
der2_c=-2.0d0*term
|
|
der2_bc=b*term
|
|
endif
|
|
endif
|
|
return
|
|
end
|
|
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
double precision function der2implicit(der2_b,der2_c,
|
|
& der2_bc,derb_p,derc_p)
|
|
implicit none
|
|
double precision der2_b,der2_c,
|
|
& der2_bc,derb_p,derc_p
|
|
der2implicit=der2_b*derb_p*derb_p+
|
|
& 2.0d0*der2_bc*derb_p*derc_p+der2_c*derc_p*derc_p
|
|
return
|
|
end
|
|
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
subroutine der_simpquadroot(iwhichroot,b,c,root,
|
|
& der_b,der_c)
|
|
implicit none
|
|
double precision b,c,root,der_b,der_c,b24c
|
|
integer iwhichroot
|
|
!x2+bx+c=0
|
|
b24c=b*b-4.0d0*c
|
|
if(b24c.gt.0.0d0)then
|
|
if(iwhichroot.lt.0)then
|
|
root=0.5d0*(-b-dsqrt(b24c))
|
|
der_b=0.5d0*(-1.0d0-b/dsqrt(b24c))
|
|
der_c=1.0d0/dsqrt(b24c)
|
|
else
|
|
root=0.5d0*(-b+dsqrt(b24c))
|
|
der_b=0.5d0*(-1.0d0+b/dsqrt(b24c))
|
|
der_c=-1.0d0/dsqrt(b24c)
|
|
endif
|
|
else
|
|
if(b24c.lt.0.0d0)then
|
|
root=-9999.0d0
|
|
der_b=-9999.0d0
|
|
der_c=-9999.0d0
|
|
else
|
|
root=-b
|
|
der_b=-1.0d0
|
|
der_c=0.0d0
|
|
endif
|
|
endif
|
|
return
|
|
end
|
|
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
subroutine EqualPoints(vcmax,jrubp,vtpu,resistwp,
|
|
&resistch,stargamma,kc,ko,oxypres,alpha,rd,ilimittype,
|
|
&co2iRubismax,co2iRuBpmax,anetRubismax,anetRuBpmax)
|
|
implicit none
|
|
!Calculates the CO2i points where limitations of Rubisco, RuBp and Tpu are equal.
|
|
!------------------ Inputs -----------------------------------
|
|
!ilimittype: limitation types to evaluate
|
|
! 1 = Rubisco,RuBp and TPU limitations
|
|
! 2 = Rubisco and RuBp limitations only
|
|
! 3 = Rubisco and TPU limitations only
|
|
! 4 = RuBp and TPU limitations only
|
|
! 5 = Rubisco limitation only
|
|
! 6 = RuBp limitation only
|
|
! 7 = TPU limitation only
|
|
!vcmax (if ilimittype=1,2,3,5), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!jrubp (if ilimittype=1,2,4,6), electron transport rate (umol m-2 s-1)
|
|
!vtpu (if ilimittype=1,3,4,7), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kc: the Michaelis constant for CO2 [Pa]
|
|
!ko: the Michaelis constant for O2 [Pa]
|
|
!oxypres: Oxygen partial pressure (Pa)
|
|
!alpha, (if ilimittype=1,3,4,7), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!------------------ Outputs ----------------------------------
|
|
!anetRubisRuBp,anetRuBpTpu,anetRubisTpu: the net assimilation rates at equal points (umol m-2 s-1)
|
|
!co2iRubisRuBp,co2iRuBpTpu,co2iRubisTpu: equal points
|
|
|
|
integer ilimittype
|
|
double precision vcmax,jrubp,vtpu,resistwp,resistch,
|
|
&rwp,rch,stargamma,kc,ko,oxypres,kco,co2i,alpha,rd,
|
|
&co2iRubismax,co2iRuBpmax,anetRubismax,anetRuBpmax,term1
|
|
!------------------------------------------------------------------
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
anetRubismax=-9999.0d0
|
|
anetRuBpmax=-9999.0d0
|
|
co2iRubismax=-9999.0d0
|
|
co2iRuBpmax=-9999.0d0
|
|
kco=kc*(1.0d0+oxypres/ko)
|
|
term1=-(1.0d0+3.0d0*alpha)*stargamma
|
|
if(ilimittype.eq.1)then
|
|
co2iRubismax=(2.0d0*stargamma*vcmax-
|
|
& kco*0.25d0*jrubp)/(0.25d0*jrubp-vcmax)
|
|
anetRubismax=(co2iRubismax-stargamma)*vcmax/
|
|
& (co2iRubismax+kco)-rd
|
|
co2iRuBpmax=(2.0d0*stargamma*3.0d0*vtpu-
|
|
& term1*0.25d0*jrubp)/(0.25d0*jrubp-3.0d0*vtpu)
|
|
anetRuBpmax=(co2iRuBpmax-stargamma)*0.25d0*jrubp/
|
|
& (co2iRuBpmax+2.0d0*stargamma)-rd
|
|
endif
|
|
if(ilimittype.eq.2)then
|
|
co2iRubismax=(2.0d0*stargamma*vcmax-
|
|
& kco*0.25d0*jrubp)/(0.25d0*jrubp-vcmax)
|
|
anetRubismax=(co2iRubismax-stargamma)*vcmax/
|
|
& (co2iRubismax+kco)-rd
|
|
endif
|
|
if(ilimittype.eq.3)then
|
|
co2iRubismax=(term1*vcmax-
|
|
& kco*3.0d0*vtpu)/(3.0d0*vtpu-vcmax)
|
|
anetRubismax=(co2iRubismax-stargamma)*vcmax/
|
|
& (co2iRubismax+kco)-rd
|
|
endif
|
|
if(ilimittype.eq.4)then
|
|
co2iRuBpmax=(2.0d0*stargamma*3.0d0*vtpu-
|
|
& term1*0.25d0*jrubp)/(0.25d0*jrubp-3.0d0*vtpu)
|
|
anetRuBpmax=(co2iRuBpmax-stargamma)*0.25d0*jrubp/
|
|
& (co2iRuBpmax+2.0d0*stargamma)-rd
|
|
endif
|
|
if(rwp.gt.0.0d0.or.rch.gt.0.0d0)then
|
|
if(ilimittype.eq.1.or.ilimittype.eq.2.or.ilimittype.eq.3)
|
|
&co2iRubismax=co2iRubismax+anetRubismax*rwp+rch*
|
|
&co2iRubismax*vcmax/(co2iRubismax+kco)
|
|
if(ilimittype.eq.1.or.ilimittype.eq.4)co2iRuBpmax=
|
|
&co2iRuBpmax+anetRuBpmax*rwp+rch*co2iRuBpmax*0.25d0*jrubp/
|
|
&(co2iRuBpmax+2.0d0*stargamma)
|
|
endif
|
|
return
|
|
end subroutine EqualPoints
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine Params_Ci(vcmax,jrubp,vtpu,resistwp,resistch,
|
|
&stargamma,kco,alpha,rd,ilimittype,cic,anetcic,cij,anetcij)
|
|
implicit none
|
|
!
|
|
!Calculates vcmax and tpu when the CO2i thresholds are known.
|
|
!------------------ Inputs -----------------------------------
|
|
!ilimittype: limitation types to evaluate
|
|
! 1 = Rubisco,RuBp and TPU limitations,
|
|
! 2 = Rubisco and RuBp limitations only
|
|
! 3 = Rubisco and TPU limitations only
|
|
! 4 = RuBp and TPU limitations only
|
|
!
|
|
!jrubp (except for ilimittype=3), electron transport rate (umol m-2 s-1)
|
|
!vtpu (when ilimittype=3 only), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kco,(if ilimittype=1,2,3), Kc(1+O/Ko), (Pa)
|
|
!alpha, (if ilimittype=1,3,4), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!cic, CO2i at rubisco and rubp limited intersection (Pa) or at rubisco and tpu limited intersection
|
|
!cij, CO2i at rubp and tpu limited intersection (Pa)
|
|
!------------------ Outputs ----------------------------------
|
|
!vcmax (when ilimittype=1,2,3 only), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!vtpu (when ilimittype=1,4 only), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!anetcic: net assimilation rate at cic (umol m-2 s-1).
|
|
!anetcij: net assimilation rate at cij (umol m-2 s-1).
|
|
|
|
integer ilimittype,idogi,i,j,k
|
|
double precision vcmax,jrubp,vtpu,resistwp,resistch,rwp,rch,
|
|
&stargamma,kco,co2i,alpha,rd,term1,cic,cij,anetcic,anetcij,
|
|
&co2cic,co2cij,realizedfjelect
|
|
!------------------------------------------------------------------
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
term1=-(1.0d0+3.0d0*alpha)*stargamma
|
|
if(ilimittype.eq.1.or.ilimittype.eq.2)then
|
|
call Anet_Final(vcmax,jrubp,vtpu,rwp,rch,stargamma,
|
|
&kco,cic,alpha,rd,6,i,anetcic,co2cic,realizedfjelect)
|
|
endif
|
|
if(ilimittype.eq.1.or.ilimittype.eq.4)then
|
|
call Anet_Final(vcmax,jrubp,vtpu,rwp,rch,stargamma,
|
|
&kco,cij,alpha,rd,6,i,anetcij,co2cij,realizedfjelect)
|
|
endif
|
|
if(ilimittype.eq.3)then
|
|
call Anet_Final(vcmax,jrubp,vtpu,rwp,rch,stargamma,
|
|
&kco,cic,alpha,rd,7,i,anetcic,co2cic,realizedfjelect)
|
|
endif
|
|
if(ilimittype.eq.1.or.ilimittype.eq.2.or.ilimittype.eq.3)
|
|
&vcmax=(anetcic+rd)*(co2cic+kco)/(co2cic-stargamma)
|
|
if(ilimittype.eq.1.or.ilimittype.eq.4)then
|
|
if(alpha.gt.0.0d0)then
|
|
vtpu=(anetcij+rd)*(co2cij+term1)/(co2cij-stargamma)
|
|
vtpu=vtpu/3.0d0
|
|
else
|
|
vtpu=(anetcij+rd)/3.0d0
|
|
endif
|
|
endif
|
|
return
|
|
end subroutine Params_Ci
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine inverse_anet(vcmax,jrubp,vtpu,resistwp,
|
|
&resistch,stargamma,kco,alpha,rd,iminimum,co2i,anet)
|
|
implicit none
|
|
!Calculates vcmax, jrubp, or tpu when CO2i and other parameters are known.
|
|
!------------------ Inputs -----------------------------------
|
|
!iminimum=1, rubisco limitation
|
|
! =2, rubp regeneration limitation
|
|
! =3, tpu limitation
|
|
!anet: net co2 assimilation rate (umolm-2s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kco (if iminimum=1), Kc(1+O/Ko), (Pa)
|
|
!alpha (if iminimum=3), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!------------------ Outputs ----------------------------------
|
|
!vcmax (when iminimum=1 only), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!jrubp (when iminimum=2 only), electron transport rate (umol m-2 s-1)
|
|
!vtpu (when iminimum=3 only), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!
|
|
integer iminimum
|
|
double precision vcmax,jrubp,vtpu,resistwp,resistch,
|
|
&stargamma,kco,co2i,alpha,rd,anet,term1,co2c
|
|
!------------------------------------------------------------------
|
|
vcmax=-9999.0d0
|
|
jrubp=-9999.0d0
|
|
vtpu=-9999.0d0
|
|
if(iminimum.eq.3.and.alpha.le.0.0d0)then
|
|
vtpu=(anet+rd)/3.0d0
|
|
return
|
|
endif
|
|
call getco2c(resistwp,resistch,stargamma,rd,co2i,anet,co2c)
|
|
if(co2c.lt.0.0d0)return
|
|
if(iminimum.eq.1)vcmax=(anet+rd)*(co2c+kco)/(co2c-stargamma)
|
|
if(iminimum.eq.2)jrubp=
|
|
&4.0d0*(anet+rd)*(co2c+2.0d0*stargamma)/(co2c-stargamma)
|
|
if(iminimum.eq.3)then
|
|
term1=-(1.0d0+3.0d0*alpha)*stargamma
|
|
vtpu=((anet+rd)*(co2c+term1)/(co2c-stargamma))/3.0d0
|
|
endif
|
|
return
|
|
end subroutine inverse_anet
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine getco2c(resistwp,resistch,stargamma,rd,co2i,anet,
|
|
&co2c)
|
|
implicit none
|
|
!Calculates CO2c
|
|
!------------------ Inputs -----------------------------------
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!anet: CO2 assimilation rate (umolm-2s-1)
|
|
double precision resistwp,rwp,resistch,rch,stargamma,co2i,rd,anet,
|
|
&co2c,b,c,b24ac,cy
|
|
!------------------------------------------------------------------
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
cy=co2i-anet*rwp
|
|
if(rch.gt.0.0d0)then
|
|
b=(anet+rd)*rch-cy-stargamma
|
|
c=cy*stargamma
|
|
b24ac=b*b-4.0d0*c
|
|
if(b24ac.ge.0.0d0)then
|
|
if(anet.lt.-rd)then
|
|
co2c=(-b-dsqrt(b24ac))/2.0d0
|
|
else
|
|
co2c=(-b+dsqrt(b24ac))/2.0d0
|
|
endif
|
|
else
|
|
co2c=-9999.0d0
|
|
endif
|
|
else
|
|
co2c=cy
|
|
endif
|
|
return
|
|
end subroutine getco2c
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine getresistmeso(resistwp,resistch,stargamma,rd,co2i,anet,
|
|
&co2c,resistmeso)
|
|
implicit none
|
|
!Calculates mesophyll resistance resistmeso (Pa s m2 umol-1) and chloroplastic CO2 co2c (Pa)
|
|
!------------------ Inputs -----------------------------------
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!anet: CO2 assimilation rate (umolm-2s-1)
|
|
!co2i: CO2 partial pressure at intercellular air space (Pa)
|
|
double precision resistwp,rwp,resistch,rch,stargamma,co2i,rd,anet,
|
|
&co2c,q,u,q24u,resistmeso
|
|
!------------------------------------------------------------------
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
if(rch.gt.0.0d0)then
|
|
call getco2c(rwp,rch,stargamma,rd,co2i,anet,co2c)
|
|
resistmeso=(co2i-co2c)/anet
|
|
!
|
|
! q=-(anet+rd)*rch-co2i+stargamma-anet*rwp
|
|
! u=(anet+rd)*rch*co2i+(co2i-stargamma)*anet*rwp
|
|
! q24u=q*q-4.0d0*u
|
|
! if(q24u.ge.0.0d0)then
|
|
! resistmeso=(-q-dsqrt(q24u))/(2.0d0*anet)
|
|
! co2c=co2i-anet*resistmeso
|
|
! write(*,*)co2c,resistmeso
|
|
! resistmeso=(-q+dsqrt(q24u))/(2.0d0*anet)
|
|
! co2c=co2i-anet*resistmeso
|
|
! write(*,*)co2c,resistmeso
|
|
! else
|
|
! resistmeso=-9999.0d0
|
|
! co2c=-9999.0d0
|
|
! endif
|
|
else
|
|
resistmeso=rwp
|
|
co2c=co2i-anet*resistmeso
|
|
endif
|
|
return
|
|
end subroutine getresistmeso
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine co2recyclingratio(resistwp,resistch,resiststom,
|
|
&stargamma,rd,co2c,anet,recyclingrate)
|
|
implicit none
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resiststom: resistance to CO2 via stomata (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma: chloraplatic CO2 photocompensation point (Pa)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!co2c: co2 partial pressure at chloroplast (Pa)
|
|
!anet, net assimilation rate (umol m-2 s-1).
|
|
double precision resistwp,resistch,resiststom,stargamma,
|
|
&rd,co2c,anet,recyclingrate,rwp,rch,rst,vc,rcarb
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
rst=dmax1(0.0d0,resiststom)
|
|
vc=(anet+rd)/(1.0d0-stargamma/co2c)
|
|
rcarb=co2c/vc
|
|
recyclingrate=(rwp+rst)/(rwp+rst+rch+rcarb)
|
|
return
|
|
end
|
|
!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
subroutine CO2i_Final(vcmax,jrubp,vtpu,resistwp,resistch,
|
|
&stargamma,kco,co2i,alpha,rd,ilimittype,iminimum,anet,co2c,
|
|
&realizedfjelect,co2i_obs,co2c_wp,anet_wp)
|
|
implicit none
|
|
!
|
|
!Calculates the net assimilation rate once all parameters are given at measurement conditions
|
|
!------------------ Inputs -----------------------------------
|
|
!ilimittype: limitation types to evaluate
|
|
! 1 = Rubisco,RuBp and TPU limitations
|
|
! 2 = Rubisco and RuBp limitations only
|
|
! 3 = Rubisco and TPU limitations only
|
|
! 4 = RuBp and TPU limitations only
|
|
! 5 = Rubisco limitation only
|
|
! 6 = RuBp limitation only
|
|
! 7 = TPU limitation only
|
|
!vcmax (if ilimittype=1,2,3,5), maximum carboxylation rate limited by Rubisco (umol m-2 s-1)
|
|
!jrubp (if ilimittype=1,2,4,6), electron transport rate (umol m-2 s-1)
|
|
!vtpu (if ilimittype=1,3,4,7), triose phosphate export rate from chloroplast (umol m-2 s-1)
|
|
!resistwp: resistance to CO2 via cell walls and plasmalemma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!resistch: resistance to CO2 via chloroplast envelope and stroma (Pa s m2 umol-1). If less than zero, set to zero.
|
|
!stargamma, chloraplatic CO2 photocompensation point (Pa)
|
|
!kco,(if ilimittype=1,2,3,5), Kc(1+O/Ko), (Pa)
|
|
!co2i, intercellular CO2 partial pressure (Pa)
|
|
!alpha, (if ilimittype=1,3,4,7), fraction of glycolate carbon not returned to the chloroplast (0-1, dimensionless)
|
|
!rd, mitochondrial respiration in the light (umol m-2 s-1).
|
|
!------------------ Outputs ----------------------------------
|
|
!anet: the net assimilation rate (umol m-2 s-1)
|
|
!iminimum, which limitation type is actually present Rubisco (1), RuBp(2), and TPU (3)
|
|
!realizedfjelect: the realized electron transport rate <= jrubp (=when RuBP regeneration limits photosynthesis).
|
|
integer ilimittype,iminimum,idorubisco,idorubp,idotpu
|
|
double precision vcmax,jrubp,vtpu,stargamma,kco,co2i,
|
|
&alpha,rd,anet,wc,wj,wp,anet_wp,term1,term2,co2c,co2i_wc,co2i_wj,
|
|
&co2i_wp,co2c_wc,co2c_wj,co2c_wp,rwp,resistwp,rch,resistch,
|
|
&realizedfjelect,co2i_obs
|
|
wc=1.0d+10
|
|
wj=1.0d+15
|
|
wp=1.0d+20
|
|
co2i=-9999.0d0
|
|
anet_wp=-9999.0d0
|
|
co2c_wp=-9999.0d0
|
|
co2i_wp=-9999.0d0
|
|
realizedfjelect=-9999.0d0
|
|
rwp=dmax1(0.0d0,resistwp)
|
|
rch=dmax1(0.0d0,resistch)
|
|
!This way of initialization is deliberate. If co2c <0, the priority of limitation
|
|
!state is Rubisco, RuBP regeneration, TPU
|
|
idorubisco=0
|
|
idorubp=0
|
|
idotpu=0
|
|
iminimum=0
|
|
if(ilimittype.le.3.or.ilimittype.eq.5)then
|
|
idorubisco=1
|
|
endif
|
|
if(ilimittype.le.2.or.ilimittype.eq.4.or.
|
|
& ilimittype.eq.6)then
|
|
idorubp=1
|
|
endif
|
|
if(ilimittype.eq.1.or.ilimittype.eq.3.or.
|
|
& ilimittype.eq.4.or.ilimittype.eq.7)then
|
|
idotpu=1
|
|
endif
|
|
if(idorubisco.eq.1)then
|
|
! x=vcmax
|
|
! y=1.0d0
|
|
! z=kco
|
|
call getCO2ibackwards(vcmax,1.0d0,kco,anet,rwp,rch,rd,stargamma,
|
|
&co2i_wc,co2c_wc)
|
|
if(co2c_wc.gt.0.0d0)wc=co2c_wc*vcmax/(co2c_wc+kco)
|
|
endif
|
|
if(idorubp.eq.1)then
|
|
! x=jrubp
|
|
! y=4.0d0
|
|
term1=8.0d0*stargamma
|
|
call getCO2ibackwards(jrubp,4.0d0,term1,anet,rwp,rch,rd,
|
|
&stargamma,co2i_wj,co2c_wj)
|
|
if(co2c_wj.gt.0.0d0)wj=
|
|
&co2c_wj*jrubp/(4.0d0*co2c_wj+8.0d0*stargamma)
|
|
endif
|
|
if(idotpu.eq.1)then
|
|
if(alpha.gt.0.0d0)then
|
|
term1=3.0d0*vtpu
|
|
term2=-(1.0d0+3.0d0*alpha)*stargamma
|
|
call getCO2ibackwards(term1,1.0d0,term2,anet,rwp,rch,rd,
|
|
&stargamma,co2i_wp,co2c_wp)
|
|
if(co2c_wp.gt.(-term2))wp=co2c_wp*term1/(co2c_wp+term2)
|
|
else
|
|
!CO2i is undefined for alpha=0 so we use the normal forward mode; in this case, CO2i is an input
|
|
!and anet is an output.
|
|
term1=3.0d0*vtpu
|
|
term2=-stargamma
|
|
call findco2c(term1,term2,co2i_obs,rd,stargamma,rwp,rch,
|
|
&co2c_wp)
|
|
co2i_wp=co2i_obs
|
|
if(co2c_wp.gt.stargamma)wp=
|
|
&co2c_wp*3.0d0*vtpu/(co2c_wp-stargamma)
|
|
anet_wp=3.0d0*vtpu-rd
|
|
endif
|
|
endif
|
|
if(ilimittype.ge.5)then
|
|
if(ilimittype.eq.5)then
|
|
iminimum=1
|
|
co2i=co2i_wc
|
|
co2c=co2c_wc
|
|
endif
|
|
if(ilimittype.eq.6)then
|
|
iminimum=2
|
|
co2i=co2i_wj
|
|
co2c=co2c_wj
|
|
endif
|
|
if(ilimittype.eq.7)then
|
|
iminimum=3
|
|
co2i=co2i_wp
|
|
co2c=co2c_wp
|
|
endif
|
|
else
|
|
if(wc.lt.wj)then
|
|
if(wc.le.wp)then
|
|
co2i=co2i_wc
|
|
co2c=co2c_wc
|
|
iminimum=1
|
|
else
|
|
co2i=co2i_wp
|
|
co2c=co2c_wp
|
|
iminimum=3
|
|
endif
|
|
else
|
|
if(wj.le.wp)then
|
|
co2i=co2i_wj
|
|
co2c=co2c_wj
|
|
iminimum=2
|
|
else
|
|
co2i=co2i_wp
|
|
co2c=co2c_wp
|
|
iminimum=3
|
|
endif
|
|
endif
|
|
endif
|
|
if(iminimum.eq.2)then
|
|
realizedfjelect=jrubp
|
|
else
|
|
if(co2c.eq.stargamma)then
|
|
realizedfjelect=0.0d0
|
|
else
|
|
realizedfjelect=
|
|
&(anet+rd)*(4.0d0*co2c+8.0d0*stargamma)/(co2c-stargamma)
|
|
endif
|
|
endif
|
|
return
|
|
end subroutine CO2i_Final
|
|
!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
subroutine getCO2ibackwards(x,y,z,anet,rwp,rch,rd,stargamma,
|
|
&co2i,co2c)
|
|
implicit none
|
|
!Calculate CO2i and CO2c from anet
|
|
!Vc=xCO2c/(yCO2c+z)
|
|
!Rubisco: x=Vcmax, y=1, z=kco
|
|
!RuBP: x=jrubp, y=4, z=8*stargamma
|
|
!TPU: x=3*tpu, y=1, z=-(1+3*alpha)*stargamma
|
|
!
|
|
double precision x,y,z,anet,rwp,rch,rd,stargamma,co2i,co2c
|
|
co2c=(x*stargamma+z*(anet+rd))/(x-(anet+rd)*y)
|
|
co2i=co2c*(1.0d0+x*rch/(y*co2c+z))+anet*rwp
|
|
return
|
|
end
|