From 70f51d9567d93612036b2aad817a98be72a7af1f Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Tue, 28 Aug 2018 00:19:56 +0300 Subject: [PATCH 1/8] add ENsetdemandpattern --- include/epanet2.bas | 1 + include/epanet2.h | 10 ++++++++++ include/epanet2.vb | 4 +++- src/epanet.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/epanet2.bas b/include/epanet2.bas index 0ded96c..88f2135 100644 --- a/include/epanet2.bas +++ b/include/epanet2.bas @@ -254,6 +254,7 @@ Public Const EN_G_CURVE = 4 ' General\default curve Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal QualCode As Long, ByVal ChemName As String, ByVal ChemUnits As String, ByVal TraceNode As String) As Long Declare Function ENgetqualinfo Lib "epanet2.dll" (QualCode As Long, ByVal ChemName As String, ByVal ChemUnits As String, TraceNode As Long) As Long Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal DemandIndex As Long, ByVal BaseDemand As Single) As Long + Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal Index As Long, ByVal DemandIndex As Long, ByVal PatIndex As Long) As Long Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long diff --git a/include/epanet2.h b/include/epanet2.h index e6d91c6..0aeb7b4 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -932,6 +932,15 @@ extern "C" { @see ENgetbasedemand */ int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + + /** + @brief Sets the index of the demand pattern assigned to a node for a category index. + @param nodeIndex The index of a node (first node is index 1). + @param demandIndex The index of a category (first category is index 1). + @param pattIndex The index of the pattern for this node and category. + @return Error code + */ + int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIdx, int patIndex); /** @brief Retrieves index of curve with specific ID. @@ -1265,6 +1274,7 @@ extern "C" { int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode); int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int patIndex); int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index); int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id); int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len); diff --git a/include/epanet2.vb b/include/epanet2.vb index fcb71af..069db45 100644 --- a/include/epanet2.vb +++ b/include/epanet2.vb @@ -197,8 +197,10 @@ Public Const EN_CUSTOM = 2 ' user-defined custom curve Declare Function ENsetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByVal X As Single, ByVal Y As Single) As Int32 Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal Index As Int32, ByRef numDemands As Int32) As Int32 'ES - Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef Value As Single) As Int32 'ES + Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef BaseDemand As Single) As Int32 'ES + Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByVal BaseDemand As Single) As Int32 'ES Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef PatIndex As Int32) As Int32 'ES + Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByVal PatIndex As Int32) As Int32 'ES Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32 Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32 diff --git a/src/epanet.c b/src/epanet.c index 6463c08..6f1254c 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -473,6 +473,10 @@ int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, return EN_setbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand); } +int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIdx, int patIndex) { + return EN_setdemandpattern(_defaultModel, nodeIndex, demandIdx, patIndex); +} + int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) { return EN_getdemandpattern(_defaultModel, nodeIndex, demandIdx, pattIdx); } @@ -4516,6 +4520,36 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx return set_error(pr->error_handle, 0); } +int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int patIndex) { + + EN_Project *pr = (EN_Project*)ph; + + EN_Network *net = &pr->network; + Snode *Node = net->Node; + + const int Nnodes = net->Nnodes; + const int Njuncs = net->Njuncs; + const int Npats = net->Npats; + + Pdemand d; + int n = 1; + /* Check for valid arguments */ + if (!pr->Openflag) + return set_error(pr->error_handle, 102); + if (nodeIndex <= 0 || nodeIndex > Nnodes) + return set_error(pr->error_handle, 203); + if (patIndex < 1 || patIndex > Npats) + return(205); + if (nodeIndex <= Njuncs) { + for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) + n++; + if (n != demandIdx) + return set_error(pr->error_handle, 253); + d->Pat = patIndex; + } + return set_error(pr->error_handle, 0); +} + int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int *pattIdx) { EN_Project *p = (EN_Project*)ph; From 8ca56d7c9d35b8a8f8ba617f4c030d8f243b6731 Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Tue, 28 Aug 2018 00:25:31 +0300 Subject: [PATCH 2/8] remove space --- src/epanet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/epanet.c b/src/epanet.c index 6f1254c..18c6540 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -473,7 +473,7 @@ int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, return EN_setbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand); } -int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIdx, int patIndex) { +int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIdx, int patIndex) { return EN_setdemandpattern(_defaultModel, nodeIndex, demandIdx, patIndex); } From 476604bf6f14f406aca10890f09738da11006917 Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Tue, 28 Aug 2018 12:07:25 +0300 Subject: [PATCH 3/8] add ENsetdemandpattern function in epanet2.def --- win_build/WinSDK/epanet2.def | 1 + 1 file changed, 1 insertion(+) diff --git a/win_build/WinSDK/epanet2.def b/win_build/WinSDK/epanet2.def index 46c82c2..a497c50 100644 --- a/win_build/WinSDK/epanet2.def +++ b/win_build/WinSDK/epanet2.def @@ -65,6 +65,7 @@ EXPORTS ENsetcoord = _ENsetcoord@12 ENgetqualinfo = _ENgetqualinfo@16 ENsetbasedemand = _ENsetbasedemand@12 + ENsetdemandpattern = _ENsetdemandpattern@12 ENgetaveragepatternvalue = _ENgetaveragepatternvalue@8 ENgetheadcurveindex = _ENgetheadcurveindex@8 ENgetpumptype = _ENgetpumptype@8 From c0b91fa9e32ec989faca8c2fe0cd65da451f6e80 Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Thu, 30 Aug 2018 12:32:00 +0300 Subject: [PATCH 4/8] Fix crash with wrong parameters ENgetbasedemand, ENsetbasedemand, ENgetdemandpattern, ENsetdemandpattern --- src/epanet.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 18c6540..5a90a4a 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -4468,7 +4468,7 @@ int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDeman int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { Pdemand d; - int n = 1; + int n = 1, numDemands; EN_Project *p = (EN_Project*)ph; @@ -4478,10 +4478,10 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return set_error(p->error_handle, 203); if (nodeIndex <= p->network.Njuncs) { - for (d = p->network.Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) { - n++; - } - if (n != demandIdx) { + for (d = p->network.Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) + n++; + EN_getnumdemands(ph, nodeIndex, &numDemands); + if (n < demandIdx || demandIdx <= 0 || n > numDemands) { return set_error(p->error_handle, 253); } *baseDemand = (EN_API_FLOAT_TYPE)(d->Base * p->Ucf[FLOW]); @@ -4504,7 +4504,8 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx double *Ucf = pr->Ucf; Pdemand d; - int n = 1; + int n = 1, numDemands; + /* Check for valid arguments */ if (!pr->Openflag) return set_error(pr->error_handle, 102); @@ -4513,8 +4514,10 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx if (nodeIndex <= Njuncs) { for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; - if (n != demandIdx) + EN_getnumdemands(ph, nodeIndex, &numDemands); + if (n < demandIdx || demandIdx <= 0 || n > numDemands) { return set_error(pr->error_handle, 253); + } d->Base = baseDemand / Ucf[FLOW]; } return set_error(pr->error_handle, 0); @@ -4532,7 +4535,8 @@ int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int deman const int Npats = net->Npats; Pdemand d; - int n = 1; + int n = 1, numDemands; + /* Check for valid arguments */ if (!pr->Openflag) return set_error(pr->error_handle, 102); @@ -4543,8 +4547,10 @@ int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int deman if (nodeIndex <= Njuncs) { for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; - if (n != demandIdx) + EN_getnumdemands(ph, nodeIndex, &numDemands); + if (n < demandIdx || demandIdx <= 0 || n > numDemands) { return set_error(pr->error_handle, 253); + } d->Pat = patIndex; } return set_error(pr->error_handle, 0); @@ -4559,7 +4565,8 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand const int Nnodes = net->Nnodes; Pdemand d; - int n = 1; + int n = 1, numDemands; + /* Check for valid arguments */ if (!p->Openflag) return set_error(p->error_handle, 102); @@ -4567,7 +4574,8 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand return set_error(p->error_handle, 203); for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; - if (n != demandIdx) + EN_getnumdemands(ph, nodeIndex, &numDemands); + if (n < demandIdx || demandIdx <= 0 || n > numDemands) return set_error(p->error_handle, 253); *pattIdx = d->Pat; return set_error(p->error_handle, 0); From 803f86959d38619324b1f672cfd5d49ace66c826 Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Thu, 30 Aug 2018 12:45:21 +0300 Subject: [PATCH 5/8] Revert "Fix crash with wrong parameters" This reverts commit c0b91fa9e32ec989faca8c2fe0cd65da451f6e80. --- src/epanet.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 5a90a4a..18c6540 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -4468,7 +4468,7 @@ int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDeman int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { Pdemand d; - int n = 1, numDemands; + int n = 1; EN_Project *p = (EN_Project*)ph; @@ -4478,10 +4478,10 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return set_error(p->error_handle, 203); if (nodeIndex <= p->network.Njuncs) { - for (d = p->network.Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) - n++; - EN_getnumdemands(ph, nodeIndex, &numDemands); - if (n < demandIdx || demandIdx <= 0 || n > numDemands) { + for (d = p->network.Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) { + n++; + } + if (n != demandIdx) { return set_error(p->error_handle, 253); } *baseDemand = (EN_API_FLOAT_TYPE)(d->Base * p->Ucf[FLOW]); @@ -4504,8 +4504,7 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx double *Ucf = pr->Ucf; Pdemand d; - int n = 1, numDemands; - + int n = 1; /* Check for valid arguments */ if (!pr->Openflag) return set_error(pr->error_handle, 102); @@ -4514,10 +4513,8 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx if (nodeIndex <= Njuncs) { for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; - EN_getnumdemands(ph, nodeIndex, &numDemands); - if (n < demandIdx || demandIdx <= 0 || n > numDemands) { + if (n != demandIdx) return set_error(pr->error_handle, 253); - } d->Base = baseDemand / Ucf[FLOW]; } return set_error(pr->error_handle, 0); @@ -4535,8 +4532,7 @@ int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int deman const int Npats = net->Npats; Pdemand d; - int n = 1, numDemands; - + int n = 1; /* Check for valid arguments */ if (!pr->Openflag) return set_error(pr->error_handle, 102); @@ -4547,10 +4543,8 @@ int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int deman if (nodeIndex <= Njuncs) { for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; - EN_getnumdemands(ph, nodeIndex, &numDemands); - if (n < demandIdx || demandIdx <= 0 || n > numDemands) { + if (n != demandIdx) return set_error(pr->error_handle, 253); - } d->Pat = patIndex; } return set_error(pr->error_handle, 0); @@ -4565,8 +4559,7 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand const int Nnodes = net->Nnodes; Pdemand d; - int n = 1, numDemands; - + int n = 1; /* Check for valid arguments */ if (!p->Openflag) return set_error(p->error_handle, 102); @@ -4574,8 +4567,7 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand return set_error(p->error_handle, 203); for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; - EN_getnumdemands(ph, nodeIndex, &numDemands); - if (n < demandIdx || demandIdx <= 0 || n > numDemands) + if (n != demandIdx) return set_error(p->error_handle, 253); *pattIdx = d->Pat; return set_error(p->error_handle, 0); From d41f362ab523e2ff85bae55ee825c48714353c2b Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Thu, 30 Aug 2018 12:52:23 +0300 Subject: [PATCH 6/8] Fix crash with wrong parameters ENgetbasedemand, ENsetbasedemand, ENgetdemandpattern, ENsetdemandpattern Co-Authored-By: Elad Salomons --- src/epanet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 18c6540..63d1524 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -4478,7 +4478,7 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return set_error(p->error_handle, 203); if (nodeIndex <= p->network.Njuncs) { - for (d = p->network.Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) { + for (d = p->network.Node[nodeIndex].D; n < demandIdx && d->next != NULL; d = d->next) { n++; } if (n != demandIdx) { @@ -4511,7 +4511,7 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx if (nodeIndex <= 0 || nodeIndex > Nnodes) return set_error(pr->error_handle, 203); if (nodeIndex <= Njuncs) { - for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) + for (d = Node[nodeIndex].D; n < demandIdx && d->next != NULL; d = d->next) n++; if (n != demandIdx) return set_error(pr->error_handle, 253); @@ -4541,7 +4541,7 @@ int DLLEXPORT EN_setdemandpattern(EN_ProjectHandle ph, int nodeIndex, int deman if (patIndex < 1 || patIndex > Npats) return(205); if (nodeIndex <= Njuncs) { - for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) + for (d = Node[nodeIndex].D; n < demandIdx && d->next != NULL; d = d->next) n++; if (n != demandIdx) return set_error(pr->error_handle, 253); @@ -4565,7 +4565,7 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand return set_error(p->error_handle, 102); if (nodeIndex <= 0 || nodeIndex > Nnodes) return set_error(p->error_handle, 203); - for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) + for (d = Node[nodeIndex].D; n < demandIdx && d->next != NULL; d = d->next) n++; if (n != demandIdx) return set_error(p->error_handle, 253); From 8991d6baf9c82817cb108f719d40649350d401a6 Mon Sep 17 00:00:00 2001 From: Marios Kyriakou Date: Thu, 30 Aug 2018 17:21:02 +0300 Subject: [PATCH 7/8] add test for the function EN_setdemandpattern --- tests/test_toolkit.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index 6ca6322..a0e0bdb 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -204,4 +204,38 @@ BOOST_FIXTURE_TEST_CASE(test_progressive_stepping, Fixture) } +BOOST_FIXTURE_TEST_CASE(test_setdemandpattern, Fixture) +{ + int i, j, pat_index, pat_index_2, numDemands, nnodes; + char newpat[] = "new_pattern"; + + // get the number of nodes + error = EN_getcount(ph, EN_NODECOUNT, &nnodes); + BOOST_REQUIRE(error == 0); + + // add a new pattern + error = EN_addpattern(ph, newpat); + BOOST_REQUIRE(error == 0); + + // get the new patterns index, should be as the number of patterns + error = EN_getpatternindex(ph, newpat, &pat_index); + BOOST_REQUIRE(error == 0); + + for (i = 1; i <= nnodes; i++) { + // get the number of demand categories + error = EN_getnumdemands(ph, i, &numDemands); + BOOST_REQUIRE(error == 0); + + for (j = 1; j <= numDemands; j++) { + // set demand patterns + error = EN_setdemandpattern(ph, i, j, pat_index); + BOOST_REQUIRE(error == 0); + // get demand patterns should be the same with set + error = EN_getdemandpattern(ph, i, j, &pat_index_2); + BOOST_REQUIRE(error == 0); + BOOST_REQUIRE(pat_index == pat_index_2); + } + } +} + BOOST_AUTO_TEST_SUITE_END() From 74d68a884c278bd19f488e24a3349e1c98c1db5d Mon Sep 17 00:00:00 2001 From: Elad Salomons Date: Thu, 30 Aug 2018 18:05:39 +0300 Subject: [PATCH 8/8] Fix typo --- tests/test_toolkit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index 7b87674..f514a26 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -236,7 +236,7 @@ BOOST_FIXTURE_TEST_CASE(test_setdemandpattern, Fixture) BOOST_REQUIRE(pat_index == pat_index_2); } } - +} BOOST_FIXTURE_TEST_CASE(test_addpattern, Fixture) { int pat_index, n_patterns_1, n_patterns_2;