Nothing
#' FARquhar And Opti
#' @description The numerical solution of the optimal stomatal conductance model, coupled with
#' the Farquhar model of photosynthesis. The model of Medlyn et al. (2011) is an approximation
#' to this full numeric solution.
#' @param lambda The marginal cost of water (mol mol-1)
#' @param Ca The CO2 concentration.
#' @param VPD Vapor pressure deficit (kPa)
#' @param photo Which photosynthesis rate should stomata respond to? Defaults to 'BOTH', i.e.
#' the minimum of Vcmax and Jmax limited rates.
#' @param energybalance If TRUE (Default = FALSE), calculates leaf temperature from energy balance
#' (and its effects on photosynthesis as well as leaf transpiration), using \code{\link{PhotosynEB}}.
#' @param C4 If TRUE, uses the C4 photosynthesis routine (\code{\link{AciC4}})
#' @param Tair Air temperature (deg C)
#' @param Wind Wind speed (m s-1) (only used if energybalance=TRUE)
#' @param Wleaf Leaf width (m) (only used if energybalance=TRUE)
#' @param StomatalRatio The stomatal ratio (see \code{\link{PhotosynEB}}) (only used if
#' energybalance=TRUE)
#' @param LeafAbs Leaf absorptance (see \code{\link{PhotosynEB}}) (only used if
#' energybalance=TRUE)
#' @param ... All other parameters are passed to \code{\link{Aci}}
#' @author Remko Duursma
#' @details This model finds the Ci that maximizes A - lambda*E (Cowan & Farquhar 1977,
#' see also Medlyn et al. 2011). The new function FARAO2 is a much simpler (and probably
#' more stable) implementation, based on Buckley et al. 2014 (P,C&E). Both functions
#' are provided, as FARAO has a few more options than FARAO2, at the moment.
#' @references
#' Buckley, T.N., Martorell, S., Diaz-Espejo, A., Tomas, M., Medrano, H., 2014. Is stomatal
#' conductance optimized over both time and space in plant crowns? A field test in
#' grapevine (Vitis vinifera). Plant Cell Environ doi:10.1111/pce.12343
#'
#' Cowan, I. and G.D. Farquhar. 1977. Stomatal function in relation to leaf metabolism
#' and environment. Symposia of the Society for Experimental Biology. 31:471-505.
#'
#' Medlyn, B.E., R.A. Duursma, D. Eamus, D.S. Ellsworth, I.C. Prentice, C.V.M. Barton,
#' K.Y. Crous, P. De Angelis, M. Freeman and L. Wingate. 2011. Reconciling the optimal
#' and empirical approaches to modelling stomatal conductance. Global Change Biology. 17:2134-2144.
#' @export
#' @importFrom stats optimize
#' @rdname FARAO
FARAO <- function(lambda=0.002, Ca=400, VPD=1,
photo=c("BOTH","VCMAX","JMAX"),
energybalance=FALSE,
C4=FALSE,
Tair=25,
Wind=2,
Wleaf=0.02,
StomatalRatio=1,
LeafAbs=0.86,
...){
photo <- match.arg(photo)
# Non-vectorized form.
FARAOfun <- function(lambda, Ca, VPD,
photo,
energybalance, C4,
Tair,
Wind,
Wleaf,
StomatalRatio,
LeafAbs,
...){
if(!energybalance){
fx <- function(Ca,...)optimize(OPTfun, interval=c(0,Ca),
maximum=TRUE,Ca=Ca,
...)$maximum
optimalcis <- mapply(fx,Ca=Ca,lambda=lambda, photo=photo, C4=C4, VPD=VPD,...)
res <- as.data.frame(OPTfun(Ci=optimalcis, retobjfun=FALSE,
Ca=Ca, photo=photo, C4=C4, VPD=VPD,...))
} else {
fx <- function(Ca,...)optimize(OPTfunEB, interval=c(0,Ca),
maximum=TRUE,Ca=Ca,
...)$maximum
optimalcis <- mapply(fx,Ca=Ca,lambda=lambda, photo=photo, C4=C4, VPD=VPD,
Tair=Tair,
Wind=Wind,
Wleaf=Wleaf,
StomatalRatio=StomatalRatio,
LeafAbs=LeafAbs,
...)
res <- as.data.frame(OPTfunEB(Ci=optimalcis, retobjfun=FALSE,
Ca=Ca, photo=photo, C4=C4, VPD=VPD,
Tair=Tair,
Wind=Wind,
Wleaf=Wleaf,
StomatalRatio=StomatalRatio,
LeafAbs=LeafAbs,...))
}
return(res)
}
f <- t(mapply(FARAOfun, lambda=lambda, Ca=Ca, VPD=VPD,
photo=photo,
energybalance=energybalance, C4=C4,
Tair=Tair,
Wind=Wind,
Wleaf=Wleaf,
StomatalRatio=StomatalRatio,
LeafAbs=LeafAbs, ..., SIMPLIFY=FALSE))
return(as.data.frame(do.call(rbind,f)))
}
# This function returns the 'objective function' A - lambda*E
# This is to be optimized by the next function by varying ci.
OPTfun <- function(Ci, # mu mol mol-1
lambda=0.002, # mol mol-1
Ca=400, # mu mol mol-1
VPD=1, # kPa
Patm=101, # ambient pressure, kPa
photo=c("BOTH","VCMAX","JMAX"),
energybalance=FALSE,
retobjfun=TRUE, # if false, returns A, g and E (otherwise sum(A-lambda*E))
C4=FALSE,
...){
GCtoGW <- 1.57
VPDmol <- VPD/Patm
photo <- match.arg(photo)
# Given a Ci, calculate photosynthetic rate
if(!C4)
# note that VPD does not do anything, just for consistency in I/O
run <- Aci(Ci=Ci, VPD=VPD, ...)
else
run <- AciC4(Ci, VPD=VPD, ...)
if(photo == "BOTH")A <- run$ALEAF
if(photo == "VCMAX")A <- run$Ac
if(photo == "JMAX")A <- run$Aj
# Given Ci and A, calculate gs (diffusion constraint)
gs <- GCtoGW * A / (Ca - Ci)
# Transpiration rate
E <- gs*VPDmol
# Objective function to be maximized (Cowan-Farquhar condition)
objfun <- 10^-6*A - lambda*E
if(retobjfun)return(objfun)
if(!retobjfun)return(list( Ci=Ci, ALEAF=A, GS=gs, ELEAF=E*1000, Ac=run$Ac, Aj=run$Aj,
Rd=run$Rd, VPD=VPD, Tleaf=run$Tleaf, Ca=Ca, PPFD=run$PPFD ))
}
OPTfunEB <- function(Ci, # mu mol mol-1
lambda=0.002, # mol mol-1
Ca=400, # mu mol mol-1
VPD=1.5, # AIR VPD! kPa
Patm=101, # ambient pressure, kPa
Tair=25,
Wind=2,
Wleaf=0.02,
StomatalRatio=1,
LeafAbs=0.86,
photo=c("BOTH","VCMAX","JMAX"),
retobjfun=TRUE, # if false, returns A, g and E (otherwise sum(A-lambda*E))
C4=FALSE,
...){
GCtoGW <- 1.57
VPDmol <- VPD/Patm
photo <- match.arg(photo)
gsfun <- function(Ci, VPD, returnwhat=c("gs","all"), ...){
returnwhat <- match.arg(returnwhat)
# Given a Ci, calculate photosynthetic rate
if(!C4)
# note that VPD does not do anything, just for consistency in I/O
run <- Aci(Ci, VPD=VPD, ...)
else
run <- AciC4(Ci, VPD=VPD, ...)
if(photo == "BOTH")A <- run$ALEAF
if(photo == "VCMAX")A <- run$Ac
if(photo == "JMAX")A <- run$Aj
# Given Ci and A, calculate gs (diffusion constraint)
gs <- GCtoGW * A / (Ca - Ci)
if(returnwhat == "gs")return(gs)
if(returnwhat == "all")return(list(run=run, GS=gs, A=A))
}
# Find Tleaf. Here, we take into account that Tleaf as solved from
# energy balance affects gs (because it affects)
fx <- function(x, Ci, Tair, Wind, VPD, Wleaf, StomatalRatio, LeafAbs, ...){
newx <- FindTleaf(Tair=Tair, gs=gsfun(Ci=Ci, Tleaf=x, VPD=VPD, ...),
Wind=Wind, Wleaf=Wleaf,
StomatalRatio=StomatalRatio, LeafAbs=LeafAbs)
(newx - x)^2
}
Tleaf <- optimize(fx, interval=c(Tair-10, Tair+10), Ci=Ci, Tair=Tair,
Wind=Wind, VPD=VPD, Wleaf=Wleaf,
StomatalRatio=StomatalRatio, LeafAbs=LeafAbs, ...)$minimum
z <- gsfun(Ci=Ci, Tleaf=Tleaf, VPD=VPD, returnwhat="all",...)
GS <- z$GS
A <- z$A
# And energy balance components
e <- LeafEnergyBalance(Tleaf=Tleaf, Tair=Tair, gs=GS,
PPFD=z$run$PPFD, VPD=VPD, Patm=z$run$Patm,
Wind=Wind, Wleaf=Wleaf,
StomatalRatio=StomatalRatio, LeafAbs=LeafAbs,
returnwhat="fluxes")
E <- e$ELEAFeb
# Objective function to be maximized (Cowan-Farquhar)
objfun <- 10^-6*A - lambda*E/1000
if(retobjfun)return(objfun)
if(!retobjfun)return(list( Ci=Ci, ALEAF=A, GS=GS, ELEAF=E, Ac=z$run$Ac, Aj=z$run$Aj,
Rd=z$run$Rd, VPD=VPD, Tleaf=Tleaf, Ca=Ca, PPFD=z$run$PPFD ))
}
getdAdE <- function(Ci,...,energybalance=FALSE,
returnwhat=c("dAdE","both")){
returnwhat <- match.arg(returnwhat)
delta <- 1e-03
if(energybalance){
r1 <- PhotosynEB(Ci=Ci, ...)
r2 <- PhotosynEB(Ci=Ci+delta, ...)
} else {
r1 <- Photosyn(Ci=Ci, ...)
r2 <- Photosyn(Ci=Ci+delta, ...)
}
dA <- r2$ALEAF - r1$ALEAF
dE <- r2$ELEAF - r1$ELEAF
if(returnwhat == "dAdE")
return(dA/dE)
else
return(c(dA=dA, dE=dE))
}
#' @rdname FARAO
#' @export
FARAO2 <- function(lambda=0.002, Ca=400, energybalance=FALSE, ...){
faraofun <- function(lambda,Ca,energybalance,...){
f <- function(x, ...)(getdAdE(x, energybalance=energybalance, ...) - lambda*1000)^2
CI <- try(optimize(f, c(80, Ca-0.1), ...)$minimum)
if(inherits(CI, "try-error"))return(NULL)
if(energybalance)
p <- PhotosynEB(Ci=CI, ...)
else
p <- Photosyn(Ci=CI, ...)
return(p)
}
m <- mapply(faraofun, lambda=lambda, Ca=Ca,
energybalance=energybalance, ..., SIMPLIFY=FALSE)
return(do.call(rbind, m))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.