Nothing
## Function to simulate the multilayer drying of the soil
## This should probably take into account the distribution of
## root biomass in the profile
soilML <- function(precipt,CanopyT,cws,soilDepth,FieldC,WiltP,phi1=0.01,phi2 =10, wsFun = c("linear","logistic","exp","none"),rootDB,soilLayers=3,
LAI,k,AirTemp,IRad,winds,RelH,soilType=10,hydrDist=0,rfl=0.3){
if(length(cws) !=soilLayers)
stop("cws should be of length == soilLayers")
wsFun <- match.arg(wsFun)
if(wsFun == "linear") wsFun <- 0
else if(wsFun == "logistic") wsFun <- 1
else if(wsFun =="exp") wsFun <- 2
else if(wsFun == "none") wsFun <- 3
if(hydrDist > 0){
mat <- matrix(nrow=soilLayers,ncol=12)
}else{
mat <- matrix(nrow=soilLayers,ncol=9)
}
tmp2 <- SoilType(soilType)
oldEvapoTra <- 0
oldWaterIn <- 0
drainage <- 0
theta_s <- tmp2$satur
FieldC <- tmp2$fieldc
WiltP <- tmp2$wiltp
psim <- numeric(soilLayers)
## rootDepth
## Crude empirical relationship between root biomass and rooting depth
rootDepth <- rootDB * 0.44
if(rootDepth > soilDepth) rootDepth = soilDepth;
depths <- seq(0,soilDepth,length.out=I(soilLayers+1))
## rprops <- dpois(1:soilLayers,0.3*soilLayers)/sum(dpois(1:soilLayers,0.3*soilLayers))
rprops <- rootDist(soilLayers,rootDepth,depths,rfl)
## Precipitation enters in mm
waterIn = precipt * 1e-3; ## This is now cubic meter of water
for(i in I(length(depths)-1):1){
## First determine the layer depth
if(i == 1){
layerDepth <- depths[1+1]
}else{
layerDepth <- depths[i] - depths[i-1] ## These are in meters
}
### There is redistribution of water in the profile.
### For this section see Campbell and Norman "Environmental BioPhysics" Chapter 9
### First compute the matric potential
if(hydrDist > 0){
psim[i] = tmp2$air.entry * (cws[i]/theta_s)^-tmp2$b ; # This is matric potential of current layer
if(i > 1){
psim[i-1] = tmp2$air.entry * (cws[i-1]/theta_s)^-tmp2$b ;# This is matric potential of next layer
dPsim = psim[i] - psim[i-1];
}else{
dPsim = 0;
}
K_psim = tmp2$Ks * (tmp2$air.entry/psim[i])^(2+3/tmp2$b); # This is hydraulic conductivity
J_w = K_psim * (dPsim/layerDepth) - 9.8 * K_psim## Ignore gravitational effect - 10 * K_psim
## This is in kg (m2 * s)
## if(is.infinite(J_w) || is.na(J_w) || J_w > 1 || J_w < -1){
## J_w <- 0
## }
# This flow is in kg / (m2 * s)
if(is.na(J_w)){
cat("K_psim: ",K_psim," psim[i]: ",psim[i]," psim[i-1]: ",psim[i-1]," i",i,"\n")
stop("J_w is NA")
}
## The model runs at hourly time steps so
## times 3600 to convert seconds to hours
## Density of water at 20C 0.9882 Mg /m3
## 1e-3 to convert from kg to Mg
J_w = J_w * 3600 * (1/0.9882) * 1e-3; #/* This is flow in m3 /(m2 * hr)*/
if(i == soilLayers && J_w < 0){
## cws[i] = cws[i] + J_w / layerDepth;
drainage = drainage - J_w
}else
if(i > 1){
cws[i] = cws[i] - J_w / layerDepth;
cws[i - 1] = cws[i-1] + J_w / layerDepth;
}else{
## if(J_w < 0){
cws[i] = cws[i] - J_w / layerDepth;
## }
}
}
if(cws[i] > FieldC) cws[i] = FieldC;
## if(cws[i+1] > FieldC) cws[i+1] = FieldC;
if(cws[i] < WiltP) cws[i] = WiltP;
## if(cws[i+1] < WiltP) cws[i+1] = WiltP;
aw = cws[i] * layerDepth; ## Volume of water in layer i currently
if(waterIn > 0){
aw = aw + waterIn / soilLayers + oldWaterIn; ## They are both in meters so it works
## This is likely to overflow for the first layer when there is plenty precipitation
diffwc = FieldC*layerDepth - aw;
if(diffwc < 0){
## This means that precipitation exceeded the capacity of the last layer
## Save this amount of water for the next layer
oldWaterIn <- -diffwc
aw <- FieldC * layerDepth
}
}
## Root Biomass
rootATdepth <- rootDB*rprops[i]
## Plant available water is only between current water status and permanent wilting point
## Plant available water
paw <- aw - WiltP * layerDepth;
if(paw <0) paw = 0;
## The next step is to calculate the Evapo Transpiration I will
## assume that only the first layer of the soil profile has both
## evaporation and transpiration
if(i == 1){
## This assumes that the Canopy Transpiration is distributed
## proportionally to the root distribution
SoilEvap <- SoilEvapo(LAI=LAI,k=k,AirTemp=AirTemp,IRad=IRad,aw/layerDepth,FieldC=FieldC,WiltP=WiltP,winds=winds,RelH=RelH)
CanopyTra <- CanopyT*rprops[i]
EvapoTra <- CanopyTra + SoilEvap
## These units are in Mg/ha so
Newpawha <- (paw * 1e4) - EvapoTra
}else{
SoilEvap <- 0
CanopyTra <- CanopyT*rprops[i]
EvapoTra <- CanopyTra + SoilEvap
## These units are in Mg/ha so
Newpawha <- (paw * 1e4) - (EvapoTra + oldEvapoTra);
}
if(Newpawha < 0){
oldEvapoTra = -Newpawha;
paw = 0;
## If the Demand is not satisfied by the first layer. This will be stored and added to subsequent soilLayers
}else{
paw = Newpawha / 1e4 ;
}
awc <- paw / layerDepth + WiltP
cws[i] <- awc
if(wsFun == 0){
slp = 1/(FieldC - WiltP);
intcpt = 1 - FieldC * slp;
wsPhoto = slp * awc + intcpt ;
}else
if(wsFun == 1){
phi10 = (FieldC + WiltP)/2;
wsPhoto = 1/(1 + exp((phi10 - awc)/ phi1));
}else
if(wsFun == 2){
slp = (1 - WiltP)/(FieldC - WiltP);
intcpt = 1 - FieldC * slp;
theta = slp * awc + intcpt ;
wsPhoto = (1 - exp(-2.5 * (theta - WiltP)/(1 - WiltP))) / (1 - exp(-2.5));
}else
if(wsFun == 3){
wsPhoto = 1;
}
if(wsPhoto <= 0 )
wsPhoto = 1e-20; ## This can be mathematically lower than zero in some cases but I should prevent that.
wsSpleaf = awc^phi2 * 1/FieldC^phi2;
if(wsFun == 3){
wsSpleaf = 1;
}
mat[i,1] <- cws[i]
mat[i,2] <- rootATdepth
mat[i,3] <- waterIn
mat[i,4] <- layerDepth
mat[i,5] <- CanopyTra
mat[i,6] <- SoilEvap
mat[i,7] <- wsPhoto
mat[i,8] <- wsSpleaf
mat[i,9] <- drainage
if(hydrDist > 0){
mat[i,10] <- J_w
mat[i,11] <- K_psim
mat[i,12] <- psim[i]
}
}
if(waterIn > 0) drainage <- drainage + waterIn
if(hydrDist > 0){
colnames(mat) <- c("cws","rootATdepth","waterIn","layerDepth","CanopyTra","SoilEvap","wsPhoto","wsSpleaf","drainage","J_w","K_psim","psim")
}else{
colnames(mat) <- c("cws","rootATdepth","waterIn","layerDepth","CanopyTra","SoilEvap","wsPhoto","wsSpleaf","drainage")
}
mat
}
rootDist <- function(layers,rootDepth,depthsp,rfl){
if(layers < 2)
stop("layers should be at least 2")
CumLayerDepth <- 0
CumRootDist <- 0
ca <- 0
rootDist <- numeric(layers)
# for(i in 1:I(length(depthsp)-1)){
for(i in seq_len(layers)){
if(i == 1){
layerDepth = depthsp[1+1];
}else{
layerDepth = depthsp[i] - depthsp[i-1];
}
CumLayerDepth = CumLayerDepth + layerDepth;
if(rootDepth > CumLayerDepth){
CumRootDist = CumRootDist + 1
}
}
for(j in seq_len(layers)){
if(j < CumRootDist){
a = dpois(j,CumRootDist*rfl)
rootDist[j] = a
ca = ca + a
}else{
rootDist[j] = 0
}
}
rootDist = rootDist / ca
rootDist
}
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.