-
Notifications
You must be signed in to change notification settings - Fork 51
Channel Routing
T-Route has currently implemented two channel routing methods: the Muskingum Cunge (MC) and a diffusive wave. The MC is applied to only a synthetic channel cross section that is a compound channel cross section with a trapezoidal main and rectangular floodplain. The flow in each segment at each time step is updated using a finite difference equation that is derived using a continuity equation and a storage equation (The NCAR WRF-Hydro Modeling System Technical Description).
, where
The wave celerity for a trapezoidal main channel is
, where
Assuming
, where
For overbank flow, the MC algorithm implemented within T-Route computes an weighted wave celerity by considering the celerities of the main channel and floodplain according to their relative areas. The weighting is based on the ratio of the main channel flow area to the total flow area and the ratio of the floodplain flow area to the total flow area.
Applying the aforementioned equations, the Muskingum-Cunge (MC) algorithm searches for the water depth that minimizes the difference between
The Fortran compute kernel of the MC is MCsingeSegStime_f2py_NOLOOP.f90. Integration of the Fortran kernel with Python using Cython involves several steps:
pyMCsingleSegStime_NoLoop.f90 is the Fortran code that is used to create a C-compatible wrapper for the kernel. This wrapper helps to interface the Fortran code with Cython by providing C-callable functions.
Use compiler.sh to run makefile to compile the kernel and Fortran wrapper into shared libraries.
Write a Cython wrapper file to interface with the compiled Fortran codes. reach.pyx is written in Python using Cython syntax to build the Cython extension module for the compute kernel.
fortran_wrappers.pxd integrates the Fortran codes with C/C++ or Cython by providing the declarations for the Fortran functions that will be used in the C/C++ or Cython code.
setup.py compiles the Cython module and link it with the Fortran object files.
mc_reach.pyx can now import and use the compiled Fortran compute kernel for the MC method in Cython.
In mc_reach.pyx, the MC extension module troute.routing.fast_reach.reach
is executed within the compute_reach_kernel
Cython function. To facilitate parallel computing, T-Route originally made the assumption that
becomes
, allowing, in theory, each stream segment within a given sub-network domain to simultaneously perform the MC computation without waiting for the completions of
The governing equation of the diffusive wave routing within T-Route is
, where
with
The partial differential equation is solved using the Crank-Nicolson scheme to non-uniform space grids, combined with an adapted Talyor series and Hermite Interpolation method. This approach is referred to as Crank-Nicolson over Space (CNS). Using the values of mesh_diffusive_forward
for CNS in diffusive.f90 computes Q at each compute node for the subsequent time step, with the computation progressing from upstream to downstream. Once the Q computation reaches the tailwater of a sub-network at a given time step, the process mesh_diffusive_backward
then computes water depth using the computed Q values and the downstream boundary condition for water depth, with the computation now progressing from upstream to downstream. The equation used is
Hence, Q is computed from upstream to downstream, followed by computing y from downstream to upstream at each time step, and this process repeats until the end of the simulation period.
The Fortran compute kernel of the diffusive wave is diffusive.f90. Integration of the Fortran kernel with Python using Cython involves several steps:
pydiffusive.f90 is the Fortran code that is used to create a C-compatible wrapper for the kernel. This wrapper helps to interface the Fortran code with Cython by providing C-callable functions.
Use compiler.sh to run makefile to compile the kernel and Fortran wrapper into shared libraries.
Write a Cython wrapper file to interface with the compiled Fortran codes. diffusive.pyx is written in Python using Cython syntax to build the Cython extension module for the compute kernel.
fortran_wrappers.pxd and pydiffusive.h integrates the Fortran codes with C/C++ or Cython by providing the declarations for the Fortran functions that will be used in the C/C++ or Cython code.
setup.py compiles the Cython module and link it with the Fortran object files.
While the MC method obtains channel network connectivity information, including flow direction, from reach extension module at every time step, the diffusive wave routing retrieves this information from frnw_g
in diffusive_utils_v02.py at the start of the simulation. It then maintains this information, along with channel geometry data, within the Fortran compute kernel for the entire duration of the simulation.
In Figure 1, each stream reach is assigned an integer number based on frnw_g, indicating the sequence in which the diffusive wave routing is applied. Each reach is colored differently according to its respective stream junction number. A stream junction is a confluence point where two or more stream reaches meet and combine their flow. The stream junction order reflects the total number of stream junctions downstream of a given reach.
Reaches with indices from 1 to 6 share a common junction order of four and do not transfer water to each other. As a result, channel routing can be applied to these reaches either simultaneously or serially. Once channel routing for the reaches with a junction order of four is complete, routing for the reaches with one less junction order—those with indices from 7 to 11—follows. Similarly, these reaches can also be computed either simultaneously or serially. This process continues until channel routing is applied to reaches with a junction order of zero.
This approach reflects the computation direction for channel routing methods, such as the Muskingum-Cunge (MC) and diffusive wave methods used within T-Route, which moves from upstream to downstream. This direction ensures that flow calculations for upstream reaches are completed before those for downstream reaches.
Conversely, when computation from downstream to upstream is required—such as in calculating water depth based on downstream boundary conditions—the computation direction is reversed, starting from reaches with the least junction order and progressing to those with the highest.
Table 1 provides the contents of frnw_g
. The row index corresponds to the sequence of reaches in which diffusive wave routing is applied. The first column displays the number of compute nodes in a stream reach, which is always one more than the number of stream segments within the reach. This is because each compute node represents a terminal point of a segment, with two co-located terminal points—one from the upstream segment and one from the downstream segment—treated as a single terminal point.
The second column indicates the reach index of the reach immediately downstream of the reach associated with the current row index. For example, the stream reach represented by row index 1 corresponds to the reach in the top-left corner with index 1 in Figure 1, and the reach immediately downstream has an index of 7.
The third column indicates the total number of upstream reaches converging at the upstream terminal point of the reach associated with the row index. When this number is greater than one, additional columns are included, each representing the reach index of one of the upstream reaches.
Currently, the hybrid routing methodology in T-Route allows for the dynamic exchange of output between the Muskingum-Cunge (MC) and reservoir modules during each real-time computation step. Following this, the diffusive wave module is executed separately on the diffusive channel domain, overwriting the previously computed results with the more accurate diffusive wave output. This approach is applied specifically to diffusive domains that are downstream of MC and reservoir domains. However, if a non-diffusive domain is situated downstream of a diffusive domain, it does not received the updated outflow from the upstream diffusive domain. This issue is illustrated in Figure 2. In the diagram illustrating the sequential execution, the reaches marked with red circle do not receive updated flow from the upstream diffusive domain, even though the flow values in the light blue domain has been updated by the diffusive wave output.
However, a prototype that fully integrates the diffusive wave module with the MC and reservoir modules, allowing dynamic exchange of output among all modules, is currently under development. This prototype ensures that the output from the diffusive domain is properly carried downstream to non-diffusive domains, while also enabling the output from non-diffusive domains, such as water depth, to be carried upstream to the diffusive domain during each real-time computation step.
- Overview
- Hydrofabric Integration
- Input Forcing
- Domain Data
- Data Formats
- CLI
- BMI Tutorial
- Lower Colorado, TX example
- Larger Domains (e.g. CONUS)