Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create preprocessing docs RibaMetaMod #68

Merged
merged 5 commits into from
Jul 5, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 220 additions & 0 deletions docs/coupler_ribametamod_preprocessing.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
---
title: Pre-processing
---

This document describes how to setup a coupled Ribasim-MetaSWAP-MODFLOW6 model. The `primod` Python package is used to setting up coupled models. It takes all three models, derives the exchange relationships, and writes:

HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
* the Ribasim model
* the MetaSWAP model
* the MODFLOW 6 simulation
* the exchange files
* the iMOD coupler configuration file
* the optional logging configuration file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the Ribasim model, the MetaSWAP model and the MODFLOW 6 model written here??
The foregoing suggests that only the interactions are being configured here
If that is the case plse remove the first three bullets

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No thats not the case. Primod even updated modelinput and then writes all models to file. I changed it to: the model input files,

The derivation of exchange connections between the models is automatic, and
based on the spatial information provided for both models.

HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
As `primod` is a Python package, all three models must be represented in Python:

* The Ribasim model is represented by the
[Model](https://deltares.github.io/Ribasim/python/reference/#model) class of
the `ribasim` Python package.
* The MODFLOW 6 simulation is represented by the
[Modflow6Simulation](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.Modflow6Simulation.html)
class of the `imod` Python package.
* The MetaSWAP model is represented by the
[MetaSwapModel](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.MetaSwapModel.html) class of the `imod` Python package

The combination of the three models is represented by the [RibaMetaMod](primod_api/RibaMetaMod.html#primod.RibaMetaMod) class of `primod`.

The [Modflow6Simulation](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.Modflow6Simulation.html) and Ribasim [Model](https://deltares.github.io/Ribasim/python/reference/#model) can be initialised from a TOML file with associated data. The [MetaSwapModel](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.MetaSwapModel.html)
does not support this yet. Initialising this model can be scripted.


## Coupling and model requirements
The [RibaMetaMod](primod_api/RibaMetaMod.html#primod.RibaMetaMod) class includes three seperate couplings.

### MODFLOW 6 and MetaSWAP
This coupling is equal to the [MetaMod](primod_api/MetaMod.html#primod.MetaMod) driver. This coupling requires the following [MODFLOW](https://deltares.github.io/imod-python/api/mf6.html) packages:

HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
* [Recharge](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.Recharge.html) for the exchange of the flux from the unstaurated zone.
* [Wel](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.Wel.html) for the optional exchange of irrigation from groundwater

This coupling requires the following [MetaSWAP](https://deltares.github.io/imod-python/api/msw.html) packages:

* [Sprinkling](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.Sprinkling.html) to define the maximum irrigation rate.
* [LanduseOptions](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.LanduseOptions.html) to specify the irrigation regime.

### MODFLOW 6 and Ribasim
This coupling is equal to the one of [RibaMod](primod_api/RibaMod.html#primod.RibaMod). This coupling requires the following [MODFLOW](https://deltares.github.io/imod-python/api/mf6.html) packages:

* [River](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.River.html) and/or [Drainage](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.Drainage.html) to exchange stage (active) and/or flux (active and passive).

HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
This coupling has the folowing requirement on the Ribasim model:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This coupling requires the Basins in the Ribasim model to be set up with a subgrid [...]

* The [Basins](https://deltares.github.io/Ribasim/reference/node/basin.html) need to be set up with a [subgrid](https://deltares.github.io/Ribasim/reference/node/basin.html#subgrid) for active coupling.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are water levels ? stages ? We should select one of these expresions

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](https://deltares.github.io/Ribasim/reference/node/basin.html#subgrid) piecewise interpolation table:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

potential for inconsistency -> a potential inconsistency
elevation: -> elevation,
subgridelelevation ->subgrid elevation
will stop -> stops
will proceed -> proceeds
will raise an error -> raises an error


* In case the MODFLOW 6 bed elevation is higher than the [subgrid](https://deltares.github.io/Ribasim/reference/node/basin.html#subgrid) elevation,
infiltration will stop before the Ribasim basin is empty.
* In case the MODFLOW 6 bed elevation is lower than the [subgrid](https://deltares.github.io/Ribasim/reference/node/basin.html#subgrid)elevation,
infiltration will proceed even when the Ribasim basin is empty. In this case `primod` will raise an error

### Ribasim and MetaSWAP
This coupling is used for routing runoff at the subsurface to the Ribasim basins. This coupling requires the following [MetaSWAP](https://deltares.github.io/imod-python/api/msw.html) package:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plse replace
This coupling is used for routing at the subsurface ->
by
This coupling is responsible for the surface runoff from the unsaturated zone.

* [Ponding](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.Ponding.html) to define the ponding level at which runoff is generated.

Optionally the irrigation from surface water can be coupled to the [UserDemand](https://deltares.github.io/Ribasim/reference/node/user-demand.html) in Ribasim. In that case the sprinkling realised in MetaSWAP, depends on the water availability for the [UserDemand](https://deltares.github.io/Ribasim/reference/node/user-demand.html) in Ribasim. This coupling requires the following [MetaSWAP](https://deltares.github.io/imod-python/api/msw.html) packages:

* [Sprinkling](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.Sprinkling.html) to define the maximum irrigation rates.
* [LanduseOptions](https://deltares.github.io/imod-python/api/generated/msw/imod.msw.LanduseOptions.html) to specify the irrigation regime.

This coupling has the following requirements on the Ribasim model:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has the folowing requirements -> imposes the following requirement

* There should be [User_demand](https://deltares.github.io/Ribasim/reference/python/Model.html#ribasim.Model.user_demand) defined with one priority per coupled water user. For this priority there should be a rate defined > 0.0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whereas in general water users in Ribasim can have non-zero demands set at multiple priorities,
for water users this demand can only be positive at one priority and should be zero for others.

If [Allocation](https://deltares.github.io/Ribasim/reference/python/Allocation.html#ribasim.Allocation) is active in the Ribasim model, The demand-realisation cyle is based on the user priority and the water availibility. When it's inactive its based on water availibility alone.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Allocation ... alone -> should be in the technical doc


## Coupling and model extents
* The start and end times of the Ribasim, MetaSWAP and MODFLOW 6 simulations must align.
`primod` will raise an error otherwise.
* Spatial extents of the models need not coincide:
+ Part of the Ribasim basins may be located outside of the MODFLOW 6 and MetaSWAP simulation window. Uncoupled basins will proceed with the regular drainage and irrigation terms define in the model.
+ Not every MODFLOW 6 River and Drainage boundary needs to be linked with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general:"
omit "will"
may -> can

terms define -> terms defined
simulation window -> domain
linked with Ribasim -> completely coupled to Ribasim
SVAT or svat ?? choose one

Ribasim. Boundaries outside of any basin polygon will simply use the regular
file input.
+ Not every MetaSWAP SVAT need to be linked with Ribasim. For uncoupled SVATS, runoff is not routed via the surface water and irrigation from surface water is unlimited.
+ The MetaSWAP model does not need to be active in the complete MODFLOW 6 simulation window. Uncoupled MODFLOW 6 nodes can have an aditional [RCH](https://deltares.github.io/imod-python/api/generated/msw/imod.mf6.Recharge.html) and [EVT](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.Evapotranspiration.html) package.


## Abbreviated examples of coupling

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is an ABBREVIATED example ?

The following abbreviated example for coupling Runoff:

* Reads a Ribasim model
* Takes a MetaSWAP 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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example for coupling Runoff -> example of coupling runoff
Takes -> Reads or the three reads on a line: Reads a Ribasim, MetaSWAP and MODFLOW 6 model


``` python
import ribasim
import geopandas as gpd
import imod
import primod


ribasim_model = ribasim.Model.read("ribasim/ribasim.toml")
metaswap_model = metaswap_model_from_script
mf6_simulation = imod.mf6.Modflow6Simulation.from_file("modflow/GWF_1.toml")

basin_definition = gpd.read_file("ribasim_network.gpkg", layer="basin_areas")

# Active coupling Ribasim - MODFLOW
driver_coupling_ribamod_active = primod.RibaModActiveDriverCoupling(
mf6_model="GWF_1",
mf6_packages=["riv-1"],
basin_definition=basin_definition,
)
# coupling Ribasim - MetaSWAP
driver_coupling_ribameta = primod.RibaMetaDriverCoupling(
ribasim_basin_definition=basin_definition,
)
# coupling MODFLOW 6 - MetaSWAP
driver_coupling_metamod = primod.MetaModDriverCoupling(
mf6_model="GWF_1",
mf6_recharge_package="rch_msw",
mf6_wel_package="well_msw",
)
# generate coupled model
ribametamod_model = primod.RibaMetaMod(
ribasim_model=ribasim_model,
mf6_simulation=mf6sim,
coupling_list=[driver_coupling_ribamod_active, driver_coupling_ribameta,driver_coupling_metamod],
)

ribametamod_model.write(
directory="coupled-ribametamod-simulation",
modflow6_dll=r"c:\bin\imod_coupler\modflow6\libmf6.dll",
ribasim_dll=r"c:\bin\imod_coupler\ribasim\bin\libribasim.dll",
ribasim_dll_dependency=r"c:\bin\imod_coupler\ribasim\bin",
)
```

For including the optional coupling of irrigation from surface water, the folowing adition can be done:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adition can be done -> addition is required
State that the driver_coupling_ribameta replaces the one in the upper part, but now with an extra basin definition for the water users

``` python
# read aditional water-user definition polygon
water_users_definition = gpd.read_file("ribasim_network.gpkg", layer="water_user_areas")

# add water-user definition to the RibaMetaDriverCoupling
driver_coupling_ribameta = primod.RibaMetaDriverCoupling(
ribasim_basin_definition=basin_definition,
ribasim_user_demand_definition=water_users_definition,
)

# proceed as previous example

```

## Exchange derivation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exchange derivation -> Mapping definition

The exchanges are derived based on spatial overlap of the models. In general all couplings with ribasim are based on a spatial overlap of the basin and/or water user definition polygons. The coupling between MODFLOW 6 6 and MetaSWAP is based on overlapping grid based coordinates. The coupling based on polygon defninitions is done in the folowing way:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapping between MODFLOW 6 and MetaSWAP is based on matching grid-based coordinates.
The mapping between either MODFLOW 6 or MetaSWAP and Ribasim are based on a spatial overlap of a
Ribasim basin or water definition polygon. This polygon is provided as a geopandas.GeoDataFrame.
Mapping proceeds as follows:

* Rasterize the basin and/or Water users definition polygons (provided as a
`geopandas.GeoDataFrame`) to the MODFLOW 6 or MetaSWAP model grid.
* Overlay the grid-based variable on the rasterized basin definition,
and derive for each gridcel the basin index.
* Identify the indices of the coupled MODFLOW 6 or MetaSWAP gridcel.
* Store the basin indices and gridcel indices in a table.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reword the first two bullets:

  • Rasterize de basin index to the M&M model grid, based on the definition polygon
  • From the raster, obtain for each M&M node/svat the corresponding basin index

Ribasim and MODFLOW
: For the flux exchange, the Overlay is based on the [river](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.River.html) conductance. The indices are based on the package level. For the stage exchange, the mapping is based on the x and y locations of the [subgrid](https://deltares.github.io/Ribasim/reference/node/basin.html#subgrid) elements. For every [river](https://deltares.github.io/imod-python/api/generated/mf6/imod.mf6.River.html) conductance gridcell the neirest [subgrid](https://deltares.github.io/Ribasim/reference/node/basin.html#subgrid) element is found.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Overlay -> the mapping (see further in that sentence)
Overlay -> mapping
all SVATS where -> all svats for which
grid based -> grid-based

Copy link
Contributor Author

@HendrikKok HendrikKok Jul 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the overlay, because its referencing to line 179. SVATS are caps since its an abbreviation. Agree?

Ribasim and MetaSWAP
: For Runoff exchange the Overlay is based on the basin definition and all active SVATS. For the irrigation of surface water, the Overlay is based on the water user definition and all SVATS where irrigation from surface water is active.

MODFLOW 6 and MetaSWAP
: The grid based recharge, storage and well exchange is based on overlapping xy-coordinates. The optional 1-N coupling between MODFLOW 6 and MetaSWAP is based on the subunit coordinate in the MetaSWAP model.


## Modifications to the models

Ribasim
: 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
HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
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.

* For all [User_demand](https://deltares.github.io/Ribasim/reference/python/Model.html#ribasim.Model.user_demand) coupled to MetaSWAP, the rate is set to zero after initialisation of the iMOD-coupler. The rate > 0 is needed to find the coupled indices from the internal
[User_demand](https://deltares.github.io/Ribasim/reference/python/Model.html#ribasim.Model.user_demand) array.
HendrikKok marked this conversation as resolved.
Show resolved Hide resolved

Modflow 6
: For all actively coupled RIV packages an API-package is added to the simulation. This package is used to return the correction flux. When making a water-balance from the MODFLOW 6 output, this package output should be summed with the RIV output

HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
MetaSWAP
: curently no modifications are made in the MetaSWAP model


HendrikKok marked this conversation as resolved.
Show resolved Hide resolved
Loading