Friday, December 23, 2016

Initialization and Main Tab in State Variables in HEC-ResSim

This post will demonstrate the use of the Initialization tab for state variables in HEC-ResSim.

For state variables, the code that resides in the Main tab is run at each time step.  The code that resides in the Initialization tab is run only at the beginning of the simulation.  For computational efficiency and clean organization of the code, it may be desirable to store constants and functions in the Initialization tab.

To demonstrate this, I developed a simple model consisting of two reservoirs.  There are no rules in the downstream reservoir.  The upstream reservoir has a single rule that is based on the value of the state variable.

Below is the reservoir network.

The image below shows the maximum release rule at the upstream reservoir being dependent on the value of the state variable "upstreammaxrel".

In this example, we use a dictionary to correlate the maximum allowable release with the pool elevation.  For example, a maximum release of 500 cfs is used for pool elevations up to and including 75 feet, a maximum release of 1,500 cfs is used for pools elevation greater than 75 feet and less than or equal to 77 feet, etc.  This code is shown below.  Note that all of the code is entered into the main tab for this example.


It may be desirable to move the dictionary values to the Initialization tab.  The coding for the Initialization tab and the Main tab is shown below:

Initialization tab:

Main tab:

Note that sending the dictionary from the Initialization tab to the Main tab is accomplished through the use of the varPut and varGet commands.

The point of this post was to show the use of the initialization and main tab, however, this example also provides us with an opportunity to examine the behavior of HEC-ResSim and the caution that needs to be exercised when developing realistic rules.  The output at the upstream reservoir from this simulation is shown below.  Note that the green line (reservoir outflow) is very bouncy.  This is due to the maximum release being strictly defined at discrete elevations.

Tabulating the result provides a more comprehensive evaluation of the behavior (note that the last three columns in the table below are pool elevation, inflow, and outflow).  In the state variable, we are using the previous value of the pool elevation to determine the maximum release.  On 07Jan2016 at 12:00, the pool elevation is 75.046 ft.  Since the reservoir is in its flood pool, HEC-ResSim releases the maximum of 1,500 cfs (from the state variable computation) to bring the pool elevation down to 75.021 at the next time step.  It again releases 1,500 cfs to bring the pool down to 75.004 ft.  At this time, HEC-ResSim only releases 1,300 cfs to bring the pool down to the top of conservation level of 75.0 feet.  Once at this level, the maximum release becomes 500 cfs for that time step.  Since the inflow is greater than 500 cfs (set to a constant 1,200 cfs), the pool rises back into the flood pool at the next time step and the cycle starts over.

Since HEC-ResSim interprets our commands very literally, the behavior is what should be expected.

A review of Python Dictionaries

This post will provide a brief review of Python dictionaries.  For this review, both the keys and the items are numerical.

Below is a dictionary with the name, "upstream_res_rel".

upstream_res_rel = {75:500, 77:1500, 80:2000, 120:2500}

To print the keys in a sequential manner, I use the following command:

Below is the result:

To get a specific item in the dictionary, I use the following command:

Below is the result:

Wednesday, December 14, 2016

Putting a hydropower plant on a diverted outlet in HEC-ResSim

I recently received a question regarding the placement of a hydropower plant on a diverted outlet.  Since I had not done that before, I developed this example to demonstrate this in HEC-ResSim.

In the figure below, there are two reservoirs on the main stem of the river.  There is also a tributary entering the main stem at the junction named "confluence".

There is a diverted outlet coming from the upstream reservoir and re-entering the main stem at the junction named "hydro return".

Here are some of the pertinent parameters of the model:

1.)  There is 1,200 cfs entering the system at both the upstream end of the main stem and the upstream end of the tributary.

2.)  The upstream reservoir has a controlled outlet at the dam (capacity 1,500 cfs) and the diverted outlet from the reservoir.  On the diverted outlet, there is a power plant with a hydraulic capacity of 1,500 cfs, a generating capacity of 4 MW, and an efficiency of 85%.  The station use and hydraulic losses are set to zero in our example.

3.)  The downstream reservoir has a controlled outlet with a capacity of 1,500 cfs.

4.)  The tailwater associated with the power plant is a constant 50 ft.

