Update a 2D Delft3D FM model: mesh refinements#

Once you have a Delft3D FM model, you may want to update your model in order to use a new data map, change a parameter value, add structures or cross-sections data, use different boundary data, create and run different scenarios etc.

With HydroMT, you can easily read your model and update one or several components of your model using the update function of the command line interface (CLI). Here are the steps and some examples on how to refine the mesh 2D grid for an existing 1D2D model.

All lines in this notebook which starts with ! are executed from the command line. Within the notebook environment the logging messages are shown after completion. You can also copy these lines and paste them in your shell to get more feedback.

Model setup configuration#

Updating a bedlevel or infiltration capacity map is an easy step with the command line but sometimes, for example with forcing or grid refinement, you need to update several things at the same time. This is possible by preparing a configuration file that includes every methods and settings that you want to do during your update.

The configuration-file contains the model setup configuration and determines which methods are updated and in which sequence and sets optional arguments for each method. This configuration is passed to hydromt using -i <path_to_configuration_file>.

Each section, before indent, (e.g. setup_mesh2d_refine) corresponds with a model method which are explained in the docs (model methods).

Let’s open the example configuration file dflowfm_update_mesh2d_refine.yml from the model repository [examples folder] and have a look at the settings.

[1]:
fn_yml = "dflowfm_update_mesh2d_refine.yml"
with open(fn_yml, "r") as f:
    txt = f.read()
print(txt)
global:
  crs: 3857

setup_mesh2d_refine:
  polygon_fn: ./data/refine.geojson
  steps: 2

setup_link1d2d:
  link_direction: 1d_to_2d

Here we can see that to fully refine the 2D grid, we will run two methods:

  • global: our model to update is defined in the projected CRS WGS84 EPSG 3857. Unfortunately Delft3D FM do not allow yet to store the model CRS information, and the CRS of the model to update needs to be passed to HydroMT again.

  • setup_mesh2d_refine: we will refine our 2D mesh within the polygons defined in the file data/refine.geojson with 2 steps or iterations.

  • setup_link1d2d: in the model we would like to update, 1D elements are present. Because we will udpate the 2D mesh with our refinements, we need to update and re-create the 1D2D links so that they match the newly refined 2D grid.

You can find more information on the different methods and their options in the docs (model methods).

NOTE: to provide data to HydroMT, you can either provide a data catalog entry, a direct path to a file (provided reading that file is straightforward and no pre-processing is required) or for python users. We use a direct path in setup_mesh2d_refine for the refine polygon.

NOTE: Refinment of the 2D grid leads to a new grid definition. There fore the setup_link1d2d is called again.

HydroMT CLI update interface#

Using the HydroMT build API, we can update one or several components of an already existing Delft3D FM model. Let’s get an overview of the available options:

[2]:
# Print the options available from the update command
! hydromt update --help
Usage: hydromt update [OPTIONS] MODEL MODEL_ROOT

  Update a specific component of a model.

  Set an output directory to copy the edited model to a new folder, otherwise
  maps are overwritten.

  Example usage: --------------

  Update (overwrite!) landuse-landcover based maps in a Wflow model: hydromt
  update wflow /path/to/model_root -c setup_lulcmaps --opt lulc_fn=vito -d
  /path/to/data_catalog.yml -v

  Update Wflow model components outlined in an .yml configuration file and
  write the model to a directory: hydromt update wflow /path/to/model_root  -o
  /path/to/model_out  -i /path/to/wflow_config.yml  -d
  /path/to/data_catalog.yml -v

Options:
  -o, --model-out DIRECTORY  Output model folder. Maps in MODEL_ROOT are
                             overwritten if left empty.
  -i, --config PATH          Path to hydroMT configuration file, for the model
                             specific implementation.
  -c, --components TEXT      Model methods from configuration file to run
  --opt TEXT                 Method specific keyword arguments, see the method
                             documentation of the specific model for more
                             information about the arguments.
  -d, --data TEXT            Path to local yaml data catalog file OR name of
                             predefined data catalog.
  --dd, --deltares-data      Flag: Shortcut to add the "deltares_data" catalog
  --fo, --force-overwrite    Flag: If provided overwrite existing model files
  --cache                    Flag: If provided cache tiled rasterdatasets
  -q, --quiet                Decrease verbosity.
  -v, --verbose              Increase verbosity.
  --help                     Show this message and exit.

Update a 1D2D Delft3D FM model to refine the 2D mesh#

