1. Simple water balance simulation

Miquel De Caceres

2019-03-20

About this vignette

This document describes how to run the soil water balance model described in De Cáceres et al. (2015) using package medfate. The document indicates how to prepare the inputs, use the simulation functions and inspect the outputs. All the details of the model design and formulation are given in a separate document that can be found on the website of the R package (http://vegmod.ctfc.cat/medfateweb).

Preparing model inputs

Any forest water balance model needs information on climate, vegetation and soils of the forest stand to be simulated. Moreover, since the soil water balance in medfate differentiates between species, species-specific parameters are also needed. In this subsection we explain the different steps (including optional pathways) to prepare all the data needed to run function spwb().

Soils

Required soil data

Simulation models in medfate require information on the physical attributes of soil, namely soil depth, texture, bulk density and rock fragment content. Soil information needs to be entered as a data frame with soil layers in rows and physical attributes in columns. The model accepts one to five soil layers with arbitrary widths. Soil physical attributes can be initialized to default values, for a given number of layers, using function defaultSoilParams():

spar = defaultSoilParams(2)
print(spar)
##   widths clay sand om  bd rfc
## 1    300   25   25 NA 1.5  20
## 2    700   25   25 NA 1.5  40

where widths are soil layer widths in mm; clay and sand are the percentage of clay and sand, in percent of dry weight, om stands for organic matter, bd is bulk density (in g·cm\(^{-3}\)) and rfc the percentage of rock fragments. Because soil properties vary strongly at fine spatial scales, ideally soil physical attributes should be measured on samples taken at the forest stand to be simulated. For those users lacking such data, soil properties modelled at larger scales are available via soilgrids.org (see function soilgridsParams()).

Soil input object

The soil input for function spwb() is actually an object of class soil that is created using a function with the same name:

examplesoil = soil(spar, VG_PTF = "Toth")
names(examplesoil)
##  [1] "SoilDepth"    "W"            "SWE"          "Temp"        
##  [5] "Ksoil"        "Gsoil"        "dVec"         "sand"        
##  [9] "clay"         "om"           "usda_Type"    "VG_alpha"    
## [13] "VG_n"         "VG_theta_res" "VG_theta_sat" "macro"       
## [17] "rfc"

In addition to the physical soil description, this object contains soil parameters needed for soil water balance simulations. For example, macro specifies the macroporosity of each layer; Gsoil and Ksoil are parameters needed to model the process of water infiltration into the soil. The meaning of all elements in the soil object can be found in the help page for function soil().

The soil object is also used to store the moisture degree of each soil layer. In particular, W contains the state variable that represents moisture content - the proportion of moisture relative to field capacity - which is normally initialized to 1 for each layer:

examplesoil$W
## [1] 1 1

It is important to remember that, unlike normal objects in R, any water balance simulation will modify the moisture values in soil object. That is, the state of the soil at the end of the simulated process (i.e. W) will be stored. Hence, one can use the same object to simulate water balance sequentially and the final state of one simulation is the initial state of the next.

Water retention curves

At any time, one can print the status of the soil object using its print function:

print(examplesoil, model = "SX")
## Soil depth (mm): 1000 
## 
## Layer  1  [ 0  to  300 mm ] 
##     clay (%): 25 silt (%): 50 sand (%): 25 organic matter (%): NA [ Silt loam ]
##     Rock fragment content (%): 20 Macroporosity (%): 5 
##     Theta WP (%): 14 Theta FC (%): 30 Theta SAT (%): 49 Theta current (%) 30 
##     Vol. WP (mm): 34 Vol. FC (mm): 73 Vol. SAT (mm): 118 Vol. current (mm): 73 
##     Temperature (Celsius): NA 
## 
## Layer  2  [ 300  to  1000 mm ] 
##     clay (%): 25 silt (%): 50 sand (%): 25 organic matter (%): NA [ Silt loam ]
##     Rock fragment content (%): 40 Macroporosity (%): 5 
##     Theta WP (%): 14 Theta FC (%): 30 Theta SAT (%): 49 Theta current (%) 30 
##     Vol. WP (mm): 60 Vol. FC (mm): 127 Vol. SAT (mm): 207 Vol. current (mm): 127 
##     Temperature (Celsius): NA 
## 
## Total soil saturated capacity (mm): 325 
## Total soil water holding capacity (mm): 200 
## Total soil extractable water (mm): 106 
## Total soil current Volume (mm): 200 
## Water table depth (mm): 1000 
## 
## Snow pack water equivalent (mm): 0

The modelled moisture content of the soil depends on the water retention curve used to represent the relationship between soil volumetric water content (\(\theta\); %) and soil water potential (\(\Psi\); MPa). By default the Saxton (model = "SX") equations are used as water retention curve, but the user may choose to follow Van Genuchten - Mualem equations, which will give different values for the same texture:

print(examplesoil, model="VG")
## Soil depth (mm): 1000 
## 
## Layer  1  [ 0  to  300 mm ] 
##     clay (%): 25 silt (%): 50 sand (%): 25 organic matter (%): NA [ Silt loam ]
##     Rock fragment content (%): 20 Macroporosity (%): 5 
##     Theta WP (%): 13 Theta FC (%): 29 Theta SAT (%): 42 Theta current (%) 29 
##     Vol. WP (mm): 32 Vol. FC (mm): 68 Vol. SAT (mm): 102 Vol. current (mm): 68 
##     Temperature (Celsius): NA 
## 
## Layer  2  [ 300  to  1000 mm ] 
##     clay (%): 25 silt (%): 50 sand (%): 25 organic matter (%): NA [ Silt loam ]
##     Rock fragment content (%): 40 Macroporosity (%): 5 
##     Theta WP (%): 13 Theta FC (%): 30 Theta SAT (%): 42 Theta current (%) 30 
##     Vol. WP (mm): 54 Vol. FC (mm): 127 Vol. SAT (mm): 178 Vol. current (mm): 127 
##     Temperature (Celsius): NA 
## 
## Total soil saturated capacity (mm): 280 
## Total soil water holding capacity (mm): 196 
## Total soil extractable water (mm): 111 
## Total soil current Volume (mm): 196 
## Water table depth (mm): 1000 
## 
## Snow pack water equivalent (mm): 0

While Saxton equations use texture and organic matter as inputs, the Van Genuchten-Mualem equations need other parameters, which are estimated using pedotransfer functions and their names start with VG_ (two alternative options are provided in function soil to estimate Van Genuchten parameters). The following figure illustrates the difference between the two water retention models:

par(mar=c(4,4,1,1))
# Plot Saxton's retention curve
psi = seq(-0.001, -2.0, by=-0.001)
plot(-psi, lapply(as.list(psi), FUN=soil.psi2thetaSX, clay=25, sand=25),
type="l", ylim=c(0,0.5),ylab="Water content (prop. volume)", xlab = "Soil water potential (-MPa)")
#Add Van Genuchten retention curve
lines(-psi, lapply(as.list(psi), FUN=soil.psi2thetaVG,
alpha=examplesoil$VG_alpha[1], n = examplesoil$VG_n[1],
theta_res = examplesoil$VG_theta_res[1],
theta_sat = examplesoil$VG_theta_sat[1]), lty=2)
legend("topright", legend=c("Saxton", "Van Genuchten"), lty=c(1,2), bty="n")

Functions soil.psi2thetaSX() and soil.psi2thetaVG() (and their counterparts) can be used to calculate volumetric soil moisture from the water potential using the two models. When simulating soil water balance, the user can choose among the two models (see control parameters below).

Species data

Simulation models in medfate require a data frame with species parameter values. The package provides a default data set of parameter values for 89 Mediterranean species (rows), resulting from bibliographic search, fit to empirical data or expert-based guesses:

data("SpParamsMED")

These species commonly occur in the Spanish forest inventory of Catalonia, but may not be sufficient for other areas. A large number of parameters (columns) can be found in SpParamsMED:

names(SpParamsMED)
##  [1] "Name"               "IFNcodes"           "SpIndex"           
##  [4] "Group"              "Order"              "Family"            
##  [7] "GrowthForm"         "TreeType"           "Hmed"              
## [10] "Hmax"               "Z50"                "Z95"               
## [13] "Zmax"               "a_ash"              "a_bsh"             
## [16] "b_bsh"              "cr"                 "a_fbt"             
## [19] "b_fbt"              "c_fbt"              "d_fbt"             
## [22] "a_cr"               "b_1cr"              "b_2cr"             
## [25] "b_3cr"              "c_1cr"              "c_2cr"             
## [28] "a_cw"               "b_cw"               "fHDmin"            
## [31] "fHDmax"             "SLA"                "LeafDensity"       
## [34] "r635"               "pDead"              "maxFMC"            
## [37] "minFMC"             "LeafPI0"            "LeafEPS"           
## [40] "LeafAF"             "StemPI0"            "StemEPS"           
## [43] "StemAF"             "LeafDuration"       "LigninPercent"     
## [46] "ParticleDensity"    "LeafLitterFuelType" "Flammability"      
## [49] "SAV"                "HeatContent"        "albedo"            
## [52] "k"                  "g"                  "Sgdd"              
## [55] "Psi_Extract"        "WUE"                "pRootDisc"         
## [58] "Gwmin"              "Gwmax"              "VCleaf_kmax"       
## [61] "VCleaf_c"           "VCleaf_d"           "Kmax_stemxylem"    
## [64] "VCstem_c"           "VCstem_d"           "Kmax_rootxylem"    
## [67] "VCroot_c"           "VCroot_d"           "LeafWidth"         
## [70] "Vmax298"            "Jmax298"            "Al2As"             
## [73] "WoodDensity"        "WoodC"              "RGRmax"            
## [76] "Cstoragepmax"

Not all parameters are needed for all models. The user can find parameter definitions in the help page of this data set. However, to fully understand the role of parameters in the model, the user should read the details of model design and formulation (http://vegmod.ctfc.cat/medfateweb).

Vegetation

Forest plot data

Models included in medfate were primarily designed to be ran on forest inventory plots. In this kind of data, the vegetation of a sampled area is described in terms of woody plants (trees and shrubs) along with their size and species identity. Forest plots in medfate are assumed to be in a format that follows closely the Spanish forest inventory. Each forest plot is represented in an object of class forest, a list that contains several elements. Among them, the most important items are two data frames, treeData (for trees) and shrubData for shrubs:

data(exampleforest)
exampleforest
## $ID
## [1] "1"
## 
## $patchsize
## [1] 10000
## 
## $treeData
##   Species   N   DBH Height Z50  Z95
## 1      54 168 37.55    800 750 3000
## 2      68 384 14.60    660 750 3000
## 
## $shrubData
##   Species Cover Height Z50  Z95
## 1      65  3.75     30  50 1000
## 
## $herbCover
## [1] 10
## 
## $herbHeight
## [1] 20
## 
## $seedBank
##   Species Abundance
## 5      54       100
## 8      65       100
## 9      68       100
## 
## attr(,"class")
## [1] "forest" "list"

Trees are expected to be primarily described in terms of species, diameter (DBH) and height, whereas shrubs are described in terms of species, percent cover and mean height.

Aboveground and belowground data tables

Because the forest plot format is rather specific, simulation functions in medfate allow starting in a more general way using two data frames, one with aboveground information (i.e. the leave area and size of plants) and the other with belowground information (i.e. root distribution). The aboveground data frame does not distinguish between trees and shrubs. It includes, for each plant cohort to be considered in rows, its species identity, height and leaf area index (LAI). While users can build their input data themselves, we use function forest2aboveground() on the object exampleforest to show how should the data look like:

above = forest2aboveground(exampleforest, SpParamsMED)
above
##       SP        N   DBH Cover   H        CR   LAI_live LAI_expanded
## T1_54 54  168.000 37.55    NA 800 0.7150421 0.81630007   0.81630007
## T2_68 68  384.000 14.60    NA 660 0.6055507 0.79744714   0.79744714
## S1_65 65 5504.183    NA  3.75  30 0.9740000 0.08911235   0.08911235
##       LAI_dead
## T1_54        0
## T2_68        0
## S1_65        0

Note that the call to forest2aboveground() included species parameters, because species-specific values are needed to calculate leaf area from tree diameters or shrub cover. Columns N, DBH and Cover are required for simulating growth, but not for soil water balance, which only requires columns SP, H (in cm), CR (i.e. the crown ratio), LAI_live, LAI_expanded and LAI_dead. Here plant cohorts are given unique codes that tell us whether they correspond to trees or shrubs, but the user can use other row identifiers as long as they are unique. In practice, the user only needs to worry to calculate the values for LAI_live. LAI_live and LAI_expanded can contain the same LAI values, and LAI_dead is normally zero. This is so because models update LAI_expanded and LAI_dead according to the leaf phenology of species.

Regarding belowground information, a matrix describing for each plant cohort, the proportion of fine roots in each soil layer. As before, we use function forest2belowground() on the object exampleforest to show how should the data look like:

below = forest2belowground(exampleforest, examplesoil, SpParamsMED)
below
##               1         2
## T1_54 0.1933638 0.8066362
## T2_68 0.1933638 0.8066362
## S1_65 0.8981075 0.1018925

Function forest2belowground() internally takes values of Z50 and Z95 and calls function root.ldrDistribution() to estimate the distribution of fine roots according to the linear dose response model. For example the first row is:

root.ldrDistribution(exampleforest$treeData$Z50[1],
exampleforest$treeData$Z95[1],
examplesoil$dVec)
##           [,1]      [,2]
## [1,] 0.1933638 0.8066362

An analogous function root.conicDistribution() can be used to estimate fine root distribution according to a cone. The user is free to build any numeric matrix for root distribution, as long as values in rows sum always one (i.e. we have proportions). Otherwise, functions root.conicDistribution() and root.ldrDistribution() can be used to calculate root distribution under specific assumptions.

Meteorological forcing

Soil water simulations require daily weather inputs. The weather variables that are required depend on the complexity of the soil water balance model we are using. In the simplest case, only mean temperature, precipitation and potential evapotranspiration is required, but the more complex simulation model also requires radiation, wind speed, min/max temparature and relative humitidy. Here we show an example of meteorological forcing data.

data(examplemeteo)
head(examplemeteo)
##            MeanTemperature MinTemperature MaxTemperature Precipitation
## 2001-01-01      3.57668969     -0.5934215       6.287950      4.869109
## 2001-01-02      1.83695972     -2.3662458       4.569737      2.498292
## 2001-01-03      0.09462563     -3.8541036       2.661951      0.000000
## 2001-01-04      1.13866156     -1.8744860       3.097705      5.796973
## 2001-01-05      4.70578690      0.3288287       7.551532      1.884401
## 2001-01-06      4.57036721      0.5461322       7.186784     13.359801
##            MeanRelativeHumidity MinRelativeHumidity MaxRelativeHumidity
## 2001-01-01             78.73709            65.15411           100.00000
## 2001-01-02             69.70800            57.43761            94.71780
## 2001-01-03             70.69610            58.77432            94.66823
## 2001-01-04             76.89156            66.84256            95.80950
## 2001-01-05             76.67424            62.97656           100.00000
## 2001-01-06             89.01940            74.25754           100.00000
##            Radiation WindSpeed WindDirection       PET
## 2001-01-01  12.89251  2.000000           172 1.3212770
## 2001-01-02  13.03079  7.662544           278 2.2185985
## 2001-01-03  16.90722  2.000000           141 1.8045176
## 2001-01-04  11.07275  2.000000           172 0.9200627
## 2001-01-05  13.45205  7.581347           321 2.2914449
## 2001-01-06  12.84841  6.570501           141 1.7255058

Simulation models in medfate have been designed to work along with data generated from package meteoland. The user is strongly recommended to resort to this package to obtain suitable weather input for soil water balance simulations.

Simulation control

Apart from data inputs, the behaviour of simulation models can be controlled using a set of global parameters. The default parameterization is obtained using function defaultControl():

control = defaultControl()
control
## $verbose
## [1] TRUE
## 
## $subdailyResults
## [1] FALSE
## 
## $soilFunctions
## [1] "SX"
## 
## $snowpack
## [1] TRUE
## 
## $drainage
## [1] TRUE
## 
## $transpirationMode
## [1] "Simple"
## 
## $hydraulicCostFunction
## [1] 1
## 
## $verticalLayerSize
## [1] 100
## 
## $nStemSegments
## [1] 1
## 
## $capacitance
## [1] FALSE
## 
## $cavitationRefill
## [1] TRUE
## 
## $klat
## [1] 0.1
## 
## $taper
## [1] TRUE
## 
## $numericParams
## $numericParams$maxNsteps
## [1] 400
## 
## $numericParams$ntrial
## [1] 200
## 
## $numericParams$psiTol
## [1] 1e-04
## 
## $numericParams$ETol
## [1] 1e-07
## 
## 
## $averageFracRhizosphereResistance
## [1] 0.15
## 
## $Catm
## [1] 386
## 
## $ndailysteps
## [1] 24
## 
## $thermalCapacityLAI
## [1] 1e+06
## 
## $defaultWindSpeed
## [1] 5
## 
## $storagePool
## [1] "none"

Most of these parameters should normally be left to their default value. However, there are three that deserve explanation here:

  1. Console output can be turned off by setting verbose = FALSE.
  2. The soil water retention curves can be switched between Saxton’s and Van Genuchten’s using parameter soilFunctions.
  3. The complexity of the soil water balance calculations will be very different if we set transpirationMode = "Complex". Most of the other options apply in the case of complex soil water balance only.
  4. Non-reversible cavitation can be forced by setting cavitationRefill = FALSE.

Water balance input object

A last step is needed before calling simulation functions. It consists in the compilation of all aboveground and belowground parameters and the specification of additional parameter values for each plant cohort, such as their light extinction coefficient or their response to drought. This is done by calling function spwbInput() and taking species parameter values from species parameter data:

x = spwbInput(above, below, examplesoil, SpParamsMED, control)

Different parameter variables will be drawn depending on the value of transpirationMode. For the simple model, relatively few parameters are needed. All the input information for forest data and species parameter values can be inspected by printing the input object.

x
## $control
## $control$verbose
## [1] TRUE
## 
## $control$subdailyResults
## [1] FALSE
## 
## $control$soilFunctions
## [1] "SX"
## 
## $control$snowpack
## [1] TRUE
## 
## $control$drainage
## [1] TRUE
## 
## $control$transpirationMode
## [1] "Simple"
## 
## $control$hydraulicCostFunction
## [1] 1
## 
## $control$verticalLayerSize
## [1] 100
## 
## $control$nStemSegments
## [1] 1
## 
## $control$capacitance
## [1] FALSE
## 
## $control$cavitationRefill
## [1] TRUE
## 
## $control$klat
## [1] 0.1
## 
## $control$taper
## [1] TRUE
## 
## $control$numericParams
## $control$numericParams$maxNsteps
## [1] 400
## 
## $control$numericParams$ntrial
## [1] 200
## 
## $control$numericParams$psiTol
## [1] 1e-04
## 
## $control$numericParams$ETol
## [1] 1e-07
## 
## 
## $control$averageFracRhizosphereResistance
## [1] 0.15
## 
## $control$Catm
## [1] 386
## 
## $control$ndailysteps
## [1] 24
## 
## $control$thermalCapacityLAI
## [1] 1e+06
## 
## $control$defaultWindSpeed
## [1] 5
## 
## $control$storagePool
## [1] "none"
## 
## 
## $canopy
## $canopy$gdd
## [1] 0
## 
## 
## $cohorts
##       SP              Name
## T1_54 54  Pinus halepensis
## T2_68 68      Quercus ilex
## S1_65 65 Quercus coccifera
## 
## $above
##         H        CR   LAI_live LAI_expanded LAI_dead
## T1_54 800 0.7150421 0.81630007   0.81630007        0
## T2_68 660 0.6055507 0.79744714   0.79744714        0
## S1_65  30 0.9740000 0.08911235   0.08911235        0
## 
## $below
## $below$V
##               1         2
## T1_54 0.1933638 0.8066362
## T2_68 0.1933638 0.8066362
## S1_65 0.8981075 0.1018925
## 
## 
## $paramsBase
##       albedo    k    g Sgdd
## T1_54   0.14 0.50 1.00    0
## T2_68   0.18 0.55 0.50    0
## S1_65   0.18 0.55 0.25    0
## 
## $paramsTransp
##       Psi_Extract WUE pRootDisc
## T1_54          -2   6         0
## T2_68          -3   6         0
## S1_65          -4   6         0
## 
## $Transpiration
## T1_54 T2_68 S1_65 
##     0     0     0 
## 
## $Photosynthesis
## T1_54 T2_68 S1_65 
##     0     0     0 
## 
## $PLC
## [1] 0 0 0
## 
## attr(,"class")
## [1] "spwbInput" "list"

As with the soil input object, the spwbInput object may be modified during simulations. In the case of soil water balance, these modifications are minimal, for example concerning LAI_expanded, but in the case of growth simulations the object is used to store the status of vegetation during and at the end of simulations. If one has a forest object, the spwbInput object can be generated in directly from it, avoiding the need to explicitly build aboveground and belowground data frames:

x = forest2spwbInput(exampleforest, examplesoil, SpParamsMED, control)

Finally, note that one can play with plant-specific parameters for soil water balance (instead of using species-level values) by modifying manually the parameter values in this object.

Executing the soil water balance model

Water balance for a single day

Soil water balance simulations will normally span periods of several months or years, but since the model operates at a daily temporal scale, it is possible to perform soil water balance for one day only. This is done using function spwb.day(). In the following code we select day 100 from the meteorological input data and perform soil water balance for that day only:

d = 100
sd1<-spwb.day(x, examplesoil, rownames(examplemeteo)[d],
examplemeteo$MinTemperature[d], examplemeteo$MaxTemperature[d],
examplemeteo$MinRelativeHumidity[d], examplemeteo$MaxRelativeHumidity[d],
examplemeteo$Radiation[d], examplemeteo$WindSpeed[d],
latitude = 41.82592, elevation = 100,
slope= 0, aspect = 0, prec = examplemeteo$Precipitation[d])

Function spwb.day() is most useful when working with the complex transpiration model. This is why so many meteorological variables are required. The output of spwb.day() is a list with three elements:

names(sd1)
## [1] "cohorts"      "WaterBalance" "Soil"         "Plants"
sd1
## $cohorts
##       SP              Name
## T1_54 54  Pinus halepensis
## T2_68 68      Quercus ilex
## S1_65 65 Quercus coccifera
## 
## $WaterBalance
##             PET            Rain            Snow         NetRain 
##       5.0233468       0.0000000       0.0000000       0.0000000 
##           Runon    Infiltration          Runoff    DeepDrainage 
##       0.0000000       0.0000000       0.0000000       0.0000000 
## SoilEvaporation PlantExtraction   Transpiration         LAIcell 
##       0.5000000       1.0588430       1.0588430       1.7028596 
##     LAIcelldead              Cm         Lground 
##       0.0000000       1.2373017       0.4082981 
## 
## $Soil
##   SoilEvaporation PlantExtraction    psi
## 1    4.999998e-01       0.2340415 -0.033
## 2    1.529512e-07       0.8248016 -0.033
## 
## $Plants
##              LAI Transpiration    psi          DDS
## T1_54 0.81630007    0.50990026 -0.033 3.113699e-06
## T2_68 0.79744714    0.50736806 -0.033 9.225785e-07
## S1_65 0.08911235    0.04157472 -0.033 3.892129e-07
## 
## attr(,"class")
## [1] "spwb.day" "list"

Water balance for multiple days

Most often, users will use function spwb() to run the soil water balance model. This function requires the spwbInput object, the soil object and the meteorological data frame. However, function spwb.day() modified the state variables of the input objects. In particular, the values of soil moisture and cumulative growth degree days are now:

examplesoil$W
## [1] 0.9899190 0.9935271
x$canopy$gdd
## [1] 1.232373

We simply reset state variables to their default values so that new simulations are not affected by the end state of the previous simulation:

spwb.resetInputs(x, examplesoil)
examplesoil$W
## [1] 1 1
x$canopy$gdd
## [1] 0

Now we are ready to call function spwb():

S = spwb(x, examplesoil, examplemeteo, elevation = 100)
## W1i:1 W2i:1 
## Daily balance:.............................................................................................................................................................................................................................................................................................................................................................................done
## Precipitation (mm) 513
## Rain (mm) 462 Snow (mm) 51
## Interception (mm) 99 Net rainfall (mm) 364
## Infiltration (mm) 454 Runoff (mm) 8 Deep drainage (mm) 129
## Soil evaporation (mm) 48 Transpiration (mm) 297
## W1f:0.92 W2f:0.89 
## Final soil water content (mm): 180
## 
## Building SPWB output ...done.

Function spwb() returns an object of class with the same name, actually a list:

class(S)
## [1] "spwb" "list"

If we inspect its elements, we realize that the output is arranged differently than in spwb.day():

names(S)
##  [1] "spwbInput"           "soilInput"           "WaterBalance"       
##  [4] "Soil"                "PlantLAI"            "PlantTranspiration" 
##  [7] "PlantPhotosynthesis" "PlantPsi"            "PlantStress"        
## [10] "subdaily"

In particular, element spwbInput contains a copy of the input parameters that were used to run the model:

names(S$spwbInput)
##  [1] "control"        "canopy"         "cohorts"        "above"         
##  [5] "below"          "paramsBase"     "paramsTransp"   "Transpiration" 
##  [9] "Photosynthesis" "PLC"

As before, WaterBalance contains water balance components, but in this case in form of a data frame with days in rows:

head(S$WaterBalance)
##            GDD LAIcell LAIcelldead       Cm   Lground       PET
## 2001-01-01   0 1.70286           0 1.237302 0.4082981 1.3212770
## 2001-01-02   0 1.70286           0 1.237302 0.4082981 2.2185985
## 2001-01-03   0 1.70286           0 1.237302 0.4082981 1.8045176
## 2001-01-04   0 1.70286           0 1.237302 0.4082981 0.9200627
## 2001-01-05   0 1.70286           0 1.237302 0.4082981 2.2914449
## 2001-01-06   0 1.70286           0 1.237302 0.4082981 1.7255058
##            Precipitation      Rain Snow    NetRain Infiltration Runoff
## 2001-01-01      4.869109  4.869109    0  3.1885130    3.1885130      0
## 2001-01-02      2.498292  2.498292    0  1.0982592    1.0982592      0
## 2001-01-03      0.000000  0.000000    0  0.0000000    0.0000000      0
## 2001-01-04      5.796973  5.796973    0  4.0065734    4.0065734      0
## 2001-01-05      1.884401  1.884401    0  0.7693975    0.7693975      0
## 2001-01-06     13.359801 13.359801    0 10.6744131   10.6744131      0
##            DeepDrainage Evapotranspiration Interception SoilEvaporation
## 2001-01-01    3.1885130          2.4591004     1.680596       0.5000000
## 2001-01-02    0.3197546          2.3676783     1.400032       0.5000000
## 2001-01-03    0.0000000          0.5606118     0.000000       0.1802478
## 2001-01-04    2.4783156          2.4581971     1.790400       0.4738627
## 2001-01-05    0.1016000          2.0980047     1.115004       0.5000000
## 2001-01-06    9.6914123          3.5490972     2.685388       0.5000000
##            PlantExtraction Transpiration
## 2001-01-01       0.2785046     0.2785046
## 2001-01-02       0.4676459     0.4676459
## 2001-01-03       0.3803641     0.3803641
## 2001-01-04       0.1939349     0.1939349
## 2001-01-05       0.4830008     0.4830008
## 2001-01-06       0.3637097     0.3637097

Elements PlantLAI, PlantStress, PlantPsi, PlantTranspiration and PlantPhotosynthesis contain daily values by plant cohorts, for example plant water potentials are:

head(S$PlantPsi)
##                  T1_54       T2_68       S1_65
## 2001-01-01 -0.03300000 -0.03300000 -0.03300000
## 2001-01-02 -0.03300000 -0.03300000 -0.03300000
## 2001-01-03 -0.03366851 -0.03366851 -0.03432907
## 2001-01-04 -0.03300000 -0.03300000 -0.03300000
## 2001-01-05 -0.03300000 -0.03300000 -0.03300000
## 2001-01-06 -0.03300000 -0.03300000 -0.03300000

Plotting results

Package medfate provides a simple plot function for objects of class spwb. It can be used to show the meteorological input:

par(mar=c(5,5,1,1))
plot(S, type = "PET_Precipitation")

Since this simulations include snow dynamics, we can plot the water input in form of snow and the dynamics of the snowpack.

par(mar=c(5,5,1,1))
plot(S, type = "Snow")

It is also useful to plot the dynamics of soil state variables by layer, such as the percentage of moisture in relation to field capacity:

par(mar=c(5,5,1,1))
plot(S, type="SoilTheta")

Or soil water potentials:

par(mar=c(5,5,1,1))
plot(S, type="SoilPsi")

Additionally, it can also be used to draw plant variables, such as plant transpiration:

par(mar=c(5,5,1,1))
plot(S, type="PlantTranspiration")

Generating output summaries

While the simulation model uses daily steps, users will normally be interested in outputs at larger time scales. The package provides a summary for objects of class spwb. This function can be used to summarize the model’s output at different temporal steps (i.e. weekly, annual, …). For example, to obtain the average soil moisture and water potentials by months one can use:

summary(S, freq="months",FUN=mean, output="Soil")
##                  W.1       W.2     ML.1      ML.2    MLTot  WTD        SWE
## 2001-01-01 0.9896225 0.9958004 72.05855 126.88968 198.9482 1000 1.65045409
## 2001-02-01 0.9735915 0.9633684 70.89127 122.75704 193.6483 1000 0.27477726
## 2001-03-01 0.9762610 0.9663211 71.08564 123.13328 194.2189 1000 0.01762496
## 2001-04-01 0.9601092 0.8746602 69.90956 111.45340 181.3630 1000 0.57892253
## 2001-05-01 0.9500448 0.9266482 69.17673 118.07797 187.2547 1000 0.00000000
## 2001-06-01 0.8355693 0.7017067 60.84129  89.41484 150.2561 1000 0.00000000
## 2001-07-01 0.9638331 0.7368312 70.18071  93.89058 164.0713 1000 0.00000000
## 2001-08-01 0.9649472 0.8092188 70.26184 103.11456 173.3764 1000 0.00000000
## 2001-09-01 0.9646835 0.8443110 70.24264 107.58617 177.8288 1000 0.00000000
## 2001-10-01 0.9786082 0.8601130 71.25655 109.59973 180.8563 1000 0.00000000
## 2001-11-01 0.9708081 0.9395455 70.68859 119.72141 190.4100 1000 2.59359494
## 2001-12-01 0.9403160 0.9292005 68.46834 118.40320 186.8715 1000 0.00000000
##            PlantExt.1 PlantExt.2       psi.1       psi.2
## 2001-01-01 0.06683854  0.2355503 -0.03406229 -0.03345586
## 2001-02-01 0.13942295  0.4913494 -0.03741046 -0.04002574
## 2001-03-01 0.14487045  0.5105474 -0.03642897 -0.03891798
## 2001-04-01 0.18487080  0.6515064 -0.04008745 -0.06573411
## 2001-05-01 0.21820974  0.7690031 -0.04311717 -0.05030673
## 2001-06-01 0.31108832  1.0945499 -0.08255836 -0.23611310
## 2001-07-01 0.26258670  0.9219999 -0.03921643 -0.23772034
## 2001-08-01 0.26529184  0.9348716 -0.03851804 -0.09802990
## 2001-09-01 0.20820865  0.7337453 -0.03899551 -0.07707626
## 2001-10-01 0.14934869  0.5263139 -0.03631734 -0.07469575
## 2001-11-01 0.10787654  0.3801738 -0.03781471 -0.04572363
## 2001-12-01 0.10089653  0.3555757 -0.04519835 -0.04838294

Parameter output is used to indicate the element of the spwb object for which we desire summaries. Similarly, it is possible to calculate the average stress of plant cohorts by months:

summary(S, freq="months",FUN=mean, output="PlantStress")
##                   T1_54        T2_68        S1_65
## 2001-01-01 3.282798e-06 9.726819e-07 4.267819e-07
## 2001-02-01 5.614420e-06 1.663536e-06 5.914400e-07
## 2001-03-01 5.225700e-06 1.548359e-06 5.491305e-07
## 2001-04-01 2.495126e-05 7.393080e-06 1.016845e-06
## 2001-05-01 1.304102e-05 3.864041e-06 1.034090e-06
## 2001-06-01 1.913494e-03 5.685156e-04 3.617461e-05
## 2001-07-01 4.579882e-03 1.367567e-03 7.387092e-05
## 2001-08-01 8.892996e-05 2.635143e-05 1.968106e-06
## 2001-09-01 3.637437e-05 1.077779e-05 1.165768e-06
## 2001-10-01 4.121765e-05 1.221299e-05 1.107669e-06
## 2001-11-01 8.745022e-06 2.591129e-06 6.701548e-07
## 2001-12-01 9.895270e-06 2.931943e-06 1.046359e-06

The summary function can be also used to aggregate the output by species. In this case, the values of plant cohorts belonging to the same species will be averaged using LAI values as weights. For example, we may average the daily drought stress across cohorts of the same species (here there is only one cohort by species, so this does not modify the output):

head(summary(S, freq="day", output="PlantStress", bySpecies = TRUE))
##            Pinus halepensis Quercus coccifera Quercus ilex
## 2001-01-01     3.113699e-06      3.892129e-07 9.225785e-07
## 2001-01-02     3.113699e-06      3.892129e-07 9.225785e-07
## 2001-01-03     3.306787e-06      4.381586e-07 9.797900e-07
## 2001-01-04     3.113699e-06      3.892129e-07 9.225785e-07
## 2001-01-05     3.113699e-06      3.892129e-07 9.225785e-07
## 2001-01-06     3.113699e-06      3.892129e-07 9.225785e-07

Or we can combine the aggregation by species with a temporal aggregation (here monthly averages):

summary(S, freq="month", FUN = mean, output="PlantStress", bySpecies = TRUE)
##            Pinus halepensis Quercus coccifera Quercus ilex
## 2001-01-01     3.282798e-06      4.267819e-07 9.726819e-07
## 2001-02-01     5.614420e-06      5.914400e-07 1.663536e-06
## 2001-03-01     5.225700e-06      5.491305e-07 1.548359e-06
## 2001-04-01     2.495126e-05      1.016845e-06 7.393080e-06
## 2001-05-01     1.304102e-05      1.034090e-06 3.864041e-06
## 2001-06-01     1.913494e-03      3.617461e-05 5.685156e-04
## 2001-07-01     4.579882e-03      7.387092e-05 1.367567e-03
## 2001-08-01     8.892996e-05      1.968106e-06 2.635143e-05
## 2001-09-01     3.637437e-05      1.165768e-06 1.077779e-05
## 2001-10-01     4.121765e-05      1.107669e-06 1.221299e-05
## 2001-11-01     8.745022e-06      6.701548e-07 2.591129e-06
## 2001-12-01     9.895270e-06      1.046359e-06 2.931943e-06

Water balance without cavitation refill

One of the simulation control parameters allows specifying that refilling of conduits does not occur after cavitation, so that plants cannot recover from drought stress. To simulate this behaviour we set cavitationRefill = FALSE (we also turn off console output):

x$control$cavitationRefill = FALSE
x$control$verbose = FALSE

We re-run the water balance model after resetting state variables

spwb.resetInputs(x, examplesoil)
Snr = spwb(x, examplesoil, examplemeteo, elevation=100)

In this case no console output is produced during the simulation process. We can examine the effect of preventing cavitation refill in the plots of plant drought stress and plant transpiration:

par(mar=c(5,5,1,1), mfrow=c(1,2))
plot(Snr, type="PlantStress")
plot(Snr, type="PlantTranspiration")

Water balance for a set of forest stands

So far, we used spwb() to simulate soil water balance on a single stand. Package medfate offers the possibility to conduct simulations on a set of forest stands in one call, using function spwbpoints(). This function takes an object of class SpatialPointsForest as input. We begin by loading an example dataset of 30 forest stands:

data("exampleSPL")
plot(exampleSPL)

As before, we need meteorological data, species parameters and control parameters (which will apply to all forest stands):

data("examplemeteo")
data("SpParamsMED")
control = defaultControl()
control$verbose = FALSE

The call to spwbpoints() can be done as follows:

res <- spwbpoints(exampleSPL, SpParamsMED, examplemeteo, control = control)
## 
## Processing 80001 at (402024, 4683921) - Meteorology - Soil water balance
## Processing 80002 at (399986, 4682988) - Meteorology - Soil water balance
## Processing 80003 at (401004, 4683037) - Meteorology - Soil water balance
## Processing 80004 at (402018, 4682997) - Meteorology - Soil water balance
## Processing 80005 at (400010, 4681938) - Meteorology - Soil water balance
## Processing 80006 at (397044, 4681032) - Meteorology - Soil water balance
## Processing 80007 at (399001, 4680983) - Meteorology - Soil water balance
## Processing 80008 at (401000, 4681017) - Meteorology - Soil water balance
## Processing 80009 at (402005, 4681013) - Meteorology - Soil water balance
## Processing 80010 at (393941, 4679962) - Meteorology - Soil water balance
## Processing 80011 at (394975, 4680031) - Meteorology - Soil water balance
## Processing 80012 at (396045, 4679970) - Meteorology - Soil water balance
## Processing 80013 at (396957, 4680027) - Meteorology - Soil water balance
## Processing 80014 at (398021, 4679971) - Meteorology - Soil water balance
## Processing 80015 at (398977, 4679962) - Meteorology - Soil water balance
## Processing 80016 at (392924, 4678941) - Meteorology - Soil water balance
## Processing 80017 at (393981, 4679007) - Meteorology - Soil water balance
## Processing 80018 at (395016, 4679013) - Meteorology - Soil water balance
## Processing 80019 at (395969, 4679058) - Meteorology - Soil water balance
## Processing 80020 at (397933, 4679078) - Meteorology - Soil water balance
## Processing 80021 at (399002, 4679035) - Meteorology - Soil water balance
## Processing 80022 at (402005, 4679039) - Meteorology - Soil water balance
## Processing 80023 at (394052, 4677980) - Meteorology - Soil water balance
## Processing 80024 at (395976, 4677996) - Meteorology - Soil water balance
## Processing 80025 at (401030, 4678059) - Meteorology - Soil water balance
## Processing 80026 at (394973, 4677026) - Meteorology - Soil water balance
## Processing 80027 at (395993, 4677015) - Meteorology - Soil water balance
## Processing 80028 at (398000, 4677031) - Meteorology - Soil water balance
## Processing 80029 at (399000, 4676978) - Meteorology - Soil water balance
## Processing 80030 at (400010, 4676998) - Meteorology - Soil water balance

For each forest stand described in the SpatialPointsForest object, function spwbpoints() first calls forest2spwbInput(), to generate the appropriate input, and then it calls spwb(). The elements of the result of calling spwbpoints() are:

names(res)
## [1] "sp"     "input"  "result"

where sp is object of class SpatialPoints with the spatial coordinates of forest stands. Vector input contains the spwbInput corresponding to each forest stand, and vector result contains the output of spwb() for each forest stand. This structure of the output of spwbpoints() allows querying information for the simulation of any forest stand. For example, if we want a monthly summary of species transpiration for the stand ‘80013’, we can use:

summary(res$result$`80013`, freq="months",FUN=sum,
output="PlantTranspiration", bySpecies = TRUE)
##            Amelanchier ovalis Buxus sempervirens Fagus sylvatica
## 2001-01-01                 NA          0.1854988              NA
## 2001-02-01                 NA          0.3495023              NA
## 2001-03-01        0.002159455          0.4020889    0.0004193099
## 2001-04-01        0.005903584          0.4965935    0.0011462411
## 2001-05-01        0.013562617          0.6056656    0.0026328944
## 2001-06-01        0.016643879          0.7939005    0.0032306465
## 2001-07-01        0.018215350          0.7038897    0.0035356755
## 2001-08-01        0.015696949          0.7092205    0.0030468433
## 2001-09-01        0.009685920          0.5299104    0.0018800776
## 2001-10-01        0.008011271          0.3937934    0.0015550211
## 2001-11-01                 NA          0.2852425              NA
## 2001-12-01                 NA          0.2799218              NA
##            Juniperus communis Pinus sylvestris Pinus uncinata  Sorbus spp.
## 2001-01-01          0.1323964        0.2846429      0.5194117           NA
## 2001-02-01          0.2494506        0.5363001      0.9786314           NA
## 2001-03-01          0.2869815        0.6170012      1.1258931 0.0001854806
## 2001-04-01          0.3544288        0.7619504      1.3903933 0.0005070367
## 2001-05-01          0.4322701        0.9271756      1.6918922 0.0011646537
## 2001-06-01          0.5654416        0.7423066      1.3545460 0.0014290677
## 2001-07-01          0.5014988        0.8123932      1.4824386 0.0015639965
## 2001-08-01          0.5057832        0.7000741      1.2774810 0.0013477629
## 2001-09-01          0.3776310        0.4319860      0.7882792 0.0008316472
## 2001-10-01          0.2805453        0.3572977      0.6519895 0.0006878594
## 2001-11-01          0.2035692        0.3594941      0.6559982           NA
## 2001-12-01          0.1997902        0.4273376      0.7797985           NA

If one needs to save memory, it is possible with spwbpoints() to generate summaries automatically after the simulation of soil water balance of each stand, and storing those summaries instead of all the output of spwb().