Merge pull request #580 from OpenWaterAnalytics/dev_2.3
Network building enhancements
This commit is contained in:
11
ReleaseNotes2_3.md
Normal file
11
ReleaseNotes2_3.md
Normal 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`.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
84
src/epanet.c
84
src/epanet.c
@@ -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)
|
||||
/*----------------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
59
src/input2.c
59
src/input2.c
@@ -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[])
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -920,8 +948,8 @@ void adjustpattern(int *pat, int index)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
if (*pat == index) *pat = 0;
|
||||
else if (*pat > index) (*pat)--;
|
||||
if (*pat == index) *pat = 0;
|
||||
else if (*pat > index) (*pat)--;
|
||||
}
|
||||
|
||||
void adjustpatterns(Network *network, int index)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user