[3]:
# NOTE: copy this line (without !) to your shell for more direct feedback
! hydromt update dflowfm dflowfm_piave -o ./build/dflowfm_mesh2d_refine -i dflowfm_update_mesh2d_refine.yml -v
2025-03-03 12:40:26,910 - update - log - INFO - HydroMT version: 0.10.1
2025-03-03 12:40:26,910 - update - main - INFO - Updating dflowfm model at /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/dflowfm_piave (r).
2025-03-03 12:40:26,910 - update - main - INFO - Output dir: /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/build/dflowfm_mesh2d_refine
2025-03-03 12:40:26,910 - update - main - INFO - User settings:
2025-03-03 12:40:27,760 - update - model_api - INFO - Initializing dflowfm model from hydromt_delft3dfm (v0.3.1.dev0).
2025-03-03 12:40:27,760 - update - data_catalog - INFO - Parsing data catalog from /usr/share/miniconda/envs/test/lib/python3.12/site-packages/hydromt_delft3dfm/data/parameters_data.yml
2025-03-03 12:40:27,765 - update - dflowfm - INFO - Reading mdu file at /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/dflowfm_piave/dflowfm/DFlowFM.mdu
2025-03-03 12:40:28,474 - update - dflowfm - INFO - project crs: 3857
2025-03-03 12:40:28,474 - update - dflowfm - INFO - Reading model data from /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/dflowfm_piave
2025-03-03 12:40:28,474 - update - dflowfm - INFO - Reading dimr file at /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/dflowfm_piave/dimr_config.xml
2025-03-03 12:40:29,576 - update - dflowfm - INFO - Reading branches GUI file
2025-03-03 12:40:29,717 - update - dflowfm - INFO - Reading cross-sections files
2025-03-03 12:40:29,763 - update - dflowfm - INFO - Reading manholes file
2025-03-03 12:40:29,864 - update - model_api - WARNING - Replacing result: elevtn
2025-03-03 12:40:29,868 - update - model_api - WARNING - Replacing result: infiltcap
2025-03-03 12:40:29,874 - update - model_api - WARNING - Replacing result: roughness_manning
2025-03-03 12:40:29,876 - update - model_api - WARNING - Replacing geom: region
2025-03-03 12:40:29,876 - update - dflowfm - INFO - Reading cross-sections files
2025-03-03 12:40:30,108 - update - model_api - WARNING - Replacing geom: crosssections
2025-03-03 12:40:30,108 - update - dflowfm - INFO - Reading manholes file
2025-03-03 12:40:30,158 - update - model_api - WARNING - Replacing geom: manholes
2025-03-03 12:40:30,252 - update - model_api - WARNING - Replacing forcing: boundary1d_waterlevelbndbnd
2025-03-03 12:40:30,254 - update - model_api - WARNING - Replacing forcing: rainfall_rate
2025-03-03 12:40:30,254 - update - dflowfm - INFO - project crs: 3857
2025-03-03 12:40:30,255 - update - model_api - INFO - setup_mesh2d_refine.polygon_fn: /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/data/refine.geojson
2025-03-03 12:40:30,255 - update - model_api - INFO - setup_mesh2d_refine.sample_fn: None
2025-03-03 12:40:30,255 - update - model_api - INFO - setup_mesh2d_refine.steps: 2
2025-03-03 12:40:30,255 - update - dflowfm - INFO - reading geometry from file /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/data/refine.geojson.
2025-03-03 12:40:30,256 - update - geodataframe - INFO - Reading  vector data from /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/data/refine.geojson
2025-03-03 12:40:30,283 - update - mesh - INFO - 2d mesh refined based on polygon.Number of faces before: 460 and after: 828
2025-03-03 12:40:30,284 - update - model_mesh - WARNING - Overwriting grid mesh2d and the corresponding data variables in mesh.
2025-03-03 12:40:30,392 - update - model_api - INFO - setup_link1d2d.link_direction: 1d_to_2d
2025-03-03 12:40:30,392 - update - model_api - INFO - setup_link1d2d.link_type: embedded
2025-03-03 12:40:30,392 - update - model_api - INFO - setup_link1d2d.polygon_fn: None
2025-03-03 12:40:30,392 - update - model_api - INFO - setup_link1d2d.branch_type: None
2025-03-03 12:40:30,392 - update - model_api - INFO - setup_link1d2d.max_length: inf
2025-03-03 12:40:30,392 - update - model_api - INFO - setup_link1d2d.dist_factor: 2.0
2025-03-03 12:40:30,392 - update - dflowfm - WARNING - adding 1d2d links for all branches at non boundary locations.
2025-03-03 12:40:30,393 - update - dflowfm - INFO - setting up 1d_to_2d links.
2025-03-03 12:40:30,545 - update - dflowfm - INFO - Writing model data to /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/build/dflowfm_mesh2d_refine
2025-03-03 12:40:30,545 - update - dflowfm - INFO - Writing maps files to /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/build/dflowfm_mesh2d_refine/maps
2025-03-03 12:40:30,754 - update - dflowfm - INFO - Writting cross-sections files crsdef and crsloc
2025-03-03 12:40:31,087 - update - dflowfm - INFO - Writting friction file(s)
2025-03-03 12:40:31,092 - update - dflowfm - INFO - Writting manholes file.
2025-03-03 12:40:31,379 - update - model_api - WARNING - Replacing geom: mesh1d
2025-03-03 12:40:31,379 - update - model_api - WARNING - Replacing geom: network1d
2025-03-03 12:40:31,380 - update - model_api - WARNING - Replacing geom: mesh2d
2025-03-03 12:40:31,394 - update - model_api - WARNING - Replacing geom: crosssections
2025-03-03 12:40:31,401 - update - model_api - WARNING - Replacing geom: manholes
2025-03-03 12:40:31,401 - update - model_api - WARNING - Replacing geom: rivers
2025-03-03 12:40:31,404 - update - model_api - WARNING - Replacing geom: pipes
2025-03-03 12:40:31,406 - update - model_api - WARNING - Replacing geom: branches
2025-03-03 12:40:31,406 - update - model_api - WARNING - Replacing geom: region
2025-03-03 12:40:31,407 - update - model_api - WARNING - Replacing geom: mesh1d
2025-03-03 12:40:31,408 - update - model_api - WARNING - Replacing geom: network1d
2025-03-03 12:40:31,408 - update - model_api - WARNING - Replacing geom: mesh2d
2025-03-03 12:40:31,880 - update - dflowfm - INFO - Writting branches.gui file
2025-03-03 12:40:32,032 - update - dflowfm - INFO - Writting forcing files.
2025-03-03 12:40:32,942 - update - dflowfm - INFO - Adding dflowfm component to dimr config
2025-03-03 12:40:32,948 - update - dflowfm - INFO - Writing model dimr file to /home/runner/work/hydromt_delft3dfm/hydromt_delft3dfm/docs/_examples/build/dflowfm_mesh2d_refine/dimr_config.xml

