In a previous blog post, I wrote an introduction to automating HEC-RAS using the HEC-RAS Controller. For this blog post, I will be showing you how to write a simple program that retrieves output data using the HEC-RAS Controller.
Getting Output Using the HEC-RAS Controller
Download the Appropriate Files
For this exercise, I will be using the Critical Creek example data. This data is available in the Example Projects folder that comes with your HEC-RAS download. If you are having a hard time finding these files, feel free to download the attached files.
Open the Model in HEC-RAS
Now it is time to start writing our program. First pull up Excel VBA by clickicking Alt+F11. Then instantiate a new HECRASController class. This is a fancy way of saying creating an occurrence of the HEC-RAS Controller class. Next, open the HEC-RAS project in the background using the Project_Open subroutine. The Project_Open subroutine starts the HEC-RAS software in the background. To open HEC-RAS, use the ShowRas subroutine. This will literally show HEC-RAS while the program is running. Example code is shown below.
Sub HECRASController1()
'1. Instantiate a new HECRASController Class
Dim RC As New RAS504.HECRASController
'2. Open HEC-RAS Project in the background
Dim strRASProject As String
strRASProject = "C:\filepath\RAS Model\Baxter.prj"
RC.Project_Open (strRASProject)
'3. Open the HEC-RAS Project
RC.ShowRas
End Sub
Populating the Geometry
Secondly, we will use the Geometry_GetNodes subroutine to obtain the geometry information before retrieving output data. Example code is shown below.
Sub HECRASController1()
'4. Run the HEC-RAS
Dim lngMessages As Long 'Number of messages returned
Dim strMessages() As String 'String of messages returned
RC.Compute_CurrentPlan lngMessages, strMessages()
'5. Get nodes and node types
Dim lngRiverID As Long, lngReachID As Long 'River ID and Reach ID
lngRiverID = 1 'Hard-coded River ID since there is only one
lngReachID = 1 'Hard-coded Reach ID since there is only one
Dim lngNum_RS As Long 'Number of nodes
Dim strRS() As String 'Array of name of nodes
Dim strNodeType() As String
RC.Geometry_GetNodes lngRiverID, lngReachID, lngNum_RS, strRS(), strNodeType()
End Sub
Retrieving Output
Thirdly, we will write the code that retrieves the output data. Although we got the river stations and node types in the previous step, some variables still need to be declared to obtain output. This involves declaring a single array for water surface elevations (or whatever you are retrieving), re-dimensioning the array to the number of river stations, and declaring the appropriate RAS ID. There are 268 HEC-RAS variables available in the HEC-RAS Controller. The table below lists some variables available in HEC-RAS and their associated IDs.
RAS ID | Description |
---|---|
1 | Profile Number |
2 | Water Surface Elevation |
3 | Energy gradeline |
9 | Total flow in a cross section |
10 | Flow Area |
22 | Velocity Head |
23 | Average velocity in cross section |
32 | Flow Area of the entire cross section including ineffective flow |
48 | Froude number for the main channel |
49 | Froude number for the entire cross section |
58 | Critical depth |
59 | Friction loss between two cross sections |
62 | Top width of the wetted cross section |
68 | Friction slope between two cross sections |
73 | Flow through all barrels in a culvert |
74 | Flow through one barrel in a culvert |
94 | Flow over the weir |
223 | Surface area of a storage area |
224 | Storage volume of a storage area |
233 | Flow from a piping failure |
260 | Flow through a breach |
Next, write a for loop that will get data for each cross section. The code block below outlines the steps.
Sub HECRASController1()
'6. Retrieving Output Data
Dim sngWS() As Single 'Array of water surface elevations
ReDim sngWS(1 To lngNum_RS)
Dim lngWS_ID As Long
lngWS_ID = 2
Dim i As Long
For i = 1 To lngNum_RS
If strNodeType(i) = "" Then
sngWS(i) = RC.Output_NodeOutput(lngRiverID, lngReachID, i, 0, 3, lngWS_ID)
strRS(i) = RC.Geometry.NodeRS(lngRiverID, lngReachID, i)
End If
Next i
End Sub
Putting the data in a Spreadsheet
Finally, export your output to an Excel file. The code for performing this step is shown below. I also encourage you to try this with various variables in HEC-RAS.
Sub HECRASController1()
'7. Writing Output Data to Spreadsheet
Dim blnSheetExists As Boolean
For i = 1 To Sheets.Count
If Sheets(i).Name = "RASResults" Then
blnSheetExists = True
End If
Next i
'Add RASResults if it doesn't exist as a sheet
If blnSheetExists = False Then
Sheets.Add
ActiveSheet.Name = "RASResults"
End If
Sheets("RASResults").Select
'Clear all data
Cells.Select
Cells.Delete
'Title
Range("A1").Select
ActiveCell.Value = "Results from HEC-RAS"
Range("A2").Select
ActiveCell.Value = RC.CurrentPlanFile
Range("A3").Select
'**********************************************************
'Demonstrates the Plan_Names subroutine and _
Plan_GetFilename function
'Written by Christopher Goodell
'June 28, 2014
'Determines the current plan name, given the current plan _
file. Requires HECRASController as a parameter.
'http://hecrasmodel.blogspot.com/p/book.html
'**********************************************************
'Get all of the Plan Names in the project
Dim lngPlanCount As Long, strPlanNames() As String
Dim blnBasePlans As Boolean
RC.Plan_Names lngPlanCount, strPlanNames(), blnBasePlans
'Determine the current plan name.
Dim j As Integer
Dim strPlanFileNames() As String
ReDim strPlanFileNames(1 To lngPlanCount)
For j = 1 To lngPlanCount
strPlanFileNames(j) = RC.Plan_GetFilename(strPlanNames(j))
If strPlanFileNames(j) = RC.CurrentPlanFile Then
GetCurrentPlanName = strPlanNames(j)
End If
Next j
ActiveCell.Value = GetCurrentPlanName
'Headers
Range("A5") = "Cross Section"
Range("B5") = "WS El (ft)"
Dim strWSEL As String
Range("A6").Select
For i = 1 To lngNum_RS
strWSEL = Round(sngWS(i), 2)
If strNodeType(i) = "" Then
ActiveCell.Value = strRS(i)
ActiveCell.Offset(0, 1).Activate
ActiveCell.Value = strWSEL
ActiveCell.Offset(1, -1).Activate
End If
Next i
'Close HEC-RASS
MsgBox "Program Complete!!"
RC.QuitRas
End Sub