You are on page 1of 9

Option Explicit

Private ERROR As Long


Global linkCount As Long
Global nodeCount As Long
Global selectedLinkCount As Long
Global linkIndexAddr As Range
Global diamAddr As Range
Global nodeAddr As Range
Global nodePressuresAddr As Range
Global linkAddr As Range
Global nodePressures(1724, 100)
Global linkIndicesArray As Variant

Public Sub openNetwork()


ERROR = ENopen(ActiveWorkbook.Path + "\inpp3.inp", ActiveWorkbook.Path +
"\inpp3.rep", "")
ERROR = ENopenH()
End Sub

Private Function getCount(ByVal property) As Long


Dim Value As Long
ERROR = ENgetcount(property, Value)
getCount = Value
End Function

Public Function getNodeCount() As Long


getNodeCount = getCount(EN_NODECOUNT)
End Function
Public Function getLinkCount() As Long
getLinkCount = getCount(EN_LINKCOUNT)
End Function

Public Sub closeNetwork()


ERROR = ENclose()
End Sub

Public Sub solve()


' run hydraulic solver

Dim T As Long
Dim Tstep As Long
Dim ID As String
Dim i, k As Long
Dim val, SumTime As Variant

SumTime = 0
Tstep = 3600
k=1
ENinitH (10)
Do
'run Epanet
ENrunH (T)
'read pressure head values and store them in internal variables
'assumption: simulation times coincide with the reporting times
For i = 1 To nodeCount
' ID = getNodeId(i)
'If ID = i Then
nodePressures(i, k) = EPANetInterface.getNodePressure(i)
Next i
'determine the next time step
val = ENnextH(Tstep)
SumTime = SumTime + Tstep

k = Application.WorksheetFunction.Ceiling(SumTime / 3600, 1) + 1
Loop While (Tstep > 0)
End Sub
Private Function getLinkValue(ByVal linkIndex As Long, ByVal property As Long)
As Single
Dim Value As Single
ERROR = ENgetlinkvalue(linkIndex, property, Value)
getLinkValue = Value
End Function

Private Sub setLinkValue(ByVal linkIndex As Long, ByVal property As Long, ByVal


Value As Single)
ERROR = ENsetlinkvalue(linkIndex, property, Value)
End Sub
Public Function getLinkDiameter(ByVal linkIndex As Long) As Single
getLinkDiameter = getLinkValue(linkIndex, EN_DIAMETER)
End Function
Public Function getLinkLength(ByVal linkIndex As Long) As Single
getLinkLength = getLinkValue(linkIndex, EN_LENGTH)
End Function

Public Sub setLinkDiameter(ByVal linkIndex As Long, ByVal diameter As Single)


Call setLinkValue(linkIndex, EN_DIAMETER, diameter)
End Sub
Private Function getNodeValue(ByVal nodeIndex As Long, ByVal property As
Long) As Single
Dim Value As Single
ERROR = ENgetnodevalue(nodeIndex, property, Value)
getNodeValue = Value
End Function
Private Sub setNodeValue(ByVal nodeIndex As Long, ByVal property As Long,
ByVal Value As Single)
ERROR = ENsetnodevalue(nodeIndex, property, Value)

End Sub
Public Function getNodeHead(ByVal nodeIndex As Long) As Single
getNodeHead = getNodeValue(nodeIndex, EN_HEAD)
End Function
Public Function getNodePressure(ByVal nodeIndex As Long) As Single
getNodePressure = getNodeValue(nodeIndex, EN_PRESSURE)
End Function
Public Function getNodeDemand(ByVal nodeIndex As Long) As Single
getNodeDemand = getNodeValue(nodeIndex, EN_DEMAND)
End Function
Public Function getNodeId(ByVal Index As Long) As String
Dim S As String
S = String$(255, vbNullChar)
ERROR = ENgetnodeid(Index, S)
getNodeId = Left(S, InStr(1, S, vbNullChar) - 1)
End Function
Public Function getLinkId(ByVal Index As Long) As String
Dim S As String
S = String$(255, vbNullChar)
ERROR = ENgetlinkid(Index, S)
getLinkId = Left(S, InStr(1, S, vbNullChar) - 1)
End Function
Public Function getLinkIndex(ByVal LinkID As String) As Long
Dim Index As Long
ERROR = ENgetlinkindex(LinkID, Index)
getLinkIndex = Index
End Function
Public Function getNodeIndex(ByVal NodeID As String) As Long
Dim Index As Long
ERROR = ENgetnodeindex(NodeID, Index)
getNodeIndex = Index
End Function

