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:



Tuesday, November 29, 2016

Review of rule logic in HEC-ResSim

This post further demonstrates the rule logic and rule behavior in HEC-ResSim.

The network below contains two reservoirs, one on the main stem and one on a tributary.  There is 1,000 cfs entering the main stem and 1,000 cfs entering the tributary.



The tributary reservoir has no rules of operation.  Basically, this means that the only constraint placed on that reservoir is the physical capacity of 5,000 cfs.



The reservoir on the main stem has a downstream control function that wants to limit the flow at the downstream junction, "downstream control point", to 2,200 cfs.  Note that with no restrictions on the tributary reservoir, trying to keep the flow at or below 2,200 cfs falls solely on the main stem reservoir.




The tributary reservoir operations are shown below.  The simulation begins with the reservoir in the flood pool.  Since ResSim wants to release as much as possible and with the tributary reservoir having no restrictions, it releases its full physical capacity of 5,000 cfs (once the lookback period ends) until the pool is empty.  It then passes the inflow of 1,000 cfs to hold top of conservation.




The main stem reservoir operations are shown below.  Since the downstream control function is being violated, the main stem reservoir releases zero (after the lookback period) until the tributary reservoir is empty.  At that point, the tributary reservoir is releasing the inflow of 1,000 cfs leaving 1,200 cfs capacity for the main stem reservoir.  Note that I am using null routing in this model.




I also wanted to use this example to further explain when rule priority applies.  For the next simulation, I add a maximum release rule of 500 cfs below the downstream control function rule.  Basically, I now have two maximum release rules.  The rule set is shown below.



The result of this simulation is shown below.



The release still goes to zero until the tributary reservoir is empty, however, now the release only increases to 500 cfs instead of 1,200 cfs.  The reason for this is the ResSim uses the lowest maximum regardless of the order in the rule set.  So, even though "ds rule" is at a higher position in the rule set, "max rel from main" still governs.

For minimum release rules, ResSim will use the highest minimum in the rule set.  Rule priority, or the location of the rule in the rule set, factors in when there is a mix of minimum and maximum rules.


Monday, November 28, 2016

Microsoft Excel Advanced #5 - Using Macro to convert time series data from rows to columns

This post will show the use of a macro in Excel to convert time series data from rows to columns.  In the figure below, there is an elevation reading at 8:00 am and 4:00 pm each day.  We want to get the elevation data into a single column.  


On a new sheet we develop a column with the date and time (column A) and a single column for the elevation values (column B).  We begin by putting the first date and time in cell A2.  In cell A3, we add 8 hours to the value in cell A2.


In cell A4, we add 16 hours to cell A3.


We can then copy cells A3 and A4 to cells A5:A11.  Our date and time column is now ready.


To get the elevation data into a single column, we can record a macro since the steps are repetitive.  In the figure below, we name the macro, "data_into_columns", and make a shortcut key of Ctrl+A.


For this example, I copied the data into a different portion of the worksheet.  I begin recording the macro with the cursor on row 10.  Additionally, for this macro to work correctly, "Use Relative References", must be selected.


The first step is to arrow down one row and insert a new row.


The next step is to arrow up to the second value on row 10.  I select CTRL-X, then arrow down to row 11, and select CTRL-V.  I then arrow down one row so that the cursor will be in the correct location for the macro.  I can then stop recording.  These steps are shown in the next three figures below.




With the macro now recorded, I can simply select CTRL-A enough times to move all of the values into a single column.


I can then move this single column next to the date and time that was created earlier.


Friday, November 18, 2016

Compute Blocking in HEC-ResSim

HEC-ResSim first performs its computations at the upstream end of the main stem of the river system and at the upstream end of the tributaries and works its way downstream.  If there is a rule that has dependence on a downstream condition that does not appear to be behaving correctly, there may be a compute blocking issue.  In this post, I will demonstrate a compute blocking issue and show how to solve it.

The river system in this example consists of a main stem with two reservoirs.  Both reservoirs have a top of conservation level of 75.0 feet.  For this simulation, I started both reservoirs in their flood pool.  The downstream reservoir has no rules so it releases it physical capacity of 1,500 cfs until the flood pool is empty.



The upstream reservoir has a scripted rule that sets the maximum release to 100 cfs if the downstream reservoir is at 77.0 feet or higher.  Once the downstream reservoir is below 77.0 feet, the maximum release increases to 1,200 cfs.  The script is shown below.





Below are the results of the simulation for the upstream reservoir.  At the first time step after the lookback period, the release is correct since the downstream pool elevation is available.  However, due to compute blocking, the downstream elevation is not available at the time the script is run so the the "else" condition is triggered allowing for 1,200 cfs.



The plot below shows the downstream pool elevation.  We can see that the pool elevation starts at 80.0 feet so the release at the upstream reservoir should be held at 100 cfs until the downstream pool elevation falls to 77.0 feet.



Below is a screenshot of the compute blocking found in the compute log.  Note that there are 9 blocks with CP1 (upstream end of model) being the first block.



To solve our issue, I want to create dependence of a downstream element for the upstream reservoir.  To do this, I simply create a "dummy" rule at the upstream reservoir setting a minimum release of zero for a very large range of values at the junction, "downstream point".  A minimum release rule of zero does not affect the operations, it simply creates the dependence we are seeking.



The addition of this rule now decreases the number of compute block and puts the computations of the upstream and downstream reservoir into the same compute block.



The results for the upstream reservoir are shown below.  The release is held to 100 cfs at the beginning of the simulation and then increases to 1,200 cfs once the downstream reservoir falls below 77.0 feet (note: the downstream reservoir results are not shown).