Solved the tank level issue. LemonTigerJ now gives right hyd/WQ results.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -61,4 +61,7 @@ Debug/
|
||||
*.metagen
|
||||
*.bi
|
||||
*.opensdf
|
||||
test/
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -11,9 +11,11 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\epanet2.h" />
|
||||
<ClInclude Include="src\enumstxt.h" />
|
||||
<ClInclude Include="src\funcs.h" />
|
||||
<ClInclude Include="src\hash.h" />
|
||||
<ClInclude Include="src\lemontiger.h" />
|
||||
<ClInclude Include="src\mempool.h" />
|
||||
<ClInclude Include="src\text.h" />
|
||||
<ClInclude Include="src\toolkit.h" />
|
||||
@@ -28,12 +30,14 @@
|
||||
<ClCompile Include="src\input1.c" />
|
||||
<ClCompile Include="src\input2.c" />
|
||||
<ClCompile Include="src\input3.c" />
|
||||
<ClCompile Include="src\lemontiger.c" />
|
||||
<ClCompile Include="src\mempool.c" />
|
||||
<ClCompile Include="src\output.c" />
|
||||
<ClCompile Include="src\quality.c" />
|
||||
<ClCompile Include="src\report.c" />
|
||||
<ClCompile Include="src\rules.c" />
|
||||
<ClCompile Include="src\smatrix.c" />
|
||||
<ClCompile Include="src\testLT.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4B66D9F0-407B-4995-B625-1CA1B72662C6}</ProjectGuid>
|
||||
@@ -73,6 +77,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
||||
@@ -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
|
||||
12
src/epanet.c
12
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 <math.h>
|
||||
#include <float.h> //(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; n<demandIdx && d != NULL; d=d->next) 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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -32,7 +32,6 @@ AUTHOR: L. Rossman
|
||||
#include "text.h"
|
||||
#include "types.h"
|
||||
#include "funcs.h"
|
||||
#define EXTERN extern
|
||||
#include "vars.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
156
src/lemontiger.c
156
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
71
src/testLT.c
71
src/testLT.c
@@ -16,41 +16,55 @@ 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();
|
||||
@@ -58,18 +72,35 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
|
||||
/* 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();
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
65
src/vars.h
65
src/vars.h
@@ -11,15 +11,21 @@ AUTHOR: L. Rossman
|
||||
|
||||
************************************************************************
|
||||
*/
|
||||
EXTERN FILE *InFile, /* Input file pointer */
|
||||
#ifndef VARS_H
|
||||
#define VARS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#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
|
||||
102
test/Net3.rpt
102
test/Net3.rpt
@@ -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
|
||||
Reference in New Issue
Block a user