Merge branch 'dev' into dev_2.3
This commit is contained in:
@@ -30,4 +30,4 @@ The **Open Water Analytics** (OWA) Community is an international group of EPANET
|
||||
## DISCLAIMER
|
||||
Although OWA is not formally affiliated with nor endorsed by USEPA, this project has been a collaborative effort between the two that builds upon and extends the USEPA’s legacy EPANET 2.0 code base. For the last "official" release of EPANET please go to the [USEPA website](http://www2.epa.gov/water-research/epanet).
|
||||
|
||||
For more general community discussion, FAQ, and roadmapping of the project, please go to the [Community Forum](http://community/wateranalytics.org).
|
||||
For more general community discussion, FAQ, and roadmapping of the project, please go to the [Community Forum](http://community.wateranalytics.org).
|
||||
|
||||
@@ -25,7 +25,6 @@ Public Const EN_SOURCEMASS = 13
|
||||
Public Const EN_INITVOLUME = 14
|
||||
Public Const EN_MIXMODEL = 15
|
||||
Public Const EN_MIXZONEVOL = 16
|
||||
|
||||
Public Const EN_TANKDIAM = 17
|
||||
Public Const EN_MINVOLUME = 18
|
||||
Public Const EN_VOLCURVE = 19
|
||||
@@ -37,6 +36,7 @@ Public Const EN_TANKVOLUME = 24
|
||||
Public Const EN_MAXVOLUME = 25
|
||||
Public Const EN_CANOVERFLOW = 26
|
||||
Public Const EN_DEMANDDEFICIT = 27
|
||||
Public Const EN_NODE_INCONTROL = 28
|
||||
|
||||
Public Const EN_DIAMETER = 0 ' Link parameters
|
||||
Public Const EN_LENGTH = 1
|
||||
@@ -54,7 +54,6 @@ Public Const EN_SETTING = 12
|
||||
Public Const EN_ENERGY = 13
|
||||
Public Const EN_LINKQUAL = 14
|
||||
Public Const EN_LINKPATTERN = 15
|
||||
|
||||
Public Const EN_PUMP_STATE = 16
|
||||
Public Const EN_PUMP_EFFIC = 17
|
||||
Public Const EN_PUMP_POWER = 18
|
||||
@@ -62,7 +61,8 @@ Public Const EN_PUMP_HCURVE = 19
|
||||
Public Const EN_PUMP_ECURVE = 20
|
||||
Public Const EN_PUMP_ECOST = 21
|
||||
Public Const EN_PUMP_EPAT = 22
|
||||
Public Const EN_GPV_CURVE = 23
|
||||
Public Const EN_LINK_INCONTROL = 23
|
||||
Public Const EN_GPV_CURVE = 24
|
||||
|
||||
Public Const EN_DURATION = 0 ' Time parameters
|
||||
Public Const EN_HYDSTEP = 1
|
||||
@@ -79,6 +79,7 @@ Public Const EN_HTIME = 11
|
||||
Public Const EN_QTIME = 12
|
||||
Public Const EN_HALTFLAG = 13
|
||||
Public Const EN_NEXTEVENT = 14
|
||||
Public Const EN_NEXTEVENTTANK = 15
|
||||
|
||||
Public Const EN_ITERATIONS = 0 ' Run statistics
|
||||
Public Const EN_RELATIVEERROR = 1
|
||||
@@ -117,6 +118,14 @@ Public Const EN_FCV = 6
|
||||
Public Const EN_TCV = 7
|
||||
Public Const EN_GPV = 8
|
||||
|
||||
Public Const EN_CLOSED = 0 ' Link status types
|
||||
Public Const EN_OPEN = 1
|
||||
|
||||
Public Const EN_PUMP_XHEAD = 0 ' Pump state types
|
||||
Public Const EN_PUMP_CLOSED = 2
|
||||
Public Const EN_PUMP_OPEN = 3
|
||||
Public Const EN_PUMP_XFLOW = 5
|
||||
|
||||
Public Const EN_NONE = 0 ' Quality analysis types
|
||||
Public Const EN_CHEM = 1
|
||||
Public Const EN_AGE = 2
|
||||
@@ -174,7 +183,8 @@ Public Const EN_HILEVEL = 1
|
||||
Public Const EN_TIMER = 2
|
||||
Public Const EN_TIMEOFDAY = 3
|
||||
|
||||
Public Const EN_AVERAGE = 1 ' Time statistic types
|
||||
Public Const EN_SERIES = 0 ' Time statistic types
|
||||
Public Const EN_AVERAGE = 1
|
||||
Public Const EN_MINIMUM = 2
|
||||
Public Const EN_MAXIMUM = 3
|
||||
Public Const EN_RANGE = 4
|
||||
|
||||
@@ -31,7 +31,6 @@ const
|
||||
EN_INITVOLUME = 14;
|
||||
EN_MIXMODEL = 15;
|
||||
EN_MIXZONEVOL = 16;
|
||||
|
||||
EN_TANKDIAM = 17;
|
||||
EN_MINVOLUME = 18;
|
||||
EN_VOLCURVE = 19;
|
||||
@@ -43,6 +42,7 @@ const
|
||||
EN_MAXVOLUME = 25;
|
||||
EN_CANOVERFLOW = 26;
|
||||
EN_DEMANDDEFICIT = 27;
|
||||
EN_NODE_INCONTROL = 28;
|
||||
|
||||
EN_DIAMETER = 0; { Link parameters }
|
||||
EN_LENGTH = 1;
|
||||
@@ -67,7 +67,8 @@ const
|
||||
EN_PUMP_ECURVE = 20;
|
||||
EN_PUMP_ECOST = 21;
|
||||
EN_PUMP_EPAT = 22;
|
||||
EN_GPV_CURVE = 23;
|
||||
EN_LINK_INCONTROL = 23;
|
||||
EN_GPV_CURVE = 24;
|
||||
|
||||
EN_DURATION = 0; { Time parameters }
|
||||
EN_HYDSTEP = 1;
|
||||
|
||||
@@ -29,7 +29,6 @@ Public Const EN_SOURCEMASS = 13
|
||||
Public Const EN_INITVOLUME = 14
|
||||
Public Const EN_MIXMODEL = 15
|
||||
Public Const EN_MIXZONEVOL = 16
|
||||
|
||||
Public Const EN_TANKDIAM = 17
|
||||
Public Const EN_MINVOLUME = 18
|
||||
Public Const EN_VOLCURVE = 19
|
||||
@@ -37,11 +36,11 @@ Public Const EN_MINLEVEL = 20
|
||||
Public Const EN_MAXLEVEL = 21
|
||||
Public Const EN_MIXFRACTION = 22
|
||||
Public Const EN_TANK_KBULK = 23
|
||||
|
||||
Public Const EN_TANKVOLUME = 24
|
||||
Public Const EN_MAXVOLUME = 25
|
||||
Public Const EN_CANOVERFLOW = 26
|
||||
Public Const EN_DEMANDDEFICIT = 27
|
||||
Public Const EN_NODE_INCONTROL = 28
|
||||
|
||||
Public Const EN_DIAMETER = 0 ' Link parameters
|
||||
Public Const EN_LENGTH = 1
|
||||
@@ -59,7 +58,6 @@ Public Const EN_SETTING = 12
|
||||
Public Const EN_ENERGY = 13
|
||||
Public Const EN_LINKQUAL = 14
|
||||
Public Const EN_LINKPATTERN = 15
|
||||
|
||||
Public Const EN_PUMP_STATE = 16
|
||||
Public Const EN_PUMP_EFFIC = 17
|
||||
Public Const EN_PUMP_POWER = 18
|
||||
@@ -67,7 +65,8 @@ Public Const EN_PUMP_HCURVE = 19
|
||||
Public Const EN_PUMP_ECURVE = 20
|
||||
Public Const EN_PUMP_ECOST = 21
|
||||
Public Const EN_PUMP_EPAT = 22
|
||||
Public Const EN_GPV_CURVE = 23
|
||||
Public Const EN_LINK_INCONTROL = 23
|
||||
Public Const EN_GPV_CURVE = 24
|
||||
|
||||
Public Const EN_DURATION = 0 ' Time parameters
|
||||
Public Const EN_HYDSTEP = 1
|
||||
|
||||
@@ -63,7 +63,8 @@ typedef enum {
|
||||
EN_TANKVOLUME = 24, //!< Current computed tank volume (read only)
|
||||
EN_MAXVOLUME = 25, //!< Tank maximum volume (read only)
|
||||
EN_CANOVERFLOW = 26, //!< Tank can overflow (= 1) or not (= 0)
|
||||
EN_DEMANDDEFICIT = 27 //!< Amount that full demand is reduced under PDA (read only)
|
||||
EN_DEMANDDEFICIT = 27,//!< Amount that full demand is reduced under PDA (read only)
|
||||
EN_NODE_INCONTROL = 28 //!< Is present in any simple or rule-based control (= 1) or not (= 0)
|
||||
} EN_NodeProperty;
|
||||
|
||||
/// Link properties
|
||||
@@ -95,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_GPV_CURVE = 23 //!< GPV head loss v. flow curve index
|
||||
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
|
||||
|
||||
30
src/epanet.c
30
src/epanet.c
@@ -1591,6 +1591,11 @@ int DLLEXPORT EN_settimeparam(EN_Project p, int param, long value)
|
||||
time->Qtime = value;
|
||||
break;
|
||||
|
||||
case EN_STARTTIME:
|
||||
if (value < 0 || value > SECperDAY) return 213;
|
||||
time->Tstart = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 251;
|
||||
}
|
||||
@@ -1772,6 +1777,8 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType, int *index)
|
||||
hyd->NodeDemand = (double *)realloc(hyd->NodeDemand, size);
|
||||
qual->NodeQual = (double *)realloc(qual->NodeQual, size);
|
||||
hyd->NodeHead = (double *)realloc(hyd->NodeHead, size);
|
||||
hyd->DemandFlow = (double *)realloc(hyd->DemandFlow, size);
|
||||
hyd->EmitterFlow = (double *)realloc(hyd->EmitterFlow, size);
|
||||
|
||||
// Actions taken when a new Junction is added
|
||||
if (nodeType == EN_JUNCTION)
|
||||
@@ -2247,6 +2254,10 @@ int DLLEXPORT EN_getnodevalue(EN_Project p, int index, int property, double *val
|
||||
(hyd->NodeDemand[index] - hyd->EmitterFlow[index])) * Ucf[FLOW];
|
||||
break;
|
||||
|
||||
case EN_NODE_INCONTROL:
|
||||
v = (double)incontrols(p, NODE, index);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 251;
|
||||
}
|
||||
@@ -2621,8 +2632,8 @@ int DLLEXPORT EN_settankdata(EN_Project p, int index, double elev,
|
||||
Network *net = &p->network;
|
||||
|
||||
int i, j, n, curveIndex = 0;
|
||||
double area, elevation = elev;
|
||||
double *Ucf = p->Ucf;
|
||||
double area;
|
||||
Stank *Tank = net->Tank;
|
||||
Scurve *curve;
|
||||
|
||||
@@ -2659,11 +2670,11 @@ int DLLEXPORT EN_settankdata(EN_Project p, int index, double elev,
|
||||
else area = PI * diam * diam / 4.0;
|
||||
|
||||
// Assign parameters to tank object
|
||||
net->Node[Tank[j].Node].El = elevation;
|
||||
net->Node[Tank[j].Node].El = elev / Ucf[ELEV];
|
||||
Tank[j].A = area / Ucf[ELEV] / Ucf[ELEV];
|
||||
Tank[j].H0 = elevation + initlvl / Ucf[ELEV];
|
||||
Tank[j].Hmin = elevation + minlvl / Ucf[ELEV];
|
||||
Tank[j].Hmax = elevation + maxlvl / Ucf[ELEV];
|
||||
Tank[j].H0 = (elev + initlvl) / Ucf[ELEV];
|
||||
Tank[j].Hmin = (elev + minlvl) / Ucf[ELEV];
|
||||
Tank[j].Hmax = (elev + maxlvl) / Ucf[ELEV];
|
||||
Tank[j].Vcurve = curveIndex;
|
||||
if (curveIndex == 0)
|
||||
{
|
||||
@@ -3631,7 +3642,8 @@ int DLLEXPORT EN_getlinkvalue(EN_Project p, int index, int property, double *val
|
||||
{
|
||||
return EN_getlinkvalue(p, index, EN_ROUGHNESS, value);
|
||||
}
|
||||
v = Link[index].Kc;
|
||||
if (Link[index].Kc == MISSING) v = 0.0;
|
||||
else v = Link[index].Kc;
|
||||
switch (Link[index].Type)
|
||||
{
|
||||
case PRV:
|
||||
@@ -3785,6 +3797,10 @@ int DLLEXPORT EN_getlinkvalue(EN_Project p, int index, int property, double *val
|
||||
v = Link[index].Kc;
|
||||
}
|
||||
|
||||
case EN_LINK_INCONTROL:
|
||||
v = (double)incontrols(p, LINK, index);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 251;
|
||||
}
|
||||
@@ -3852,7 +3868,7 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
|
||||
case EN_MINORLOSS:
|
||||
if (Link[index].Type != PUMP)
|
||||
{
|
||||
if (value <= 0.0) return 211;
|
||||
if (value < 0.0) return 211;
|
||||
Link[index].Km = 0.02517 * value / SQR(Link[index].Diam) /
|
||||
SQR(Link[index].Diam);
|
||||
}
|
||||
|
||||
@@ -298,16 +298,12 @@ int allocmatrix(Project *pr)
|
||||
|
||||
hyd->P = (double *) calloc(net->Nlinks+1,sizeof(double));
|
||||
hyd->Y = (double *) calloc(net->Nlinks+1,sizeof(double));
|
||||
hyd->DemandFlow = (double *) calloc(net->Nnodes + 1, sizeof(double));
|
||||
hyd->EmitterFlow = (double *) calloc(net->Nnodes+1, sizeof(double));
|
||||
hyd->Xflow = (double *) calloc(MAX((net->Nnodes+1), (net->Nlinks+1)),
|
||||
sizeof(double));
|
||||
hyd->OldStatus = (StatusType *) calloc(net->Nlinks+net->Ntanks+1,
|
||||
sizeof(StatusType));
|
||||
ERRCODE(MEMCHECK(hyd->P));
|
||||
ERRCODE(MEMCHECK(hyd->Y));
|
||||
ERRCODE(MEMCHECK(hyd->DemandFlow));
|
||||
ERRCODE(MEMCHECK(hyd->EmitterFlow));
|
||||
ERRCODE(MEMCHECK(hyd->Xflow));
|
||||
ERRCODE(MEMCHECK(hyd->OldStatus));
|
||||
return errcode;
|
||||
@@ -327,8 +323,6 @@ void freematrix(Project *pr)
|
||||
|
||||
free(hyd->P);
|
||||
free(hyd->Y);
|
||||
free(hyd->DemandFlow);
|
||||
free(hyd->EmitterFlow);
|
||||
free(hyd->Xflow);
|
||||
free(hyd->OldStatus);
|
||||
}
|
||||
|
||||
@@ -253,6 +253,8 @@ void initpointers(Project *pr)
|
||||
pr->hydraul.P = NULL;
|
||||
pr->hydraul.Y = NULL;
|
||||
pr->hydraul.Xflow = NULL;
|
||||
pr->hydraul.DemandFlow = NULL;
|
||||
pr->hydraul.EmitterFlow = NULL;
|
||||
|
||||
pr->quality.NodeQual = NULL;
|
||||
pr->quality.PipeRateCoeff = NULL;
|
||||
@@ -313,10 +315,14 @@ int allocdata(Project *pr)
|
||||
pr->hydraul.NodeDemand = (double *)calloc(n, sizeof(double));
|
||||
pr->hydraul.NodeHead = (double *)calloc(n, sizeof(double));
|
||||
pr->quality.NodeQual = (double *)calloc(n, sizeof(double));
|
||||
pr->hydraul.DemandFlow = (double *)calloc(n, sizeof(double));
|
||||
pr->hydraul.EmitterFlow = (double *)calloc(n, sizeof(double));
|
||||
ERRCODE(MEMCHECK(pr->network.Node));
|
||||
ERRCODE(MEMCHECK(pr->hydraul.NodeDemand));
|
||||
ERRCODE(MEMCHECK(pr->hydraul.NodeHead));
|
||||
ERRCODE(MEMCHECK(pr->quality.NodeQual));
|
||||
ERRCODE(MEMCHECK(pr->hydraul.DemandFlow));
|
||||
ERRCODE(MEMCHECK(pr->hydraul.EmitterFlow));
|
||||
}
|
||||
|
||||
// Allocate memory for network links
|
||||
@@ -388,6 +394,8 @@ void freedata(Project *pr)
|
||||
free(pr->hydraul.LinkFlow);
|
||||
free(pr->hydraul.LinkSetting);
|
||||
free(pr->hydraul.LinkStatus);
|
||||
free(pr->hydraul.DemandFlow);
|
||||
free(pr->hydraul.EmitterFlow);
|
||||
free(pr->quality.NodeQual);
|
||||
|
||||
// Free memory used for nodal adjacency lists
|
||||
|
||||
@@ -48,8 +48,8 @@ static int paralink(Network *, Smatrix *, int, int, int k);
|
||||
static void xparalinks(Network *);
|
||||
static int reordernodes(Project *);
|
||||
static int factorize(Project *);
|
||||
static int growlist(Project *, int);
|
||||
static int newlink(Project *, Padjlist);
|
||||
static int growlist(Project *, int, int *);
|
||||
static int newlink(Project *, Padjlist, int *);
|
||||
static int linked(Network *, int, int);
|
||||
static int addlink(Network *, int, int, int);
|
||||
static int storesparse(Project *, int);
|
||||
@@ -443,8 +443,8 @@ int factorize(Project *pr)
|
||||
Padjlist alink;
|
||||
|
||||
// Find degree of each junction node
|
||||
sm->Degree = (int *)calloc(net->Nnodes + 1, sizeof(int));
|
||||
if (sm->Degree == NULL) return 101;
|
||||
int *degree = (int *)calloc(net->Nnodes + 1, sizeof(int));
|
||||
if (degree == NULL) return 101;
|
||||
|
||||
// NOTE: For purposes of node re-ordering, Tanks (nodes with
|
||||
// indexes above Njuncs) have zero degree of adjacency.
|
||||
@@ -453,7 +453,7 @@ int factorize(Project *pr)
|
||||
{
|
||||
for (alink = net->Adjlist[k]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
if (alink->node > 0) sm->Degree[k]++;
|
||||
if (alink->node > 0) degree[k]++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,19 +463,19 @@ int factorize(Project *pr)
|
||||
for (k = 1; k <= net->Njuncs; k++) // Examine each junction
|
||||
{
|
||||
knode = sm->Order[k]; // Re-ordered index
|
||||
if (!growlist(pr, knode)) // Augment adjacency list
|
||||
if (!growlist(pr, knode, degree)) // Augment adjacency list
|
||||
{
|
||||
errcode = 101;
|
||||
break;
|
||||
}
|
||||
sm->Degree[knode] = 0; // In-activate node
|
||||
degree[knode] = 0; // In-activate node
|
||||
}
|
||||
free(sm->Degree);
|
||||
free(degree);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
|
||||
int growlist(Project *pr, int knode)
|
||||
int growlist(Project *pr, int knode, int *degree)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: knode = node index
|
||||
@@ -496,10 +496,10 @@ int growlist(Project *pr, int knode)
|
||||
for (alink = net->Adjlist[knode]; alink != NULL; alink = alink -> next)
|
||||
{
|
||||
node = alink->node; // End node of connecting link
|
||||
if (node > 0 && sm->Degree[node] > 0) // End node is active
|
||||
if (node > 0 && degree[node] > 0) // End node is active
|
||||
{
|
||||
sm->Degree[node]--; // Reduce degree of adjacency
|
||||
if (!newlink(pr, alink)) // Add to adjacency list
|
||||
degree[node]--; // Reduce degree of adjacency
|
||||
if (!newlink(pr, alink, degree)) // Add to adjacency list
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -509,7 +509,7 @@ int growlist(Project *pr, int knode)
|
||||
}
|
||||
|
||||
|
||||
int newlink(Project *pr, Padjlist alink)
|
||||
int newlink(Project *pr, Padjlist alink, int *degree)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: alink = element of node's adjacency list
|
||||
@@ -533,7 +533,7 @@ int newlink(Project *pr, Padjlist alink)
|
||||
|
||||
// If jnode still active, and inode not connected to jnode,
|
||||
// then add a new connection between inode and jnode.
|
||||
if (jnode > 0 && sm->Degree[jnode] > 0) // jnode still active
|
||||
if (jnode > 0 && degree[jnode] > 0) // jnode still active
|
||||
{
|
||||
if (!linked(net, inode, jnode)) // inode not linked to jnode
|
||||
{
|
||||
@@ -545,8 +545,8 @@ int newlink(Project *pr, Padjlist alink)
|
||||
// reflect the new connection.
|
||||
if (!addlink(net, inode, jnode, sm->Ncoeffs)) return 0;
|
||||
if (!addlink(net, jnode, inode, sm->Ncoeffs)) return 0;
|
||||
sm->Degree[inode]++;
|
||||
sm->Degree[jnode]++;
|
||||
degree[inode]++;
|
||||
degree[jnode]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,7 +688,6 @@ typedef struct {
|
||||
*XLNZ, // Start position of each column in NZSUB
|
||||
*NZSUB, // Row index of each coeff. in each column
|
||||
*LNZ, // Position of each coeff. in Aij array
|
||||
*Degree, // Number of links adjacent to each node
|
||||
*link, // Array used by linear eqn. solver
|
||||
*first; // Array used by linear eqn. solver
|
||||
|
||||
|
||||
Reference in New Issue
Block a user