R.A. Collenteur, University of Graz
This notebook explains the use of the RechargeModel
stress model to simulate the combined effect of precipitation and potential evapotranspiration on the groundwater levels. For the computation of the actual recharge, different (non-linear) models are available. The non-linear models are introduced in Pastas 0.14 and will be described in more detail in Collenteur et al. (in Prep.). The Berendrecht
model is already fully described in Berendrecht et al. (2006).
To run this notebook and the related non-linear recharge models, it is strongly recommended to install Numba (http://numba.pydata.org). This Just-In-Time (JIT) compiler compiles the computationally intensive part of the recharge calculation, making the non-linear model as fast as the Linear recharge model.
In this notebook we analyze a head time series near the town of De Bilt in the Netherlands. Data is obtained from the following resources:
B32C0639001.csv
) are downloaded from https://www.dinoloket.nl/ etmgeg_260.txt
) are downloaded from https://knmi.nl
In [1]:
import pandas as pd
import pastas as ps
import matplotlib.pyplot as plt
%matplotlib inline
ps.show_versions()
ps.set_log_level("ERROR")
Input data handling is similar to normal. The only thing that is necessary to check is that the precipitation and evaporation are provided in mm/day. This is necessary because the parameters for the unsaturated zone models are defined in mm for the length unit and days for the time unit. It is possible to use other units, but this would require manually setting the initial values and parameter boundaries for the recharge models.
In [2]:
head = pd.read_csv("../data/B32C0639001.csv", parse_dates=['date'],
index_col='date', squeeze=True)
# Make this millimeters per day
evap = ps.read_knmi("../data/etmgeg_260.txt", variables="EV24").series * 1e3
rain = ps.read_knmi("../data/etmgeg_260.txt", variables="RH").series * 1e3
fig, axes = plt.subplots(3,1, figsize=(10,6), sharex=True)
head.plot(ax=axes[0], x_compat=True, linestyle=" ", marker=".")
evap.plot(ax=axes[1], x_compat=True)
rain.plot(ax=axes[2], x_compat=True)
axes[0].set_ylabel("Head [m]")
axes[1].set_ylabel("Evap [mm/d]")
axes[2].set_ylabel("Rain [mm/d]")
plt.xlim("1985", "2005");
Linear
, FlexModel
, and Berendrecht
). All recharge models can be accessed through the recharge subpackage (ps.rch
).RechargeModel
object and add it to the model
In [3]:
ml = ps.Model(head)
# Select a recharge model
rch = ps.rch.FlexModel()
#rch = ps.rch.Berendrecht()
#rch = ps.rch.Linear()
rm = ps.RechargeModel(rain, evap, recharge=rch, rfunc=ps.Gamma, name="rch")
ml.add_stressmodel(rm)
ml.solve(noise=True, tmin="1990")
ml.plots.results();
After the parameter estimation we can take a look at the recharge flux computed by the model. The flux is easy to obtain using the get_stress
method of the model object, which automatically provides the optimal parameter values that were just estimated. After this, we can for example look at the yearly recharge flux estimated by the Pastas model.
In [4]:
recharge = ml.get_stress("rch").resample("A").sum()
ax = recharge.plot.bar(figsize=(10,4))
ax.set_xticklabels(recharge.index.year)
plt.ylabel("Recharge [mm/year]");