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