Merge remote-tracking branch 'upstream/dev' into dev-swig-redux

This commit is contained in:
Michael Tryby
2019-01-28 10:41:23 -05:00
61 changed files with 35539 additions and 3263 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -7,10 +7,15 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/29/2018
Last Updated: 01/09/2019
******************************************************************************
*/
#ifndef __APPLE__
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#include <string.h>
#include "types.h"
#include "funcs.h"
@@ -46,13 +51,13 @@ void removetmpfiles()
********************************************************************/
int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
void (*pviewprog)(char *))
int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile,
const char *outFile, void (*pviewprog)(char *))
{
/*------------------------------------------------------------------------
** Input: f1 = name of EPANET formatted input file
** f2 = name of report file
** f3 = name of binary output file
** Input: inpFile = name of EPANET formatted input file
** rptFile = name of report file
** outFile = name of binary output file
** pviewprog = see note below
** Output: none
** Returns: error code
@@ -71,7 +76,7 @@ int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
// Run the project and record any warning
createtmpfiles();
errcode = EN_runproject(_defaultProject, f1, f2, f3, pviewprog);
errcode = EN_runproject(_defaultProject, inpFile, rptFile, outFile, pviewprog);
if (errcode < 100) warncode = errcode;
removetmpfiles();
@@ -80,20 +85,20 @@ int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3,
return errcode;
}
int DLLEXPORT ENinit(const char *f2, const char *f3, int UnitsType,
int HeadlossFormula)
int DLLEXPORT ENinit(const char *rptFile, const char *outFile, int unitsType,
int headlossType)
{
int errcode = 0;
createtmpfiles();
errcode = EN_init(_defaultProject, f2, f3, UnitsType, HeadlossFormula);
errcode = EN_init(_defaultProject, rptFile, outFile, unitsType, headlossType);
return errcode;
}
int DLLEXPORT ENopen(const char *f1, const char *f2, const char *f3)
int DLLEXPORT ENopen(const char *inpFile, const char *rptFile, const char *outFile)
{
int errcode = 0;
createtmpfiles();
errcode = EN_open(_defaultProject, f1, f2, f3);
errcode = EN_open(_defaultProject, inpFile, rptFile, outFile);
return errcode;
}
@@ -121,11 +126,11 @@ int DLLEXPORT ENsaveH() { return EN_saveH(_defaultProject); }
int DLLEXPORT ENopenH() { return EN_openH(_defaultProject); }
int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultProject, flag); }
int DLLEXPORT ENinitH(int initFlag) { return EN_initH(_defaultProject, initFlag); }
int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultProject, t); }
int DLLEXPORT ENrunH(long *currentTime) { return EN_runH(_defaultProject, currentTime); }
int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultProject, tstep); }
int DLLEXPORT ENnextH(long *tStep) { return EN_nextH(_defaultProject, tStep); }
int DLLEXPORT ENcloseH() { return EN_closeH(_defaultProject); }
@@ -149,13 +154,13 @@ int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultProject); }
int DLLEXPORT ENopenQ() { return EN_openQ(_defaultProject); }
int DLLEXPORT ENinitQ(int saveflag) { return EN_initQ(_defaultProject, saveflag); }
int DLLEXPORT ENinitQ(int saveFlag) { return EN_initQ(_defaultProject, saveFlag); }
int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultProject, t); }
int DLLEXPORT ENrunQ(long *currentTime) { return EN_runQ(_defaultProject, currentTime); }
int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultProject, tstep); }
int DLLEXPORT ENnextQ(long *tStep) { return EN_nextQ(_defaultProject, tStep); }
int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultProject, tleft); }
int DLLEXPORT ENstepQ(long *timeLeft) { return EN_stepQ(_defaultProject, timeLeft); }
int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultProject); }
@@ -171,28 +176,31 @@ int DLLEXPORT ENreport() { return EN_report(_defaultProject); }
int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultProject); }
int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultProject, s); }
int DLLEXPORT ENsetreport(char *format) { return EN_setreport(_defaultProject, format); }
int DLLEXPORT ENsetstatusreport(int code)
int DLLEXPORT ENsetstatusreport(int level)
{
return EN_setstatusreport(_defaultProject, code);
return EN_setstatusreport(_defaultProject, level);
}
int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); }
int DLLEXPORT ENgetversion(int *version) { return EN_getversion(version); }
int DLLEXPORT ENgetcount(int code, int *count)
int DLLEXPORT ENgetcount(int object, int *count)
{
return EN_getcount(_defaultProject, (EN_CountType)code, count);
return EN_getcount(_defaultProject, object, count);
}
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n)
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen)
{
return EN_geterror(errcode, errmsg, n);
return EN_geterror(errcode, errmsg, maxLen);
}
int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetstatistic(int type, EN_API_FLOAT_TYPE *value)
{
return EN_getstatistic(_defaultProject, code, value);
double v = 0.0;
int errcode = EN_getstatistic(_defaultProject, type, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
/********************************************************************
@@ -201,45 +209,54 @@ int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value)
********************************************************************/
int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetoption(int option, EN_API_FLOAT_TYPE *value)
{
return EN_getoption(_defaultProject, (EN_Option)code, value);
double v = 0.0;
int errcode = EN_getoption(_defaultProject, option, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v)
int DLLEXPORT ENsetoption(int option, EN_API_FLOAT_TYPE value)
{
return EN_setoption(_defaultProject, code, v);
return EN_setoption(_defaultProject, option, value);
}
int DLLEXPORT ENgetflowunits(int *code) { return EN_getflowunits(_defaultProject, code); }
int DLLEXPORT ENsetflowunits(int code) { return EN_setflowunits(_defaultProject, code); }
int DLLEXPORT ENgettimeparam(int code, long *value)
int DLLEXPORT ENgetflowunits(int *units)
{
return EN_gettimeparam(_defaultProject, code, value);
return EN_getflowunits(_defaultProject, units);
}
int DLLEXPORT ENsettimeparam(int code, long value)
int DLLEXPORT ENsetflowunits(int units)
{
return EN_settimeparam(_defaultProject, code, value);
return EN_setflowunits(_defaultProject, units);
}
int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits,
int *tracenode)
int DLLEXPORT ENgettimeparam(int param, long *value)
{
return EN_getqualinfo(_defaultProject, qualcode, chemname, chemunits, tracenode);
return EN_gettimeparam(_defaultProject, param, value);
}
int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode)
int DLLEXPORT ENsettimeparam(int param, long value)
{
return EN_getqualtype(_defaultProject, qualcode, tracenode);
return EN_settimeparam(_defaultProject, param, value);
}
int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits,
char *tracenode)
int DLLEXPORT ENgetqualinfo(int *qualType, char *chemName, char *chemUnits,
int *traceNode)
{
return EN_setqualtype(_defaultProject, qualcode, chemname, chemunits, tracenode);
return EN_getqualinfo(_defaultProject, qualType, chemName, chemUnits, traceNode);
}
int DLLEXPORT ENgetqualtype(int *qualType, int *traceNode)
{
return EN_getqualtype(_defaultProject, qualType, traceNode);
}
int DLLEXPORT ENsetqualtype(int qualType, char *chemName, char *chemUnits,
char *traceNode)
{
return EN_setqualtype(_defaultProject, qualType, chemName, chemUnits, traceNode);
}
/********************************************************************
@@ -248,7 +265,7 @@ int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits,
********************************************************************/
int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType)
int DLLEXPORT ENaddnode(char *id, int nodeType)
{
return EN_addnode(_defaultProject, id, nodeType);
}
@@ -273,24 +290,46 @@ int DLLEXPORT ENsetnodeid(int index, char *newid)
return EN_setnodeid(_defaultProject, index, newid);
}
int DLLEXPORT ENgetnodetype(int index, int *code)
int DLLEXPORT ENgetnodetype(int index, int *nodeType)
{
return EN_getnodetype(_defaultProject, index, code);
return EN_getnodetype(_defaultProject, index, nodeType);
}
int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetnodevalue(int index, int property, EN_API_FLOAT_TYPE *value)
{
return EN_getnodevalue(_defaultProject, index, code, value);
double v = 0.0;
int errcode = EN_getnodevalue(_defaultProject, index, property, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v)
int DLLEXPORT ENsetnodevalue(int index, int property, EN_API_FLOAT_TYPE value)
{
return EN_setnodevalue(_defaultProject, index, code, v);
return EN_setnodevalue(_defaultProject, index, property, value);
}
int DLLEXPORT ENsetjuncdata(int index, EN_API_FLOAT_TYPE elev, EN_API_FLOAT_TYPE dmnd,
char *dmndpat)
{
return EN_setjuncdata(_defaultProject, index, elev, dmnd, dmndpat);
}
int DLLEXPORT ENsettankdata(int index, EN_API_FLOAT_TYPE elev,
EN_API_FLOAT_TYPE initlvl, EN_API_FLOAT_TYPE minlvl,
EN_API_FLOAT_TYPE maxlvl, EN_API_FLOAT_TYPE diam,
EN_API_FLOAT_TYPE minvol, char *volcurve)
{
return EN_settankdata(_defaultProject, index, elev, initlvl, minlvl, maxlvl,
diam, minvol, volcurve);
}
int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
{
return EN_getcoord(_defaultProject, index, x, y);
double xx = 0.0, yy = 0.0;
int errcode = EN_getcoord(_defaultProject, index, &xx, &yy);
*x = (EN_API_FLOAT_TYPE)xx;
*y = (EN_API_FLOAT_TYPE)yy;
return errcode;
}
int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
@@ -304,16 +343,21 @@ int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
********************************************************************/
int DLLEXPORT ENgetdemandmodel(int *type, EN_API_FLOAT_TYPE *pmin,
EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp)
int DLLEXPORT ENgetdemandmodel(int *model, EN_API_FLOAT_TYPE *pmin,
EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp)
{
return EN_getdemandmodel(_defaultProject, type, pmin, preq, pexp);
double pmin2 = 0.0, preq2 = 0.0, pexp2 = 0.0;
int errcode = EN_getdemandmodel(_defaultProject, model, &pmin2, &preq2, &pexp2);
*pmin = (EN_API_FLOAT_TYPE)pmin2;
*preq = (EN_API_FLOAT_TYPE)preq2;
*pexp = (EN_API_FLOAT_TYPE)pexp2;
return errcode;
}
int DLLEXPORT ENsetdemandmodel(int type, EN_API_FLOAT_TYPE pmin,
EN_API_FLOAT_TYPE preq, EN_API_FLOAT_TYPE pexp)
int DLLEXPORT ENsetdemandmodel(int model, EN_API_FLOAT_TYPE pmin,
EN_API_FLOAT_TYPE preq, EN_API_FLOAT_TYPE pexp)
{
return EN_setdemandmodel(_defaultProject, type, pmin, preq, pexp);
return EN_setdemandmodel(_defaultProject, model, pmin, preq, pexp);
}
int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
@@ -321,34 +365,39 @@ int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
return EN_getnumdemands(_defaultProject, nodeIndex, numDemands);
}
int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand)
int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex,
EN_API_FLOAT_TYPE *baseDemand)
{
return EN_getbasedemand(_defaultProject, nodeIndex, demandIdx, baseDemand);
double bd2 = 0.0;
int errcode = EN_getbasedemand(_defaultProject, nodeIndex, demandIndex, &bd2);
*baseDemand = (EN_API_FLOAT_TYPE)bd2;
return errcode;
}
int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand)
int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIndex,
EN_API_FLOAT_TYPE baseDemand)
{
return EN_setbasedemand(_defaultProject, nodeIndex, demandIdx, baseDemand);
return EN_setbasedemand(_defaultProject, nodeIndex, demandIndex, baseDemand);
}
int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIdx, int patIndex)
int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIndex, int patIndex)
{
return EN_setdemandpattern(_defaultProject, nodeIndex, demandIdx, patIndex);
return EN_setdemandpattern(_defaultProject, nodeIndex, demandIndex, patIndex);
}
int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx)
int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIdx)
{
return EN_getdemandpattern(_defaultProject, nodeIndex, demandIdx, pattIdx);
return EN_getdemandpattern(_defaultProject, nodeIndex, demandIndex, pattIdx);
}
int DLLEXPORT ENgetdemandname(int nodeIndex, int demandIdx, char *demandName)
int DLLEXPORT ENgetdemandname(int nodeIndex, int demandIndex, char *demandName)
{
return EN_getdemandname(_defaultProject, nodeIndex, demandIdx, demandName);
return EN_getdemandname(_defaultProject, nodeIndex, demandIndex, demandName);
}
int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIdx, char *demandName)
int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIndex, char *demandName)
{
return EN_setdemandname(_defaultProject, nodeIndex, demandIdx, demandName);
return EN_setdemandname(_defaultProject, nodeIndex, demandIndex, demandName);
}
/********************************************************************
@@ -357,7 +406,7 @@ int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIdx, char *demandName)
********************************************************************/
int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode)
int DLLEXPORT ENaddlink(char *id, int linkType, char *fromNode, char *toNode)
{
return EN_addlink(_defaultProject, id, linkType, fromNode, toNode);
}
@@ -382,14 +431,14 @@ int DLLEXPORT ENsetlinkid(int index, char *newid)
return EN_setlinkid(_defaultProject, index, newid);
}
int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code)
int DLLEXPORT ENgetlinktype(int index, int *linkType)
{
return EN_getlinktype(_defaultProject, index, code);
return EN_getlinktype(_defaultProject, index, linkType);
}
int DLLEXPORT ENsetlinktype(int *index, EN_LinkType type, int actionCode)
int DLLEXPORT ENsetlinktype(int *index, int linkType, int actionCode)
{
return EN_setlinktype(_defaultProject, index, type, actionCode);
return EN_setlinktype(_defaultProject, index, linkType, actionCode);
}
int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2)
@@ -402,35 +451,45 @@ int DLLEXPORT ENsetlinknodes(int index, int node1, int node2)
return EN_setlinknodes(_defaultProject, index, node1, node2);
}
int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetlinkvalue(int index, int property, EN_API_FLOAT_TYPE *value)
{
return EN_getlinkvalue(_defaultProject, index, (EN_LinkProperty)code, value);
double v = 0.0;
int errcode = EN_getlinkvalue(_defaultProject, index, property, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v)
int DLLEXPORT ENsetlinkvalue(int index, int property, EN_API_FLOAT_TYPE value)
{
return EN_setlinkvalue(_defaultProject, index, code, v);
return EN_setlinkvalue(_defaultProject, index, property, value);
}
int DLLEXPORT ENsetpipedata(int index, EN_API_FLOAT_TYPE length,
EN_API_FLOAT_TYPE diam, EN_API_FLOAT_TYPE rough, EN_API_FLOAT_TYPE mloss)
{
return EN_setpipedata(_defaultProject, index, length, diam, rough, mloss);
}
/********************************************************************
Pump Functions
********************************************************************/
int DLLEXPORT ENgetpumptype(int index, int *type)
int DLLEXPORT ENgetpumptype(int linkIndex, int *pumpType)
{
return EN_getpumptype(_defaultProject, index, type);
return EN_getpumptype(_defaultProject, linkIndex, pumpType);
}
int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex)
int DLLEXPORT ENgetheadcurveindex(int linkIndex, int *curveIndex)
{
return EN_getheadcurveindex(_defaultProject, index, curveindex);
return EN_getheadcurveindex(_defaultProject, linkIndex, curveIndex);
}
int DLLEXPORT ENsetheadcurveindex(int index, int curveindex)
int DLLEXPORT ENsetheadcurveindex(int linkIndex, int curveIndex)
{
return EN_setheadcurveindex(_defaultProject, index, curveindex);
return EN_setheadcurveindex(_defaultProject, linkIndex, curveIndex);
}
/********************************************************************
@@ -461,7 +520,10 @@ int DLLEXPORT ENgetpatternlen(int index, int *len)
int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value)
{
return EN_getpatternvalue(_defaultProject, index, period, value);
double v = 0.0;
int errcode = EN_getpatternvalue(_defaultProject, index, period, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
@@ -471,12 +533,25 @@ int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value)
{
return EN_getaveragepatternvalue(_defaultProject, index, value);
double v;
int errcode = EN_getaveragepatternvalue(_defaultProject, index, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n)
int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *values, int len)
{
return EN_setpattern(_defaultProject, index, f, n);
double *v = NULL;
int i, errcode;
v = (double *)calloc(len, sizeof(double));
if (v)
{
for (i = 0; i < len; i++) v[i] = values[i];
errcode = EN_setpattern(_defaultProject, index, v, len);
}
else errcode = 101;
free(v);
return errcode;
}
/********************************************************************
@@ -505,32 +580,67 @@ int DLLEXPORT ENgetcurvelen(int index, int *len)
return EN_getcurvelen(_defaultProject, index, len);
}
int DLLEXPORT ENgetcurvetype(int curveindex, int *type)
int DLLEXPORT ENgetcurvetype(int index, int *type)
{
return EN_getcurvetype(_defaultProject, curveindex, type);
return EN_getcurvetype(_defaultProject, index, type);
}
int DLLEXPORT ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y)
int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y)
{
return EN_getcurvevalue(_defaultProject, index, pnt, x, y);
double xx = 0.0, yy = 0.0;
int errcode = EN_getcurvevalue(_defaultProject, curveIndex, pointIndex, &xx, &yy);
*x = (EN_API_FLOAT_TYPE)xx;
*y = (EN_API_FLOAT_TYPE)yy;
return errcode;
}
int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x,
EN_API_FLOAT_TYPE y)
int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x,
EN_API_FLOAT_TYPE y)
{
return EN_setcurvevalue(_defaultProject, index, pnt, x, y);
return EN_setcurvevalue(_defaultProject, curveIndex, pointIndex, x, y);
}
int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues,
EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
int DLLEXPORT ENgetcurve(int index, char *id, int *nPoints,
EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
{
return EN_getcurve(_defaultProject, curveIndex, id, nValues, xValues, yValues);
int i;
Network *net = &_defaultProject->network;
Scurve *curve;
if (index <= 0 || index > net->Ncurves) return 206;
curve = &net->Curve[index];
strncpy(id, curve->ID, MAXID);
*nPoints = curve->Npts;
for (i = 0; i < curve->Npts; i++)
{
*xValues[i] = (EN_API_FLOAT_TYPE)curve->X[i];
*yValues[i] = (EN_API_FLOAT_TYPE)curve->Y[i];
}
return 0;
}
int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n)
int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *xValues,
EN_API_FLOAT_TYPE *yValues, int nPoints)
{
return EN_setcurve(_defaultProject, index, x, y, n);
double *xx = NULL;
double *yy = NULL;
int i, errcode;
xx = (double *)calloc(nPoints, sizeof(double));
yy = (double *)calloc(nPoints, sizeof(double));
if (xx && yy)
{
for (i = 0; i < nPoints; i++)
{
xx[i] = xValues[i];
yy[i] = yValues[i];
}
errcode = EN_setcurve(_defaultProject, index, xx, yy, nPoints);
}
else errcode = 101;
free(xx);
free(yy);
return errcode;
}
/********************************************************************
@@ -539,27 +649,34 @@ int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y,
********************************************************************/
int DLLEXPORT ENaddcontrol(int *cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting,
int nindex, EN_API_FLOAT_TYPE level)
int DLLEXPORT ENaddcontrol(int type, int linkIndex, EN_API_FLOAT_TYPE setting,
int nodeIndex, EN_API_FLOAT_TYPE level, int *index)
{
return EN_addcontrol(_defaultProject, cindex, ctype, lindex, setting, nindex, level);
return EN_addcontrol(_defaultProject, type, linkIndex, setting, nodeIndex,
level, index);
}
int DLLEXPORT ENdeletecontrol(int cindex)
int DLLEXPORT ENdeletecontrol(int index)
{
return EN_deletecontrol(_defaultProject, cindex);
return EN_deletecontrol(_defaultProject, index);
}
int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, EN_API_FLOAT_TYPE *setting,
int *nindex, EN_API_FLOAT_TYPE *level)
int DLLEXPORT ENgetcontrol(int index, int *type, int *linkIndex,
EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level)
{
return EN_getcontrol(_defaultProject, cindex, ctype, lindex, setting, nindex, level);
double setting2 = 0.0, level2 = 0.0;
int errcode = EN_getcontrol(_defaultProject, index, type, linkIndex, &setting2,
nodeIndex, &level2);
*setting = (EN_API_FLOAT_TYPE)setting2;
*level = (EN_API_FLOAT_TYPE)level2;
return errcode;
}
int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting,
int nindex, EN_API_FLOAT_TYPE level)
int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex,
EN_API_FLOAT_TYPE setting, int nodeIndex, EN_API_FLOAT_TYPE level)
{
return EN_setcontrol(_defaultProject, cindex, ctype, lindex, setting, nindex, level);
return EN_setcontrol(_defaultProject, index, type, linkIndex, setting,
nodeIndex, level);
}
/********************************************************************
@@ -578,10 +695,14 @@ int DLLEXPORT ENdeleterule(int index)
return EN_deleterule(_defaultProject, index);
}
int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions, int *nElseActions,
EN_API_FLOAT_TYPE *priority)
int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions,
int *nElseActions, EN_API_FLOAT_TYPE *priority)
{
return EN_getrule(_defaultProject, index, nPremises, nThenActions, nElseActions, priority);
double priority2 = 0.0;
int errcode = EN_getrule(_defaultProject, index, nPremises, nThenActions,
nElseActions, &priority2);
*priority = (EN_API_FLOAT_TYPE)priority2;
return errcode;
}
int DLLEXPORT ENgetruleID(int index, char* id)
@@ -589,17 +710,19 @@ int DLLEXPORT ENgetruleID(int index, char* id)
return EN_getruleID(_defaultProject, index, id);
}
int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop,
int *object, int *objIndex, int *variable,
int *relop, int *status, EN_API_FLOAT_TYPE *value)
int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop, int *object,
int *objIndex, int *variable, int *relop, int *status,
EN_API_FLOAT_TYPE *value)
{
return EN_getpremise(_defaultProject, ruleIndex, premiseIndex, logop, object,
objIndex, variable, relop, status, value);
double v = 0.0;
int errcode = EN_getpremise(_defaultProject, ruleIndex, premiseIndex, logop,
object, objIndex, variable, relop, status, &v);
*value = (EN_API_FLOAT_TYPE)v;
return errcode;
}
int DLLEXPORT ENsetpremise(int ruleIndex, int premiseIndex, int logop,
int object, int objIndex, int variable, int relop,
int status, EN_API_FLOAT_TYPE value)
int DLLEXPORT ENsetpremise(int ruleIndex, int premiseIndex, int logop, int object,
int objIndex, int variable, int relop, int status, EN_API_FLOAT_TYPE value)
{
return EN_setpremise(_defaultProject, ruleIndex, premiseIndex, logop, object,
objIndex, variable, relop, status, value);
@@ -621,28 +744,34 @@ int DLLEXPORT ENsetpremisevalue(int ruleIndex, int premiseIndex, EN_API_FLOAT_TY
}
int DLLEXPORT ENgetthenaction(int ruleIndex, int actionIndex, int *linkIndex,
int *status, EN_API_FLOAT_TYPE *setting)
int *status, EN_API_FLOAT_TYPE *setting)
{
return EN_getthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);
double setting2 = 0.0;
int errcode = EN_getthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, &setting2);
*setting = (EN_API_FLOAT_TYPE)setting2;
return errcode;
}
int DLLEXPORT ENsetthenaction(int ruleIndex, int actionIndex, int linkIndex,
int status, EN_API_FLOAT_TYPE setting)
int status, EN_API_FLOAT_TYPE setting)
{
return EN_setthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);
}
int DLLEXPORT ENgetelseaction(int ruleIndex, int actionIndex, int *linkIndex,
int *status, EN_API_FLOAT_TYPE *setting)
int *status, EN_API_FLOAT_TYPE *setting)
{
return EN_getelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);
double setting2 = 0.0;
int errcode = EN_getelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, &setting2);
*setting = (EN_API_FLOAT_TYPE)setting2;
return errcode;
}
int DLLEXPORT ENsetelseaction(int ruleIndex, int actionIndex, int linkIndex,
int status, EN_API_FLOAT_TYPE setting)
int status, EN_API_FLOAT_TYPE setting)
{
return EN_setelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
status, setting);

View File

@@ -1,76 +1,69 @@
//EPANET 2 Error Messages
DAT(0,"ok")
DAT(101,"insufficient memory available")
DAT(102,"no network data available")
DAT(103,"hydraulic solver not opened")
DAT(104,"no hydraulics for water quality analysis")
DAT(105,"water quality solver not opened")
DAT(106,"no results saved to report on")
DAT(107,"hydraulics supplied from external file")
DAT(108,"cannot use external file while hydraulics solver is active")
DAT(110,"cannot solve network hydraulic equations")
DAT(120,"cannot solve water quality transport equations")
DAT(0,EN_OK,"ok")
DAT(101,ENERR_INSUF_MEM,"insufficient memory available")
DAT(102,ENERR_NO_NET_DATA,"no network data available")
DAT(103,ENERR_HYD_NOT_INIT,"hydraulics not initialized")
DAT(104,ENERR_NO_HYD,"no hydraulics for water quality analysis")
DAT(105,ENERR_WQ_NOT_INIT,"water quality not initialized")
DAT(106,ENERR_NO_RESULT,"no results saved to report on")
DAT(107,ENERR_HYD_EXT_FILE,"hydraulics supplied from external file")
DAT(108,ENERR_CANT_USE_EXT_FILE,"cannot use external file while hydraulics solver is active")
DAT(109,ENERR_CANT_CHANGE_TIME_PARAM,"cannot change time parameter when solver is active")
DAT(110,ENERR_CANT_SOLVE_HYD,"cannot solve network hydraulic equations")
DAT(120,ENERR_CANT_SOLVE_WQ,"cannot solve water quality transport equations")
// These errors apply only to an input file
DAT(200,"one or more errors in input file")
DAT(201,"syntax error")
DAT(200,ENERR_INP_ERR,"one or more errors in input file")
DAT(201,ENERR_SYNTAX_LINE,"syntax error in following line of section")
DAT(202,ENERR_ILLEGAL_NUM,"function call contains illegal numeric value")
DAT(203,ENERR_UNDEF_NODE,"function call refers to undefined node")
DAT(204,ENERR_UNDEF_LINK,"function call refers to undefined link")
DAT(205,ENERR_UNDEF_PAT,"function call refers to undefined time pattern")
DAT(206,ENERR_UNDEF_CURVE,"function call refers to undefined curve")
DAT(207,ENERR_CANT_CONTROL_CV,"function call attempts to control a CV")
// These errors apply to both an input file and to API functions
DAT(202,"illegal numeric value")
DAT(203,"undefined node")
DAT(204,"undefined link")
DAT(205,"undefined time pattern")
DAT(206,"undefined curve")
DAT(207,"attempt to control CV/GPV link")
DAT(209,"illegal node property value")
DAT(211,"illegal link property value")
DAT(212,"undefined trace node")
DAT(213,"invalid option value")
DAT(214,"too many characters in input line")
DAT(215,"duplicate ID label")
DAT(216,"reference to undefined pump")
DAT(217,"invalid pump energy data")
DAT(219,"illegal valve connection to tank node")
DAT(220,"illegal valve connection to another valve")
DAT(221,"mis-placed rule clause in rule-based control")
DAT(222,"same start and end nodes for link")
DAT(208,ENERR_SPEC_UNDEF_NODE,"undefined Node")
DAT(209,ENERR_ILLEGAL_VAL_NODE,"illegal value for Node")
DAT(210,ENERR_SPEC_UNDEF_LINK,"specified for undefined Link")
DAT(211,ENERR_ILLEGAL_VAL_LINK,"illegal value for Link")
DAT(212,ENERR_TRACE_NODE,"invalid trace node")
DAT(213,ENERR_ILLEGAL_OPT,"illegal option value in section")
DAT(214,ENERR_TOO_MANY_CHAR,"following line of section contains too many characters")
DAT(215,ENERR_DUPLICATE_ID,"duplicate ID")
DAT(216,ENERR_UNDEF_PUMP,"data specified for undefined Pump")
DAT(217,ENERR_INVALID_DATA_PUMP,"invalid data for Pump")
DAT(219,ENERR_ILLEGAL_CON_TANK,"illegally connected to a tank")
DAT(220,ENERR_ILLEGAL_CON_VALVE,"illegally connected to another valve")
DAT(221,ENERR_RULE_CLAUSE, "mis-placed rule clause")
DAT(222,ENERR_SAME_START_END,"same start and end nodes")
DAT(223,ENERR_NOT_ENOUGH_NODES,"not enough nodes in network")
DAT(224,ENERR_NO_TANKS_RES,"no tanks or reservoirs in network")
DAT(225,ENERR_INVALID_LEVELS,"invalid lower/upper levels for Tank")
DAT(226,ENERR_NO_HEAD_CURVE,"no head curve supplied for Pump")
DAT(227,ENERR_INVALID_HEAD_CURVE,"invalid head curve for Pump")
DAT(230,ENERR_X_NONINCREASING,"Curve has nonincreasing x-values")
DAT(233,ENERR_NODE_UNCONNECTED,"Node is unconnected")
DAT(240,ENERR_UNDEF_SOURCE,"undefined source")
DAT(241,ENERR_UNDEF_CONTROL,"refers to undefined control")
DAT(250,ENERR_INVALID_FORMAT,"function call contains invalid format")
DAT(251,ENERR_INVALID_CODE,"function call contains invalid parameter code")
DAT(253,ENERR_NO_DEMAND_CAT,"function applied to nonexistent demand category")
DAT(254,ENERR_NO_COORDS,"function applied to node with no coordinates")
DAT(255,ENERR_COORDS_NOT_LOADED,"function fails because no node coordinates were supplied")
DAT(257,ENERR_NO_RULE,"function applied to nonexistent rule")
DAT(258,ENERR_NO_CONDITION_ACTION,"function applied to nonexistent rule clause")
DAT(260,ENERR_DEL_TRACE_NODE,"cannot delete node assigned as a Trace Node")
DAT(261,ENERR_DEL_NODE_LINK, "cannot delete a node or link contained in a control")
DAT(301,ENERR_FILES_ARE_SAME,"identical file names")
DAT(302,ENERR_CANT_OPEN_INP,"cannot open input file")
DAT(303,ENERR_CANT_OPEN_RPT,"cannot open report file")
DAT(304,ENERR_CANT_OPEN_BIN,"cannot open binary output file")
DAT(305,ENERR_CANT_OPEN_HYD,"cannot open hydraulics file")
DAT(306,ENERR_HYD_FILE_NOMATCH,"hydraulics file does not match network data")
DAT(307,ENERR_CANT_READ_HYD,"cannot read hydraulics file")
DAT(308,ENERR_CANT_SAVE_RES,"cannot save results to file")
DAT(309,ENERR_CANT_SAVE_RPT,"cannot save results to report file")
DAT(411,ENERR_NO_MEM_ALLOC,"no memory allocated for results")
DAT(412,ENERR_NO_RESULTS_NO_FILE,"no results; binary file hasn't been opened")
DAT(435,ENERR_RUN_TERMINATED,"run terminated; no results in binary file")
// These errors apply to network consistency check
DAT(223,"not enough nodes in network")
DAT(224,"no tanks or reservoirs in network")
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")
// These errors apply only to API functions
DAT(240,"nonexistent source")
DAT(241,"nonexistent control")
DAT(250,"invalid format")
DAT(251,"invalid parameter code")
DAT(253,"nonexistent demand category")
DAT(254,"node with no coordinates")
DAT(257,"nonexistent rule")
DAT(258,"nonexistent rule clause")
DAT(260,"attempt to delete node assigned as a Trace Node")
DAT(261,"attempt to delete a node or link contained in a control")
DAT(262,"attempt to modify network structure while solver is active")
// File errors
DAT(301,"identical file names")
DAT(302,"cannot open input file")
DAT(303,"cannot open report file")
DAT(304,"cannot open binary output file")
DAT(305,"cannot open hydraulics file")
DAT(306,"hydraulics file does not match network data")
DAT(307,"cannot read hydraulics file")
DAT(308,"cannot save results to file")
DAT(309,"cannot save results to report file")

View File

@@ -29,6 +29,7 @@ int buildadjlists(Network *);
void freeadjlists(Network *);
int incontrols(Project *, int, int);
int valvecheck(Project *, int, int, int);
int findnode(Network *, char *);
int findlink(Network *, char *);
int findtank(Network *, int);
@@ -88,7 +89,6 @@ int statusdata(Project *);
int reportdata(Project *);
int timedata(Project *);
int optiondata(Project *);
int valvecheck(Project *, int, int, int);
// ------- RULES.C ------------------

View File

@@ -771,11 +771,19 @@ void pumpcoeff(Project *pr, int k)
return;
}
// Obtain reference to pump object & its speed setting
// Obtain reference to pump object
q = ABS(hyd->LinkFlow[k]);
p = findpump(&pr->network, k);
pump = &pr->network.Pump[p];
// If no pump curve treat pump as an open valve
if (pump->Ptype == NOCURVE)
{
hyd->P[k] = 1.0 / CSMALL;
hyd->Y[k] = hyd->LinkFlow[k];
return;
}
// Get pump curve coefficients for custom pump curve
// (Other pump types have pre-determined coeffs.)
if (pump->Ptype == CUSTOM)

View File

@@ -58,12 +58,26 @@ int openhyd(Project *pr)
int errcode = 0;
Slink *link;
// Check for too few nodes & no fixed grade nodes
if (pr->network.Nnodes < 2) errcode = 223;
else if (pr->network.Ntanks == 0) errcode = 224;
// Allocate memory for sparse matrix structures (see SMATRIX.C)
ERRCODE(createsparse(pr));
// Allocate memory for hydraulic variables
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;
}
}
// Initialize link flows
if (!errcode) for (i = 1; i <= pr->network.Nlinks; i++)
{

View File

@@ -100,6 +100,8 @@ int hydsolve(Project *pr, int *iter, double *relerr)
// Initialize status checking & relaxation factor
nextcheck = hyd->CheckFreq;
hyd->RelaxFactor = 1.0;
hydbal.maxheaderror = 0.0;
hydbal.maxflowchange = 0.0;
// Repeat iterations until convergence or trial limit is exceeded.
// (ExtraIter used to increase trials in case of status cycling.)
@@ -121,7 +123,7 @@ int hydsolve(Project *pr, int *iter, double *relerr)
// Matrix ill-conditioning problem - if control valve causing problem,
// fix its status & continue, otherwise quit with no solution.
if (errcode > 0)
{
{
if (badvalve(pr, sm->Order[errcode])) continue;
else break;
}
@@ -360,7 +362,6 @@ double newflows(Project *pr, Hydbalance *hbal)
**----------------------------------------------------------------
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
double dqsum, // Network flow change

View File

@@ -102,7 +102,6 @@ int saveinpfile(Project *pr, const char *fname)
Times *time = &pr->times;
int i, j, n;
int errcode;
double d, kc, ke, km, ucf;
char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1];
Pdemand demand;
@@ -116,7 +115,7 @@ int saveinpfile(Project *pr, const char *fname)
Scurve *curve;
// Open the new text file
if ((f = fopen(fname, "wt")) == NULL) return (308);
if ((f = fopen(fname, "wt")) == NULL) return 302;
// Write [TITLE] section
fprintf(f, s_TITLE);
@@ -451,7 +450,7 @@ int saveinpfile(Project *pr, const char *fname)
for (i = 1; i <= net->Nrules; i++)
{
fprintf(f, "\nRULE %s", pr->network.Rule[i].label);
errcode = writerule(pr, f, i); // see RULES.C
writerule(pr, f, i); // see RULES.C
fprintf(f, "\n");
}
@@ -489,7 +488,7 @@ int saveinpfile(Project *pr, const char *fname)
fprintf(f, s_MIXING);
for (i = 1; i <= net->Ntanks; i++)
{
Stank *tank = &net->Tank[i];
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));
@@ -719,7 +718,7 @@ int saveinpfile(Project *pr, const char *fname)
j = 0;
for (i = 1; i <= net->Nlinks; i++)
{
Slink *link = &net->Link[i];
link = &net->Link[i];
if (link->Rpt == 1)
{
if (j % 5 == 0) fprintf(f, "\n LINKS ");

View File

@@ -7,7 +7,7 @@ Description: retrieves network data from an EPANET input file
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/10/2018
Last Updated: 12/15/2018
******************************************************************************
*/
@@ -353,10 +353,11 @@ int inittanks(Project *pr)
*/
{
Network *net = &pr->network;
int i, j, n = 0;
double a;
int errcode = 0, levelerr;
char errmsg[MAXMSG+1] = "";
Stank *tank;
Scurve *curve;
@@ -383,14 +384,6 @@ int inittanks(Project *pr)
levelerr = 1;
}
// Report error in levels if found
if (levelerr)
{
sprintf(pr->Msg, "%s node: %s", geterrmsg(225, pr->Msg),
net->Node[tank->Node].ID);
writeline(pr, pr->Msg);
errcode = 200;
}
else
{
// Find min., max., and initial volumes from curve
@@ -403,6 +396,15 @@ int inittanks(Project *pr)
tank->A = sqrt(4.0 * a / PI);
}
}
// Report error in levels if found
if (levelerr)
{
sprintf(pr->Msg, "Error 225: %s node %s", geterrmsg(225, errmsg),
net->Node[tank->Node].ID);
writeline(pr, pr->Msg);
errcode = 200;
}
}
return errcode;
}

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: 11/10/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -179,6 +179,7 @@ int readdata(Project *pr)
parser->Comment);
// Skip blank lines and comments
parser->ErrTok = -1;
if (parser->Ntokens == 0) continue;
if (*parser->Tok[0] == ';') continue;
@@ -218,7 +219,7 @@ int readdata(Project *pr)
inperr = newline(pr, sect, line);
if (inperr > 0)
{
inperrmsg(pr,inperr, sect, line);
inperrmsg(pr, inperr, sect, line);
errsum++;
}
}
@@ -326,7 +327,8 @@ int getpumpparams(Project *pr)
*/
{
Network *net = &pr->network;
int i, k, errcode = 0;
int i, k, errcode = 0;
char errmsg[MAXMSG+1];
for (i = 1; i <= net->Npumps; i++)
{
@@ -334,8 +336,8 @@ int getpumpparams(Project *pr)
if (errcode)
{
k = net->Pump[i].Link;
sprintf(pr->Msg, "%s link: %s", geterrmsg(errcode, pr->Msg),
net->Link[k].ID);
sprintf(pr->Msg, "Error %d: %s %s",
errcode, geterrmsg(errcode, errmsg), net->Link[k].ID);
writeline(pr, pr->Msg);
return 200;
}
@@ -379,7 +381,7 @@ int updatepumpparams(Project *pr, int pumpindex)
curveindex = pump->Hcurve;
if (curveindex == 0) return 226;
curve = &net->Curve[curveindex];
curve->Type = P_CURVE;
curve->Type = PUMP_CURVE;
npts = curve->Npts;
// Generic power function curve
@@ -596,8 +598,7 @@ int unlinked(Project *pr)
if (marked[i] == 0)
{
err++;
sprintf(pr->Msg, "%s link: %s", geterrmsg(233, pr->Msg),
net->Node[i].ID);
sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID);
writeline(pr, pr->Msg);
}
if (err >= MAXERRS) break;
@@ -685,6 +686,7 @@ int getcurves(Project *pr)
int i, j;
double x;
char errmsg[MAXMSG+1];
SFloatlist *fx, *fy;
STmplist *tmpcurve;
Scurve *curve;
@@ -705,10 +707,9 @@ int getcurves(Project *pr)
// Check that network curve has data points
if (curve->Npts <= 0)
{
sprintf(pr->Msg, "%s link: %s", geterrmsg(230, pr->Msg),
curve->ID);
sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg), curve->ID);
writeline(pr, pr->Msg);
return (200);
return 200;
}
// Allocate memory for network's curve data
@@ -726,10 +727,9 @@ int getcurves(Project *pr)
// Check that x data is in ascending order
if (fx->value >= x)
{
sprintf(pr->Msg, "%s link: %s", geterrmsg(230, pr->Msg),
curve->ID);
sprintf(pr->Msg, "Error 230: %s %s", geterrmsg(230, errmsg), curve->ID);
writeline(pr, pr->Msg);
return (200);
return 200;
}
x = fx->value;
@@ -967,33 +967,18 @@ void inperrmsg(Project *pr, int err, int sect, char *line)
{
Parser *parser = &pr->parser;
char errStr[MAXMSG + 1];
char id[MAXMSG + 1];
char errStr[MAXMSG + 1] = "";
char tok[MAXMSG + 1];
// Get token associated with input error
if (parser->ErrTok >= 0) strcpy(tok, parser->Tok[parser->ErrTok]);
else strcpy(tok, "");
// get text for error message
sprintf(pr->Msg, "%s - section: %s", geterrmsg(err, errStr), SectTxt[sect]);
// Retrieve ID label of object with input error
// (No ID used for CONTROLS or REPORT sections)
switch (sect)
{
case _CONTROLS:
case _REPORT:
// don't append
break;
case _ENERGY:
sprintf(id, " id: %s", parser->Tok[1]);
break;
default:
sprintf(id, " id: %s", parser->Tok[0]);
break;
}
strcat(pr->Msg, id);
// write error message to report file
sprintf(pr->Msg, "Error %d: %s %s in %s section:",
err, geterrmsg(err, errStr), tok, SectTxt[sect]);
writeline(pr, pr->Msg);
// Echo input line for syntax errors, and
// errors in CONTROLS and OPTIONS sections
if (sect == _CONTROLS || err == 201 || err == 213) writeline(pr, line);
else writeline(pr, "");
// Echo input line
writeline(pr, line);
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/27/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -60,8 +60,8 @@ int openfiles(Project *pr, const char *f1, const char *f2, const char *f3)
else pr->outfile.Outflag = SCRATCH;
// Check that file names are not identical
if (strcomp(f1, f2) || strcomp(f1, f3) ||
(strcomp(f2, f3) && (strlen(f2) > 0 || strlen(f3) > 0))) return 301;
if (strlen(f1) > 0 && (strcomp(f1, f2) || strcomp(f1, f3))) return 301;
if (strlen(f3) > 0 && strcomp(f2, f3)) return 301;
// Attempt to open input and report files
if (strlen(f1) > 0)
@@ -69,7 +69,12 @@ int openfiles(Project *pr, const char *f1, const char *f2, const char *f3)
if ((pr->parser.InFile = fopen(f1, "rt")) == NULL) return 302;
}
if (strlen(f2) == 0) pr->report.RptFile = stdout;
else if ((pr->report.RptFile = fopen(f2, "wt")) == NULL) return 303;
else
{
pr->report.RptFile = fopen(f2, "wt");
if (pr->report.RptFile == NULL) return 303;
}
writelogo(pr);
return 0;
}
@@ -146,7 +151,7 @@ int openhydfile(Project *pr)
if (version != ENGINE_VERSION) return 306;
if (fread(nsize, sizeof(INT4), 6, pr->outfile.HydFile) < 6) return 306;
if (nsize[0] != Nnodes || nsize[1] != Nlinks || nsize[2] != Ntanks ||
nsize[3] != Npumps || nsize[4] != Nvalves ||
nsize[3] != Npumps || nsize[4] != Nvalves ||
nsize[5] != pr->times.Dur
) return 306;
pr->outfile.SaveHflag = TRUE;
@@ -182,7 +187,7 @@ int openoutfile(Project *pr)
}
// If output file name was supplied, then attempt to
// open it. Otherwise open a temporary output file.
// open it. Otherwise open a temporary output file.
if (pr->outfile.Outflag == SAVE)
{
pr->outfile.OutFile = fopen(pr->outfile.OutFname, "w+b");
@@ -300,7 +305,7 @@ int allocdata(Project *pr)
ERRCODE(MEMCHECK(pr->quality.NodeQual));
}
// Allocate memory for network links
// Allocate memory for network links
if (!errcode)
{
n = pr->parser.MaxLinks + 1;
@@ -349,7 +354,7 @@ int allocdata(Project *pr)
for (n = 0; n <= pr->parser.MaxCurves; n++)
{
pr->network.Curve[n].Npts = 0;
pr->network.Curve[n].Type = G_CURVE;
pr->network.Curve[n].Type = GENERIC_CURVE;
pr->network.Curve[n].X = NULL;
pr->network.Curve[n].Y = NULL;
}
@@ -437,7 +442,7 @@ void freedata(Project *pr)
free(demand);
demand = nextdemand;
}
// Free memory used for WQ source data
// Free memory used for WQ source data
source = pr->network.Node[j].S;
if (source != NULL) free(source);
}
@@ -574,7 +579,6 @@ int incontrols(Project *pr, int objType, int index)
*/
{
Network *net = &pr->network;
Rules *rules = &pr->rules;
int i, ruleObject;
Spremise *premise;
@@ -625,6 +629,65 @@ int incontrols(Project *pr, int objType, int index)
return 0;
}
int valvecheck(Project *pr, int type, int j1, int j2)
/*
**--------------------------------------------------------------
** Input: type = valve type
** j1 = index of upstream node
** j2 = index of downstream node
** Output: returns an error code
** Purpose: checks for illegal connections between valves
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
int k, vj1, vj2;
LinkType vtype;
Slink *link;
Svalve *valve;
if (type == PRV || type == PSV || type == FCV)
{
// Can't be connected to a fixed grade node
if (j1 > net->Njuncs || j2 > net->Njuncs) return 219;
// Examine each existing valve
for (k = 1; k <= net->Nvalves; k++)
{
valve = &net->Valve[k];
link = &net->Link[valve->Link];
vj1 = link->N1;
vj2 = link->N2;
vtype = link->Type;
// Cannot have two PRVs sharing downstream nodes or in series
if (vtype == PRV && type == PRV)
{
if (vj2 == j2 || vj2 == j1 || vj1 == j2) return 220;
}
// Cannot have two PSVs sharing upstream nodes or in series
if (vtype == PSV && type == PSV)
{
if (vj1 == j1 || vj1 == j2 || vj2 == j1) return 220;
}
// Cannot have PSV connected to downstream node of PRV
if (vtype == PSV && type == PRV && vj1 == j2) return 220;
if (vtype == PRV && type == PSV && vj2 == j1) return 220;
// Cannot have PSV connected to downstream node of FCV
// nor have PRV connected to upstream node of FCV
if (vtype == FCV && type == PSV && vj2 == j1) return 220;
if (vtype == FCV && type == PRV && vj1 == j2) return 220;
if (vtype == PSV && type == FCV && vj1 == j2) return 220;
if (vtype == PRV && type == FCV && vj2 == j1) return 220;
}
}
return 0;
}
int findnode(Network *network, char *id)
/*----------------------------------------------------------------
** Input: id = node ID
@@ -768,7 +831,7 @@ double interp(int n, double x[], double y[], double xx)
double dx, dy;
m = n - 1; // Highest data index
if (xx <= x[0]) return (y[0]); // xx off low end of curve
if (xx <= x[0]) return (y[0]); // xx off low end of curve
for (k = 1; k <= m; k++) // Bracket xx on curve
{
if (x[k] >= xx) // Interp. over interval
@@ -791,11 +854,14 @@ char *geterrmsg(int errcode, char *msg)
**----------------------------------------------------------------
*/
{
switch (errcode) { /* Warnings */
//#define DAT(code,enumer,string) case code: strcpy(msg, string); break;
#define DAT(code,enumer,string) case code: sprintf(msg, "Error %d: %s", code, string); break;
switch (errcode)
{
//#define DAT(code,string) case code: sprintf(msg, "%s", string); break;
#define DAT(code,string) case code: strcpy(msg, string); break;
#include "errors.dat"
#undef DAT
default:
strcpy(msg, "");
}
@@ -810,13 +876,15 @@ void errmsg(Project *pr, int errcode)
**----------------------------------------------------------------
*/
{
char errmsg[MAXMSG + 1] = "";
if (errcode == 309) /* Report file write error - */
{ /* Do not write msg to file. */
}
else if (pr->report.RptFile != NULL && pr->report.Messageflag)
else if (pr->report.RptFile != NULL && pr->report.Messageflag && errcode > 100)
{
writeline(pr, geterrmsg(errcode, pr->Msg));
sprintf(pr->Msg, "Error %d: %s", errcode, geterrmsg(errcode, errmsg));
writeline(pr, pr->Msg);
}
}

View File

@@ -35,7 +35,7 @@ const double Q_STAGNANT = 0.005 / GPMperCFS; // 0.005 gpm = 1.114e-5 cfs
//int stepqual(Project *, long *);
//int closequal(Project *);
//double avgqual(Project *, int);
double findsourcequal(Project *, int, double, double, long);
double findsourcequal(Project *, int, double, long);
// Imported functions
extern char setreactflag(Project *);
@@ -78,21 +78,21 @@ int openqual(Project *pr)
// Create a memory pool for water quality segments
qual->OutOfMemory = FALSE;
qual->SegPool = mempool_create();
if (qual->SegPool == NULL) errcode = 101;
if (qual->SegPool == NULL) errcode = 101;
// Allocate arrays for link flow direction & reaction rates
n = net->Nlinks + 1;
qual->FlowDir = (FlowDirection *)calloc(n, sizeof(FlowDirection));
qual->PipeRateCoeff = (double *)calloc(n, sizeof(double));
// Allocate arrays used for volume segments in links & tanks
// Allocate arrays used for volume segments in links & tanks
n = net->Nlinks + net->Ntanks + 1;
qual->FirstSeg = (Pseg *)calloc(n, sizeof(Pseg));
qual->LastSeg = (Pseg *)calloc(n, sizeof(Pseg));
// Allocate memory for topologically sorted nodes
// Allocate memory for topologically sorted nodes
qual->SortedNodes = (int *)calloc(n, sizeof(int));
ERRCODE(MEMCHECK(qual->FlowDir));
ERRCODE(MEMCHECK(qual->PipeRateCoeff));
ERRCODE(MEMCHECK(qual->FirstSeg));
@@ -119,7 +119,7 @@ int initqual(Project *pr)
int i;
int errcode = 0;
// Re-position hydraulics file
// Re-position hydraulics file
if (!hyd->OpenHflag)
{
fseek(pr->outfile.HydFile, pr->outfile.HydOffset, SEEK_SET);
@@ -148,7 +148,7 @@ int initqual(Project *pr)
// Initialize quality at trace node (if applicable)
if (qual->Qualflag == TRACE) qual->NodeQual[qual->TraceNode] = 100.0;
// Compute Schmidt number
if (qual->Diffus > 0.0) qual->Sc = hyd->Viscos / qual->Diffus;
else qual->Sc = 0.0;
@@ -202,17 +202,17 @@ int runqual(Project *pr, long *t)
Quality *qual = &pr->quality;
Times *time = &pr->times;
long hydtime; // Hydraulic solution time
long hydstep; // Hydraulic time step
long hydtime = 0; // Hydraulic solution time
long hydstep = 0; // Hydraulic time step
int errcode = 0;
// Update reported simulation time
*t = time->Qtime;
// Read hydraulic solution from hydraulics file
// Read hydraulic solution from hydraulics file
if (time->Qtime == time->Htime)
{
// Read hydraulic results from file
// Read hydraulic results from file
if (!hyd->OpenHflag)
{
if (!readhyd(pr, &hydtime)) return 307;
@@ -220,7 +220,7 @@ int runqual(Project *pr, long *t)
time->Htime = hydtime;
}
// Save current results to output file
// Save current results to output file
if (time->Htime >= time->Rtime)
{
if (pr->outfile.Saveflag)
@@ -263,7 +263,7 @@ int nextqual(Project *pr, long *tstep)
{
Quality *qual = &pr->quality;
Times *time = &pr->times;
long hydstep; // Time step until next hydraulic event
long dt, qtime;
int errcode = 0;
@@ -316,7 +316,7 @@ int stepqual(Project *pr, long *tleft)
** Input: none
** Output: tleft = time left in simulation
** Returns: error code
** Purpose: updates quality conditions over a single
** Purpose: updates quality conditions over a single
** quality time step
**--------------------------------------------------------------
*/
@@ -402,7 +402,7 @@ int closequal(Project *pr)
int errcode = 0;
if (qual->SegPool) mempool_delete(qual->SegPool);
FREE(qual->FirstSeg);
FREE(qual->FirstSeg);
FREE(qual->LastSeg);
FREE(qual->PipeRateCoeff);
FREE(qual->FlowDir);
@@ -452,11 +452,10 @@ double avgqual(Project *pr, int k)
}
double findsourcequal(Project *pr, int n, double volin, double volout, long tstep)
double findsourcequal(Project *pr, int n, double volout, long tstep)
/*
**---------------------------------------------------------------------
** Input: n = node index
** volin = volume of node inflow over time step
** volout = volume of node outflow over time step
** tstep = current quality time step
** Output: returns concentration added by an external quality source.
@@ -543,7 +542,6 @@ double sourcequal(Project *pr, Psource source)
*/
{
Network *net = &pr->network;
Quality *qual = &pr->quality;
Times *time = &pr->times;
int i;

View File

@@ -222,7 +222,7 @@ double piperate(Project *pr, int k)
d = net->Link[k].Diam; // Pipe diameter, ft
// Ignore mass transfer if Schmidt No. is 0
// Ignore mass transfer if Schmidt No. is 0
if (qual->Sc == 0.0)
{
if (qual->WallOrder == 0.0) return BIG;
@@ -445,7 +445,6 @@ double mixtank(Project *pr, int n, double volin, double massin, double volout)
*/
{
Network *net = &pr->network;
Quality *qual = &pr->quality;
int i;
double vnet;
@@ -475,7 +474,6 @@ void tankmix1(Project *pr, int i, double vin, double win, double vnet)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int k;
@@ -544,7 +542,7 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)
}
}
// Tank is emptying
// Tank is emptying
else if (vnet < 0.0)
{
if (stagzone->v > 0.0) vt = MIN(stagzone->v, (-vnet));
@@ -555,7 +553,7 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)
}
}
// Update segment volumes
// Update segment volumes
if (vt > 0.0)
{
mixzone->v = vmz;
@@ -589,7 +587,6 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int k;
@@ -640,7 +637,7 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
}
// Use quality withdrawn from 1st segment
// to represent overall quality of tank
// to represent overall quality of tank
if (vsum > 0.0) tank->C = wsum / vsum;
else if (qual->FirstSeg[k] == NULL) tank->C = 0.0;
else tank->C = qual->FirstSeg[k]->c;
@@ -662,7 +659,7 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
Network *net = &pr->network;
Quality *qual = &pr->quality;
int k, n;
int k;
double cin, vsum, wsum, vseg;
Pseg seg;
Stank *tank = &pr->network.Tank[i];
@@ -671,7 +668,6 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
if (qual->LastSeg[k] == NULL || qual->FirstSeg[k] == NULL) return;
// Find inflows & outflows
n = tank->Node;
if (vin > 0.0) cin = win / vin;
else cin = 0.0;
@@ -691,7 +687,7 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
qual->LastSeg[k]->prev = seg;
}
// ... update reported tank quality
// ... update reported tank quality
tank->C = qual->LastSeg[k]->c;
}

View File

@@ -35,7 +35,7 @@ void reversesegs(Project *, int);
void addseg(Project *, int, double, double);
// Imported functions
extern double findsourcequal(Project *, int, double, double, long);
extern double findsourcequal(Project *, int, double, long);
extern void reactpipes(Project *, long);
extern void reacttanks(Project *, long);
extern double mixtank(Project *, int, double, double, double);
@@ -147,7 +147,6 @@ void evalnodeinflow(Project *pr, int k, long tstep, double *volin,
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
@@ -251,7 +250,7 @@ double findnodequal(Project *pr, int n, double volin,
}
// Find quality contribued by any external chemical source
else qual->SourceQual = findsourcequal(pr, n, volin, volout, tstep);
else qual->SourceQual = findsourcequal(pr, n, volout, tstep);
if (qual->SourceQual == 0.0) return qual->NodeQual[n];
// Combine source quality with node quality
@@ -285,7 +284,6 @@ double noflowqual(Project *pr, int n)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int k, inflow, kount = 0;
@@ -300,7 +298,7 @@ double noflowqual(Project *pr, int n)
k = alink->link;
dir = qual->FlowDir[k];
// Node n is link's downstream node - add quality
// Node n is link's downstream node - add quality
// of link's first segment to average
if (net->Link[k].N2 == n && dir >= 0) inflow = TRUE;
else if (net->Link[k].N1 == n && dir < 0) inflow = TRUE;
@@ -311,7 +309,7 @@ double noflowqual(Project *pr, int n)
kount++;
}
// Node n is link's upstream node - add quality
// Node n is link's upstream node - add quality
// of link's last segment to average
else if (inflow == FALSE && qual->LastSeg[k] != NULL)
{
@@ -428,7 +426,6 @@ int sortnodes(Project *pr)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int i, j, k, n;
@@ -578,7 +575,6 @@ void initsegs(Project *pr)
*/
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
Quality *qual = &pr->quality;
int j, k;

View File

@@ -69,8 +69,8 @@ int writereport(Project *pr)
{
Report *rpt = &pr->report;
Parser *parser = &pr->parser;
char tflag;
int tflag;
FILE *tfile;
int errcode = 0;
@@ -82,7 +82,7 @@ int writereport(Project *pr)
if (rpt->Energyflag) writeenergy(pr);
errcode = writeresults(pr);
}
// A secondary report file was specified
else if (strlen(rpt->Rpt2Fname) > 0)
{
@@ -145,7 +145,7 @@ void writelogo(Project *pr)
char s[80];
time_t timer; // time_t structure & functions time() &
// ctime() are defined in time.h
version = CODEVERSION;
major = version / 10000;
minor = (version % 10000) / 100;
@@ -230,12 +230,12 @@ void writesummary(Project *pr)
writeline(pr, s);
}
sprintf(s, FMT27a, hyd->CheckFreq);
writeline(pr, s);
sprintf(s, FMT27b, hyd->MaxCheck);
writeline(pr, s);
sprintf(s, FMT27c, hyd->DampLimit);
writeline(pr, s);
sprintf(s, FMT27a, hyd->CheckFreq);
writeline(pr, s);
sprintf(s, FMT27b, hyd->MaxCheck);
writeline(pr, s);
sprintf(s, FMT27c, hyd->DampLimit);
writeline(pr, s);
sprintf(s, FMT28, hyd->MaxIter);
writeline(pr, s);
@@ -341,7 +341,7 @@ void writehydstat(Project *pr, int iter, double relerr)
}
}
// Display status changes for links
// Display status changes for links
for (i = 1; i <= net->Nlinks; i++)
{
if (hyd->LinkStatus[i] != hyd->OldStatus[i])
@@ -399,7 +399,7 @@ void writemassbalance(Project *pr)
writeline(pr, s1);
snprintf(s1, MAXMSG, "Final Mass: %12.5e", qual->MassBalance.final);
writeline(pr, s1);
snprintf(s1, MAXMSG, "Mass Ratio: %-0.5f", qual->MassBalance.ratio);
snprintf(s1, MAXMSG, "Mass Ratio: %-.5f", qual->MassBalance.ratio);
writeline(pr, s1);
snprintf(s1, MAXMSG, "================================\n");
writeline(pr, s1);
@@ -426,7 +426,7 @@ void writeenergy(Project *pr)
if (net->Npumps == 0) return;
writeline(pr, " ");
writeheader(pr,ENERHDR, 0);
csum = 0.0;
for (j = 1; j <= net->Npumps; j++)
{
@@ -534,7 +534,7 @@ int writeresults(Project *pr)
}
}
// Free allocated memory
// Free allocated memory
for (j = 0; j < m; j++) free(x[j]);
free(x);
return errcode;
@@ -572,7 +572,7 @@ void writenodetable(Project *pr, Pfloat *x)
if ((rpt->Nodeflag == 1 || node->Rpt) &&
checklimits(rpt, y, ELEV, QUALITY))
{
// Check if new page needed
// Check if new page needed
if (rpt->LineNum == (long)rpt->PageSize) writeheader(pr, NODEHDR, 1);
// Add node ID and each reported field to string s
@@ -618,7 +618,7 @@ void writelinktable(Project *pr, Pfloat *x)
double y[MAXVAR];
double *Ucf = pr->Ucf;
Slink *Link = net->Link;
// Write table header
writeheader(pr, LINKHDR, 0);
@@ -686,7 +686,7 @@ void writeheader(Project *pr, int type, int contin)
Quality *qual = &pr->quality;
Parser *parser = &pr->parser;
Times *time = &pr->times;
char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1], s3[MAXLINE + 1];
int i, n;
@@ -697,7 +697,7 @@ void writeheader(Project *pr, int type, int contin)
}
writeline(pr, " ");
// Hydraulic Status Table
// Hydraulic Status Table
if (type == STATHDR)
{
sprintf(s, FMT49);
@@ -737,12 +737,12 @@ void writeheader(Project *pr, int type, int contin)
else sprintf(s, FMT78, clocktime(rpt->Atime, time->Htime));
if (contin) strcat(s, t_CONTINUED);
writeline(pr, s);
n = 15;
sprintf(s2, "%15s", "");
strcpy(s, t_NODEID);
sprintf(s3, "%-15s", s);
for (i = ELEV; i < QUALITY; i++)
{
if (rpt->Field[i].Enabled == TRUE)
@@ -846,7 +846,7 @@ void writerelerr(Project *pr, int iter, double relerr)
{
Report *rpt = &pr->report;
Times *time = &pr->times;
if (iter == 0)
{
sprintf(pr->Msg, FMT64, clocktime(rpt->Atime, time->Htime));
@@ -878,7 +878,7 @@ void writestatchange(Project *pr, int k, char s1, char s2)
double *Ucf = pr->Ucf;
double *LinkSetting = hyd->LinkSetting;
Slink *Link = net->Link;
// We have a pump/valve setting change instead of a status change
if (s1 == s2)
{
@@ -934,7 +934,7 @@ void writecontrolaction(Project *pr, int k, int i)
Snode *Node = net->Node;
Slink *Link = net->Link;
Scontrol *Control = net->Control;
switch (Control[i].Type)
{
case LOWLEVEL:
@@ -944,7 +944,7 @@ void writecontrolaction(Project *pr, int k, int i)
LinkTxt[Link[k].Type], Link[k].ID,
NodeTxt[getnodetype(net, n)], Node[n].ID);
break;
case TIMER:
case TIMEOFDAY:
sprintf(pr->Msg, FMT55, clocktime(rpt->Atime, time->Htime),
@@ -1001,7 +1001,7 @@ int writehydwarn(Project *pr, int iter, double relerr)
int i, j;
char flag = 0;
char s;
int s;
Snode *Node = net->Node;
Slink *Link = net->Link;
Spump *Pump = net->Pump;
@@ -1010,7 +1010,7 @@ int writehydwarn(Project *pr, int iter, double relerr)
double *NodeDemand = hyd->NodeDemand;
double *LinkFlow = hyd->LinkFlow;
double *LinkSetting = hyd->LinkSetting;
// Check if system unstable
if (iter > hyd->MaxIter && relerr <= hyd->Hacc)
{
@@ -1046,19 +1046,19 @@ int writehydwarn(Project *pr, int iter, double relerr)
}
}
// Check for abnormal pump condition
// Check for abnormal pump condition
for (i = 1; i <= net->Npumps; i++)
{
j = Pump[i].Link;
s = hyd->LinkStatus[j];
if (hyd->LinkStatus[j] >= OPEN)
{
if (LinkFlow[j] > LinkSetting[j] * Pump[i].Qmax) s = XFLOW;
if (LinkFlow[j] < 0.0) s = XHEAD;
}
if (s == XHEAD || s == XFLOW)
s = hyd->LinkStatus[j];
if (hyd->LinkStatus[j] >= OPEN)
{
sprintf(pr->Msg, WARN04, Link[j].ID, StatTxt[s],
if (LinkFlow[j] > LinkSetting[j] * Pump[i].Qmax) s = XFLOW;
if (LinkFlow[j] < 0.0) s = XHEAD;
}
if (s == XHEAD || s == XFLOW)
{
sprintf(pr->Msg, WARN04, Link[j].ID, StatTxt[s],
clocktime(rpt->Atime, time->Htime));
if (rpt->Messageflag) writeline(pr, pr->Msg);
flag = 4;
@@ -1098,7 +1098,7 @@ void writehyderr(Project *pr, int errnode)
Times *time = &pr->times;
Snode *Node = net->Node;
sprintf(pr->Msg, FMT62, clocktime(rpt->Atime, time->Htime),
Node[errnode].ID);
if (rpt->Messageflag) writeline(pr, pr->Msg);
@@ -1218,7 +1218,7 @@ void marknodes(Project *pr, int m, int *nodelist, char *marked)
int i, j, k, n;
Padjlist alink;
// Scan each successive entry of node list
n = 1;
while (n <= m)
@@ -1232,7 +1232,7 @@ void marknodes(Project *pr, int m, int *nodelist, char *marked)
j = alink->node;
if (marked[j]) continue;
// Check if valve connection is in correct direction
// Check if valve connection is in correct direction
switch (net->Link[k].Type)
{
case CVPIPE:
@@ -1299,7 +1299,7 @@ void writelimits(Project *pr, int j1, int j2)
{
Report *rpt = &pr->report;
int j;
for (j = j1; j <= j2; j++)
{
if (rpt->Field[j].RptLim[LOW] < BIG)

View File

@@ -193,7 +193,7 @@ int ruledata(Project *pr)
switch (key)
{
case -1:
err = 201; // Unrecognized keyword
err = 201; // Unrecognized keyword
break;
case r_RULE:
@@ -328,7 +328,6 @@ void adjustrules(Project *pr, int objtype, int index)
//-----------------------------------------------------------
{
Network *net = &pr->network;
Rules *rules = &pr->rules;
int i, delete;
Spremise *p;
@@ -453,7 +452,6 @@ int writerule(Project *pr, FILE *f, int ruleIndex)
//-----------------------------------------------------------------------------
{
Network *net = &pr->network;
Rules *rules = &pr->rules;
Srule *rule = &net->Rule[ruleIndex];
Spremise *p;
@@ -678,7 +676,7 @@ int newpremise(Project *pr, int logop)
{
if (!getfloat(Tok[parser->Ntokens - 1], &x))
return (202);
if (v == r_FILLTIME || v == r_DRAINTIME) x = x * 3600.0;
if (v == r_FILLTIME || v == r_DRAINTIME) x = x * 3600.0;
}
// Create new premise structure
@@ -715,7 +713,7 @@ int newaction(Project *pr)
double x;
Saction *a;
char **Tok = parser->Tok;
// Check for correct number of tokens
if (parser->Ntokens != 6) return 201;
@@ -848,7 +846,7 @@ int checktime(Project *pr, Spremise *p)
{
t1 = rules->Time1;
t2 = time->Htime;
}
}
else if (p->variable == r_CLOCKTIME)
{
t1 = (rules->Time1 + time->Tstart) % SECperDAY;
@@ -878,7 +876,7 @@ int checktime(Project *pr, Spremise *p)
case EQ:
case NE:
flag = FALSE;
if (t2 < t1) // E.g., 11:00 am to 1:00 am
if (t2 < t1) // E.g., 11:00 am to 1:00 am
{
if (x >= t1 || x <= t2)
flag = TRUE;
@@ -893,7 +891,7 @@ int checktime(Project *pr, Spremise *p)
break;
}
// If we get to here then premise was satisfied
// If we get to here then premise was satisfied
return 1;
}
@@ -906,7 +904,7 @@ int checkstatus(Project *pr, Spremise *p)
char i;
int j;
switch (p->status)
{
case IS_OPEN:
@@ -930,7 +928,7 @@ int checkvalue(Project *pr, Spremise *p)
{
Network *net = &pr->network;
Hydraul *hyd = &pr->hydraul;
int i, j, v;
double x, // A variable's value
tol = 1.e-3; // Equality tolerance
@@ -942,7 +940,7 @@ int checkvalue(Project *pr, Spremise *p)
Snode *Node = net->Node;
Slink *Link = net->Link;
Stank *Tank = net->Tank;
// Find the value being checked
i = p->index;
v = p->variable;
@@ -1099,13 +1097,13 @@ int takeactions(Project *pr)
Hydraul *hyd = &pr->hydraul;
Report *rpt = &pr->report;
Rules *rules = &pr->rules;
char flag;
int k, s, n;
double tol = 1.e-3, v, x;
Saction *a;
SactionList *actionItem;
n = 0;
actionItem = rules->ActionList;
while (actionItem != NULL)

View File

@@ -81,9 +81,9 @@ static void transpose(int, int *, int *, int *, int *,
int createsparse(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: creates sparse representation of coeff. matrix
** Input: none
** Output: returns error code
** Purpose: creates sparse representation of coeff. matrix
**--------------------------------------------------------------
*/
{
@@ -104,7 +104,7 @@ int createsparse(Project *pr)
errcode = localadjlists(net, sm);
if (errcode) return errcode;
// Re-order nodes to minimize number of non-zero coeffs.
// Re-order nodes to minimize number of non-zero coeffs.
// in factorized solution matrix
ERRCODE(reordernodes(pr));
@@ -134,9 +134,9 @@ int createsparse(Project *pr)
int allocsmatrix(Smatrix *sm, int Nnodes, int Nlinks)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: allocates memory for representing a sparse matrix
** Input: none
** Output: returns error code
** Purpose: allocates memory for representing a sparse matrix
**--------------------------------------------------------------
*/
{
@@ -192,20 +192,19 @@ int alloclinsolve(Smatrix *sm, int n)
void freesparse(Project *pr)
/*
**----------------------------------------------------------------
** Input: None
** Output: None
** Purpose: Frees memory used for sparse matrix storage
** Input: None
** Output: None
** Purpose: Frees memory used for sparse matrix storage
**----------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
// stoptimer(SmatrixTimer);
// printf("\n");
// printf("\n Processing Time = %7.3f s", gettimer(SmatrixTimer));
// printf("\n");
FREE(sm->Order);
FREE(sm->Row);
FREE(sm->Ndx);
@@ -247,7 +246,7 @@ int localadjlists(Network *net, Smatrix *sm)
i = net->Link[k].N1;
j = net->Link[k].N2;
pmark = paralink(net, sm, i, j, k); // Parallel link check
// Include link in start node i's list
alink = (struct Sadjlist *) malloc(sizeof(struct Sadjlist));
if (alink == NULL) return(101);
@@ -261,7 +260,7 @@ int localadjlists(Network *net, Smatrix *sm)
alink = (struct Sadjlist *) malloc(sizeof(struct Sadjlist));
if (alink == NULL) return(101);
if (!pmark) alink->node = i;
else alink->node = 0; // Parallel link marker
else alink->node = 0; // Parallel link marker
alink->link = k;
alink->next = net->Adjlist[j];
net->Adjlist[j] = alink;
@@ -276,7 +275,7 @@ int localadjlists(Network *net, Smatrix *sm)
int paralink(Network *net, Smatrix *sm, int i, int j, int k)
/*
**--------------------------------------------------------------
** Input: i = index of start node of link
** Input: i = index of start node of link
** j = index of end node of link
** k = link index
** Output: returns 1 if link k parallels another link, else 0
@@ -350,10 +349,10 @@ void xparalinks(Network *net)
int reordernodes(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns 1 if successful, 0 if not
** Purpose: re-orders nodes to minimize # of non-zeros that
** will appear in factorized solution matrix
** Input: none
** Output: returns 1 if successful, 0 if not
** Purpose: re-orders nodes to minimize # of non-zeros that
** will appear in factorized solution matrix
**--------------------------------------------------------------
*/
{
@@ -376,7 +375,7 @@ int reordernodes(Project *pr)
int *qsize = NULL;
int *llist = NULL;
int *marker = NULL;
// Default ordering
for (k = 1; k <= net->Nnodes; k++)
{
@@ -483,17 +482,17 @@ int factorize(Project *pr)
int growlist(Project *pr, int knode)
/*
**--------------------------------------------------------------
** Input: knode = node index
** Output: returns 1 if successful, 0 if not
** Purpose: creates new entries in knode's adjacency list for
** all unlinked pairs of active nodes that are
** adjacent to knode
** Input: knode = node index
** Output: returns 1 if successful, 0 if not
** Purpose: creates new entries in knode's adjacency list for
** all unlinked pairs of active nodes that are
** adjacent to knode
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
int node;
Padjlist alink;
@@ -517,16 +516,16 @@ int growlist(Project *pr, int knode)
int newlink(Project *pr, Padjlist alink)
/*
**--------------------------------------------------------------
** Input: alink = element of node's adjacency list
** Output: returns 1 if successful, 0 if not
** Purpose: links end of current adjacent link to end nodes of
** all links that follow it on adjacency list
** Input: alink = element of node's adjacency list
** Output: returns 1 if successful, 0 if not
** Purpose: links end of current adjacent link to end nodes of
** all links that follow it on adjacency list
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
int inode, jnode;
Padjlist blink;
@@ -535,7 +534,7 @@ int newlink(Project *pr, Padjlist alink)
for (blink = alink->next; blink != NULL; blink = blink->next)
{
jnode = blink->node; // End node of next connection
// 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
@@ -545,7 +544,7 @@ int newlink(Project *pr, Padjlist alink)
// Since new connection represents a non-zero coeff.
// in the solution matrix, update the coeff. count.
sm->Ncoeffs++;
// Update adjacency lists for inode & jnode to
// reflect the new connection.
if (!addlink(net, inode, jnode, sm->Ncoeffs)) return 0;
@@ -562,10 +561,10 @@ int newlink(Project *pr, Padjlist alink)
int linked(Network *net, int i, int j)
/*
**--------------------------------------------------------------
** Input: i = node index
** j = node index
** Output: returns 1 if nodes i and j are linked, 0 if not
** Purpose: checks if nodes i and j are already linked.
** Input: i = node index
** j = node index
** Output: returns 1 if nodes i and j are linked, 0 if not
** Purpose: checks if nodes i and j are already linked.
**--------------------------------------------------------------
*/
{
@@ -581,11 +580,11 @@ int linked(Network *net, int i, int j)
int addlink(Network *net, int i, int j, int n)
/*
**--------------------------------------------------------------
** Input: i = node index
** j = node index
** n = link index
** Output: returns 1 if successful, 0 if not
** Purpose: augments node i's adjacency list with node j
** Input: i = node index
** j = node index
** n = link index
** Output: returns 1 if successful, 0 if not
** Purpose: augments node i's adjacency list with node j
**--------------------------------------------------------------
*/
{
@@ -603,20 +602,20 @@ int addlink(Network *net, int i, int j, int n)
int storesparse(Project *pr, int n)
/*
**--------------------------------------------------------------
** Input: n = number of rows in solution matrix
** Output: returns error code
** Purpose: stores row indexes of non-zeros of each column of
** lower triangular portion of factorized matrix
** Input: n = number of rows in solution matrix
** Output: returns error code
** Purpose: stores row indexes of non-zeros of each column of
** lower triangular portion of factorized matrix
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Smatrix *sm = &pr->hydraul.smatrix;
int i, ii, j, k, l, m;
int errcode = 0;
Padjlist alink;
// Allocate sparse matrix storage
sm->XLNZ = (int *) calloc(n+2, sizeof(int));
sm->NZSUB = (int *) calloc(sm->Ncoeffs+2, sizeof(int));
@@ -625,7 +624,7 @@ int storesparse(Project *pr, int n)
ERRCODE(MEMCHECK(sm->NZSUB));
ERRCODE(MEMCHECK(sm->LNZ));
if (errcode) return errcode;
// Generate row index pointers for each column of matrix
k = 0;
sm->XLNZ[1] = 1;
@@ -655,20 +654,20 @@ int storesparse(Project *pr, int n)
int sortsparse(Smatrix *sm, int n)
/*
**--------------------------------------------------------------
** Input: n = number of rows in solution matrix
** Output: returns eror code
** Purpose: puts row indexes in ascending order in NZSUB
** Input: n = number of rows in solution matrix
** Output: returns eror code
** Purpose: puts row indexes in ascending order in NZSUB
**--------------------------------------------------------------
*/
{
int i, k;
int *xlnzt, *nzsubt, *lnzt, *nzt;
int errcode = 0;
int *LNZ = sm->LNZ;
int *XLNZ = sm->XLNZ;
int *NZSUB = sm->NZSUB;
xlnzt = (int *) calloc(n+2, sizeof(int));
nzsubt = (int *) calloc(sm->Ncoeffs+2, sizeof(int));
lnzt = (int *) calloc(sm->Ncoeffs+2, sizeof(int));
@@ -687,12 +686,12 @@ int sortsparse(Smatrix *sm, int n)
}
xlnzt[1] = 1;
for (i = 1; i <= n; i++) xlnzt[i+1] = xlnzt[i] + nzt[i];
// Transpose matrix twice to order column indexes
transpose(n, XLNZ, NZSUB, LNZ, xlnzt, nzsubt, lnzt, nzt);
transpose(n, xlnzt, nzsubt, lnzt, XLNZ, NZSUB, LNZ, nzt);
}
// Reclaim memory
free(xlnzt);
free(nzsubt);
@@ -706,11 +705,11 @@ void transpose(int n, int *il, int *jl, int *xl, int *ilt, int *jlt,
int *xlt, int *nzt)
/*
**---------------------------------------------------------------------
** Input: n = matrix order
** il,jl,xl = sparse storage scheme for original matrix
** nzt = work array
** Output: ilt,jlt,xlt = sparse storage scheme for transposed matrix
** Purpose: Determines sparse storage scheme for transpose of a matrix
** Input: n = matrix order
** il,jl,xl = sparse storage scheme for original matrix
** nzt = work array
** Output: ilt,jlt,xlt = sparse storage scheme for transposed matrix
** Purpose: Determines sparse storage scheme for transpose of a matrix
**---------------------------------------------------------------------
*/
{
@@ -735,25 +734,25 @@ int linsolve(Smatrix *sm, int n)
/*
**--------------------------------------------------------------
** Input: sm = sparse matrix struct
n = number of equations
** Output: sm->F = solution values
** returns 0 if solution found, or index of
** equation causing system to be ill-conditioned
** Purpose: solves sparse symmetric system of linear
** equations using Cholesky factorization
**
** NOTE: This procedure assumes that the solution matrix has
** been symbolically factorized with the positions of
** the lower triangular, off-diagonal, non-zero coeffs.
** stored in the following integer arrays:
** XLNZ (start position of each column in NZSUB)
** NZSUB (row index of each non-zero in each column)
** LNZ (position of each NZSUB entry in Aij array)
**
** This procedure has been adapted from subroutines GSFCT and
** GSSLV in the book "Computer Solution of Large Sparse
** Positive Definite Systems" by A. George and J. W-H Liu
** (Prentice-Hall, 1981).
n = number of equations
** Output: sm->F = solution values
** returns 0 if solution found, or index of
** equation causing system to be ill-conditioned
** Purpose: solves sparse symmetric system of linear
** equations using Cholesky factorization
**
** NOTE: This procedure assumes that the solution matrix has
** been symbolically factorized with the positions of
** the lower triangular, off-diagonal, non-zero coeffs.
** stored in the following integer arrays:
** XLNZ (start position of each column in NZSUB)
** NZSUB (row index of each non-zero in each column)
** LNZ (position of each NZSUB entry in Aij array)
**
** This procedure has been adapted from subroutines GSFCT and
** GSSLV in the book "Computer Solution of Large Sparse
** Positive Definite Systems" by A. George and J. W-H Liu
** (Prentice-Hall, 1981).
**--------------------------------------------------------------
*/
{
@@ -766,7 +765,7 @@ int linsolve(Smatrix *sm, int n)
int *NZSUB = sm->NZSUB;
int *link = sm->link;
int *first = sm->first;
int i, istop, istrt, isub, j, k, kfirst, newk;
double bj, diagj, ljk;

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 11/27/2018
Last Updated: 01/01/2019
******************************************************************************
*/
@@ -157,11 +157,11 @@ typedef enum {
} QualType;
typedef enum {
V_CURVE, // volume curve
P_CURVE, // pump curve
E_CURVE, // efficiency curve
H_CURVE, // head loss curve
G_CURVE // general\default curve
VOLUME_CURVE, // volume curve
PUMP_CURVE, // pump curve
EFFIC_CURVE, // efficiency curve
HLOSS_CURVE, // head loss curve
GENERIC_CURVE // generic curve
} CurveType;
typedef enum {
@@ -384,7 +384,7 @@ typedef struct // Node Object
Psource S; // source pointer
double C0; // initial quality
double Ke; // emitter coeff.
char Rpt; // reporting flag
int Rpt; // reporting flag
NodeType Type; // node type
char Comment[MAXMSG+1]; // node comment
} Snode;
@@ -405,7 +405,7 @@ typedef struct // Link Object
double Qa; // low flow limit
LinkType Type; // link type
StatusType Status; // initial status
char Rpt; // reporting flag
int Rpt; // reporting flag
char Comment[MAXMSG+1]; // link Comment
} Slink;
@@ -466,7 +466,7 @@ typedef struct // Field Object of Report Table
{
char Name[MAXID+1]; // name of reported variable
char Units[MAXID+1]; // units of reported variable
char Enabled; // enabled if in table
int Enabled; // enabled if in table
int Precision; // number of decimal places
double RptLim[2]; // lower/upper report limits
} SField;
@@ -544,9 +544,6 @@ typedef struct {
FILE *InFile; // Input file handle
char
Unitsflag, // Unit system flag
Flowflag, // Flow units flag
Pressflag, // Pressure units flag
DefPatID[MAXID+1], // Default demand pattern ID
InpFname[MAXFNAME+1], // Input file name
*Tok[MAXTOKS], // Array of token strings
@@ -565,7 +562,11 @@ typedef struct {
MaxPats, // Pattern count " " "
MaxCurves, // Curve count " " "
Ntokens, // Number of tokens in line of input
Ntitle; // Number of title lines
Ntitle, // Number of title lines
ErrTok, // Index of error-producing token
Unitsflag, // Unit system flag
Flowflag, // Flow units flag
Pressflag; // Pressure units flag
STmplist
*Patlist, // Temporary time pattern list
@@ -604,13 +605,7 @@ typedef struct {
int
Nperiods, // Number of reporting periods
PageSize; // Lines/page in output report/
long
LineNum, // Current line number
PageNum; // Current page number
char
PageSize, // Lines/page in output report/
Rptflag, // Report flag
Tstatflag, // Report time series statistic flag
Summaryflag, // Report summary flag
@@ -619,11 +614,17 @@ typedef struct {
Energyflag, // Energy report flag
Nodeflag, // Node report flag
Linkflag, // Link report flag
Fprinterr; // File write error flag
long
LineNum, // Current line number
PageNum; // Current page number
char
Atime[13], // Clock time (hrs:min:sec)
Rpt1Fname[MAXFNAME+1], // Primary report file name
Rpt2Fname[MAXFNAME+1], // Secondary report file name
DateStamp[26], // Current date & time
Fprinterr; // File write error flag
DateStamp[26]; // Current date & time
SField Field[MAXVAR]; // Output reporting fields
@@ -634,7 +635,9 @@ typedef struct {
char
HydFname[MAXFNAME+1], // Hydraulics file name
OutFname[MAXFNAME+1], // Binary output file name
OutFname[MAXFNAME+1]; // Binary output file name
int
Outflag, // Output file flag
Hydflag, // Hydraulics flag
SaveHflag, // Hydraulic results saved flag
@@ -731,22 +734,20 @@ typedef struct {
DefPat, // Default demand pattern
Epat, // Energy cost time pattern
DemandModel, // Fixed or pressure dependent
Formflag, // Head loss formula flag
Iterations, // Number of hydraulic trials taken
MaxIter, // Max. hydraulic trials allowed
ExtraIter, // Extra hydraulic trials
CheckFreq, // Hydraulic trials between status checks
MaxCheck, // Hydraulic trials limit on status checks
OpenHflag, // Hydraulic system opened flag
Haltflag; // Flag to halt simulation
StatusType
*LinkStatus, // Link status
*OldStatus; // Previous link/tank status
char
OpenHflag, // Hydraulic system opened flag
Formflag; // Head loss formula flag
Smatrix smatrix; // Sparse matrix storage
Smatrix smatrix; // Sparse matrix storage
} Hydraul;
@@ -756,20 +757,18 @@ struct Mempool;
// Water Quality Solver Wrapper
typedef struct {
char
int
Qualflag, // Water quality analysis flag
OpenQflag, // Quality system opened flag
Reactflag, // Reaction indicator
OutOfMemory; // Out of memory indicator
OutOfMemory, // Out of memory indicator
TraceNode, // Source node for flow tracing
*SortedNodes; // Topologically sorted node indexes
char
ChemName[MAXID + 1], // Name of chemical
ChemUnits[MAXID + 1]; // Units of chemical
int
TraceNode, // Source node for flow tracing
*SortedNodes; // Topologically sorted node indexes
double
Ctol, // Water quality tolerance
Diffus, // Diffusivity (sq ft/sec)
@@ -853,9 +852,11 @@ typedef struct Project {
double Ucf[MAXVAR]; // Unit conversion factors
char
int
Openflag, // Project open flag
Warnflag, // Warning flag
Warnflag; // Warning flag
char
Msg[MAXMSG+1], // General-purpose string: errors, messages
Title[MAXTITLE][TITLELEN+1], // Project title
MapFname[MAXFNAME+1], // Map file name