Merge branch 'lemontiger-rtx' into next
This commit is contained in:
@@ -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
|
||||
125
src/epanet.c
125
src/epanet.c
@@ -107,17 +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 */
|
||||
|
||||
/*** Following lines are deprecated ***/ //(2.00.11 - LR)
|
||||
//#ifdef DLL
|
||||
//#include <windows.h>
|
||||
//#include <float.h>
|
||||
//#endif
|
||||
|
||||
/*** Need to define WINDOWS to use the getTmpName function ***/ //(2.00.12 - LR)
|
||||
// --- define WINDOWS
|
||||
#undef WINDOWS
|
||||
@@ -137,14 +126,14 @@ 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"
|
||||
#include "epanet2.h"
|
||||
|
||||
void (* viewprog) (char *); /* Pointer to progress viewing function */
|
||||
|
||||
@@ -1761,7 +1750,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value)
|
||||
}
|
||||
|
||||
|
||||
int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) // !sph
|
||||
int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: curveIndex = curve index
|
||||
** Output: *nValues = number of points on curve
|
||||
@@ -1794,6 +1783,7 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xVal
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
Functions for changing network data
|
||||
@@ -1984,7 +1974,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v)
|
||||
if (j < 0 || j > Npats) return(205);
|
||||
source->Pat = j;
|
||||
}
|
||||
else
|
||||
else // code == EN_SOURCETYPE
|
||||
{
|
||||
j = ROUND(value);
|
||||
if ( j < CONCEN || j > FLOWPACED) return(251);
|
||||
@@ -2358,44 +2348,69 @@ int DLLEXPORT ENsettimeparam(int code, long value)
|
||||
*/
|
||||
}
|
||||
if (value < 0) return(202);
|
||||
switch(code)
|
||||
{
|
||||
case EN_DURATION: Dur = value;
|
||||
if (Rstart > Dur) Rstart = 0;
|
||||
break;
|
||||
case EN_HYDSTEP: if (value == 0) return(202);
|
||||
Hstep = value;
|
||||
Hstep = MIN(Pstep, Hstep);
|
||||
Hstep = MIN(Rstep, Hstep);
|
||||
Qstep = MIN(Qstep, Hstep);
|
||||
break;
|
||||
case EN_QUALSTEP: if (value == 0) return(202);
|
||||
Qstep = value;
|
||||
Qstep = MIN(Qstep, Hstep);
|
||||
break;
|
||||
case EN_PATTERNSTEP: if (value == 0) return(202);
|
||||
Pstep = value;
|
||||
if (Hstep > Pstep) Hstep = Pstep;
|
||||
break;
|
||||
case EN_PATTERNSTART: Pstart = value;
|
||||
break;
|
||||
case EN_REPORTSTEP: if (value == 0) return(202);
|
||||
Rstep = value;
|
||||
if (Hstep > Rstep) Hstep = Rstep;
|
||||
break;
|
||||
case EN_REPORTSTART: if (Rstart > Dur) return(202);
|
||||
Rstart = value;
|
||||
break;
|
||||
case EN_RULESTEP: if (value == 0) return(202);
|
||||
Rulestep = value;
|
||||
Rulestep = MIN(Rulestep, Hstep);
|
||||
break;
|
||||
case EN_STATISTIC: if (value > RANGE) return(202);
|
||||
Tstatflag = (char)value;
|
||||
break;
|
||||
case EN_HTIME: Htime = value;
|
||||
break;
|
||||
default: return(251);
|
||||
switch(code)
|
||||
{
|
||||
case EN_DURATION:
|
||||
Dur = value;
|
||||
if (Rstart > Dur) Rstart = 0;
|
||||
break;
|
||||
|
||||
case EN_HYDSTEP:
|
||||
if (value == 0) return(202);
|
||||
Hstep = value;
|
||||
Hstep = MIN(Pstep, Hstep);
|
||||
Hstep = MIN(Rstep, Hstep);
|
||||
Qstep = MIN(Qstep, Hstep);
|
||||
break;
|
||||
|
||||
case EN_QUALSTEP:
|
||||
if (value == 0) return(202);
|
||||
Qstep = value;
|
||||
Qstep = MIN(Qstep, Hstep);
|
||||
break;
|
||||
|
||||
case EN_PATTERNSTEP:
|
||||
if (value == 0) return(202);
|
||||
Pstep = value;
|
||||
if (Hstep > Pstep) Hstep = Pstep;
|
||||
break;
|
||||
|
||||
case EN_PATTERNSTART:
|
||||
Pstart = value;
|
||||
break;
|
||||
|
||||
case EN_REPORTSTEP:
|
||||
if (value == 0) return(202);
|
||||
Rstep = value;
|
||||
if (Hstep > Rstep) Hstep = Rstep;
|
||||
break;
|
||||
|
||||
case EN_REPORTSTART:
|
||||
if (Rstart > Dur) return(202);
|
||||
Rstart = value;
|
||||
break;
|
||||
|
||||
case EN_RULESTEP:
|
||||
if (value == 0) return(202);
|
||||
Rulestep = value;
|
||||
Rulestep = MIN(Rulestep, Hstep);
|
||||
break;
|
||||
|
||||
case EN_STATISTIC:
|
||||
if (value > RANGE) return(202);
|
||||
Tstatflag = (char)value;
|
||||
break;
|
||||
|
||||
case EN_HTIME:
|
||||
Htime = value;
|
||||
break;
|
||||
|
||||
case EN_QTIME:
|
||||
Qtime = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
return(251);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -2406,8 +2421,8 @@ int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v)
|
||||
** Input: code = option code (see TOOLKIT.H)
|
||||
** v = option value
|
||||
** Output: none
|
||||
** Returns: error code
|
||||
** Purpose: sets value for an analysis option
|
||||
** Returns: error code
|
||||
** Purpose: sets value for an analysis option
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
@@ -282,3 +286,5 @@ int saveepilog(void); /* Saves output file epilog */
|
||||
|
||||
/* ------------ INPFILE.C --------------*/
|
||||
int saveinpfile(char *); /* Saves network to text file */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -205,7 +205,7 @@ int runhyd(long *t)
|
||||
if (Statflag) writehydstat(iter,relerr);
|
||||
|
||||
/* solution info */
|
||||
_relativeError = relerr;
|
||||
_relativeError = (int)relerr;
|
||||
_iterations = iter;
|
||||
|
||||
/*** Updated 3/1/01 ***/
|
||||
@@ -1064,7 +1064,6 @@ void tanklevels(long tstep)
|
||||
else if (Tank[i].V - D[n] <= Tank[i].Vmin) {
|
||||
Tank[i].V = Tank[i].Vmin;
|
||||
}
|
||||
|
||||
H[n] = tankgrade(i,Tank[i].V);
|
||||
}
|
||||
} /* End of tanklevels */
|
||||
|
||||
@@ -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
|
||||
@@ -162,8 +162,9 @@ int savehyd(long *htime)
|
||||
/* Force flow in closed links to be zero then save flows */
|
||||
for (i=1; i<=Nlinks; i++)
|
||||
{
|
||||
if (S[i] <= CLOSED) x[i] = 0.0f;
|
||||
else x[i] = (REAL4)Q[i];
|
||||
if (S[i] <= CLOSED) x[i] = 0.0f;
|
||||
else x[i] = (REAL4)Q[i];
|
||||
|
||||
}
|
||||
fwrite(x+1,sizeof(REAL4),Nlinks,HydFile);
|
||||
|
||||
@@ -379,7 +380,7 @@ int nodeoutput(int j, REAL4 *x, double ucf)
|
||||
} /* End of nodeoutput */
|
||||
|
||||
|
||||
int linkoutput(int j, float *x, double ucf)
|
||||
int linkoutput(int j, REAL4 *x, double ucf)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: j = type of link variable
|
||||
|
||||
@@ -108,7 +108,7 @@ int openqual()
|
||||
/* Allocate scratch array & reaction rate array*/
|
||||
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 */
|
||||
@@ -151,9 +151,10 @@ void initqual()
|
||||
for (i=1; i<=Nnodes; i++) C[i] = Node[i].C0;
|
||||
for (i=1; i<=Ntanks; i++) Tank[i].C = Node[Tank[i].Node].C0;
|
||||
for (i=1; i<=Ntanks; i++) Tank[i].V = Tank[i].V0;
|
||||
for (i=1; i<=Nnodes; i++)
|
||||
if (Node[i].S != NULL) Node[i].S->Smass = 0.0;
|
||||
|
||||
for (i=1; i<=Nnodes; i++) {
|
||||
if (Node[i].S != NULL) Node[i].S->Smass = 0.0;
|
||||
}
|
||||
|
||||
QTankVolumes = calloc(Ntanks, sizeof(double)); // keep track of previous step's tank volumes.
|
||||
QLinkFlow = calloc(Nlinks, sizeof(double)); // keep track of previous step's link flows.
|
||||
|
||||
@@ -229,10 +230,10 @@ int runqual(long *t)
|
||||
errcode = gethyd(&hydtime, &hydstep);
|
||||
if (!OpenHflag) { // test for sequential vs stepwise
|
||||
// sequential
|
||||
Htime = hydtime + hydstep;
|
||||
}
|
||||
Htime = hydtime + hydstep;
|
||||
}
|
||||
else {
|
||||
// stepwise calculation
|
||||
// stepwise calculation - hydraulic results are already in memory
|
||||
for (int i=1; i<= Ntanks; ++i) {
|
||||
QTankVolumes[i-1] = Tank[i].V;
|
||||
}
|
||||
@@ -246,6 +247,21 @@ int runqual(long *t)
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
// stepwise calculation
|
||||
for (int i=1; i<= Ntanks; ++i) {
|
||||
QTankVolumes[i-1] = Tank[i].V;
|
||||
}
|
||||
|
||||
for (int i=1; i<= Nlinks; ++i)
|
||||
{
|
||||
if (S[i] <= CLOSED) {
|
||||
QLinkFlow[i-1] = Q[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(errcode);
|
||||
}
|
||||
|
||||
@@ -300,7 +316,7 @@ int nextqual(long *tstep)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Perform water quality routing over this time step */
|
||||
if (Qualflag != NONE && hydstep > 0) transport(hydstep);
|
||||
|
||||
@@ -425,10 +441,10 @@ int gethyd(long *hydtime, long *hydstep)
|
||||
// if hydraulics are not open, then we're operating in sequential mode.
|
||||
// else hydraulics are open, so use the hydraulic results in memory rather than reading from the temp file.
|
||||
if (!OpenHflag) {
|
||||
/* Read hydraulic results from file */
|
||||
if (!readhyd(hydtime)) return(307);
|
||||
if (!readhydstep(hydstep)) return(307);
|
||||
Htime = *hydtime;
|
||||
/* Read hydraulic results from file */
|
||||
if (!readhyd(hydtime)) return(307);
|
||||
if (!readhydstep(hydstep)) return(307);
|
||||
Htime = *hydtime;
|
||||
}
|
||||
|
||||
/* Save current results to output file */
|
||||
@@ -497,7 +513,7 @@ void transport(long tstep)
|
||||
*/
|
||||
{
|
||||
long qtime, dt;
|
||||
|
||||
|
||||
/* Repeat until elapsed time equals hydraulic time step */
|
||||
|
||||
AllocSetPool(SegPool); //(2.00.11 - LR)
|
||||
@@ -513,6 +529,7 @@ void transport(long tstep)
|
||||
release(dt); /* Release new nodal flows */
|
||||
}
|
||||
updatesourcenodes(tstep); /* Update quality at source nodes */
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1080,21 +1097,19 @@ void updatetanks(long dt)
|
||||
for (i=1; i<=Ntanks; i++)
|
||||
{
|
||||
n = Tank[i].Node;
|
||||
|
||||
/* Use initial quality for reservoirs */
|
||||
if (Tank[i].A == 0.0)
|
||||
{
|
||||
C[n] = Node[n].C0;
|
||||
}
|
||||
|
||||
/* Update tank WQ based on mixing model */
|
||||
else {
|
||||
switch(Tank[i].MixModel)
|
||||
{
|
||||
case MIX2: tankmix2(i,dt); break;
|
||||
case FIFO: tankmix3(i,dt); break;
|
||||
case LIFO: tankmix4(i,dt); break;
|
||||
default: tankmix1(i,dt); break;
|
||||
case MIX2: tankmix2(i,dt); break;
|
||||
case FIFO: tankmix3(i,dt); break;
|
||||
case LIFO: tankmix4(i,dt); break;
|
||||
default: tankmix1(i,dt); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
332
src/testLemonTiger.cpp
Executable file
332
src/testLemonTiger.cpp
Executable file
@@ -0,0 +1,332 @@
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "testLemonTiger.h"
|
||||
#include "toolkit.h"
|
||||
|
||||
#define COLW 15
|
||||
#define OUTPRECISION 6
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef struct {
|
||||
double head;
|
||||
double demand;
|
||||
double quality;
|
||||
} nodeState_t;
|
||||
|
||||
typedef struct {
|
||||
double flow;
|
||||
} linkState_t;
|
||||
|
||||
typedef map<int, nodeState_t> networkNodeState_t; // nodeIndex, state
|
||||
typedef map<int, linkState_t> networkLinkState_t; // linkIndex, state
|
||||
|
||||
typedef struct {
|
||||
networkNodeState_t nodeState;
|
||||
networkLinkState_t linkState;
|
||||
} networkState_t;
|
||||
typedef map<long, networkState_t> result_t; // time, networkState
|
||||
// access results by, for instance, resultsContainer[time][nodeIndex].head
|
||||
|
||||
|
||||
|
||||
void checkErr(int err, std::string function);
|
||||
void saveHydResults(networkState_t* networkState);
|
||||
void saveQualResults(networkState_t* networkState);
|
||||
void printResults(result_t* state1, result_t* state2, std::ostream& out);
|
||||
void compare(result_t* results1, result_t* results2, std::ostream &out);
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
// create storage structures for results.
|
||||
result_t epanetResults, lemonTigerResults;
|
||||
|
||||
cout << "Lemon Tiger TEST" << endl
|
||||
<< "________________" << endl;
|
||||
|
||||
|
||||
long simulationTime = 0;
|
||||
long nextEventH = 0, nextEventQ = 0;
|
||||
long simTimeRemaining = 0;
|
||||
|
||||
try {
|
||||
|
||||
/* Batch solver (old epanet) */
|
||||
cout << "*****Original EPANET results******" << endl;
|
||||
checkErr( ENopen(argv[1], argv[2], (char*)""), "ENopen" );
|
||||
|
||||
checkErr( ENopenH(), "ENopenH" );
|
||||
checkErr( ENinitH(EN_SAVE), "ENinitH" );
|
||||
|
||||
cout << "Running hydraulics..." << endl;
|
||||
do {
|
||||
|
||||
/* Solve for hydraulics & advance to next time period */
|
||||
checkErr( ENrunH(&simulationTime), "ENrunH" );
|
||||
checkErr( ENnextH(&nextEventH), "ENnextH" );
|
||||
|
||||
// gather hydraulic results
|
||||
saveHydResults(&epanetResults[simulationTime]);
|
||||
|
||||
|
||||
|
||||
} while (nextEventH > 0);
|
||||
// hydraulics are done
|
||||
checkErr( ENcloseH(), "ENcloseH" );
|
||||
cout << "\t\t\tdone." << endl;
|
||||
cout << "Running WQ..." << endl;
|
||||
|
||||
checkErr( ENopenQ(), "ENopenQ" );
|
||||
checkErr( ENinitQ(EN_NOSAVE), "ENinitQ" );
|
||||
|
||||
do {
|
||||
|
||||
checkErr( ENrunQ(&simulationTime), "ENrunQ" );
|
||||
checkErr( ENnextQ(&nextEventH), "ENstepQ" );
|
||||
|
||||
// gather quality results
|
||||
saveQualResults(&epanetResults[simulationTime]);
|
||||
|
||||
} while (nextEventH > 0);
|
||||
// water quality is done
|
||||
checkErr( ENcloseQ(), "ENcloseQ" );
|
||||
cout << "\t\t\tdone." << endl;
|
||||
|
||||
// everything is done
|
||||
checkErr( ENclose(), "ENclose" );
|
||||
|
||||
|
||||
nextEventH = 0;
|
||||
simTimeRemaining = 0;
|
||||
simulationTime = 0;
|
||||
|
||||
/* stepwise solver (LemonTiger) */
|
||||
cout << "*****LemonTiger results******" << endl;
|
||||
|
||||
checkErr( ENopen(argv[1], argv[2], (char*)""), "ENopen" );
|
||||
|
||||
checkErr( ENopenH(), "ENopenH" );
|
||||
checkErr( ENinitH(EN_NOSAVE), "ENinitH" );
|
||||
checkErr( ENopenQ(), "ENopenQ" );
|
||||
checkErr( ENinitQ(EN_NOSAVE), "ENinitQ" );
|
||||
|
||||
cout << "Running stepwise hydraulics and water quality..." << endl;
|
||||
do {
|
||||
/* Solve for hydraulics & advance to next time period */
|
||||
checkErr( ENrunH(&simulationTime), "ENrunH" );
|
||||
checkErr( ENrunQ(&simulationTime), "ENrunQ" );
|
||||
|
||||
checkErr( ENnextH(&nextEventH), "ENnextH" );
|
||||
checkErr( ENnextQ(&nextEventQ), "ENstepQ" );
|
||||
|
||||
|
||||
saveHydResults(&lemonTigerResults[simulationTime]);
|
||||
saveQualResults(&lemonTigerResults[simulationTime]);
|
||||
|
||||
|
||||
} while (nextEventH > 0);
|
||||
cout << "\t\t\tdone." << endl;
|
||||
|
||||
// all done
|
||||
checkErr( ENcloseH(), "ENcloseH" );
|
||||
checkErr( ENcloseQ(), "ENcloseQ" );
|
||||
checkErr( ENclose(), "ENclose" );
|
||||
|
||||
|
||||
// summarize the results
|
||||
printResults(&epanetResults, &lemonTigerResults, cout);
|
||||
compare(&epanetResults, &lemonTigerResults, cout);
|
||||
|
||||
} catch (int err) {
|
||||
cerr << "exiting with error " << err << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void saveHydResults(networkState_t* networkState) {
|
||||
int nNodes, nLinks;
|
||||
float head, demand, flow;
|
||||
ENgetcount(EN_NODECOUNT, &nNodes);
|
||||
ENgetcount(EN_LINKCOUNT, &nLinks);
|
||||
for (int iNode = 1; iNode <= nNodes; ++iNode) {
|
||||
ENgetnodevalue(iNode, EN_HEAD, &head);
|
||||
ENgetnodevalue(iNode, EN_DEMAND, &demand);
|
||||
(*networkState).nodeState[iNode].head = head;
|
||||
(*networkState).nodeState[iNode].demand = demand;
|
||||
}
|
||||
for (int iLink = 1; iLink <= nLinks; ++iLink) {
|
||||
ENgetlinkvalue(iLink, EN_FLOW, &flow);
|
||||
(*networkState).linkState[iLink].flow = flow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void saveQualResults(networkState_t* networkState) {
|
||||
int nNodes;
|
||||
float quality;
|
||||
ENgetcount(EN_NODECOUNT, &nNodes);
|
||||
|
||||
for (int iNode = 1; iNode <= nNodes; iNode++) {
|
||||
ENgetnodevalue(iNode, EN_QUALITY, &quality);
|
||||
(*networkState).nodeState[iNode].quality = quality;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printResults(result_t* results1, result_t* results2, std::ostream &out) {
|
||||
|
||||
result_t::const_iterator resultIterator;
|
||||
|
||||
for (resultIterator = (*results1).begin(); resultIterator != (*results1).end(); ++resultIterator) {
|
||||
// get the current frame
|
||||
const long time = resultIterator->first;
|
||||
const networkNodeState_t networkNodeState1= resultIterator->second.nodeState;
|
||||
//nodeState1 = resultIterator->second.nodeState;
|
||||
const networkLinkState_t networkLinkState1 = resultIterator->second.linkState;
|
||||
//linkState1 = resultIterator->second.linkState;
|
||||
|
||||
// see if this time is indexed in the second state container
|
||||
if ((*results2).find(time) == (*results2).end()) {
|
||||
// nope.
|
||||
out << "time " << time << " not found in second result set" << endl;
|
||||
}
|
||||
else {
|
||||
// get the second result set's state
|
||||
const networkNodeState_t networkNodeState2 = (*results2)[time].nodeState;
|
||||
const networkLinkState_t networkLinkState2 = (*results2)[time].linkState;
|
||||
// print the current simulation time
|
||||
out << left;
|
||||
out << setfill('*') << setw(100) << "*" << endl;
|
||||
out << setfill(' ');
|
||||
out << setw(4) << "T = " << setw(6) << time;
|
||||
out << "|" << setw(3*COLW) << "EPANET";
|
||||
out << "|" << setw(3*COLW) << "LemonTiger" << endl;
|
||||
out << setw(10) << "Index" << "|";
|
||||
out << setw(COLW) << "Demand" << setw(COLW) << "Head" << setw(COLW) << "Quality" << "|";
|
||||
out << setw(COLW) << "Demand" << setw(COLW) << "Head" << setw(COLW) << "Quality" << endl;
|
||||
out << setprecision(OUTPRECISION);
|
||||
|
||||
// loop through the nodes in the networkState objs, and print out the results for this time period
|
||||
networkNodeState_t::const_iterator networkNodeIterator;
|
||||
for (networkNodeIterator = networkNodeState1.begin(); networkNodeIterator != networkNodeState1.end(); ++networkNodeIterator) {
|
||||
int nodeIndex = networkNodeIterator->first;
|
||||
// trusting that all nodes are present...
|
||||
const nodeState_t nodeState1 = networkNodeIterator->second;
|
||||
const nodeState_t nodeState2 = networkNodeState2.at(nodeIndex);
|
||||
|
||||
if (nodeState1.quality != nodeState2.quality ) {
|
||||
// epanet
|
||||
out << setw(10) << nodeIndex << "|";
|
||||
out << setw(COLW) << nodeState1.demand;
|
||||
out << setw(COLW) << nodeState1.head;
|
||||
out << setw(COLW) << nodeState1.quality;
|
||||
|
||||
// lemontiger
|
||||
out << "|";
|
||||
out << setw(COLW) << nodeState2.demand;
|
||||
out << setw(COLW) << nodeState2.head;
|
||||
out << setw(COLW) << nodeState2.quality;
|
||||
out << endl;
|
||||
}
|
||||
}
|
||||
|
||||
networkLinkState_t::const_iterator networkLinkIterator;
|
||||
for (networkLinkIterator = networkLinkState1.begin(); networkLinkIterator != networkLinkState1.end(); ++networkLinkIterator) {
|
||||
int linkIndex = networkLinkIterator->first;
|
||||
// trusting that all nodes are present...
|
||||
const linkState_t linkState1 = networkLinkIterator->second;
|
||||
const linkState_t linkState2 = networkLinkState2.at(linkIndex);
|
||||
|
||||
if ( linkState1.flow != linkState2.flow ) {
|
||||
// epanet
|
||||
out << setw(10) << linkIndex << "|";
|
||||
out << setw(COLW) << linkState1.flow;
|
||||
|
||||
// lemontiger
|
||||
out << "|";
|
||||
out << setw(COLW) << linkState2.flow;
|
||||
out << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void compare(result_t* results1, result_t* results2, std::ostream &out) {
|
||||
|
||||
double sumHeadDiff=0, sumDemandDiff=0, sumQualDiff=0, sumFlowDiff=0;
|
||||
|
||||
result_t::const_iterator resultIterator;
|
||||
|
||||
for (resultIterator = (*results1).begin(); resultIterator != (*results1).end(); ++resultIterator) {
|
||||
// get the current frame
|
||||
const long time = resultIterator->first;
|
||||
const networkNodeState_t nodeState1 = resultIterator->second.nodeState;
|
||||
const networkLinkState_t linkState1 = resultIterator->second.linkState;
|
||||
|
||||
// see if this time is indexed in the second state container
|
||||
if ((*results2).find(time) == (*results2).end()) {
|
||||
// nope.
|
||||
out << "time " << time << " not found in second result set" << endl;
|
||||
}
|
||||
else {
|
||||
// get the second result set's state
|
||||
const networkNodeState_t networkNodeState2 = (*results2)[time].nodeState;
|
||||
const networkLinkState_t networkLinkState2 = (*results2)[time].linkState;
|
||||
double qualD=0;
|
||||
|
||||
networkNodeState_t::const_iterator networkNodeIterator;
|
||||
for (networkNodeIterator = nodeState1.begin(); networkNodeIterator != nodeState1.end(); ++networkNodeIterator) {
|
||||
int nodeIndex = networkNodeIterator->first;
|
||||
// trusting that all nodes are present...
|
||||
const nodeState_t nodeState1 = networkNodeIterator->second;
|
||||
const nodeState_t nodeState2 = networkNodeState2.at(nodeIndex);
|
||||
|
||||
sumHeadDiff += fabs(nodeState1.head - nodeState2.head);
|
||||
sumDemandDiff += fabs(nodeState1.demand - nodeState2.demand);
|
||||
|
||||
qualD += fabs(nodeState1.quality - nodeState2.quality);
|
||||
}
|
||||
//out << "T: " << time << " dq: " << setprecision(20) << qualD << endl;
|
||||
sumQualDiff += qualD;
|
||||
|
||||
networkLinkState_t::const_iterator networkLinkIterator;
|
||||
for (networkLinkIterator = linkState1.begin(); networkLinkIterator != linkState1.end(); ++networkLinkIterator) {
|
||||
int linkIndex = networkLinkIterator->first;
|
||||
// trusting that all nodes are present...
|
||||
const linkState_t linkState1 = networkLinkIterator->second;
|
||||
const linkState_t linkState2 = networkLinkState2.at(linkIndex);
|
||||
|
||||
sumFlowDiff += fabs(linkState1.flow - linkState2.flow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int c1 = 18;
|
||||
int p = 20;
|
||||
out << setw(c1) << "Head Diff:" << setprecision(p) << sumHeadDiff << endl;
|
||||
out << setw(c1) << "Demand Diff:" << setprecision(p) << sumDemandDiff << endl;
|
||||
out << setw(c1) << "Quality Diff:" << setprecision(p) << sumQualDiff << endl;
|
||||
out << setw(c1) << "Flow Diff:" << setprecision(p) << sumFlowDiff << endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void checkErr(int err, std::string function) {
|
||||
if (err > 0) {
|
||||
cerr << "Error in " << function << ": " << err << endl;
|
||||
char errmsg[1024];
|
||||
ENgeterror(err, errmsg, 1024);
|
||||
cerr << errmsg << endl;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
15
src/testLemonTiger.h
Executable file
15
src/testLemonTiger.h
Executable file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// testLemonTiger.h
|
||||
// epanet
|
||||
//
|
||||
// Created by Sam Hatchett on 2/1/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __epanet__testLemonTiger__
|
||||
#define __epanet__testLemonTiger__
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#endif /* defined(__epanet__testLemonTiger__) */
|
||||
259
src/toolkit.h
259
src/toolkit.h
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
*******************************************************************
|
||||
|
||||
TOOLKIT.H - Prototypes for EPANET Functions Exported to DLL Toolkit
|
||||
|
||||
VERSION: 2.00
|
||||
DATE: 5/8/00
|
||||
10/25/00
|
||||
3/1/01
|
||||
8/15/07 (2.00.11)
|
||||
2/14/08 (2.00.12)
|
||||
AUTHOR: L. Rossman
|
||||
US EPA - NRMRL
|
||||
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TOOLKIT_H
|
||||
#define TOOLKIT_H
|
||||
|
||||
#ifndef EN_API_FLOAT_TYPE
|
||||
#define EN_API_FLOAT_TYPE float
|
||||
#endif
|
||||
|
||||
#ifndef DLLEXPORT
|
||||
#ifdef DLL
|
||||
#ifdef __cplusplus
|
||||
#define DLLEXPORT extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#elif defined(CYGWIN)
|
||||
#define DLLEXPORT __stdcall
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#define DLLEXPORT
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// --- Define the EPANET toolkit constants
|
||||
|
||||
#define EN_ELEVATION 0 /* Node parameters */
|
||||
#define EN_BASEDEMAND 1
|
||||
#define EN_PATTERN 2
|
||||
#define EN_EMITTER 3
|
||||
#define EN_INITQUAL 4
|
||||
#define EN_SOURCEQUAL 5
|
||||
#define EN_SOURCEPAT 6
|
||||
#define EN_SOURCETYPE 7
|
||||
#define EN_TANKLEVEL 8
|
||||
#define EN_DEMAND 9
|
||||
#define EN_HEAD 10
|
||||
#define EN_PRESSURE 11
|
||||
#define EN_QUALITY 12
|
||||
#define EN_SOURCEMASS 13
|
||||
#define EN_INITVOLUME 14
|
||||
#define EN_MIXMODEL 15
|
||||
#define EN_MIXZONEVOL 16
|
||||
|
||||
#define EN_TANKDIAM 17
|
||||
#define EN_MINVOLUME 18
|
||||
#define EN_VOLCURVE 19
|
||||
#define EN_MINLEVEL 20
|
||||
#define EN_MAXLEVEL 21
|
||||
#define EN_MIXFRACTION 22
|
||||
#define EN_TANK_KBULK 23
|
||||
#define EN_TANKVOLUME 24
|
||||
#define EN_MAXVOLUME 25
|
||||
|
||||
#define EN_DIAMETER 0 /* Link parameters */
|
||||
#define EN_LENGTH 1
|
||||
#define EN_ROUGHNESS 2
|
||||
#define EN_MINORLOSS 3
|
||||
#define EN_INITSTATUS 4
|
||||
#define EN_INITSETTING 5
|
||||
#define EN_KBULK 6
|
||||
#define EN_KWALL 7
|
||||
#define EN_FLOW 8
|
||||
#define EN_VELOCITY 9
|
||||
#define EN_HEADLOSS 10
|
||||
#define EN_STATUS 11
|
||||
#define EN_SETTING 12
|
||||
#define EN_ENERGY 13
|
||||
#define EN_LINKQUAL 14 /* TNT */
|
||||
|
||||
#define EN_DURATION 0 /* Time parameters */
|
||||
#define EN_HYDSTEP 1
|
||||
#define EN_QUALSTEP 2
|
||||
#define EN_PATTERNSTEP 3
|
||||
#define EN_PATTERNSTART 4
|
||||
#define EN_REPORTSTEP 5
|
||||
#define EN_REPORTSTART 6
|
||||
#define EN_RULESTEP 7
|
||||
#define EN_STATISTIC 8
|
||||
#define EN_PERIODS 9
|
||||
#define EN_STARTTIME 10 /* Added TNT 10/2/2009 */
|
||||
#define EN_HTIME 11
|
||||
#define EN_HALTFLAG 12
|
||||
#define EN_NEXTEVENT 13
|
||||
|
||||
#define EN_ITERATIONS 0
|
||||
#define EN_RELATIVEERROR 1
|
||||
|
||||
#define EN_NODECOUNT 0 /* Component counts */
|
||||
#define EN_TANKCOUNT 1
|
||||
#define EN_LINKCOUNT 2
|
||||
#define EN_PATCOUNT 3
|
||||
#define EN_CURVECOUNT 4
|
||||
#define EN_CONTROLCOUNT 5
|
||||
|
||||
#define EN_JUNCTION 0 /* Node types */
|
||||
#define EN_RESERVOIR 1
|
||||
#define EN_TANK 2
|
||||
|
||||
#define EN_CVPIPE 0 /* Link types. */
|
||||
#define EN_PIPE 1 /* See LinkType in TYPES.H */
|
||||
#define EN_PUMP 2
|
||||
#define EN_PRV 3
|
||||
#define EN_PSV 4
|
||||
#define EN_PBV 5
|
||||
#define EN_FCV 6
|
||||
#define EN_TCV 7
|
||||
#define EN_GPV 8
|
||||
|
||||
#define EN_NONE 0 /* Quality analysis types. */
|
||||
#define EN_CHEM 1 /* See QualType in TYPES.H */
|
||||
#define EN_AGE 2
|
||||
#define EN_TRACE 3
|
||||
|
||||
#define EN_CONCEN 0 /* Source quality types. */
|
||||
#define EN_MASS 1 /* See SourceType in TYPES.H. */
|
||||
#define EN_SETPOINT 2
|
||||
#define EN_FLOWPACED 3
|
||||
|
||||
#define EN_CFS 0 /* Flow units types. */
|
||||
#define EN_GPM 1 /* See FlowUnitsType */
|
||||
#define EN_MGD 2 /* in TYPES.H. */
|
||||
#define EN_IMGD 3
|
||||
#define EN_AFD 4
|
||||
#define EN_LPS 5
|
||||
#define EN_LPM 6
|
||||
#define EN_MLD 7
|
||||
#define EN_CMH 8
|
||||
#define EN_CMD 9
|
||||
|
||||
#define EN_TRIALS 0 /* Misc. options */
|
||||
#define EN_ACCURACY 1
|
||||
#define EN_TOLERANCE 2
|
||||
#define EN_EMITEXPON 3
|
||||
#define EN_DEMANDMULT 4
|
||||
|
||||
#define EN_LOWLEVEL 0 /* Control types. */
|
||||
#define EN_HILEVEL 1 /* See ControlType */
|
||||
#define EN_TIMER 2 /* in TYPES.H. */
|
||||
#define EN_TIMEOFDAY 3
|
||||
|
||||
#define EN_AVERAGE 1 /* Time statistic types. */
|
||||
#define EN_MINIMUM 2 /* See TstatType in TYPES.H */
|
||||
#define EN_MAXIMUM 3
|
||||
#define EN_RANGE 4
|
||||
|
||||
#define EN_MIX1 0 /* Tank mixing models */
|
||||
#define EN_MIX2 1
|
||||
#define EN_FIFO 2
|
||||
#define EN_LIFO 3
|
||||
|
||||
#define EN_NOSAVE 0 /* Save-results-to-file flag */
|
||||
#define EN_SAVE 1
|
||||
|
||||
#define EN_INITFLOW 10 /* Re-initialize flows flag */
|
||||
|
||||
|
||||
// --- Declare the EPANET toolkit functions
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
int DLLEXPORT ENepanet(char *, char *, char *, void (*) (char *));
|
||||
|
||||
int DLLEXPORT ENopen(char *, char *, char *);
|
||||
int DLLEXPORT ENsaveinpfile(char *);
|
||||
int DLLEXPORT ENclose(void);
|
||||
|
||||
int DLLEXPORT ENsolveH(void);
|
||||
int DLLEXPORT ENsaveH(void);
|
||||
int DLLEXPORT ENopenH(void);
|
||||
int DLLEXPORT ENinitH(int);
|
||||
int DLLEXPORT ENrunH(long *);
|
||||
int DLLEXPORT ENnextH(long *);
|
||||
int DLLEXPORT ENcloseH(void);
|
||||
int DLLEXPORT ENsavehydfile(char *);
|
||||
int DLLEXPORT ENusehydfile(char *);
|
||||
|
||||
int DLLEXPORT ENsolveQ(void);
|
||||
int DLLEXPORT ENopenQ(void);
|
||||
int DLLEXPORT ENinitQ(int);
|
||||
int DLLEXPORT ENrunQ(long *);
|
||||
int DLLEXPORT ENnextQ(long *);
|
||||
int DLLEXPORT ENstepQ(long *);
|
||||
int DLLEXPORT ENcloseQ(void);
|
||||
|
||||
int DLLEXPORT ENwriteline(char *);
|
||||
int DLLEXPORT ENreport(void);
|
||||
int DLLEXPORT ENresetreport(void);
|
||||
int DLLEXPORT ENsetreport(char *);
|
||||
|
||||
int DLLEXPORT ENgetcontrol(int, int *, int *, EN_API_FLOAT_TYPE *,
|
||||
int *, EN_API_FLOAT_TYPE *);
|
||||
int DLLEXPORT ENgetcount(int, int *);
|
||||
int DLLEXPORT ENgetoption(int, EN_API_FLOAT_TYPE *);
|
||||
int DLLEXPORT ENgettimeparam(int, long *);
|
||||
int DLLEXPORT ENgetflowunits(int *);
|
||||
int DLLEXPORT ENgetpatternindex(char *, int *);
|
||||
int DLLEXPORT ENgetpatternid(int, char *);
|
||||
int DLLEXPORT ENgetpatternlen(int, int *);
|
||||
int DLLEXPORT ENgetpatternvalue(int, int, EN_API_FLOAT_TYPE *);
|
||||
int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value);
|
||||
int DLLEXPORT ENgetqualtype(int *, int *);
|
||||
int DLLEXPORT ENgeterror(int, char *, int);
|
||||
int DLLEXPORT ENgetstatistic(int code, int* value);
|
||||
|
||||
int DLLEXPORT ENgetnodeindex(char *, int *);
|
||||
int DLLEXPORT ENgetnodeid(int, char *);
|
||||
int DLLEXPORT ENgetnodetype(int, int *);
|
||||
int DLLEXPORT ENgetnodevalue(int, int, EN_API_FLOAT_TYPE *);
|
||||
int DLLEXPORT ENgetcoord(int , EN_API_FLOAT_TYPE *, EN_API_FLOAT_TYPE *);
|
||||
|
||||
int DLLEXPORT ENgetnumdemands(int, int *);
|
||||
int DLLEXPORT ENgetbasedemand(int, int, EN_API_FLOAT_TYPE *);
|
||||
int DLLEXPORT ENgetdemandpattern(int, int, int *);
|
||||
|
||||
int DLLEXPORT ENgetlinkindex(char *, int *);
|
||||
int DLLEXPORT ENgetlinkid(int, char *);
|
||||
int DLLEXPORT ENgetlinktype(int, int *);
|
||||
int DLLEXPORT ENgetlinknodes(int, int *, int *);
|
||||
int DLLEXPORT ENgetlinkvalue(int, int, EN_API_FLOAT_TYPE *);
|
||||
|
||||
int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues);
|
||||
|
||||
int DLLEXPORT ENgetversion(int *);
|
||||
|
||||
int DLLEXPORT ENsetcontrol(int, int, int, EN_API_FLOAT_TYPE, int, EN_API_FLOAT_TYPE);
|
||||
int DLLEXPORT ENsetnodevalue(int, int, EN_API_FLOAT_TYPE);
|
||||
int DLLEXPORT ENsetlinkvalue(int, int, EN_API_FLOAT_TYPE);
|
||||
int DLLEXPORT ENaddpattern(char *);
|
||||
int DLLEXPORT ENsetpattern(int, EN_API_FLOAT_TYPE *, int);
|
||||
int DLLEXPORT ENsetpatternvalue(int, int, EN_API_FLOAT_TYPE);
|
||||
int DLLEXPORT ENsettimeparam(int, long);
|
||||
int DLLEXPORT ENsetoption(int, EN_API_FLOAT_TYPE);
|
||||
int DLLEXPORT ENsetstatusreport(int);
|
||||
int DLLEXPORT ENsetqualtype(int, char *, char *, char *);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //TOOLKIT_H
|
||||
@@ -28,7 +28,7 @@ AUTHOR: L. Rossman
|
||||
Definition of 4-byte integers & reals
|
||||
-------------------------------------------
|
||||
*/
|
||||
typedef float REAL4; //(2.00.11 - LR)
|
||||
typedef double REAL4; //(2.00.11 - LR)
|
||||
typedef int INT4; //(2.00.12 - LR)
|
||||
|
||||
/*
|
||||
|
||||
24
src/vars.h
24
src/vars.h
@@ -22,10 +22,10 @@ AUTHOR: L. Rossman
|
||||
*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 */
|
||||
@@ -65,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 */
|
||||
@@ -99,7 +99,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 */
|
||||
@@ -128,7 +128,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) */
|
||||
@@ -141,12 +141,12 @@ 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 */
|
||||
@@ -193,19 +193,19 @@ 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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user