Merge pull request #450 from OpenWaterAnalytics/lrossman-dev
Eliminates use of temporary linked lists to process Patterns & Curves…
This commit is contained in:
68
src/epanet.c
68
src/epanet.c
@@ -172,10 +172,7 @@ int DLLEXPORT EN_init(EN_Project p, const char *rptFile, const char *outFile,
|
||||
initunits(p);
|
||||
inittanks(p);
|
||||
convertunits(p);
|
||||
|
||||
// Initialize the default demand pattern
|
||||
p->parser.MaxPats = 0;
|
||||
getpatterns(p);
|
||||
p->Openflag = TRUE;
|
||||
return errcode;
|
||||
}
|
||||
@@ -230,10 +227,6 @@ int DLLEXPORT EN_open(EN_Project p, const char *inpFile, const char *rptFile,
|
||||
p->parser.InFile = NULL;
|
||||
}
|
||||
|
||||
// Free temporary linked lists used for Patterns & Curves
|
||||
freeTmplist(p->parser.Patlist);
|
||||
freeTmplist(p->parser.Curvelist);
|
||||
|
||||
// If using previously saved hydraulics file then open it
|
||||
if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p));
|
||||
|
||||
@@ -3943,7 +3936,6 @@ int DLLEXPORT EN_addpattern(EN_Project p, char *id)
|
||||
{
|
||||
Network *net = &p->network;
|
||||
Parser *parser = &p->parser;
|
||||
Hydraul *hyd = &p->hydraul;
|
||||
|
||||
int i, n, err = 0;
|
||||
Spattern *pat;
|
||||
@@ -4231,6 +4223,7 @@ int DLLEXPORT EN_addcurve(EN_Project p, char *id)
|
||||
curve = &net->Curve[n];
|
||||
strcpy(curve->ID, id);
|
||||
curve->Comment = NULL;
|
||||
curve->Capacity = 1;
|
||||
curve->Npts = 1;
|
||||
curve->Type = GENERIC_CURVE;
|
||||
curve->X = (double *)calloc(1, sizeof(double));
|
||||
@@ -4302,20 +4295,11 @@ int DLLEXPORT EN_getcurveindex(EN_Project p, char *id, int *index)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
*index = 0;
|
||||
if (!p->Openflag) return 102;
|
||||
for (i = 1; i <= p->network.Ncurves; i++)
|
||||
{
|
||||
if (strcmp(id, p->network.Curve[i].ID) == 0)
|
||||
{
|
||||
*index = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*index = 0;
|
||||
return 206;
|
||||
*index = findcurve(&p->network, id);
|
||||
if (*index == 0) return 206;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DLLEXPORT EN_getcurveid(EN_Project p, int index, char *id)
|
||||
@@ -4404,8 +4388,8 @@ int DLLEXPORT EN_getcurvevalue(EN_Project p, int curveIndex, int pointIndex,
|
||||
if (!p->Openflag) return 102;
|
||||
if (curveIndex < 1 || curveIndex > p->network.Ncurves) return 206;
|
||||
if (pointIndex < 1 || pointIndex > p->network.Curve[curveIndex].Npts) return 251;
|
||||
*x = (double)p->network.Curve[curveIndex].X[pointIndex - 1];
|
||||
*y = (double)p->network.Curve[curveIndex].Y[pointIndex - 1];
|
||||
*x = p->network.Curve[curveIndex].X[pointIndex - 1];
|
||||
*y = p->network.Curve[curveIndex].Y[pointIndex - 1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4419,18 +4403,43 @@ int DLLEXPORT EN_setcurvevalue(EN_Project p, int curveIndex, int pointIndex,
|
||||
** Output: none
|
||||
** Returns: error code
|
||||
** Purpose: sets the value of a specific point on a data curve
|
||||
** Note: if pointIndex exceeds the curve's length a new point is added.
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &p->network;
|
||||
Scurve *curve;
|
||||
double x1 = -1.e37, x2 = 1.e37;
|
||||
int n = pointIndex - 1;
|
||||
|
||||
// Check for valid input
|
||||
if (!p->Openflag) return 102;
|
||||
if (curveIndex <= 0 || curveIndex > net->Ncurves) return 206;
|
||||
curve = &net->Curve[curveIndex];
|
||||
if (pointIndex <= 0 || pointIndex > curve->Npts) return 251;
|
||||
curve->X[pointIndex - 1] = x;
|
||||
curve->Y[pointIndex - 1] = y;
|
||||
if (pointIndex <= 0) return 251;
|
||||
|
||||
// Check that new point maintains increasing x values
|
||||
if (n - 1 >= 0) x1 = curve->X[n-1];
|
||||
if (n + 1 < curve->Npts) x2 = curve->X[n+1];
|
||||
if (x <= x1 || x >= x2) return 230;
|
||||
|
||||
// Expand curve if need be
|
||||
if (pointIndex > curve->Npts) pointIndex = curve->Npts + 1;
|
||||
if (pointIndex >= curve->Capacity)
|
||||
{
|
||||
if (resizecurve(curve, curve->Capacity + 10) > 0) return 101;
|
||||
}
|
||||
|
||||
// Increase curve's number of points if need be
|
||||
if (pointIndex > curve->Npts)
|
||||
{
|
||||
curve->Npts++;
|
||||
n = curve->Npts - 1;
|
||||
}
|
||||
|
||||
// Insert new point into curve
|
||||
curve->X[n] = x;
|
||||
curve->Y[n] = y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4490,15 +4499,12 @@ int DLLEXPORT EN_setcurve(EN_Project p, int index, double *xValues,
|
||||
// Check that x values are increasing
|
||||
for (j = 1; j < nPoints; j++) if (xValues[j-1] >= xValues[j]) return 230;
|
||||
|
||||
// Re-set number of points & reallocate memory for values
|
||||
// Expand size of curve's data arrays if need be
|
||||
curve = &net->Curve[index];
|
||||
curve->Npts = nPoints;
|
||||
curve->X = (double *)realloc(curve->X, nPoints * sizeof(double));
|
||||
curve->Y = (double *)realloc(curve->Y, nPoints * sizeof(double));
|
||||
if (curve->X == NULL) return 101;
|
||||
if (curve->Y == NULL) return 101;
|
||||
if (resizecurve(curve, nPoints) > 0) return 101;
|
||||
|
||||
// Load values into curve
|
||||
curve->Npts = nPoints;
|
||||
for (j = 0; j < nPoints; j++)
|
||||
{
|
||||
curve->X[j] = xValues[j];
|
||||
|
||||
10
src/funcs.h
10
src/funcs.h
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/17/2019
|
||||
Last Updated: 04/03/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef FUNCS_H
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
void initpointers(Project *);
|
||||
int allocdata(Project *);
|
||||
void freeTmplist(STmplist *);
|
||||
void freeFloatlist(SFloatlist *);
|
||||
void freedata(Project *);
|
||||
|
||||
int openfiles(Project *, const char *, const char *,const char *);
|
||||
@@ -36,8 +34,12 @@ int findlink(Network *, char *);
|
||||
int findtank(Network *, int);
|
||||
int findvalve(Network *, int);
|
||||
int findpump(Network *, int);
|
||||
int findpattern(Network *, char *);
|
||||
int findcurve(Network *, char *);
|
||||
|
||||
void adjustpatterns(Network *, int);
|
||||
void adjustcurves(Network *, int);
|
||||
int resizecurve(Scurve *, int);
|
||||
|
||||
int getcomment(Network *, int, int, char *);
|
||||
int setcomment(Network *, int, int, const char *);
|
||||
@@ -65,8 +67,6 @@ void convertunits(Project *);
|
||||
int netsize(Project *);
|
||||
int readdata(Project *);
|
||||
int updatepumpparams(Project *, int);
|
||||
int getpatterns(Project *);
|
||||
int getcurves(Project *);
|
||||
int findmatch(char *, char *[]);
|
||||
int match(const char *, const char *);
|
||||
int gettokens(char *, char **, int, char *);
|
||||
|
||||
@@ -331,6 +331,7 @@ void adjustdata(Project *pr)
|
||||
}
|
||||
|
||||
// Use default pattern if none assigned to a demand
|
||||
parser->DefPat = findpattern(net, parser->DefPatID);
|
||||
if (parser->DefPat > 0) for (i = 1; i <= net->Nnodes; i++)
|
||||
{
|
||||
node = &net->Node[i];
|
||||
|
||||
292
src/input2.c
292
src/input2.c
@@ -35,7 +35,6 @@ extern char *SectTxt[]; // Input section keywords (see ENUMSTXT.H)
|
||||
// Exported functions
|
||||
int addnodeID(Network *n, int, char *);
|
||||
int addlinkID(Network *n, int, char *);
|
||||
STmplist *getlistitem(char *, STmplist *);
|
||||
|
||||
// Imported functions
|
||||
extern int powercurve(double, double, double, double, double, double *,
|
||||
@@ -43,8 +42,8 @@ extern int powercurve(double, double, double, double, double, double *,
|
||||
|
||||
// Local functions
|
||||
static int newline(Project *, int, char *);
|
||||
static int addpattern(Parser *, char *);
|
||||
static int addcurve(Parser *, 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 *);
|
||||
@@ -65,6 +64,7 @@ int netsize(Project *pr)
|
||||
char *tok; // First token of line
|
||||
int sect, newsect; // Input data sections
|
||||
int errcode = 0; // Error code
|
||||
Spattern *pattern;
|
||||
|
||||
// Initialize object counts
|
||||
parser->MaxJuncs = 0;
|
||||
@@ -77,13 +77,20 @@ int netsize(Project *pr)
|
||||
parser->MaxCurves = 0;
|
||||
sect = -1;
|
||||
|
||||
// Add a default demand pattern
|
||||
parser->MaxPats = -1;
|
||||
addpattern(parser,"");
|
||||
|
||||
if (parser->InFile == NULL) return 0;
|
||||
// Add a "dummy" time pattern with index of 0 and a single multiplier
|
||||
// of 1.0 to be used by all demands not assigned a pattern
|
||||
pr->network.Npats = -1;
|
||||
errcode = addpattern(&pr->network, "");
|
||||
if (errcode) return errcode;
|
||||
pattern = &pr->network.Pattern[0];
|
||||
pattern->Length = 1;
|
||||
pattern[0].F = (double *)calloc(1, sizeof(double));
|
||||
pattern[0].F[0] = 1.0;
|
||||
parser->MaxPats = pr->network.Npats;
|
||||
|
||||
// Make a pass through input file counting number of each object
|
||||
if (parser->InFile == NULL) return 0;
|
||||
while (fgets(line, MAXLINE, parser->InFile) != NULL)
|
||||
{
|
||||
// Skip blank lines & those beginning with a comment
|
||||
@@ -115,8 +122,14 @@ int netsize(Project *pr)
|
||||
case _VALVES: parser->MaxValves++; break;
|
||||
case _CONTROLS: parser->MaxControls++; break;
|
||||
case _RULES: addrule(parser,tok); break;
|
||||
case _PATTERNS: errcode = addpattern(parser, tok); break;
|
||||
case _CURVES: errcode = addcurve(parser, tok); break;
|
||||
case _PATTERNS:
|
||||
errcode = addpattern(&pr->network, tok);
|
||||
parser->MaxPats = pr->network.Npats;
|
||||
break;
|
||||
case _CURVES:
|
||||
errcode = addcurve(&pr->network, tok);
|
||||
parser->MaxCurves = pr->network.Ncurves;
|
||||
break;
|
||||
}
|
||||
if (errcode) break;
|
||||
}
|
||||
@@ -166,12 +179,15 @@ int readdata(Project *pr)
|
||||
net->Nvalves = 0;
|
||||
net->Ncontrols = 0;
|
||||
net->Nrules = 0;
|
||||
net->Ncurves = parser->MaxCurves;
|
||||
net->Npats = parser->MaxPats;
|
||||
|
||||
// Patterns & Curves were created previously in netsize()
|
||||
parser->MaxPats = net->Npats;
|
||||
parser->MaxCurves = net->Ncurves;
|
||||
parser->PrevPat = NULL;
|
||||
parser->PrevCurve = NULL;
|
||||
parser->LineComment[0] = '\0';
|
||||
|
||||
// Initialize full line comment, input data section and error count
|
||||
parser->LineComment[0] = '\0';
|
||||
sect = -1;
|
||||
errsum = 0;
|
||||
|
||||
@@ -257,9 +273,7 @@ int readdata(Project *pr)
|
||||
// Check for unlinked nodes
|
||||
if (!errcode) errcode = unlinked(pr);
|
||||
|
||||
// Get pattern & curve data from temporary lists
|
||||
if (!errcode) errcode = getpatterns(pr);
|
||||
if (!errcode) errcode = getcurves(pr);
|
||||
// Determine pump curve parameters
|
||||
if (!errcode) errcode = getpumpparams(pr);
|
||||
|
||||
// Free input buffer
|
||||
@@ -487,7 +501,7 @@ int addlinkID(Network *net, int n, char *id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int addpattern(Parser *parser, char *id)
|
||||
int addpattern(Network *network, char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: id = pattern ID label
|
||||
@@ -496,34 +510,33 @@ int addpattern(Parser *parser, char *id)
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *patlist;
|
||||
int n = network->Npats;
|
||||
Spattern *pattern;
|
||||
|
||||
// Check if ID is same as last one processed
|
||||
if (parser->Patlist != NULL && strcmp(id, parser->Patlist->ID) == 0) return 0;
|
||||
|
||||
// Check that pattern was not already created
|
||||
if (getlistitem(id, parser->Patlist) == NULL)
|
||||
// Check if pattern was already created
|
||||
if (n > 0)
|
||||
{
|
||||
// Update pattern count & create new list element
|
||||
(parser->MaxPats)++;
|
||||
patlist = (STmplist *)malloc(sizeof(STmplist));
|
||||
if (patlist == NULL) return 101;
|
||||
|
||||
// Initialize list element properties
|
||||
else
|
||||
{
|
||||
patlist->i = parser->MaxPats;
|
||||
strncpy(patlist->ID, id, MAXID);
|
||||
patlist->x = NULL;
|
||||
patlist->y = NULL;
|
||||
patlist->next = parser->Patlist;
|
||||
parser->Patlist = patlist;
|
||||
}
|
||||
if (strcmp(id, network->Pattern[n].ID) == 0) return 0;
|
||||
if (findpattern(network, id) > 0) return 0;
|
||||
}
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
|
||||
// Update pattern count & add a new pattern to the database
|
||||
n = n + 2;
|
||||
network->Pattern = (Spattern *)realloc(network->Pattern, n * sizeof(Spattern));
|
||||
if (network->Pattern == NULL) return 101;
|
||||
(network->Npats)++;
|
||||
|
||||
// Initialize the pattern
|
||||
pattern = &network->Pattern[network->Npats];
|
||||
strncpy(pattern->ID, id, MAXID);
|
||||
pattern->Comment = NULL;
|
||||
pattern->Length = 0;
|
||||
pattern->F = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addcurve(Parser *parser, char *id)
|
||||
int addcurve(Network *network, char *id)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: id = curve ID label
|
||||
@@ -532,51 +545,34 @@ int addcurve(Parser *parser, char *id)
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *curvelist;
|
||||
int n = network->Ncurves;
|
||||
Scurve *curve;
|
||||
|
||||
// Check if ID is same as last one processed
|
||||
if (parser->Curvelist != NULL && strcmp(id, parser->Curvelist->ID) == 0) return 0;
|
||||
|
||||
// Check that curve was not already created
|
||||
if (getlistitem(id, parser->Curvelist) == NULL)
|
||||
// Check if was already created
|
||||
if (n > 0)
|
||||
{
|
||||
// Update curve count & create new list element
|
||||
(parser->MaxCurves)++;
|
||||
curvelist = (STmplist *)malloc(sizeof(STmplist));
|
||||
if (curvelist == NULL) return 101;
|
||||
|
||||
// Initialize list element properties
|
||||
else
|
||||
{
|
||||
curvelist->i = parser->MaxCurves;
|
||||
strncpy(curvelist->ID, id, MAXID);
|
||||
curvelist->x = NULL;
|
||||
curvelist->y = NULL;
|
||||
curvelist->next = parser->Curvelist;
|
||||
parser->Curvelist = curvelist;
|
||||
}
|
||||
if (strcmp(id, network->Curve[n].ID) == 0) return 0;
|
||||
if (findcurve(network, id) > 0) return 0;
|
||||
}
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
|
||||
n = n + 2;
|
||||
network->Curve = (Scurve *)realloc(network->Curve, n * sizeof(Scurve));
|
||||
if (network->Curve == NULL) return 101;
|
||||
(network->Ncurves)++;
|
||||
|
||||
// Initialize the curve
|
||||
curve = &network->Curve[network->Ncurves];
|
||||
strncpy(curve->ID, id, MAXID);
|
||||
curve->Type = GENERIC_CURVE;
|
||||
curve->Comment = NULL;
|
||||
curve->Capacity = 0;
|
||||
curve->Npts = 0;
|
||||
curve->X = NULL;
|
||||
curve->Y = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STmplist *getlistitem(char *id, STmplist *list)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: id = ID label
|
||||
** list = pointer to head of a temporary list
|
||||
** Output: returns list item with requested ID label
|
||||
** Purpose: searches for item in temporary list
|
||||
**-------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *item;
|
||||
for (item = list; item != NULL; item = item->next)
|
||||
{
|
||||
if (strcmp(item->ID, id) == 0) return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int unlinked(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
@@ -625,144 +621,6 @@ int unlinked(Project *pr)
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int getpatterns(Project *pr)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: retrieves pattern data from temporary linked list
|
||||
**-------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int i, j;
|
||||
SFloatlist *f;
|
||||
STmplist *tmppattern;
|
||||
Spattern *pattern;
|
||||
|
||||
// Start at head of the list of patterns
|
||||
tmppattern = parser->Patlist;
|
||||
|
||||
// Traverse list of temporary patterns
|
||||
while (tmppattern != NULL)
|
||||
{
|
||||
// Get index of temporary pattern in network's Pattern array
|
||||
i = tmppattern->i;
|
||||
|
||||
// Check if this is the default pattern
|
||||
if (strcmp(tmppattern->ID, parser->DefPatID) == 0) parser->DefPat = i;
|
||||
|
||||
// Copy temporary patttern to network's pattern
|
||||
if (i >= 0 && i <= parser->MaxPats)
|
||||
{
|
||||
pattern = &net->Pattern[i];
|
||||
strcpy(pattern->ID, tmppattern->ID);
|
||||
|
||||
/* Give pattern a length of at least 1 */
|
||||
if (pattern->Length == 0) pattern->Length = 1;
|
||||
|
||||
// Allocate array of pattern factors
|
||||
pattern->F = (double *)calloc(pattern->Length, sizeof(double));
|
||||
if (pattern->F == NULL) return 101;
|
||||
|
||||
// Start at head of temporary pattern multiplier list
|
||||
// (which holds multipliers in reverse order)
|
||||
f = tmppattern->x;
|
||||
j = pattern->Length - 1;
|
||||
|
||||
// Use at least one multiplier equal to 1.0
|
||||
if (f == NULL) pattern->F[0] = 1.0;
|
||||
|
||||
// Traverse temporary multiplier list, copying Pattern array */
|
||||
else while (f != NULL && j >= 0)
|
||||
{
|
||||
pattern->F[j] = f->value;
|
||||
f = f->next;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
tmppattern = tmppattern->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getcurves(Project *pr)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns error code
|
||||
** Purpose: retrieves curve data from temporary linked list
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int i, j;
|
||||
double x;
|
||||
char errmsg[MAXMSG+1];
|
||||
SFloatlist *fx, *fy;
|
||||
STmplist *tmpcurve;
|
||||
Scurve *curve;
|
||||
|
||||
// Traverse list of temporary curves
|
||||
tmpcurve = parser->Curvelist;
|
||||
while (tmpcurve != NULL)
|
||||
{
|
||||
// Get index of temporary curve in network's Curve array
|
||||
i = tmpcurve->i;
|
||||
|
||||
// Copy temporary curve to network's curve
|
||||
if (i >= 1 && i <= parser->MaxCurves)
|
||||
{
|
||||
curve = &net->Curve[i];
|
||||
strcpy(curve->ID, tmpcurve->ID);
|
||||
|
||||
// Check that network curve has data points
|
||||
if (curve->Npts <= 0)
|
||||
{
|
||||
sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg), curve->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return 200;
|
||||
}
|
||||
|
||||
// Allocate memory for network's curve data
|
||||
curve->X = (double *)calloc(curve->Npts, sizeof(double));
|
||||
curve->Y = (double *)calloc(curve->Npts, sizeof(double));
|
||||
if (curve->X == NULL || curve->Y == NULL) return 101;
|
||||
|
||||
// Traverse list of x,y data
|
||||
x = BIG;
|
||||
fx = tmpcurve->x;
|
||||
fy = tmpcurve->y;
|
||||
j = curve->Npts - 1;
|
||||
while (fx != NULL && fy != NULL && j >= 0)
|
||||
{
|
||||
// Check that x data is in ascending order
|
||||
if (fx->value >= x)
|
||||
{
|
||||
sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg), curve->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return 200;
|
||||
}
|
||||
x = fx->value;
|
||||
|
||||
// Copy x,y data to network's curve
|
||||
curve->X[j] = fx->value;
|
||||
fx = fx->next;
|
||||
curve->Y[j] = fy->value;
|
||||
fy = fy->next;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
tmpcurve = tmpcurve->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int findmatch(char *line, char *keyword[])
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
@@ -828,8 +686,8 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment)
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int m, n;
|
||||
size_t len;
|
||||
int n;
|
||||
size_t len, m;
|
||||
char *c, *c2;
|
||||
|
||||
// clear comment
|
||||
|
||||
202
src/input3.c
202
src/input3.c
@@ -7,7 +7,7 @@ Description: parses network data from a line of an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/17/2019
|
||||
Last Updated: 04/03/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -40,7 +40,6 @@ int powercurve(double, double, double, double, double, double *, double *,
|
||||
// Imported Functions
|
||||
extern int addnodeID(Network *, int, char *);
|
||||
extern int addlinkID(Network *, int, char *);
|
||||
extern STmplist *getlistitem(char *, STmplist *);
|
||||
|
||||
// Local functions
|
||||
static int optionchoice(Project *, int);
|
||||
@@ -87,7 +86,6 @@ int juncdata(Project *pr)
|
||||
double el, // elevation
|
||||
y = 0.0; // base demand
|
||||
Pdemand demand; // demand record
|
||||
STmplist *patlist; // list of demands
|
||||
Snode *node;
|
||||
|
||||
// Add new junction to data base
|
||||
@@ -104,9 +102,8 @@ int juncdata(Project *pr)
|
||||
if (n >= 3 && !getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
|
||||
if (n >= 4)
|
||||
{
|
||||
patlist = getlistitem(parser->Tok[3], parser->Patlist);
|
||||
if (patlist == NULL) return setError(parser, 3, 205);
|
||||
p = patlist->i;
|
||||
p = findpattern(net, parser->Tok[3]);
|
||||
if (p == 0) return setError(parser, 3, 205);
|
||||
}
|
||||
|
||||
// Save junction data
|
||||
@@ -162,7 +159,6 @@ int tankdata(Project *pr)
|
||||
minvol = 0.0, // Minimum volume
|
||||
diam = 0.0, // Diameter
|
||||
area; // X-sect. area
|
||||
STmplist *tmplist;
|
||||
Snode *node;
|
||||
Stank *tank;
|
||||
|
||||
@@ -186,9 +182,8 @@ int tankdata(Project *pr)
|
||||
// Head pattern supplied
|
||||
if (n == 3)
|
||||
{
|
||||
tmplist = getlistitem(parser->Tok[2], parser->Patlist);
|
||||
if (tmplist == NULL) return setError(parser, 2, 205);
|
||||
pattern = tmplist->i;
|
||||
pattern = findpattern(net, parser->Tok[2]);
|
||||
if (pattern == 0) return setError(parser, 2, 205);
|
||||
}
|
||||
}
|
||||
else if (n < 6) return 201;
|
||||
@@ -205,9 +200,8 @@ int tankdata(Project *pr)
|
||||
// If volume curve supplied check it exists
|
||||
if (n == 8)
|
||||
{
|
||||
tmplist = getlistitem(parser->Tok[7], parser->Curvelist);
|
||||
if (tmplist == NULL) return setError(parser, 7, 206);
|
||||
curve = tmplist->i;
|
||||
curve = findcurve(net, parser->Tok[7]);
|
||||
if (curve == 0) return setError(parser, 7, 206);
|
||||
net->Curve[curve].Type = VOLUME_CURVE;
|
||||
}
|
||||
if (initlevel < 0.0) return setError(parser, 2, 209);
|
||||
@@ -357,12 +351,12 @@ int pumpdata(Project *pr)
|
||||
Network *net = &pr->network;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int j,
|
||||
int j, m, // Token array indexes
|
||||
j1, // Start-node index
|
||||
j2, // End-node index
|
||||
m, n; // # data items
|
||||
n, // # data items
|
||||
c, p; // Curve & Pattern indexes
|
||||
double y;
|
||||
STmplist *tmplist; // Temporary list
|
||||
Slink *link;
|
||||
Spump *pump;
|
||||
|
||||
@@ -432,15 +426,15 @@ int pumpdata(Project *pr)
|
||||
}
|
||||
else if (match(parser->Tok[m - 1], w_HEAD)) // Custom pump curve
|
||||
{
|
||||
tmplist = getlistitem(parser->Tok[m], parser->Curvelist);
|
||||
if (tmplist == NULL) return setError(parser, m, 206);
|
||||
pump->Hcurve = tmplist->i;
|
||||
c = findcurve(net, parser->Tok[m]);
|
||||
if (c == 0) return setError(parser, m, 206);
|
||||
pump->Hcurve = c;
|
||||
}
|
||||
else if (match(parser->Tok[m - 1], w_PATTERN)) // Speed/status pattern
|
||||
{
|
||||
tmplist = getlistitem(parser->Tok[m], parser->Patlist);
|
||||
if (tmplist == NULL) return setError(parser, m, 205);
|
||||
pump->Upat = tmplist->i;
|
||||
p = findpattern(net, parser->Tok[m]);
|
||||
if (p == 0) return setError(parser, m, 205);
|
||||
pump->Upat = p;
|
||||
}
|
||||
else if (match(parser->Tok[m - 1], w_SPEED)) // Speed setting
|
||||
{
|
||||
@@ -469,7 +463,8 @@ int valvedata(Project *pr)
|
||||
Network *net = &pr->network;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int j1, // Start-node index
|
||||
int c, // Curve index
|
||||
j1, // Start-node index
|
||||
j2, // End-node index
|
||||
n; // # data items
|
||||
char status = ACTIVE, // Valve status
|
||||
@@ -477,7 +472,6 @@ int valvedata(Project *pr)
|
||||
double diam = 0.0, // Valve diameter
|
||||
setting, // Valve setting
|
||||
lcoeff = 0.0; // Minor loss coeff.
|
||||
STmplist *tmplist; // Temporary list
|
||||
Slink *link;
|
||||
|
||||
// Add new valve to data base
|
||||
@@ -508,10 +502,10 @@ int valvedata(Project *pr)
|
||||
// Find headloss curve for GPV
|
||||
if (type == GPV)
|
||||
{
|
||||
tmplist = getlistitem(parser->Tok[5], parser->Curvelist);
|
||||
if (tmplist == NULL) return setError(parser, 5, 206);
|
||||
setting = tmplist->i;
|
||||
net->Curve[tmplist->i].Type = HLOSS_CURVE;
|
||||
c = findcurve(net, parser->Tok[5]);
|
||||
if (c == 0) return setError(parser, 5, 206);
|
||||
setting = c;
|
||||
net->Curve[c].Type = HLOSS_CURVE;
|
||||
status = OPEN;
|
||||
}
|
||||
else if (!getfloat(parser->Tok[5], &setting)) return setError(parser, 5, 202);
|
||||
@@ -558,43 +552,47 @@ int patterndata(Project *pr)
|
||||
Network *net = &pr->network;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int i, n;
|
||||
int i, j, n, n1;
|
||||
double x;
|
||||
SFloatlist *f;
|
||||
STmplist *p;
|
||||
Spattern *pattern;
|
||||
|
||||
// "n" is the number of pattern factors contained in the line
|
||||
n = parser->Ntokens - 1;
|
||||
if (n < 1) return 201;
|
||||
|
||||
// Check for a new pattern
|
||||
if (parser->PrevPat != NULL &&
|
||||
strcmp(parser->Tok[0], parser->PrevPat->ID) == 0) p = parser->PrevPat;
|
||||
// Check if previous input line was for the same pattern
|
||||
if (parser->PrevPat && strcmp(parser->Tok[0], parser->PrevPat->ID) == 0)
|
||||
{
|
||||
pattern = parser->PrevPat;
|
||||
}
|
||||
|
||||
// Otherwise retrieve pattern from the network's Pattern array
|
||||
else
|
||||
{
|
||||
p = getlistitem(parser->Tok[0], parser->Patlist);
|
||||
if (p == NULL) return setError(parser, 0, 205);
|
||||
pattern = &(net->Pattern[p->i]);
|
||||
pattern->Comment = xstrcpy(&pattern->Comment, parser->Comment, MAXMSG);
|
||||
i = findpattern(net, parser->Tok[0]);
|
||||
if (i == 0) return setError(parser, 0, 205);
|
||||
pattern = &(net->Pattern[i]);
|
||||
if (pattern->Comment == NULL && parser->Comment[0])
|
||||
{
|
||||
pattern->Comment = xstrcpy(&pattern->Comment, parser->Comment, MAXMSG);
|
||||
}
|
||||
}
|
||||
|
||||
// Expand size of the pattern's factors array
|
||||
n1 = pattern->Length;
|
||||
pattern->Length += n;
|
||||
pattern->F = realloc(pattern->F, pattern->Length * sizeof(double));
|
||||
|
||||
// Add parsed multipliers to the pattern
|
||||
for (i = 1; i <= n; i++)
|
||||
for (j = 1; j <= n; j++)
|
||||
{
|
||||
if (!getfloat(parser->Tok[i], &x)) return setError(parser, i, 202);
|
||||
f = (SFloatlist *)malloc(sizeof(SFloatlist));
|
||||
if (f == NULL) return 101;
|
||||
f->value = x;
|
||||
f->next = p->x;
|
||||
p->x = f;
|
||||
if (!getfloat(parser->Tok[j], &x)) return setError(parser, j, 202);
|
||||
pattern->F[n1 + j - 1] = x;
|
||||
}
|
||||
|
||||
// Save # multipliers for pattern
|
||||
net->Pattern[p->i].Length += n;
|
||||
|
||||
// Set previous pattern pointer
|
||||
parser->PrevPat = p;
|
||||
return (0);
|
||||
// Save a reference to this pattern for processing additional pattern data
|
||||
parser->PrevPat = pattern;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int curvedata(Project *pr)
|
||||
@@ -612,46 +610,46 @@ int curvedata(Project *pr)
|
||||
Network *net = &pr->network;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int i;
|
||||
double x, y;
|
||||
SFloatlist *fx, *fy;
|
||||
STmplist *c;
|
||||
Scurve *curve;
|
||||
|
||||
// Check for valid curve ID
|
||||
if (parser->Ntokens < 3) return 201;
|
||||
if (parser->PrevCurve != NULL &&
|
||||
strcmp(parser->Tok[0], parser->PrevCurve->ID) == 0) c = parser->PrevCurve;
|
||||
else
|
||||
{
|
||||
c = getlistitem(parser->Tok[0], parser->Curvelist);
|
||||
if (c == NULL) return setError(parser, 0, 206);
|
||||
curve = &(net->Curve[c->i]);
|
||||
curve->Comment = xstrcpy(&curve->Comment, parser->Comment, MAXMSG);
|
||||
}
|
||||
|
||||
// Check for valid data
|
||||
if (parser->Ntokens < 3) return 201;
|
||||
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
|
||||
if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
|
||||
|
||||
// Add new data point to curve
|
||||
fx = (SFloatlist *)malloc(sizeof(SFloatlist));
|
||||
if (fx == NULL) return 101;
|
||||
fy = (SFloatlist *)malloc(sizeof(SFloatlist));
|
||||
if (fy == NULL)
|
||||
// Check if previous input line was for the same curve
|
||||
if (parser->PrevCurve && strcmp(parser->Tok[0], parser->PrevCurve->ID) == 0)
|
||||
{
|
||||
free(fx);
|
||||
return 101;
|
||||
curve = parser->PrevCurve;
|
||||
}
|
||||
fx->value = x;
|
||||
fx->next = c->x;
|
||||
c->x = fx;
|
||||
fy->value = y;
|
||||
fy->next = c->y;
|
||||
c->y = fy;
|
||||
net->Curve[c->i].Npts++;
|
||||
|
||||
// Save the pointer to this curve
|
||||
parser->PrevCurve = c;
|
||||
// Otherwise retrieve curve from the network's Curve array
|
||||
else
|
||||
{
|
||||
i = findcurve(net, parser->Tok[0]);
|
||||
if (i == 0) return setError(parser, 0, 206);
|
||||
curve = &(net->Curve[i]);
|
||||
if (curve->Comment == NULL && parser->Comment[0])
|
||||
{
|
||||
curve->Comment = xstrcpy(&curve->Comment, parser->Comment, MAXMSG);
|
||||
}
|
||||
}
|
||||
|
||||
// Expand size of data arrays if need be
|
||||
if (curve->Capacity == curve->Npts)
|
||||
{
|
||||
if (resizecurve(curve, curve->Capacity + 10) > 0) return 101;
|
||||
}
|
||||
|
||||
// Add new data point to curve
|
||||
curve->X[curve->Npts] = x;
|
||||
curve->Y[curve->Npts] = y;
|
||||
curve->Npts++;
|
||||
|
||||
// Save a reference to this curve for processing additional curve data
|
||||
parser->PrevCurve = curve;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -713,7 +711,6 @@ int demanddata(Project *pr)
|
||||
double y;
|
||||
Pdemand demand;
|
||||
Pdemand cur_demand;
|
||||
STmplist *patlist;
|
||||
|
||||
// Extract data from tokens
|
||||
n = parser->Ntokens;
|
||||
@@ -733,9 +730,8 @@ int demanddata(Project *pr)
|
||||
if (j > net->Njuncs) return 0;
|
||||
if (n >= 3)
|
||||
{
|
||||
patlist = getlistitem(parser->Tok[2], parser->Patlist);
|
||||
if (patlist == NULL) return setError(parser, 2, 205);
|
||||
p = patlist->i;
|
||||
p = findpattern(net, parser->Tok[2]);
|
||||
if (p == 0) return setError(parser, 2, 205);
|
||||
}
|
||||
|
||||
// Replace any demand entered in [JUNCTIONS] section
|
||||
@@ -746,7 +742,10 @@ int demanddata(Project *pr)
|
||||
// with what is specified in this section
|
||||
demand->Base = y;
|
||||
demand->Pat = p;
|
||||
demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXMSG);
|
||||
if (parser->Comment[0])
|
||||
{
|
||||
demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXID);
|
||||
}
|
||||
hyd->NodeDemand[j] = MISSING; // marker - next iteration will append a new category.
|
||||
}
|
||||
|
||||
@@ -759,7 +758,11 @@ int demanddata(Project *pr)
|
||||
if (demand == NULL) return 101;
|
||||
demand->Base = y;
|
||||
demand->Pat = p;
|
||||
demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXMSG);
|
||||
demand->Name = NULL;
|
||||
if (parser->Comment[0])
|
||||
{
|
||||
demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXID);
|
||||
}
|
||||
demand->next = NULL;
|
||||
cur_demand->next = demand;
|
||||
}
|
||||
@@ -900,7 +903,6 @@ int sourcedata(Project *pr)
|
||||
p = 0; // Time pattern index
|
||||
char type = CONCEN; // Source type
|
||||
double c0 = 0; // Initial quality
|
||||
STmplist *patlist;
|
||||
Psource source;
|
||||
|
||||
// Check for enough tokens & that source node exists
|
||||
@@ -929,9 +931,8 @@ int sourcedata(Project *pr)
|
||||
if (n > i + 1 && strlen(parser->Tok[i + 1]) > 0 &&
|
||||
strcmp(parser->Tok[i + 1], "*") != 0)
|
||||
{
|
||||
patlist = getlistitem(parser->Tok[i + 1], parser->Patlist);
|
||||
if (patlist == NULL) return setError(parser, i+1, 205);
|
||||
p = patlist->i;
|
||||
p = findpattern(net, parser->Tok[i + 1]);
|
||||
if (p == 0) return setError(parser, i + 1, 205);
|
||||
}
|
||||
|
||||
// Destroy any existing source assigned to node
|
||||
@@ -1335,10 +1336,9 @@ int energydata(Project *pr)
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Parser *parser = &pr->parser;
|
||||
|
||||
int j, k, n;
|
||||
int j, k, n, p, c;
|
||||
double y;
|
||||
|
||||
STmplist *listitem;
|
||||
Slink *Link = net->Link;
|
||||
Spump *Pump = net->Pump;
|
||||
|
||||
@@ -1385,10 +1385,10 @@ int energydata(Project *pr)
|
||||
// Price PATTERN being set
|
||||
else if (match(parser->Tok[n - 2], w_PATTERN))
|
||||
{
|
||||
listitem = getlistitem(parser->Tok[n - 1], parser->Patlist);
|
||||
if (listitem == NULL) return setError(parser, n - 1, 205);
|
||||
if (j == 0) hyd->Epat = listitem->i;
|
||||
else Pump[j].Epat = listitem->i;
|
||||
p = findpattern(net, parser->Tok[n - 1]);
|
||||
if (p == 0) return setError(parser, n - 1, 205);
|
||||
if (j == 0) hyd->Epat = p;
|
||||
else Pump[j].Epat = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1403,10 +1403,10 @@ int energydata(Project *pr)
|
||||
}
|
||||
else
|
||||
{
|
||||
listitem = getlistitem(parser->Tok[n - 1], parser->Curvelist);
|
||||
if (listitem == NULL) return setError(parser, n - 1, 206);
|
||||
Pump[j].Ecurve = listitem->i;
|
||||
net->Curve[listitem->i].Type = EFFIC_CURVE;
|
||||
c = findcurve(net, parser->Tok[n - 1]);
|
||||
if (c == 0) return setError(parser, n - 1, 206);
|
||||
Pump[j].Ecurve = c;
|
||||
net->Curve[c].Type = EFFIC_CURVE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
146
src/project.c
146
src/project.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/17/2019
|
||||
Last Updated: 04/03/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -274,9 +274,6 @@ void initpointers(Project *pr)
|
||||
pr->network.NodeHashTable = NULL;
|
||||
pr->network.LinkHashTable = NULL;
|
||||
|
||||
pr->parser.Patlist = NULL;
|
||||
pr->parser.Curvelist = NULL;
|
||||
|
||||
pr->hydraul.smatrix.Aii = NULL;
|
||||
pr->hydraul.smatrix.Aij = NULL;
|
||||
pr->hydraul.smatrix.F = NULL;
|
||||
@@ -317,10 +314,10 @@ int allocdata(Project *pr)
|
||||
if (!errcode)
|
||||
{
|
||||
n = pr->parser.MaxNodes + 1;
|
||||
pr->network.Node = (Snode *)calloc(n, sizeof(Snode));
|
||||
pr->network.Node = (Snode *)calloc(n, sizeof(Snode));
|
||||
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->quality.NodeQual = (double *)calloc(n, sizeof(double));
|
||||
ERRCODE(MEMCHECK(pr->network.Node));
|
||||
ERRCODE(MEMCHECK(pr->hydraul.NodeDemand));
|
||||
ERRCODE(MEMCHECK(pr->hydraul.NodeHead));
|
||||
@@ -331,8 +328,8 @@ int allocdata(Project *pr)
|
||||
if (!errcode)
|
||||
{
|
||||
n = pr->parser.MaxLinks + 1;
|
||||
pr->network.Link = (Slink *)calloc(n, sizeof(Slink));
|
||||
pr->hydraul.LinkFlow = (double *)calloc(n, sizeof(double));
|
||||
pr->network.Link = (Slink *)calloc(n, sizeof(Slink));
|
||||
pr->hydraul.LinkFlow = (double *)calloc(n, sizeof(double));
|
||||
pr->hydraul.LinkSetting = (double *)calloc(n, sizeof(double));
|
||||
pr->hydraul.LinkStatus = (StatusType *)calloc(n, sizeof(StatusType));
|
||||
ERRCODE(MEMCHECK(pr->network.Link));
|
||||
@@ -341,8 +338,8 @@ int allocdata(Project *pr)
|
||||
ERRCODE(MEMCHECK(pr->hydraul.LinkStatus));
|
||||
}
|
||||
|
||||
// Allocate memory for tanks, sources, pumps, valves,
|
||||
// controls, demands, time patterns, & operating curves
|
||||
// Allocate memory for tanks, sources, pumps, valves, and controls
|
||||
// (memory for Patterns and Curves arrays expanded as each is added)
|
||||
if (!errcode)
|
||||
{
|
||||
pr->network.Tank =
|
||||
@@ -353,35 +350,15 @@ int allocdata(Project *pr)
|
||||
(Svalve *)calloc(pr->parser.MaxValves + 1, sizeof(Svalve));
|
||||
pr->network.Control =
|
||||
(Scontrol *)calloc(pr->parser.MaxControls + 1, sizeof(Scontrol));
|
||||
pr->network.Pattern =
|
||||
(Spattern *)calloc(pr->parser.MaxPats + 1, sizeof(Spattern));
|
||||
pr->network.Curve =
|
||||
(Scurve *)calloc(pr->parser.MaxCurves + 1, sizeof(Scurve));
|
||||
ERRCODE(MEMCHECK(pr->network.Tank));
|
||||
ERRCODE(MEMCHECK(pr->network.Pump));
|
||||
ERRCODE(MEMCHECK(pr->network.Valve));
|
||||
ERRCODE(MEMCHECK(pr->network.Control));
|
||||
ERRCODE(MEMCHECK(pr->network.Pattern));
|
||||
ERRCODE(MEMCHECK(pr->network.Curve));
|
||||
}
|
||||
|
||||
// Initialize pointers used in patterns, curves, and demand category lists
|
||||
// Initialize pointers used in nodes and links
|
||||
if (!errcode)
|
||||
{
|
||||
for (n = 0; n <= pr->parser.MaxPats; n++)
|
||||
{
|
||||
pr->network.Pattern[n].Length = 0;
|
||||
pr->network.Pattern[n].F = NULL;
|
||||
pr->network.Pattern[n].Comment = NULL;
|
||||
}
|
||||
for (n = 0; n <= pr->parser.MaxCurves; n++)
|
||||
{
|
||||
pr->network.Curve[n].Npts = 0;
|
||||
pr->network.Curve[n].Type = GENERIC_CURVE;
|
||||
pr->network.Curve[n].X = NULL;
|
||||
pr->network.Curve[n].Y = NULL;
|
||||
pr->network.Curve[n].Comment = NULL;
|
||||
}
|
||||
for (n = 0; n <= pr->parser.MaxNodes; n++)
|
||||
{
|
||||
pr->network.Node[n].D = NULL; // node demand
|
||||
@@ -399,43 +376,6 @@ int allocdata(Project *pr)
|
||||
return errcode;
|
||||
}
|
||||
|
||||
void freeTmplist(STmplist *t)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: t = pointer to start of a temporary list
|
||||
** Output: none
|
||||
** Purpose: frees memory used for temporary storage
|
||||
** of pattern & curve data
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
STmplist *tnext;
|
||||
while (t != NULL)
|
||||
{
|
||||
tnext = t->next;
|
||||
freeFloatlist(t->x);
|
||||
freeFloatlist(t->y);
|
||||
free(t);
|
||||
t = tnext;
|
||||
}
|
||||
}
|
||||
|
||||
void freeFloatlist(SFloatlist *f)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: f = pointer to start of list of floats
|
||||
** Output: none
|
||||
** Purpose: frees memory used for storing list of floats
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
SFloatlist *fnext;
|
||||
while (f != NULL)
|
||||
{
|
||||
fnext = f->next;
|
||||
free(f);
|
||||
f = fnext;
|
||||
}
|
||||
}
|
||||
|
||||
void freedata(Project *pr)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: none
|
||||
@@ -446,7 +386,6 @@ void freedata(Project *pr)
|
||||
{
|
||||
int j;
|
||||
Pdemand demand, nextdemand;
|
||||
Psource source;
|
||||
|
||||
// Free memory for computed results
|
||||
free(pr->hydraul.NodeDemand);
|
||||
@@ -474,8 +413,7 @@ void freedata(Project *pr)
|
||||
demand = nextdemand;
|
||||
}
|
||||
// Free memory used for WQ source data
|
||||
source = pr->network.Node[j].S;
|
||||
free(source);
|
||||
free(pr->network.Node[j].S);
|
||||
free(pr->network.Node[j].Comment);
|
||||
}
|
||||
free(pr->network.Node);
|
||||
@@ -511,7 +449,8 @@ void freedata(Project *pr)
|
||||
// Free memory for curves
|
||||
if (pr->network.Curve != NULL)
|
||||
{
|
||||
for (j = 0; j <= pr->parser.MaxCurves; j++)
|
||||
// There is no Curve[0]
|
||||
for (j = 1; j <= pr->parser.MaxCurves; j++)
|
||||
{
|
||||
free(pr->network.Curve[j].X);
|
||||
free(pr->network.Curve[j].Y);
|
||||
@@ -809,6 +748,40 @@ int findvalve(Network *network, int index)
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
int findpattern(Network *network, char *id)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: id = time pattern ID
|
||||
** Output: none
|
||||
** Returns: time pattern index, or 0 if pattern not found
|
||||
** Purpose: finds index of time pattern given its ID
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i <= network->Npats; i++)
|
||||
{
|
||||
if (strcmp(id, network->Pattern[i].ID) == 0) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int findcurve(Network *network, char *id)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: id = data curve ID
|
||||
** Output: none
|
||||
** Returns: data curve index, or 0 if curve not found
|
||||
** Purpose: finds index of data curve given its ID
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i <= network->Ncurves; i++)
|
||||
{
|
||||
if (strcmp(id, network->Curve[i].ID) == 0) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adjustpattern(int *pat, int index)
|
||||
/*----------------------------------------------------------------
|
||||
** Local function that modifies a reference to a deleted time pattern
|
||||
@@ -904,6 +877,35 @@ void adjustcurves(Network *network, int index)
|
||||
}
|
||||
}
|
||||
|
||||
int resizecurve(Scurve *curve, int size)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: curve = a data curve object
|
||||
** size = desired number of curve data points
|
||||
** Output: error code
|
||||
** Purpose: resizes a data curve to a desired size
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
double *x;
|
||||
double *y;
|
||||
|
||||
if (curve->Capacity < size)
|
||||
{
|
||||
x = (double *)realloc(curve->X, size * sizeof(double));
|
||||
if (x == NULL) return 101;
|
||||
y = (double *)realloc(curve->Y, size * sizeof(double));
|
||||
if (y == NULL)
|
||||
{
|
||||
free(x);
|
||||
return 101;
|
||||
}
|
||||
curve->X = x;
|
||||
curve->Y = y;
|
||||
curve->Capacity = size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getcomment(Network *network, int object, int index, char *comment)
|
||||
//----------------------------------------------------------------
|
||||
// Input: object = a type of network object
|
||||
|
||||
26
src/types.h
26
src/types.h
@@ -317,23 +317,6 @@ struct IDstring // Holds component ID label
|
||||
char ID[MAXID+1];
|
||||
};
|
||||
|
||||
struct Floatlist // Element of List of Numbers
|
||||
{
|
||||
double value; // element's numerical value
|
||||
struct Floatlist *next; // next element on the list
|
||||
};
|
||||
typedef struct Floatlist SFloatlist;
|
||||
|
||||
struct Tmplist // Item of Temporary List of Objects
|
||||
{
|
||||
int i; // object's index
|
||||
char ID[MAXID+1]; // object's ID name
|
||||
SFloatlist *x; // list of data values
|
||||
SFloatlist *y; // list of data values
|
||||
struct Tmplist *next; // next object on list
|
||||
};
|
||||
typedef struct Tmplist STmplist; // Pointer to temporary list of objects
|
||||
|
||||
typedef struct // Time Pattern Object
|
||||
{
|
||||
char ID[MAXID+1]; // pattern ID
|
||||
@@ -348,6 +331,7 @@ typedef struct // Curve Object
|
||||
char *Comment; // curve comment
|
||||
CurveType Type; // curve type
|
||||
int Npts; // number of points
|
||||
int Capacity; // size of X & Y arrays
|
||||
double *X; // x-values
|
||||
double *Y; // y-values
|
||||
} Scurve;
|
||||
@@ -576,12 +560,8 @@ typedef struct {
|
||||
Pressflag, // Pressure units flag
|
||||
DefPat; // Default demand pattern
|
||||
|
||||
STmplist
|
||||
*Patlist, // Temporary time pattern list
|
||||
*PrevPat, // Previous pattern list element
|
||||
*Curvelist, // Temporary list of curves
|
||||
*PrevCurve; // Previous curve list element
|
||||
|
||||
Spattern *PrevPat; // Previous pattern processed
|
||||
Scurve *PrevCurve; // Previous curve processed
|
||||
double *X; // Temporary array for curve data
|
||||
|
||||
} Parser;
|
||||
|
||||
Reference in New Issue
Block a user