Merge pull request #580 from OpenWaterAnalytics/dev_2.3

Network building enhancements
This commit is contained in:
Lew Rossman
2020-07-15 15:15:23 -04:00
committed by GitHub
23 changed files with 205 additions and 115 deletions

11
ReleaseNotes2_3.md Normal file
View File

@@ -0,0 +1,11 @@
>
## Release Notes for EPANET 2.3
This document describes the changes and updates that have been made in version 2.3 of EPANET.
- The check for at least two nodes, one tank/reservoir and no unconnected junction nodes was moved from `EN_open` to `EN_openH` and `EN_openQ` so that partial network data files could be opened by the toolkit.
- A `EN_setcurvetype` function was added to allow API clients to set a curve's type (e.g., `EN_PUMP_CURVE,` `EN_VOLUME_CURVE,` etc.).
- A `EN_setvertex` function was added to allow API clients to change the coordinates of a single link vertex.
- The index of a General Purpose Valve's (GPV's) head loss curve was added to the list of editable Link Properties using the symbolic constant name `EN_GPV_CURVE`.
- The `EN_getlinkvalue` and `EN_setlinkvalue` functions were updated to get and set the value of `EN_GPV_CURVE`.

View File

@@ -197,6 +197,7 @@ These are the toolkit's enumerated types whose members are used as function argu
@fn int EN_setheadcurveindex(EN_Project ph, int pumpIndex, int curveIndex)
@fn int EN_getvertexcount(EN_Project ph, int index, int *count)
@fn int EN_getvertex(EN_Project ph, int index, int vertex, double *x, double *y)
@fn int EN_setvertex(EN_Project ph, int index, int vertex, double x, double y)
@fn int EN_setvertices(EN_Project ph, int index, double *x, double *y, int count)
@}
*/
@@ -227,6 +228,7 @@ These are the toolkit's enumerated types whose members are used as function argu
@fn int EN_setcurveid(EN_Project ph, int index, char *id)
@fn int EN_getcurvelen(EN_Project ph, int index, int *len)
@fn int EN_getcurvetype(EN_Project ph, int index, int *type)
@fn int EN_setcurvetype(EN_Project ph, int index, int type)
@fn int EN_getcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double *x, double *y)
@fn int EN_setcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double x, double y)
@fn int EN_getcurve(EN_Project ph, int curveIndex, char* id, int *nPoints, double **xValues, double **yValues)

View File

@@ -5,7 +5,7 @@ Attribute VB_Name = "Module1"
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL)
'Last updated on 11/04/2019
'Last updated on 02/01/2020
' These are codes used by the DLL functions
Public Const EN_ELEVATION = 0 ' Node parameters
@@ -62,6 +62,7 @@ Public Const EN_PUMP_ECURVE = 20
Public Const EN_PUMP_ECOST = 21
Public Const EN_PUMP_EPAT = 22
Public Const EN_LINK_INCONTROL = 23
Public Const EN_GPV_CURVE = 24
Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1
@@ -350,6 +351,7 @@ Public Const EN_MISSING As Double = -1.0E10
Declare Function ENsetpipedata Lib "epanet2.dll" (ByVal index As Long, ByVal length As Single, ByVal diam As Single, ByVal rough As Single, ByVal mloss As Single) As Long
Declare Function ENgetvertexcount Lib "epanet2.dll" (ByVal index As Long, count As Long) As Long
Declare Function ENgetvertex Lib "epanet2.dll" (ByVal index As Long, ByVal vertex As Long, x As Double, y As Double) As Long
Declare Function ENsetvertex Lib "epanet2.dll" (ByVal index As Long, ByVal vertex As Long, ByVal x As Double, ByVal y As Double) As Long
Declare Function ENsetvertices Lib "epanet2.dll" (ByVal index As Long, xCoords As Any, yCoords As Any, ByVal count As Long) As Long
'Pump Functions
@@ -377,6 +379,7 @@ Public Const EN_MISSING As Double = -1.0E10
Declare Function ENsetcurveid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Long, len_ As Long) As Long
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal index As Long, type_ As Long) As Long
Declare Function ENsetcurvetype Lib "epanet2.dll" (ByVal index As Long, ByVal type_ As Long) As Long
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal pointIndex As Long, x As Single, y As Single) As Long
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal pointIndex As Long, ByVal x As Single, ByVal y As Single) As Long
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal index As Long, ByVal id As String, nPoints As Long, xValues As Any, yValues As Any) As Long

