From 24d6b916071fdcaea6411e6ab4e392dfd9d60b7c Mon Sep 17 00:00:00 2001 From: Lew Rossman Date: Tue, 22 May 2018 11:12:14 -0400 Subject: [PATCH] Changes to get Net1.inp to run --- run/main.c | 13 +++--- src/epanet.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++---- src/funcs.h | 6 ++- src/hydraul.c | 3 +- src/quality.c | 14 ++++-- src/types.h | 7 +-- 6 files changed, 140 insertions(+), 27 deletions(-) diff --git a/run/main.c b/run/main.c index c2480b1..bda132f 100644 --- a/run/main.c +++ b/run/main.c @@ -5,9 +5,9 @@ #define MAXMSG 255 /* Max. # characters in message text */ #define MAXWARNCODE 99 /* text copied here, no more need of include "text.h" */ -#define FMT01 "\nEPANET Version %d.%d.%d\n" +#define FMT01 "\nEPANET Version %d.%d.%d" #define FMT03 "\n Correct syntax is:\n %s \n" -#define FMT09 "\nEPANET completed.\n" +#define FMT09 "\n\nEPANET completed." #define FMT10 "\nEPANET completed. There are warnings." #define FMT11 "\nEPANET completed. There are errors." @@ -87,7 +87,8 @@ int main(int argc, char *argv[]) /* Call the main control function */ if (strlen(f2)> 0) { /* use stdout for progress messages */ - errcode = ENepanet(f1,f2,f3,writeConsole); + //errcode = ENepanet(f1,f2,f3,writeConsole); + errcode = ENepanet(f1, f2, f3, NULL); } else { /* use stdout for reporting, no progress messages */ @@ -101,21 +102,21 @@ int main(int argc, char *argv[]) return(0); } else { + if (errcode > MAXWARNCODE) printf("\n Fatal Error: "); ENgeterror(errcode, errmsg, MAXMSG); writeConsole(errmsg); if (errcode > MAXWARNCODE) { - /* error */ + // error // writeConsole(FMT11); return(errcode); } else { - /* warning */ + // warning // writeConsole(FMT10); return(0); } } - } /* End of main */ diff --git a/src/epanet.c b/src/epanet.c index b4768ed..b8f476c 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -108,6 +108,10 @@ execute function x and set the error code equal to its return value. #ifdef __WIN32__ #define WINDOWS #endif +#ifdef WINDOWS +#include +#endif + /************************************************************/ #include @@ -166,218 +170,295 @@ int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, EN_free(_defaultModel); return (errcode); } + int DLLEXPORT ENopen(char *f1, char *f2, char *f3) { int errcode = 0; ERRCODE(EN_alloc(&_defaultModel)); EN_open(_defaultModel, f1, f2, f3); return (errcode); } + int DLLEXPORT ENsaveinpfile(char *filename) { return EN_saveinpfile(_defaultModel, filename); } + int DLLEXPORT ENclose() { return EN_close(_defaultModel); } + int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } + int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } + int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); } + int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); } + int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); } + int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } + int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } + int DLLEXPORT ENsavehydfile(char *filename) { return EN_savehydfile(_defaultModel, filename); } + int DLLEXPORT ENusehydfile(char *filename) { return EN_usehydfile(_defaultModel, filename); } + int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } + int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); } + int DLLEXPORT ENinitQ(int saveflag) { return EN_initQ(_defaultModel, saveflag); } + int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); } + int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); } + int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); } + int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); } + int DLLEXPORT ENwriteline(char *line) { return EN_writeline(_defaultModel, line); } + int DLLEXPORT ENreport() { return EN_report(_defaultModel); } + int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } + int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } + int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); } + int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) { return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, level); } + int DLLEXPORT ENgetcount(int code, int *count) { return EN_getcount(_defaultModel, (EN_CountType)code, count); } + int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) { return EN_getoption(_defaultModel, (EN_Option)code, value); } + int DLLEXPORT ENgettimeparam(int code, long *value) { return EN_gettimeparam(_defaultModel, code, value); } + int DLLEXPORT ENgetflowunits(int *code) { return EN_getflowunits(_defaultModel, code); } + int DLLEXPORT ENsetflowunits(int code) { return EN_setflowunits(_defaultModel, code); } + int DLLEXPORT ENgetpatternindex(char *id, int *index) { return EN_getpatternindex(_defaultModel, id, index); } + int DLLEXPORT ENgetpatternid(int index, char *id) { return EN_getpatternid(_defaultModel, index, id); } + int DLLEXPORT ENgetpatternlen(int index, int *len) { return EN_getpatternlen(_defaultModel, index, len); } + int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value) { return EN_getpatternvalue(_defaultModel, index, period, value); } + int DLLEXPORT ENgetcurveindex(char *id, int *index) { return EN_getcurveindex(_defaultModel, id, index); } + int DLLEXPORT ENgetcurveid(int index, char *id) { return EN_getcurveid(_defaultModel, index, id); } + int DLLEXPORT ENgetcurvelen(int index, int *len) { return EN_getcurvelen(_defaultModel, index, len); } + int DLLEXPORT ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { return EN_getcurvevalue(_defaultModel, index, pnt, x, y); } + int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode) { return EN_getqualtype(_defaultModel, qualcode, tracenode); } + int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode) { return EN_getqualinfo(_defaultModel, qualcode, chemname, chemunits, tracenode); } + int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) { return EN_geterror(errcode, errmsg, n); } + int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) { return EN_getstatistic(_defaultModel, code, value); } + int DLLEXPORT ENgetnodeindex(char *id, int *index) { return EN_getnodeindex(_defaultModel, id, index); } + int DLLEXPORT ENgetnodeid(int index, char *id) { return EN_getnodeid(_defaultModel, index, id); } + int DLLEXPORT ENgetnodetype(int index, int *code) { return EN_getnodetype(_defaultModel, index, code); } + int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { return EN_getcoord(_defaultModel, index, x, y); } + int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { return EN_setcoord(_defaultModel, index, x, y); } + int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) { return EN_getnodevalue(_defaultModel, index, code, value); } + int DLLEXPORT ENgetlinkindex(char *id, int *index) { return EN_getlinkindex(_defaultModel, id, index); } + int DLLEXPORT ENgetlinkid(int index, char *id) { return EN_getlinkid(_defaultModel, index, id); } + int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) { return EN_getlinktype(_defaultModel, index, code); } + int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) { return EN_getlinknodes(_defaultModel, index, node1, node2); } + int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) { return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value); } + int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) { return EN_getcurve(_defaultModel, curveIndex, id, nValues, xValues, yValues); } + int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) { return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, level); } + int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) { return EN_setnodevalue(_defaultModel, index, code, v); } + int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) { return EN_setlinkvalue(_defaultModel, index, code, v); } + int DLLEXPORT ENaddpattern(char *id) { return EN_addpattern(_defaultModel, id); } + int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) { return EN_setpattern(_defaultModel, index, f, n); } + int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value) { return EN_setpatternvalue(_defaultModel, index, period, value); } + int DLLEXPORT ENaddcurve(char *id) { return EN_addcurve(_defaultModel, id); } + int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n) { return EN_setcurve(_defaultModel, index, x, y, n); } + int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { return EN_setcurvevalue(_defaultModel, index, pnt, x, y); } + int DLLEXPORT ENsettimeparam(int code, long value) { return EN_settimeparam(_defaultModel, code, value); } + int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) { return EN_setoption(_defaultModel, code, v); } + int DLLEXPORT ENsetstatusreport(int code) { return EN_setstatusreport(_defaultModel, code); } + int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode) { return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits, tracenode); } + int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex) { return EN_getheadcurveindex(_defaultModel, index, curveindex); } + int DLLEXPORT ENsetheadcurveindex(int index, int curveindex) { return EN_setheadcurveindex(_defaultModel, index, curveindex); } + int DLLEXPORT ENgetpumptype(int index, int *type) { return EN_getpumptype(_defaultModel, index, type); } + int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands) { return EN_getnumdemands(_defaultModel, nodeIndex, numDemands); } + int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { return EN_getbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand); } + int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) { return EN_setbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand); } + int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) { return EN_getdemandpattern(_defaultModel, nodeIndex, demandIdx, pattIdx); } + int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value) { return EN_getaveragepatternvalue(_defaultModel, index, value); } -int DLLEXPORT ENgetrule(int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority) { + +int DLLEXPORT ENgetrule(int index, int *nPremises, int *nTrueActions, + int *nFalseActions, EN_API_FLOAT_TYPE *priority) { return EN_getrule(_defaultModel, index, nPremises, nTrueActions, nFalseActions, priority); } @@ -405,19 +486,23 @@ int DLLEXPORT ENsetpremisevalue(int indexRule, int indexPremise, EN_API_FLOAT_TY return EN_setpremisevalue(_defaultModel, indexRule, indexPremise, value); } -int DLLEXPORT ENgettrueaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting){ +int DLLEXPORT ENgettrueaction(int indexRule, int indexAction, int *indexLink, + int *status, EN_API_FLOAT_TYPE *setting){ return EN_gettrueaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); } -int DLLEXPORT ENsettrueaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting){ +int DLLEXPORT ENsettrueaction(int indexRule, int indexAction, int indexLink, + int status, EN_API_FLOAT_TYPE setting){ return EN_settrueaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); } -int DLLEXPORT ENgetfalseaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting){ +int DLLEXPORT ENgetfalseaction(int indexRule, int indexAction, int *indexLink, + int *status, EN_API_FLOAT_TYPE *setting){ return EN_getfalseaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); } -int DLLEXPORT ENsetfalseaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting){ +int DLLEXPORT ENsetfalseaction(int indexRule, int indexAction, int indexLink, + int status, EN_API_FLOAT_TYPE setting){ return EN_setfalseaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); } @@ -428,16 +513,20 @@ int DLLEXPORT ENgetruleID(int indexRule, char* id){ int DLLEXPORT ENsetlinktype(char *id, EN_LinkType toType) { return EN_setlinktype(_defaultModel, id, toType); } + int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType) { return EN_addnode(_defaultModel, id, nodeType); } + int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode) { return EN_addlink(_defaultModel, id, linkType, fromNode, toNode); } + int DLLEXPORT ENdeletelink(int index) { return EN_deletelink(_defaultModel, index); } + int DLLEXPORT ENdeletenode(int index) { return EN_deletenode(_defaultModel, index); } @@ -707,7 +796,6 @@ int DLLEXPORT EN_solveH(EN_Project *p) tstep = 0; ERRCODE(EN_runH(p, &t)); ERRCODE(EN_nextH(p, &tstep)); - /*** Updated 6/24/02 ***/ writecon("\b\b\b\b\b\b\b\b\b\b"); } while (tstep > 0); @@ -825,8 +913,10 @@ int DLLEXPORT EN_initH(EN_Project *p, int flag) errcode = openhydfile(p); if (!errcode) p->save_options.Saveflag = TRUE; - else + else { errmsg(p, errcode); + return errcode; + } } /* Initialize hydraulics */ @@ -1546,7 +1636,7 @@ int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { strncpy(errmsg, WARN6, n); break; default: - geterrmsg(n, newMsg); + geterrmsg(errcode, newMsg); strncpy(errmsg, newMsg, n); } if (strlen(errmsg) == 0) @@ -3330,7 +3420,7 @@ int openhydfile(EN_Project *p) out->HydFile = NULL; switch (out->Hydflag) { case SCRATCH: - getTmpName(p, out->HydFname); + getTmpName(p, out->HydFname); out->HydFile = fopen(out->HydFname, "w+b"); break; case SAVE: @@ -3748,7 +3838,7 @@ void freedata(EN_Project *p) ---------------------------------------------------------------- */ -/*** New function for 2.00.12 ***/ +/*** New function for 2.00.12 ***/ // DEPRECATED char *getTmpName(EN_Project *p, char *fname) // // Input: fname = file name string @@ -3757,6 +3847,19 @@ char *getTmpName(EN_Project *p, char *fname) // { out_file_t *out = &p->out_files; +#ifdef _WIN32 + TCHAR tmpFileName[MAXFNAME]; + TCHAR tmpPathName[MAXFNAME]; + int rtnValue = GetTempPath(MAXFNAME, tmpPathName); + if (rtnValue == 0 || rtnValue > MAXFNAME) return 0; + rtnValue = GetTempFileName(tmpPathName, TEXT("EN"), 0, tmpFileName); + if (rtnValue > 0) strncpy(fname, tmpFileName, MAXFNAME); + + +/////////////////// DEPRECATED ///////////////////////////////////// +// There is an OS limit on the number of times tmpnam will return a +// unique file name and it is not thread safe. +/* // --- for Windows systems: #ifdef WINDOWS // --- use system function tmpnam() to create a temporary file name @@ -3782,6 +3885,7 @@ char *getTmpName(EN_Project *p, char *fname) // --- now add the prefix to the file name strcat(fname, name); +*/ // --- for non-Windows systems: #else diff --git a/src/funcs.h b/src/funcs.h index b006c78..303f44b 100755 --- a/src/funcs.h +++ b/src/funcs.h @@ -115,11 +115,13 @@ void changestatus(EN_Network *net, int, StatType, double); /* Changes status /* -------------- RULES.C --------------*/ void initrules(rules_t *rules); /* Initializes rule base */ -void addrule(parser_data_t *par, char *); /* Adds rule to rule base */ +void addrule(parser_data_t *par, char *); /* Adds rule to rule base */ int allocrules(EN_Project *pr); /* Allocates memory for rule */ int ruledata(EN_Project *pr); /* Processes rule input data */ -int checkrules(EN_Project *pr, long); /* Checks all rules */ +int checkrules(EN_Project *pr, long); /* Checks all rules */ void freerules(EN_Project *pr); /* Frees rule base memory */ +int writeRuleinInp(EN_Project *pr, FILE *f, /* Writes rule to an INP file */ + int RuleIdx); /* ------------- REPORT.C --------------*/ int writereport(EN_Project *pr); /* Writes formatted report */ diff --git a/src/hydraul.c b/src/hydraul.c index 8f1bcd7..f4eb45c 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -628,7 +628,7 @@ void demands(EN_Project *pr) long k,p; double djunc, sum; Pdemand demand; - + EN_Network *net = &pr->network; hydraulics_t *hyd = &pr->hydraulics; time_options_t *top = &pr->time_options; @@ -680,6 +680,7 @@ void demands(EN_Project *pr) setlinksetting(pr, i, net->Pattern[j].F[k], &hyd->LinkStatus[i], &hyd->LinkSetting[i]); } } + } /* End of demands */ diff --git a/src/quality.c b/src/quality.c index 5308e2c..03e29b6 100644 --- a/src/quality.c +++ b/src/quality.c @@ -161,6 +161,9 @@ void initqual(EN_Project *pr) net->Node[i].S->Smass = 0.0; } + qu->QTempVolumes = + calloc(net->Ntanks, + sizeof(double)); // keep track of next tank volumes. qu->QTankVolumes = calloc(net->Ntanks, sizeof(double)); // keep track of previous step's tank volumes. @@ -287,7 +290,7 @@ int nextqual(EN_Project *pr, long *tstep) { long hydstep; /* Hydraulic solution time step */ int errcode = 0; - double *tankVolumes; + //double *tankVolumes = NULL; int i; EN_Network *net; hydraulics_t *hyd; @@ -315,10 +318,10 @@ int nextqual(EN_Project *pr, long *tstep) // if we're operating in stepwise mode, capture the tank levels so we can // restore them later. if (hyd->OpenHflag) { - tankVolumes = calloc(net->Ntanks, sizeof(double)); + //tankVolumes = calloc(net->Ntanks, sizeof(double)); for (i = 1; i <= net->Ntanks; ++i) { if (net->Tank[i].A != 0) { // skip reservoirs - tankVolumes[i - 1] = net->Tank[i].V; + qu->QTempVolumes[i - 1] = net->Tank[i].V; } } @@ -359,7 +362,7 @@ int nextqual(EN_Project *pr, long *tstep) for (i = 1; i <= net->Ntanks; i++) { if (net->Tank[i].A != 0) { // skip reservoirs again int n = net->Tank[i].Node; - net->Tank[i].V = tankVolumes[i - 1]; + net->Tank[i].V = qu->QTempVolumes[i - 1]; hyd->NodeHead[n] = tankgrade(pr, i, net->Tank[i].V); } } @@ -370,7 +373,7 @@ int nextqual(EN_Project *pr, long *tstep) } } - free(tankVolumes); + //free(tankVolumes); } return (errcode); @@ -448,6 +451,7 @@ int closequal(EN_Project *pr) free(qu->MassIn); free(qu->PipeRateCoeff); free(qu->TempQual); + free(qu->QTempVolumes); free(qu->QTankVolumes); free(qu->QLinkFlow); return (errcode); diff --git a/src/types.h b/src/types.h index 920c779..a3aa962 100755 --- a/src/types.h +++ b/src/types.h @@ -542,6 +542,7 @@ typedef struct { Climit, /// Limiting potential quality *NodeQual, /// Node quality state *TempQual, /// General purpose array for water quality + *QTempVolumes, *QTankVolumes, *QLinkFlow, *PipeRateCoeff; @@ -551,12 +552,12 @@ typedef struct { Qtime; /// Current quality time (sec) char OutOfMemory; /* Out of memory indicator */ - alloc_handle_t *SegPool; // Memory pool for water quality segments + alloc_handle_t *SegPool; // Memory pool for water quality segments Pseg FreeSeg; /* Pointer to unused segment */ Pseg *FirstSeg, /* First (downstream) segment in each pipe */ - *LastSeg; /* Last (upstream) segment in each pipe */ - FlowDirection *FlowDir; /* Flow direction for each pipe */ + *LastSeg; /* Last (upstream) segment in each pipe */ + FlowDirection *FlowDir; /* Flow direction for each pipe */ double *VolIn; /* Total volume inflow to node */ double *MassIn; /* Total mass inflow to node */ double Sc; /* Schmidt Number */