The example above means the following: run hydromt with:

  • update dflowfm: i.e. update a dflowfm model

  • dflowfm_piave: original model folder

  • -o ./build/dflowfm_mesh2d_refine: output updated model folder

  • -i dflowfm_update_mesh2d_refine.yml: setup configuration file containing the components to update and their different options

  • v: give some extra verbosity (2 * v) to display feedback on screen. Now debug messages are provided.

Model comparison#

From the information above, you can see that the mesh2d was refined and now contains 828 faces after refinement compared to 460 beforehand and that the 1D2D links have been regenerated.

Using the script from the plot example, we can compare the 2D mesh before and after the refinements.

First, let’s load some packages.

[4]:
import xugrid as xu
import geopandas as gpd
import matplotlib.pyplot as plt
[5]:
# Load both models with hydromt
from hydromt_delft3dfm import DFlowFMModel

mod0 = DFlowFMModel(root="dflowfm_piave", mode="r", crs=3857)
mod1 = DFlowFMModel(root="build/dflowfm_mesh2d_refine", mode="r", crs=3857)

# read dflowfm mesh; extract the 2d grid part
mesh2d_0 = mod0.mesh_grids["mesh2d"]
mesh2d_1 = mod1.mesh_grids["mesh2d"]
[6]:
# read the polygon file we used for the refinement
polygons = gpd.read_file("data/refine.geojson")
[7]:
# Make 2 side-by-side plots to plot each mesh
zoom_level = 10
fig = plt.figure(figsize=(12, 6))
axs = fig.subplots(1, 2)

axs[0].set_title("Original mesh")
axs[1].set_title("Refined mesh")

# Plot the original mesh
mesh2d_0.plot(ax=axs[0], facecolor="none", edgecolor="k")
polygons.to_crs(mod0.crs).plot(ax=axs[0], facecolor="r", edgecolor="r")

# Plot the refined mesh
mesh2d_1.plot(ax=axs[1], facecolor="none", edgecolor="k")
polygons.to_crs(mod0.crs).plot(ax=axs[1], facecolor="none", edgecolor="r")

[7]:
<Axes: title={'center': 'Refined mesh'}>
../_images/_examples_update_refine_2dgrid_18_1.png