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.

# The ResSim Blog

This blog was created by Kevin Fagot of WEST Consultants to be a forum for the modeling of reservoir systems in HEC-ResSim along with providing explanations of reservoir operations and dam operations. Additionally, programming examples in Python and Jython (scripting language used in HEC-ResSim) are also shown (with a few random Excel examples also included). The posts are labeled by topic so you can use the menu below or search by topic.

## Tuesday, November 29, 2016

## 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).

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).

## Tuesday, November 15, 2016

### Using HEC-DSSVue to convert irregular data to hourly data

In this post, HEC-DSSVue is used to convert an irregular time series to an hourly time series. Our irregular data consists of two values per day, one at noon and one at midnight.

The naming convention for DSS paths is as follows:

A part = Project, river, or basin name

B part = Location

C part = Data parameter

D part = Starting date of block, in a 9 character military format

E part = Time interval

F part = Additional user-defined descriptive information

The naming of the data set is shown below. Notice that the E part selected is IR-DAY, which means that we are entering irregular data for each day. The data that we are entering are pool elevation values for "Big Reservoir".

Data is entered for the first three days of January 2016 at noon and midnight.

We use the math function in DSSVue to convert irregular to regular selecting a time interval of 1 hour.

Now we have data at each hour. The hourly intervals are developed using interpolation.

From this computation, a new DSS path is created while the original DSS path is maintained.

It is important to check the data prior to performing this conversion. In the figure below, there is an error in one of the values giving a pool elevation of 5.19 feet instead of 55.19 feet.

If the computation is performed on this data set, the following data set is developed.

The naming convention for DSS paths is as follows:

A part = Project, river, or basin name

B part = Location

C part = Data parameter

D part = Starting date of block, in a 9 character military format

E part = Time interval

F part = Additional user-defined descriptive information

The naming of the data set is shown below. Notice that the E part selected is IR-DAY, which means that we are entering irregular data for each day. The data that we are entering are pool elevation values for "Big Reservoir".

Data is entered for the first three days of January 2016 at noon and midnight.

We use the math function in DSSVue to convert irregular to regular selecting a time interval of 1 hour.

Now we have data at each hour. The hourly intervals are developed using interpolation.

From this computation, a new DSS path is created while the original DSS path is maintained.

It is important to check the data prior to performing this conversion. In the figure below, there is an error in one of the values giving a pool elevation of 5.19 feet instead of 55.19 feet.

If the computation is performed on this data set, the following data set is developed.

## Sunday, November 13, 2016

### Microsoft Excel Advanced #4 - Using conditional formatting and sorting

This post is a continuation of Microsoft Excel Advanced #3 where two columns were compared. In the figure below, we check in column C whether each value in column B is in column A. If it is, then "yes" is placed in column C. If it is not, then "no" is placed in column C. Note that the formula for doing this is shown in Microsoft Excel Advanced #3.

If you have many values that need to be checked, then going through all of column C looking for "yes" and "no" can be time consuming. To help with this, we select "Conditional Formatting" and "Use a formula to determine which cells to format".

Since cell C2 contains "yes", cell B2 is filled with red.

We want to apply this formula to the rest of the values in column B so we need to copy cell B2 and then Paste Special - Formats. Make sure that you paste only the formats. If you do a copy and paste, you will paste the contents as well, but we don't want that.

Now all of the red shaded cells (all that have "yes" in column C) will be grouped together.

If you have many values that need to be checked, then going through all of column C looking for "yes" and "no" can be time consuming. To help with this, we select "Conditional Formatting" and "Use a formula to determine which cells to format".

The formula that we write for cell B2 is as follows: =c2="yes". This is shown in the figure below.

We also indicate that we want the fill to be red if the formula is true.

We want to apply this formula to the rest of the values in column B so we need to copy cell B2 and then Paste Special - Formats. Make sure that you paste only the formats. If you do a copy and paste, you will paste the contents as well, but we don't want that.

Below we see that both cell B2 and cell B5 are now red.

Once that is completed, you can then sort by color. To do this, we select all values in columns B and C and then select Data - Sort. We are sorting by Column B and sorting on the color red.

### Python Advanced #5 - Using Python to determine the number occurrences in a list

This post shows how to determine the number of occurrences in specified bins for a list of numbers.

The coding is commented in the program and is shown below.

The results of simulating this program are shown below.

The coding is commented in the program and is shown below.

The results of simulating this program are shown below.

### Python Advanced #4 - Using Python Dictionaries for Paired Data

This post will demonstrate the use of dictionaries in Python along with showing an example of their use with paired numerical data.

The paired numerical data in this example is a relationship between a water surface elevation in a stream and the corresponding flow. However, this coding will work for any paired numerical data.

First, an example of a dictionary and its use is needed. In the figure below, we have a dictionary titled, "paired_data". Note that a dictionary is defined with {}. In this dictionary, we have the keys 1, 2, 3, and 4. Associated with these keys are the values of 100, 200, 300, and 400.

In the print statement, we are asking that Python print the value corresponding to a key of 2 in the dictionary, "paired_data".

The following is the result:

Just as with a regular dictionary where a word can have multiple definitions, a key in a Python dictionary can have multiple values associated with it. In the example below, we create an empty dictionary named "pairs".

We then populate "pairs" with multiple values for the key, "elevation", and multiple values for the key, "flow". Note that the same information as above is used, it is simply in a slightly different format.

In the remainder of the coding, we perform the following steps:

The result of running the program is shown below.

The paired numerical data in this example is a relationship between a water surface elevation in a stream and the corresponding flow. However, this coding will work for any paired numerical data.

First, an example of a dictionary and its use is needed. In the figure below, we have a dictionary titled, "paired_data". Note that a dictionary is defined with {}. In this dictionary, we have the keys 1, 2, 3, and 4. Associated with these keys are the values of 100, 200, 300, and 400.

In the print statement, we are asking that Python print the value corresponding to a key of 2 in the dictionary, "paired_data".

The following is the result:

Just as with a regular dictionary where a word can have multiple definitions, a key in a Python dictionary can have multiple values associated with it. In the example below, we create an empty dictionary named "pairs".

We then populate "pairs" with multiple values for the key, "elevation", and multiple values for the key, "flow". Note that the same information as above is used, it is simply in a slightly different format.

In the remainder of the coding, we perform the following steps:

- Ask the user to input an elevation
- We extract the elevation and flow values that bracket the input elevation
- We write a function to interpolate using the upper and lower elevation and flow values
- We call the function
- We print out the value of the flow

The result of running the program is shown below.

Subscribe to:
Posts (Atom)