Pre-processing
This document describes how to setup coupled Ribasim-MODFLOW 6 simulations.
The primod Python package
To aid in setting up coupled models, we have created the primod
Python package. It takes both models, derives the exchange relationships between both, and writes:
- the Ribasim model
- the MODFLOW 6 simulation
- the exchange files
- the iMOD coupler configuration file
The derivation of exchange connections between the models is automatic, and based on the spatial information provided for both models.
As primod
is a Python package, both models must be represented in Python:
- The MODFLOW 6 simulation is represented by the Modflow6Simulation class of the
imod
Python package. - The Ribasim model is represented by the Model class of the
ribasim
Python package. - The combination of both models is represented by the
primod
RibaMod class.
Both Python packages support reading a model from a TOML file and associated files.
Abbreviated example
The following abbreviated example:
- Reads a Ribasim model
- Reads a MODFLOW 6 simulation
- Reads a basin definition associated with the Ribasim model
- Defines a driver coupling: which river and drainage packages are coupled
- Sets up a coupled model
- Writes the coupled model
import ribasim
import geopandas as gpd
import imod
import primod
= ribasim.Model.read("ribasim/ribasim.toml")
ribasim_model = imod.mf6.Modflow6Simulation.from_file("modflow/GWF_1.toml")
mf6_simulation = gpd.read_file("ribasim_network.gpkg", layer="basin_areas")
basin_definition
= primod.RibaModActiveDriverCoupling(
driver_coupling_active ="GWF_1",
mf6_model=["riv-1"],
mf6_packages=basin_definition,
basin_definition
)= primod.RibaModPassiveDriverCoupling(
driver_coupling_passve ="GWF_1",
mf6_model=["drn-1", "drn-2"],
mf6_packages=basin_definition,
basin_definition
)
= primod.RibaMod(
ribamod_model =ribasim_model,
ribasim_model=mf6sim,
mf6_simulation=[driver_coupling_active, driver_coupling_passive],
coupling_list
)
ribamod_model.write(="coupled-ribamod-simulation",
directory=r"c:\bin\imod_coupler\modflow6\libmf6.dll",
modflow6_dll=r"c:\bin\imod_coupler\ribasim\bin\libribasim.dll",
ribasim_dll=r"c:\bin\imod_coupler\ribasim\bin",
ribasim_dll_dependency )
Requirements
- The start and end times of the Ribasim and MODFLOW 6 simulations must align.
primod
will raise an error otherwise. - Spatial extents of both models need not coincide. Part of the Ribasim basins may be located outside of the MODFLOW 6 simulation window. Uncoupled basins will proceed with the regular drainage and irrigation terms define in the Basin / Static or Basin / Time tables.
- Similarly, not every River and Drainage boundary needs to be linked with Ribasim. Boundaries outside of any basin polygon will simply use the regular file input.
Exchange derivation
The exchanges are derived based on spatial overlap of Ribasim basins and the grid-based River and Drainage representation. For an active coupling, the x and y locations of the subgrid elements is used to link each actively coupled MODFLOW 6 boundary with a subgrid element.
Passive coupling
The derivation of exchanges proceeds in the following steps:
- Rasterize the basin definition polygons (provided as a
geopandas.GeoDataFrame
) to the MODFLOW 6 model grid. - Overlay the conductance on the rasterized basin definition, and derive for each boundary the basin index.
- Identify the indices of the coupled MODFLOW 6 boundaries.
- Store the basin indices and boundary indices in a table.
Active coupling
The derivation of active coupling exchanges proceeds largely the same, but also locates the nearest subgrid elements:
- Rasterize the basin definition polygons (provided as a
geopandas.GeoDataFrame
) to the MODFLOW 6 model grid. - Overlay the conductance on the rasterized basin definition, and derive for each boundary the basin index.
- Identify the indices of the coupled MODFLOW 6 boundaries.
- Using the
meta_x
andmeta_y
columns in the Ribasim Basin / subgrid table, find the nearest subgrid element for each MODFLOW 6 boundary. - Store the basin indices, boundary indices, subgrid indices in a table.
NB. The subgrid In a passive coupling, only drainage package are expected on the MODFLOW 6 side. In this type of coupling, the occurrence of a river package is not allowed and triggers a fatal error during preprocessing.
Modifications to the Ribasim model
The primod.RibaMod
class makes the following alteration to the Ribasim input before writing the Ribasim model: for basins that are coupled to MODFLOW 6, the infiltration and drainage columns are set to NaN
/ Null
(nodata) in the Basin / Static or Basin / Time tables.
This ensures that Ribasim does not overwrite the exchange flows while running coupled with MODFLOW 6.
Conceptually, it also means that when a basin is coupled, it should generally located inside of the MODFLOW 6 model; after all, when half of the basin is located outside of the MODFLOW 6 model, it will not receive drainage or lose water to infiltration in that half.
Modifications to the MODFLOW 6 simulation
Currently, no modifications are made in the MODFLOW 6 input.
Consistency between MODFLOW 6 and Ribasim subgrid
During the coupling, water levels should not be set below the bed elevation of the boundary. For drainage packages, this is the drainage elevation provided in the MODFLOW 6 input; for river packages, this is the bottom elevation provided in the MODFLOW 6 input.
There is potential for inconsistency here, as Ribasim also describes a bed elevation: the lowest level of the subgrid piecewise interpolation table:
- In case the MODFLOW 6 bed elevation is higher than the subgrid elevation, infiltration will stop before the Ribasim basin is empty.
- In case the MODFLOW 6 bed elevation is lower than the subgrid elevation, infiltration will proceed even when the Ribasim basin is empty.
The second is a more pressing problem, as it will results in a discrepancy between the water balances of both models. However, this problem is detected in the preprocessing stage and triggers a fatal error.