View File

@@ -92,6 +92,7 @@ EXPORTS
ENsetcoord = _ENsetcoord@20
ENsetcurve = _ENsetcurve@16
ENsetcurveid = _ENsetcurveid@8
ENsetcurvetype = _ENsetcurvetype@8
ENsetcurvevalue = _ENsetcurvevalue@16
ENsetdemandmodel = _ENsetdemandmodel@16
ENsetdemandname = _ENsetdemandname@12
@@ -123,6 +124,7 @@ EXPORTS
ENsetthenaction = _ENsetthenaction@20
ENsettimeparam = _ENsettimeparam@8
ENsettitle = _ENsettitle@12
ENsetvertex = _ENsetvertex@24
ENsetvertices = _ENsetvertices@16
ENsolveH = _ENsolveH@0
ENsolveQ = _ENsolveQ@0

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/29/2019
Last Updated: 02/01/2020
******************************************************************************
*/
@@ -290,6 +290,8 @@ extern "C" {
int DLLEXPORT ENgetvertex(int index, int vertex, double *x, double *y);
int DLLEXPORT ENsetvertex(int index, int vertex, double x, double y);
int DLLEXPORT ENsetvertices(int index, double *x, double *y, int count);
/********************************************************************
@@ -350,6 +352,8 @@ extern "C" {
int DLLEXPORT ENgetcurvetype(int index, int *type);
int DLLEXPORT ENsetcurvetype(int index, int type);
int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex,
EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y);

View File

@@ -3,7 +3,7 @@ unit epanet2;
{ Declarations of imported procedures from the EPANET PROGRAMMERs TOOLKIT }
{ (EPANET2.DLL) }
{Last updated on 11/12/19}
{Last updated on 02/01/2020}
interface
@@ -68,6 +68,7 @@ const
EN_PUMP_ECOST = 21;
EN_PUMP_EPAT = 22;
EN_LINK_INCONTROL = 23;
EN_GPV_CURVE = 24;
EN_DURATION = 0; { Time parameters }
EN_HYDSTEP = 1;
@@ -255,7 +256,11 @@ const
EN_R_IS_CLOSED = 2;
EN_R_IS_ACTIVE = 3;
{$ifdef WINDOWS}
EpanetLib = 'epanet2.dll';
{$else}
EpanetLib = 'libepanet2.so';
{$endif}
{Project Functions}
function ENepanet(F1: PAnsiChar; F2: PAnsiChar; F3: PAnsiChar; F4: Pointer): Integer; stdcall; external EpanetLib;
@@ -274,8 +279,8 @@ const
function ENsaveH: Integer; stdcall; external EpanetLib;
function ENopenH: Integer; stdcall; external EpanetLib;
function ENinitH(SaveFlag: Integer): Integer; stdcall; external EpanetLib;
function ENrunH(var T: LongInt): Integer; stdcall; external EpanetLib;
function ENnextH(var Tstep: LongInt): Integer; stdcall; external EpanetLib;
function ENrunH(var T: Integer): Integer; stdcall; external EpanetLib;
function ENnextH(var Tstep: Integer): Integer; stdcall; external EpanetLib;
function ENcloseH: Integer; stdcall; external EpanetLib;
function ENsavehydfile(F: PAnsiChar): Integer; stdcall; external EpanetLib;
function ENusehydfile(F: PAnsiChar): Integer; stdcall; external EpanetLib;
@@ -284,9 +289,9 @@ const
function ENsolveQ: Integer; stdcall; external EpanetLib;
function ENopenQ: Integer; stdcall; external EpanetLib;
function ENinitQ(SaveFlag: Integer): Integer; stdcall; external EpanetLib;
function ENrunQ(var T: LongInt): Integer; stdcall; external EpanetLib;
function ENnextQ(var Tstep: LongInt): Integer; stdcall; external EpanetLib;
function ENstepQ(var Tleft: LongInt): Integer; stdcall; external EpanetLib;
function ENrunQ(var T: Integer): Integer; stdcall; external EpanetLib;
function ENnextQ(var Tstep: Integer): Integer; stdcall; external EpanetLib;
function ENstepQ(var Tleft: Integer): Integer; stdcall; external EpanetLib;
function ENcloseQ: Integer; stdcall; external EpanetLib;
{Reporting Functions}
@@ -307,8 +312,8 @@ const
function ENsetoption(Code: Integer; Value: Single): Integer; stdcall; external EpanetLib;
function ENgetflowunits(var Code: Integer): Integer; stdcall; external EpanetLib;
function ENsetflowunits(Code: Integer): Integer; stdcall; external EpanetLib;
function ENgettimeparam(Code: Integer; var Value: LongInt): Integer; stdcall; external EpanetLib;
function ENsettimeparam(Code: Integer; Value: LongInt): Integer; stdcall; external EpanetLib;
function ENgettimeparam(Code: Integer; var Value: Integer): Integer; stdcall; external EpanetLib;
function ENsettimeparam(Code: Integer; Value: Integer): Integer; stdcall; external EpanetLib;
function ENgetqualinfo(var QualType: Integer; ChemName: PAnsiChar; ChemUnits: PAnsiChar; var TraceNode: Integer): Integer; stdcall; external EpanetLib;
function ENgetqualtype(var QualCode: Integer; var TraceNode: Integer): Integer; stdcall; external EpanetLib;
function ENsetqualtype(QualCode: Integer; ChemName: PAnsiChar; ChemUnits: PAnsiChar; TraceNodeID: PAnsiChar): Integer; stdcall; external EpanetLib;
@@ -357,6 +362,7 @@ const
function ENgetvertexcount(Index: Integer; var Count: Integer): Integer; stdcall; external EpanetLib;
function ENgetvertex(Index: Integer; Vertex: Integer; var X: Double; var Y: Double): Integer; stdcall; external EpanetLib;
function ENsetvertex(Index: Integer; Vertex: Integer; X: Double; Y: Double): Integer; stdcall; external EpanetLib;
function ENsetvertices(Index: Integer; var X: Double; var Y: Double; Count: Integer): Integer; stdcall; external EpanetLib;
{Pump Functions}
@@ -384,6 +390,7 @@ const
function ENsetcurveid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
function ENgetcurvelen(Index: Integer; var Len: Integer): Integer; stdcall; external EpanetLib;
function ENgetcurvetype(Index: Integer; var CurveType: Integer): Integer; stdcall; external EpanetLib;
function ENsetcurvetype(Index: Integer; CurveType: Integer): Integer; stdcall; external EpanetLib;
function ENgetcurvevalue(CurveIndex: Integer; PointIndex: Integer; var X: Single; var Y: Single): Integer; stdcall; external EpanetLib;
function ENsetcurvevalue(CurveIndex: Integer; PointIndex: Integer; X: Single; Y: Single): Integer; stdcall; external EpanetLib;
function ENgetcurve(Index: Integer; ID: PAnsiChar; var N: Integer; var X: Single; var Y: Single): Integer; stdcall; external EpanetLib;

View File

@@ -4,7 +4,7 @@
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
'(EPANET2.DLL) for use with VB.Net.
'Last updated on 11/04/2019
'Last updated on 02/01/2020
Imports System.Runtime.InteropServices
Imports System.Text
@@ -66,6 +66,7 @@ Public Const EN_PUMP_ECURVE = 20
Public Const EN_PUMP_ECOST = 21
Public Const EN_PUMP_EPAT = 22
Public Const EN_LINK_INCONTROL = 23
Public Const EN_GPV_CURVE = 24
Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1
@@ -344,6 +345,7 @@ Public Const EN_MISSING As Double = -1.0E10
Declare Function ENsetpipedata Lib "epanet2.dll" (ByVal index As Int32, ByVal length As Single, ByVal diam As Single, ByVal rough As Single, ByVal mloss As Single) As Int32
Declare Function ENgetvertexcount Lib "epanet2.dll" (ByVal index As Int32, count As Int32) As Int32
Declare Function ENgetvertex Lib "epanet2.dll" (ByVal index As Int32, ByVal vertex As Int32, x As Double, y As Double) As Int32
Declare Function ENsetvertex Lib "epanet2.dll" (ByVal index As Int32, ByVal vertex As Int32, ByVal x As Double, ByVal y As Double) As Int32
Declare Function ENsetvertices Lib "epanet2.dll" (ByVal index As Int32, xCoords As Any, yCoords As Any, ByVal count As Int32) As Int32
'Pump Functions
@@ -371,6 +373,7 @@ Public Const EN_MISSING As Double = -1.0E10
Declare Function ENsetcurveid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Int32, len_ As Int32) As Int32
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal index As Int32, type_ As Int32) As Int32
Declare Function ENsetcurvetype Lib "epanet2.dll" (ByVal index As Int32, ByVal type_ As Int32) As Int32
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Int32, ByVal pointIndex As Int32, x As Single, y As Single) As Int32
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Int32, ByVal pointIndex As Int32, ByVal x As Single, ByVal y As Single) As Int32
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String, nPoints As Int32, xValues As Any, yValues As Any) As Int32

View File

@@ -11,7 +11,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/29/2019
Last Updated: 02/01/2020
******************************************************************************
*/
@@ -1238,7 +1238,7 @@ typedef struct Project *EN_Project;
int DLLEXPORT EN_getvertexcount(EN_Project ph, int index, int *count);
/**
@brief Retrieves the coordinate's of a vertex point assigned to a link.
@brief Retrieves the coordinates of a vertex point assigned to a link.
@param ph an EPANET project handle.
@param index a link's index (starting from 1).
@param vertex a vertex point index (starting from 1).
@@ -1248,6 +1248,17 @@ typedef struct Project *EN_Project;
*/
int DLLEXPORT EN_getvertex(EN_Project ph, int index, int vertex, double *x, double *y);
/**
@brief Sets the coordinates of a vertex point assigned to a link.
@param ph an EPANET project handle.
@param index a link's index (starting from 1).
@param vertex a vertex point index (starting from 1).
@param x the vertex's X-coordinate value.
@param y the vertex's Y-coordinate value.
@return an error code.
*/
int DLLEXPORT EN_setvertex(EN_Project ph, int index, int vertex, double x, double y);
/**
@brief Assigns a set of internal vertex points to a link.
@param ph an EPANET project handle.
@@ -1475,6 +1486,15 @@ typedef struct Project *EN_Project;
*/
int DLLEXPORT EN_getcurvetype(EN_Project ph, int index, int *type);
/**
@brief Sets a curve's type.
@param ph an EPANET project handle.
@param index a curve's index (starting from 1).
@param type the curve's type (see @ref EN_CurveType).
@return an error code.
*/
int DLLEXPORT EN_setcurvetype(EN_Project ph, int index, int type);
/**
@brief Retrieves the value of a single data point for a curve.
@param ph an EPANET project handle.

View File

@@ -9,7 +9,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/06/2019
Last Updated: 02/01/2020
******************************************************************************
*/
@@ -96,7 +96,8 @@ typedef enum {
EN_PUMP_ECURVE = 20, //!< Pump efficiency v. flow curve index
EN_PUMP_ECOST = 21, //!< Pump average energy price
EN_PUMP_EPAT = 22, //!< Pump energy price time pattern index
EN_LINK_INCONTROL = 23 //!< Is present in any simple or rule-based control (= 1) or not (= 0)
EN_LINK_INCONTROL = 23, //!< Is present in any simple or rule-based control (= 1) or not (= 0)
EN_GPV_CURVE = 24 //!< GPV head loss v. flow curve index
} EN_LinkProperty;
/// Time parameters

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/15/2019
Last Updated: 02/01/2020
******************************************************************************
*/
@@ -1847,7 +1847,7 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType, int *index)
tank->Pat = 0;
tank->Vcurve = 0;
tank->MixModel = 0;
tank->V1max = 10000;
tank->V1frac = 1;
tank->CanOverflow = FALSE;
}
net->Nnodes++;
@@ -2164,7 +2164,9 @@ int DLLEXPORT EN_getnodevalue(EN_Project p, int index, int property, double *val
case EN_MIXZONEVOL:
v = 0.0;
if (index > nJuncs) v = Tank[index - nJuncs].V1max * Ucf[VOLUME];
if (index > nJuncs)
v = Tank[index - nJuncs].V1frac * Tank[index - nJuncs].Vmax *
Ucf[VOLUME];
break;
case EN_DEMAND:
@@ -2224,9 +2226,9 @@ int DLLEXPORT EN_getnodevalue(EN_Project p, int index, int property, double *val
case EN_MIXFRACTION:
v = 1.0;
if (index > nJuncs && Tank[index - nJuncs].Vmax > 0.0)
if (index > nJuncs)
{
v = Tank[index - nJuncs].V1max / Tank[index - nJuncs].Vmax;
v = Tank[index - nJuncs].V1frac;
}
break;
@@ -2293,7 +2295,6 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
int i, j, n;
Psource source;
double hTmp;
double vTmp;
if (!p->Openflag) return 102;
if (index <= 0 || index > nNodes) return 203;
@@ -2418,9 +2419,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
// shape below Hmin. Vmin can always be changed by setting
// EN_MINVOLUME in a subsequent function call.
Tank[j].V0 = tankvolume(p, j, Tank[j].H0); // new init. volume
vTmp = Tank[j].Vmax; // old max. volume
Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); // new max. volume
Tank[j].V1max *= Tank[j].Vmax / vTmp; // new mix zone volume
break;
case EN_MINVOLUME:
@@ -2450,9 +2449,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
// Since Vmin changes the other volumes need updating
Tank[j].V0 = tankvolume(p, j, Tank[j].H0); // new init. volume
vTmp = Tank[j].Vmax; // old max. volume
Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); // new max. volume
Tank[j].V1max *= Tank[j].Vmax / vTmp; // new mix zone volume
}
break;
@@ -2477,9 +2474,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
Tank[j].Vcurve = i; // assign curve to tank
Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); // new min. volume
Tank[j].V0 = tankvolume(p, j, Tank[j].H0); // new init. volume
vTmp = Tank[j].Vmax; // old max. volume
Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); // new max. volume
Tank[j].V1max *= Tank[j].Vmax / vTmp; // new mix zone volume
Tank[j].A = (curve->Y[n] - curve->Y[0]) / // nominal area
(curve->X[n] - curve->X[0]);
break;
@@ -2521,9 +2516,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
if (value > curve->X[n]) return 225; // new level is off curve
}
Tank[j].Hmax = hTmp; // new max. head
vTmp = Tank[j].Vmax; // old max. volume
Tank[j].Vmax = tankvolume(p, j, hTmp); // new max. volume
Tank[j].V1max *= Tank[j].Vmax / vTmp; // new mix zone volume
break;
case EN_MIXMODEL:
@@ -2542,7 +2535,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
j = index - nJuncs;
if (Tank[j].A > 0.0)
{
Tank[j].V1max = value * Tank[j].Vmax;
Tank[j].V1frac = value;
}
break;
@@ -3791,6 +3784,13 @@ int DLLEXPORT EN_getlinkvalue(EN_Project p, int index, int property, double *val
}
break;
case EN_GPV_CURVE:
if (Link[index].Type == GPV)
{
v = Link[index].Kc;
}
break;
case EN_LINK_INCONTROL:
v = (double)incontrols(p, LINK, index);
break;
@@ -4002,6 +4002,14 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
}
break;
case EN_GPV_CURVE:
if (Link[index].Type == GPV)
{
curveIndex = ROUND(value);
if (curveIndex < 0 || curveIndex > net->Ncurves) return 206;
Link[index].Kc = curveIndex;
}
default:
return 251;
}
@@ -4105,6 +4113,35 @@ int DLLEXPORT EN_getvertex(EN_Project p, int index, int vertex, double *x, doubl
return 0;
}
int DLLEXPORT EN_setvertex(EN_Project p, int index, int vertex, double x, double y)
/*----------------------------------------------------------------
** Input: index = link index
** vertex = index of a link vertex point
** x = vertex point's X-coordinate
** y = vertex point's Y-coordinate
** Returns: error code
** Purpose: sets the coordinates of a vertex point in a link
**----------------------------------------------------------------
*/
{
Network *net = &p->network;
Slink *Link = net->Link;
Pvertices vertices;
// Check that link exists
if (!p->Openflag) return 102;
if (index <= 0 || index > net->Nlinks) return 204;
// Check that vertex exists
vertices = Link[index].Vertices;
if (vertices == NULL) return 255;
if (vertex <= 0 || vertex > vertices->Npts) return 255;
vertices->X[vertex - 1] = x;
vertices->Y[vertex - 1] = y;
return 0;
}
int DLLEXPORT EN_setvertices(EN_Project p, int index, double *x, double *y, int count)
/*----------------------------------------------------------------
** Input: index = link index
@@ -4715,6 +4752,23 @@ int DLLEXPORT EN_getcurvetype(EN_Project p, int index, int *type)
return 0;
}
int DLLEXPORT EN_setcurvetype(EN_Project p, int index, int type)
/*----------------------------------------------------------------
** Input: index = data curve index
** type = type of data curve (see EN_CurveType)
** Returns: error code
** Purpose: sets the type assigned to a data curve
**----------------------------------------------------------------
*/
{
Network *net = &p->network;
if (!p->Openflag) return 102;
if (index < 1 || index > net->Ncurves) return 206;
if (type < 0 || type > EN_GENERIC_CURVE) return 251;
net->Curve[index].Type = type;
return 0;
}
int DLLEXPORT EN_getcurvevalue(EN_Project p, int curveIndex, int pointIndex,
double *x, double *y)
/*----------------------------------------------------------------

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/02/2019
Last Updated: 02/01/2020
******************************************************************************
*/
@@ -522,6 +522,11 @@ int DLLEXPORT ENgetvertex(int index, int vertex, double *x, double *y)
return EN_getvertex(_defaultProject, index, vertex, x, y);
}
int DLLEXPORT ENsetvertex(int index, int vertex, double x, double y)
{
return EN_setvertex(_defaultProject, index, vertex, x, y);
}
int DLLEXPORT ENsetvertices(int index, double *x, double *y, int count)
{
return EN_setvertices(_defaultProject, index, x, y, count);
@@ -662,6 +667,11 @@ int DLLEXPORT ENgetcurvetype(int index, int *type)
return EN_getcurvetype(_defaultProject, index, type);
}
int DLLEXPORT ENsetcurvetype(int index, int type)
{
return EN_setcurvetype(_defaultProject, index, type);
}
int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y)
{

View File

@@ -43,7 +43,7 @@ DAT(225,"invalid lower/upper levels for tank")
DAT(226,"no head curve or power rating for pump")
DAT(227,"invalid head curve for pump")
DAT(230,"nonincreasing x-values for curve")
DAT(233,"network has unconnected node")
DAT(233,"network has unconnected nodes")
// These errors apply only to API functions
DAT(240,"nonexistent source")

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/15/2019
Last Updated: 02/03/2020
******************************************************************************
*/
#ifndef FUNCS_H
@@ -29,6 +29,8 @@ void freeadjlists(Network *);
int incontrols(Project *, int, int);
int valvecheck(Project *, int, int, int, int);
int unlinked(Project *);
int findnode(Network *, char *);
int findlink(Network *, char *);
int findtank(Network *, int);

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 12/05/2019
Last Updated: 02/03/2020
******************************************************************************
*/
@@ -64,14 +64,7 @@ int openhyd(Project *pr)
ERRCODE(allocmatrix(pr));
// Check for unconnected nodes
if (!errcode) for (i = 1; i <= pr->network.Njuncs; i++)
{
if (pr->network.Adjlist[i] == NULL)
{
errcode = 233;
break;
}
}
ERRCODE(unlinked(pr));
// Initialize link flows
if (!errcode) for (i = 1; i <= pr->network.Nlinks; i++)

View File

@@ -523,7 +523,7 @@ int saveinpfile(Project *pr, const char *fname)
tank = &net->Tank[i];
if (tank->A == 0.0) continue;
fprintf(f, "\n %-31s %-8s %12.4f", net->Node[tank->Node].ID,
MixTxt[tank->MixModel], (tank->V1max / tank->Vmax));
MixTxt[tank->MixModel], tank->V1frac);
}
// Write [REACTIONS] section

