Network building enhancements

This commit is contained in:
Lew Rossman
2020-02-04 10:01:23 -05:00
parent 77243b1607
commit 80f9acfe4d
16 changed files with 188 additions and 93 deletions

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
******************************************************************************
*/
@@ -3778,6 +3778,12 @@ int DLLEXPORT EN_getlinkvalue(EN_Project p, int index, int property, double *val
v = (double)Pump[findpump(&p->network, index)].Epat;
}
break;
case EN_GPV_CURVE:
if (Link[index].Type == GPV)
{
v = Link[index].Kc;
}
default:
return 251;
@@ -3985,6 +3991,14 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
net->Pump[pumpIndex].Epat = patIndex;
}
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;
@@ -4088,6 +4102,35 @@ int DLLEXPORT EN_getvertex(EN_Project p, int index, int vertex, double *x, doubl
*y = vertices->Y[vertex - 1];
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)
/*----------------------------------------------------------------
@@ -4699,6 +4742,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

@@ -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

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/15/2019
Last Updated: 02/03/2020
******************************************************************************
*/
@@ -795,6 +795,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
@@ -912,8 +940,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)

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