From 9da5f4f658164abf0a562476287452db904fa4ae Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 24 May 2013 15:54:02 -0400 Subject: [PATCH] rtx mods, epanet gets coords --- src/epanet.c | 44 +++++++++++++++-- src/funcs.h | 3 ++ src/input2.c | 133 ++++++++++++++++++++++++++++++++++++++++++++------ src/input3.c | 55 +++++++++++++++++++++ src/toolkit.h | 1 + src/types.h | 7 +++ src/vars.h | 4 ++ 7 files changed, 228 insertions(+), 19 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index f193147..5b7edb1 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -318,6 +318,7 @@ int DLLEXPORT ENopen(char *f1, char *f2, char *f3) /* Free temporary linked lists used for Patterns & Curves */ freeTmplist(Patlist); freeTmplist(Curvelist); + freeTmplist(Coordlist); /* If using previously saved hydraulics then open its file */ if (Hydflag == USE) ERRCODE(openhydfile()); @@ -1345,6 +1346,21 @@ int DLLEXPORT ENgetnodetype(int index, int *code) } +int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) +/*---------------------------------------------------------------- + ** Input: index = node index + ** Output: *x = value of node's coordinate + ** *x = value of node's coordinate + ** Returns: error code + ** Purpose: retrieves coordinate x, y for a node + **---------------------------------------------------------------- + */ +{ + *x = Coord[index].X[0]; + *y = Coord[index].Y[0]; + return 0; +} + int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) /*---------------------------------------------------------------- ** Input: index = node index @@ -2330,10 +2346,16 @@ int DLLEXPORT ENsettimeparam(int code, long value) { if (!Openflag) return(102); if (OpenHflag || OpenQflag) { - // --> there's nothing wrong with changing certain time parameters during a simulation run - if (code != EN_DURATION) { + // --> there's nothing wrong with changing certain time parameters during a simulation run, or before the run has started. + // todo -- how to tell? + /* + if (code == EN_DURATION || code == EN_HTIME || code == EN_REPORTSTEP || code == EN_DURATION || Htime == 0) { + // it's ok + } + else { return(109); } + */ } if (value < 0) return(202); switch(code) @@ -2730,10 +2752,12 @@ void initpointers() Pattern = NULL; Curve = NULL; Control = NULL; + Coord = NULL; X = NULL; Patlist = NULL; Curvelist = NULL; + Coordlist = NULL; Adjlist = NULL; Aii = NULL; Aij = NULL; @@ -2813,12 +2837,14 @@ int allocdata() Control = (Scontrol *) calloc(MaxControls+1,sizeof(Scontrol)); Pattern = (Spattern *) calloc(MaxPats+1, sizeof(Spattern)); Curve = (Scurve *) calloc(MaxCurves+1, sizeof(Scurve)); + Coord = (Scoord *) calloc(MaxNodes+1, sizeof(Scoord)); ERRCODE(MEMCHECK(Tank)); ERRCODE(MEMCHECK(Pump)); ERRCODE(MEMCHECK(Valve)); ERRCODE(MEMCHECK(Control)); ERRCODE(MEMCHECK(Pattern)); ERRCODE(MEMCHECK(Curve)); + ERRCODE(MEMCHECK(Coord)); } /* Initialize pointers used in patterns, curves, and demand category lists */ @@ -2836,7 +2862,19 @@ int allocdata() Curve[n].X = NULL; Curve[n].Y = NULL; } - for (n=0; n<=MaxNodes; n++) Node[n].D = NULL; + + for (n=0; n<=MaxNodes; n++) + { + // node demand + Node[n].D = NULL; + /* Allocate memory for coord data */ + Coord[n].X = (double *) calloc(1, sizeof(double)); + Coord[n].Y = (double *) calloc(1, sizeof(double)); + if (Coord[n].X == NULL || Coord[n].Y == NULL) return(101); + Coord[n].X[0] = 0; + Coord[n].Y[0] = 0; + } + } /* Allocate memory for rule base (see RULES.C) */ diff --git a/src/funcs.h b/src/funcs.h index 1fa5677..c7907f8 100755 --- a/src/funcs.h +++ b/src/funcs.h @@ -61,11 +61,13 @@ int addnodeID(int, char *); /* Adds node ID to data base */ int addlinkID(int, char *); /* Adds link ID to data base */ int addpattern(char *); /* Adds pattern to data base */ int addcurve(char *); /* Adds curve to data base */ +int addcoord(char *); /* Adds coord to data base */ STmplist *findID(char *, STmplist *); /* Locates ID on linked list */ int unlinked(void); /* Checks for unlinked nodes */ int getpumpparams(void); /* Computes pump curve coeffs.*/ int getpatterns(void); /* Gets pattern data from list*/ int getcurves(void); /* Gets curve data from list */ +int getcoords(void); /* Gets coordinate data from list */ int findmatch(char *,char *[]); /* Finds keyword in line */ int match(char *, char *); /* Checks for word match */ int gettokens(char *); /* Tokenizes input line */ @@ -82,6 +84,7 @@ int pumpdata(void); /* Processes pump data */ int valvedata(void); /* Processes valve data */ int patterndata(void); /* Processes pattern data */ int curvedata(void); /* Processes curve data */ +int coordata(void); /* Processes coordinate data */ int demanddata(void); /* Processes demand data */ int controldata(void); /* Processes simple controls */ int energydata(void); /* Processes energy data */ diff --git a/src/input2.c b/src/input2.c index a0fa344..1c8b873 100755 --- a/src/input2.c +++ b/src/input2.c @@ -48,6 +48,7 @@ char *Tok[MAXTOKS]; /* Array of token strings */ /* Used in INPUT3.C: */ STmplist *PrevPat; /* Pointer to pattern list element */ STmplist *PrevCurve; /* Pointer to curve list element */ +STmplist *PrevCoord; /* Pointer to coordinate list element */ /* Defined in enumstxt.h in EPANET.C */ extern char *SectTxt[]; /* Input section keywords */ @@ -78,7 +79,8 @@ int netsize() MaxRules = 0; MaxCurves = 0; sect = -1; - + MaxCoords = 0; + /* Add a default pattern 0 */ MaxPats = -1; addpattern(""); @@ -106,20 +108,22 @@ int netsize() /* Add to count of current component */ switch(sect) - { - case _JUNCTIONS: MaxJuncs++; break; - case _RESERVOIRS: - case _TANKS: MaxTanks++; break; - case _PIPES: MaxPipes++; break; - case _PUMPS: MaxPumps++; break; - case _VALVES: MaxValves++; break; - case _CONTROLS: MaxControls++; break; - case _RULES: addrule(tok); break; /* See RULES.C */ - case _PATTERNS: errcode = addpattern(tok); - break; - case _CURVES: errcode = addcurve(tok); - break; - } + { + case _JUNCTIONS: MaxJuncs++; break; + case _RESERVOIRS: + case _TANKS: MaxTanks++; break; + case _PIPES: MaxPipes++; break; + case _PUMPS: MaxPumps++; break; + case _VALVES: MaxValves++; break; + case _CONTROLS: MaxControls++; break; + case _RULES: addrule(tok); break; /* See RULES.C */ + case _PATTERNS: errcode = addpattern(tok); + break; + case _CURVES: errcode = addcurve(tok); + break; + case _COORDS: errcode = addcoord(tok); //06.02.2010-woohn + break; + } if (errcode) break; } @@ -172,6 +176,8 @@ int readdata() Npats = MaxPats; PrevPat = NULL; PrevCurve = NULL; + PrevCoord = NULL; + sect = -1; errsum = 0; @@ -239,6 +245,7 @@ int readdata() /* Get pattern & curve data from temp. lists */ if (!errcode) errcode = getpatterns(); if (!errcode) errcode = getcurves(); + if (!errcode) errcode = getcoords(); if (!errcode) errcode = getpumpparams(); /* Free input buffer */ @@ -293,7 +300,7 @@ int newline(int sect, char *line) case _OPTIONS: return(optiondata()); /* Data in these sections are not used for any computations */ - case _COORDS: return(0); + case _COORDS: return(coordata()); case _LABELS: return(0); case _TAGS: return(0); case _VERTICES: return(0); @@ -513,6 +520,42 @@ int addcurve(char *id) return(0); } +int addcoord(char *id) +/* + **------------------------------------------------------------- + ** Input: id = curve ID label + ** Output: returns error code + ** Purpose: adds a new curve to the database + **-------------------------------------------------------------- + */ +{ + STmplist *c; + + /* Check if ID is same as last one processed */ + if (Coordlist != NULL && strcmp(id,Coordlist->ID) == 0) return(0); + + /* Check that coordinate was not already created */ + if (findID(id,Coordlist) == NULL) + { + + /* Update coordinate count & create new list element */ + (MaxCoords)++; + c = (STmplist *) malloc(sizeof(STmplist)); + if (c == NULL) { + return(101); + } + else { + /* Initialize list element properties */ + c->i = MaxCoords; + strncpy(c->ID,id,MAXID); + c->x = NULL; + c->y = NULL; + c->next = Coordlist; + Coordlist = c; + } + } + return(0); +} STmplist *findID(char *id, STmplist *list) /* @@ -705,6 +748,64 @@ int getcurves(void) return(0); } +int getcoords(void) +/* + **----------------------------------------------------------- + ** Input: none + ** Output: returns error code + ** Purpose: retrieves curve data from temporary linked list + **----------------------------------------------------------- + */ +{ + int i,j,n; + double x; + SFloatlist *xFloatList, *yFloatList; + STmplist *coordinateList; + + /* Start at head of coordinate list */ + coordinateList = Coordlist; + + /* Traverse list of coordinates */ + while (coordinateList != NULL) + { + i = coordinateList->i; + if (i >= 1 && i <= MaxNodes) + { + /* Save coordinate ID */ + strcpy(Coord[i].ID, coordinateList->ID); + + n = 1; //Coord[i].Npts + + /* Traverse list of x,y data */ + x = BIG; + xFloatList = coordinateList->x; + yFloatList = coordinateList->y; + j = n - 1; + while (xFloatList != NULL && yFloatList != NULL && j >= 0) + { + + /* Check that x data is in ascending order */ + if (xFloatList->value >= x) + { + sprintf(Msg,ERR230,coordinateList->ID); + writeline(Msg); + return(200); + } + x = xFloatList->value; + + /* Save x,y data in Curve structure */ + Coord[i].X[j] = xFloatList->value; + xFloatList = xFloatList->next; + Coord[i].Y[j] = yFloatList->value; + yFloatList = yFloatList->next; + j--; + } + } + coordinateList = coordinateList->next; + } + return(0); +} + int findmatch(char *line, char *keyword[]) /* diff --git a/src/input3.c b/src/input3.c index 0d72c37..a19bfdc 100755 --- a/src/input3.c +++ b/src/input3.c @@ -42,6 +42,8 @@ extern char *Fldname[]; extern char *Tok[MAXTOKS]; extern STmplist *PrevPat; extern STmplist *PrevCurve; + +extern STmplist *PrevCoord; extern int Ntokens; @@ -577,6 +579,59 @@ int curvedata() return(0); } +int coordata() +/* + **-------------------------------------------------------------- + ** Input: none + ** Output: returns error code + ** Purpose: processes coordinate data + ** Format: + ** [COORD] + ** id x y + **-------------------------------------------------------------- + */ +{ + double x,y; + SFloatlist *fx, *fy; + STmplist *c; + + /* Check for valid curve ID */ + if (Ntokens < 3) return(201); + + if ( + PrevCoord != NULL && + strcmp(Tok[0],PrevCoord->ID) == 0 + ) c = PrevCoord; + else c = findID(Tok[0],Coordlist); + + // c = findID(Tok[0],Coordlist); + if (c == NULL) return(205); + + /* Check for valid data */ + if (!getfloat(Tok[1],&x)) return(202); + if (!getfloat(Tok[2],&y)) return(202); + + /* Add new data point to curve's linked list */ + fx = (SFloatlist *) malloc(sizeof(SFloatlist)); + fy = (SFloatlist *) malloc(sizeof(SFloatlist)); + if (fx == NULL || fy == NULL) return(101); + fx->value = x; + fx->next = c->x; + c->x = fx; + fy->value = y; + fy->next = c->y; + c->y = fy; + //Curve[c->i].Npts++; + + /* Save the pointer to this curve */ + PrevCoord = c; + return(0); + + /* Save coordn data */ + //Coord[Njuncs].X = x; + //Coord[Njuncs].Y = y; + +} /* end of coordata */ int demanddata() /* diff --git a/src/toolkit.h b/src/toolkit.h index 814fc39..b2fa8a7 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -224,6 +224,7 @@ extern "C" { int DLLEXPORT ENgetnodeid(int, char *); int DLLEXPORT ENgetnodetype(int, int *); int DLLEXPORT ENgetnodevalue(int, int, EN_API_FLOAT_TYPE *); + int DLLEXPORT ENgetcoord(int , EN_API_FLOAT_TYPE *, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgetnumdemands(int, int *); int DLLEXPORT ENgetbasedemand(int, int, EN_API_FLOAT_TYPE *); diff --git a/src/types.h b/src/types.h index bc135aa..becf1b2 100755 --- a/src/types.h +++ b/src/types.h @@ -167,6 +167,13 @@ typedef struct /* CURVE OBJECT */ double *Y; /* Y-values */ } Scurve; +typedef struct /* Coord OBJECT */ +{ + char ID[MAXID+1]; /* Coord ID */ + double *X; /* X-values */ + double *Y; /* Y-values */ +} Scoord; + struct Sdemand /* DEMAND CATEGORY OBJECT */ { double Base; /* Baseline demand */ diff --git a/src/vars.h b/src/vars.h index 6ca5be4..99273e3 100755 --- a/src/vars.h +++ b/src/vars.h @@ -76,6 +76,7 @@ EXTERN int MaxNodes, /* Node count from input file */ MaxRules, /* Rule count */ MaxPats, /* Pattern count */ MaxCurves, /* Curve count */ + MaxCoords, /* Coords count */ Nnodes, /* Number of network nodes */ Ntanks, /* Number of tanks */ Njuncs, /* Number of junction nodes */ @@ -87,6 +88,7 @@ EXTERN int MaxNodes, /* Node count from input file */ Nrules, /* Number of control rules */ Npats, /* Number of time patterns */ Ncurves, /* Number of data curves */ + Ncoords, /* Number of Coords */ Nperiods, /* Number of reporting periods */ Ncoeffs, /* Number of non-0 matrix coeffs*/ DefPat, /* Default demand pattern */ @@ -157,8 +159,10 @@ EXTERN double *QTankVolumes; EXTERN double *QLinkFlow; EXTERN STmplist *Patlist; /* Temporary time pattern list */ EXTERN STmplist *Curvelist; /* Temporary list of curves */ +EXTERN STmplist *Coordlist; /* Temporary list of coordinates*/ EXTERN Spattern *Pattern; /* Time patterns */ EXTERN Scurve *Curve; /* Curve data */ +EXTERN Scoord *Coord; /* Coordinate data */ EXTERN Snode *Node; /* Node data */ EXTERN Slink *Link; /* Link data */ EXTERN Stank *Tank; /* Tank data */