Public Sub setLinkRoughness(ByVal linkIndex As Long, ByVal roughness As


Single)
Call setLinkValue(linkIndex, EN_ROUGHNESS, roughness)
End Sub

Public Function getLinkFlow(ByVal linkIndex As Long) As Single


getLinkFlow = getLinkValue(linkIndex, EN_FLOW)
End Function

Public Function getLinkType(ByVal linkIndex As Long) As Single


Dim linkType As Long
ERROR = ENgetlinktype(linkIndex, linkType)
getLinkType = linkType
End Function
Sub simulation()
Dim i, j As Long
Dim linkType As Long
Dim ID As String

ActiveSheet.Calculate

' Read link indices from Excel into VBA - whole range is read at once to
improve the performance
Dim diametersArray() As Variant
' Dim nodeHeads() As Double

' ReDim nodeHeads(1 To nodePressuresAddr.Rows.Count, 1 To


nodePressuresAddr.Columns.Count)

diametersArray = diamAddr.Value

'write new diameters to EPANet


For i = 1 To selectedLinkCount

Call EPANetInterface.setLinkDiameter(linkIndexAddr.Cells(i, 1),


diamAddr.Cells(i, 1).Value)

Next i

'run simulation
EPANetInterface.solve

ActiveSheet.Calculate

'save nodal pressure heads to the spreadsheet


For i = 1 To 24
For j = 1 To nodeCount
nodePressuresAddr.Cells(j, i).Value = nodePressures(j, i)
Next j
Next i

're-calcualte the spreadsheet (updates the cell with objective function value)
'

ActiveSheet.Calculate
' Worksheets("Problem").UsedRange.Calculate
'
'read Pressure values and store them to internal variables
' For j = 1 To nodeCount'
' Store original diameters into the worksheet

'

nodeAddr.Cells(j, 1).value = EPANetInterface.getNodePressure(j)


' nodePressures(j, 1) = EPANetInterface.getNodePressure(j)

' Next j '


'
' nodePressuresAddr.Value = nodePressures

ActiveSheet.Calculate

End Sub

Option Explicit

Private Sub CommandButton1_Click()


Dim i As Long

' open network file


EPANetInterface.openNetwork

' read link count and node count from the file
EPANetInterface.linkCount = EPANetInterface.getLinkCount
EPANetInterface.nodeCount = EPANetInterface.getNodeCount

' write link count and node count to given cells


Range("B1").FormulaR1C1 = EPANetInterface.linkCount
Range("B2").FormulaR1C1 = EPANetInterface.nodeCount

' create range - this approach of accessing cells should be fast


Dim r As Range
Set r = Range("D10")

' read original link diameters and write them to column D starting from cell
D10

For i = 1 To EPANetInterface.linkCount
' Store original diameters into the worksheet
r.Offset(i - 1, -3) = EPANetInterface.getLinkId(i)
r.Offset(i - 1, -2) = i
r.Offset(i - 1, 0) = EPANetInterface.getLinkDiameter(i)
r.Offset(i - 1, 1) = EPANetInterface.getLinkLength(i)
Next i

Set r = Range("I10")
For i = 1 To EPANetInterface.nodeCount
' Load node indices
r.Offset(i - 1, -1) = EPANetInterface.getNodeId(i)
r.Offset(i - 1, 0) = i
r.Offset(i - 1, 1) = EPANetInterface.getNodeDemand(i)
Next i

EPANetInterface.selectedLinkCount = Range("B3").Value

Set EPANetInterface.linkIndexAddr = Range("B1765:B3519")


Set EPANetInterface.diamAddr = Range("F1765:F3519")
Set EPANetInterface.nodePressuresAddr = Range("P10:AN1734")

' Read manipulated link indices into an array


EPANetInterface.linkIndicesArray = EPANetInterface.linkIndexAddr.Value

End Sub

Private Sub CommandButton2_Click()


Call EPANetInterface.simulation

End Sub

Private Sub CommandButton3_Click()


EPANetInterface.closeNetwork
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub

You might also like