Presentation by Martijn Visser and Huite Bootsma (Deltares) at the iMOD International User Day 2018, during Delft Software Days - Edition 2018. Tuesday 13 November 2018, Delft.
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
DSD-INT 2018 Work with iMOD MODFLOW models in Python - Visser Bootsma
1. Work with iMOD MODFLOW models in Python
Martijn Visser, martijn.visser@deltares.nl
Huite Bootsma, huite.bootsma@deltares.nl
November 16, 2018
Note: this document has been translated from a Jupyter Notebook. The content will also be made avail-
able in Jupyter Notebook form here:
https://gitlab.com/deltares/imod-python/tree/master/examples
1 Introduction
Python has seen very strong growth in recent years:
https://stackoverflow.blog/2017/09/06/incredible-growth-python/
1
3. 1.1 pip install imod
The python imod package is available on PyPI.org and can be installed with pip install imod.
PyPI page: https://pypi.org/project/imod/
Source code is available here: https://gitlab.com/deltares/imod-python
Documentation can be found here: https://deltares.gitlab.io/imod-python/
The package is built on xarray and pandas:
• pandas makes working with tabular data easy, for example timeseries
• xarray makes working with N-D arrays easy, for example groundwater heads that
vary over (x, y, time, and layer). It’s effectively an in-memory netCDF file.
• imod Python package makes working with iMODFLOW models in Python easy
3
4. 1.2 What’s so great about pandas?
In [1]: import pandas
import matplotlib.pyplot as plt
%matplotlib inline
In [2]: fig = plt.figure(figsize=(25, 10))
df = pandas.read_csv("groundwater_timeseries.csv", index_col=1, parse_dates=[1])
df["head"].plot()
df["head"].rolling(window=180, center=True).mean().plot()
Out[2]: <matplotlib.axes._subplots.AxesSubplot at 0x8d20f60>
1.2.1 xarray versus numpy
# numpy style
>>> array[[0, 1, 3], :, :].max(axis=2)
# xarray style
>>> ds.sel(time="2017-11-28").max(dim="station")
4
6. 3 Let’s build a model from scratch!
3.1 After:
• Toth, 1963, A Theoretical Analysis of Groundwater Flow in Small Drainage Basins
• Xiao-Wei Jiang, Li Wan, Xu-Sheng Wang, Shemin Ge, and Jie Liu, 2008, Effect of exponential
decay in hydraulic conductivity with depth on regional groundwater flow
The goal is to simulate an aquifer with a sloping phreatic water table, with local drainage:
Which results in a region flow, with nested systems:
6
7. In [9]: from collections import OrderedDict
import subprocess
import imod
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr
%matplotlib inline
The phreatic water table is given by the following function (Toth, 1963):
zx(x) = z0 + x tan α + a
cos(α)
sin( bx
cos α )
Conductivity decreases exponentially with depth (Jiang et al., 2009):
k(z) = k0 exp[−A(zs − z)]
We can translate these functions into Python as follows:
In [10]: def phreatic_head(z0, x, a, alpha, b):
"""Synthetic ground surface, a la Toth 1963"""
return (z0 + x * np.tan(alpha) + a / np.cos(alpha)
* np.sin((b * x) / (np.cos(alpha))))
def conductivity(k0, z, A):
"""Exponentially decaying conductivity"""
return k0 * np.exp(-A * (1000.0 - z))
7
8. 4 Generate the phreatic boundary condition
In [11]: z0 = 1000.0
x = np.arange(0.0, 6000.0, 10.0) + 5.0
a = 15.0
b = np.pi / 750.0
alpha = 0.02
In [12]: head_top = xr.DataArray(
data=phreatic_head(z0, x, a, alpha, b),
coords={"x": x},
dims=("x")
)
In [13]: fig = plt.figure(figsize=(10, 5))
head_top.plot()
Out[13]: [<matplotlib.lines.Line2D at 0xbc34d68>]
8
11. 6 Generate the iMODFLOW model files
In [17]: model = OrderedDict()
model["bnd"] = bnd
# constant head in the first layer
model["bnd"].sel(layer=1)[...] = -1.0
model["kdw"] = kh * 10.0
model["vcw"] = 10.0 / kh
model["shd"] = bnd * head_top
# We have to an additional package for it to run...
model["rch"] = xr.full_like(bnd.sel(layer=1), 0.0)
In [18]: imod.write("toth", model)
Now let’s inspect these files, and run the model.
11