Objects and Methods

Reservoir Convergence

Introduction

This document describes the convergence algorithm used by the getMaxOutflow, getMaxRelease, getMinSpillGivenInflowRelease and the mass balance functions. These functions are used by the Storage, Level Power and Slope Power reservoirs. The purpose of each of these functions is to solve for the variable of interest which is dependent upon a second changing variable. The functions must be simultaneously solved to determine the variable of interest. For example, the getMaxOutflow function returns the maximum allowable outflow based on the pool elevation. Two function are used in this iterative process; the mass balance and maximum outflow functions. The reservoir inflows are known and the function searches for the solution for maximum outflow that satisfies both the maximum outflow tables (max outflow as a function of pool elevation) and the mass balance equation for the reservoir. As guesses for the maximum outflow change, the pool elevation fluctuates as a result of the changing storage as calculated by the mass balance equation. This pool elevation is then used to determine a new maximum outflow value. Thus, an iterative search algorithm is needed to simultaneously solve the functions. Two types of search algorithms are employed to find the solution. The first algorithm iterates by updating the variable of interest based on the independent variable (usually pool elevation) in each iteration. For example, during each iteration in the getMaxOutflow function, outflow is calculated based on the mass balance pool elevation. At the end of each iteration, the outflow value is compared to that of the previous iteration and the algorithm is exited if these values are within convergence. The values are considered converged if

Note: If New Value is zero, the Old Value is used as the denominator. If Old and New Value are both zero, it has converged. Convergence Percentage is a general slot on the reservoir which defaults to 0.0001 if not input by the user.

Under certain circumstances, this simplistic iterative routine may fall into a loop that iterates around the solution and never converges. In this event, the bisection routine is invoked using the final values from the first routine as its initial conditions.

The bisection routine is an incremental search method in which the functions are reevaluated at the midpoint of the interval between the values of the previous guess to determine on which side of the midpoint the root lies. Depending on which side of the midpoint the root lies, the midpoint becomes either the upper or lower bound to the search interval. The interval is again divided in half and the functions are reevaluated at the midpoint. This procedure is repeated until the solution is obtained.

Example

The following example describes how the bisection method is implemented in the function getMaxOutflowGivenInflow. The mass balance functions and getMinSpillGivenInflowRelease use the identical procedure

Given the total inflow over the timestep, getMaxOutflowGivenInflow returns the maximum outflow. This function is either called by a rule or executed as a result of a max capacity flag being set on an outflow slot. The maximum outflow is a combination of the maximum release (turbine release if the object is a Level Power Reservoir or a Slope Power Reservoir), the maximum regulated and unregulated spill, and the maximum bypass. In the event that the first iterative routine fails, the bisection routine is started with six final values that were determined during the final two iterations of the first routine. These six values can be combined to form four pairs of Cartesian coordinates where storage is on the x-axis and outflow is on the y-axis. For the purpose of this example, these values are denoted as

• stor_high = the largest storage value returned from the mass balance function

• stor_low = the smallest storage value returned from the mass balance function

• qMB_high = the outflow corresponding to stor_high determined by mass balance

• qMB_low = the outflow corresponding to stor_low determined by mass balance

• qMAX_high = the outflow corresponding to stor_high determined by the max outflow function

• qMAX_low = the outflow corresponding to stor_low determined by the max outflow function

Figure A.1 depicts these coordinates graphically. The functions fMB and fMAX denote the mass balance and the max outflow functions, respectively.

Figure A.1

The root of the mass balance and max outflow functions is the intersection of the two curves. To begin the search for this intersection, the routine finds the average of stor_high and stor_low, denoted as stor_ave, and then calculates the corresponding outflows, denoted as qMB_ave and qMAX_ave. Figure A.2 is an illustration.

Figure A.2

Thus, two intervals have been created. The upper interval is between stor_ave and stor_high, the lower interval is between stor_low and stor_ave. Visually it is apparent that the solution lies in the upper interval. The algorithm determines the interval in which the solution lies using an if-statement. Generally, the if-statements compare qMB_ave to qMAX_ave. If qMB_ave > qMAX_ave, the solution lies in the upper interval. Conversely, if qMB_ave < qMAX_ave, the solution lies in the lower interval. In this example, qMB_ave > qMAX_ave, thus, the solution lies in the upper interval and stor_ave becomes the lower bound by setting stor_low equal to stor_ave. The first step of the second iteration is to calculate a new stor_ave to determine the midpoint of the new interval. Figure A.3 illustrates the results of the second iteration.

Figure A.3

The search area has decreased because the lower interval was eliminated in the first iteration. The outflows were evaluated using stor_ave resulting in qMB_ave < qMAX_ave. Thus, the solution lies in the lower interval; stor_high is set equal to stor_ave and the third iteration is begun. The first step of the third iteration is again to calculate the midpoint of the new interval. The same process is repeated until the values of qMB_ave and qMAX_ave are within convergence. At this point the algorithm is exited and stor_ave and the minimum value of qMAX_ave and qMB_ave are returned as the solution.

The getMinSpillGivenInflowRelease and the mass balance functions evaluate the variables using different curves, but follow the identical procedure as described above. For example, in getMinSpillGivenInflowRelease fmax would be replaced by fmin which describes the behavior of the spill curve.

Revised: 06/03/2019