View File

@@ -588,7 +588,6 @@ void convertunits(Project *pr)
tank->Kb /= SECperDAY;
tank->V = tank->V0;
tank->C = node->C0;
tank->V1max *= tank->Vmax;
}
// Convert hydraulic convergence criteria

View File

@@ -7,7 +7,7 @@ Description: reads and interprets network data from an EPANET input file
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/29/2019
Last Updated: 02/03/2020
******************************************************************************
*/
@@ -37,7 +37,6 @@ extern int powercurve(double, double, double, double, double, double *,
static int newline(Project *, int, char *);
static int addpattern(Network *, char *);
static int addcurve(Network *, char *);
static int unlinked(Project *);
static int getpumpparams(Project *);
static void inperrmsg(Project *, int, int, char *);
@@ -130,11 +129,6 @@ int netsize(Project *pr)
parser->MaxNodes = parser->MaxJuncs + parser->MaxTanks;
parser->MaxLinks = parser->MaxPipes + parser->MaxPumps + parser->MaxValves;
if (parser->MaxPats < 1) parser->MaxPats = 1;
if (!errcode)
{
if (parser->MaxJuncs < 1) errcode = 223; // Not enough nodes
else if (parser->MaxTanks == 0) errcode = 224; // No tanks
}
return errcode;
}
@@ -263,9 +257,6 @@ int readdata(Project *pr)
// Check for errors
if (errsum > 0) errcode = 200;
// Check for unlinked nodes
if (!errcode) errcode = unlinked(pr);
// Determine pump curve parameters
if (!errcode) errcode = getpumpparams(pr);
@@ -572,54 +563,6 @@ int addcurve(Network *network, char *id)
return 0;
}
int unlinked(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code if any unlinked junctions found
** Purpose: checks for unlinked junctions in network
**
** NOTE: unlinked tanks have no effect on computations.
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
int *marked;
int i, err, errcode;
errcode = 0;
err = 0;
// Create an array to record number of links incident on each node
marked = (int *)calloc(net->Nnodes + 1, sizeof(int));
ERRCODE(MEMCHECK(marked));
if (errcode) return errcode;
memset(marked, 0, (net->Nnodes + 1) * sizeof(int));
// Mark end nodes of each link
for (i = 1; i <= net->Nlinks; i++)
{
marked[net->Link[i].N1]++;
marked[net->Link[i].N2]++;
}
// Check each junction
for (i = 1; i <= net->Njuncs; i++)
{
// If not marked then error
if (marked[i] == 0)
{
err++;
sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID);
writeline(pr, pr->Msg);
}
if (err >= MAXERRS) break;
}
if (err > 0) errcode = 200;
free(marked);
return errcode;
}
int findmatch(char *line, char *keyword[])
/*
**--------------------------------------------------------------

View File

@@ -252,7 +252,7 @@ int tankdata(Project *pr)
tank->Vcurve = curve;
tank->MixModel = MIX1; // Completely mixed
tank->V1max = 1.0; // Mixing compartment size fraction
tank->V1frac = 1.0; // Mixing compartment size fraction
return 0;
}
@@ -1288,7 +1288,7 @@ int mixingdata(Project *pr)
i = j - net->Njuncs;
if (net->Tank[i].A == 0.0) return 0;
net->Tank[i].MixModel = (char)m;
net->Tank[i].V1max = v;
net->Tank[i].V1frac = v;
return 0;
}

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/15/2019
Last Updated: 02/03/2020
******************************************************************************
*/
@@ -803,6 +803,34 @@ int valvecheck(Project *pr, int index, int type, int j1, int j2)
return 0;
}
int unlinked(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code if any unlinked junctions found
** Purpose: checks for unlinked junctions in network
**
** NOTE: unlinked tanks have no effect on computations.
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
int i, count = 0;
for (i = 1; i <= net->Njuncs; i++)
{
if (pr->network.Adjlist[i] == NULL)
{
count++;
sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID);
writeline(pr, pr->Msg);
}
if (count >= 10) break;
}
if (count > 0) return 233;
return 0;
}
int findnode(Network *network, char *id)
/*----------------------------------------------------------------
** Input: id = node ID

View File

@@ -7,7 +7,7 @@ Description: implements EPANET's water quality engine
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 05/15/2019
Last Updated: 02/03/2020
******************************************************************************
*/
@@ -63,8 +63,16 @@ int openqual(Project *pr)
// Build nodal adjacency lists if they don't already exist
if (net->Adjlist == NULL)
{
// Check for too few nodes & no fixed grade nodes
if (net->Nnodes < 2) return 223;
if (net->Ntanks == 0) return 224;
// Build adjacency lists
errcode = buildadjlists(net);
if (errcode ) return errcode;
// Check for unconnected nodes
if (errcode = unlinked(pr)) return errcode;
}
// Create a memory pool for water quality segments

View File

@@ -525,7 +525,7 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)
if (mixzone == NULL || stagzone == NULL) return;
// Full mixing zone volume
vmz = tank->V1max;
vmz = tank->V1frac * tank->Vmax;
// Tank is filling
vt = 0.0;

View File

@@ -612,7 +612,7 @@ void initsegs(Project *pr)
if (net->Tank[j].MixModel == MIX2)
{
// ... mixing zone segment
v1 = MAX(0, v - net->Tank[j].V1max);
v1 = MAX(0, v - net->Tank[j].V1frac * net->Tank[j].Vmax);
qual->FirstSeg[k]->v = v1;
// ... stagnant zone segment

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/29/2019
Last Updated: 07/11/2020
******************************************************************************
*/
@@ -428,7 +428,7 @@ typedef struct // Tank Object
int Pat; // fixed grade time pattern
int Vcurve; // volume v. elev. curve index
MixType MixModel; // type of mixing model
double V1max; // mixing compartment size
double V1frac; // mixing compartment fraction
int CanOverflow; // tank can overflow or not
} Stank;