This dispatch method finds the flow through the canal.
For the canal to dispatch correctly, the linked reservoirs must solve with one of a limited set of dispatch methods.
Table 7.1 identifies which dispatch methods are allowed for reservoirs linked to a canal and which are not. If a reservoir linked to a canal tries to dispatch with a method that is not allowed, the run terminates with an error message.
The dispatch method of the canal object is unique because the canal solves the reservoirs and the canal at the same time. The usual dispatching pattern is unstable when three objects are iterating with one another. If the Pool Elevations or Storages on both Reservoirs are input, the canal flow can be immediately found. If the reservoirs are solving for Storage/Pool Elevation, the canal performs a modified bisection algorithm to solve for Canal Flow.
Following is a description of how these objects interact and how the method solves.
Note: The canal flow solution requires that the slot minimum and maximum be set in the Pool Elevation slot configuration on both linked reservoirs. Also the quality of the solution for Canal Flow is sensitive to the slot convergence values in the slot configuration for all series slots on the Canal object. It is recommended that the slot convergence be set to 0.00001 Percent for all Canal series slots.
When a reservoir dispatches to solve for Pool Elevation, if it is linked to a canal, it sets its Pool Elevation slot with a seed value (previous value) and exits its dispatch method. It waits for the canal to solve and set the Canal Flow; then it dispatches again. When both reservoirs have set their Pool Elevation slots, the canal’s solveFlow dispatch method goes on the queue and executes. The result is the flow in the canal. When the flow is set on Flow1 and its negative value is set on Flow2, the values propagate to each reservoir. Each reservoir re-dispatches and solves mass balance to set the Storage and Pool Elevation.
Note: The seed values in the Pool Elevation slots are only used to cause the canal to dispatch. They are not actually used in the calculation.
The canal flow algorithm begins by summing side inflows to both reservoirs. These include Hydrologic Inflow, Diversion, Return Flow, Inflow Forecast and Pumped Storage Flow. Any of these that are not in use default to zero. The side inflows do not change based on the Canal Flow and thus are treated as a constant in the canal flow algorithm.
Note: Bank Storage, Evaporation, and Seepage are not included in the Canal Flow solution as they can be a function of Pool Elevation. Any non-default method selection in these three categories results in an error at the start of the run.
Then Canal Flow is set to an initial estimate of zero. With an estimate for Canal Flow, an estimate can be calculated for the remaining eight variables (Outflow, Inflow, Storage and Pool Elevation on both reservoirs) in the following order.
Note: The following description uses the syntax ObjVariable to indicate that these values are the intermediate values used in the calculation, not the values on the slots. If a variable is known, then ObjVariable is set equal to Object.Slot. Otherwise, it must be computed within the iterative bisection algorithm. Also, a positive canal flow represents flow from Res1 to Res2 and a negative canal flow represents flow from Res2 to Res1.
Res1Outflow
If not known, then Res1.Inflow must be known, and the outflow is either a function of maximum outflow or mass balance. If Res1.Outflow is flagged Max Capacity (M), then Res1Outflow is:
The function getMaxOutGivenIn uses the known Inflow, either input or propagated across a link from an upstream object, to compute the maximum outflow using the specified spill and power methods.
If Res1.Outflow is not flagged max capacity, then Res1.Storage must be input (or Res1.Pool Elevation is input and thus storage is known). Then Res1.Outflow is calculated from the mass balance:
Res1Inflow
If not known, then Res1.Outflow must be known and Res1.Storage must be input (or Res1.Pool Elevation is input and thus storage is known). Then Res1.Inflow is calculated from the mass balance:
Res1Storage
If not known, the Storage is a calculated from the mass balance:
Res1Pool Elevation
If not input, the pool elevation depends on the type of reservoir. For sloped reservoirs, the selected slope storage calculation is executed. It is a function of inflow, outflow and storage:
If it is not a sloped reservoir, the Pool Elevation is looked up on the Elevation Volume table:
Then the same variables are calculated for Reservoir 2 with the one difference being that a positive canal flow represents a flow out of the reservoir.
Res2Outflow
If not known, then Res2.Inflow must be known, and the outflow is either a function of maximum outflow or mass balance. If Res2.Outflow is flagged Max Capacity (M), then Res2Outflow is:
The function getMaxOutGivenIn uses the known Inflow, either input or propagated across a link from an upstream object, to compute the maximum outflow using the specified spill and power methods.
If Res2.Outflow is not flagged max capacity, then Res2.Storage must be input (or Res2.Pool Elevation is input and thus storage is known). Then Res2.Outflow is calculated from the mass balance:
Res2Inflow
If not known, then Res2.Outflow must be known and Res2.Storage must be input (or Res2.Pool Elevation is input and thus storage is known). Then Res2.Inflow is calculated from the mass balance:
Res2Storage
If not known, the Storage is a calculated from the mass balance:
Res2Pool Elevation
If not input, the pool elevation depends on the type of reservoir. For sloped reservoirs, the selected slope storage calculation is executed. It is a function of inflow, outflow and storage:
If it is not a sloped reservoir, the Pool Elevation is looked up on the Elevation Volume table:
With two new pool elevations, a new Canal Flow can be calculated based on the user-selected Canal Flow method.
For the first iteration, with an estimate of zero canal flow, the resulting pool elevations represent the maximum possible elevation difference and thus produce a canalFlowUpdated that is the maximum possible canal flow (absolute value). This represents an upper bound on the magnitude of canal flow, with the initial estimate of zero as the lower bound. These two bounds are then bisected to give a new estimate:
Then the process of calculating updated values for all variables is repeated. Each iteration provides two new bounds for canal flow, which move toward convergence with each iteration. In some cases, canalFlowUpdated can fall outside of the current bounds. In these cases, the algorithm can determine whether canalFlowEst for that iteration was too low or too high. It then replaces canalFlowUpdated with the appropriate existing bound when bisecting to calculate a new estimate. In other words, the solution never allows the bounds to expand from one iteration to the next; they are always converging.
Following are the convergence criteria used in the canal flow algorithm. That is, after each iteration, the new value is compared to the previous computed value. The iteration is stopped when the difference between old and new are within the indicated criteria. The iterations also stop the run with an error if max iterations has been exceeded.
Item | Stopping Criteria |
---|
Canal Flow | 10 m3/s |
Reservoir Storage | 1000 m3 |
Reservoir Inflows and Outflows | 10 m3/s |
Reservoir Pool Elevations | 0.01 m |
Max Iterations | 100 |
The quality of the canal flow solution is dependent on the quality of data in the Canal Flow Table and the reservoir tables. Inaccurate data in these tables or insufficient precision in these data may cause the solution to have difficulty converging.