5.)  The top of conservation for both reservoirs is set to 75 ft and this elevation is held throughout the entire simulation by passing inflow.

Note that on the upstream reservoir, two outlet groups are modeled.  One outlet group is at the dam and one is the diverted outlet from the reservoir.  Also note that there is a tailwater associated with the power plant.  This is needed for HEC-ResSim to compute the generation.

The operations set for the upstream reservoir contains no rules.  Since our simulation will start at the top of conservation, inflow will be passed to hold the top of conservation.

Since we have two outlet groups at the upstream reservoir, I set the release allocation to "Balanced" to have half the inflow go through the dam and half the inflow go to the diverted outlet.

The downstream reservoir will also pass inflow.

Below are the lookback conditions.  Both reservoirs start at the top of conservation of 75 ft.  The release through the dam of the upstream reservoir is 600 cfs (half the inflow).  The other half of the inflow goes to the diverted outlet.  The downstream reservoir will be passing 600 cfs of inflow since the 600 cfs going through the diverted outlet re-enters the system below the downstream reservoir.

In the reach below the upstream reservoir, there is 600 cfs for both the lookback and simulation period.  This is what we should expect to see.

At the junction named "confluence", there is 1,800 cfs.  Of this total, 600 cfs comes from the main stem while 1,200 cfs comes from the tributary.  The 1,200 cfs is shown as the local contribution in the figure below.

At the junction named "hydro return", the total flow is 2,400 cfs.  This is due to an additional 600 cfs coming in from the diverted outlet.

The computation of power is shown below.

Power computed in MW is equal to (Q*w*h*e) / 737,560

Q in cfs
w in lb/ft^2
h is head differential in feet (75 ft - 50 ft for this example)
e is efficiency

MW = (600*62.4*25*.85)/737,560 = 1.08 MW

The line at the top of the plot shows the potential generation assuming the entire hydraulic capacity is used:

MW = (1500*62.4*25*.85)/737,560 = 2.70 MW

Tuesday, December 13, 2016

Python Advanced #7 - Using Python class for Physics problem to determine distance traveled based on velocity and angle

This post is similar to Python Advanced #6 only it uses a Python class to determine the distance traveled based on velocity and angle.

Instead of using individual functions, we create a class to perform the computations.  The object. "distance", becomes an instance of the class, "Dist_comp", with the angle and velocity being sent to the class.  In our example, we have three angles in a list.  We use 100 ft/s for all examples.

The Python coding is shown below:

 The results are shown below (note that 45 degrees gives the maximum distance):

In the coding above, the 100 ft/s was sent as a constant.  This can also be sent as an entry in a Python dictionary.  This would allow for varying of the velocity as well as the angle.  Some of the previous coding is commented out, and the new code has been added.  This is shown below:

The results of this simulation are the same as those given above.

Python Advanced #6 - Using Python functions for Physics problem to determine distance traveled based on velocity and angle

To code this, we first need to understand how the computations are performed.

The first step is to break the velocity into its x and y components.  The x-component is determined by multiplying the velocity by the cosine of the angle from the horizontal.  The y-component is determined by multiplying the velocity by the cosine of 90 degrees minus that angle.

So, if the angle from the horizontal is 30 degrees, the x-component is derived by using cosine(30), and the y-component is derived by using cosine(60).

To get the travel time, we start by dividing the y-component of the velocity by 32.2 ft/s^2.  This is derived by the following:

final velocity = initial velocity + acceleration * time

At the highest point, the y component of the velocity is zero.  This is also the halfway point of the travel time.  Setting final velocity to zero and rearranging the variables gives the following:

time = initial velocity / acceleration

On the way up the acceleration is actually deceleration.

Remember to double the time since we are only computing the time to get to the halfway point.  In other words, it needs to come back down.

We can then solve for the distance traveled by multiplying the time by the x component of the velocity.  Note that we are neglecting the impact of the forces affecting the x component of the velocity.

The Python coding for this is shown below.  In the code, we use three functions to determine the following:

1.)  x and y components of the velocity
2.)  total travel time
3.)  distance traveled

Also, note that the result of the functions are being sent to a different function.

The result of running the program with 30 degrees and 100 ft/s is given below: