In this example, we’ll work with an unstructured grid. We’ll create a very simple unstructured model of the Netherlands from scratch. We’ll use a digital elevation model (DEM) to set as drain level to simulate overland flow. To this we add constant recharge.
Let’s start with importing the required packages. These are iMOD Python, xarray, and xugrid.
import imodimport xarray as xrimport xugrid as xu
/home/runner/work/iMOD-Documentation/iMOD-Documentation/.pixi/envs/default/lib/python3.14/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
Load the data
This data is distributed with the xugrid package. You need an internet connection to download the data.
elevation = xu.data.elevation_nl()elevation
Downloading file 'elevation_nl.nc' from 'https://github.com/deltares/xugrid/raw/main/data/elevation_nl.nc' to '/home/runner/.cache/xugrid'.
It is convenient to create a template grid, which has the right shape, dimensions, and coordinates. This can be used to construct DataArrays for different variables.
We’ll start off with creating a layer DataArray, which is a 1D DataArray, containing all layer information required.
Next, we’ll create a 2D planar template grid. The xarray function .ones_like returns a new object of ones with the same shape and type as a given dataarray or dataset.
Finally, we’ll create our unstructured template 3D grid.
We’ll multiply our template 2d grid with the layer template to construct the full 3D grid. Pay attention to the dimension order, iMOD Python is very specific about this. We’ll put the dimensions in the right order immediately, to save ourselves headaches later.
# iMOD Python requires the layer dimension first, faces dimension secondtemplate = (template_2d * layer).transpose("layer", "mesh2d_nFaces")# plottemplate.sel(layer=1).ugrid.plot(vmin=0, vmax=2, cmap="viridis")
Drainage
We can now use the template grid to transform the 2D elevation grid to a 3D elevation grid, required for the drainage package.
Compute conductance. The function .ugrid.grid.area yields a numpy array with for each unstructured element its area (m2). Multiplied with the unstructured grid with value 1 yiels grid with area.
Prepare our model discretization. idomain specifies whether a call is active [1], inactive [0], or vertical pass through [-1]. In this case we’ll go for a grid that is active everywhere.
idomain = template.copy()
We’ll also define the bottom of the model. To keep things simple, we’ll subtract 300 from the drainage level, which will also be our top. In this way, we’ll construct a model with thickness 300 everywhere.
Within a Modflow6Simulation object one or more models can be defined. In this example there is just one ground water flow model. In the next cells we will assemble our groundwater model in the object “gwf_model”. Further down, we add it to the object “simulation”.
In the next cell we define that option newton is chosen.
# mf6_path = "path/to/mf6.exe" # If you installed Modflow6 in your PATH environment variable, you can use the# following argument:mf6_path ="mf6"simulation.run(mf6_path)
Let’s look at the results:
head = simulation.open_head().load().isel(time=-1, layer=0)# calculate ground water below surface level.groundwater_depth = elevation - head# Plotgroundwater_depth.ugrid.plot()
iMOD Python also supports partitioning a simulation, for parallel computation. It offers convenience functions to split existing simulations. For this we require a label array first.
from imod.prepare import create_partition_labelslabel_array = create_partition_labels(idomain, npartitions=4)label_array.ugrid.plot()