---
title: "Tutorial for R package kwb.wtaq"
author: "Hauke Sonnenberg & Michael Rustler (Kompetenzzentrum Wasser Berlin gGmbH)"
date: "`r format(Sys.Date(),format='%B %d, %Y')`"
output:
rmarkdown::html_document:
fig_height: 7
fig_width: 10
toc: true
toc_float: true
vignette: >
%\VignetteIndexEntry{Tutorial for R package kwb.wtaq}
%\VignetteEngine{knitr::rmarkdown}
%\usepackage[utf8]{inputenc}
---
# Introduction
**Background**
Within the OPTIWELLS-2 project, sponsored by Veolia Water, a detailed study was
performed for screening available models that:
- are able to simulate time-dependent well drawdown
- also include the additional drawdown in case of well interference and
- are quite easy to parameterise
The semi-analytical groundwater model WTAQ-2 was chosen, because it fitted best with the
above defined requirements. However, as the model is programmed in FORTRAN it requires
that the user follows the steps that are listed below:
- 1. Step: Definition and parameterisation of text input file,
- 2. Step: Execution of the WTAQ-2 model engine in MS DOS command shell
- 3. Step: Saving of model results in a text output file
- 4. Step: Reading and analysing of model outputs
- 5. Step (in case of well interference): looping through Steps 1-4 for each
active production well and superposition of additional drawdowns due to well interference
For simplifying this process it was decided to build an R package that enables to
perform all these steps and also includes the WTAQ-2 model engine (for more details
see: [Sonnenberg et al., 2014](https://doi.org/10.13140/RG.2.1.2140.3683)).
This R package *kwb.wtaq* was developed by Hauke Sonnenberg at Kompetenzzentrum
Wasser Berlin (KWB). It provides an Application Programming Interface (API) to the analytical
groundwater drawdown model WTAQ-2, developed by the
United States Geological Survey (USGS) and provided for free (for further
information on WTAQ-2 see: ).
In the following we will simply use "WTAQ" when referring to the software
WTAQ-2.
**Objective**
The objective of this tutorial is to demonstrate how the functions from the
R-package *kwb.wtaq* can be used to configure and run a WTAQ model setup and to
read the resulting groundwater drawdowns from the output files that are generated by
the WTAQ model software.
## Preparation
In order to use the R package you need to have the **R programming environment
(in version 3.0 or higher)** installed on your computer. You can download it
for free from .
As Integrated Programming Interface (IDE) for the R environment we recommend
--- and for the purpose of this tutorial require --- to use the free software **RStudio**.
You can download RStudio from: .
The programming environment R is shipped with a basic set of functions. It can be extended
by so-called packages that contain user-defined functions. We used this packaging
mechanism and provide the access functions to WTAQ in the form of an R package
that we named *kwb.wtaq*.
Before you can start using the functions provided in the package you need to
1. Install the package into your R programming environment and
2. Load the package into your current R session.
### Installation of required R packages
Since the package *kwb.wtaq* depends on a number of other packages, not only
*kwb.wtaq* but also all the packages that it depends on need to be installed.
In order to simplify the package installation run the following code:
```{r eval=FALSE}
if(!require("devtools")) { install.packages("devtools") }
devtools::install_github(repo = "KWB-R/kwb.wtaq", dependencies = TRUE)
```
This will download and install the package **[kwb.wtaq](https://github.com/KWB-R/kwb.wtaq)** with all required
dependencies, i.e.:
- publicly available packages from the Comprehensive R Archive Network (CRAN) and
- the KWB Github package [kwb.utils](https://github.com/KWB-R/kwb.utils)
If the installation succeeds the messages generated should read like these:
```{r}
## package 'zoo' successfully unpacked and MD5 sums checked
## package 'hydroGOF' successfully unpacked and MD5 sums checked
## package 'lattice' successfully unpacked and MD5 sums checked
## package 'plotrix' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Dokumente und Einstellungen\Key Hauke\Lokale Einstellungen\Temp\RtmpctBYMz\downloaded_packages
## package 'kwb.utils' successfully unpacked and MD5 sums checked
```
The installation needs to be done only once. The packages keep installed
until you decide to uninstall them. Uninstalling a package in RStudio can
be done by clicking on the `Remove package` button right to the
package name on the "Packages" tab.
### Loading the package
Once you have installed all the requied packages you are almost ready to use
the functions contained in the package *kwb.wtaq*.
As a last step you need to explicitly load the package into your current R
session by running the following R command:
```{r, warning = FALSE, message = TRUE}
library(kwb.wtaq)
```
You will see messages stating the progress of loading not only the package
*kwb.wtaq* but also of all the packages that it depends on.
You may see warnings that the packages have been built under R in a higher
version compared to the version that you are using:
```{r}
## Warning: package 'kwb.utils' was built under R version 3.0.3
```
Unless you are using R in a version prior to 3.0 these messages do not indicate
a problem and can be ignored.
Please note that the functions provided in the *kwb.wtaq* package can only be
used when the package is loaded with `library(kwb.wtaq)` as shown here.
This needs to be done each time you start a new R session or each time you
open RStudio.
If you write an R script that uses the functions from *kwb.wtaq* then
it would be a good practice to put `library(kwb.wtaq)` as one of the first
lines of your script.
## Using the package help
A detailed description of the WTAQ model parameters is available in the [WTAQ documentation](http://pubs.usgs.gov/tm/tm3b9/pdf/tm3-b9_barlow_wtaqv2_report.pdf). However, within 'RStudio' is not always necessary to consult this manual, because the parameter description is integrated in the **kwb.wtaq** package help. These information can be accessed by pressing `Ctrl` and `Space` simultaneously, if the cursor is located within a function, e.g. `wtConfGeneral()`:
![On the fly help in RStudio](pictures/ontheflyhelp.jpg)
The help file for each R function in `RStudio` can be accessed by using the R command `help(functionname)` or using `?` before the functionname, e.g.:
```{r, eval = FALSE}
?kwb.wtaq::wtConfigure
help(kwb.wtaq::wtConfigure)
```
**Note:**
*Typing `kwb.wtaq::` before the function name is only needed if you haven't loaded
the package into your R session with `library(kwb.wtaq)` (see [Loading the package](#loading-the-package))*
In addition, we also provide a [full description](kwbwtaq_ParameterTable.html)
of all the parameters that are accepted by the configuration functions, which
are descriped later in this tutorial.
# Example sessions
```{r echo = FALSE}
#Als Grundlage w?re ein gutes Beispielmodell mit guten Beispieldaten (Messdaten #f?r Kalibrierung) wichtig, das wir durchg?ngig verwenden k?nnen und das wir mit #in das Paket packen mit Zugriffsfunktionen, z.B. getTutorialData(), getTutorial#Model()
```
## Level 1: One pumping well
### Pumping test data
We have provided an example dataset "drawdowns" containing four different pumping
tests with measured drawdown time-series in five different wells (production well
and four observation wells). You can load the dataset by running:
```{r}
data("drawdowns", package = "kwb.wtaq")
```
Let's have a short look to the dataset. It is a list of four data frames as
the R command "str" reveals:
```{r}
str(drawdowns)
```
The four list elements represent four different pumping tests (in "W1", "W2", "W4"
and "W5". The resulting drawdowns of each pumping test are stored in a data frame
of six columns. Column "time.in.seconds" contains the time in seconds since the
start of a pumping test. The columns "W1" through "W5" contain the water table
drawdowns measured in the corresponding wells "W1" to "W5",in meters below the
initial water table.
For example, the fourth pumping test, during which a discharge of Q = 313 m3/h
was measured in Well W5, resulted in the following drawdowns:
```{r}
drawdowns[["W5"]]
```
It seems as if the drawdowns reach a steady-state after a certain time. This can
be judged better by a diagram that can be produced in R by using the xyplot
function from the R-package "lattice":
```{r invisible = TRUE, asis = TRUE}
lattice::xyplot(W1 + W2 + W3 + W4 + W5 ~ time.in.seconds,
data = drawdowns[["W5"]],
type = c("b", "g"), # (b)oth, dots and lines, and a (g)rid
auto.key = list(columns = 5), # legend arranged in five columns
ylim=c(1,-0.1),
ylab= "Drawdown (m)", # label of y-Axis
xlab= "Time in seconds since start of pumping in W5 (s)") # label of y-Axis
```
### Model parameterisation
In a first step a WTAQ input file needs to be defined. This can be realised with
two different functions:
* `wtConfigure()`: definition of WTAQ configuration within R
* `wtReadInputFile()`: importing of WTAQ configuration from existing WTAQ input
text file into R
The WTAQ input file can be directly defined in R using the function `wtConfigure()`
and saved in the R object `wtaqConfiguration` (for a full description of all the
parameters that are accepted by the configuration functions, see:
[Parameter tables](kwbwtaq_ParameterTable.html)).
```{r}
generalConfiguration <- wtConfigureGeneral(
### title of the project (max. length 70 characters)
title="Example well field, long-term pumping test of well 5"
)
aquiferConfiguration <- wtConfigureAquifer(
aqtype = "WATER TABLE", # aquifer type
bb = 10, # saturated aquifer thickness
hkr = 1E-03, # horizontal hydraulic conductivity
hkz = 3.5E-05, # vertical hydraulic conductivity
ss = 1E-05, # specific storage
sy = 0.05 # specific yield
)
drainageConfiguration <- wtConfigureDrainage(
idra = 0 # = instantaneous drainage in unsaturated zone
)
timesConfiguration <- wtConfigureTimes(
its = 1 # = user-specified time-steps
)
```
In the following we will configure one pumping well and two observation wells
(for simplifying the tutorial we restrict ourselves to two instead of four
observation wells four which drawdown time series are available).
Since WTAQ allows to define time-series of measured drawdowns for each well,
the corresponding functions `wtConfigurePumpwell()` and `wtConfigureObservationWell()`,
that are described in the following, also allow to specify these measured drawdown
values. For this example, we want to use the drawdowns of the fourth pumping test,
provided in the example dataset `drawdowns`. We store it in a separate variable
`drawdowns5`:
```{r}
drawdowns5 <- drawdowns[["W5"]]
```
Now we prepare some data frames (a table-like structure in R, defined by rows
and columns, see `?data.frame`) representing three drawdown time series, which
are measured at :
- the pumping well "PW" and
- two different observation wells "OW1" and "OW4".
By doing this we simplify the programmig code that is used later on:
```{r}
# the times of observations are the same for all wells:
times <- drawdowns5$time.in.seconds
# observed drawdowns at the pumping well
observed.PW <- data.frame(t = times, dd = drawdowns5$W5)
# observed drawdowns at the observation wells
observed.OW1 <- data.frame(t = times, dd = drawdowns5$W1)
observed.OW4 <- data.frame(t = times, dd = drawdowns5$W4)
```
Let's start with the configuration of the pumping well:
```{r}
pumpwellConfiguration <- wtConfigurePumpwell(
### partially penetrating pumped well
ipws = 0,
### finite diameter well
ipwd = 1,
### pumping rate of production well in (here: m3/s)
qq = 0.0869,
### radius of pumped well-screen (here: meter)
rw = 1.5,
### top of filter screen below initial water table (here: meter)
zpd = 0.4,
### bottom of filter screen below initial water table (here: meter)
zpl = 7.8,
### well-bore skin parameter (dimensionless)
sw = 0,
### data.frame with times and measured drawdown data in pumping well
tspw = observed.PW
)
```
Now, let's define our first observation well:
```{r}
observationWell1 <- wtConfigureObservationWell(
### name of observation well
obname = "OW1",
### distance from pumping well (here: meters)
r = 309.5,
### partially penetrating observation well
iows = 0,
### delayed response
idpr = 1,
### top of filter screen below initial water table (here: meters)
z1 = 1.8,
### bottom of filter screen below initial water table (here: meters)
z2 = 7.5,
### inside radius of the observation well (here: meters)
rp = 1.5,
### data.frame with times and measured drawdown data in OW1
tsobs= observed.OW1
)
```
In the same way, we define a second observation well "OW4"
(in a formally more compact way to save some space here):
```{r}
observationWell4 <- wtConfigureObservationWell(obname = "OW4", r = 86.6,
iows = 0, idpr = 1, z1 = 1.8, z2 = 7.5, rp = 1.5, tsobs = observed.OW4)
```
Out of these parts of configuration we can build one complete configuration by
using the function `wtConfigure()`. It returns a R list structure that represents
a model configuration containing all the necessary information that WTAQ
requires to perform a model run.
This information is saved in the R object `wtaqConfiguration` and will be
used for the following chapters of this tutorial.
```{r}
wtaqConfiguration <- wtConfigure(
general = generalConfiguration,
aquifer = aquiferConfiguration,
drainage = drainageConfiguration,
times = timesConfiguration,
solution = wtConfigureSolution(),
pumpwell = pumpwellConfiguration,
obswells = list(observationWell4,
observationWell1)
)
```
**Note:**
*Alternatively it is possible to load WTAQ input text files diretly into R with
the function `wtReadInputFile()` from an already existing WTAQ input text file,
e.g.:*
```{r, echo=TRUE}
inputFile <- system.file("extdata", "example1.inp", package = "kwb.wtaq")
wtaqConfiguration2 <- wtReadInputFile(inputFile)
```
*However, in this tutorial we just focus on the example that is stored in the R
object `wtaqConfiguration`.*
For checking this model parameterisation it can be printed:
```{r, echo=TRUE}
wtaqConfiguration
```
and also graphically visualised with the function `wtPlotConfiguration()`, e.g.:
```{r, eval=TRUE}
wtPlotConfiguration(wtaqConfiguration, asp = NA)
```
### Model run
For running WTAQ and saving the results in the R object `result` we just have do
use the function `wtRunConfiguration()` with our above defined model parameterisation
`wtaqConfiguration`:
```{r, eval=TRUE}
result <- wtRunConfiguration(wtaqConfiguration)
```
### Analysing results
To print the results of the model run, that are stored in the object `result`
in the **RStudio** console we simply need to enter:
```{r, eval=TRUE}
result
```
For plotting the results we can either use the function `wtPlotResult()` with
the parameter `plottype = "w"` to plot for each well measured (MEASDD) and
calculated (CALCDD) drawdowns in one plot:
```{r, eval=TRUE}
wtPlotResult(result,
plottype = "w",
main="Pumping test W5: model results without calibration")
```
or produce a plot that contains measured and calculated drawdowns for all wells
in two separate plots by setting the parameter `plottype = "s"`:
```{r, eval=TRUE}
wtPlotResult(result,
plottype = "s",
main="Pumping test W5: model results without calibration")
```
### Model calibration
For this tutorial calibration is realised by using an automatised one-dimensional
optimisation approach for the following two model parameters, because these were
identified to be the most sensitive ones:
* [1. Step: Horizontal hydraulic aquifer conductivity (hkr): for calibrating the drawdown in the observation well](#aquifer-characteristics-horizontal-hydraulic-conductivity-step-1)
* [2. Step: Well-skin parameter: for calibrating production well drawdown](#well-characteristics-well-bore-skin-parameter-of-production-well-step-2)
The approach is valid because the calibration of the well-skin parameter (during
Step 2) has no impact on the observation well drawdowns (Step 1). However, it
needs to be stated that conditions could occur, where a better model fit could
be possible (especially if the mid-term drawdown data are not fitting well) in
case that both, vertical `hkz` and horizontal `hkr` hydraulic aquifer conductivity
are varied in tandem.
Within this tutorial we solve this one-dimensional optimisation problem by using:
* the build-in R function `optimise()` and
* the Root-Mean-Square-Error (RMSE) as the only performance criteria for
evaluating the model fitness (i.e. comparision of calculated and measured drawdowns).
For solving this optimisation (or: calibration) problem we define the R function
`calibrateModel()` which requires the following four input parameters:
* `configuration`: a valid WTAQ input parameterisation (here: `wtaqConfiguration`)
* `wellPattern`: a regular expression or the well(s) names to be used for the
model fit evaluation (here: `OW4` or `PW`)
* `parameterName`: name of the WTAQ parameter that should be calibrated (here: `hkr` or `sw`)
* `parameterRange`: allowed value range for calibration parameter (e.g.
`c(0.0001, 0.1)` for parameter `hkr`)
Firstly this function - and its three dependent helper functions `modelFitness()`,
`modelFitnessAggregated` and `fitnessAdaptedModelConfiguration()` - need to be
loaded in R by running the following code:
```{r, eval=TRUE}
### Package for gof function
library(hydroGOF)
# modelFitness(): called by function modelFitnessAggregated()
modelFitness <- function
(
wtaqResult,
wellPattern
)
{
subResult <- wtaqResult[grep(pattern = wellPattern, wtaqResult$WELL),]
fitness <- t(hydroGOF::gof(sim = subResult$MEASDD, obs = subResult$CALCDD, digits = 3))
colnames(fitness) <- sub(" %", "", colnames(fitness))
### data.frame with plenty of performance indicators: e.g. RMSE, NSE, R2
as.data.frame(fitness)
}
# modelFitnessAggregated: called by function fitnessAdaptedModelConfiguration()
modelFitnessAggregated <- function
(
wtaqResult,
wellPattern
)
{
fitness <- modelFitness(wtaqResult, wellPattern)
### Objective function for the performance criteria that is minimised, here:
fitness$RMSE
}
# fitnessAdaptedModelConfiguration: called by function calibrateModel()
fitnessAdaptedModelConfiguration <- function
(
parameterValue, parameterName, configuration, wellPattern
)
{
configuration <- wtSetParameter(configuration, parameterName, parameterValue)
wtaqResult <- wtRunConfiguration(configuration)
modelFitnessAggregated(wtaqResult, wellPattern)
}
#calibrateModel()
calibrateModel <- function (
### WTAQ parameterisation, e.g. as retrieved by wtConfigure()
configuration,
### regular expression or name of well(s) to be used for calibration: e.g. "OW4"
wellPattern,
### name of ONE WTAQ parameter to be calibrated: e.g. `hkr`, `sw`
parameterName,
### min/max range of possible calibration parameter values
parameterRange
)
{
optResults <- optimise(
f = fitnessAdaptedModelConfiguration,
interval = parameterRange,
parameterName = parameterName,
configuration = configuration,
wellPattern = wellPattern )
### Save calibrated WTAQ configuration:
wtaqConfigurationCalibrated <- wtSetParameter(
configuration = configuration,
parameterName = parameterName,
parameterValue = optResults$minimum)
### Save optimisation results in list
list(parameterName=parameterName,
wellPattern=wellPattern,
optimalParameterValue=optResults$minimum,
minimalPerformanceValue=optResults$objective,
wtaqConfig=wtaqConfigurationCalibrated
)
}
```
#### Aquifer characteristics: horizontal hydraulic conductivity (Step 1)
```{r, eval=TRUE}
# 1.Step: Calibrate aquifer characteristics 'hkr' for OW4-------------------------------
calibratedAquifer <- calibrateModel(
### reference wtaq configuration
configuration = wtaqConfiguration,
### calibrate hydraulic aquifer conductivity
parameterName = "hkr",
### 'hkr' is within 0.0001 - 0.1 m/s
parameterRange = c(0.0001, 0.1),
### only use drawdown time-series of OW4 for calibration
wellPattern = "OW4"
)
### Plot the drawdowns with calibrated aquifer characteristics:
wtPlotResult(wtaqResult = wtRunConfiguration(
configuration = calibratedAquifer$wtaqConfig),
main = sprintf("Optimal value of parameter '%s' for %s: %0.4f m/s",
calibratedAquifer$parameterName,
calibratedAquifer$wellPattern,
calibratedAquifer$optimalParameterValue),
plottype = "w")
```
After this step observed and measured drawdowns fit nearly perfectly for the
calibrated observation well "OW4" only by setting the **hkr** to **`r calibratedAquifer$optimalParameterValue`** (m/s) , but still the drawdown in the production well
"PW" is underestimated (because it is still assumed that here are no "well losses").
Thus the production well characteristics (i.e. the well-skin parameter `sw`) need to be
calibrated in a next step.
#### Well characteristics: well-bore skin parameter of production well (Step 2)
```{r, eval=TRUE}
#2.Step: Calibrate well-bore skin parameter 'sw' for PW-------------------------------
calibratedAquiferAndWellSkin <- calibrateModel(
#### WTAQ configuration with calibrated aquifer (Step1)
configuration = calibratedAquifer$wtaqConfig,
### calibrate well-bore skin parameter
parameterName = "sw",
### 'sw' within 0 - 100 (dimensionless)
parameterRange = c(0, 100),
### only use drawdown time-series of PW for calibration
wellPattern = "PW"
)
### Plot the drawdowns with calibrated aquifer & well-bore skin characteristics:
wtPlotResult(wtaqResult = wtRunConfiguration(
configuration = calibratedAquiferAndWellSkin$wtaqConfig,
),
main = sprintf("Optimal value of parameter '%s' for %s: %2.4f (dimensionless)",
calibratedAquiferAndWellSkin$parameterName,
calibratedAquiferAndWellSkin$wellPattern,
calibratedAquiferAndWellSkin$optimalParameterValue),
plottype = "w")
```
By calibrating the well-skin parameter **sw** to **`r calibratedAquiferAndWellSkin$optimalParameterValue`** the drawdown in the production well "PW" now also fits nearly perfectly the
observed drawdown values, without impacting the fit for the observation wells.
**Note:**
*There might be cases where the calibration results by following the methodology
defined above is not satisfying. This can be possibly solved by calibrating
multiple parameters in parallel (e.g. horizontal `hkr` and vertical hydraulic
aquifer conductivity `hkz`). For this a more complex algorithm (e.g. build-in R
function `optim()`), which is able to solve multi-dimenional optimisation problems,
might be usefull. However, this goes beyond the scope of this tutorial.*
## Level 2: Multiple pumping wells
**Note:**
*For performing this example session it is required to perform all steps of the
[Level 1: one pumping well](#level-1-one-pumping-well) example session first,
because this example session requires some data of the [Level 1: one pumping well](#level-1-one-pumping-well) example*
One challenge of using WTAQ for multiple wells is that the drawdown simulation
for each model run is limited to:
* one active production well and
* up to 25 observation wells
This means that the model parameterisation for the pumping (e.g. pumping rate)
and observation wells (e.g. distance to pumping well) needs to be
adapted for each model run manually by using the **Level 1** function (see: [Level 1: one pumping well](#level-1-one-pumping-well) example).
For avoiding such time consuming task additional **Level 2** functions were developed
and included in the *kwb.wtaq* package that simplify using WTAQ on the well-field scale.
The usage of these functions is described in the following:
### Model parameterisation
#### Well field
In a first step the well field is defined, by creating a R object `owWellfieldConf`
that contains the following properties for each well, i.e.:
* Location `x`, `y`,
* Well diameter `r`,
* Depth of filter screen top `z1` and bottom `z2` below initial groundwater level
* Well-skin parameter `sw`
For **all** production wells the well-skin parameter `sw` is set to `wellSkin`,
because this value achieved the best-model fit during [calibration for W5](#well-characteristics-well-bore-skin-parameter-of-production-well-step-2)
```{r, echo=TRUE}
### Well-skin parameter from calibration of W5 for all wells of the well field
wellSkin <- calibratedAquiferAndWellSkin$optimalParameterValue
sprintf("Well-skin parameter value: %2.6f (dimensionless)", wellSkin)
# Example well field configuration with 5 wells
owWellfieldConf <- rbind(
owConfigureWell(
wellName = "W1", x = 807679.64, y = 2091015.29,
r = 1.5, z1 = 2, z2 = 4, sw = wellSkin),
owConfigureWell(
wellName = "W2", x = 807608.66, y = 2091018.51,
r = 1.7, z1 = 4.2, z2 = 7, sw = wellSkin),
owConfigureWell(
wellName = "W3", x = 807558.27, y = 2091090.30,
r = 1.5, z1 = 1.8, z2 = 8, sw = wellSkin),
owConfigureWell(
wellName = "W4", x = 807509.29, y = 2091161.80,
r = 1.5, z1 = 1.8, z2 = 7.5, sw = wellSkin),
owConfigureWell(
wellName = "W5", x = 807458.95, y = 2091232.26,
r = 1.5, z1 = 0.4, z2 = 7.8, sw = wellSkin))
```
**Note:**
*On the **Level 2** function level it is now not necessary to define well distances
(this was required in the [Level 1: one pumping well example](#model-parameterisation).
The well distances will be set later automatically for each model run based on
both, the `x` `y` coordinates:*
```{r, echo=FALSE}
distanceMatrix <- round(dist(owWellfieldConf[,c("x","y")],
method="euclidian",
upper=TRUE,),
1)
attr(distanceMatrix, "Labels") <- owWellfieldConf$wellName
cat("Well distance matrix table:")
cat("")
distanceMatrix
```
*and on the information which well is operating. For example column "W2" is used
if the pumping Well is "W2"*
#### Basic model parameterisation
In a next step we define we use the **Level 2** function `owConfigure()` to
prepare the constant parts of the WTAQ configuration parameterisation (`wellfield`,
`aquifer` and `drainage`) and store them in the object `owConf`:
```{r, echo=TRUE}
# Create constant components of WTAQ configuration
owConf <- owConfigure(wellfield = owWellfieldConf,
aquifer = calibratedAquiferAndWellSkin$wtaqConfig$aquifer,
drainage = wtConfigureDrainage(idra = 0)
)
```
**Note:**
*For the parameter `aquifer` we simply use the calibrated parameter setting, that
we obtained after the [Level 1 model calibration](#model-calibration), which is
stored in the R object:*
```{r, echo=TRUE}
calibratedAquiferAndWellSkin$wtaqConfig$aquifer
```
The well field configuration can be plotted with the function `owPlotConfiguration()`
(top view & side view). By setting the parameter `referenceWell=1` the Well 1
is selected as reference well for plotting:
```{r, echo=TRUE, fig.height=7, fig.width=10}
owPlotConfiguration(owConf, referenceWell = 1)
```
#### Time-varying model parameteristion
The time-variant model parameterisation contains:
* the pumping rates (`pumpingRates`) of each well (here: defined in `owWellfieldConf`) and
* the times for which the drawdowns should be calculated (`timesForDDcalculation`)
These are defined in the following code:
```{r, echo=TRUE}
# pumping rates of well W1 to W5
pumpingRates <- c(0.069, 0.089, 0.088, 0.087, 0.086)
### user-specified times
timesForDDcalculation <- c(1,5,10,30,60,600,1200, 2400,3600,
10000, 50000, 100000, 300000)
```
### Model run
Now we have all parts for parameterising WTAQ and calulating the drawdowns easily
on the well field scale (i.e. running WTAQ multiple times in the background).
For this we use the function `owGetDrawdowns()` with the following parameters:
```{r, echo=TRUE}
ddlist <- owGetDrawdowns(
owConf=owConf,
Q = pumpingRates,
times = timesForDDcalculation,
### required for using the function wtPlotResults()
to.matrix=FALSE
)
ddmatrix<- owGetDrawdowns(
owConf=owConf,
Q = pumpingRates,
times = timesForDDcalculation,
### saves results in "matrix" format: required for function owSuperposeDrawdowns()
to.matrix=TRUE
)
```
The switch `to.matrix=TRUE` is required in case one would like to calculate the
total drawdown in each well including well interference with the function `owSuperposeDrawdowns()`:
```{r echo=TRUE}
drawdownsWithWellInterference <- owSuperposeDrawdowns(drawdownList = ddmatrix)
```
### Analysing results
**Quantifying the impact of well interference**
Finally the modelling results can be analysed. For example it is possible to
quantify the additional drawdown due to well interference, e.g. for "W1":
```{r echo=TRUE}
myWell <- "W1"
DD_inProductionWell_withInterference <- drawdownsWithWellInterference[,myWell]
DD_inProductionWell_withoutInterference <- ddmatrix[[myWell]][,myWell]
diffDrawdown <- DD_inProductionWell_withInterference-DD_inProductionWell_withoutInterference
data.frame(time.in.seconds=drawdownsWithWellInterference[,1],
additionalDrawdown.due.to.wellInterference.in.meter=diffDrawdown)
```
**Plotting of well drawdowns (without well interference):**
```{r, echo=TRUE}
for (wellName in owWellfieldConf$wellName)
{
index <- which(owWellfieldConf$wellName==wellName)
wellQ <- pumpingRates[index]
if (wellQ > 0)
{
wtPlotResult(wtaqResult = ddlist[[wellName]],
plottype = "s",
ylab = "Drawdown (m)",
xlab = "Time in seconds since start of pumping (s)",
main = sprintf("Pumping well: %s (Q: %3.1f m3/h)",
wellName,
wellQ*3600))
}
}
```
**Plotting of well drawdowns (with well interference):**
```{r, echo=TRUE}
plotWellInterference <- function(wellName, Q=NULL)
{
if (is.null(Q)) {
label <- sprintf("%s ",wellName)
} else {
label <- sprintf("%s (%3.1f m3/h) ",wellName, Q*3600)
}
drawdown <- data.frame(SCENARIO="no well interference",
TIME=ddmatrix[[wellName]][,"TIME"],
CALCDD=ddmatrix[[wellName]][,wellName])
drawdownWithInterference <- data.frame("SCENARIO"="with well interference",
TIME=drawdownsWithWellInterference[,"TIME"],
CALCDD=drawdownsWithWellInterference[,wellName])
res <- rbind(drawdown, drawdownWithInterference)
print(lattice::xyplot(CALCDD ~ TIME,
groups = SCENARIO,
ylim=rev(extendrange(res$CALCDD)),
ylab = "Drawdown (m)",
xlab = "Time in seconds since start of pumping (s)",
type="b",
auto.key = list(columns=2),
data=res,
main = label))
}
for (wellName in owWellfieldConf$wellName)
{
index <- which(owWellfieldConf$wellName==wellName)
wellQ <- pumpingRates[index]
plotWellInterference(wellName = wellName, Q = wellQ)
}
```