Merge branch 'lemontiger-rtx' into next

This commit is contained in:
Sam Hatchett
2013-07-22 16:56:05 -04:00
40 changed files with 1637 additions and 2253 deletions

View File

@@ -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

View File

@@ -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
**----------------------------------------------------------------
*/
{

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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
View 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__) */

View File

@@ -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

View File

@@ -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)
/*

View File

@@ -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 */