diff --git a/.gitignore b/.gitignore index 163692f..99c1559 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,7 @@ Debug/ *.metagen *.bi *.opensdf +test/ + + diff --git a/LemonTigerJ.v11.suo b/LemonTigerJ.v11.suo index b5f0829..4f787f3 100644 Binary files a/LemonTigerJ.v11.suo and b/LemonTigerJ.v11.suo differ diff --git a/LemonTigerJ.vcxproj b/LemonTigerJ.vcxproj index d8d39ca..cab68ab 100644 --- a/LemonTigerJ.vcxproj +++ b/LemonTigerJ.vcxproj @@ -11,9 +11,11 @@ + + @@ -28,12 +30,14 @@ + + {4B66D9F0-407B-4995-B625-1CA1B72662C6} @@ -73,6 +77,7 @@ Level3 ProgramDatabase Disabled + .\include MachineX86 diff --git a/src/enumstxt.h b/src/enumstxt.h index 6a8404e..a546b7e 100755 --- a/src/enumstxt.h +++ b/src/enumstxt.h @@ -11,6 +11,9 @@ AUTHOR: L. Rossman ********************************************************************** */ +#ifndef ENUMSTXT_H +#define ENUMSTXT_H + char *NodeTxt[] = {t_JUNCTION, t_RESERVOIR, t_TANK}; @@ -133,3 +136,4 @@ char *Fldname[] = {t_ELEV, t_DEMAND, t_HEAD, char *LogoTxt[] = {LOGO1,LOGO2,LOGO3,LOGO4,LOGO5,LOGO6,NULL}; +#endif \ No newline at end of file diff --git a/src/epanet.c b/src/epanet.c index 25cd708..e3da576 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -107,11 +107,6 @@ execute function x and set the error code equal to its return value. ******************************************************************************* */ -/*** New compile directives ***/ //(2.00.11 - LR) -#define CLE /* Compile as a command line executable */ -//#define SOL /* Compile as a shared object library */ -//#define DLL /* Compile as a Windows DLL */ - /*** Need to define WINDOWS to use the getTmpName function ***/ //(2.00.12 - LR) // --- define WINDOWS #undef WINDOWS @@ -131,12 +126,11 @@ execute function x and set the error code equal to its return value. #endif #include #include //(2.00.12 - LR) -#include "hash.h" + #include "text.h" #include "types.h" #include "enumstxt.h" #include "funcs.h" -#define EXTERN #include "vars.h" #include "toolkit.h" @@ -3140,6 +3134,8 @@ char *geterrmsg(int errcode) case 307: strcpy(Msg,ERR307); break; case 308: strcpy(Msg,ERR308); break; case 309: strcpy(Msg,ERR309); break; + + case 401: strcpy(Msg,ERR401); break; default: strcpy(Msg,""); } return(Msg); @@ -3219,7 +3215,7 @@ int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, float *baseDemand) if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); for(d=Node[nodeIndex].D; nnext) n++; if(n!=demandIdx) return(253); - *baseDemand=d->Base*Ucf[FLOW]; + *baseDemand=(float)(d->Base*Ucf[FLOW]); return 0; } int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) diff --git a/src/funcs.h b/src/funcs.h index 1fa5677..d31eca1 100755 --- a/src/funcs.h +++ b/src/funcs.h @@ -25,6 +25,10 @@ AUTHOR: L. Rossman ** NOTE: The exportable functions that can be called ** via the DLL are prototyped in TOOLKIT.H. */ + +#ifndef FUNCS_H +#define FUNCS_H + void initpointers(void); /* Initializes pointers */ int allocdata(void); /* Allocates memory */ void freeTmplist(STmplist *); /* Frees items in linked list */ @@ -279,3 +283,5 @@ int saveepilog(void); /* Saves output file epilog */ /* ------------ INPFILE.C --------------*/ int saveinpfile(char *); /* Saves network to text file */ + +#endif \ No newline at end of file diff --git a/src/hash.h b/src/hash.h index 8195afd..38999d1 100755 --- a/src/hash.h +++ b/src/hash.h @@ -4,6 +4,9 @@ ** */ +#ifndef HASH_H +#define HASH_H + #define HTMAXSIZE 1999 #define NOTFOUND 0 @@ -22,3 +25,4 @@ int HTfind(HTtable *, char *); char *HTfindKey(HTtable *, char *); void HTfree(HTtable *); +#endif \ No newline at end of file diff --git a/src/hydraul.c b/src/hydraul.c index fd3cfb9..bf9cea5 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -58,7 +58,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #define QZERO 1.e-6 /* Equivalent to zero flow */ diff --git a/src/inpfile.c b/src/inpfile.c index e21fa98..36abd63 100755 --- a/src/inpfile.c +++ b/src/inpfile.c @@ -31,7 +31,6 @@ data describing a piping network to a file in EPANET's text format. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" /* Defined in enumstxt.h in EPANET.C */ diff --git a/src/input1.c b/src/input1.c index 15e1ae8..0e9627c 100755 --- a/src/input1.c +++ b/src/input1.c @@ -32,7 +32,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" /* diff --git a/src/input2.c b/src/input2.c index a0fa344..6a1c3d4 100755 --- a/src/input2.c +++ b/src/input2.c @@ -36,7 +36,6 @@ The following utility functions are all called from INPUT3.C #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #define MAXERRS 10 /* Max. input errors reported */ diff --git a/src/input3.c b/src/input3.c index 0d72c37..8954d78 100755 --- a/src/input3.c +++ b/src/input3.c @@ -31,7 +31,6 @@ All functions in this module are called from newline() in INPUT2.C. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" /* Defined in enumstxt.h in EPANET.C */ diff --git a/src/lemontiger.c b/src/lemontiger.c index 5634d22..eff0c04 100644 --- a/src/lemontiger.c +++ b/src/lemontiger.c @@ -5,11 +5,19 @@ #include "lemontiger.h" extern char OutOfMemory; +extern int Haltflag; int ENopeninitHQ() { int errcode = 0; - Statflag = FALSE; //disable status report + + if (Hstep % Qstep) { + errcode = 401; + errmsg(errcode); + return errcode; + } + + Statflag = TRUE; //disable status report if (errcode = ENopenH()) return errcode; @@ -28,6 +36,100 @@ int ENopeninitHQ() { return errcode; } +long timestepLT(void) +/* +**---------------------------------------------------------------- +** Input: none +** Output: returns time step until next change in hydraulics +** Purpose: computes time step to advance hydraulic simulation, but don't update tank levels +** Let nextqual() to do the job. +**---------------------------------------------------------------- +*/ +{ + long n,t,tstep; + + /* Normal time step is hydraulic time step */ + tstep = Hstep; + + /* Revise time step based on time until next demand period */ + n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */ + t = n*Pstep - Htime; /* Time till next period */ + if (t > 0 && t < tstep) tstep = t; + + /* Revise time step based on time until next reporting period */ + t = Rtime - Htime; + if (t > 0 && t < tstep) tstep = t; + + /* Revise time step based on smallest time to fill or drain a tank */ + tanktimestep(&tstep); + + /* Revise time step based on smallest time to activate a control */ + controltimestep(&tstep); + + /* Evaluate rule-based controls (which will also update tank levels) */ + if (Nrules > 0) ruletimestep(&tstep); + + return(tstep); +} + +int nexthydLT(long *tstep) +/* +**-------------------------------------------------------------- +** Input: none +** Output: tstep = pointer to time step (in seconds) +** Returns: error code +** Purpose: finds length of next time step & updates tank +** levels and rule-based contol actions. don't save +** results to hydraulics file. don't consider Report time. +**-------------------------------------------------------------- +*/ +{ + long hydstep; /* Actual time step */ + int errcode = 0; /* Error code */ + + if (Haltflag) Htime = Dur; + + /* Compute next time step & update tank levels */ + *tstep = 0; + hydstep = 0; + if (Htime < Dur) hydstep = timestepLT(); + + /* Compute pumping energy */ + if (Dur == 0) addenergy(0); + else if (Htime < Dur) addenergy(hydstep); + + /* Update current time. */ + if (Htime < Dur) /* More time remains */ + { + Htime += hydstep; + } + else + { + Htime++; /* Force completion of analysis */ + } + *tstep = hydstep; + return(errcode); +} + + +void updateTanklevels() { + int i,n; + + for (i=1; i<=Ntanks; i++) + { + + /* Skip reservoirs */ + if (Tank[i].A == 0.0) continue; + + n = Tank[i].Node; + /* Check if tank full/empty within next second */ + if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; + if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; + + H[n] = tankgrade(i,Tank[i].V); + } +} + int ENrunstepHQ(long* pstime /* Simulation time pointer */ , long* ptleft /* Time left in the simulation*/) { long hydtime; /* Hydraulic solution time */ @@ -35,14 +137,11 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ int errcode = 0; long dt, hstep, tstep; - /* Update reported simulation time */ - *pstime = Qtime; - - /* if needed, push forward hydraulic simulation */ + /* if needed, push forward hydraulic simulation, similar to runqual() */ if (Qtime == Htime) { if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthyd(&hydstep)) + (errcode = nexthydLT(&hydstep)) ) return errcode; /* If simulating WQ: */ if (Qualflag != NONE && Qtime < Dur) { @@ -58,22 +157,21 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ Htime = hydtime + hydstep; } - /* run WQ simulation similar to stepqual() */ + /* run WQ simulation, similar to stepqual() */ tstep = Qstep; - do - { + do { dt = tstep; hstep = Htime - Qtime; - if (hstep < dt) - { + if (hstep < dt) {/* Htime is closer */ dt = hstep; if (Qualflag != NONE) transport(dt); Qtime += dt; + updateTanklevels(); /* if needed, push forward hydraulic simulation */ if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthyd(&hydstep)) + (errcode = nexthydLT(&hydstep)) ) return errcode; if (Qualflag != NONE && Qtime < Dur) { @@ -85,22 +183,44 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ if (Qtime == 0) initsegs(); else reorientsegs(); } - Htime = hydtime + hydstep; - Qtime = hydtime; - } - else - { + + } else { /* Qtime is closer */ if (Qualflag != NONE) transport(dt); Qtime += dt; } tstep -= dt; if (OutOfMemory) errcode = 101; - } while (!errcode && tstep > 0); + } while (!errcode && tstep > 0); /*do it until Qstep is elapsed.*/ *ptleft = Dur - Qtime; if (!errcode && Saveflag && *ptleft == 0) errcode = savefinaloutput(); + + /* if needed, push forward hydraulic simulation again, so that hyd and wq states are consistent. */ + if (Qtime == Htime && Htime < Dur) { + updateTanklevels(); + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthydLT(&hydstep)) + ) return errcode; + // If simulating WQ: + if (Qualflag != NONE && Qtime < Dur) { + + // Compute reaction rate coeffs. + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + // Initialize pipe segments (at time 0) or + // else re-orient segments if flow reverses. + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + Htime = hydtime + hydstep; + } + + + /* Update reported simulation time */ + *pstime = Qtime; + return(errcode); } diff --git a/src/mempool.h b/src/mempool.h index 2e43dde..ede9d44 100755 --- a/src/mempool.h +++ b/src/mempool.h @@ -6,6 +6,10 @@ ** The type alloc_handle_t provides an opaque reference to the ** alloc pool - only the alloc routines know its structure. */ + +#ifndef MEMPOOL_H +#define MEMPOOL_H + #ifndef DLLEXPORT #ifdef DLL #ifdef __cplusplus @@ -24,6 +28,7 @@ #endif #endif + typedef struct { long dummy; @@ -34,3 +39,5 @@ DLLEXPORT char *Alloc(long); DLLEXPORT alloc_handle_t *AllocSetPool(alloc_handle_t *); DLLEXPORT void AllocReset(void); DLLEXPORT void AllocFreePool(void); + +#endif \ No newline at end of file diff --git a/src/output.c b/src/output.c index e25a5d3..ea56057 100755 --- a/src/output.c +++ b/src/output.c @@ -23,7 +23,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "hash.h" #include "vars.h" diff --git a/src/quality.c b/src/quality.c index 8cc1ffe..b6e2134 100755 --- a/src/quality.c +++ b/src/quality.c @@ -59,7 +59,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #include "mempool.h" @@ -106,9 +105,9 @@ int openqual() if (SegPool == NULL) errcode = 101; //(2.00.11 - LR) /* Allocate scratch array & reaction rate array*/ - X = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); + XC = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); R = (double *) calloc((Nlinks+1), sizeof(double)); - ERRCODE(MEMCHECK(X)); + ERRCODE(MEMCHECK(XC)); ERRCODE(MEMCHECK(R)); /* Allocate memory for WQ solver */ @@ -321,7 +320,7 @@ int closequal() free(VolIn); free(MassIn); free(R); - free(X); + free(XC); return(errcode); } @@ -666,7 +665,7 @@ void accumulate(long dt) /* Re-set memory used to accumulate mass & volume */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); memset(MassIn,0,(Nnodes+1)*sizeof(double)); - memset(X,0,(Nnodes+1)*sizeof(double)); + memset(XC,0,(Nnodes+1)*sizeof(double)); /* Compute average conc. of segments adjacent to each node */ /* (For use if there is no transport through the node) */ @@ -686,7 +685,7 @@ void accumulate(long dt) } } for (k=1; k<=Nnodes; k++) - if (VolIn[k] > 0.0) X[k] = MassIn[k]/VolIn[k]; + if (VolIn[k] > 0.0) XC[k] = MassIn[k]/VolIn[k]; /* Move mass from first segment of each pipe into downstream node */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); @@ -767,7 +766,7 @@ void updatenodes(long dt) ** Purpose: updates concentration at all nodes to mixture of accumulated ** inflow from connecting pipes. ** -** Note: Does not account for source flow effects. X[i] contains +** Note: Does not account for source flow effects. XC[i] contains ** average concen. of segments adjacent to node i, used in case ** there was no inflow into i. **--------------------------------------------------------------------------- @@ -780,7 +779,7 @@ void updatenodes(long dt) { if (D[i] < 0.0) VolIn[i] -= D[i]*dt; if (VolIn[i] > 0.0) C[i] = MassIn[i]/VolIn[i]; - else C[i] = X[i]; + else C[i] = XC[i]; } /* Update tank quality */ @@ -809,8 +808,8 @@ void sourceinput(long dt) /* Establish a flow cutoff which indicates no outflow from a node */ qcutoff = 10.0*TINY; - /* Zero-out the work array X */ - memset(X,0,(Nnodes+1)*sizeof(double)); + /* Zero-out the work array XC */ + memset(XC,0,(Nnodes+1)*sizeof(double)); if (Qualflag != CHEM) return; /* Consider each node */ @@ -872,7 +871,7 @@ void sourceinput(long dt) } /* Source concen. contribution = (mass added / outflow volume) */ - X[n] = massadded/volout; + XC[n] = massadded/volout; /* Update total mass added for time period & simulation */ source->Smass += massadded; @@ -923,7 +922,7 @@ void release(long dt) v = q*dt; /* Include source contribution in quality released from node. */ - c = C[n] + X[n]; + c = C[n] + XC[n]; /* If link has a last seg, check if its quality */ /* differs from that of the flow released from node.*/ @@ -952,7 +951,7 @@ void updatesourcenodes(long dt) ** Input: dt = current WQ time step ** Output: none ** Purpose: updates quality at source nodes. -** (X[n] = concen. added by source at node n) +** (XC[n] = concen. added by source at node n) **--------------------------------------------------- */ { @@ -968,7 +967,7 @@ void updatesourcenodes(long dt) if (source == NULL) continue; /* Add source to current node concen. */ - C[n] += X[n]; + C[n] += XC[n]; /* For tanks, node concen. = internal concen. */ if (n > Njuncs) diff --git a/src/report.c b/src/report.c index b021461..d74c1a7 100755 --- a/src/report.c +++ b/src/report.c @@ -38,7 +38,6 @@ formatted string S to the report file. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #define MAXCOUNT 10 /* Max. # of disconnected nodes listed */ diff --git a/src/rules.c b/src/rules.c index aa2e003..e6ac10a 100755 --- a/src/rules.c +++ b/src/rules.c @@ -33,7 +33,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" struct Premise /* Rule Premise Clause */ diff --git a/src/smatrix.c b/src/smatrix.c index 7b0e7f3..f95dada 100755 --- a/src/smatrix.c +++ b/src/smatrix.c @@ -42,7 +42,6 @@ Linsolve() solves the linearized system of hydraulic equations. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" int *Degree; /* Number of links adjacent to each node */ diff --git a/src/testLT.c b/src/testLT.c index 97b29b9..ba173b8 100644 --- a/src/testLT.c +++ b/src/testLT.c @@ -16,60 +16,91 @@ int main(int argc, char* argv[]) { long stime = 0; //simulation time point, = t = Htime long step = 1; //time to next time point, = tstep = hydstep long tleft = 0; //time left in the simulation - int id; // some node id + int id, id2, id3; // some node id float value; // some node/link value - int TIME_A = 3600*10; - int TIME_B = 3600*20; //two time points for testing + int TIME_A = 3600*3; + int TIME_B = 3600*6; //two time points for testing + int TIME_C = 3600*10; /* Asychronous solver (old epanet) */ - + printf("*****Original EPANET results******\n"); + if (err=ENopen(argv[1], argv[2], "")) return err; - ENgetnodeindex("184", &id); - + ENgetnodeindex("184", &id); // a node far away from water source + ENgetlinkindex("101", &id2); // a link close to the lake + ENgetnodeindex("199", &id3); // a node close to the lake (tracer point) + for (ENopenH(), ENinitH(1), step=1; // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute - step>0; ) { + step>0; ENnextH(&step)) { - ENrunH(&stime); ENnextH(&step); - printf("stime = %d sec, step = %d sec.\n", stime, step); + ENrunH(&stime); + + + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { // grab some results + printf("Hydraulic simulation time = %d sec, step = %d sec.\n", stime, step); - if (stime == TIME_A || stime == TIME_B) { // grab some results ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = %f.\n", value); + printf("Node 184's head = \t%f.\n", value); + ENgetlinkvalue(id2, EN_FLOW, &value); + printf("Link 101's flowrate = \t%f. \n", value); + ENgetnodevalue(id3, EN_HEAD, &value); + printf("Node 199's head = \t%f.\n", value); } } ENcloseH(); - printf("Reset time pointer and run WQ.\n"); - for (ENopenQ(), ENinitQ(0), step=1; step>0; ) { - /* this operation resets the internal time pointer (back to 0)*/ - ENrunQ(&stime); ENnextQ(&step); - printf("stime = %d sec, step = %d sec.\n", stime, step); + printf("\nReset time pointer and run WQ.\n"); + for (step=1, ENopenQ(), ENinitQ(0); // this operation resets the internal time pointer (back to 0) + step>0; ENnextQ(&step)) { + ENrunQ(&stime); + // grab some results - if (stime == TIME_A || stime == TIME_B) { + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { + printf("WQ simulation time = %d sec, step = %d sec.\n", stime, step); + ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = %f.\n", value); + printf("Node 184's quality = \t%f.\n", value); + ENgetnodevalue(id3, EN_QUALITY, &value); + printf("Node 199's quality = \t%f.\n", value); } } ENcloseQ(); ENclose(); - + /* Sychronous solver (LemonTiger) */ - + printf("\n\n*****LemonTiger results******\n\n"); + if (err=ENopen(argv[1], argv[2], "")) return err; for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { ENrunstepHQ(&stime, &tleft); - printf("stime = %d sec, time left = %d sec.\n", stime, tleft); + + - if (stime == TIME_A || stime == TIME_B) { + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { + //if (! (stime%1800)){ + printf("Simulation = %d sec, time left = %d sec.\n", stime, tleft); ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = %f.\n", value); + printf("Node 184's head = \t%f.\n", value); + ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = %f.\n", value); + printf("Node 184's quality = \t%f.\n", value); + + ENgetnodevalue(id3, EN_HEAD, &value); + printf("Node 199's head = \t%f.\n", value); + + ENgetnodevalue(id3, EN_QUALITY, &value); + printf("Node 199's quality = \t%f.\n", value); + + ENgetlinkvalue(id2, EN_FLOW, &value); + printf("Link 101's flowrate = \t%f. \n", value); + + + printf("\n"); } } ENcloseHQ(); diff --git a/src/text.h b/src/text.h index 0a0e5c0..890e099 100755 --- a/src/text.h +++ b/src/text.h @@ -14,6 +14,8 @@ AUTHOR: L. Rossman **************************************************** */ /* ------------ Keyword Dictionary ---------- */ +#ifndef TEXT_H +#define TEXT_H #define w_USE "USE" #define w_SAVE "SAVE" @@ -501,6 +503,8 @@ AUTHOR: L. Rossman #define ERR308 "File Error 308: cannot save results to file." #define ERR309 "File Error 309: cannot save results to report file." +#define ERR401 "Sync Error 401: Qstep is not dividable by Hstep. Can't sync." + #define R_ERR201 "Input Error 201: syntax error in following line of " #define R_ERR202 "Input Error 202: illegal numeric value in following line of " #define R_ERR203 "Input Error 203: undefined node in following line of " @@ -528,3 +532,4 @@ AUTHOR: L. Rossman #define WARN5 "WARNING: Valves cannot deliver enough flow." #define WARN6 "WARNING: System has negative pressures." +#endif \ No newline at end of file diff --git a/src/toolkit.h b/src/toolkit.h index 016a31f..3e0501b 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -15,6 +15,15 @@ AUTHOR: L. Rossman ******************************************************************* */ +#ifndef TOOLKIT_H +#define TOOLKIT_H + +/*** New compile directives ***/ //(2.00.11 - LR) +//#define CLE /* Compile as a command line executable */ +#define CLE_LT /* LemonTiger test */ +//#define SOL /* Compile as a shared object library */ +//#define DLL /* Compile as a Windows DLL */ + #ifndef DLLEXPORT #ifdef DLL @@ -247,3 +256,5 @@ extern "C" { #if defined(__cplusplus) } #endif + +#endif \ No newline at end of file diff --git a/src/types.h b/src/types.h index 68a495e..81fe7f1 100755 --- a/src/types.h +++ b/src/types.h @@ -17,6 +17,8 @@ AUTHOR: L. Rossman ********************************************************************** */ +#ifndef TYPES_H +#define TYPES_H /*********************************************************/ /* All floats have been re-declared as doubles (7/3/07). */ @@ -451,3 +453,4 @@ enum HdrType /* Type of table heading */ NODEHDR, /* Node Results */ LINKHDR}; /* Link Results */ +#endif \ No newline at end of file diff --git a/src/vars.h b/src/vars.h index b8b821b..b6d9b49 100755 --- a/src/vars.h +++ b/src/vars.h @@ -11,15 +11,21 @@ AUTHOR: L. Rossman ************************************************************************ */ -EXTERN FILE *InFile, /* Input file pointer */ +#ifndef VARS_H +#define VARS_H + +#include +#include "hash.h" + + FILE *InFile, /* Input file pointer */ *OutFile, /* Output file pointer */ *RptFile, /* Report file pointer */ *HydFile, /* Hydraulics file pointer */ *TmpOutFile; /* Temporary file handle */ -EXTERN long HydOffset, /* Hydraulics file byte offset */ + long HydOffset, /* Hydraulics file byte offset */ OutOffset1, /* 1st output file byte offset */ OutOffset2; /* 2nd output file byte offset */ -EXTERN char Msg[MAXMSG+1], /* Text of output message */ + char Msg[MAXMSG+1], /* Text of output message */ InpFname[MAXFNAME+1], /* Input file name */ Rpt1Fname[MAXFNAME+1], /* Primary report file name */ Rpt2Fname[MAXFNAME+1], /* Secondary report file name */ @@ -59,7 +65,7 @@ EXTERN char Msg[MAXMSG+1], /* Text of output message */ OpenQflag, /* Quality system opened flag */ SaveQflag, /* Quality results saved flag */ Saveflag; /* General purpose save flag */ -EXTERN int MaxNodes, /* Node count from input file */ + int MaxNodes, /* Node count from input file */ MaxLinks, /* Link count from input file */ MaxJuncs, /* Junction count */ MaxPipes, /* Pipe count */ @@ -91,7 +97,7 @@ EXTERN int MaxNodes, /* Node count from input file */ PageSize, /* Lines/page in output report */ CheckFreq, /* Hydraulics solver parameter */ MaxCheck; /* Hydraulics solver parameter */ -EXTERN double Ucf[MAXVAR], /* Unit conversion factors */ + double Ucf[MAXVAR], /* Unit conversion factors */ Ctol, /* Water quality tolerance */ Htol, /* Hydraulic head tolerance */ Qtol, /* Flow rate tolerance */ @@ -120,7 +126,7 @@ EXTERN double Ucf[MAXVAR], /* Unit conversion factors */ Wwall, /* Avg. wall reaction rate */ Wtank, /* Avg. tank reaction rate */ Wsource; /* Avg. mass inflow */ -EXTERN long Tstart, /* Starting time of day (sec) */ + long Tstart, /* Starting time of day (sec) */ Hstep, /* Nominal hyd. time step (sec) */ Qstep, /* Quality time step (sec) */ Pstep, /* Time pattern time step (sec) */ @@ -133,32 +139,33 @@ EXTERN long Tstart, /* Starting time of day (sec) */ Hydstep, /* Actual hydraulic time step */ Rulestep, /* Rule evaluation time step */ Dur; /* Duration of simulation (sec) */ -EXTERN SField Field[MAXVAR]; /* Output reporting fields */ + SField Field[MAXVAR]; /* Output reporting fields */ /* Array pointers not allocated and freed in same routine */ -EXTERN char *S, /* Link status */ + char *S, /* Link status */ *OldStat; /* Previous link/tank status */ -EXTERN double *D, /* Node actual demand */ + double *D, /* Node actual demand */ *C, /* Node actual quality */ *E, /* Emitter flows */ *K, /* Link settings */ *Q, /* Link flows */ *R, /* Pipe reaction rate */ - *X; /* General purpose array */ -EXTERN double *H; /* Node heads */ -EXTERN STmplist *Patlist; /* Temporary time pattern list */ -EXTERN STmplist *Curvelist; /* Temporary list of curves */ -EXTERN Spattern *Pattern; /* Time patterns */ -EXTERN Scurve *Curve; /* Curve data */ -EXTERN Snode *Node; /* Node data */ -EXTERN Slink *Link; /* Link data */ -EXTERN Stank *Tank; /* Tank data */ -EXTERN Spump *Pump; /* Pump data */ -EXTERN Svalve *Valve; /* Valve data */ -EXTERN Scontrol *Control; /* Control data */ -EXTERN HTtable *Nht, *Lht; /* Hash tables for ID labels */ -EXTERN Padjlist *Adjlist; /* Node adjacency lists */ -EXTERN int _relativeError, _iterations; /* Info about hydraulic solution */ + *X, /* General purpose array */ + *XC; /* General Purpose array - WQ */ + double *H; /* Node heads */ + STmplist *Patlist; /* Temporary time pattern list */ + STmplist *Curvelist; /* Temporary list of curves */ + Spattern *Pattern; /* Time patterns */ + Scurve *Curve; /* Curve data */ + Snode *Node; /* Node data */ + Slink *Link; /* Link data */ + Stank *Tank; /* Tank data */ + Spump *Pump; /* Pump data */ + Svalve *Valve; /* Valve data */ + Scontrol *Control; /* Control data */ + HTtable *Nht, *Lht; /* Hash tables for ID labels */ + Padjlist *Adjlist; /* Node adjacency lists */ + int _relativeError, _iterations; /* Info about hydraulic solution */ /* ** NOTE: Hydraulic analysis of the pipe network at a given point in time @@ -180,18 +187,20 @@ EXTERN int _relativeError, _iterations; /* Info about hydraulic solution */ ** The following arrays are used to efficiently manage this sparsity: */ -EXTERN double *Aii, /* Diagonal coeffs. of A */ + double *Aii, /* Diagonal coeffs. of A */ *Aij, /* Non-zero, off-diagonal coeffs. of A */ *F; /* Right hand side coeffs. */ -EXTERN double *P, /* Inverse headloss derivatives */ + double *P, /* Inverse headloss derivatives */ *Y; /* Flow correction factors */ -EXTERN int *Order, /* Node-to-row of A */ + int *Order, /* Node-to-row of A */ *Row, /* Row-to-node of A */ *Ndx; /* Index of link's coeff. in Aij */ /* ** The following arrays store the positions of the non-zero coeffs. ** of the lower triangular portion of A whose values are stored in Aij: */ -EXTERN int *XLNZ, /* Start position of each column in NZSUB */ + int *XLNZ, /* Start position of each column in NZSUB */ *NZSUB, /* Row index of each coeff. in each column */ *LNZ; /* Position of each coeff. in Aij array */ + +#endif \ No newline at end of file diff --git a/test/Net3.rpt b/test/Net3.rpt deleted file mode 100644 index 91c383f..0000000 --- a/test/Net3.rpt +++ /dev/null @@ -1,102 +0,0 @@ - Page 1 Tue Jan 22 11:23:06 2013 - - ****************************************************************** - * E P A N E T * - * Hydraulic and Water Quality * - * Analysis for Pipe Networks * - * Version 2.00.12 * - ****************************************************************** - - Analysis begun Tue Jan 22 11:23:06 2013 - - - Hydraulic Status: - ----------------------------------------------------------------------- - 0:00:00: Balanced after 5 trials - 0:00:00: Reservoir River is emptying - 0:00:00: Reservoir Lake is closed - 0:00:00: Tank 1 is filling at 13.10 ft - 0:00:00: Tank 2 is emptying at 23.50 ft - 0:00:00: Tank 3 is filling at 29.00 ft - - 1:00:00: Pump 10 changed by timer control - 1:00:00: Balanced after 7 trials - 1:00:00: Reservoir Lake is emptying - 1:00:00: Pump 10 changed from closed to open - - 2:00:00: Balanced after 3 trials - 2:00:00: Tank 2 is filling at 20.90 ft - - 3:00:00: Balanced after 2 trials - - 4:00:00: Balanced after 3 trials - - 4:13:33: Pump 335 changed by Tank 1 control - 4:13:33: Pipe 330 changed by Tank 1 control - 4:13:33: Balanced after 4 trials - 4:13:33: Pipe 330 changed from closed to open - 4:13:33: Pump 335 changed from open to closed - - 5:00:00: Balanced after 3 trials - 5:00:00: Tank 3 is emptying at 34.30 ft - - 6:00:00: Balanced after 3 trials - 6:00:00: Tank 3 is filling at 34.12 ft - - 7:00:00: Balanced after 3 trials - - 8:00:00: Balanced after 2 trials - - 9:00:00: Balanced after 3 trials - 9:00:00: Tank 3 is emptying at 35.15 ft - - 10:00:00: Balanced after 2 trials - 10:00:00: Tank 1 is emptying at 22.20 ft - - 11:00:00: Balanced after 3 trials - 11:00:00: Tank 2 is emptying at 27.70 ft - - 12:00:00: Balanced after 2 trials - 12:00:00: Tank 2 is filling at 27.64 ft - - 13:00:00: Balanced after 3 trials - 13:00:00: Tank 1 is filling at 21.73 ft - - 14:00:00: Balanced after 3 trials - - 15:00:00: Pump 10 changed by timer control - 15:00:00: Balanced after 5 trials - 15:00:00: Reservoir Lake is closed - 15:00:00: Tank 1 is emptying at 21.98 ft - 15:00:00: Tank 2 is emptying at 28.20 ft - 15:00:00: Pump 10 changed from open to closed - - 16:00:00: Balanced after 3 trials - - 17:00:00: Balanced after 2 trials - - 18:00:00: Balanced after 3 trials - - 19:00:00: Balanced after 2 trials - - 20:00:00: Balanced after 3 trials - - 21:00:00: Balanced after 2 trials - - 21:19:39: Pump 335 changed by Tank 1 control - 21:19:39: Pipe 330 changed by Tank 1 control - 21:19:39: Balanced after 5 trials - 21:19:39: Tank 1 is filling at 17.10 ft - 21:19:39: Tank 3 is filling at 29.68 ft - 21:19:39: Pipe 330 changed from open to closed - 21:19:39: Pump 335 changed from closed to open - - 22:00:00: Balanced after 3 trials - 22:00:00: Tank 1 is emptying at 17.30 ft - - 23:00:00: Balanced after 3 trials - - 24:00:00: Balanced after 4 trials - 24:00:00: Tank 1 is filling at 15.79 ft - - Analysis ended Tue Jan 22 11:23:18 2013