From 691c65878b87ddf851805b194e562cead53d5980 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 12 Jan 2018 09:46:32 -0500 Subject: [PATCH 01/45] Initial commit of toolkit SWIG wrapper work --- include/epanet2.h | 37 ++-- src/epanet.c | 54 ++++-- src/input2.c | 3 +- src/vars.h | 2 +- tools/epanet-toolkit/setup.py | 40 ++++ tools/epanet-toolkit/src/epanet_toolkit.i | 71 +++++++ tools/epanet-toolkit/test/data/Net1.inp | 178 ++++++++++++++++++ .../test/epanet_toolkit_test.py | 49 +++++ tools/epanet-toolkit/test/main.py | 13 ++ .../test/test_epanet_toolkit.cpp | 34 ++++ 10 files changed, 453 insertions(+), 28 deletions(-) create mode 100644 tools/epanet-toolkit/setup.py create mode 100644 tools/epanet-toolkit/src/epanet_toolkit.i create mode 100644 tools/epanet-toolkit/test/data/Net1.inp create mode 100644 tools/epanet-toolkit/test/epanet_toolkit_test.py create mode 100644 tools/epanet-toolkit/test/main.py create mode 100644 tools/epanet-toolkit/test/test_epanet_toolkit.cpp diff --git a/include/epanet2.h b/include/epanet2.h index c9fe158..9392137 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -43,7 +43,7 @@ #ifndef DLLEXPORT #ifdef WINDOWS #ifdef __cplusplus - #define DLLEXPORT extern "C" __declspec(dllexport) + #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT __declspec(dllexport) __stdcall #endif // __cplusplus @@ -266,6 +266,7 @@ extern "C" { /** @brief The EPANET Project wrapper object */ + typedef void* EN_ProjectHandle; typedef struct EN_Project EN_Project; typedef struct EN_Pattern EN_Pattern; typedef struct EN_Curve EN_Curve; @@ -1117,14 +1118,22 @@ extern "C" { Threadsafe versions of all epanet functions ***************************************************/ - int DLLEXPORT EN_alloc(EN_Project **p); - int DLLEXPORT EN_free(EN_Project *p); - int DLLEXPORT EN_epanet(char *inpFile, char *rptFile, char *binOutFile, void (*callback) (char *)); - int DLLEXPORT EN_init(EN_Project *p, char *rptFile, char *binOutFile, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); - int DLLEXPORT EN_open(EN_Project *p, char *inpFile, char *rptFile, char *binOutFile); + int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); + int DLLEXPORT EN_free(EN_ProjectHandle ph); + + int DLLEXPORT EN_epanet(char *inpFile, char *rptFile, char *binOutFile, + void (*callback) (char *)); + int DLLEXPORT EN_init(EN_Project *p, char *rptFile, char *binOutFile, + EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); + + int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, + const char *rptFile, const char *binOutFile); + int DLLEXPORT EN_saveinpfile(EN_Project *p, char *filename); - int DLLEXPORT EN_close(EN_Project *p); - int DLLEXPORT EN_solveH(EN_Project *p); + + int DLLEXPORT EN_close(EN_ProjectHandle ph); + int DLLEXPORT EN_solveH(EN_ProjectHandle ph); + int DLLEXPORT EN_saveH(EN_Project *p); int DLLEXPORT EN_openH(EN_Project *p); int DLLEXPORT EN_initH(EN_Project *p, int EN_SaveOption); @@ -1133,7 +1142,9 @@ extern "C" { int DLLEXPORT EN_closeH(EN_Project *p); int DLLEXPORT EN_savehydfile(EN_Project *p, char *filename); int DLLEXPORT EN_usehydfile(EN_Project *p, char *filename); - int DLLEXPORT EN_solveQ(EN_Project *p); + + int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); + int DLLEXPORT EN_openQ(EN_Project *p); int DLLEXPORT EN_initQ(EN_Project *p, int saveFlag); int DLLEXPORT EN_runQ(EN_Project *p, long *currentTime); @@ -1141,7 +1152,9 @@ extern "C" { int DLLEXPORT EN_stepQ(EN_Project *p, long *timeLeft); int DLLEXPORT EN_closeQ(EN_Project *p); int DLLEXPORT EN_writeline(EN_Project *p, char *line); - int DLLEXPORT EN_report(EN_Project *p); + + int DLLEXPORT EN_report(EN_ProjectHandle ph); + int DLLEXPORT EN_resetreport(EN_Project *p); int DLLEXPORT EN_setreport(EN_Project *p, char *reportFormat); int DLLEXPORT EN_getcontrol(EN_Project *p, int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); @@ -1214,10 +1227,6 @@ extern "C" { int DLLEXPORT EN_deletelink(EN_Project *p, int linkIndex); - - - - #if defined(__cplusplus) } #endif diff --git a/src/epanet.c b/src/epanet.c index 6059fc0..be1801a 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -151,30 +151,40 @@ execute function x and set the error code equal to its return value. ** needed then the argument should be NULL. **------------------------------------------------------------------------- */ -int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, - void (*pviewprog)(char *)) { +int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) +{ int errcode = 0; + EN_Project* _p; + + _p = (EN_Project*)_defaultModel; + ERRCODE(EN_alloc(&_defaultModel)); ERRCODE(EN_open(_defaultModel, f1, f2, f3)); - _defaultModel->viewprog = pviewprog; - if (_defaultModel->out_files.Hydflag != USE) { + + _p->viewprog = pviewprog; + if (_p->out_files.Hydflag != USE) { ERRCODE(EN_solveH(_defaultModel)); } + ERRCODE(EN_solveQ(_defaultModel)); ERRCODE(EN_report(_defaultModel)); EN_close(_defaultModel); EN_free(_defaultModel); + return (errcode); } + int DLLEXPORT ENopen(char *f1, char *f2, char *f3) { int errcode = 0; ERRCODE(EN_alloc(&_defaultModel)); EN_open(_defaultModel, f1, f2, f3); return (errcode); } + int DLLEXPORT ENsaveinpfile(char *filename) { return EN_saveinpfile(_defaultModel, filename); } + int DLLEXPORT ENclose() { return EN_close(_defaultModel); } int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } @@ -446,16 +456,21 @@ int DLLEXPORT ENdeletenode(int index) { */ /// allocate a project pointer -int DLLEXPORT EN_alloc(EN_Project **p) +int DLLEXPORT EN_alloc(EN_ProjectHandle *ph) { EN_Project *project = calloc(1, sizeof(EN_Project)); - *p = project; + *ph = project; + return 0; } -int DLLEXPORT EN_free(EN_Project *p) +int DLLEXPORT EN_free(EN_ProjectHandle ph) { + EN_Project* p; + p = (EN_Project*)ph; + free(p); + return 0; } @@ -518,7 +533,7 @@ int DLLEXPORT EN_init(EN_Project *pr, char *f2, char *f3, return (errcode); } -int DLLEXPORT EN_open(EN_Project *p, char *f1, char *f2, char *f3) +int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3) /*---------------------------------------------------------------- ** Input: f1 = pointer to name of input file ** f2 = pointer to name of report file @@ -537,6 +552,9 @@ int DLLEXPORT EN_open(EN_Project *p, char *f1, char *f2, char *f3) _fpreset(); #endif + EN_Project* p; + p = (EN_Project*)ph; + /* Set system flags */ p->Openflag = FALSE; p->hydraulics.OpenHflag = FALSE; @@ -605,7 +623,7 @@ int DLLEXPORT EN_saveinpfile(EN_Project *p, char *filename) return (saveinpfile(p, filename)); } -int DLLEXPORT EN_close(EN_Project *p) +int DLLEXPORT EN_close(EN_ProjectHandle ph) /*---------------------------------------------------------------- ** Input: none ** Output: none @@ -615,6 +633,9 @@ int DLLEXPORT EN_close(EN_Project *p) */ { out_file_t *out; + EN_Project* p; + + p = (EN_Project*)ph; if (p->Openflag) { writetime(p, FMT105); @@ -667,7 +688,7 @@ int DLLEXPORT EN_close(EN_Project *p) ---------------------------------------------------------------- */ -int DLLEXPORT EN_solveH(EN_Project *p) +int DLLEXPORT EN_solveH(EN_ProjectHandle ph) /*---------------------------------------------------------------- ** Input: none ** Output: none @@ -678,6 +699,9 @@ int DLLEXPORT EN_solveH(EN_Project *p) { int errcode; long t, tstep; + EN_Project* p; + + p = (EN_Project*)ph; /* Open hydraulics solver */ errcode = EN_openH(p); @@ -922,9 +946,12 @@ int DLLEXPORT EN_usehydfile(EN_Project *p, char *filename) { ---------------------------------------------------------------- */ -int DLLEXPORT EN_solveQ(EN_Project *p) { +int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { int errcode; long t, tstep; + EN_Project* p; + + p = (EN_Project*)ph; /* Open WQ solver */ errcode = EN_openQ(p); @@ -1070,8 +1097,11 @@ int DLLEXPORT EN_writeline(EN_Project *p, char *line) { return (0); } -int DLLEXPORT EN_report(EN_Project *p) { +int DLLEXPORT EN_report(EN_ProjectHandle ph) { int errcode; + EN_Project* p; + + p = (EN_Project*)ph; /* Check if results saved to binary output file */ if (!p->save_options.SaveQflag) diff --git a/src/input2.c b/src/input2.c index 2e54645..90c68aa 100644 --- a/src/input2.c +++ b/src/input2.c @@ -821,9 +821,10 @@ int match(const char *str, const char *substr) break; /* Check if substr matches remainder of str. */ - for (i = i, j = 0; substr[j]; i++, j++) + for (j = 0; substr[j]; i++, j++) if (!str[i] || UCHAR(str[i]) != UCHAR(substr[j])) return (0); + return (1); } /* end of match */ diff --git a/src/vars.h b/src/vars.h index 04f540c..88a940a 100755 --- a/src/vars.h +++ b/src/vars.h @@ -11,6 +11,6 @@ // this single global variable is used only when the library is called in "legacy mode" // with the 2.1-style API. -EXTERN EN_Project *_defaultModel; +EXTERN void* _defaultModel; #endif diff --git a/tools/epanet-toolkit/setup.py b/tools/epanet-toolkit/setup.py new file mode 100644 index 0000000..c3743c0 --- /dev/null +++ b/tools/epanet-toolkit/setup.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# +# setup.py - Setup up script for en_toolkit python extension +# +# Created: 11/27/2017 +# Author: Michael E. Tryby +# US EPA - ORD/NRMRL +# +# Requires: +# Platform C language compiler +# SWIG +# + +try: + from setuptools import setup, Extension + from setuptools.command.build_ext import build_ext +except ImportError: + from distutils.core import setup, Extension + from distutils.command.build_ext import build_ext + +setup( + name = "epanet-toolkit", + version = "0.0.0", + ext_modules = [ + Extension("_epanet_toolkit", + include_dirs = ['lib\\'], + libraries = ['epanet'], + library_dirs = ['lib\\'], + sources = ['src\\epanet_toolkit.i'], + swig_opts=['-modern'], + language = 'C' + ) + ], + package_dir = {'':'src'}, + py_modules = ['epanet_toolkit'], + + install_requires = [ + 'enum34' + ] +) diff --git a/tools/epanet-toolkit/src/epanet_toolkit.i b/tools/epanet-toolkit/src/epanet_toolkit.i new file mode 100644 index 0000000..40f7698 --- /dev/null +++ b/tools/epanet-toolkit/src/epanet_toolkit.i @@ -0,0 +1,71 @@ +/* + * epanet_toolkit.i - SWIG interface description file for EPANET toolkit + * + * Created: 11/27/2017 + * Author: Michael E. Tryby + * US EPA - ORD/NRMRL + * + * Build command: + * $ swig -I../../../include -python epanet_toolkit.i + * +*/ + +%module epanet_toolkit +%{ +#include "epanet2.h" + +#define SWIG_FILE_WITH_INIT +%} + + +/* DEFINE AND TYPEDEF MUST BE INCLUDED */ +typedef void* EN_ProjectHandle; + + +#ifndef DLLEXPORT + #ifdef WINDOWS + #ifdef __cplusplus + #define DLLEXPORT extern "C" __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllexport) __stdcall + #endif // __cplusplus + #elif defined(CYGWIN) + #define DLLEXPORT __stdcall + #elif defined(__APPLE__) + #ifdef __cplusplus + #define DLLEXPORT + #else + #define DLLEXPORT + #endif + #else + #define DLLEXPORT + #endif +#endif + + +/* TYPEMAPS FOR OPAQUE POINTER */ +/* Used for functions that output a new opaque pointer */ +%typemap(in, numinputs=0) EN_ProjectHandle* ph (EN_ProjectHandle retval) +{ + /* OUTPUT in */ + retval = NULL; + $1 = &retval; +} +/* used for functions that take in an opaque pointer (or NULL) +and return a (possibly) different pointer */ +%typemap(argout) EN_PorjectHandle* ph +{ + /* OUTPUT argout */ + %append_output(SWIG_NewPointerObj(SWIG_as_voidptr(retval$argnum), $1_descriptor, 0)); +} +/* No need for special IN typemap for opaque pointers, it works anyway */ + + +/* NO EXCEPTION HANDLING FOR THESE FUNCTIONS */ +int DLLEXPORT EN_alloc(EN_ProjectHandle* ph); +int DLLEXPORT EN_open(EN_ProjectHandle ph, char *inpFile, char *rptFile, char *binOutFile); +int DLLEXPORT EN_solveH(EN_ProjectHandle ph); +int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); +int DLLEXPORT EN_report(EN_ProjectHandle ph); +int DLLEXPORT EN_close(EN_ProjectHandle ph); +int DLLEXPORT EN_free(EN_ProjectHandle ph); diff --git a/tools/epanet-toolkit/test/data/Net1.inp b/tools/epanet-toolkit/test/data/Net1.inp new file mode 100644 index 0000000..4df5bbf --- /dev/null +++ b/tools/epanet-toolkit/test/data/Net1.inp @@ -0,0 +1,178 @@ +[TITLE] + EPANET Example Network 1 +A simple example of modeling chlorine decay. Both bulk and +wall reactions are included. + +[JUNCTIONS] +;ID Elev Demand Pattern + 10 710 0 ; + 11 710 150 ; + 12 700 150 ; + 13 695 100 ; + 21 700 150 ; + 22 695 200 ; + 23 690 150 ; + 31 700 100 ; + 32 710 100 ; + +[RESERVOIRS] +;ID Head Pattern + 9 800 ; + +[TANKS] +;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve + 2 850 120 100 150 50.5 0 ; + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness MinorLoss Status + 10 10 11 10530 18 100 0 Open ; + 11 11 12 5280 14 100 0 Open ; + 12 12 13 5280 10 100 0 Open ; + 21 21 22 5280 10 100 0 Open ; + 22 22 23 5280 12 100 0 Open ; + 31 31 32 5280 6 100 0 Open ; + 110 2 12 200 18 100 0 Open ; + 111 11 21 5280 10 100 0 Open ; + 112 12 22 5280 12 100 0 Open ; + 113 13 23 5280 8 100 0 Open ; + 121 21 31 5280 8 100 0 Open ; + 122 22 32 5280 6 100 0 Open ; + +[PUMPS] +;ID Node1 Node2 Parameters + 9 9 10 HEAD 1 ; + +[VALVES] +;ID Node1 Node2 Diameter Type Setting MinorLoss + +[TAGS] + +[DEMANDS] +;Junction Demand Pattern Category + +[STATUS] +;ID Status/Setting + +[PATTERNS] +;ID Multipliers +;Demand Pattern + 1 1.0 1.2 1.4 1.6 1.4 1.2 + 1 1.0 0.8 0.6 0.4 0.6 0.8 + +[CURVES] +;ID X-Value Y-Value +;PUMP: Pump Curve for Pump 9 + 1 1500 250 + +[CONTROLS] + LINK 9 OPEN IF NODE 2 BELOW 110 + LINK 9 CLOSED IF NODE 2 ABOVE 140 + + +[RULES] + +[ENERGY] + Global Efficiency 75 + Global Price 0.0 + Demand Charge 0.0 + +[EMITTERS] +;Junction Coefficient + +[QUALITY] +;Node InitQual + 10 0.5 + 11 0.5 + 12 0.5 + 13 0.5 + 21 0.5 + 22 0.5 + 23 0.5 + 31 0.5 + 32 0.5 + 9 1.0 + 2 1.0 + +[SOURCES] +;Node Type Quality Pattern + +[REACTIONS] +;Type Pipe/Tank Coefficient + + +[REACTIONS] + Order Bulk 1 + Order Tank 1 + Order Wall 1 + Global Bulk -.5 + Global Wall -1 + Limiting Potential 0.0 + Roughness Correlation 0.0 + +[MIXING] +;Tank Model + +[TIMES] + Duration 24:00 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Pattern Timestep 2:00 + Pattern Start 0:00 + Report Timestep 1:00 + Report Start 0:00 + Start ClockTime 12 am + Statistic None + +[REPORT] + Status Yes + Summary No + Page 0 + +[OPTIONS] + Units GPM + Headloss H-W + Specific Gravity 1.0 + Viscosity 1.0 + Trials 40 + Accuracy 0.001 + CHECKFREQ 2 + MAXCHECK 10 + DAMPLIMIT 0 + Unbalanced Continue 10 + Pattern 1 + Demand Multiplier 1.0 + Emitter Exponent 0.5 + Quality Chlorine mg/L + Diffusivity 1.0 + Tolerance 0.01 + +[COORDINATES] +;Node X-Coord Y-Coord + 10 20.00 70.00 + 11 30.00 70.00 + 12 50.00 70.00 + 13 70.00 70.00 + 21 30.00 40.00 + 22 50.00 40.00 + 23 70.00 40.00 + 31 30.00 10.00 + 32 50.00 10.00 + 9 10.00 70.00 + 2 50.00 90.00 + +[VERTICES] +;Link X-Coord Y-Coord + +[LABELS] +;X-Coord Y-Coord Label & Anchor Node + 6.99 73.63 "Source" + 13.48 68.13 "Pump" + 43.85 91.21 "Tank" + +[BACKDROP] + DIMENSIONS 7.00 6.00 73.00 94.00 + UNITS None + FILE + OFFSET 0.00 0.00 + +[END] diff --git a/tools/epanet-toolkit/test/epanet_toolkit_test.py b/tools/epanet-toolkit/test/epanet_toolkit_test.py new file mode 100644 index 0000000..7a2e8ce --- /dev/null +++ b/tools/epanet-toolkit/test/epanet_toolkit_test.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# +# epanet_toolkit_test.py - Unit tests for epanet toolkit API +# +# Created: Dec. 4, 2017 +# Author: Michael E. Tryby +# US EPA - ORD/NRMRL +# + +from unittest import TestCase +import inspect + +import epanet_toolkit as ent + + +class TestToolkitMethods(TestCase): + + def test_alloc(self): + pass + + def test_free(self): + pass + + def test_open(self): + pass + + def test_close(self): + pass + + +class TestToolkit(TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_solveH(self): + pass + + def test_solveQ(self): + pass + + def test_report(self): + pass + + \ No newline at end of file diff --git a/tools/epanet-toolkit/test/main.py b/tools/epanet-toolkit/test/main.py new file mode 100644 index 0000000..41b7dd6 --- /dev/null +++ b/tools/epanet-toolkit/test/main.py @@ -0,0 +1,13 @@ + +import epanet_toolkit as tlkt + +def epanet(): + [error, handle] = tlkt.EN_alloc() + + [error, handle] = tlkt.EN_free(handle) + + +if __name__ == "__main__": + + epanet() + diff --git a/tools/epanet-toolkit/test/test_epanet_toolkit.cpp b/tools/epanet-toolkit/test/test_epanet_toolkit.cpp new file mode 100644 index 0000000..ddca787 --- /dev/null +++ b/tools/epanet-toolkit/test/test_epanet_toolkit.cpp @@ -0,0 +1,34 @@ + +#include +#include + +#include "epanet2.h" + +// NOTE: Project Home needs to be updated to run unit test +#define PROJECT_HOME "C:/Users/mtryby/Workspace/GitRepo/michaeltryby/epanet" +#define DATA_PATH "/tools/epanet-toolkit/test/data/" + +using namespace std; + + +int main(int argc, char *argv[]) +{ + int error = 0; + EN_ProjectHandle project = NULL; + + char inputFile[10] = "Net1.inp"; + char reportFile[10] = "net1.rpt"; + char outputFile[10] = "net1.out"; + + error = EN_alloc(&project); + error = EN_open(project, inputFile, reportFile, outputFile); + + error = EN_solveH(project); + error = EN_solveQ(project); + error = EN_report(project); + + error = EN_close(project); + error = EN_free(project); + + return error; +} From 859a2ab9aaf1502dd496613b0db07488ed95bf34 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 25 Jan 2018 10:59:40 -0500 Subject: [PATCH 02/45] Moving epanet-toolkit to epanet-python repo --- tools/epanet-toolkit/setup.py | 40 ---- tools/epanet-toolkit/src/epanet_toolkit.i | 71 ------- tools/epanet-toolkit/test/data/Net1.inp | 178 ------------------ .../test/epanet_toolkit_test.py | 49 ----- tools/epanet-toolkit/test/main.py | 13 -- .../test/test_epanet_toolkit.cpp | 34 ---- 6 files changed, 385 deletions(-) delete mode 100644 tools/epanet-toolkit/setup.py delete mode 100644 tools/epanet-toolkit/src/epanet_toolkit.i delete mode 100644 tools/epanet-toolkit/test/data/Net1.inp delete mode 100644 tools/epanet-toolkit/test/epanet_toolkit_test.py delete mode 100644 tools/epanet-toolkit/test/main.py delete mode 100644 tools/epanet-toolkit/test/test_epanet_toolkit.cpp diff --git a/tools/epanet-toolkit/setup.py b/tools/epanet-toolkit/setup.py deleted file mode 100644 index c3743c0..0000000 --- a/tools/epanet-toolkit/setup.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# -# setup.py - Setup up script for en_toolkit python extension -# -# Created: 11/27/2017 -# Author: Michael E. Tryby -# US EPA - ORD/NRMRL -# -# Requires: -# Platform C language compiler -# SWIG -# - -try: - from setuptools import setup, Extension - from setuptools.command.build_ext import build_ext -except ImportError: - from distutils.core import setup, Extension - from distutils.command.build_ext import build_ext - -setup( - name = "epanet-toolkit", - version = "0.0.0", - ext_modules = [ - Extension("_epanet_toolkit", - include_dirs = ['lib\\'], - libraries = ['epanet'], - library_dirs = ['lib\\'], - sources = ['src\\epanet_toolkit.i'], - swig_opts=['-modern'], - language = 'C' - ) - ], - package_dir = {'':'src'}, - py_modules = ['epanet_toolkit'], - - install_requires = [ - 'enum34' - ] -) diff --git a/tools/epanet-toolkit/src/epanet_toolkit.i b/tools/epanet-toolkit/src/epanet_toolkit.i deleted file mode 100644 index 40f7698..0000000 --- a/tools/epanet-toolkit/src/epanet_toolkit.i +++ /dev/null @@ -1,71 +0,0 @@ -/* - * epanet_toolkit.i - SWIG interface description file for EPANET toolkit - * - * Created: 11/27/2017 - * Author: Michael E. Tryby - * US EPA - ORD/NRMRL - * - * Build command: - * $ swig -I../../../include -python epanet_toolkit.i - * -*/ - -%module epanet_toolkit -%{ -#include "epanet2.h" - -#define SWIG_FILE_WITH_INIT -%} - - -/* DEFINE AND TYPEDEF MUST BE INCLUDED */ -typedef void* EN_ProjectHandle; - - -#ifndef DLLEXPORT - #ifdef WINDOWS - #ifdef __cplusplus - #define DLLEXPORT extern "C" __declspec(dllexport) - #else - #define DLLEXPORT __declspec(dllexport) __stdcall - #endif // __cplusplus - #elif defined(CYGWIN) - #define DLLEXPORT __stdcall - #elif defined(__APPLE__) - #ifdef __cplusplus - #define DLLEXPORT - #else - #define DLLEXPORT - #endif - #else - #define DLLEXPORT - #endif -#endif - - -/* TYPEMAPS FOR OPAQUE POINTER */ -/* Used for functions that output a new opaque pointer */ -%typemap(in, numinputs=0) EN_ProjectHandle* ph (EN_ProjectHandle retval) -{ - /* OUTPUT in */ - retval = NULL; - $1 = &retval; -} -/* used for functions that take in an opaque pointer (or NULL) -and return a (possibly) different pointer */ -%typemap(argout) EN_PorjectHandle* ph -{ - /* OUTPUT argout */ - %append_output(SWIG_NewPointerObj(SWIG_as_voidptr(retval$argnum), $1_descriptor, 0)); -} -/* No need for special IN typemap for opaque pointers, it works anyway */ - - -/* NO EXCEPTION HANDLING FOR THESE FUNCTIONS */ -int DLLEXPORT EN_alloc(EN_ProjectHandle* ph); -int DLLEXPORT EN_open(EN_ProjectHandle ph, char *inpFile, char *rptFile, char *binOutFile); -int DLLEXPORT EN_solveH(EN_ProjectHandle ph); -int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); -int DLLEXPORT EN_report(EN_ProjectHandle ph); -int DLLEXPORT EN_close(EN_ProjectHandle ph); -int DLLEXPORT EN_free(EN_ProjectHandle ph); diff --git a/tools/epanet-toolkit/test/data/Net1.inp b/tools/epanet-toolkit/test/data/Net1.inp deleted file mode 100644 index 4df5bbf..0000000 --- a/tools/epanet-toolkit/test/data/Net1.inp +++ /dev/null @@ -1,178 +0,0 @@ -[TITLE] - EPANET Example Network 1 -A simple example of modeling chlorine decay. Both bulk and -wall reactions are included. - -[JUNCTIONS] -;ID Elev Demand Pattern - 10 710 0 ; - 11 710 150 ; - 12 700 150 ; - 13 695 100 ; - 21 700 150 ; - 22 695 200 ; - 23 690 150 ; - 31 700 100 ; - 32 710 100 ; - -[RESERVOIRS] -;ID Head Pattern - 9 800 ; - -[TANKS] -;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve - 2 850 120 100 150 50.5 0 ; - -[PIPES] -;ID Node1 Node2 Length Diameter Roughness MinorLoss Status - 10 10 11 10530 18 100 0 Open ; - 11 11 12 5280 14 100 0 Open ; - 12 12 13 5280 10 100 0 Open ; - 21 21 22 5280 10 100 0 Open ; - 22 22 23 5280 12 100 0 Open ; - 31 31 32 5280 6 100 0 Open ; - 110 2 12 200 18 100 0 Open ; - 111 11 21 5280 10 100 0 Open ; - 112 12 22 5280 12 100 0 Open ; - 113 13 23 5280 8 100 0 Open ; - 121 21 31 5280 8 100 0 Open ; - 122 22 32 5280 6 100 0 Open ; - -[PUMPS] -;ID Node1 Node2 Parameters - 9 9 10 HEAD 1 ; - -[VALVES] -;ID Node1 Node2 Diameter Type Setting MinorLoss - -[TAGS] - -[DEMANDS] -;Junction Demand Pattern Category - -[STATUS] -;ID Status/Setting - -[PATTERNS] -;ID Multipliers -;Demand Pattern - 1 1.0 1.2 1.4 1.6 1.4 1.2 - 1 1.0 0.8 0.6 0.4 0.6 0.8 - -[CURVES] -;ID X-Value Y-Value -;PUMP: Pump Curve for Pump 9 - 1 1500 250 - -[CONTROLS] - LINK 9 OPEN IF NODE 2 BELOW 110 - LINK 9 CLOSED IF NODE 2 ABOVE 140 - - -[RULES] - -[ENERGY] - Global Efficiency 75 - Global Price 0.0 - Demand Charge 0.0 - -[EMITTERS] -;Junction Coefficient - -[QUALITY] -;Node InitQual - 10 0.5 - 11 0.5 - 12 0.5 - 13 0.5 - 21 0.5 - 22 0.5 - 23 0.5 - 31 0.5 - 32 0.5 - 9 1.0 - 2 1.0 - -[SOURCES] -;Node Type Quality Pattern - -[REACTIONS] -;Type Pipe/Tank Coefficient - - -[REACTIONS] - Order Bulk 1 - Order Tank 1 - Order Wall 1 - Global Bulk -.5 - Global Wall -1 - Limiting Potential 0.0 - Roughness Correlation 0.0 - -[MIXING] -;Tank Model - -[TIMES] - Duration 24:00 - Hydraulic Timestep 1:00 - Quality Timestep 0:05 - Pattern Timestep 2:00 - Pattern Start 0:00 - Report Timestep 1:00 - Report Start 0:00 - Start ClockTime 12 am - Statistic None - -[REPORT] - Status Yes - Summary No - Page 0 - -[OPTIONS] - Units GPM - Headloss H-W - Specific Gravity 1.0 - Viscosity 1.0 - Trials 40 - Accuracy 0.001 - CHECKFREQ 2 - MAXCHECK 10 - DAMPLIMIT 0 - Unbalanced Continue 10 - Pattern 1 - Demand Multiplier 1.0 - Emitter Exponent 0.5 - Quality Chlorine mg/L - Diffusivity 1.0 - Tolerance 0.01 - -[COORDINATES] -;Node X-Coord Y-Coord - 10 20.00 70.00 - 11 30.00 70.00 - 12 50.00 70.00 - 13 70.00 70.00 - 21 30.00 40.00 - 22 50.00 40.00 - 23 70.00 40.00 - 31 30.00 10.00 - 32 50.00 10.00 - 9 10.00 70.00 - 2 50.00 90.00 - -[VERTICES] -;Link X-Coord Y-Coord - -[LABELS] -;X-Coord Y-Coord Label & Anchor Node - 6.99 73.63 "Source" - 13.48 68.13 "Pump" - 43.85 91.21 "Tank" - -[BACKDROP] - DIMENSIONS 7.00 6.00 73.00 94.00 - UNITS None - FILE - OFFSET 0.00 0.00 - -[END] diff --git a/tools/epanet-toolkit/test/epanet_toolkit_test.py b/tools/epanet-toolkit/test/epanet_toolkit_test.py deleted file mode 100644 index 7a2e8ce..0000000 --- a/tools/epanet-toolkit/test/epanet_toolkit_test.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# epanet_toolkit_test.py - Unit tests for epanet toolkit API -# -# Created: Dec. 4, 2017 -# Author: Michael E. Tryby -# US EPA - ORD/NRMRL -# - -from unittest import TestCase -import inspect - -import epanet_toolkit as ent - - -class TestToolkitMethods(TestCase): - - def test_alloc(self): - pass - - def test_free(self): - pass - - def test_open(self): - pass - - def test_close(self): - pass - - -class TestToolkit(TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass - - def test_solveH(self): - pass - - def test_solveQ(self): - pass - - def test_report(self): - pass - - \ No newline at end of file diff --git a/tools/epanet-toolkit/test/main.py b/tools/epanet-toolkit/test/main.py deleted file mode 100644 index 41b7dd6..0000000 --- a/tools/epanet-toolkit/test/main.py +++ /dev/null @@ -1,13 +0,0 @@ - -import epanet_toolkit as tlkt - -def epanet(): - [error, handle] = tlkt.EN_alloc() - - [error, handle] = tlkt.EN_free(handle) - - -if __name__ == "__main__": - - epanet() - diff --git a/tools/epanet-toolkit/test/test_epanet_toolkit.cpp b/tools/epanet-toolkit/test/test_epanet_toolkit.cpp deleted file mode 100644 index ddca787..0000000 --- a/tools/epanet-toolkit/test/test_epanet_toolkit.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -#include -#include - -#include "epanet2.h" - -// NOTE: Project Home needs to be updated to run unit test -#define PROJECT_HOME "C:/Users/mtryby/Workspace/GitRepo/michaeltryby/epanet" -#define DATA_PATH "/tools/epanet-toolkit/test/data/" - -using namespace std; - - -int main(int argc, char *argv[]) -{ - int error = 0; - EN_ProjectHandle project = NULL; - - char inputFile[10] = "Net1.inp"; - char reportFile[10] = "net1.rpt"; - char outputFile[10] = "net1.out"; - - error = EN_alloc(&project); - error = EN_open(project, inputFile, reportFile, outputFile); - - error = EN_solveH(project); - error = EN_solveQ(project); - error = EN_report(project); - - error = EN_close(project); - error = EN_free(project); - - return error; -} From 060db170184b4dd3cef8f403b3de92b9b8480ce3 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 26 Jan 2018 13:16:53 -0500 Subject: [PATCH 03/45] Adding epanet-output lib target to CMake --- CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 787806c..2c64c03 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,17 +56,19 @@ IF (MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) ENDIF (MSVC) -# create object library for reuse in other targets -include_directories(include src) +include_directories(include src tools/epanet-output/src) # configure file groups file(GLOB EPANET_SOURCES src/*.c) set(EPANET_API_HEADER include/epanet2.h) set(EPANET_CLI_SOURCES run/main.c) +file(GLOB EPANET_OUT_SOURCES tools/epanet-output/src/*.c) +set(EPANET_OUT_HEADER tools/epanet-output/src/epanet_output.h) +file(GLOB EPANET_LIB_ALL src/*.c) -file(GLOB EPANET_LIB_ALL src/*) source_group("Library" FILES ${EPANET_LIB_ALL}) source_group("CLI" REGULAR_EXPRESSION "run/.*") +source_group("Output" FILES ${EPANET_OUT_SOURCES}) # the shared library add_library(epanet SHARED ${EPANET_SOURCES} ${EPANET_API_HEADER}) @@ -79,3 +81,6 @@ if(NOT MSVC) else(NOT MSVC) target_link_libraries(runepanet LINK_PUBLIC epanet) endif(NOT MSVC) + +# the binary hydraulics file API +add_library(epanet-output SHARED ${EPANET_OUT_SOURCES} ${EPANET_OUT_HEADERS}) \ No newline at end of file From 62d6c9fadee773ae035191e7b1387157f0520199 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 30 Jan 2018 18:12:27 -0500 Subject: [PATCH 04/45] Converting EN_Project to void* EN_ProjectHandle to facilitate wrapping Toolkit API using SWIG. --- include/epanet2.h | 183 +++++++++-------- src/epanet.c | 501 ++++++++++++++++++++++++++++++++++++---------- src/types.h | 6 +- 3 files changed, 484 insertions(+), 206 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index cf0c106..617d71f 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -267,7 +267,7 @@ extern "C" { @brief The EPANET Project wrapper object */ typedef void* EN_ProjectHandle; - typedef struct EN_Project EN_Project; +// typedef struct EN_Project EN_Project; typedef struct EN_Pattern EN_Pattern; typedef struct EN_Curve EN_Curve; @@ -1125,114 +1125,113 @@ extern "C" { Threadsafe versions of all epanet functions ***************************************************/ - int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); - int DLLEXPORT EN_free(EN_ProjectHandle ph); + int DLLEXPORT EN_alloc(EN_ProjectHandle* ph); + int DLLEXPORT EN_free(EN_ProjectHandle* ph); - int DLLEXPORT EN_epanet(char *inpFile, char *rptFile, char *binOutFile, - void (*callback) (char *)); - int DLLEXPORT EN_init(EN_Project *p, char *rptFile, char *binOutFile, + int DLLEXPORT EN_init(EN_ProjectHandle* ph, char *rptFile, char *binOutFile, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, const char *rptFile, const char *binOutFile); - int DLLEXPORT EN_saveinpfile(EN_Project *p, char *filename); + int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename); int DLLEXPORT EN_close(EN_ProjectHandle ph); int DLLEXPORT EN_solveH(EN_ProjectHandle ph); - int DLLEXPORT EN_saveH(EN_Project *p); - int DLLEXPORT EN_openH(EN_Project *p); - int DLLEXPORT EN_initH(EN_Project *p, int EN_SaveOption); - int DLLEXPORT EN_runH(EN_Project *p, long *currentTime); - int DLLEXPORT EN_nextH(EN_Project *p, long *tStep); - int DLLEXPORT EN_closeH(EN_Project *p); - int DLLEXPORT EN_savehydfile(EN_Project *p, char *filename); - int DLLEXPORT EN_usehydfile(EN_Project *p, char *filename); + int DLLEXPORT EN_saveH(EN_ProjectHandle ph); + int DLLEXPORT EN_openH(EN_ProjectHandle ph); + int DLLEXPORT EN_initH(EN_ProjectHandle ph, int EN_SaveOption); + int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *currentTime); + int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tStep); + int DLLEXPORT EN_closeH(EN_ProjectHandle ph); + int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename); + int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename); int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); - - int DLLEXPORT EN_openQ(EN_Project *p); - int DLLEXPORT EN_initQ(EN_Project *p, int saveFlag); - int DLLEXPORT EN_runQ(EN_Project *p, long *currentTime); - int DLLEXPORT EN_nextQ(EN_Project *p, long *tStep); - int DLLEXPORT EN_stepQ(EN_Project *p, long *timeLeft); - int DLLEXPORT EN_closeQ(EN_Project *p); - int DLLEXPORT EN_writeline(EN_Project *p, char *line); + int DLLEXPORT EN_openQ(EN_ProjectHandle ph); + int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveFlag); + int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *currentTime); + int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tStep); + int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *timeLeft); + int DLLEXPORT EN_closeQ(EN_ProjectHandle ph); + int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line); int DLLEXPORT EN_report(EN_ProjectHandle ph); + int DLLEXPORT EN_resetreport(EN_ProjectHandle ph); + int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *reportFormat); - int DLLEXPORT EN_resetreport(EN_Project *p); - int DLLEXPORT EN_setreport(EN_Project *p, char *reportFormat); - int DLLEXPORT EN_getcontrol(EN_Project *p, int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); - int DLLEXPORT EN_getcount(EN_Project *p, EN_CountType code, int *count); - int DLLEXPORT EN_getoption(EN_Project *p, EN_Option opt, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_gettimeparam(EN_Project *p, int code, long *value); - int DLLEXPORT EN_getflowunits(EN_Project *p, int *code); - int DLLEXPORT EN_setflowunits(EN_Project *p, int code); - int DLLEXPORT EN_getpatternindex(EN_Project *p, char *id, int *index); - int DLLEXPORT EN_getpatternid(EN_Project *p, int index, char *id); - int DLLEXPORT EN_getpatternlen(EN_Project *p, int index, int *len); - int DLLEXPORT EN_getpatternvalue(EN_Project *p, int index, int period, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getaveragepatternvalue(EN_Project *p, int index, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getqualtype(EN_Project *p, int *qualcode, int *tracenode); + int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); + int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count); + int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option opt, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value); + int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code); + int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code); + int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len); + int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); - int DLLEXPORT EN_getstatistic(EN_Project *p, int code, EN_API_FLOAT_TYPE* value); - int DLLEXPORT EN_getnodeindex(EN_Project *p, char *id, int *index); - int DLLEXPORT EN_getnodeid(EN_Project *p, int index, char *id); - int DLLEXPORT EN_getnodetype(EN_Project *p, int index, int *code); - int DLLEXPORT EN_getnodevalue(EN_Project *p, int index, int code, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - int DLLEXPORT EN_setcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - int DLLEXPORT EN_getnumdemands(EN_Project *p, int nodeIndex, int *numDemands); - int DLLEXPORT EN_getbasedemand(EN_Project *p, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); - int DLLEXPORT EN_getdemandpattern(EN_Project *p, int nodeIndex, int demandIndex, int *pattIndex); - int DLLEXPORT EN_getlinkindex(EN_Project *p, char *id, int *index); - int DLLEXPORT EN_getlinkid(EN_Project *p, int index, char *id); - int DLLEXPORT EN_getlinktype(EN_Project *p, int index, EN_LinkType *code); - int DLLEXPORT EN_setlinktype(EN_Project *p, char *id, EN_LinkType type); - int DLLEXPORT EN_getlinknodes(EN_Project *p, int index, int *node1, int *node2); - int DLLEXPORT EN_getlinkvalue(EN_Project *p, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getcurve(EN_Project *p, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); - int DLLEXPORT EN_getheadcurveindex(EN_Project *p, int pumpIndex, int *curveIndex); - int DLLEXPORT EN_setheadcurveindex(EN_Project *p, int pumpIndex, int curveIndex); - int DLLEXPORT EN_getpumptype(EN_Project *p, int linkIndex, int *outType); + + int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE* value); + int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code); + int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands); + int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); + int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIndex, int *pattIndex); + int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code); + int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); + int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2); + int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); + int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int *curveIndex); + int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int curveIndex); + int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int linkIndex, int *outType); int DLLEXPORT EN_getversion(int *version); - int DLLEXPORT EN_setcontrol(EN_Project *p, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); - int DLLEXPORT EN_setnodevalue(EN_Project *p, int index, int code, EN_API_FLOAT_TYPE v); - int DLLEXPORT EN_setlinkvalue(EN_Project *p, int index, int code, EN_API_FLOAT_TYPE v); - int DLLEXPORT EN_addpattern(EN_Project *p, char *id); - int DLLEXPORT EN_setpattern(EN_Project *p, int index, EN_API_FLOAT_TYPE *f, int len); - int DLLEXPORT EN_setpatternvalue(EN_Project *p, int index, int period, EN_API_FLOAT_TYPE value); - int DLLEXPORT EN_settimeparam(EN_Project *p, int code, long value); - int DLLEXPORT EN_setoption(EN_Project *p, int code, EN_API_FLOAT_TYPE v); - int DLLEXPORT EN_setstatusreport(EN_Project *p, int code); - int DLLEXPORT EN_setqualtype(EN_Project *p, int qualcode, char *chemname, char *chemunits, char *tracenode); - int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname, char *chemunits, int *tracenode); - int DLLEXPORT EN_setbasedemand(EN_Project *p, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); - int DLLEXPORT EN_getcurveindex(EN_Project *p, char *id, int *index); - int DLLEXPORT EN_getcurveid(EN_Project *p, int index, char *id); - int DLLEXPORT EN_getcurvelen(EN_Project *p, int index, int *len); - int DLLEXPORT EN_getcurvevalue(EN_Project *p, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - int DLLEXPORT EN_setcurvevalue(EN_Project *p, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - int DLLEXPORT EN_setcurve(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); - int DLLEXPORT EN_addcurve(EN_Project *p, char *id); - int DLLEXPORT EN_getrule(EN_Project *p, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); - int DLLEXPORT EN_setrulepriority(EN_Project *p, int index, EN_API_FLOAT_TYPE priority); - int DLLEXPORT EN_getpremise(EN_Project *p, int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_setpremise(EN_Project *p, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); - int DLLEXPORT EN_setpremiseindex(EN_Project *p, int indexRule, int indexPremise, int indexObj); - int DLLEXPORT EN_setpremisestatus(EN_Project *p, int indexRule, int indexPremise, int status); - int DLLEXPORT EN_setpremisevalue(EN_Project *p, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); - int DLLEXPORT EN_gettrueaction(EN_Project *p, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); - int DLLEXPORT EN_settrueaction(EN_Project *p, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - int DLLEXPORT EN_getfalseaction(EN_Project *p, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); - int DLLEXPORT EN_setfalseaction(EN_Project *p, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - int DLLEXPORT EN_getruleID(EN_Project *p, int indexRule, char* id); - int DLLEXPORT EN_addnode(EN_Project *p, char *id, EN_NodeType nodeType); - int DLLEXPORT EN_addlink(EN_Project *p, char *id, EN_LinkType linkType, char *fromNode, char *toNode); - int DLLEXPORT EN_deletenode(EN_Project *p, int nodeIndex); - int DLLEXPORT EN_deletelink(EN_Project *p, int linkIndex); + int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); + int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id); + int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int len); + int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value); + int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value); + int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code); + int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode); + + int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode); + int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len); + int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); + int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id); + int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); + int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority); + int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); + int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj); + int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status); + int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); + int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char* id); + int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType); + int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode); + int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int nodeIndex); + int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex); #if defined(__cplusplus) diff --git a/src/epanet.c b/src/epanet.c index cc7d43c..3ce3ccf 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -154,8 +154,8 @@ execute function x and set the error code equal to its return value. int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) { int errcode = 0; - EN_Project* _p; + EN_Project* _p; _p = (EN_Project*)_defaultModel; ERRCODE(EN_alloc(&_defaultModel)); @@ -459,7 +459,7 @@ int DLLEXPORT ENdeletenode(int index) { */ /// allocate a project pointer -int DLLEXPORT EN_alloc(EN_ProjectHandle *ph) +int DLLEXPORT EN_alloc(EN_ProjectHandle* ph) { EN_Project *project = calloc(1, sizeof(EN_Project)); *ph = project; @@ -467,17 +467,19 @@ int DLLEXPORT EN_alloc(EN_ProjectHandle *ph) return 0; } -int DLLEXPORT EN_free(EN_ProjectHandle ph) +int DLLEXPORT EN_free(EN_ProjectHandle* ph) { EN_Project* p; - p = (EN_Project*)ph; + p = (EN_Project*)*ph; free(p); + *ph = NULL; + return 0; } -int DLLEXPORT EN_init(EN_Project *pr, char *f2, char *f3, +int DLLEXPORT EN_init(EN_ProjectHandle* ph, char *f2, char *f3, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula) /*---------------------------------------------------------------- ** Input: @@ -499,6 +501,10 @@ int DLLEXPORT EN_init(EN_Project *pr, char *f2, char *f3, _fpreset(); #endif + EN_Project* pr; + pr = (EN_Project*)*ph; + + /* Set system flags */ pr->Openflag = TRUE; pr->hydraulics.OpenHflag = FALSE; @@ -612,7 +618,7 @@ int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const return (errcode); } -int DLLEXPORT EN_saveinpfile(EN_Project *p, char *filename) +int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) /*---------------------------------------------------------------- ** Input: filename = name of INP file ** Output: none @@ -621,6 +627,9 @@ int DLLEXPORT EN_saveinpfile(EN_Project *p, char *filename) **---------------------------------------------------------------- */ { + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); return (saveinpfile(p, filename)); @@ -636,8 +645,8 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph) */ { out_file_t *out; - EN_Project* p; + EN_Project* p; p = (EN_Project*)ph; if (p->Openflag) { @@ -702,15 +711,15 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph) { int errcode; long t, tstep; - EN_Project* p; + EN_Project* p; p = (EN_Project*)ph; /* Open hydraulics solver */ - errcode = EN_openH(p); + errcode = EN_openH(ph); if (!errcode) { /* Initialize hydraulics */ - errcode = EN_initH(p, EN_SAVE); + errcode = EN_initH(ph, EN_SAVE); writecon(FMT14); /* Analyze each hydraulic period */ @@ -729,8 +738,8 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph) /* Solve for hydraulics & advance to next time period */ tstep = 0; - ERRCODE(EN_runH(p, &t)); - ERRCODE(EN_nextH(p, &tstep)); + ERRCODE(EN_runH(ph, &t)); + ERRCODE(EN_nextH(ph, &tstep)); /*** Updated 6/24/02 ***/ writecon("\b\b\b\b\b\b\b\b\b\b"); @@ -742,12 +751,12 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph) /*** Updated 6/24/02 ***/ writecon("\b\b\b\b\b\b\b\b "); - EN_closeH(p); + EN_closeH(ph); errcode = MAX(errcode, p->Warnflag); return (errcode); } -int DLLEXPORT EN_saveH(EN_Project *p) +int DLLEXPORT EN_saveH(EN_ProjectHandle ph) /*---------------------------------------------------------------- ** Input: none ** Output: none @@ -762,6 +771,9 @@ int DLLEXPORT EN_saveH(EN_Project *p) char tmpflag; int errcode; + EN_Project* p; + p = (EN_Project*)ph; + /* Check if hydraulic results exist */ if (!p->save_options.SaveHflag) return (104); @@ -783,7 +795,7 @@ int DLLEXPORT EN_saveH(EN_Project *p) return (errcode); } -int DLLEXPORT EN_openH(EN_Project *p) +int DLLEXPORT EN_openH(EN_ProjectHandle ph) /*---------------------------------------------------------------- ** Input: none ** Output: none @@ -794,6 +806,9 @@ int DLLEXPORT EN_openH(EN_Project *p) { int errcode = 0; + EN_Project* p; + p = (EN_Project*)ph; + /* Check that input data exists */ p->hydraulics.OpenHflag = FALSE; p->save_options.SaveHflag = FALSE; @@ -816,7 +831,7 @@ int DLLEXPORT EN_openH(EN_Project *p) } /*** Updated 3/1/01 ***/ -int DLLEXPORT EN_initH(EN_Project *p, int flag) +int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) /*---------------------------------------------------------------- ** Input: flag = 2-digit flag where 1st (left) digit indicates ** if link flows should be re-initialized (1) or @@ -831,6 +846,9 @@ int DLLEXPORT EN_initH(EN_Project *p, int flag) int errcode = 0; int sflag, fflag; + EN_Project* p; + p = (EN_Project*)ph; + /* Reset status flags */ p->save_options.SaveHflag = FALSE; p->Warnflag = FALSE; @@ -860,8 +878,12 @@ int DLLEXPORT EN_initH(EN_Project *p, int flag) return (errcode); } -int DLLEXPORT EN_runH(EN_Project *p, long *t) { +int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { int errcode; + + EN_Project* p; + p = (EN_Project*)ph; + *t = 0; if (!p->hydraulics.OpenHflag) return (103); @@ -871,8 +893,12 @@ int DLLEXPORT EN_runH(EN_Project *p, long *t) { return (errcode); } -int DLLEXPORT EN_nextH(EN_Project *p, long *tstep) { +int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { int errcode; + + EN_Project* p; + p = (EN_Project*)ph; + *tstep = 0; if (!p->hydraulics.OpenHflag) return (103); @@ -884,8 +910,11 @@ int DLLEXPORT EN_nextH(EN_Project *p, long *tstep) { return (errcode); } -int DLLEXPORT EN_closeH(EN_Project *p) +int DLLEXPORT EN_closeH(EN_ProjectHandle ph) { + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) { return (102); } @@ -896,11 +925,14 @@ int DLLEXPORT EN_closeH(EN_Project *p) return (0); } -int DLLEXPORT EN_savehydfile(EN_Project *p, char *filename) { +int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { FILE *f; int c; FILE *HydFile; + EN_Project* p; + p = (EN_Project*)ph; + /* Check that hydraulics results exist */ if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) return (104); @@ -919,9 +951,12 @@ int DLLEXPORT EN_savehydfile(EN_Project *p, char *filename) { return (0); } -int DLLEXPORT EN_usehydfile(EN_Project *p, char *filename) { +int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { int errcode; + EN_Project* p; + p = (EN_Project*)ph; + /* Check that input data exists & hydraulics system closed */ if (!p->Openflag) return (102); @@ -952,15 +987,15 @@ int DLLEXPORT EN_usehydfile(EN_Project *p, char *filename) { int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { int errcode; long t, tstep; - EN_Project* p; + EN_Project* p; p = (EN_Project*)ph; /* Open WQ solver */ - errcode = EN_openQ(p); + errcode = EN_openQ(ph); if (!errcode) { /* Initialize WQ */ - errcode = EN_initQ(p, EN_SAVE); + errcode = EN_initQ(ph, EN_SAVE); if (p->quality.Qualflag) writecon(FMT15); else { @@ -986,8 +1021,8 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { /* Retrieve current network solution & update WQ to next time period */ tstep = 0; - ERRCODE(EN_runQ(p, &t)); - ERRCODE(EN_nextQ(p, &tstep)); + ERRCODE(EN_runQ(ph, &t)); + ERRCODE(EN_nextQ(ph, &tstep)); /*** Updated 6/24/02 ***/ writecon("\b\b\b\b\b\b\b\b\b\b"); @@ -999,13 +1034,16 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { /*** Updated 6/24/02 ***/ writecon("\b\b\b\b\b\b\b\b "); - EN_closeQ(p); + EN_closeQ(ph); return (errcode); } -int DLLEXPORT EN_openQ(EN_Project *p) { +int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { int errcode = 0; + EN_Project* p; + p = (EN_Project*)ph; + /* Check that hydraulics results exist */ p->quality.OpenQflag = FALSE; p->save_options.SaveQflag = FALSE; @@ -1023,8 +1061,12 @@ int DLLEXPORT EN_openQ(EN_Project *p) { return (errcode); } -int DLLEXPORT EN_initQ(EN_Project *p, int saveflag) { +int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { int errcode = 0; + + EN_Project* p; + p = (EN_Project*)ph; + if (!p->quality.OpenQflag) return (105); initqual(p); @@ -1038,8 +1080,12 @@ int DLLEXPORT EN_initQ(EN_Project *p, int saveflag) { return (errcode); } -int DLLEXPORT EN_runQ(EN_Project *p, long *t) { +int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { int errcode; + + EN_Project* p; + p = (EN_Project*)ph; + *t = 0; if (!p->quality.OpenQflag) return (105); @@ -1049,8 +1095,12 @@ int DLLEXPORT EN_runQ(EN_Project *p, long *t) { return (errcode); } -int DLLEXPORT EN_nextQ(EN_Project *p, long *tstep) { +int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { int errcode; + + EN_Project* p; + p = (EN_Project*)ph; + *tstep = 0; if (!p->quality.OpenQflag) return (105); @@ -1063,8 +1113,12 @@ int DLLEXPORT EN_nextQ(EN_Project *p, long *tstep) { return (errcode); } -int DLLEXPORT EN_stepQ(EN_Project *p, long *tleft) { +int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { int errcode; + + EN_Project* p; + p = (EN_Project*)ph; + *tleft = 0; if (!p->quality.OpenQflag) return (105); @@ -1077,9 +1131,11 @@ int DLLEXPORT EN_stepQ(EN_Project *p, long *tleft) { return (errcode); } -int DLLEXPORT EN_closeQ(EN_Project *p) +int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { + + EN_Project* p; + p = (EN_Project*)ph; -{ if (!p->Openflag) return (102); closequal(p); @@ -1093,7 +1149,11 @@ int DLLEXPORT EN_closeQ(EN_Project *p) ---------------------------------------------------------------- */ -int DLLEXPORT EN_writeline(EN_Project *p, char *line) { +int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { + + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); writeline(p, line); @@ -1102,8 +1162,8 @@ int DLLEXPORT EN_writeline(EN_Project *p, char *line) { int DLLEXPORT EN_report(EN_ProjectHandle ph) { int errcode; - EN_Project* p; + EN_Project* p; p = (EN_Project*)ph; /* Check if results saved to binary output file */ @@ -1115,8 +1175,12 @@ int DLLEXPORT EN_report(EN_ProjectHandle ph) { return (errcode); } -int DLLEXPORT EN_resetreport(EN_Project *p) { +int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { int i; + + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); initreport(&p->report); @@ -1127,8 +1191,12 @@ int DLLEXPORT EN_resetreport(EN_Project *p) { return (0); } -int DLLEXPORT EN_setreport(EN_Project *p, char *s) { +int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { char s1[MAXLINE + 1]; + + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); if (strlen(s) > MAXLINE) @@ -1163,11 +1231,14 @@ int DLLEXPORT EN_getversion(int *v) return (0); } -int DLLEXPORT EN_getcontrol(EN_Project *pr, int cindex, int *ctype, int *lindex, +int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *lindex, EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) { double s, lvl; + EN_Project* pr; + pr = (EN_Project*)ph; + EN_Network *net = &pr->network; Scontrol *Control = net->Control; @@ -1221,7 +1292,11 @@ int DLLEXPORT EN_getcontrol(EN_Project *pr, int cindex, int *ctype, int *lindex, return (0); } -int DLLEXPORT EN_getcount(EN_Project *pr, EN_CountType code, int *count) { +int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { + + EN_Project* pr; + pr = (EN_Project*)ph; + EN_Network *net = &pr->network; *count = 0; @@ -1255,8 +1330,11 @@ int DLLEXPORT EN_getcount(EN_Project *pr, EN_CountType code, int *count) { return (0); } -int DLLEXPORT EN_getoption(EN_Project *pr, EN_Option code, +int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, EN_API_FLOAT_TYPE *value) { + EN_Project* pr; + pr = (EN_Project*)ph; + hydraulics_t *hyd = &pr->hydraulics; quality_t *qu = &pr->quality; double *Ucf = pr->Ucf; @@ -1289,9 +1367,12 @@ int DLLEXPORT EN_getoption(EN_Project *pr, EN_Option code, return (0); } -int DLLEXPORT EN_gettimeparam(EN_Project *pr, int code, long *value) { - +int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { int i; + + EN_Project* pr; + pr = (EN_Project*)ph; + report_options_t *rep = &pr->report; quality_t *qu = &pr->quality; time_options_t *time = &pr->time_options; @@ -1353,7 +1434,11 @@ int DLLEXPORT EN_gettimeparam(EN_Project *pr, int code, long *value) { return (0); } -int DLLEXPORT EN_getflowunits(EN_Project *p, int *code) { +int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { + + EN_Project* p; + p = (EN_Project*)ph; + *code = -1; if (!p->Openflag) return (102); @@ -1361,9 +1446,13 @@ int DLLEXPORT EN_getflowunits(EN_Project *p, int *code) { return (0); } -int DLLEXPORT EN_setflowunits(EN_Project *p, int code) { +int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int i, j; double qfactor, vfactor, hfactor, efactor, xfactor, yfactor; + + EN_Project* p; + p = (EN_Project*)ph; + double *Ucf = p->Ucf; EN_Network *net = &p->network; @@ -1435,8 +1524,12 @@ int DLLEXPORT EN_setflowunits(EN_Project *p, int code) { return(0); } -int DLLEXPORT EN_getpatternindex(EN_Project *p, char *id, int *index) { +int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { int i; + + EN_Project* p; + p = (EN_Project*)ph; + *index = 0; if (!p->Openflag) return (102); @@ -1450,7 +1543,10 @@ int DLLEXPORT EN_getpatternindex(EN_Project *p, char *id, int *index) { return (205); } -int DLLEXPORT EN_getpatternid(EN_Project *p, int index, char *id) { +int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { + EN_Project* p; + p = (EN_Project*)ph; + strcpy(id, ""); if (!p->Openflag) return (102); @@ -1460,7 +1556,10 @@ int DLLEXPORT EN_getpatternid(EN_Project *p, int index, char *id) { return (0); } -int DLLEXPORT EN_getpatternlen(EN_Project *p, int index, int *len) { +int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); if (index < 1 || index > p->network.Npats) @@ -1469,8 +1568,11 @@ int DLLEXPORT EN_getpatternlen(EN_Project *p, int index, int *len) { return (0); } -int DLLEXPORT EN_getpatternvalue(EN_Project *p, int index, int period, +int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE *value) { + EN_Project* p; + p = (EN_Project*)ph; + *value = 0.0; if (!p->Openflag) return (102); @@ -1482,8 +1584,12 @@ int DLLEXPORT EN_getpatternvalue(EN_Project *p, int index, int period, return (0); } -int DLLEXPORT EN_getcurveindex(EN_Project *p, char *id, int *index) { +int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { int i; + + EN_Project* p; + p = (EN_Project*)ph; + *index = 0; if (!p->Openflag) return (102); @@ -1497,7 +1603,10 @@ int DLLEXPORT EN_getcurveindex(EN_Project *p, char *id, int *index) { return (206); } -int DLLEXPORT EN_getcurveid(EN_Project *p, int index, char *id) { +int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { + EN_Project* p; + p = (EN_Project*)ph; + strcpy(id, ""); if (!p->Openflag) return (102); @@ -1507,7 +1616,10 @@ int DLLEXPORT EN_getcurveid(EN_Project *p, int index, char *id) { return (0); } -int DLLEXPORT EN_getcurvelen(EN_Project *p, int index, int *len) { +int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); if (index < 1 || index > p->network.Ncurves) @@ -1516,8 +1628,11 @@ int DLLEXPORT EN_getcurvelen(EN_Project *p, int index, int *len) { return (0); } -int DLLEXPORT EN_getcurvevalue(EN_Project *p, int index, int pnt, +int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { + EN_Project* p; + p = (EN_Project*)ph; + *x = 0.0; *y = 0.0; if (!p->Openflag) @@ -1531,7 +1646,10 @@ int DLLEXPORT EN_getcurvevalue(EN_Project *p, int index, int pnt, return (0); } -int DLLEXPORT EN_getqualtype(EN_Project *p, int *qualcode, int *tracenode) { +int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) { + EN_Project* p; + p = (EN_Project*)ph; + *tracenode = 0; if (!p->Openflag) return (102); @@ -1541,7 +1659,11 @@ int DLLEXPORT EN_getqualtype(EN_Project *p, int *qualcode, int *tracenode) { return (0); } -int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname, char *chemunits, int *tracenode) { +int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, + char *chemunits, int *tracenode) { + EN_Project* p; + p = (EN_Project*)ph; + ENgetqualtype(qualcode, tracenode); if (p->quality.Qualflag == TRACE) { strncpy(chemname, "", MAXID); @@ -1585,7 +1707,11 @@ int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { return (0); } -int DLLEXPORT EN_getstatistic(EN_Project *p, int code, EN_API_FLOAT_TYPE *value) { +int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE *value) { + + EN_Project* p; + p = (EN_Project*)ph; + switch (code) { case EN_ITERATIONS: *value = (EN_API_FLOAT_TYPE)p->hydraulics.iterations; @@ -1605,7 +1731,11 @@ int DLLEXPORT EN_getstatistic(EN_Project *p, int code, EN_API_FLOAT_TYPE *value) ---------------------------------------------------------------- */ -int DLLEXPORT EN_getnodeindex(EN_Project *p, char *id, int *index) { +int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { + + EN_Project* p; + p = (EN_Project*)ph; + *index = 0; if (!p->Openflag) return (102); @@ -1616,7 +1746,11 @@ int DLLEXPORT EN_getnodeindex(EN_Project *p, char *id, int *index) { return (0); } -int DLLEXPORT EN_getnodeid(EN_Project *p, int index, char *id) { +int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project* p; + p = (EN_Project*)ph; + strcpy(id, ""); if (!p->Openflag) return (102); @@ -1626,7 +1760,11 @@ int DLLEXPORT EN_getnodeid(EN_Project *p, int index, char *id) { return (0); } -int DLLEXPORT EN_getnodetype(EN_Project *p, int index, int *code) { +int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { + + EN_Project* p; + p = (EN_Project*)ph; + *code = -1; if (!p->Openflag) return (102); @@ -1643,8 +1781,11 @@ int DLLEXPORT EN_getnodetype(EN_Project *p, int index, int *code) { return (0); } -int DLLEXPORT EN_getcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, +int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); if (index < 1 || index > p->network.Nnodes) @@ -1661,8 +1802,11 @@ int DLLEXPORT EN_getcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, return 0; } -int DLLEXPORT EN_setcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE x, +int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { + EN_Project* p; + p = (EN_Project*)ph; + if (!p->Openflag) return (102); if (index < 1 || index > p->network.Nnodes) @@ -1676,12 +1820,14 @@ int DLLEXPORT EN_setcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE x, return 0; } -int DLLEXPORT EN_getnodevalue(EN_Project *p, int index, int code, +int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE *value) { double v = 0.0; Pdemand demand; Psource source; + EN_Project* p; + p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -1878,7 +2024,10 @@ int DLLEXPORT EN_getnodevalue(EN_Project *p, int index, int code, ---------------------------------------------------------------- */ -int DLLEXPORT EN_getlinkindex(EN_Project *p, char *id, int *index) { +int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { + EN_Project* p; + p = (EN_Project*)ph; + *index = 0; if (!p->Openflag) return (102); @@ -1889,7 +2038,10 @@ int DLLEXPORT EN_getlinkindex(EN_Project *p, char *id, int *index) { return (0); } -int DLLEXPORT EN_getlinkid(EN_Project *p, int index, char *id) { +int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { + EN_Project* p; + p = (EN_Project*)ph; + strcpy(id, ""); if (!p->Openflag) return (102); @@ -1899,7 +2051,10 @@ int DLLEXPORT EN_getlinkid(EN_Project *p, int index, char *id) { return (0); } -int DLLEXPORT EN_getlinktype(EN_Project *p, int index, EN_LinkType *code) { +int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { + EN_Project* p; + p = (EN_Project*)ph; + *code = -1; if (!p->Openflag) return (102); @@ -1909,8 +2064,11 @@ int DLLEXPORT EN_getlinktype(EN_Project *p, int index, EN_LinkType *code) { return (0); } -int DLLEXPORT EN_getlinknodes(EN_Project *p, int index, int *node1, +int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2) { + EN_Project* p; + p = (EN_Project*)ph; + *node1 = 0; *node2 = 0; if (!p->Openflag) @@ -1922,10 +2080,14 @@ int DLLEXPORT EN_getlinknodes(EN_Project *p, int index, int *node1, return (0); } -int DLLEXPORT EN_getlinkvalue(EN_Project *p, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value) { +int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, + EN_API_FLOAT_TYPE *value) { double a, h, q, v = 0.0; int returnValue = 0; + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2133,13 +2295,16 @@ int DLLEXPORT EN_getlinkvalue(EN_Project *p, int index, EN_LinkProperty code, EN return returnValue; } -int DLLEXPORT EN_getcurve(EN_Project *p, int curveIndex, char *id, int *nValues, +int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) { int iPoint, nPoints; Scurve curve; EN_API_FLOAT_TYPE *pointX, *pointY; + EN_Project* p; + p = (EN_Project*)ph; + /* Check that input file opened */ if (!p->Openflag) return (102); @@ -2172,7 +2337,7 @@ int DLLEXPORT EN_getcurve(EN_Project *p, int curveIndex, char *id, int *nValues, ---------------------------------------------------------------- */ -int DLLEXPORT EN_setcontrol(EN_Project *p, int cindex, int ctype, int lindex, +int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) { char status = ACTIVE; @@ -2188,6 +2353,9 @@ int DLLEXPORT EN_setcontrol(EN_Project *p, int cindex, int ctype, int lindex, int Nlinks; double *Ucf; + EN_Project* p; + p = (EN_Project*)ph; + /* Check that input file opened */ if (!p->Openflag) return (102); @@ -2284,7 +2452,7 @@ int DLLEXPORT EN_setcontrol(EN_Project *p, int cindex, int ctype, int lindex, return (0); } -int DLLEXPORT EN_setnodevalue(EN_Project *p, int index, int code, EN_API_FLOAT_TYPE v) +int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) /*---------------------------------------------------------------- ** Input: index = node index ** code = node parameter code (see EPANET2.H) @@ -2295,6 +2463,9 @@ int DLLEXPORT EN_setnodevalue(EN_Project *p, int index, int code, EN_API_FLOAT_T **---------------------------------------------------------------- */ { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; quality_t *qu = &p->quality; @@ -2548,7 +2719,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project *p, int index, int code, EN_API_FLOAT_T return (0); } -int DLLEXPORT EN_setlinkvalue(EN_Project *p, int index, int code, +int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) /*---------------------------------------------------------------- @@ -2561,7 +2732,9 @@ int DLLEXPORT EN_setlinkvalue(EN_Project *p, int index, int code, **---------------------------------------------------------------- */ { - + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; quality_t *qu = &p->quality; @@ -2692,10 +2865,13 @@ int DLLEXPORT EN_setlinkvalue(EN_Project *p, int index, int code, return (0); } -int DLLEXPORT EN_addpattern(EN_Project *p, char *id) { +int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int i, j, n, err = 0; Spattern *tmpPat; + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; parser_data_t *par = &p->parser; @@ -2767,9 +2943,12 @@ int DLLEXPORT EN_addpattern(EN_Project *p, char *id) { return 0; } -int DLLEXPORT EN_setpattern(EN_Project *p, int index, EN_API_FLOAT_TYPE *f, int n) { +int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { int j; + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Spattern *Pattern = net->Pattern; const int Npats = net->Npats; @@ -2795,8 +2974,11 @@ int DLLEXPORT EN_setpattern(EN_Project *p, int index, EN_API_FLOAT_TYPE *f, int return (0); } -int DLLEXPORT EN_setpatternvalue(EN_Project *p, int index, int period, EN_API_FLOAT_TYPE value) { +int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Spattern *Pattern = net->Pattern; @@ -2814,8 +2996,11 @@ int DLLEXPORT EN_setpatternvalue(EN_Project *p, int index, int period, EN_API_FL return (0); } -int DLLEXPORT EN_addcurve(EN_Project *p, char *id) { +int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; parser_data_t *par = &p->parser; Scurve *Curve = net->Curve; @@ -2902,8 +3087,11 @@ int DLLEXPORT EN_addcurve(EN_Project *p, char *id) { return 0; } -int DLLEXPORT EN_setcurve(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n) { +int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Scurve *Curve = net->Curve; @@ -2935,8 +3123,11 @@ int DLLEXPORT EN_setcurve(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, EN_API return (0); } -int DLLEXPORT EN_setcurvevalue(EN_Project *p, int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { - +int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { + + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Scurve *Curve = net->Curve; @@ -2955,8 +3146,11 @@ int DLLEXPORT EN_setcurvevalue(EN_Project *p, int index, int pnt, EN_API_FLOAT_T return (0); } -int DLLEXPORT EN_settimeparam(EN_Project *p, int code, long value) +int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) { + EN_Project* p; + p = (EN_Project*)ph; + report_options_t *rep = &p->report; quality_t *qu = &p->quality; time_options_t *time = &p->time_options; @@ -3055,7 +3249,7 @@ int DLLEXPORT EN_settimeparam(EN_Project *p, int code, long value) return (0); } -int DLLEXPORT EN_setoption(EN_Project *p, int code, EN_API_FLOAT_TYPE v) +int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) /*---------------------------------------------------------------- ** Input: code = option code (see EPANET2.H) ** v = option value @@ -3065,6 +3259,9 @@ int DLLEXPORT EN_setoption(EN_Project *p, int code, EN_API_FLOAT_TYPE v) **---------------------------------------------------------------- */ { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; quality_t *qu = &p->quality; @@ -3118,8 +3315,12 @@ int DLLEXPORT EN_setoption(EN_Project *p, int code, EN_API_FLOAT_TYPE v) return (0); } -int DLLEXPORT EN_setstatusreport(EN_Project *p, int code) { +int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int errcode = 0; + + EN_Project* p; + p = (EN_Project*)ph; + if (code >= 0 && code <= 2) p->report.Statflag = (char)code; else @@ -3127,8 +3328,11 @@ int DLLEXPORT EN_setstatusreport(EN_Project *p, int code) { return (errcode); } -int DLLEXPORT EN_setqualtype(EN_Project *p, int qualcode, char *chemname, char *chemunits, char *tracenode) { +int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; report_options_t *rep = &p->report; quality_t *qu = &p->quality; @@ -3192,8 +3396,11 @@ int DLLEXPORT EN_setqualtype(EN_Project *p, int qualcode, char *chemname, char * return (0); } -int DLLEXPORT EN_getheadcurveindex(EN_Project *p, int index, int *curveindex) { +int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveindex) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Slink *Link = net->Link; Spump *Pump = net->Pump; @@ -3207,8 +3414,11 @@ int DLLEXPORT EN_getheadcurveindex(EN_Project *p, int index, int *curveindex) { return (0); } -int DLLEXPORT EN_setheadcurveindex(EN_Project *p, int index, int curveindex) { +int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveindex) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Slink *Link = net->Link; @@ -3246,8 +3456,11 @@ int DLLEXPORT EN_setheadcurveindex(EN_Project *p, int index, int curveindex) { return (0); } -int DLLEXPORT EN_getpumptype(EN_Project *p, int index, int *type) { +int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Slink *Link = net->Link; @@ -4017,9 +4230,13 @@ void writewin(void (*vp)(char *), char *s) } } -int DLLEXPORT EN_getnumdemands(EN_Project *p, int nodeIndex, int *numDemands) { +int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands) { Pdemand d; int n = 0; + + EN_Project* p; + p = (EN_Project*)ph; + /* Check for valid arguments */ if (!p->Openflag) return (102); @@ -4031,9 +4248,13 @@ int DLLEXPORT EN_getnumdemands(EN_Project *p, int nodeIndex, int *numDemands) { return 0; } -int DLLEXPORT EN_getbasedemand(EN_Project *p, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { +int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { Pdemand d; int n = 1; + + EN_Project* p; + p = (EN_Project*)ph; + /* Check for valid arguments */ if (!p->Openflag) return (102); @@ -4053,8 +4274,11 @@ int DLLEXPORT EN_getbasedemand(EN_Project *p, int nodeIndex, int demandIdx, EN_A return 0; } -int DLLEXPORT EN_setbasedemand(EN_Project *pr, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) { +int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) { + EN_Project* pr; + pr = (EN_Project*)ph; + EN_Network *net = &pr->network; Snode *Node = net->Node; @@ -4080,8 +4304,11 @@ int DLLEXPORT EN_setbasedemand(EN_Project *pr, int nodeIndex, int demandIdx, EN_ return 0; } -int DLLEXPORT EN_getdemandpattern(EN_Project *p, int nodeIndex, int demandIdx, int *pattIdx) { +int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int *pattIdx) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Snode *Node = net->Node; const int Nnodes = net->Nnodes; @@ -4101,8 +4328,11 @@ int DLLEXPORT EN_getdemandpattern(EN_Project *p, int nodeIndex, int demandIdx, i return 0; } -int DLLEXPORT EN_getaveragepatternvalue(EN_Project *p, int index, EN_API_FLOAT_TYPE *value) { +int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value) { + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Spattern *Pattern = net->Pattern; @@ -4122,10 +4352,13 @@ int DLLEXPORT EN_getaveragepatternvalue(EN_Project *p, int index, EN_API_FLOAT_T return (0); } -int DLLEXPORT EN_setlinktype(EN_Project *p, char *id, EN_LinkType toType) { +int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType toType) { int i; EN_LinkType fromType; + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; if (!p->Openflag) @@ -4159,10 +4392,14 @@ int DLLEXPORT EN_setlinktype(EN_Project *p, char *id, EN_LinkType toType) { return 0; } -int DLLEXPORT EN_addnode(EN_Project *p, char *id, EN_NodeType nodeType) { +int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) { int i, nIdx; int index; struct Sdemand *demand; + + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; quality_t *qu = &p->quality; @@ -4272,10 +4509,14 @@ int DLLEXPORT EN_addnode(EN_Project *p, char *id, EN_NodeType nodeType) { return (0); } -int DLLEXPORT EN_addlink(EN_Project *p, char *id, EN_LinkType linkType, char *fromNode, +int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode) { int i, n; int N1, N2; + + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; Slink *link; @@ -4382,9 +4623,13 @@ int DLLEXPORT EN_addlink(EN_Project *p, char *id, EN_LinkType linkType, char *fr return (0); } -int DLLEXPORT EN_deletelink(EN_Project *p, int index) { +int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { int i; EN_LinkType linkType; + + EN_Project* p; + p = (EN_Project*)ph; + EN_Network *net = &p->network; Slink *link; @@ -4441,7 +4686,10 @@ int DLLEXPORT EN_deletelink(EN_Project *p, int index) { return 0; } -int DLLEXPORT EN_deletenode(EN_Project *p, int index) { +int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) { + + EN_Project* p; + p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4509,7 +4757,7 @@ int DLLEXPORT EN_deletenode(EN_Project *p, int index) { return (0); } -int DLLEXPORT EN_getrule(EN_Project *pr, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority) +int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority) /*---------------------------------------------------------------- ** Input: index = index of the rule ** nPremises = number of conditions (IF AND OR) @@ -4525,6 +4773,9 @@ int DLLEXPORT EN_getrule(EN_Project *pr, int index, int *nPremises, int *nTrueAc Premise *p; Action *c; + EN_Project* pr; + pr = (EN_Project*)ph; + EN_Network *net = &pr->network; if (index > net->Nrules) @@ -4558,14 +4809,15 @@ int DLLEXPORT EN_getrule(EN_Project *pr, int index, int *nPremises, int *nTrueAc return (0); } -int DLLEXPORT EN_getpremise(EN_Project *pr, int indexRule, int idxPremise, int *logop, +int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int idxPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value) { int count = 1, error = 0, nPremises, a, b; EN_API_FLOAT_TYPE priority; Premise *p; - + EN_Project* pr; + pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -4590,7 +4842,7 @@ int DLLEXPORT EN_getpremise(EN_Project *pr, int indexRule, int idxPremise, int * return (0); } -int DLLEXPORT EN_setrulepriority(EN_Project *pr, int index, EN_API_FLOAT_TYPE priority) +int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority) /*---------------------------------------------------------------- ** Input: index = index of the rule ** priority = rule priority @@ -4599,6 +4851,9 @@ int DLLEXPORT EN_setrulepriority(EN_Project *pr, int index, EN_API_FLOAT_TYPE pr **---------------------------------------------------------------- */ { + EN_Project* pr; + pr = (EN_Project*)ph; + if (index > pr->network.Nrules) { return (257); } @@ -4607,14 +4862,15 @@ int DLLEXPORT EN_setrulepriority(EN_Project *pr, int index, EN_API_FLOAT_TYPE pr return (0); } -int DLLEXPORT EN_setpremise(EN_Project *pr, int indexRule, int indexPremise, int logop, +int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value) { int count = 1, error = 0, nPremises, a, b; EN_API_FLOAT_TYPE priority; Premise *p; - + EN_Project* pr; + pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -4638,11 +4894,14 @@ int DLLEXPORT EN_setpremise(EN_Project *pr, int indexRule, int indexPremise, int return (0); } -int DLLEXPORT EN_setpremiseindex(EN_Project *pr, int indexRule, int indexPremise, int indexObj) { +int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj) { int count = 1, error = 0, nPremises, a, b; EN_API_FLOAT_TYPE priority; Premise *p; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) return (257); error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); @@ -4658,11 +4917,14 @@ int DLLEXPORT EN_setpremiseindex(EN_Project *pr, int indexRule, int indexPremise return (0); } -int DLLEXPORT EN_setpremisestatus(EN_Project *pr, int indexRule, int indexPremise, int status) { +int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status) { int count = 1, error = 0, nPremises, a, b; EN_API_FLOAT_TYPE priority; Premise *p; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) { return (257); } @@ -4679,12 +4941,15 @@ int DLLEXPORT EN_setpremisestatus(EN_Project *pr, int indexRule, int indexPremis return (0); } -int DLLEXPORT EN_setpremisevalue(EN_Project *pr, int indexRule, int indexPremise, +int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value) { int count = 1, error = 0, nPremises, a, b; EN_API_FLOAT_TYPE priority; Premise *p; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) return (257); error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); @@ -4700,12 +4965,15 @@ int DLLEXPORT EN_setpremisevalue(EN_Project *pr, int indexRule, int indexPremise return (0); } -int DLLEXPORT EN_gettrueaction(EN_Project *pr, int indexRule, int indexAction, int *indexLink, +int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting) { int count = 1, error = 0, nTrueAction, c, b; EN_API_FLOAT_TYPE priority; Action *a; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) { return (252); } @@ -4724,12 +4992,15 @@ int DLLEXPORT EN_gettrueaction(EN_Project *pr, int indexRule, int indexAction, i return (0); } -int DLLEXPORT EN_settrueaction(EN_Project *pr, int indexRule, int indexAction, int indexLink, +int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting) { int count = 1, error = 0, nTrueAction, c, b; EN_API_FLOAT_TYPE priority; Action *a; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) { return (257); } @@ -4748,12 +5019,15 @@ int DLLEXPORT EN_settrueaction(EN_Project *pr, int indexRule, int indexAction, i return (0); } -int DLLEXPORT EN_getfalseaction(EN_Project *pr, int indexRule, int indexAction, int *indexLink, +int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting) { int count = 1, error = 0, nFalseAction, c, b; EN_API_FLOAT_TYPE priority; Action *a; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) { return (257); } @@ -4772,12 +5046,15 @@ int DLLEXPORT EN_getfalseaction(EN_Project *pr, int indexRule, int indexAction, return (0); } -int DLLEXPORT EN_setfalseaction(EN_Project *pr, int indexRule, int indexAction, int indexLink, +int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting) { int count = 1, error = 0, nFalseAction, c, b; EN_API_FLOAT_TYPE priority; Action *a; + EN_Project* pr; + pr = (EN_Project*)ph; + if (indexRule > pr->network.Nrules) { return (257); } @@ -4797,7 +5074,11 @@ int DLLEXPORT EN_setfalseaction(EN_Project *pr, int indexRule, int indexAction, return (0); } -int DLLEXPORT EN_getruleID(EN_Project *pr, int indexRule, char *id) { +int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char *id) { + + EN_Project* pr; + pr = (EN_Project*)ph; + strcpy(id, ""); if (!pr->Openflag) return (102); diff --git a/src/types.h b/src/types.h index 920c779..a521f7d 100755 --- a/src/types.h +++ b/src/types.h @@ -825,7 +825,7 @@ typedef struct { /* project wrapper */ -struct EN_Project { +typedef struct EN_Project { EN_Network network; /// the network description struct hydraulics_t hydraulics; @@ -849,9 +849,7 @@ struct EN_Project { void (* viewprog) (char *); /* Pointer to progress viewing function */ -}; - - +} EN_Project; #endif From 17cd1c60f828b5460f8386d6291371d3a0a8a257 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 1 Feb 2018 17:10:36 -0500 Subject: [PATCH 05/45] Switching EN_Project to void* for SWIG wrap. Cleaning up build. --- src/epanet.c | 308 +++++++++++++++++++-------------------------------- src/funcs.h | 8 +- src/rules.c | 2 +- 3 files changed, 122 insertions(+), 196 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 3ce3ccf..d1afb37 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -155,8 +155,7 @@ int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) { int errcode = 0; - EN_Project* _p; - _p = (EN_Project*)_defaultModel; + EN_Project* _p = (EN_Project*)_defaultModel; ERRCODE(EN_alloc(&_defaultModel)); ERRCODE(EN_open(_defaultModel, f1, f2, f3)); @@ -469,8 +468,7 @@ int DLLEXPORT EN_alloc(EN_ProjectHandle* ph) int DLLEXPORT EN_free(EN_ProjectHandle* ph) { - EN_Project* p; - p = (EN_Project*)*ph; + EN_Project* p = (EN_Project*)*ph; free(p); @@ -501,8 +499,7 @@ int DLLEXPORT EN_init(EN_ProjectHandle* ph, char *f2, char *f3, _fpreset(); #endif - EN_Project* pr; - pr = (EN_Project*)*ph; + EN_Project* pr = (EN_Project*)*ph; /* Set system flags */ @@ -561,8 +558,7 @@ int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const _fpreset(); #endif - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Set system flags */ p->Openflag = FALSE; @@ -627,8 +623,7 @@ int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) **---------------------------------------------------------------- */ { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -646,8 +641,7 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph) { out_file_t *out; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (p->Openflag) { writetime(p, FMT105); @@ -712,8 +706,7 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph) int errcode; long t, tstep; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Open hydraulics solver */ errcode = EN_openH(ph); @@ -771,8 +764,7 @@ int DLLEXPORT EN_saveH(EN_ProjectHandle ph) char tmpflag; int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check if hydraulic results exist */ if (!p->save_options.SaveHflag) @@ -806,8 +798,7 @@ int DLLEXPORT EN_openH(EN_ProjectHandle ph) { int errcode = 0; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check that input data exists */ p->hydraulics.OpenHflag = FALSE; @@ -846,8 +837,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) int errcode = 0; int sflag, fflag; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Reset status flags */ p->save_options.SaveHflag = FALSE; @@ -881,8 +871,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *t = 0; if (!p->hydraulics.OpenHflag) @@ -896,8 +885,7 @@ int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *tstep = 0; if (!p->hydraulics.OpenHflag) @@ -912,8 +900,7 @@ int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { int DLLEXPORT EN_closeH(EN_ProjectHandle ph) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) { return (102); @@ -930,8 +917,7 @@ int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { int c; FILE *HydFile; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check that hydraulics results exist */ if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) @@ -954,8 +940,7 @@ int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check that input data exists & hydraulics system closed */ if (!p->Openflag) @@ -988,8 +973,7 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { int errcode; long t, tstep; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Open WQ solver */ errcode = EN_openQ(ph); @@ -1041,8 +1025,7 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { int errcode = 0; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check that hydraulics results exist */ p->quality.OpenQflag = FALSE; @@ -1064,8 +1047,7 @@ int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { int errcode = 0; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->quality.OpenQflag) return (105); @@ -1083,8 +1065,7 @@ int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *t = 0; if (!p->quality.OpenQflag) @@ -1098,8 +1079,7 @@ int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *tstep = 0; if (!p->quality.OpenQflag) @@ -1116,8 +1096,7 @@ int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *tleft = 0; if (!p->quality.OpenQflag) @@ -1133,8 +1112,7 @@ int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1151,8 +1129,7 @@ int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1163,8 +1140,7 @@ int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { int DLLEXPORT EN_report(EN_ProjectHandle ph) { int errcode; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check if results saved to binary output file */ if (!p->save_options.SaveQflag) @@ -1178,8 +1154,7 @@ int DLLEXPORT EN_report(EN_ProjectHandle ph) { int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { int i; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1194,8 +1169,7 @@ int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { char s1[MAXLINE + 1]; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1236,8 +1210,7 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li EN_API_FLOAT_TYPE *level) { double s, lvl; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; EN_Network *net = &pr->network; @@ -1247,7 +1220,7 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li const int Njuncs = net->Njuncs; double *Ucf = pr->Ucf; - + s = 0.0; lvl = 0.0; *ctype = 0; @@ -1294,8 +1267,7 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; EN_Network *net = &pr->network; @@ -1332,8 +1304,8 @@ int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, EN_API_FLOAT_TYPE *value) { - EN_Project* pr; - pr = (EN_Project*)ph; + + EN_Project* pr = (EN_Project*)ph; hydraulics_t *hyd = &pr->hydraulics; quality_t *qu = &pr->quality; @@ -1370,8 +1342,7 @@ int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { int i; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; report_options_t *rep = &pr->report; quality_t *qu = &pr->quality; @@ -1436,8 +1407,7 @@ int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *code = -1; if (!p->Openflag) @@ -1450,8 +1420,7 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int i, j; double qfactor, vfactor, hfactor, efactor, xfactor, yfactor; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; double *Ucf = p->Ucf; EN_Network *net = &p->network; @@ -1527,8 +1496,7 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { int i; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -1544,8 +1512,8 @@ int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { } int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -1557,8 +1525,8 @@ int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { } int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1570,8 +1538,8 @@ int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE *value) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; *value = 0.0; if (!p->Openflag) @@ -1587,8 +1555,7 @@ int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { int i; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -1604,8 +1571,8 @@ int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { } int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -1617,8 +1584,8 @@ int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { } int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1630,8 +1597,8 @@ int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; *x = 0.0; *y = 0.0; @@ -1647,8 +1614,8 @@ int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, } int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; *tracenode = 0; if (!p->Openflag) @@ -1661,8 +1628,7 @@ int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; ENgetqualtype(qualcode, tracenode); if (p->quality.Qualflag == TRACE) { @@ -1709,8 +1675,7 @@ int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE *value) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; switch (code) { case EN_ITERATIONS: @@ -1733,8 +1698,7 @@ int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE * int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -1748,8 +1712,7 @@ int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -1762,8 +1725,7 @@ int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; *code = -1; if (!p->Openflag) @@ -1783,8 +1745,8 @@ int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1797,15 +1759,16 @@ int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, if (p->network.Coord[index].HaveCoords == FALSE) return (254); - *x = p->network.Coord[index].X; - *y = p->network.Coord[index].Y; + *x = (EN_API_FLOAT_TYPE)p->network.Coord[index].X; + *y = (EN_API_FLOAT_TYPE)p->network.Coord[index].Y; + return 0; } int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1826,8 +1789,7 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, Pdemand demand; Psource source; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2025,8 +1987,8 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, */ int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -2039,8 +2001,8 @@ int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { } int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -2052,8 +2014,8 @@ int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { } int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; *code = -1; if (!p->Openflag) @@ -2066,8 +2028,8 @@ int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2) { - EN_Project* p; - p = (EN_Project*)ph; + + EN_Project* p = (EN_Project*)ph; *node1 = 0; *node2 = 0; @@ -2085,8 +2047,7 @@ int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty co double a, h, q, v = 0.0; int returnValue = 0; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2302,8 +2263,7 @@ int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nV Scurve curve; EN_API_FLOAT_TYPE *pointX, *pointY; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check that input file opened */ if (!p->Openflag) @@ -2353,8 +2313,7 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind int Nlinks; double *Ucf; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check that input file opened */ if (!p->Openflag) @@ -2463,8 +2422,7 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F **---------------------------------------------------------------- */ { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2732,8 +2690,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, **---------------------------------------------------------------- */ { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2869,8 +2826,7 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int i, j, n, err = 0; Spattern *tmpPat; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; parser_data_t *par = &p->parser; @@ -2946,8 +2902,7 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { int j; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; Spattern *Pattern = net->Pattern; @@ -2976,8 +2931,7 @@ int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -2998,8 +2952,7 @@ int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; parser_data_t *par = &p->parser; @@ -3089,8 +3042,7 @@ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; Scurve *Curve = net->Curve; @@ -3125,8 +3077,7 @@ int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -3148,8 +3099,7 @@ int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_F int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; report_options_t *rep = &p->report; quality_t *qu = &p->quality; @@ -3259,8 +3209,7 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) **---------------------------------------------------------------- */ { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -3318,8 +3267,7 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int errcode = 0; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; if (code >= 0 && code <= 2) p->report.Statflag = (char)code; @@ -3330,8 +3278,7 @@ int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; report_options_t *rep = &p->report; @@ -3398,8 +3345,7 @@ int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveindex) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; Slink *Link = net->Link; @@ -3416,8 +3362,7 @@ int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveind int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveindex) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -3458,8 +3403,7 @@ int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveinde int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -3482,7 +3426,7 @@ int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { ---------------------------------------------------------------- */ -int openfiles(EN_Project *p, char *f1, char *f2, char *f3) +int openfiles(EN_Project *p, const char *f1, const char *f2, const char *f3) /*---------------------------------------------------------------- ** Input: f1 = pointer to name of input file ** f2 = pointer to name of report file @@ -4035,7 +3979,7 @@ char *getTmpName(EN_Project *p, char *fname) return fname; } -int strcomp(char *s1, char *s2) +int strcomp(const char *s1, const char *s2) /*--------------------------------------------------------------- ** Input: s1 = character string ** s2 = character string @@ -4201,7 +4145,7 @@ void errmsg(EN_Project *p, int errcode) } } -void writecon(char *s) +void writecon(const char *s) /*---------------------------------------------------------------- ** Input: text string ** Output: none @@ -4234,8 +4178,7 @@ int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDeman Pdemand d; int n = 0; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check for valid arguments */ if (!p->Openflag) @@ -4252,8 +4195,7 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx Pdemand d; int n = 1; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; /* Check for valid arguments */ if (!p->Openflag) @@ -4276,8 +4218,7 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) { - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; EN_Network *net = &pr->network; Snode *Node = net->Node; @@ -4306,8 +4247,7 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int *pattIdx) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; Snode *Node = net->Node; @@ -4330,8 +4270,7 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4346,7 +4285,7 @@ int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_F return (205); // if (period < 1 || period > Pattern[index].Length) return(251); for (i = 0; i < Pattern[index].Length; i++) { - *value += Pattern[index].F[i]; + *value += (EN_API_FLOAT_TYPE)Pattern[index].F[i]; } *value /= (EN_API_FLOAT_TYPE)Pattern[index].Length; return (0); @@ -4356,8 +4295,7 @@ int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType toType) int i; EN_LinkType fromType; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4397,8 +4335,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) { int index; struct Sdemand *demand; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -4514,8 +4451,7 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch int i, n; int N1, N2; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -4627,8 +4563,7 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { int i; EN_LinkType linkType; - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; Slink *link; @@ -4688,8 +4623,7 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) { - EN_Project* p; - p = (EN_Project*)ph; + EN_Project* p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4773,8 +4707,7 @@ int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nT Premise *p; Action *c; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; EN_Network *net = &pr->network; @@ -4838,7 +4771,7 @@ int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int idxPremise, *variable = p->variable; *relop = p->relop; *status = p->status; - *value = p[0].value; + *value = (EN_API_FLOAT_TYPE)p[0].value; return (0); } @@ -4851,8 +4784,7 @@ int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TY **---------------------------------------------------------------- */ { - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (index > pr->network.Nrules) { return (257); @@ -4899,8 +4831,7 @@ int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPr EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) return (257); @@ -4922,8 +4853,7 @@ int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexP EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -4947,8 +4877,7 @@ int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPr EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) return (257); @@ -4971,8 +4900,7 @@ int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexActi EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (252); @@ -4988,7 +4916,7 @@ int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexActi } *indexLink = a->link; *status = a->status; - *setting = a->setting; + *setting = (EN_API_FLOAT_TYPE)a->setting; return (0); } @@ -4998,8 +4926,7 @@ int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexActi EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -5025,8 +4952,7 @@ int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -5042,7 +4968,7 @@ int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct } *indexLink = a->link; *status = a->status; - *setting = a->setting; + *setting = (EN_API_FLOAT_TYPE)a->setting; return (0); } @@ -5052,8 +4978,7 @@ int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -5076,8 +5001,7 @@ int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char *id) { - EN_Project* pr; - pr = (EN_Project*)ph; + EN_Project* pr = (EN_Project*)ph; strcpy(id, ""); if (!pr->Openflag) diff --git a/src/funcs.h b/src/funcs.h index b006c78..c000515 100755 --- a/src/funcs.h +++ b/src/funcs.h @@ -36,10 +36,10 @@ int allocdata(EN_Project *p); /* Allocates memory void freeTmplist(STmplist *); /* Frees items in linked list */ void freeFloatlist(SFloatlist *); /* Frees list of floats */ void freedata(EN_Project *p); /* Frees allocated memory */ -int openfiles(EN_Project *p, char *,char *,char *); /* Opens input & report files */ +int openfiles(EN_Project *p, const char *, const char *, const char *); /* Opens input & report files */ int openhydfile(EN_Project *p); /* Opens hydraulics file */ int openoutfile(EN_Project *p); /* Opens binary output file */ -int strcomp(char *, char *); /* Compares two strings */ +int strcomp(const char *, const char *); /* Compares two strings */ char* getTmpName(EN_Project *p, char* fname); /* Gets temporary file name */ double interp(int, double *,double *, double); /* Interpolates a data curve */ @@ -50,7 +50,7 @@ int findvalve(EN_Network *n, int); /* Find valve index fro int findpump(EN_Network *n, int); /* Find pump index from node index */ // (AH) char *geterrmsg(int errcode, char *msg); /* Gets text of error message */ void errmsg(EN_Project *p, int); /* Reports program error */ -void writecon(char *); /* Writes text to console */ +void writecon(const char *); /* Writes text to console */ void writewin(void (*vp)(char *), char *); /* Passes text to calling app */ /* ------- INPUT1.C --------------------*/ @@ -121,6 +121,8 @@ int ruledata(EN_Project *pr); /* Processes rule input data int checkrules(EN_Project *pr, long); /* Checks all rules */ void freerules(EN_Project *pr); /* Frees rule base memory */ +int writeRuleinInp(EN_Project *pr, FILE *f, int RuleIdx); + /* ------------- REPORT.C --------------*/ int writereport(EN_Project *pr); /* Writes formatted report */ void writelogo(EN_Project *pr); /* Writes program logo */ diff --git a/src/rules.c b/src/rules.c index 39d6a6a..87b7a6a 100644 --- a/src/rules.c +++ b/src/rules.c @@ -114,7 +114,7 @@ int takeactions(EN_Project *pr); void clearactlist(rules_t *rules); void clearrules(EN_Project *pr); void ruleerrmsg(EN_Project *pr, int); -int writeRuleinInp(EN_Project *pr, FILE *f, int RuleIdx); +//int writeRuleinInp(EN_Project *pr, FILE *f, int RuleIdx); void initrules(rules_t *rules) /* From 38292ad849e3027d1f57a24da2ad9570d6b424ca Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 2 Feb 2018 08:16:17 -0500 Subject: [PATCH 06/45] Fixed bug that was causing hard crash --- src/epanet.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index d1afb37..9129281 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -154,11 +154,12 @@ execute function x and set the error code equal to its return value. int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) { int errcode = 0; - - EN_Project* _p = (EN_Project*)_defaultModel; + EN_Project* _p; ERRCODE(EN_alloc(&_defaultModel)); ERRCODE(EN_open(_defaultModel, f1, f2, f3)); + + _p = (EN_Project*)_defaultModel; _p->viewprog = pviewprog; if (_p->out_files.Hydflag != USE) { @@ -468,7 +469,7 @@ int DLLEXPORT EN_alloc(EN_ProjectHandle* ph) int DLLEXPORT EN_free(EN_ProjectHandle* ph) { - EN_Project* p = (EN_Project*)*ph; + EN_Project* p = (EN_Project*)ph; free(p); From ddd08e3d5f9beb4388f44fee2bee0857ae7edd1d Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 2 Feb 2018 10:52:32 -0500 Subject: [PATCH 07/45] Conforming to pointer declaration style. --- include/epanet2.h | 8 +- src/epanet.c | 194 +++++++++++++++++++++++----------------------- src/vars.h | 2 +- 3 files changed, 102 insertions(+), 102 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index 617d71f..d5f0aab 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -266,7 +266,7 @@ extern "C" { /** @brief The EPANET Project wrapper object */ - typedef void* EN_ProjectHandle; + typedef void *EN_ProjectHandle; // typedef struct EN_Project EN_Project; typedef struct EN_Pattern EN_Pattern; typedef struct EN_Curve EN_Curve; @@ -1125,10 +1125,10 @@ extern "C" { Threadsafe versions of all epanet functions ***************************************************/ - int DLLEXPORT EN_alloc(EN_ProjectHandle* ph); - int DLLEXPORT EN_free(EN_ProjectHandle* ph); + int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); + int DLLEXPORT EN_free(EN_ProjectHandle *ph); - int DLLEXPORT EN_init(EN_ProjectHandle* ph, char *rptFile, char *binOutFile, + int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *rptFile, char *binOutFile, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, diff --git a/src/epanet.c b/src/epanet.c index 9129281..5b1d7db 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -154,7 +154,7 @@ execute function x and set the error code equal to its return value. int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) { int errcode = 0; - EN_Project* _p; + EN_Project *_p; ERRCODE(EN_alloc(&_defaultModel)); ERRCODE(EN_open(_defaultModel, f1, f2, f3)); @@ -169,7 +169,7 @@ int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) ERRCODE(EN_solveQ(_defaultModel)); ERRCODE(EN_report(_defaultModel)); EN_close(_defaultModel); - EN_free(_defaultModel); + EN_free(&_defaultModel); return (errcode); } @@ -459,7 +459,7 @@ int DLLEXPORT ENdeletenode(int index) { */ /// allocate a project pointer -int DLLEXPORT EN_alloc(EN_ProjectHandle* ph) +int DLLEXPORT EN_alloc(EN_ProjectHandle *ph) { EN_Project *project = calloc(1, sizeof(EN_Project)); *ph = project; @@ -467,9 +467,9 @@ int DLLEXPORT EN_alloc(EN_ProjectHandle* ph) return 0; } -int DLLEXPORT EN_free(EN_ProjectHandle* ph) +int DLLEXPORT EN_free(EN_ProjectHandle *ph) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)(*ph); free(p); @@ -478,7 +478,7 @@ int DLLEXPORT EN_free(EN_ProjectHandle* ph) return 0; } -int DLLEXPORT EN_init(EN_ProjectHandle* ph, char *f2, char *f3, +int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula) /*---------------------------------------------------------------- ** Input: @@ -500,7 +500,7 @@ int DLLEXPORT EN_init(EN_ProjectHandle* ph, char *f2, char *f3, _fpreset(); #endif - EN_Project* pr = (EN_Project*)*ph; + EN_Project *pr = (EN_Project*)*ph; /* Set system flags */ @@ -559,7 +559,7 @@ int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const _fpreset(); #endif - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Set system flags */ p->Openflag = FALSE; @@ -624,7 +624,7 @@ int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) **---------------------------------------------------------------- */ { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -642,7 +642,7 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph) { out_file_t *out; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (p->Openflag) { writetime(p, FMT105); @@ -707,7 +707,7 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph) int errcode; long t, tstep; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Open hydraulics solver */ errcode = EN_openH(ph); @@ -765,7 +765,7 @@ int DLLEXPORT EN_saveH(EN_ProjectHandle ph) char tmpflag; int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check if hydraulic results exist */ if (!p->save_options.SaveHflag) @@ -799,7 +799,7 @@ int DLLEXPORT EN_openH(EN_ProjectHandle ph) { int errcode = 0; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check that input data exists */ p->hydraulics.OpenHflag = FALSE; @@ -838,7 +838,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) int errcode = 0; int sflag, fflag; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Reset status flags */ p->save_options.SaveHflag = FALSE; @@ -872,7 +872,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *t = 0; if (!p->hydraulics.OpenHflag) @@ -886,7 +886,7 @@ int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *tstep = 0; if (!p->hydraulics.OpenHflag) @@ -901,7 +901,7 @@ int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { int DLLEXPORT EN_closeH(EN_ProjectHandle ph) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) { return (102); @@ -918,7 +918,7 @@ int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { int c; FILE *HydFile; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check that hydraulics results exist */ if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) @@ -941,7 +941,7 @@ int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check that input data exists & hydraulics system closed */ if (!p->Openflag) @@ -974,7 +974,7 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { int errcode; long t, tstep; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Open WQ solver */ errcode = EN_openQ(ph); @@ -1026,7 +1026,7 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { int errcode = 0; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check that hydraulics results exist */ p->quality.OpenQflag = FALSE; @@ -1048,7 +1048,7 @@ int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { int errcode = 0; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->quality.OpenQflag) return (105); @@ -1066,7 +1066,7 @@ int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *t = 0; if (!p->quality.OpenQflag) @@ -1080,7 +1080,7 @@ int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *tstep = 0; if (!p->quality.OpenQflag) @@ -1097,7 +1097,7 @@ int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *tleft = 0; if (!p->quality.OpenQflag) @@ -1113,7 +1113,7 @@ int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1130,7 +1130,7 @@ int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1141,7 +1141,7 @@ int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { int DLLEXPORT EN_report(EN_ProjectHandle ph) { int errcode; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check if results saved to binary output file */ if (!p->save_options.SaveQflag) @@ -1155,7 +1155,7 @@ int DLLEXPORT EN_report(EN_ProjectHandle ph) { int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { int i; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1170,7 +1170,7 @@ int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { char s1[MAXLINE + 1]; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1211,7 +1211,7 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li EN_API_FLOAT_TYPE *level) { double s, lvl; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; EN_Network *net = &pr->network; @@ -1268,7 +1268,7 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; EN_Network *net = &pr->network; @@ -1306,7 +1306,7 @@ int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, EN_API_FLOAT_TYPE *value) { - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; hydraulics_t *hyd = &pr->hydraulics; quality_t *qu = &pr->quality; @@ -1343,7 +1343,7 @@ int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { int i; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; report_options_t *rep = &pr->report; quality_t *qu = &pr->quality; @@ -1408,7 +1408,7 @@ int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *code = -1; if (!p->Openflag) @@ -1421,7 +1421,7 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int i, j; double qfactor, vfactor, hfactor, efactor, xfactor, yfactor; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; double *Ucf = p->Ucf; EN_Network *net = &p->network; @@ -1497,7 +1497,7 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { int i; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -1514,7 +1514,7 @@ int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -1527,7 +1527,7 @@ int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1540,7 +1540,7 @@ int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE *value) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *value = 0.0; if (!p->Openflag) @@ -1556,7 +1556,7 @@ int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { int i; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -1573,7 +1573,7 @@ int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -1586,7 +1586,7 @@ int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1599,7 +1599,7 @@ int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *x = 0.0; *y = 0.0; @@ -1616,7 +1616,7 @@ int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *tracenode = 0; if (!p->Openflag) @@ -1629,7 +1629,7 @@ int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; ENgetqualtype(qualcode, tracenode); if (p->quality.Qualflag == TRACE) { @@ -1676,7 +1676,7 @@ int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE *value) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; switch (code) { case EN_ITERATIONS: @@ -1699,7 +1699,7 @@ int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE * int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -1713,7 +1713,7 @@ int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -1726,7 +1726,7 @@ int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *code = -1; if (!p->Openflag) @@ -1747,7 +1747,7 @@ int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1769,7 +1769,7 @@ int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (!p->Openflag) return (102); @@ -1790,7 +1790,7 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, Pdemand demand; Psource source; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -1989,7 +1989,7 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *index = 0; if (!p->Openflag) @@ -2003,7 +2003,7 @@ int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; strcpy(id, ""); if (!p->Openflag) @@ -2016,7 +2016,7 @@ int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *code = -1; if (!p->Openflag) @@ -2030,7 +2030,7 @@ int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; *node1 = 0; *node2 = 0; @@ -2048,7 +2048,7 @@ int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty co double a, h, q, v = 0.0; int returnValue = 0; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2264,7 +2264,7 @@ int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nV Scurve curve; EN_API_FLOAT_TYPE *pointX, *pointY; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check that input file opened */ if (!p->Openflag) @@ -2314,7 +2314,7 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind int Nlinks; double *Ucf; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check that input file opened */ if (!p->Openflag) @@ -2423,7 +2423,7 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F **---------------------------------------------------------------- */ { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2691,7 +2691,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, **---------------------------------------------------------------- */ { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -2827,7 +2827,7 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int i, j, n, err = 0; Spattern *tmpPat; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; parser_data_t *par = &p->parser; @@ -2903,7 +2903,7 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { int j; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; Spattern *Pattern = net->Pattern; @@ -2932,7 +2932,7 @@ int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -2953,7 +2953,7 @@ int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; parser_data_t *par = &p->parser; @@ -3043,7 +3043,7 @@ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; Scurve *Curve = net->Curve; @@ -3078,7 +3078,7 @@ int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -3100,7 +3100,7 @@ int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_F int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; report_options_t *rep = &p->report; quality_t *qu = &p->quality; @@ -3210,7 +3210,7 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) **---------------------------------------------------------------- */ { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -3268,7 +3268,7 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int errcode = 0; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; if (code >= 0 && code <= 2) p->report.Statflag = (char)code; @@ -3279,7 +3279,7 @@ int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; report_options_t *rep = &p->report; @@ -3346,7 +3346,7 @@ int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveindex) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; Slink *Link = net->Link; @@ -3363,7 +3363,7 @@ int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveind int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveindex) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -3404,7 +3404,7 @@ int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveinde int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4179,7 +4179,7 @@ int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDeman Pdemand d; int n = 0; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check for valid arguments */ if (!p->Openflag) @@ -4196,7 +4196,7 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx Pdemand d; int n = 1; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; /* Check for valid arguments */ if (!p->Openflag) @@ -4219,7 +4219,7 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) { - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; EN_Network *net = &pr->network; Snode *Node = net->Node; @@ -4248,7 +4248,7 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int *pattIdx) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; Snode *Node = net->Node; @@ -4271,7 +4271,7 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4296,7 +4296,7 @@ int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType toType) int i; EN_LinkType fromType; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4336,7 +4336,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) { int index; struct Sdemand *demand; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -4452,7 +4452,7 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch int i, n; int N1, N2; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; hydraulics_t *hyd = &p->hydraulics; @@ -4564,7 +4564,7 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { int i; EN_LinkType linkType; - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; Slink *link; @@ -4624,7 +4624,7 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) { - EN_Project* p = (EN_Project*)ph; + EN_Project *p = (EN_Project*)ph; EN_Network *net = &p->network; @@ -4708,7 +4708,7 @@ int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nT Premise *p; Action *c; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; EN_Network *net = &pr->network; @@ -4750,7 +4750,7 @@ int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int idxPremise, EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr; + EN_Project *pr; pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { @@ -4785,7 +4785,7 @@ int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TY **---------------------------------------------------------------- */ { - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (index > pr->network.Nrules) { return (257); @@ -4802,7 +4802,7 @@ int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr; + EN_Project *pr; pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { @@ -4832,7 +4832,7 @@ int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPr EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) return (257); @@ -4854,7 +4854,7 @@ int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexP EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -4878,7 +4878,7 @@ int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPr EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) return (257); @@ -4901,7 +4901,7 @@ int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexActi EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (252); @@ -4927,7 +4927,7 @@ int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexActi EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -4953,7 +4953,7 @@ int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -4979,7 +4979,7 @@ int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct EN_API_FLOAT_TYPE priority; Action *a; - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { return (257); @@ -5002,7 +5002,7 @@ int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char *id) { - EN_Project* pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; strcpy(id, ""); if (!pr->Openflag) diff --git a/src/vars.h b/src/vars.h index 88a940a..9c4c08f 100755 --- a/src/vars.h +++ b/src/vars.h @@ -11,6 +11,6 @@ // this single global variable is used only when the library is called in "legacy mode" // with the 2.1-style API. -EXTERN void* _defaultModel; +EXTERN void *_defaultModel; #endif From 508bfb1cd4f8eb68faf8f829836ba22887509255 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 14:17:12 -0500 Subject: [PATCH 08/45] Adding support for unit testing using boost unit test and ctest --- CMakeLists.txt | 1 + tests/CMakeLists.txt | 42 ++++++ tests/data/net1.out | Bin 0 -> 16832 bytes tests/test_output.cpp | 308 +++++++++++++++++++++++++++++++++++++++++ tests/test_toolkit.cpp | 68 +++++++++ 5 files changed, 419 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/data/net1.out create mode 100644 tests/test_output.cpp create mode 100644 tests/test_toolkit.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c64c03..214f94a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ cmake_minimum_required (VERSION 2.8.8) project(EPANET) +add_subdirectory(tests) SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..52feb09 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# +# CMakeLists.txt - CMake configuration file for epanet/tests +# +# Created: February 13, 2018 +# Author: Constantin Savtchenko +# Ref: http://neyasystems.com/an-engineers-guide-to-unit-testing-cmake-and-boost-unit-tests/ +# +# Modified by: Michael E. Tryby +# US EPA ORD/NRMRL +# + +#Setup CMake to run tests +enable_testing() + +#Prep ourselves for compiling boost +find_package(Boost COMPONENTS unit_test_framework REQUIRED) +include_directories (${Boost_INCLUDE_DIRS} ../include ../tools/epanet-output/src) + +#I like to keep test files in a separate source directory called test +file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} test_*.cpp) + +#Run through each source +foreach(testSrc ${TEST_SRCS}) + #Extract the filename without an extension (NAME_WE) + get_filename_component(testName ${testSrc} NAME_WE) + + #Add compile target + add_executable(${testName} ${testSrc}) + + #link to Boost libraries AND your targets and dependencies + target_link_libraries(${testName} ${Boost_LIBRARIES} epanet epanet-output) + + #I like to move testing binaries into a testBin directory + set_target_properties(${testName} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + + #Finally add it to test execution - + #Notice the WORKING_DIRECTORY and COMMAND + add_test(NAME ${testName} + COMMAND ${CMAKE_BINARY_DIR}/bin/${testName} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data) +endforeach(testSrc) diff --git a/tests/data/net1.out b/tests/data/net1.out new file mode 100644 index 0000000000000000000000000000000000000000..6cede26b23767e4bd91a30d2ccaba14f34904ba3 GIT binary patch literal 16832 zcmeI4cT^Nf_xA?`K~PB|f`K5CgCJ3;x=nQvL_q~JCKSx1nE^#nQBhGbqM~BXIiM(l z5fF2BRS-pyj0i{&N&b3f*j@K|c6I%|=k>gQynW6+MORmMeY^TIx9;4oVYEj^FEei* zPm#ytNpseTGbzqQ+kcjlS{_fiGmjTNREp<1#Kqfnn2zfl|De!WfjZuS!r3AGnL1WF zzc>8J(nUuwU3{g$wkw8A(FqC(2%I%Nc&g6iX|qE3(}M$b0s<%dM_TBR5aBePN#V0* z>i7o-{C$tJ{b$Y6;RpIp7ETWd7U=l%19hecPo5PX5Ex+b_h)=xu%)GozlDE*MPR7E z#ng}p%MgBmB|E^|a=0LnFR%>qpB`*E$b5)pkdPlaDbg}HP^c3W84xl#JSZ?&D6r&4 zOJ@i_WJcg*$qqMMzYm?jlH0Mem>wMZeF6Xf=>HQVz_y|IPhx_mS`PZBW1@PizTZ2_ z9k=?yaqAx(@Av)V)<3wu^$)IZ{e$cG`@!}5{owkJ-IZ;WS$%(mtgOEO0Ihy-gH}HPG_Q!}ns%JYa@L+RdCq>HgGBW*oc(@Gf&2US z_M&=GdpXWJaQ5vrM0KL;i0Vas{H%%k5cMU}A=#P2^0c%^0q{#z^W#b)tP3Wm2u_MfyR8QoE=7c%?fL~KR$icqJR@Ld467zzP;bKN%WQ6{Vx5wl zS-+EIE(;!ZWaZLliL}%4o4PXbyY-nAMh;dLyMrn@g$HU@V4H!n;h1zYuG=o zs!xHQRi+{>ychl@ur9-%8D};Pr;e(`+A@bxyvhO0yOxBTbNevZgTd*u`=V6g05BY? z4^^WEW&HC!F#m9WqI!n;c@sUSpE1$c{ro1KE`^q^l0{utTcf#4jgZqB2h`x2QEjdn+NL!M1rIevzQ>%&~RnO1$AsPUP3w5BzJ?)MN-(|PM zC!hu8eCnFOr}AceF;8QufPUJ{W8;ddNMX_klF(F1j=ZZN8~ap|cin4A=RsxUnfY5W zPmW&0xiT6AT^|x5p{T1GL{3%v2euZ}_<>QVMAL5ipH?XKp!_nEmX`v@pZ=vx$ zq}hnmPHb*gCE52%mvH(rPpMV1oi70!Ur^;z8qtv*uOCcA?aPhT8HGD~OoFmJ6uMCu zt9ugf?^=$h><9xnnMSyR6ruhB#c?r#z^^tFkG=ZH0$AVFkKtv`z~1AFaRcul63*L; zdCW1K655-QS8~J37LI7&N)NEpG=Tk?-Wg-p4uw(c-eTohuW&~Eb9{@<$9m4U#rI{m z>oqPvk%zAyc!OcfLp+Jx7T?p)vn1m0XIK)ojRx6QO3Z?5w?R|;F+@Qgq}dp1R<1MO^LJ^s=C@jz#nKv0B*&GM-Y`GgsUf%_+ z>aB*%!p%@f|B)!w-xPT*`j#gf&L7#ZQoJgzZ&4Zg$G)iU+R4JqCF7*1k7^X16EvGn zY%iqRO9WIVS3vb61oXg20iC{>Pp5a5@MJF|q@zHJJrwwfB+yFo>Pa=Ze&!>2eW035 zSzkx4wksnBH}kl@cs!qlW5o9>73l{r77c{2zG>KhS{hyxe+hrSbrav$I)ts)ZxN6E z8TSz2w9xx;>*>=vGgkd&SJtmfD=~UwL^yq!kCxZ79xWSK&lkRArM({eVO^p~JGG@< zm^VYZGiiA?P<5pzOp8guDz0^SnT#Q%74sOw1;Zg#^#p#hJO(Ul{KY&izW)xg8}*sQ zH(A)wZyPpznu4mXpTfLHW_TaZoDr_b!ERUEVN$vnYDp}33>cDey)GCGqlUqVnoK;^ z`2vn#orNt5cVW?ez4D~6wfPRd^Yt1w7;+l-H8}K3c}o3a%(QeujKYm%fOVIl_x?2? zSW^M3KCFc;S)-Vdy1U^^!(M1+ioju!93y%*4xOdZl(X&8gbt=CJ=Ow+c-o^!o~}sq zT@Undjw;f5uZy&#+>jvC5JfxLeB+-cH(R20Mah*!xnib@T@ayaop&+;<4YCJ{>qM)OgG~x^lib zJ8el9_Jd3d*<))&IDHw@JnGn|4e_jD{ctk9lOAhXm`FtJQ#{p}Lmjl3!$G$2*}FS< zUcG<^4yna!d-aAChQ~ygj{taZ5>E+?f%QR?#5|o-%7b;0dfd3)!a)t2u+aYkN}7KX z^M>@nA(Kp*KzNN~EZbxMql+QwZY*5-Ff>CxI~YC|`NB;zIao8R4ByB>dI8XZS5YsdZ!}r?r!*{JY_#JX6_|9G5Kd@nDnwdP<$5!MhVy9Q1eGHdd_E< z!Od`^^C2)=YRwoKHHydJq=hs}d)*$bt204yRTk*sBzvSW%@vIp))O^vR7DRj>LT75 zSJZUJ5H*^8%aaf1k3`n7t&IC-zau+t-uuki6|2~qqfxX+_c^qqVmNhm71CLQg>;Fk zkY-j1D7%qQ-?aHBKZS7m&Rv>ad$pEW-1|gw1hwRzOBE@}s3GS2Ka)K!WhCvE#6O+h z;xFb&bBQ0g9v=W%(-W}U8h}Sq&Dgv&0sAN@KIPf4KYeE!2&?JA@-0~4G&QHff zu?);TbPh+k%QCSxYoW*O&-l=W1Tc44As)+D4_|}f!Y<6?XX+3W?||c%-b1B5?r`(n zIHWD_z@&RPgIkAa-2L?-C>)vr_m25wD5nKO=^{LlCuX~?F|*uLk$I#v84PW&LVaQdv`*(U=a2Se zUX;bbdiOER4ufj(7#u><=;3oY#9!J6@p5d@!pF8qsXL2?A2&rN*Hln_s}|as?u5q7 z)<+uJmf!fN@AK5@aDHaL-LdSG_fhnb-yC|`C!9vb3F-NbLMk&_NT=Eh>EmoZO&=!l zPhGgiY zt24l3t#8Jd- z|Af{VGfyiVnWS1f=3P}M#%4|w*eiX4`!4rj=sp2+H{Xb1vd=;A?nz8uJm&l|k9U5s zG&)i#hq}%0gLWC%A^X?1s6~%Ohd-JkwFfF_Nu?HAdC&>nj?_mhwEpBt6fa3)CY`o& z_aFP*cS*L_{`|~GONNoR1yNLH+#IUEC7hC_LR!EIX;5z=&1n(Ph^~D4Vz%V_T@UWK z`*CSjW`7-VO|B(Jht`p&npI?FYYkcX_%m6(x`fzWmVCbp3kekSbUxM(`mAt=v(@Ub z#2ujgwI+m29Eo)fDuZJ{f_UurB#i-13)OR6Of8C|SvGku*>BaERjP9*oWAtN-(=|9 zS#@m6_6$N>hO&{exkS`{qn9dES*O4#++PM=4Ub~=I2}4p$CBKbjuxxI&iFpQ)8{Fy zn=Qpe$NOezY!8NBvc53kxdq(y)&$1&Chn_}fuD_WhpzeFaMr~RR>Y;_9eze|H=M`y zBl_OOaL?{%?dRihn>ofzO0px98(_~oU8Bg{KDiD&Zz?mBzutk1iv$e&+K4ef^%8E| zPG*MXj~DY)&+#NzC67WJb!Yiki-#!=58i{VQcOzH?WU`OpR}pR0>**qi?0 zpMJ#C-Ff+$!y^ZiIa{3&4{XjUqu|Y_?3>DIweTCFXQAkhq=2Ok35}s1Iegd0)cQq!oTJtG638n`%OPc?R%h zUAS(r02?%^0X}<0%u|%X2;j8PiQN{{hZWJR9J81B>vv{pg*)N&rT>;CLzl(WvG_s; z8QL_I9p53Bh}y^XQ)QZ-C@^21E`zA!NAMHD1AMcu3iSNA6shDWFoy>vfnJd|Um>~DnkUI80_Sbs~-J_(KXIFeP zvbP08)oLH`nPdeUc3q&Fad|%zQEn_69&$Vd>AHceUw3#e%fP1*IuNUI3NH;+ho*kF z#60ymI}|uA^ltTX+B$C(>wWeOk&cmNdoH&noW6_;<62nHfGoE8^A>W;-;oV-zDz{z z>o=<~dCDqG^5jYI^nD5T`fweaKWhgy+m7N3b7hzSwRNCY^9A1*CIAFU=DW3nb70*h z6^3`JD+GPA#CHzfLGLO!9oO8@rWRW!X&MHNo{O>e?nB`DIs;PDhh^j^1jF!HA5gQk z0{&uE=svs|e@Jl za54>61Q;*}kBo;pt#D>xpT5jGbv34X(M+bPr%=q3@-%65K}8-}@cW?ZI6EZxWQ)dG zvgmS|8A9(=(7;z(C?LiOjf>JpE4%zT-~EWE`m1j(VxRy z-!GizH45q4Y$071DWG&+f!q=%{o`T~1V2!Ce+#aF&Pw`eVK^bE2^t7E&tf+>AdqKgSw9-68zE zH$*y z(yul`aX#~{Lj+ZGm0@SOeIc7m>dD!eUr3U2J(0HjLfZFgA%?T6$yujjv48q{d%Bn> zwAK$I3)~>8M;8dL!k~Fi1IE~1!I@6VaCTy+=#gQ8$@;&OBaJ&*xw|M2pe5dKU+kEXVPelTbGQDCWKGgkN_z zV0dmtIB`~I9QAe)Xe?RD<)B7pSVsgy(`g@=8D#-A8XBM_--v?_KE=~tyFqTeH*~GF z1&uRhcz}`-lm)ej@9F1bCx-do6gXI4$Q0FSh_nYlhUVRr+c z>6vcCnD&xoCf=CDbb2+G>x0K@O_WCFv*b|VITO@wa9^Zw#~#(CyP|6*+UVjZRm8W^ zMJv-O`tZgO*|qlj*F0Ug{W>$(;5{p6xqx1M7D?ZniJ)gqBIx9h2x`+Uf>tz!Q&r7y zI^c+eC$rNLbYY1MD@bi5FPAouxb{tC%C65OB&(5Foo^*~n?I2U4@$&5Dai(jdFrsy z4|?|S0Ix)4NIZd{&qP(Y)$JotdC_3VfV2m~LxJU}jS&Bd^zs(Rx@6 zT~x;~MGXVRJbg)(M)e!zklS7pwBdYT6!YF5sl9bY%hI$_a3?i%Tv-=&SVWOwp&@$o z>06$@|GuU7o>!UfM4!fAT|hk}=hDxHvuVR`5mec4Hl2_gL64e~h-Wg79X0qfIpIVT|++p~@ zPM~a!pj)^K=(J14inA4f$(H1jXFOwo(?T`k*HS6t_H6PgW47f)F*zsQopAax`#Kb| zJEja~+wYerC$1^5gIa_{)IKk(6XR&B$%GB+2vlGNQp{nzL;oGNR~ZJX$(1l*XIJR# zIswm1nFPWzD=|;gUOWW9S2~PFD zeVr^}Q0thCfzDjMV2uy7I+(zw;XPpH@elZd?Jewl%pK(Rdco!_D^TnA0`K7IgYv8L zU&>Q)i4n7ZizCxzgDFFHs57?*9fdS4HRfb$5tOeAW!j(X$xIB$1MOp@m@mj(%u_%L%93Yq&YDJe)rIBBZ9*CH_h4YXtQcRuYj77JMQ5lA4HM zdmY*2-blO`wUV%P+%2ZuKY@pYf} zP%6D&Jofoz&XAJimwL|PY=*~rXLdniT>6{TaI$!0p$n&vT8$gRX2jlR*Xx}j)kk@( z_R%%sJ{+E`ww-MQz_WG*zCt|K5nAJks}Ew+rDxzy;b_?5w*hJ{C_^>kVrjdo3N$Ww?*If@PEn1Hh3H1Rphb7w+?C4tyS z2CzI)6_gVS@%#~2u}Jsr6D(-xSVD8yQ@rDTFL?gA82gS{z@5i1KW99y{m3QK?{2fkndWTbN!^P$n;Z$m^kgk|6;i+$7IE~l&Ktwk5cpaI% zyMdVK)sX(DKNDKhMEdorCQqs*@zcYlQ;EJ{HYi1yLtLUg)GqA^c}Ch$uH7B@*#|Ib zl7d~SiDI4#WE`RO$%xdAqt<5Z$?3{IXqcEje-kA(kr!MzeYEDZ0c+QP4@;6)6R$V- z$rLt#)6e7GJigNQc6~S4cD*N5vNQ3(jLx_SEyemWYanQ-1z4EPfYi8RyxPhLax?q< z!IMTQ#Yq#k;l$%^Nc++P=i%z_5wBY@7GAuF?T$-<-D`iGz3d%+w@y=hPEzd@sLL^d zK&%HRb9lfkc#C81oWmmBM^sJ0XudJ*Z=ZuBjMYHJvJP*!IPaJ7bk3#}kNqme*bgvZ zl2_e_XEpP|+_(}v6TU!pfDP06PERHTe}%rm&dh>Co=h7}yzAHcASv$M9osShef;W! z6sty}BWfxry}=Z|fA@w0bn(QN_;a)-- zc|yRg!QqTsk8`M9IK8V{N<_9|C+CYc)R9SDsz}J*S`t;*KxQg`Byt4>;%DtJ!=G&T z;)4fKg48$t;MhzV*uP5w9we(l_f30nA+E%JRlCGI&F^Om+b;V2g{K97!;{N@@HAd7 z_AfjQ`Wv27{(&bu|7|#Gw;S5GYJqcLcaEp3A~8=598Z=xf90vkU=n=jqYGhMwP4YK zGCcWdHa>moFc#@nY^MUr2YW;K$>;dmc_|PqtH2KoB7YfA(tZV4HoXKAC^uKXIu64x z`oluUhfvbF0vb+p`QCPF%;!BHVIycW7o^Z%c)GB{0##KFKp8K5(1W^>D6Uai%u_AL zQ_8;o=84BU$35F~oNp4vGNMxCn^I+1_slbOK1`xRMQFCneS7tsBu1(c);sQCo} zbsa6B?yQ6-Z9O3!Jfnz+OlE5(sqIxmrgZ;En%93Kak=$m#fJ~%LEU>XPlvqyNE90c zCoU?&a-+U5WMB(ECM?AftCZkm@7=ie`D46m#!fL$B*F@uRJ>D5WJYFGyXTWVsYdBN zL)A#}wiTRz>O*IAXe7Qb!q|ef!^p)c+sJBbQ*j@MWtZAI@(b~_y&rHRzb~%Te~z+q z-Esf+!$IY;H0bZKgt#Lou&-w`9(bsM>r1kw8y2G~M_Zh&U+NqetnO?#U@7A5UXBgr z#$Y?AEjTb<1_%1bV4mAK@i{N}v%^RVv1clgSlh+oE2@5DUpus0tre^6!YTX(~aw_~95_N%bfqy#cuT4CU3CFa7C zLXb}Ez(}p**6Flu3+l{Jp0*wGPx3);6vv{yKK^L+I1O}&^GU9I4bZeASG0{dA*%xV zhkyFFJcSMxP?2p47touI0y>{t`_w~4K;=3MsP<_-)!in^KQ+t|&^qk`BC-?S6=dhL zD$?Eb8 zGe|P#*{l-tbn~7$jL;aETKtndJ=a`f>+rwe>9M(lCk^xsPjmjt)4K_O@^tmZC`g*G z0n#SQaEt#CEB3gDcZ^z%MY`D`&wYk5?d5-2D%plr?!96t|s^68izeA*$5PY+Fz z@bu&%_qT375m~H4Ir-G`k%W#YBeT*zlD&#GWa-UPBLC&B*mrpJ@ge35CxhirIdacfg9?!>Hk0WL zQ-_|!)@Eh+O59W~emaa_XL4&W+qNLRG3cG*F%+ma);YB#&S~7aCTE@w4`<)Ij~<^; z!immvQPR6FDACA7e2&@hVem>*4PGo$gcXTdIB3ibJh#sREYjWD?iEf+REJe|$vD7k zFK)Vd18=?>_RDy>H03$|=$r*=%UWUT>BS%yW(&Q7&7;vSZe zSepux8dFVnFeOBvFIle=tudJ7XN-pm-p0>qD+vc_L)ZrVROn<;roW-9!B@I~Zq`h6j)152{PpKYr zQF`&8JnbkO4E=mMK|r+(RB2zqyM|oBQOhRdGxH5VZ|!|tZmtB+KOMpY0@vWN1!Ivo6{kzG zjXf;k$(`eAqtXm?f`p(LjwiX55}qa*`k;cBf92`l%y%8R_$fUzjEbzNER1$L6-FOK zh0&m8VRY1zFdEt?jPjKvJb8W$qc3j0AtH;bFDCP&%1Qa0A`(+sM%4RP5*5!vGSW9! z?4MFP3?jF6$3S6gAvW%y2bZ_q#V@{Y!WS$naGCo&Y;toN?k7D=%+oW{8{U4Qf6RBg zzlonXeg7Cg#d|NXwQrm6zI+ouIsD7`=`Zsg7e84l{24!eJKt?c7zodI$iw&xU-9$9 z=W${11>EVjCpPQc8`7lHagM73Xr*t*LdE%b`iLXAP&w$A@iaXCJ`PaY4=Upx!inde zpdQqT`>yK@!b53rVc%Y`Qg{wu>sP_LifHhx$oqq*MQ!oZpl{~8wOssU5bz)T^XKOhky#%vB)zRm z$tH^eVsW5^T&?^-(!S=C7Wo`8PqN|eWbBsVuxt4{eDYQ=NbYnK^U^lrtivT(aZ?Z; zFqOfcH$BBXjW5uKgJCYIg>CWEu7BX^{eQ&crdK0vZQFQi_y?X=eJ39OohP@!f5ziU zj$81!buw7QQ;fSL9$)R}4)){aV8iEDY_sSTR#iQNXY#DDNOxrICA{&q0>~?G#)F)K z@Q}9$vBkX^zl^8rgKpyr6wG(t1h@3l@Zd-}v|GLvX4Wl( z+dTR`IqX$LLLR;)(c=oqiruAT z&fPaeW7ltDo<_eVq^sdjFk@fiyhYtX;bS_U_i_Uc3#`C0a{icCZ-wV)yNG#8PUr!X z@1xZ9ZTY8rT>eRvFRDFa!299EX56 zrJyiiBiO_)2IHLiKX~eYMUsDV zEIyJR;?}0@9vw=PZ9{3MT^OzL3Z->6p>)HvP+C+i;i-6NDAj-Qh1jntAsd$GlOYp} zh~Bb7GWuK*sZS~+{%QGSY4}SqPZ!@XTp11f+F3!c=2uKp?%^8)58{FucW`y)R9yJU z2FuMg67#f;(F9HleUi72nm;{88c)w;ADb1B%e5wi)0f%BzLH%yB!RrPzRZlDTSr($ zb*}y+y{4+g?0aLu+&Og?AB~KFh;s*Uj8_AmqI(b&j2mG{mLFD&*Fx2+J)ryCmt0>w zUSHuSn7q)7aXXcb+$Q#g^w|l>`@vbv6KcWC9laUvWu4GCp^8(WZ4Zc>vkIRceT8!jCThD+S~>YJrWFxas(gBth2?Tr>#_R%J=eNijsDQc(` zTJ9%<{LdoPJh3;r$Mi=VDk;i7-wE03sG$Y9u4tp&3grCU0=@d;@kcx^`K{gWzqb>W zfBpU4?d2ab*DJYEp2b{x+%25WA0I|_)WYbsn_={^E;k2qbKlprP%0cGneWm@bMaGU z6B%E{{VqzWh&-QAN|K|BNydg!;<&7Wtj~Q3GsH zEvP)c6dQbu#*=ahKEA1^cI61YqqMO*rYxQDi8^y$|MMY{Lb{%&{DM9Fx}@$-nf3 zxP7|7OYz8vnAQ)O~;pR@4`yTQdo3f-Yd-@@p=o+%vy)lhM&TQbARpn z@s-a_7~XR&W?}VRP*=!;!&m&_eLV)fs8{gZfimw0CqmQ(b38=w3`(4ziO1m1d?~ck zK^ASeV~uih4N>w82jpJriVCKwA=C4!XvqR|w0**8w8_yFbt{wnUdp0kgPX(4gYI%Q VZ{1BMO!v?feK@&oH21$7{s%(sdMW?_ literal 0 HcmV?d00001 diff --git a/tests/test_output.cpp b/tests/test_output.cpp new file mode 100644 index 0000000..dc48616 --- /dev/null +++ b/tests/test_output.cpp @@ -0,0 +1,308 @@ +/* + * test_epanet_output.cpp + * + * Created: 8/4/2017 + * Author: Michael E. Tryby + * US EPA - ORD/NRMRL + * + * Unit testing for EPANET Output API. +*/ + +#define BOOST_TEST_DYN_LINK + +#define BOOST_TEST_MODULE "output" +#include +#include + +#include +#include +#include +#include + +#include "epanet_output.h" + +//#define PROJECT_HOME "C:/Users/mtryby/Workspace/GitRepo/michaeltryby/epanet/" +#define DATA_PATH "./net1.out" + +using namespace std; + +// Custom test to check the minimum number of correct decimal digits between +// the test and the ref vectors. +boost::test_tools::predicate_result check_cdd(std::vector& test, + std::vector& ref, long cdd_tol) +{ + float tmp, min_cdd = 100.0; + + // TODO: What is the vectors aren't the same length? + + std::vector::iterator test_it; + std::vector::iterator ref_it; + + for (test_it = test.begin(); test_it < test.end(); ++test_it) { + for (ref_it = ref.begin(); ref_it < ref.end(); ++ref_it) { + + if (*test_it != *ref_it) { + tmp = - log10f(abs(*test_it - *ref_it)); + if (tmp < min_cdd) min_cdd = tmp; + } + } + } + + if (min_cdd == 100.0) + return true; + else + return std::lround(min_cdd) <= cdd_tol; +} + + +BOOST_AUTO_TEST_SUITE (test_output_auto) + +BOOST_AUTO_TEST_CASE(InitTest) { + ENR_Handle p_handle = NULL; + + int error = ENR_init(&p_handle); + BOOST_REQUIRE(error == 0); + BOOST_CHECK(p_handle != NULL); +} + +BOOST_AUTO_TEST_CASE(OpenTest) { + std::string path = std::string(DATA_PATH); + ENR_Handle p_handle = NULL; + ENR_init(&p_handle); + + int error = ENR_open(p_handle, path.c_str()); + BOOST_REQUIRE(error == 0); + ENR_close(&p_handle); +} + +BOOST_AUTO_TEST_CASE(CloseTest) { + ENR_Handle p_handle = NULL; + int error = ENR_init(&p_handle); + + error = ENR_close(&p_handle); + BOOST_REQUIRE(error == -1); + BOOST_CHECK(p_handle != NULL); +} + +BOOST_AUTO_TEST_SUITE_END() + + +struct Fixture{ + Fixture() { + path = std::string(DATA_PATH); + + error = ENR_init(&p_handle); + ENR_clearError(p_handle); + error = ENR_open(p_handle, path.c_str()); + } + ~Fixture() { + ENR_free((void**)&array); + error = ENR_close(&p_handle); + } + + std::string path; + int error = 0; + ENR_Handle p_handle = NULL; + + float* array = NULL; + int array_dim = 0; + +}; + +BOOST_AUTO_TEST_SUITE(test_output_fixture) + +BOOST_FIXTURE_TEST_CASE(test_getNetSize, Fixture) +{ + int *i_array = NULL; + + error = ENR_getNetSize(p_handle, &i_array, &array_dim); + BOOST_REQUIRE(error == 0); + + // nodes, tanks, links, pumps, valves + std::vector test_vec; + test_vec.assign(i_array, i_array + array_dim); + std::vector ref_vec({11,2,13,1,0}); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + + ENR_free((void**)&i_array); +} + +BOOST_FIXTURE_TEST_CASE(test_getElementName, Fixture) { + char* name = new char[MAXID]; + int length, index = 1; + + error = ENR_getElementName(p_handle, ENR_node, index, &name, &length); + BOOST_REQUIRE(error == 0); + + BOOST_TEST("10" == name); + + delete(name); +} + +BOOST_FIXTURE_TEST_CASE(test_getNodeAttribute, Fixture) { + + error = ENR_getNodeAttribute(p_handle, 1, ENR_quality, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({ 1.0, + 0.44407997, + 0.43766347, + 0.42827705, + 0.41342604, + 0.42804748, + 0.44152543, + 0.40502965, + 0.38635802, + 1.0, + 0.96745253 }); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); +} + +BOOST_FIXTURE_TEST_CASE(test_getLinkAttribute, Fixture) { + + error = ENR_getLinkAttribute(p_handle, 1, ENR_flow, &array ,&array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({ 1848.5812, + 1220.4274, + 130.11162, + 187.6893, + 119.8884, + 40.464489, + -748.58112, + 478.15378, + 191.73459, + 30.111609, + 140.46449, + 59.535515, + 1848.5812}); + + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); +} + +BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) { + + error = ENR_getNodeResult(p_handle, 1, 2, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({0.041142918, + 150.0, + 987.98358, + 120.45029}); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); +} + +BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) { + + error = ENR_getLinkResult(p_handle, 24, 13, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({0.58586824, + 1892.2433, + 0.0, + -200.71875, + 1.0, + 3.0, + 1.0, + 0.0}); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); +} + +BOOST_FIXTURE_TEST_CASE(test_getNodeSeries, Fixture){ + + error = ENR_getNodeSeries(p_handle, 2, ENR_pressure, 0, 10, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({119.25731, + 120.45029, + 121.19854, + 122.00622, + 122.37414, + 122.8122, + 122.82034, + 122.90379, + 123.40434, + 123.81807}); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(check_cdd(test_vec, ref_vec, 3)); +} + +BOOST_FIXTURE_TEST_CASE(test_getLinkSeries, Fixture) { + + error = ENR_getLinkSeries(p_handle, 2, ENR_flow, 0, 10, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({1234.2072, + 1220.4274, + 1164.4, + 1154.8175, + 1100.0635, + 1094.759, + 1041.7854, + 1040.7617, + 1087.556, + 1082.5011}); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); +} + +BOOST_FIXTURE_TEST_CASE(test_getNetReacts, Fixture) { + + error = ENR_getNetReacts(p_handle, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({18806.59, + 85424.438, + 115174.05, + 238972.66}); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(check_cdd(test_vec, ref_vec, 2)); +} + +BOOST_FIXTURE_TEST_CASE(test_getEnergyUsage, Fixture) { + + int linkIdx; + + error = ENR_getEnergyUsage(p_handle, 1, &linkIdx, &array, &array_dim); + BOOST_REQUIRE(error == 0); + + std::vector ref_vec({57.712959, + 75.0, + 880.41583, + 96.254318, + 96.707115, + 0.0}); + + std::vector test_vec; + test_vec.assign(array, array + array_dim); + + BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp new file mode 100644 index 0000000..e64ffe1 --- /dev/null +++ b/tests/test_toolkit.cpp @@ -0,0 +1,68 @@ +// +// test_epanet_toolkit.cpp +// +// Date Created: January 24, 2018 +// +// Author: Michael E. Tryby +// US EPA - ORD/NRMRL +// + +#define BOOST_TEST_DYN_LINK + +#define BOOST_TEST_MODULE "toolkit" +#include + +#include +#include "epanet2.h" + +// NOTE: Project Home needs to be updated to run unit test +#define PROJECT_HOME "C:/Users/mtryby/Workspace/GitRepo/michaeltryby/epanet" +#define DATA_PATH "/tests/network_tests/net1" + +using namespace std; + +BOOST_AUTO_TEST_SUITE (test_toolkit) + +BOOST_AUTO_TEST_CASE (test_alloc_free) +{ + int error = 0; + EN_ProjectHandle ph = NULL; + + error = EN_alloc(&ph); + + BOOST_REQUIRE(error == 0); + BOOST_CHECK(ph != NULL); + + error = EN_free(&ph); + + BOOST_REQUIRE(error == 0); + BOOST_CHECK(ph == NULL); +} + +BOOST_AUTO_TEST_SUITE_END( ) + +// int main(int argc, char *argv[]) +// { +// int error = 0; +// EN_ProjectHandle project = NULL; + +// std::string data_path = std::string(PROJECT_HOME) + std::string(DATA_PATH); +// std::string inputFile(data_path); +// inputFile.append(std::string("/net1.inp")); +// std::string reportFile(data_path); +// reportFile.append(std::string("/net1.rpt")); +// std::string outputFile(data_path); +// outputFile.append(std::string("/net1.out")); + +// error = EN_alloc(&project); +// error = EN_open(project, inputFile.c_str(), reportFile.c_str(), outputFile.c_str()); + +// error = EN_solveH(project); +// error = EN_solveQ(project); +// error = EN_report(project); + +// error = EN_close(project); +// error = EN_free(&project); + +// return error; +// } From 9d2d131ce53b9a430c74c3016fd5c5492d49df64 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 14:35:53 -0500 Subject: [PATCH 09/45] Adding libboost-test to Travis config. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 69f29f6..93b33c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: before_install: - sudo apt-get -qq update + - sudo apt-get install -y libboost-test - sudo apt-get install -y swig install: From 89f17d61c3601ec633b83a383e629273e86c4f95 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 14:41:33 -0500 Subject: [PATCH 10/45] Adding libboost-test to Travis config. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 93b33c2..5c0476f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ env: before_install: - sudo apt-get -qq update - - sudo apt-get install -y libboost-test + - sudo apt-get install -y libboost-test-dev - sudo apt-get install -y swig install: From 887572208244e8ecd9feb03d714a1fcea10f6564 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 15:13:07 -0500 Subject: [PATCH 11/45] Changing cmake to no longer glob output library files. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 214f94a..be07e6b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,8 @@ include_directories(include src tools/epanet-output/src) file(GLOB EPANET_SOURCES src/*.c) set(EPANET_API_HEADER include/epanet2.h) set(EPANET_CLI_SOURCES run/main.c) -file(GLOB EPANET_OUT_SOURCES tools/epanet-output/src/*.c) +set(EPANET_OUT_SOURCES tools/epanet-output/src/epanet_output.c + tools/epanet-output/src/errormanager.c) set(EPANET_OUT_HEADER tools/epanet-output/src/epanet_output.h) file(GLOB EPANET_LIB_ALL src/*.c) From 7c525318b509c5bc39c6c30a75086d4b3d068fcc Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 15:20:42 -0500 Subject: [PATCH 12/45] Adding flag to compile for c++11 --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index be07e6b..56c4f4b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,10 @@ IF (MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) ENDIF (MSVC) +if(UNIX) + set(CMAKE_CXX_FLAGS "-std=c++11") +endif(UNIX) + include_directories(include src tools/epanet-output/src) # configure file groups From 07fa9f4758bc49150effb278ec847015e73c9d9d Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 15:25:57 -0500 Subject: [PATCH 13/45] Adding flag to compile for c++11 --- CMakeLists.txt | 4 ---- tests/CMakeLists.txt | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c4f4b..be07e6b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,10 +57,6 @@ IF (MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) ENDIF (MSVC) -if(UNIX) - set(CMAKE_CXX_FLAGS "-std=c++11") -endif(UNIX) - include_directories(include src tools/epanet-output/src) # configure file groups diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 52feb09..4f976bd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,6 +12,10 @@ #Setup CMake to run tests enable_testing() +if(UNIX) + set(CMAKE_CXX_FLAGS "-std=c++11") +endif(UNIX) + #Prep ourselves for compiling boost find_package(Boost COMPONENTS unit_test_framework REQUIRED) include_directories (${Boost_INCLUDE_DIRS} ../include ../tools/epanet-output/src) From 6199052744c2dd5c7a83ca1f562505eb48626d42 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 15:43:50 -0500 Subject: [PATCH 14/45] Modifying per element comparison --- tests/test_output.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_output.cpp b/tests/test_output.cpp index dc48616..2f32172 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -12,7 +12,6 @@ #define BOOST_TEST_MODULE "output" #include -#include #include #include @@ -119,11 +118,11 @@ BOOST_FIXTURE_TEST_CASE(test_getNetSize, Fixture) BOOST_REQUIRE(error == 0); // nodes, tanks, links, pumps, valves - std::vector test_vec; - test_vec.assign(i_array, i_array + array_dim); - std::vector ref_vec({11,2,13,1,0}); + std::vector test; + test.assign(i_array, i_array + array_dim); + std::vector ref({11,2,13,1,0}); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK_EQUAL_COLLECTIONS(ref.begin(), ref.end(), test.begin(), test.end()); ENR_free((void**)&i_array); } From 2f90f401ef0bed7e998ed340ccc3600979a40baf Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 15:54:24 -0500 Subject: [PATCH 15/45] Modifying per element comparison --- tests/test_output.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_output.cpp b/tests/test_output.cpp index 2f32172..6b464f3 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -134,7 +134,7 @@ BOOST_FIXTURE_TEST_CASE(test_getElementName, Fixture) { error = ENR_getElementName(p_handle, ENR_node, index, &name, &length); BOOST_REQUIRE(error == 0); - BOOST_TEST("10" == name); + BOOST_CHECK("10" == name); delete(name); } @@ -159,7 +159,7 @@ BOOST_FIXTURE_TEST_CASE(test_getNodeAttribute, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_FIXTURE_TEST_CASE(test_getLinkAttribute, Fixture) { @@ -185,7 +185,7 @@ BOOST_FIXTURE_TEST_CASE(test_getLinkAttribute, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3))); } BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) { @@ -201,7 +201,7 @@ BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3))); } BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) { @@ -221,7 +221,7 @@ BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3))); } BOOST_FIXTURE_TEST_CASE(test_getNodeSeries, Fixture){ @@ -243,7 +243,7 @@ BOOST_FIXTURE_TEST_CASE(test_getNodeSeries, Fixture){ std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(check_cdd(test_vec, ref_vec, 3)); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_FIXTURE_TEST_CASE(test_getLinkSeries, Fixture) { @@ -265,7 +265,7 @@ BOOST_FIXTURE_TEST_CASE(test_getLinkSeries, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_FIXTURE_TEST_CASE(test_getNetReacts, Fixture) { @@ -301,7 +301,7 @@ BOOST_FIXTURE_TEST_CASE(test_getEnergyUsage, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(ref_vec == test_vec, boost::test_tools::per_element()); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_AUTO_TEST_SUITE_END() From fe8d81d382cb515bc079510e2d1fc7c73ed7b0e5 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 15:58:30 -0500 Subject: [PATCH 16/45] Fixing typo --- tests/test_output.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_output.cpp b/tests/test_output.cpp index 6b464f3..4888a94 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -185,7 +185,7 @@ BOOST_FIXTURE_TEST_CASE(test_getLinkAttribute, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_CHECK(check_cdd(test_vec, ref_vec, 3))); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) { @@ -201,7 +201,7 @@ BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_CHECK(check_cdd(test_vec, ref_vec, 3))); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) { @@ -221,7 +221,7 @@ BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_CHECK(check_cdd(test_vec, ref_vec, 3))); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 3)); } BOOST_FIXTURE_TEST_CASE(test_getNodeSeries, Fixture){ From b1e8694cbf31a28e38e246deb7936c60d120cad9 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 16:01:07 -0500 Subject: [PATCH 17/45] Fixing typo --- tests/test_output.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_output.cpp b/tests/test_output.cpp index 4888a94..4f3acae 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -281,7 +281,7 @@ BOOST_FIXTURE_TEST_CASE(test_getNetReacts, Fixture) { std::vector test_vec; test_vec.assign(array, array + array_dim); - BOOST_TEST(check_cdd(test_vec, ref_vec, 2)); + BOOST_CHECK(check_cdd(test_vec, ref_vec, 2)); } BOOST_FIXTURE_TEST_CASE(test_getEnergyUsage, Fixture) { From 100421f5094449c31b857b5cd1e594d08346ce7f Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 16:29:00 -0500 Subject: [PATCH 18/45] Adding custom comparison for strings --- tests/test_output.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_output.cpp b/tests/test_output.cpp index 4f3acae..d72c83c 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -53,6 +53,13 @@ boost::test_tools::predicate_result check_cdd(std::vector& test, return std::lround(min_cdd) <= cdd_tol; } +boost::test_tools::predicate_result check_string(std::string test, std::string ref) +{ + if (ref.compare(test) == 0) + return true; + else + return false; +} BOOST_AUTO_TEST_SUITE (test_output_auto) @@ -134,7 +141,9 @@ BOOST_FIXTURE_TEST_CASE(test_getElementName, Fixture) { error = ENR_getElementName(p_handle, ENR_node, index, &name, &length); BOOST_REQUIRE(error == 0); - BOOST_CHECK("10" == name); + std::string test (name); + std::string ref ("10"); + BOOST_CHECK(check_string(test, ref)); delete(name); } From 60db2a44351ed8e6c73fb7fbc904257d09c735e3 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 16:42:46 -0500 Subject: [PATCH 19/45] Updating Travis to run unit tests --- .travis.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c0476f..d6b516f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,9 @@ -language: python +language: c env: global: - EPANET_HOME=`pwd` - - BUILD_HOME=buildproducts + - BUILD_HOME=buildprod - TEST_HOME=tests/epanet-nrtestsuite before_install: @@ -20,7 +20,11 @@ before_script: - cmake .. script: - - make + - cmake --build . + # run unit tests + - cd /tests + - ctest + # run regression tests - cd $EPANET_HOME - tools/gen-config.sh $EPANET_HOME/$BUILD_HOME/bin > $TEST_HOME/apps/epanet-$TRAVIS_COMMIT.json - tools/run-nrtest.sh $TEST_HOME $TRAVIS_COMMIT From 65aafc06b777211fad4d4a7679547b79358fa0c4 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 16:47:11 -0500 Subject: [PATCH 20/45] Updating Travis to run unit tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d6b516f..2f47880 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -language: c +language: python env: global: From 18cec6e7fb356a1e86d585e17ce1631d220c51d3 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 16 Feb 2018 17:02:16 -0500 Subject: [PATCH 21/45] Fixing typo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f47880..354b37a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ before_script: script: - cmake --build . # run unit tests - - cd /tests + - cd tests - ctest # run regression tests - cd $EPANET_HOME From 323e041e6b17a12f817b3ea01affb54b015f08ae Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 3 Jul 2018 18:16:09 -0400 Subject: [PATCH 22/45] Fixing typo --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3be9d32..6e5d3f8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,6 @@ file(GLOB EPANET_SOURCES src/*.c) file(GLOB EPANET_LIB_ALL src/*) source_group("Library" FILES ${EPANET_LIB_ALL}) -source_group("CLI" REGULAR_EXPRESSION "run/.*") # the shared library From 245e2c50605efe0eb9aa17ebd5572a80d6d536fe Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 5 Jul 2018 18:35:41 -0400 Subject: [PATCH 23/45] Adding tests and a fixture --- include/epanet2.h | 3 +- src/epanet.c | 2 +- tests/data/net1.inp | 178 +++++++++++++++++++++++++++++++++++++++++ tests/test_toolkit.cpp | 66 ++++++++++++++- 4 files changed, 244 insertions(+), 5 deletions(-) create mode 100644 tests/data/net1.inp diff --git a/include/epanet2.h b/include/epanet2.h index 112b6f8..3f3e524 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -287,7 +287,8 @@ extern "C" { as it carries out its computations. If this feature is not needed then the argument should be NULL. */ - int DLLEXPORT ENepanet(char *inpFile, char *rptFile, char *binOutFile, void (*callback) (char *)); + int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile, + const char *binOutFile, void (*callback) (char *)); /** @brief Initializes an EPANET session diff --git a/src/epanet.c b/src/epanet.c index f4746bc..568b3c8 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -156,7 +156,7 @@ execute function x and set the error code equal to its return value. ** needed then the argument should be NULL. **------------------------------------------------------------------------- */ -int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog)(char *)) +int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *)) { int errcode = 0; EN_Project *_p; diff --git a/tests/data/net1.inp b/tests/data/net1.inp new file mode 100644 index 0000000..4df5bbf --- /dev/null +++ b/tests/data/net1.inp @@ -0,0 +1,178 @@ +[TITLE] + EPANET Example Network 1 +A simple example of modeling chlorine decay. Both bulk and +wall reactions are included. + +[JUNCTIONS] +;ID Elev Demand Pattern + 10 710 0 ; + 11 710 150 ; + 12 700 150 ; + 13 695 100 ; + 21 700 150 ; + 22 695 200 ; + 23 690 150 ; + 31 700 100 ; + 32 710 100 ; + +[RESERVOIRS] +;ID Head Pattern + 9 800 ; + +[TANKS] +;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve + 2 850 120 100 150 50.5 0 ; + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness MinorLoss Status + 10 10 11 10530 18 100 0 Open ; + 11 11 12 5280 14 100 0 Open ; + 12 12 13 5280 10 100 0 Open ; + 21 21 22 5280 10 100 0 Open ; + 22 22 23 5280 12 100 0 Open ; + 31 31 32 5280 6 100 0 Open ; + 110 2 12 200 18 100 0 Open ; + 111 11 21 5280 10 100 0 Open ; + 112 12 22 5280 12 100 0 Open ; + 113 13 23 5280 8 100 0 Open ; + 121 21 31 5280 8 100 0 Open ; + 122 22 32 5280 6 100 0 Open ; + +[PUMPS] +;ID Node1 Node2 Parameters + 9 9 10 HEAD 1 ; + +[VALVES] +;ID Node1 Node2 Diameter Type Setting MinorLoss + +[TAGS] + +[DEMANDS] +;Junction Demand Pattern Category + +[STATUS] +;ID Status/Setting + +[PATTERNS] +;ID Multipliers +;Demand Pattern + 1 1.0 1.2 1.4 1.6 1.4 1.2 + 1 1.0 0.8 0.6 0.4 0.6 0.8 + +[CURVES] +;ID X-Value Y-Value +;PUMP: Pump Curve for Pump 9 + 1 1500 250 + +[CONTROLS] + LINK 9 OPEN IF NODE 2 BELOW 110 + LINK 9 CLOSED IF NODE 2 ABOVE 140 + + +[RULES] + +[ENERGY] + Global Efficiency 75 + Global Price 0.0 + Demand Charge 0.0 + +[EMITTERS] +;Junction Coefficient + +[QUALITY] +;Node InitQual + 10 0.5 + 11 0.5 + 12 0.5 + 13 0.5 + 21 0.5 + 22 0.5 + 23 0.5 + 31 0.5 + 32 0.5 + 9 1.0 + 2 1.0 + +[SOURCES] +;Node Type Quality Pattern + +[REACTIONS] +;Type Pipe/Tank Coefficient + + +[REACTIONS] + Order Bulk 1 + Order Tank 1 + Order Wall 1 + Global Bulk -.5 + Global Wall -1 + Limiting Potential 0.0 + Roughness Correlation 0.0 + +[MIXING] +;Tank Model + +[TIMES] + Duration 24:00 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Pattern Timestep 2:00 + Pattern Start 0:00 + Report Timestep 1:00 + Report Start 0:00 + Start ClockTime 12 am + Statistic None + +[REPORT] + Status Yes + Summary No + Page 0 + +[OPTIONS] + Units GPM + Headloss H-W + Specific Gravity 1.0 + Viscosity 1.0 + Trials 40 + Accuracy 0.001 + CHECKFREQ 2 + MAXCHECK 10 + DAMPLIMIT 0 + Unbalanced Continue 10 + Pattern 1 + Demand Multiplier 1.0 + Emitter Exponent 0.5 + Quality Chlorine mg/L + Diffusivity 1.0 + Tolerance 0.01 + +[COORDINATES] +;Node X-Coord Y-Coord + 10 20.00 70.00 + 11 30.00 70.00 + 12 50.00 70.00 + 13 70.00 70.00 + 21 30.00 40.00 + 22 50.00 40.00 + 23 70.00 40.00 + 31 30.00 10.00 + 32 50.00 10.00 + 9 10.00 70.00 + 2 50.00 90.00 + +[VERTICES] +;Link X-Coord Y-Coord + +[LABELS] +;X-Coord Y-Coord Label & Anchor Node + 6.99 73.63 "Source" + 13.48 68.13 "Pump" + 43.85 91.21 "Tank" + +[BACKDROP] + DIMENSIONS 7.00 6.00 73.00 94.00 + UNITS None + FILE + OFFSET 0.00 0.00 + +[END] diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index abe33a3..4862d13 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -16,11 +16,13 @@ #include "epanet2.h" // NOTE: Project Home needs to be updated to run unit test -#define PROJECT_HOME "C:/Users/mtryby/Workspace/GitRepo/michaeltryby/epanet" -#define DATA_PATH "/tests/network_tests/net1" +#define DATA_PATH_INP "./net1.inp" +#define DATA_PATH_RPT "./test.rpt" +#define DATA_PATH_OUT "./test.out" using namespace std; + BOOST_AUTO_TEST_SUITE (test_toolkit) BOOST_AUTO_TEST_CASE (test_alloc_free) @@ -39,7 +41,65 @@ BOOST_AUTO_TEST_CASE (test_alloc_free) BOOST_CHECK(ph == NULL); } -BOOST_AUTO_TEST_SUITE_END( ) +BOOST_AUTO_TEST_CASE (test_open_close) +{ + EN_ProjectHandle ph = NULL; + EN_alloc(&ph); + + std::string path_inp = std::string(DATA_PATH_INP); + std::string path_rpt = std::string(DATA_PATH_RPT); + std::string path_out = std::string(DATA_PATH_OUT); + + int error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str()); + BOOST_REQUIRE(error == 0); + + error = EN_close(ph); + BOOST_REQUIRE(error == 0); + + EN_free(&ph); +} + +BOOST_AUTO_TEST_CASE(test_epanet) +{ + std::string path_inp = std::string(DATA_PATH_INP); + std::string path_rpt = std::string(DATA_PATH_RPT); + std::string path_out = std::string(DATA_PATH_OUT); + + int error = ENepanet(path_inp.c_str(), path_rpt.c_str(), path_out.c_str(), NULL); + BOOST_REQUIRE(error == 0); +} + +BOOST_AUTO_TEST_SUITE_END() + + +struct Fixture{ + Fixture() { + + path_inp = std::string(DATA_PATH_INP); + path_rpt = std::string(DATA_PATH_RPT); + path_out = std::string(DATA_PATH_OUT); + + EN_alloc(&ph); + error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str()); + + } + + ~Fixture() { + error = EN_close(&ph); + EN_free(&ph); + } + + std::string path_inp; + std::string path_rpt; + std::string path_out; + + int error; + EN_ProjectHandle ph; + +}; + + + // int main(int argc, char *argv[]) // { From efcf8735f0de8ed0e00d1218d697b1226f08920b Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 5 Jul 2018 18:45:13 -0400 Subject: [PATCH 24/45] Fixing indent --- tests/test_toolkit.cpp | 79 +++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index 4862d13..becf0a8 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -27,74 +27,73 @@ BOOST_AUTO_TEST_SUITE (test_toolkit) BOOST_AUTO_TEST_CASE (test_alloc_free) { - int error = 0; - EN_ProjectHandle ph = NULL; + int error = 0; + EN_ProjectHandle ph = NULL; - error = EN_alloc(&ph); + error = EN_alloc(&ph); - BOOST_REQUIRE(error == 0); - BOOST_CHECK(ph != NULL); + BOOST_REQUIRE(error == 0); + BOOST_CHECK(ph != NULL); - error = EN_free(&ph); + error = EN_free(&ph); - BOOST_REQUIRE(error == 0); - BOOST_CHECK(ph == NULL); + BOOST_REQUIRE(error == 0); + BOOST_CHECK(ph == NULL); } BOOST_AUTO_TEST_CASE (test_open_close) { - EN_ProjectHandle ph = NULL; - EN_alloc(&ph); + EN_ProjectHandle ph = NULL; + EN_alloc(&ph); - std::string path_inp = std::string(DATA_PATH_INP); - std::string path_rpt = std::string(DATA_PATH_RPT); - std::string path_out = std::string(DATA_PATH_OUT); + std::string path_inp = std::string(DATA_PATH_INP); + std::string path_rpt = std::string(DATA_PATH_RPT); + std::string path_out = std::string(DATA_PATH_OUT); - int error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str()); - BOOST_REQUIRE(error == 0); + int error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str()); + BOOST_REQUIRE(error == 0); - error = EN_close(ph); - BOOST_REQUIRE(error == 0); + error = EN_close(ph); + BOOST_REQUIRE(error == 0); - EN_free(&ph); + EN_free(&ph); } BOOST_AUTO_TEST_CASE(test_epanet) { - std::string path_inp = std::string(DATA_PATH_INP); - std::string path_rpt = std::string(DATA_PATH_RPT); - std::string path_out = std::string(DATA_PATH_OUT); + std::string path_inp = std::string(DATA_PATH_INP); + std::string path_rpt = std::string(DATA_PATH_RPT); + std::string path_out = std::string(DATA_PATH_OUT); - int error = ENepanet(path_inp.c_str(), path_rpt.c_str(), path_out.c_str(), NULL); - BOOST_REQUIRE(error == 0); + int error = ENepanet(path_inp.c_str(), path_rpt.c_str(), path_out.c_str(), NULL); + BOOST_REQUIRE(error == 0); } BOOST_AUTO_TEST_SUITE_END() struct Fixture{ - Fixture() { + Fixture() { + path_inp = std::string(DATA_PATH_INP); + path_rpt = std::string(DATA_PATH_RPT); + path_out = std::string(DATA_PATH_OUT); - path_inp = std::string(DATA_PATH_INP); - path_rpt = std::string(DATA_PATH_RPT); - path_out = std::string(DATA_PATH_OUT); + EN_alloc(&ph); + error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str()); - EN_alloc(&ph); - error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str()); + } - } + ~Fixture() { + error = EN_close(&ph); + EN_free(&ph); + } - ~Fixture() { - error = EN_close(&ph); - EN_free(&ph); - } + std::string path_inp; + std::string path_rpt; + std::string path_out; - std::string path_inp; - std::string path_rpt; - std::string path_out; - - int error; - EN_ProjectHandle ph; + int error; + EN_ProjectHandle ph; }; From 64f72abd786e7bc50d6a0949644f09aaa85c13c8 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 5 Jul 2018 19:36:50 -0400 Subject: [PATCH 25/45] Adding test for stepping through hydraulic simulation --- tests/test_toolkit.cpp | 53 +++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index becf0a8..4604eaa 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -84,7 +84,7 @@ struct Fixture{ } ~Fixture() { - error = EN_close(&ph); + error = EN_close(ph); EN_free(&ph); } @@ -97,31 +97,42 @@ struct Fixture{ }; +BOOST_AUTO_TEST_SUITE(test_epanet_fixture) +BOOST_FIXTURE_TEST_CASE(test_epanet, Fixture) +{ + error = EN_solveH(ph); + BOOST_REQUIRE(error == 0); + error = EN_solveQ(ph); + BOOST_REQUIRE(error == 0); -// int main(int argc, char *argv[]) -// { -// int error = 0; -// EN_ProjectHandle project = NULL; + error = EN_report(ph); + BOOST_REQUIRE(error == 0); +} -// std::string data_path = std::string(PROJECT_HOME) + std::string(DATA_PATH); -// std::string inputFile(data_path); -// inputFile.append(std::string("/net1.inp")); -// std::string reportFile(data_path); -// reportFile.append(std::string("/net1.rpt")); -// std::string outputFile(data_path); -// outputFile.append(std::string("/net1.out")); +BOOST_FIXTURE_TEST_CASE(test_hyd_step, Fixture) +{ + int flag = 00; + long t, tstep; -// error = EN_alloc(&project); -// error = EN_open(project, inputFile.c_str(), reportFile.c_str(), outputFile.c_str()); + error = EN_openH(ph); + BOOST_REQUIRE(error == 0); -// error = EN_solveH(project); -// error = EN_solveQ(project); -// error = EN_report(project); + error = EN_initH(ph, flag); + BOOST_REQUIRE(error == 0); -// error = EN_close(project); -// error = EN_free(&project); + for (int i = 0; i <= 24; i++) + { + error = EN_runH(ph, &t); + BOOST_REQUIRE(error == 0); -// return error; -// } + error = EN_nextH(ph, &tstep); + BOOST_REQUIRE(error == 0); + } + + error = EN_closeH(ph); + BOOST_REQUIRE(error == 0); +} + +BOOST_AUTO_TEST_SUITE_END() From 74fbcf7768fc006e4ae30e8c626088691eca8385 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 6 Jul 2018 09:31:58 -0400 Subject: [PATCH 26/45] Adding test for stepping through quality simulation --- tests/test_toolkit.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index 4604eaa..143e59e 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -135,4 +135,30 @@ BOOST_FIXTURE_TEST_CASE(test_hyd_step, Fixture) BOOST_REQUIRE(error == 0); } +BOOST_FIXTURE_TEST_CASE(test_qual_step, Fixture) +{ + int flag = 0; + long t, tstep; + + error = EN_solveH(ph); + BOOST_REQUIRE(error == 0); + + error = EN_openQ(ph); + BOOST_REQUIRE(error == 0); + + error = EN_initQ(ph, flag); + BOOST_REQUIRE(error == 0); + + do { + error = EN_runQ(ph, &t); + BOOST_REQUIRE(error == 0); + + error = EN_nextQ(ph, &tstep); + BOOST_REQUIRE(error == 0); + } while (tstep > 0); + + error = EN_closeQ(ph); + BOOST_REQUIRE(error == 0); +} + BOOST_AUTO_TEST_SUITE_END() From a93465e1ccaf16a9c333a2cf8ed1bf4d088fce43 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 6 Jul 2018 09:48:33 -0400 Subject: [PATCH 27/45] Adding test for simultaneous stepping through hyd and qual simulation --- tests/test_toolkit.cpp | 49 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index 143e59e..91be266 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -122,14 +122,14 @@ BOOST_FIXTURE_TEST_CASE(test_hyd_step, Fixture) error = EN_initH(ph, flag); BOOST_REQUIRE(error == 0); - for (int i = 0; i <= 24; i++) - { + do { error = EN_runH(ph, &t); BOOST_REQUIRE(error == 0); error = EN_nextH(ph, &tstep); BOOST_REQUIRE(error == 0); - } + + } while (tstep > 0); error = EN_closeH(ph); BOOST_REQUIRE(error == 0); @@ -155,10 +155,53 @@ BOOST_FIXTURE_TEST_CASE(test_qual_step, Fixture) error = EN_nextQ(ph, &tstep); BOOST_REQUIRE(error == 0); + } while (tstep > 0); error = EN_closeQ(ph); BOOST_REQUIRE(error == 0); } +BOOST_FIXTURE_TEST_CASE(test_hyd_qual_step, Fixture) +{ + int flag = EN_NOSAVE; + long t, tstep_h, tstep_q; + + error = EN_openH(ph); + BOOST_REQUIRE(error == 0); + + error = EN_initH(ph, flag); + BOOST_REQUIRE(error == 0); + + error = EN_openQ(ph); + BOOST_REQUIRE(error == 0); + + error = EN_initQ(ph, flag); + BOOST_REQUIRE(error == 0); + + do { + + + error = EN_runH(ph, &t); + BOOST_REQUIRE(error == 0); + + error = EN_runQ(ph, &t); + BOOST_REQUIRE(error == 0); + + error = EN_nextH(ph, &tstep_h); + BOOST_REQUIRE(error == 0); + + error = EN_nextQ(ph, &tstep_q); + BOOST_REQUIRE(error == 0); + + } while (tstep_h > 0); + + error = EN_closeH(ph); + BOOST_REQUIRE(error == 0); + + error = EN_closeQ(ph); + BOOST_REQUIRE(error == 0); + +} + BOOST_AUTO_TEST_SUITE_END() From c8803a9f1b5fe789dd99392d8ad795487cbfbd90 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 6 Jul 2018 17:42:27 -0400 Subject: [PATCH 28/45] Reorganizing epanet header --- include/epanet2.h | 1812 +++++++++++++++++++++------------------- tests/test_toolkit.cpp | 4 +- 2 files changed, 937 insertions(+), 879 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index 3f3e524..ef6f9d2 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -1,13 +1,13 @@ /** @file epanet2.h @see http://github.com/openwateranalytics/epanet - + */ /* ******************************************************************* - + EPANET2.H - Prototypes for EPANET Functions Exported to DLL Toolkit - + VERSION: 2.00 DATE: 5/8/00 10/25/00 @@ -16,7 +16,7 @@ 2/14/08 (2.00.12) AUTHORS: L. Rossman - US EPA - NRMRL OpenWaterAnalytics members: see git stats for contributors - + ******************************************************************* */ @@ -27,7 +27,7 @@ // the toolkit can be compiled with support for double-precision as well. // just make sure that you use the correct #define in your client code. #ifndef EN_API_FLOAT_TYPE - #define EN_API_FLOAT_TYPE float +#define EN_API_FLOAT_TYPE float #endif // // --- define WINDOWS @@ -66,197 +66,197 @@ /// Node property codes typedef enum { - EN_ELEVATION = 0, /**< Node Elevation */ - EN_BASEDEMAND = 1, /**< Node Base Demand, from last demand category */ - EN_PATTERN = 2, /**< Node Demand Pattern */ - EN_EMITTER = 3, /**< Node Emitter Coefficient */ - EN_INITQUAL = 4, /**< Node initial quality */ - EN_SOURCEQUAL = 5, /**< Node source quality */ - EN_SOURCEPAT = 6, /**< Node source pattern index */ - EN_SOURCETYPE = 7, /**< Node source type */ - EN_TANKLEVEL = 8, /**< Tank Level */ - EN_DEMAND = 9, /**< Node current simulated demand */ - EN_HEAD = 10, /**< Node Head value */ - EN_PRESSURE = 11, /**< Node pressure value */ - EN_QUALITY = 12, /**< Node quality value */ - EN_SOURCEMASS = 13, /**< Node source mass value */ - EN_INITVOLUME = 14, /**< Tank or Reservoir initial volume */ - EN_MIXMODEL = 15, /**< Tank mixing model */ - EN_MIXZONEVOL = 16, /**< Tank mixing zone volume */ - EN_TANKDIAM = 17, /**< Tank diameter */ - EN_MINVOLUME = 18, /**< Tank minimum volume */ - EN_VOLCURVE = 19, /**< Tank volume curve index */ - EN_MINLEVEL = 20, /**< Tank minimum level */ - EN_MAXLEVEL = 21, /**< Tank maximum level */ - EN_MIXFRACTION = 22, /**< Tank mixing fraction */ - EN_TANK_KBULK = 23, /**< Tank bulk decay coefficient */ - EN_TANKVOLUME = 24, /**< Tank current volume */ - EN_MAXVOLUME = 25 /**< Tank maximum volume */ + EN_ELEVATION = 0, /**< Node Elevation */ + EN_BASEDEMAND = 1, /**< Node Base Demand, from last demand category */ + EN_PATTERN = 2, /**< Node Demand Pattern */ + EN_EMITTER = 3, /**< Node Emitter Coefficient */ + EN_INITQUAL = 4, /**< Node initial quality */ + EN_SOURCEQUAL = 5, /**< Node source quality */ + EN_SOURCEPAT = 6, /**< Node source pattern index */ + EN_SOURCETYPE = 7, /**< Node source type */ + EN_TANKLEVEL = 8, /**< Tank Level */ + EN_DEMAND = 9, /**< Node current simulated demand */ + EN_HEAD = 10, /**< Node Head value */ + EN_PRESSURE = 11, /**< Node pressure value */ + EN_QUALITY = 12, /**< Node quality value */ + EN_SOURCEMASS = 13, /**< Node source mass value */ + EN_INITVOLUME = 14, /**< Tank or Reservoir initial volume */ + EN_MIXMODEL = 15, /**< Tank mixing model */ + EN_MIXZONEVOL = 16, /**< Tank mixing zone volume */ + EN_TANKDIAM = 17, /**< Tank diameter */ + EN_MINVOLUME = 18, /**< Tank minimum volume */ + EN_VOLCURVE = 19, /**< Tank volume curve index */ + EN_MINLEVEL = 20, /**< Tank minimum level */ + EN_MAXLEVEL = 21, /**< Tank maximum level */ + EN_MIXFRACTION = 22, /**< Tank mixing fraction */ + EN_TANK_KBULK = 23, /**< Tank bulk decay coefficient */ + EN_TANKVOLUME = 24, /**< Tank current volume */ + EN_MAXVOLUME = 25 /**< Tank maximum volume */ } EN_NodeProperty; /// Link property codes typedef enum { - EN_DIAMETER = 0, - EN_LENGTH = 1, - EN_ROUGHNESS = 2, - EN_MINORLOSS = 3, - EN_INITSTATUS = 4, - EN_INITSETTING = 5, - EN_KBULK = 6, - EN_KWALL = 7, - EN_FLOW = 8, - EN_VELOCITY = 9, - EN_HEADLOSS = 10, - EN_STATUS = 11, - EN_SETTING = 12, - EN_ENERGY = 13, - EN_LINKQUAL = 14, - EN_LINKPATTERN = 15, - EN_EFFICIENCY = 16, - EN_HEADCURVE = 17, - EN_EFFICIENCYCURVE = 18, - EN_PRICEPATTERN = 19 + EN_DIAMETER = 0, + EN_LENGTH = 1, + EN_ROUGHNESS = 2, + EN_MINORLOSS = 3, + EN_INITSTATUS = 4, + EN_INITSETTING = 5, + EN_KBULK = 6, + EN_KWALL = 7, + EN_FLOW = 8, + EN_VELOCITY = 9, + EN_HEADLOSS = 10, + EN_STATUS = 11, + EN_SETTING = 12, + EN_ENERGY = 13, + EN_LINKQUAL = 14, + EN_LINKPATTERN = 15, + EN_EFFICIENCY = 16, + EN_HEADCURVE = 17, + EN_EFFICIENCYCURVE = 18, + EN_PRICEPATTERN = 19 } EN_LinkProperty; /// Time parameter codes typedef enum { - EN_DURATION = 0, - EN_HYDSTEP = 1, - EN_QUALSTEP = 2, - EN_PATTERNSTEP = 3, - EN_PATTERNSTART = 4, - EN_REPORTSTEP = 5, - EN_REPORTSTART = 6, - EN_RULESTEP = 7, - EN_STATISTIC = 8, - EN_PERIODS = 9, - EN_STARTTIME = 10, - EN_HTIME = 11, - EN_QTIME = 12, - EN_HALTFLAG = 13, - EN_NEXTEVENT = 14, - EN_NEXTEVENTIDX = 15 + EN_DURATION = 0, + EN_HYDSTEP = 1, + EN_QUALSTEP = 2, + EN_PATTERNSTEP = 3, + EN_PATTERNSTART = 4, + EN_REPORTSTEP = 5, + EN_REPORTSTART = 6, + EN_RULESTEP = 7, + EN_STATISTIC = 8, + EN_PERIODS = 9, + EN_STARTTIME = 10, + EN_HTIME = 11, + EN_QTIME = 12, + EN_HALTFLAG = 13, + EN_NEXTEVENT = 14, + EN_NEXTEVENTIDX = 15 } EN_TimeProperty; typedef enum { - EN_ITERATIONS = 0, - EN_RELATIVEERROR = 1 + EN_ITERATIONS = 0, + EN_RELATIVEERROR = 1 } EN_AnalysisStatistic; typedef enum { - EN_NODECOUNT = 0, /**< Number of Nodes (Juntions + Tanks + Reservoirs) */ - EN_TANKCOUNT = 1, /**< Number of Tanks and Reservoirs */ - EN_LINKCOUNT = 2, /**< Number of Links (Pipes + Pumps + Valves) */ - EN_PATCOUNT = 3, /**< Number of Time Patterns */ - EN_CURVECOUNT = 4, /**< Number of Curves */ - EN_CONTROLCOUNT = 5, /**< Number of Control Statements */ - EN_RULECOUNT = 6 /**< Number of Rule-based Control Statements */ + EN_NODECOUNT = 0, /**< Number of Nodes (Juntions + Tanks + Reservoirs) */ + EN_TANKCOUNT = 1, /**< Number of Tanks and Reservoirs */ + EN_LINKCOUNT = 2, /**< Number of Links (Pipes + Pumps + Valves) */ + EN_PATCOUNT = 3, /**< Number of Time Patterns */ + EN_CURVECOUNT = 4, /**< Number of Curves */ + EN_CONTROLCOUNT = 5, /**< Number of Control Statements */ + EN_RULECOUNT = 6 /**< Number of Rule-based Control Statements */ } EN_CountType; typedef enum { - EN_JUNCTION = 0, - EN_RESERVOIR = 1, - EN_TANK = 2 + EN_JUNCTION = 0, + EN_RESERVOIR = 1, + EN_TANK = 2 } EN_NodeType; typedef enum { - EN_CVPIPE = 0, /* Link types. */ - EN_PIPE = 1, /* See LinkType in TYPES.H */ - EN_PUMP = 2, - EN_PRV = 3, - EN_PSV = 4, - EN_PBV = 5, - EN_FCV = 6, - EN_TCV = 7, - EN_GPV = 8 + EN_CVPIPE = 0, /* Link types. */ + EN_PIPE = 1, /* See LinkType in TYPES.H */ + EN_PUMP = 2, + EN_PRV = 3, + EN_PSV = 4, + EN_PBV = 5, + EN_FCV = 6, + EN_TCV = 7, + EN_GPV = 8 } EN_LinkType; typedef enum { - EN_NONE = 0, /* Quality analysis types. */ - EN_CHEM = 1, /* See QualType in TYPES.H */ - EN_AGE = 2, - EN_TRACE = 3 + EN_NONE = 0, /* Quality analysis types. */ + EN_CHEM = 1, /* See QualType in TYPES.H */ + EN_AGE = 2, + EN_TRACE = 3 } EN_QualityType; typedef enum { - EN_CONCEN = 0, /* Source quality types. */ - EN_MASS = 1, /* See SourceType in TYPES.H. */ - EN_SETPOINT = 2, - EN_FLOWPACED = 3 + EN_CONCEN = 0, /* Source quality types. */ + EN_MASS = 1, /* See SourceType in TYPES.H. */ + EN_SETPOINT = 2, + EN_FLOWPACED = 3 } EN_SourceType; typedef enum { /* Head loss formula: */ - EN_HW = 0, /* Hazen-Williams */ - EN_DW = 1, /* Darcy-Weisbach */ - EN_CM = 2 /* Chezy-Manning */ + EN_HW = 0, /* Hazen-Williams */ + EN_DW = 1, /* Darcy-Weisbach */ + EN_CM = 2 /* Chezy-Manning */ } EN_FormType; /* See FormType in TYPES.H */ typedef enum { - EN_CFS = 0, /* Flow units types. */ - EN_GPM = 1, /* See FlowUnitsType */ - EN_MGD = 2, /* in TYPES.H. */ - EN_IMGD = 3, - EN_AFD = 4, - EN_LPS = 5, - EN_LPM = 6, - EN_MLD = 7, - EN_CMH = 8, - EN_CMD = 9 + EN_CFS = 0, /* Flow units types. */ + EN_GPM = 1, /* See FlowUnitsType */ + EN_MGD = 2, /* in TYPES.H. */ + EN_IMGD = 3, + EN_AFD = 4, + EN_LPS = 5, + EN_LPM = 6, + EN_MLD = 7, + EN_CMH = 8, + EN_CMD = 9 } EN_FlowUnits; /// Simulation Option codes typedef enum { - EN_TRIALS = 0, - EN_ACCURACY = 1, - EN_TOLERANCE = 2, - EN_EMITEXPON = 3, - EN_DEMANDMULT = 4, - EN_HEADERROR = 5, - EN_FLOWCHANGE = 6 + EN_TRIALS = 0, + EN_ACCURACY = 1, + EN_TOLERANCE = 2, + EN_EMITEXPON = 3, + EN_DEMANDMULT = 4, + EN_HEADERROR = 5, + EN_FLOWCHANGE = 6 } EN_Option; typedef enum { - EN_LOWLEVEL = 0, /* Control types. */ - EN_HILEVEL = 1, /* See ControlType */ - EN_TIMER = 2, /* in TYPES.H. */ - EN_TIMEOFDAY = 3 + EN_LOWLEVEL = 0, /* Control types. */ + EN_HILEVEL = 1, /* See ControlType */ + EN_TIMER = 2, /* in TYPES.H. */ + EN_TIMEOFDAY = 3 } EN_ControlType; typedef enum { - EN_AVERAGE = 1, /* Time statistic types. */ - EN_MINIMUM = 2, /* See TstatType in TYPES.H */ - EN_MAXIMUM = 3, - EN_RANGE = 4 + EN_AVERAGE = 1, /* Time statistic types. */ + EN_MINIMUM = 2, /* See TstatType in TYPES.H */ + EN_MAXIMUM = 3, + EN_RANGE = 4 } EN_StatisticType; typedef enum { - EN_MIX1 = 0, /* Tank mixing models */ - EN_MIX2 = 1, - EN_FIFO = 2, - EN_LIFO = 3 + EN_MIX1 = 0, /* Tank mixing models */ + EN_MIX2 = 1, + EN_FIFO = 2, + EN_LIFO = 3 } EN_MixingModel; typedef enum { - EN_NOSAVE = 0, - EN_SAVE = 1, - EN_INITFLOW = 10, - EN_SAVE_AND_INIT = 11 + EN_NOSAVE = 0, + EN_SAVE = 1, + EN_INITFLOW = 10, + EN_SAVE_AND_INIT = 11 } EN_SaveOption; typedef enum { - EN_CONST_HP = 0, /* constant horsepower */ - EN_POWER_FUNC = 1, /* power function */ - EN_CUSTOM = 2 /* user-defined custom curve */ + EN_CONST_HP = 0, /* constant horsepower */ + EN_POWER_FUNC = 1, /* power function */ + EN_CUSTOM = 2 /* user-defined custom curve */ } EN_CurveType; @@ -265,217 +265,200 @@ typedef enum { #if defined(__cplusplus) extern "C" { #endif - - /** + +/** @brief The EPANET Project wrapper object - */ - typedef void *EN_ProjectHandle; -// typedef struct EN_Project EN_Project; - typedef struct EN_Pattern EN_Pattern; - typedef struct EN_Curve EN_Curve; - - /** + */ +typedef void *EN_ProjectHandle; + +typedef struct EN_Pattern EN_Pattern; +typedef struct EN_Curve EN_Curve; + + +//////////////////////////////////////////////////////////////////////////////// +//-------------------- CANONICAL API - ORGANIZED BY TASK ---------------------// +//////////////////////////////////////////////////////////////////////////////// + +// RUNNING A COMPLETE SIMULATION +/** @brief runs a complete EPANET simulation @param inpFile pointer to name of input file (must exist) @param rptFile pointer to name of report file (to be created) @param binOutFile pointer to name of binary output file (to be created) @param callback a callback function that takes a character string (char *) as its only parameter. @return error code - + The callback function should reside in and be used by the calling code to display the progress messages that EPANET generates as it carries out its computations. If this feature is not needed then the argument should be NULL. - */ - int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile, - const char *binOutFile, void (*callback) (char *)); - - /** - @brief Initializes an EPANET session - @param rptFile pointer to name of report file (to be created) - @param binOutFile pointer to name of binary output file (to be created) - @param UnitsType flow units flag - @param HeadlossFormula headloss formula flag - @return error code - */ - int DLLEXPORT ENinit(char *rptFile, char *binOutFile, int UnitsType, int HeadlossFormula); - - /** + */ +int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile, + const char *binOutFile, void (*callback) (char *)); + + +// OPENING A CLOSING THE EPANET TOOLKIT SYSTEM +/** @brief Opens EPANET input file & reads in network data @param inpFile pointer to name of input file (must exist) @param rptFile pointer to name of report file (to be created) @param binOutFile pointer to name of binary output file (to be created) @return error code - */ - int DLLEXPORT ENopen(char *inpFile, char *rptFile, char *binOutFile); - - /** - @brief Saves current data to "INP" formatted text file. - @param filename The file path to create - @return Error code - */ - int DLLEXPORT ENsaveinpfile(char *filename); - - /** + */ +int DLLEXPORT ENopen(char *inpFile, char *rptFile, char *binOutFile); +int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, + const char *rptFile, const char *binOutFile); + +/** @brief Frees all memory and files used by EPANET @return Error code - */ - int DLLEXPORT ENclose(); - - /** - @brief Solves the network hydraulics for all time periods + */ +int DLLEXPORT ENclose(); +int DLLEXPORT EN_close(EN_ProjectHandle ph); + + +// RETREIVING INFORMATION ABOUT NETWORK NODES +/** + @brief Get index of node with specified ID + @param id The string ID of the node + @param[out] index The node's index (first node is index 1) @return Error code - */ - int DLLEXPORT ENsolveH(); - - /** - @brief Saves hydraulic results to binary file + @see ENgetnodeid + */ +int DLLEXPORT ENgetnodeindex(char *id, int *index); +int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index); + +/** + @brief Get the string ID of the specified node. + @param index The index of the node (first node is index 1) + @param[out] id The string ID of the specified node. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. @return Error code - - Must be called before ENreport() if no WQ simulation has been made. - Should not be called if ENsolveQ() will be used. - */ - int DLLEXPORT ENsaveH(); - - /** - @brief Sets up data structures for hydraulic analysis + @see ENgetnodeindex + */ +int DLLEXPORT ENgetnodeid(int index, char *id); +int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id); + +/** + @brief Get the type of node with specified index. + @param index The index of a node (first node is index 1) + @param[out] code The type code for the node. @return Error code - */ - int DLLEXPORT ENopenH(); - - /** - @brief Initializes hydraulic analysis - @param initFlag 2-digit flag where 1st (left) digit indicates if link flows should be re-initialized (1) or not (0), and 2nd digit indicates if hydraulic results should be saved to file (1) or not (0). + */ +int DLLEXPORT ENgetnodetype(int index, int *code); +int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code); + +/** + @brief Get a property value for specified node + @param index The index of a node (first node is index 1). + @param code The property type code + @param[out] value The value of the node's property. @return Error code - */ - int DLLEXPORT ENinitH(int initFlag); - - /** - @brief Run a hydraulic solution period - @param[out] currentTime The current simulation time in seconds - @return Error or warning code - @see ENsolveH - - This function is used in a loop with ENnextH() to run - an extended period hydraulic simulation. - See ENsolveH() for an example. - */ - int DLLEXPORT ENrunH(long *currentTime); - - /** - @brief Determine time (in seconds) until next hydraulic event - @param[out] tStep Time (seconds) until next hydraulic event. 0 marks end of simulation period. + @see EN_NodeProperty + */ +int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value); +int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, + EN_API_FLOAT_TYPE *value); + + +// RETREIVING INFORMATION ABOUT NETWORK LINKS +/** + @brief Get the index of a Link with specified ID. + @param id The string ID of a link. + @param[out] index The index of the named link (first link is index 1) @return Error code - - This function is used in a loop with ENrunH() to run an extended period hydraulic simulation. - See ENsolveH() for an example. - */ - int DLLEXPORT ENnextH(long *tStep); - - - /** - @brief Frees data allocated by hydraulics solver + @see ENgetlinkid + */ +int DLLEXPORT ENgetlinkindex(char *id, int *index); +int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index); + +/** + @brief Get the string ID of a link with specified index + @param index The index of a link (first link is index 1) + @param[out] id The ID of the link. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. @return Error code - */ - int DLLEXPORT ENcloseH(); - - /** - @brief Copies binary hydraulics file to disk - @param filename Name of file to be created + @see ENgetlinkindex + */ +int DLLEXPORT ENgetlinkid(int index, char *id); +int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id); + +/** + @brief Get the link type code for a specified link + @param index The index of a link (first link is index 1) + @param[out] code The type code of the link. @return Error code - */ - int DLLEXPORT ENsavehydfile(char *filename); - - /** - @brief Opens previously saved binary hydraulics file - @param filename Name of file to be used + @see EN_LinkType + */ +int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code); +int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code); + +/** + @brief Get the indexes of a link's start- and end-nodes. + @param index The index of a link (first link is index 1) + @param[out] node1 The index of the link's start node (first node is index 1). + @param[out] node2 The index of the link's end node (first node is index 1). @return Error code - */ - int DLLEXPORT ENusehydfile(char *filename); - - /** - @brief Solves for network water quality in all time periods + @see ENgetnodeid, ENgetlinkid + */ +int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2); +int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2); + +/** + @brief Get a property value for specified link. + @param index The index of a node (first node is index 1). + @param code The parameter desired. + @param[out] value The value of the link's specified property. @return Error code - */ - int DLLEXPORT ENsolveQ(); - - /** - @brief Sets up data structures for WQ analysis + @see ENgetnodevalue, EN_LinkProperty + */ +int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value); +int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, + EN_LinkProperty code, EN_API_FLOAT_TYPE *value); + + +// RETREIVING INFORMATION ABOUT TIME PATTERNS +/** + @brief Retrieves ID of a time pattern with specific index. + @param index The index of a time pattern. + @param[out] id The string ID of the time pattern. @return Error code - */ - int DLLEXPORT ENopenQ(); - - /** - @brief Initializes water quality analysis - @param saveFlag EN_SAVE (1) if results saved to file, EN_NOSAVE (0) if not + @see ENgetpatternindex + */ +int DLLEXPORT ENgetpatternid(int index, char *id); +int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id); + +/** + @brief Retrieves the index of the time pattern with specified ID + @param id String ID of the time pattern + @param[out] index Index of the specified time pattern @return Error code - */ - int DLLEXPORT ENinitQ(int saveFlag); - - /** - @brief Retrieves hydraulic & WQ results at time t. - @param[out] currentTime Current simulation time, in seconds. + @see ENgetpatternid + */ +int DLLEXPORT ENgetpatternindex(char *id, int *index); +int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index); + +/** + @brief Retrieves the number of multipliers in a time pattern. + @param index The index of a time pattern. + @param[out] len The length of the time pattern. @return Error code - - This function is used in a loop with ENnextQ() to run - an extended period WQ simulation. See ENsolveQ() for - an example. - */ - int DLLEXPORT ENrunQ(long *currentTime); - - /** - @brief Advances WQ simulation to next hydraulic event. - @param[out] tStep Time in seconds until next hydraulic event. 0 marks end of simulation period. + */ +int DLLEXPORT ENgetpatternlen(int index, int *len); +int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len); + +/** + @brief Retrive a multiplier from a pattern for a specific time period. + @param index The index of a time pattern + @param period The pattern time period. First time period is 1. + @param[out] value Pattern multiplier @return Error code - - This function is used in a loop with ENrunQ() to run - an extended period WQ simulation. See ENsolveQ() for - an example. - */ - int DLLEXPORT ENnextQ(long *tStep); - - /** - @brief Advances WQ simulation by a single WQ time step - @param[out] timeLeft Time left in overall simulation (in seconds) - @return Error code - - This function is used in a loop with ENrunQ() to run - an extended period WQ simulation. - */ - int DLLEXPORT ENstepQ(long *timeLeft); - - /** - @brief Frees data allocated by water quality solver. - @return Error code. - */ - int DLLEXPORT ENcloseQ(); - - /** - @brief Writes line of text to the report file. - @param line Text string to write - @return Error code. - */ - int DLLEXPORT ENwriteline(char *line); - - /** - @brief Writes simulation report to the report file - @return Error code - */ - int DLLEXPORT ENreport(); - - /** - @brief Resets report options to default values - @return Error code - */ - int DLLEXPORT ENresetreport(); - - /** - @brief Processes a reporting format command - @return Error code - */ - int DLLEXPORT ENsetreport(char *reportFormat); - - /** + */ +int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value); +int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, + EN_API_FLOAT_TYPE *value); + + +// RETREIVING OTHER NETWORK INFORMATION +/** @brief Retrieves parameters that define a simple control @param controlIndex Control index (position of control statement in the input file, starting from 1) @param[out] controlType Control type code (see EPANET2.H) @@ -484,381 +467,114 @@ extern "C" { @param[out] nodeIndex Index of controlling node (0 for TIMER or TIMEOFDAY control) @param[out] level Control level (tank level, junction pressure, or time (seconds)) @return Error code - */ - int DLLEXPORT ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); - - /** + */ +int DLLEXPORT ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, + EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); +int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int controlIndex, int *controlType, + int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); + +/** @brief Retrieves the number of components of a given type in the network. @param code Component code (see EPANET2.H) @param[out] count Number of components in network @return Error code - */ - int DLLEXPORT ENgetcount(int code, int *count); - - /** - @brief Gets value for an analysis option - @param code Option code (see EPANET2.H) - @param[out] value Option value + */ +int DLLEXPORT ENgetcount(int code, int *count); +int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count); + +/** + @brief Retrieves the flow units code + @param[out] code Code of flow units in use @return Error code - */ - int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value); - - /** + */ +int DLLEXPORT ENgetflowunits(int *code); +int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code); + +/** @brief Retrieves value of specific time parameter. @param code Time parameter code @param[out] value Value of time parameter. @return Error code - */ - int DLLEXPORT ENgettimeparam(int code, long *value); - - /** - @brief Retrieves the flow units code - @param[out] code Code of flow units in use - @return Error code - */ - int DLLEXPORT ENgetflowunits(int *code); - - /** - @brief Sets the flow units - @param code Code of flow units to use - @return Error code - */ - int DLLEXPORT ENsetflowunits(int code); - - /** - @brief Retrieves the index of the time pattern with specified ID - @param id String ID of the time pattern - @param[out] index Index of the specified time pattern - @return Error code - @see ENgetpatternid - */ - int DLLEXPORT ENgetpatternindex(char *id, int *index); - - /** - @brief Retrieves ID of a time pattern with specific index. - @param index The index of a time pattern. - @param[out] id The string ID of the time pattern. - @return Error code - @see ENgetpatternindex - */ - int DLLEXPORT ENgetpatternid(int index, char *id); + */ +int DLLEXPORT ENgettimeparam(int code, long *value); +int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value); - /** - @brief Retrieves the number of multipliers in a time pattern. - @param index The index of a time pattern. - @param[out] len The length of the time pattern. +/** + @brief Gets value for an analysis option + @param code Option code (see EPANET2.H) + @param[out] value Option value @return Error code - */ - int DLLEXPORT ENgetpatternlen(int index, int *len); - - /** - @brief Retrive a multiplier from a pattern for a specific time period. - @param index The index of a time pattern - @param period The pattern time period. First time period is 1. - @param[out] value Pattern multiplier - @return Error code - */ - int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value); - - /** - @brief Retrieve the average multiplier value in a time pattern - @param index The index of a time pattern - @param[out] value The average of all of this time pattern's values - @return Error code - */ - int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); - - /** - @brief Retrieve the type of quality analytis to be run. - @param[out] qualcode The quality analysis code number. - @param[out] tracenode The index of node being traced, if qualcode == trace - @return Error code - @see ENsetqualtype - */ - int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode); - - /** - @brief Get the text of an error code. - @param errcode The error code - @param[out] errmsg The error string represented by the code - @param maxLen The maximum number of characters to copy into the char pointer errmsg - @return Error code - */ - int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen); - - /** - @brief Get hydraulic simulation statistic - @param code The type of statistic to get - @param[out] value The value of the statistic - @return Error code - */ - int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value); - - /** - @brief Get index of node with specified ID - @param id The string ID of the node - @param[out] index The node's index (first node is index 1) - @return Error code - @see ENgetnodeid - */ - int DLLEXPORT ENgetnodeindex(char *id, int *index); - - /** - @brief Get the string ID of the specified node. - @param index The index of the node (first node is index 1) - @param[out] id The string ID of the specified node. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. - @return Error code - @see ENgetnodeindex - */ - int DLLEXPORT ENgetnodeid(int index, char *id); - - /** - @brief Get the type of node with specified index. - @param index The index of a node (first node is index 1) - @param[out] code The type code for the node. - @return Error code - */ - int DLLEXPORT ENgetnodetype(int index, int *code); - - /** - @brief Get a property value for specified node - @param index The index of a node (first node is index 1). - @param code The property type code - @param[out] value The value of the node's property. - @return Error code - @see EN_NodeProperty - */ - int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value); - - /** - @brief Get coordinates (x,y) for a node. - @param index The index of a node (first node is index 1). - @param[out] x X-value of node's coordinate - @param[out] y Y-value of node's coordinate - @return Error code - @see ENsetcoord - */ - int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - - /** - @brief Set coordinates (x,y) for a node. - @param index The index of a node (first node is index 1) - @param x X-value of node's coordinate - @param y Y-value of node's coordinate - @return Error code - @see ENgetcoord - */ - int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - - /** - @brief Get the number of demand categories for a node. - @param nodeIndex The index of a node (first node is index 1) - @param[out] numDemands The number of demand categories - @return Error code - */ - int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands); - - /** - @brief Get a node's base demand for a specified category. - @param nodeIndex The index of a node (first node is index 1) - @param demandIndex The index of the demand category (starting at 1) - @return Error code - */ - int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); - - /** - @brief Get the index of the demand pattern assigned to a node for a category index. - @param nodeIndex The index of a node (first node is index 1). - @param demandIndex The index of a category (first category is index 1). - @param[out] pattIndex The index of the pattern for this node and category. - @return Error code - */ - int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIndex); - - /** - @brief Get the index of a Link with specified ID. - @param id The string ID of a link. - @param[out] index The index of the named link (first link is index 1) - @return Error code - @see ENgetlinkid - */ - int DLLEXPORT ENgetlinkindex(char *id, int *index); - - /** - @brief Get the string ID of a link with specified index - @param index The index of a link (first link is index 1) - @param[out] id The ID of the link. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. - @return Error code - @see ENgetlinkindex - */ - int DLLEXPORT ENgetlinkid(int index, char *id); - - /** - @brief Get the link type code for a specified link - @param index The index of a link (first link is index 1) - @param[out] code The type code of the link. - @return Error code - @see EN_LinkType - */ - int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code); + */ +int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value); +int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option opt, EN_API_FLOAT_TYPE *value); - /** - @brief Set the link type code for a specified link - @param id The id of a link - @param type The type code of the link. - @return Error code - @see EN_LinkType - */ - int DLLEXPORT ENsetlinktype(char *id, EN_LinkType type); - - /** - @brief Get the indexes of a link's start- and end-nodes. - @param index The index of a link (first link is index 1) - @param[out] node1 The index of the link's start node (first node is index 1). - @param[out] node2 The index of the link's end node (first node is index 1). - @return Error code - @see ENgetnodeid, ENgetlinkid - */ - int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2); - - /** - @brief Get a property value for specified link. - @param index The index of a node (first node is index 1). - @param code The parameter desired. - @param[out] value The value of the link's specified property. - @return Error code - @see ENgetnodevalue, EN_LinkProperty - */ - int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value); - - /** - @brief Get a curve's properties. - @param curveIndex The index of a curve (first curve is index 1). - @param[out] id The curve's string ID. Client code must preallocate at least MAXID characters. - @param[out] nValues The number of values in the curve's (x,y) list. - @param[out] xValues The curve's x-values. Pointer must be freed by client. - @param[out] yValues The curve's y-values. Pointer must be freed by client. - @return Error code. - */ - int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); - - /** - @brief Retrieves the curve index for a specified pump index. - @param pumpIndex The index of a pump - @param[out] curveIndex The index of the curve used by the pump. - @return Error code. - */ - int DLLEXPORT ENgetheadcurveindex(int pumpIndex, int *curveIndex); - - /** - @brief Sets the curve id for a specified pump index. - @param pumpIndex The index of the pump - @param curveIndex The index of the curve used by the pump - @return Error code. - */ - int DLLEXPORT ENsetheadcurveindex(int pumpIndex, int curveIndex); - - /** - @brief Get the type of pump - @param linkIndex The index of the pump element - @param[out] outType The integer-typed pump curve type signifier (output parameter) - @return Error code - @see EN_CurveType - */ - int DLLEXPORT ENgetpumptype(int linkIndex, int *outType); - - /** +/** @brief Get the version number. This number is to be interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" @param[out] version The version of EPANET @return Error code. - */ - int DLLEXPORT ENgetversion(int *version); - - /** - @brief Specify parameters to define a simple control - @param cindex The index of the control to edit. First control is index 1. - @param ctype The type code to set for this control. - @param lindex The index of a link to control. - @param setting The control setting applied to the link. - @param nindex The index of a node used to control the link, or 0 for TIMER / TIMEOFDAY control. - @param level control point (tank level, junction pressure, or time in seconds). - @return Error code. - */ - int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); - - /** - @brief Set a property value for a node. - @param index The index of a node. First node is index 1. - @param code The code for the proprty to set. - @param v The value to set for this node and property. - @return Error code. - @see EN_NodeProperty - */ - int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v); - - /** - @brief Set a proprty value for a link. - @param index The index of a link. First link is index 1. - @param code The code for the property to set. - @param v The value to set for this link and property. - @return Error code. - @see EN_LinkProperty - */ - int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v); - - /** - @brief Add a new time pattern. - @param id The string ID of the pattern to add. - @return Error code. - @see ENgetpatternindex - */ - int DLLEXPORT ENaddpattern(char *id); - - /** - @brief Set multipliers for a specific pattern - @param index The index of a pattern. First pattern is index 1. - @param f An array of multipliers - @param len The length of array f. - @return Error code. - @see ENgetpatternindex - */ - int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len); - - /** - @brief Set the multiplier for a specific pattern at a specific period. - @param index The index of a pattern. First pattern is index 1. - @param period The period of the pattern to set. - @param value The value of the multiplier to set. - @return Error code. - */ - int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value); - - /** - @brief Set the value for a time parameter. - @param code The code for the parameter to set. - @param value The desired value of the parameter. - @return Error code. - @see EN_TimeProperty - */ - int DLLEXPORT ENsettimeparam(int code, long value); - - /** - @brief Set a value for an anlysis option. - @param code The code for the desired option. - @param v The desired value for the option specified. - @return Error code. - @see EN_Option - */ - int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v); - - /** - @brief Sets the level of hydraulic status reporting. - @param code Status reporting code. - @return Error code. - */ - int DLLEXPORT ENsetstatusreport(int code); - - /** + */ +int DLLEXPORT ENgetversion(int *version); +int DLLEXPORT EN_getversion(int *version); + + +// SETTING NEW VALUES FOR NETWORK PARAMETERS +/** + @brief Specify parameters to define a simple control + @param cindex The index of the control to edit. First control is index 1. + @param ctype The type code to set for this control. + @param lindex The index of a link to control. + @param setting The control setting applied to the link. + @param nindex The index of a node used to control the link, or 0 for TIMER / TIMEOFDAY control. + @param level control point (tank level, junction pressure, or time in seconds). + @return Error code. + */ +int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); +int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); + +/** + @brief Set a property value for a node. + @param index The index of a node. First node is index 1. + @param code The code for the proprty to set. + @param v The value to set for this node and property. + @return Error code. + @see EN_NodeProperty + */ +int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v); +int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); + +/** + @brief Set a proprty value for a link. + @param index The index of a link. First link is index 1. + @param code The code for the property to set. + @param v The value to set for this link and property. + @return Error code. + @see EN_LinkProperty + */ +int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v); +int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); + +/** + @brief Set multipliers for a specific pattern + @param index The index of a pattern. First pattern is index 1. + @param f An array of multipliers + @param len The length of array f. + @return Error code. + @see ENgetpatternindex + */ +int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len); +int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int len); + +/** + @brief Set the multiplier for a specific pattern at a specific period. + @param index The index of a pattern. First pattern is index 1. + @param period The period of the pattern to set. + @param value The value of the multiplier to set. + @return Error code. + */ +int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value); +int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value); + +/** @brief Sets type of quality analysis called for @param qualcode WQ parameter code, EN_QualityType @param chemname Name of WQ constituent @@ -866,12 +582,405 @@ extern "C" { @param tracenode ID of node being traced (if applicable) @return Error code. @see EN_QualityType - + chemname and chemunits only apply when WQ analysis is for chemical. tracenode only applies when WQ analysis is source tracing. - */ - int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); - - /** + */ +int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); +int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode); + +/** + @brief Set the value for a time parameter. + @param code The code for the parameter to set. + @param value The desired value of the parameter. + @return Error code. + @see EN_TimeProperty + */ +int DLLEXPORT ENsettimeparam(int code, long value); +int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value); + +/** + @brief Set a value for an anlysis option. + @param code The code for the desired option. + @param v The desired value for the option specified. + @return Error code. + @see EN_Option + */ +int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v); +int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v); + + +// SAVING AND USING HYDRAULIC ANALYSIS RESULTS FILES +/** + @brief Copies binary hydraulics file to disk + @param filename Name of file to be created + @return Error code + */ +int DLLEXPORT ENsavehydfile(char *filename); +int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename); + +/** + @brief Opens previously saved binary hydraulics file + @param filename Name of file to be used + @return Error code + */ +int DLLEXPORT ENusehydfile(char *filename); +int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename); + + +// RUNNING A HYDRAULIC ANALYSIS +/** + @brief Solves the network hydraulics for all time periods + @return Error code + */ +int DLLEXPORT ENsolveH(); +int DLLEXPORT EN_solveH(EN_ProjectHandle ph); + +/** + @brief Sets up data structures for hydraulic analysis + @return Error code + */ +int DLLEXPORT ENopenH(); +int DLLEXPORT EN_openH(EN_ProjectHandle ph); + +/** + @brief Initializes hydraulic analysis + @param initFlag 2-digit flag where 1st (left) digit indicates if link flows should be re-initialized (1) or not (0), and 2nd digit indicates if hydraulic results should be saved to file (1) or not (0). + @return Error code + */ +int DLLEXPORT ENinitH(int initFlag); +int DLLEXPORT EN_initH(EN_ProjectHandle ph, int EN_SaveOption); + +/** + @brief Run a hydraulic solution period + @param[out] currentTime The current simulation time in seconds + @return Error or warning code + @see ENsolveH + + This function is used in a loop with ENnextH() to run + an extended period hydraulic simulation. + See ENsolveH() for an example. + */ +int DLLEXPORT ENrunH(long *currentTime); +int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *currentTime); + +/** + @brief Determine time (in seconds) until next hydraulic event + @param[out] tStep Time (seconds) until next hydraulic event. 0 marks end of simulation period. + @return Error code + + This function is used in a loop with ENrunH() to run an extended period hydraulic simulation. + See ENsolveH() for an example. + */ +int DLLEXPORT ENnextH(long *tStep); +int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tStep); + +/** + @brief Frees data allocated by hydraulics solver + @return Error code + */ +int DLLEXPORT ENcloseH(); +int DLLEXPORT EN_closeH(EN_ProjectHandle ph); + + +// RUNNING A WATER QUALITY ANALYSIS +/** + @brief Solves for network water quality in all time periods + @return Error code + */ +int DLLEXPORT ENsolveQ(); +int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); + +/** + @brief Sets up data structures for WQ analysis + @return Error code + */ +int DLLEXPORT ENopenQ(); +int DLLEXPORT EN_openQ(EN_ProjectHandle ph); + +/** + @brief Initializes water quality analysis + @param saveFlag EN_SAVE (1) if results saved to file, EN_NOSAVE (0) if not + @return Error code + */ +int DLLEXPORT ENinitQ(int saveFlag); +int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveFlag); + +/** + @brief Retrieves hydraulic & WQ results at time t. + @param[out] currentTime Current simulation time, in seconds. + @return Error code + + This function is used in a loop with ENnextQ() to run + an extended period WQ simulation. See ENsolveQ() for + an example. + */ +int DLLEXPORT ENrunQ(long *currentTime); +int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *currentTime); + +/** + @brief Advances WQ simulation to next hydraulic event. + @param[out] tStep Time in seconds until next hydraulic event. 0 marks end of simulation period. + @return Error code + + This function is used in a loop with ENrunQ() to run + an extended period WQ simulation. See ENsolveQ() for + an example. + */ +int DLLEXPORT ENnextQ(long *tStep); +int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tStep); + +/** + @brief Advances WQ simulation by a single WQ time step + @param[out] timeLeft Time left in overall simulation (in seconds) + @return Error code + + This function is used in a loop with ENrunQ() to run + an extended period WQ simulation. + */ +int DLLEXPORT ENstepQ(long *timeLeft); +int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *timeLeft); + +/** + @brief Frees data allocated by water quality solver. + @return Error code. + */ +int DLLEXPORT ENcloseQ(); +int DLLEXPORT EN_closeQ(EN_ProjectHandle ph); + + +// GENERATING AN OUTPUT REPORT +/** + @brief Saves hydraulic results to binary file + @return Error code + + Must be called before ENreport() if no WQ simulation has been made. + Should not be called if ENsolveQ() will be used. + */ +int DLLEXPORT ENsaveH(); +int DLLEXPORT EN_saveH(EN_ProjectHandle ph); + +/** + @brief Saves current data to "INP" formatted text file. + @param filename The file path to create + @return Error code + */ +int DLLEXPORT ENsaveinpfile(char *filename); +int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename); + +/** + @brief Writes simulation report to the report file + @return Error code + */ +int DLLEXPORT ENreport(); +int DLLEXPORT EN_report(EN_ProjectHandle ph); + +/** + @brief Resets report options to default values + @return Error code + */ +int DLLEXPORT ENresetreport(); +int DLLEXPORT EN_resetreport(EN_ProjectHandle ph); + +/** + @brief Processes a reporting format command + @return Error code + */ +int DLLEXPORT ENsetreport(char *reportFormat); +int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *reportFormat); + +/** + @brief Sets the level of hydraulic status reporting. + @param code Status reporting code. + @return Error code. + */ +int DLLEXPORT ENsetstatusreport(int code); +int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code); + +/** + @brief Get the text of an error code. + @param errcode The error code + @param[out] errmsg The error string represented by the code + @param maxLen The maximum number of characters to copy into the char pointer errmsg + @return Error code + */ +int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen); +int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); + + + +//////////////////////////////////////////////////////////////////////////////// +//-------------------------------- NEW API -----------------------------------// +//////////////////////////////////////////////////////////////////////////////// + +/** + @brief Initializes an EPANET session + @param rptFile pointer to name of report file (to be created) + @param binOutFile pointer to name of binary output file (to be created) + @param UnitsType flow units flag + @param HeadlossFormula headloss formula flag + @return error code + */ +int DLLEXPORT ENinit(char *rptFile, char *binOutFile, int UnitsType, + int HeadlossFormula); +int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *rptFile, char *binOutFile, + EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); + +/** + @brief Writes line of text to the report file. + @param line Text string to write + @return Error code. + */ +int DLLEXPORT ENwriteline(char *line); +int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line); + +/** + @brief Sets the flow units + @param code Code of flow units to use + @return Error code + */ +int DLLEXPORT ENsetflowunits(int code); +int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code); + + +/** + @brief Retrieve the average multiplier value in a time pattern + @param index The index of a time pattern + @param[out] value The average of all of this time pattern's values + @return Error code + */ +int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); +int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value); + + +/** + @brief Retrieve the type of quality analytis to be run. + @param[out] qualcode The quality analysis code number. + @param[out] tracenode The index of node being traced, if qualcode == trace + @return Error code + @see ENsetqualtype + */ +int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode); + + +/** + @brief Get hydraulic simulation statistic + @param code The type of statistic to get + @param[out] value The value of the statistic + @return Error code + */ +int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value); + +/** + @brief Get coordinates (x,y) for a node. + @param index The index of a node (first node is index 1). + @param[out] x X-value of node's coordinate + @param[out] y Y-value of node's coordinate + @return Error code + @see ENsetcoord + */ +int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + + +/** + @brief Set coordinates (x,y) for a node. + @param index The index of a node (first node is index 1) + @param x X-value of node's coordinate + @param y Y-value of node's coordinate + @return Error code + @see ENgetcoord + */ +int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + + +/** + @brief Get the number of demand categories for a node. + @param nodeIndex The index of a node (first node is index 1) + @param[out] numDemands The number of demand categories + @return Error code + */ +int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands); + + +/** + @brief Get a node's base demand for a specified category. + @param nodeIndex The index of a node (first node is index 1) + @param demandIndex The index of the demand category (starting at 1) + @return Error code + */ +int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); + + +/** + @brief Get the index of the demand pattern assigned to a node for a category index. + @param nodeIndex The index of a node (first node is index 1). + @param demandIndex The index of a category (first category is index 1). + @param[out] pattIndex The index of the pattern for this node and category. + @return Error code + */ +int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIndex); + + +/** + @brief Set the link type code for a specified link + @param id The id of a link + @param type The type code of the link. + @return Error code + @see EN_LinkType + */ +int DLLEXPORT ENsetlinktype(char *id, EN_LinkType type); +int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); + + +/** + @brief Get a curve's properties. + @param curveIndex The index of a curve (first curve is index 1). + @param[out] id The curve's string ID. Client code must preallocate at least MAXID characters. + @param[out] nValues The number of values in the curve's (x,y) list. + @param[out] xValues The curve's x-values. Pointer must be freed by client. + @param[out] yValues The curve's y-values. Pointer must be freed by client. + @return Error code. + */ +int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); + + +/** + @brief Retrieves the curve index for a specified pump index. + @param pumpIndex The index of a pump + @param[out] curveIndex The index of the curve used by the pump. + @return Error code. + */ +int DLLEXPORT ENgetheadcurveindex(int pumpIndex, int *curveIndex); + + +/** + @brief Sets the curve id for a specified pump index. + @param pumpIndex The index of the pump + @param curveIndex The index of the curve used by the pump + @return Error code. + */ +int DLLEXPORT ENsetheadcurveindex(int pumpIndex, int curveIndex); + + +/** + @brief Get the type of pump + @param linkIndex The index of the pump element + @param[out] outType The integer-typed pump curve type signifier (output parameter) + @return Error code + @see EN_CurveType + */ +int DLLEXPORT ENgetpumptype(int linkIndex, int *outType); + + +/** + @brief Add a new time pattern. + @param id The string ID of the pattern to add. + @return Error code. + @see ENgetpatternindex + */ +int DLLEXPORT ENaddpattern(char *id); + + +/** @brief Get quality analysis information (type, chemical name, units, trace node ID) @param[out] qualcode The EN_QualityType code being used. @param[out] chemname The name of the WQ constituent. @@ -879,49 +988,54 @@ extern "C" { @param[out] tracenode The trace node ID. @return Error code. @see EN_QualityType - */ - int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode); - - /** + */ +int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode); + +/** @brief Sets the node's base demand for a category. @param nodeIndex The index of a node. @param demandIdx The index of a demand category. @param baseDemand The base demand multiplier for the selected category. @return Error code. @see ENgetbasedemand - */ - int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); - - /** + */ +int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + + +// RETREIVING AND SETTING CURVES +/** @brief Retrieves index of curve with specific ID. @param id The ID of a curve. @param[out] index The index of the named curve @return Error code. @see ENgetcurveid - */ - int DLLEXPORT ENgetcurveindex(char *id, int *index); - - /** + */ +int DLLEXPORT ENgetcurveindex(char *id, int *index); + + +/** @brief Retrieves ID of a curve with specific index. @param index The index of a curve. @param[out] id The ID of the curve specified. @return Error code. @see ENsetcurveindex - + NOTE: 'id' must be able to hold MAXID characters - */ - int DLLEXPORT ENgetcurveid(int index, char *id); - - /** + */ +int DLLEXPORT ENgetcurveid(int index, char *id); + + +/** @brief Retrieves number of points in a curve @param index The index of a curve. @param[out] len The length of the curve coordinate list @return Error code. @see ENgetcurvevalue - */ - int DLLEXPORT ENgetcurvelen(int index, int *len); - - /** + */ +int DLLEXPORT ENgetcurvelen(int index, int *len); + + +/** @brief retrieves x,y point for a specific point number and curve @param curveIndex The index of a curve @param pointIndex The index of a point in the curve @@ -929,39 +1043,41 @@ extern "C" { @param[out] y The y-value of the specified point. @return Error code. @see ENgetcurvelen ENsetcurvevalue - */ - int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - - /** + */ +int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + +/** @brief Sets x,y point for a specific point and curve. @param curveIndex The index of a curve. @param pointIndex The index of a point in the curve. @param x The x-value of the point. @param y The y-value of the point. @return Error code. - */ - int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - - /** + */ +int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + +/** @brief Sets x,y values for a specified curve. @param index The index of a curve. @param x An array of x-values for the curve. @param y An array of y-values for the curve. @param len The length of the arrays x and y. @return Error code. - */ - int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); - - /** + */ +int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); + + +/** @brief Adds a new curve appended to the end of the existing curves. @param id The name of the curve to be added. @return Error code. @see ENgetcurveindex ENsetcurve - */ - int DLLEXPORT ENaddcurve(char *id); - + */ +int DLLEXPORT ENaddcurve(char *id); - /** + +// CONTROL API +/** @brief Gets the number of premises, true actions, and false actions and the priority of an existing rule-based control. @param index The index of a rule-based control. @param nPremises The number of conditions in a rule-based control. @@ -969,18 +1085,20 @@ extern "C" { @param nFalseActions The number of actions that are executed when the conditions in the rule-based control are not met. @param priority The priority of a rule-based control. @return Error code. - */ - int DLLEXPORT ENgetrule(int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); + */ +int DLLEXPORT ENgetrule(int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); +int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); - /** +/** @brief Sets the priority of the existing rule-based control. @param index The index of a rule-based control. @param priority The priority to be set in the rule-based control. @return Error code. - */ - int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority); + */ +int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority); +int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority); - /** +/** @brief Gets the components of a premise/condition in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @@ -992,10 +1110,11 @@ extern "C" { @param status The status of the object to be checked (e.g. CLOSED) @param value The value of the variable to be checked (e.g. 5.5) @return Error code. - */ - int DLLEXPORT ENgetpremise(int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); + */ +int DLLEXPORT ENgetpremise(int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); +int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); - /** +/** @brief Sets the components of a premise/condition in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @@ -1007,37 +1126,41 @@ extern "C" { @param status The status of the object to be checked (e.g. CLOSED) @param value The value of the variable to be checked (e.g. 5.5) @return Error code. - */ - int DLLEXPORT ENsetpremise(int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); + */ +int DLLEXPORT ENsetpremise(int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); +int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); - /** +/** @brief Sets the index of an object in a premise of an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @param indexObj The index of the object (e.g. the index of the tank). @return Error code. - */ - int DLLEXPORT ENsetpremiseindex(int indexRule, int indexPremise, int indexObj); + */ +int DLLEXPORT ENsetpremiseindex(int indexRule, int indexPremise, int indexObj); +int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj); - /** +/** @brief Sets the status in a premise of an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @param status The status of the object to be checked (e.g. CLOSED) @return Error code. - */ - int DLLEXPORT ENsetpremisestatus(int indexRule, int indexPremise, int status); + */ +int DLLEXPORT ENsetpremisestatus(int indexRule, int indexPremise, int status); +int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status); - /** +/** @brief Sets the value in a premise of an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @param value The value of the variable to be checked (e.g. 5.5) @return Error code. - */ - int DLLEXPORT ENsetpremisevalue(int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); - - /** + */ +int DLLEXPORT ENsetpremisevalue(int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); +int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); + +/** @brief Gets the components of a true-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are met. @@ -1045,10 +1168,11 @@ extern "C" { @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ - int DLLEXPORT ENgettrueaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + */ +int DLLEXPORT ENgettrueaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); +int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); - /** +/** @brief Sets the components of a true-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are met. @@ -1056,10 +1180,11 @@ extern "C" { @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ - int DLLEXPORT ENsettrueaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - - /** + */ +int DLLEXPORT ENsettrueaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); +int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + +/** @brief Gets the components of a false-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are not met. @@ -1067,10 +1192,11 @@ extern "C" { @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ - int DLLEXPORT ENgetfalseaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + */ +int DLLEXPORT ENgetfalseaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); +int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); - /** +/** @brief Sets the components of a false-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are not met. @@ -1078,166 +1204,100 @@ extern "C" { @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ - int DLLEXPORT ENsetfalseaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + */ +int DLLEXPORT ENsetfalseaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); +int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - /** +/** @brief Returns the ID of a rule. @param indexRule The index of a rule-based control. @param id The ID of the rule @return Error code. - */ - int DLLEXPORT ENgetruleID(int indexRule, char* id); + */ +int DLLEXPORT ENgetruleID(int indexRule, char* id); +int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char* id); - /** + +// ADDING AND DELETING NETWORK OBJECTS +/** @brief Adds a new node @param id The name of the node to be added. @param nodeType The node type code @return Error code. - */ - int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType); - - /** + */ +int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType); +int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType); + +/** @brief Adds a new link @param id The name of the link to be added. @param linkType The link type code @param fromNode The id of the from node @param toNode The id of the to node @return Error code. - */ - int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode); - - /** + */ +int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode); +int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode); + +/** @brief Deletes a node @param nodeIndex The node index @return Error code. - */ - int DLLEXPORT ENdeletenode(int nodeIndex); - - /** + */ +int DLLEXPORT ENdeletenode(int nodeIndex); +int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int nodeIndex); + +/** @brief Deletes a link @param linkIndex The link index @return Error code. - */ - int DLLEXPORT ENdeletelink(int linkIndex); - - - - - /*************************************************** - + */ +int DLLEXPORT ENdeletelink(int linkIndex); +int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex); + +/*************************************************** Threadsafe versions of all epanet functions - - ***************************************************/ - int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); - int DLLEXPORT EN_free(EN_ProjectHandle *ph); + ***************************************************/ +int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); +int DLLEXPORT EN_free(EN_ProjectHandle *ph); - int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *rptFile, char *binOutFile, - EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); - int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, - const char *rptFile, const char *binOutFile); - int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename); +int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); - int DLLEXPORT EN_close(EN_ProjectHandle ph); - int DLLEXPORT EN_solveH(EN_ProjectHandle ph); - int DLLEXPORT EN_saveH(EN_ProjectHandle ph); - int DLLEXPORT EN_openH(EN_ProjectHandle ph); - int DLLEXPORT EN_initH(EN_ProjectHandle ph, int EN_SaveOption); - int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *currentTime); - int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tStep); - int DLLEXPORT EN_closeH(EN_ProjectHandle ph); - int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename); - int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename); +int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE* value); + +int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); +int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + +int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands); +int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); +int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIndex, int *pattIndex); + +int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); +int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int *curveIndex); +int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int curveIndex); +int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int linkIndex, int *outType); + +int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id); + +int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode); +int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + +int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index); +int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id); +int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len); +int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); +int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); +int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); +int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id); + - int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); - int DLLEXPORT EN_openQ(EN_ProjectHandle ph); - int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveFlag); - int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *currentTime); - int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tStep); - int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *timeLeft); - int DLLEXPORT EN_closeQ(EN_ProjectHandle ph); - int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line); - int DLLEXPORT EN_report(EN_ProjectHandle ph); - int DLLEXPORT EN_resetreport(EN_ProjectHandle ph); - int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *reportFormat); - int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); - int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count); - int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option opt, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value); - int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code); - int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code); - int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index); - int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id); - int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len); - int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); - int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); - int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE* value); - int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index); - int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id); - int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code); - int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands); - int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); - int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIndex, int *pattIndex); - int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index); - int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id); - int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code); - int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); - int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2); - int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); - int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int *curveIndex); - int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int curveIndex); - int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int linkIndex, int *outType); - int DLLEXPORT EN_getversion(int *version); - int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); - int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); - int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); - int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id); - int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int len); - int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value); - int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value); - int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v); - int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code); - int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode); - int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode); - int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); - int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index); - int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id); - int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len); - int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); - int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id); - int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); - int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority); - int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); - int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj); - int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status); - int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); - int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); - int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); - int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char* id); - int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType); - int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode); - int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int nodeIndex); - int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex); - - #if defined(__cplusplus) } #endif diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index 91be266..d01d53a 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -113,7 +113,7 @@ BOOST_FIXTURE_TEST_CASE(test_epanet, Fixture) BOOST_FIXTURE_TEST_CASE(test_hyd_step, Fixture) { - int flag = 00; + int flag = EN_NOSAVE; long t, tstep; error = EN_openH(ph); @@ -180,8 +180,6 @@ BOOST_FIXTURE_TEST_CASE(test_hyd_qual_step, Fixture) BOOST_REQUIRE(error == 0); do { - - error = EN_runH(ph, &t); BOOST_REQUIRE(error == 0); From 4723336726bca146d9f7529e313b27e6ef261a8d Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 13 Jul 2018 11:47:47 -0400 Subject: [PATCH 29/45] Adding errormanager to toolkit api --- CMakeLists.txt | 4 +- include/epanet2.h | 7 ++- src/epanet.c | 135 +++++++++++++++++++++++++++++++++------- src/types.h | 4 ++ src/util/errormanager.c | 73 ++++++++++++++++++++++ src/util/errormanager.h | 30 +++++++++ tests/test_toolkit.cpp | 21 +++++++ 7 files changed, 246 insertions(+), 28 deletions(-) create mode 100644 src/util/errormanager.c create mode 100644 src/util/errormanager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e82365..acb522c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,8 +69,8 @@ ENDIF (MSVC) # configure file groups -file(GLOB EPANET_SOURCES src/*.c) -file(GLOB EPANET_LIB_ALL src/*) +file(GLOB EPANET_SOURCES src/*.c src/util/*.c) +file(GLOB EPANET_LIB_ALL src/* src/util/*) source_group("Library" FILES ${EPANET_LIB_ALL}) diff --git a/include/epanet2.h b/include/epanet2.h index ef6f9d2..726678c 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -294,8 +294,9 @@ typedef struct EN_Curve EN_Curve; needed then the argument should be NULL. */ int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile, - const char *binOutFile, void (*callback) (char *)); - + const char *binOutFile, void (*callback) (char *)); +int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *inpFile, + const char *rptFile, const char *binOutFile, void(*callback) (char *)); // OPENING A CLOSING THE EPANET TOOLKIT SYSTEM /** @@ -1261,6 +1262,8 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex); int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); int DLLEXPORT EN_free(EN_ProjectHandle *ph); +void DLLEXPORT EN_clearError(EN_ProjectHandle ph); +int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char **msg_buffer); int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); diff --git a/src/epanet.c b/src/epanet.c index 568b3c8..90b790f 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -133,6 +133,10 @@ execute function x and set the error code equal to its return value. ////////////////////////////////////////////#include "epanet2.h" #include "vars.h" + +// Local functions +void errorLookup(int errcode, char *errmsg, int len); + /**************************************************************** LEGACY (v <= 2.1) API: uses global project variable @@ -159,24 +163,14 @@ execute function x and set the error code equal to its return value. int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *)) { int errcode = 0; - EN_Project *_p; ERRCODE(EN_alloc(&_defaultModel)); - ERRCODE(EN_open(_defaultModel, f1, f2, f3)); - _p = (EN_Project*)_defaultModel; + ERRCODE(EN_epanet(_defaultModel, f1, f2, f3, pviewprog)); + + ERRCODE(EN_free(&_defaultModel)); - _p->viewprog = pviewprog; - if (_p->out_files.Hydflag != USE) { - ERRCODE(EN_solveH(_defaultModel)); - } - - ERRCODE(EN_solveQ(_defaultModel)); - ERRCODE(EN_report(_defaultModel)); - EN_close(_defaultModel); - EN_free(&_defaultModel); - - return (errcode); + return errcode; } int DLLEXPORT ENopen(char *f1, char *f2, char *f3) { @@ -548,21 +542,55 @@ int DLLEXPORT ENdeletenode(int index) { /// allocate a project pointer int DLLEXPORT EN_alloc(EN_ProjectHandle *ph) { + int errorcode = 0; EN_Project *project = calloc(1, sizeof(EN_Project)); - *ph = project; - return 0; + if (project != NULL){ + project->error_handle = new_errormanager(&errorLookup); + *ph = project; + } + else + errorcode = -1; + + return errorcode; } int DLLEXPORT EN_free(EN_ProjectHandle *ph) { - EN_Project *p = (EN_Project*)(*ph); + int errorcode = 0; + EN_Project *p = (EN_Project*)(*ph); - free(p); + if (p == NULL) + errorcode = -1; + else + { + dst_errormanager(p->error_handle); + free(p); - *ph = NULL; + *ph = NULL; + } - return 0; + return 0; +} + +int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, + const char *f3, void(*pviewprog)(char *)) +{ + int errcode = 0; + EN_Project *_p = (EN_Project*)ph; + + ERRCODE(EN_open(ph, f1, f2, f3)); + + _p->viewprog = pviewprog; + if (_p->out_files.Hydflag != USE) { + ERRCODE(EN_solveH(ph)); + } + + ERRCODE(EN_solveQ(ph)); + ERRCODE(EN_report(ph)); + EN_close(ph); + + return set_error(_p->error_handle, errcode); } int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, @@ -1724,10 +1752,12 @@ int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) } -int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname, +int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode) { - EN_getqualtype(p, qualcode, tracenode); + EN_Project *p = (EN_Project*)ph; + + EN_getqualtype(ph, qualcode, tracenode); if (p->quality.Qualflag == TRACE) { strncpy(chemname, "", MAXID); @@ -1739,6 +1769,63 @@ int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname, return 0; } +void errorLookup(int errcode, char *dest_msg, int dest_len) +// Purpose: takes error code returns error message +{ + char *msg = NULL; + + switch (errcode) + { + case 1: msg = WARN1; + break; + case 2: msg = WARN2; + break; + case 3: msg = WARN3; + break; + case 4: msg = WARN4; + break; + case 5: msg = WARN5; + break; + case 6: msg = WARN6; + break; + default: + msg = geterrmsg(errcode, msg); + } + strncpy(dest_msg, msg, MAXMSG); +} + +void DLLEXPORT EN_clearError(EN_ProjectHandle ph) +{ + EN_Project *p = (EN_Project*)ph; + + clear_error(p->error_handle); +} + +int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer) +// +// Purpose: Returns the error message or NULL. +// +// Note: Caller must free memory allocated by EN_check_error +// +{ + int errorcode = 0; + char *temp = NULL; + EN_Project *p = (EN_Project*)ph; + + + if (p == NULL) return -1; + else + { + errorcode = p->error_handle->error_status; + if (errorcode) + temp = check_error(p->error_handle); + + *msg_buffer = temp; + } + + return errorcode; +} + int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { char newMsg[MAXMSG+1]; @@ -4247,11 +4334,11 @@ char *geterrmsg(int errcode, char *msg) */ { switch (errcode) { /* Warnings */ -#define DAT(code,enumer,string) case code: strcpy(msg, string); break; +#define DAT(code,enumer,string) case code: msg = string; break; #include "errors.dat" #undef DAT default: - strcpy(msg, ""); + msg = ""; } return (msg); } diff --git a/src/types.h b/src/types.h index cd64eb5..cd3fdf7 100755 --- a/src/types.h +++ b/src/types.h @@ -23,6 +23,8 @@ AUTHOR: L. Rossman #include "epanet2.h" #include "hash.h" #include "mempool.h" +#include "util/errormanager.h" + /*********************************************************/ /* All floats have been re-declared as doubles (7/3/07). */ @@ -870,6 +872,8 @@ typedef struct EN_Project { Title[MAXTITLE][MAXMSG+1], /// Problem title MapFname[MAXFNAME+1]; /// Map file name + error_handle_t* error_handle; //Simple error manager + void (* viewprog) (char *); /* Pointer to progress viewing function */ } EN_Project; diff --git a/src/util/errormanager.c b/src/util/errormanager.c new file mode 100644 index 0000000..abba233 --- /dev/null +++ b/src/util/errormanager.c @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// +// errormanager.c +// +// Purpose: Provides a simple interface for managing runtime error messages. +// +// Date: 08/25/2017 +// +// Author: Michael E. Tryby +// US EPA - ORD/NRMRL +//----------------------------------------------------------------------------- +#include "errormanager.h" + +error_handle_t* new_errormanager(void (*p_error_message)(int, char*, int)) +// +// Purpose: Constructs a new error handle. +// +{ + error_handle_t* error_handle; + error_handle = (error_handle_t*)calloc(1, sizeof(error_handle_t)); + + if (error_handle != NULL) + error_handle->p_msg_lookup = p_error_message; + + return error_handle; +} + +void dst_errormanager(error_handle_t* error_handle) +// +// Purpose: Destroys the error handle. +// +{ + free(error_handle); +} + +int set_error(error_handle_t* error_handle, int errorcode) +// +// Purpose: Sets an error code in the handle. +// +{ + // If the error code is 0 no action is taken and 0 is returned. + // This is a feature not a bug. + if (errorcode) + error_handle->error_status = errorcode; + + return errorcode; +} + +char* check_error(error_handle_t* error_handle) +// +// Purpose: Returns the error message or NULL. +// +// Note: Caller must free memory allocated by check_error +// +{ + char* temp = NULL; + + if (error_handle->error_status != 0) { + temp = (char*) calloc(ERR_MAXMSG, sizeof(char)); + + if (temp) + error_handle->p_msg_lookup(error_handle->error_status, temp, ERR_MAXMSG); + } + return temp; +} + +void clear_error(error_handle_t* error_handle) +// +// Purpose: Clears the error from the handle. +// +{ + error_handle->error_status = 0; +} diff --git a/src/util/errormanager.h b/src/util/errormanager.h new file mode 100644 index 0000000..36ee969 --- /dev/null +++ b/src/util/errormanager.h @@ -0,0 +1,30 @@ +/* + * errormanager.h + * + * Created on: Aug 25, 2017 + * + * Author: Michael E. Tryby + * US EPA - ORD/NRMRL + */ + +#ifndef ERRORMANAGER_H_ +#define ERRORMANAGER_H_ + +#include +#include + +#define ERR_MAXMSG 256 + +typedef struct error_s { + int error_status; + void (*p_msg_lookup)(int, char*, int); +} error_handle_t; + +error_handle_t* new_errormanager(void (*p_error_message)(int, char*, int)); +void dst_errormanager(error_handle_t* error_handle); + +int set_error(error_handle_t* error_handle, int errorcode); +char* check_error(error_handle_t* error_handle); +void clear_error(error_handle_t* error_handle); + +#endif /* ERRORMANAGER_H_ */ diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index d01d53a..efb144c 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -69,6 +69,27 @@ BOOST_AUTO_TEST_CASE(test_epanet) BOOST_REQUIRE(error == 0); } +BOOST_AUTO_TEST_CASE(test_errormanager) +{ + char *error_msg; + EN_ProjectHandle ph = NULL; + + std::string path_inp = std::string(DATA_PATH_INP); + std::string path_rpt = std::string(DATA_PATH_RPT); + std::string path_out = std::string(DATA_PATH_RPT); + + + EN_alloc(&ph); + + EN_clearError(ph); + int error = EN_epanet(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str(), NULL); + EN_checkError(ph, &error_msg); + + EN_free(&ph); + + free(error_msg); +} + BOOST_AUTO_TEST_SUITE_END() From 437a7c70e0f481ee08d0f1c66d20c993c5fe45a9 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 18 Jul 2018 18:33:51 -0400 Subject: [PATCH 30/45] Reorganizing / refactoring api functions for swig wrap --- src/epanet.c | 3949 +++++++++++++++++++++++++------------------------- 1 file changed, 2008 insertions(+), 1941 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 90b790f..8248ca8 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -143,6 +143,20 @@ void errorLookup(int errcode, char *errmsg, int len); *****************************************************************/ +int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, + void (*pviewprog)(char *)) +{ + int errcode = 0; + + ERRCODE(EN_alloc(&_defaultModel)); + ERRCODE(EN_epanet(_defaultModel, f1, f2, f3, pviewprog)); + ERRCODE(EN_free(&_defaultModel)); + + return errcode; +} + +int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, + const char *f3, void(*pviewprog)(char *)) /*------------------------------------------------------------------------ ** Input: f1 = pointer to name of input file ** f2 = pointer to name of report file @@ -160,31 +174,2011 @@ void errorLookup(int errcode, char *errmsg, int len); ** needed then the argument should be NULL. **------------------------------------------------------------------------- */ -int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *)) +{ + int errcode = 0; + EN_Project *_p = (EN_Project*)ph; + + ERRCODE(EN_open(ph, f1, f2, f3)); + + _p->viewprog = pviewprog; + if (_p->out_files.Hydflag != USE) { + ERRCODE(EN_solveH(ph)); + } + + ERRCODE(EN_solveQ(ph)); + ERRCODE(EN_report(ph)); + EN_close(ph); + + return set_error(_p->error_handle, errcode); +} + +int DLLEXPORT ENopen(char *f1, char *f2, char *f3) { int errcode = 0; ERRCODE(EN_alloc(&_defaultModel)); - - ERRCODE(EN_epanet(_defaultModel, f1, f2, f3, pviewprog)); - - ERRCODE(EN_free(&_defaultModel)); + EN_open(_defaultModel, f1, f2, f3); - return errcode; + return (errcode); } -int DLLEXPORT ENopen(char *f1, char *f2, char *f3) { +int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3) +/*---------------------------------------------------------------- + ** Input: f1 = pointer to name of input file + ** f2 = pointer to name of report file + ** f3 = pointer to name of binary output file + ** Output: none + ** Returns: error code + ** Purpose: opens EPANET input file & reads in network data + **---------------------------------------------------------------- + */ +{ int errcode = 0; - ERRCODE(EN_alloc(&_defaultModel)); - EN_open(_defaultModel, f1, f2, f3); - return (errcode); + +/*** Updated 9/7/00 ***/ +/* Reset math coprocessor */ +#ifdef DLL + _fpreset(); +#endif + + EN_Project *p = (EN_Project*)ph; + + /* Set system flags */ + p->Openflag = FALSE; + p->hydraulics.OpenHflag = FALSE; + p->quality.OpenQflag = FALSE; + p->save_options.SaveHflag = FALSE; + p->save_options.SaveQflag = FALSE; + p->Warnflag = FALSE; + p->parser.Coordflag = TRUE; + + /*** Updated 9/7/00 ***/ + p->report.Messageflag = TRUE; + p->report.Rptflag = 1; + + /* Initialize global pointers to NULL. */ + initpointers(p); + + /* Open input & report files */ + ERRCODE(openfiles(p, f1, f2, f3)); + if (errcode > 0) { + errmsg(p, errcode); + return set_error(p->error_handle, errcode); + } + writelogo(p); + + /* Find network size & allocate memory for data */ + writecon(FMT02); + writewin(p->viewprog, FMT100); + ERRCODE(netsize(p)); + ERRCODE(allocdata(p)); + + /* Retrieve input data */ + ERRCODE(getdata(p)); + + /* Free temporary linked lists used for Patterns & Curves */ + freeTmplist(p->parser.Patlist); + freeTmplist(p->parser.Curvelist); + + /* If using previously saved hydraulics then open its file */ + if (p->out_files.Hydflag == USE) { + ERRCODE(openhydfile(p)); + } + + /* Write input summary to report file */ + if (!errcode) { + if (p->report.Summaryflag) { + writesummary(p); + } + writetime(p, FMT104); + p->Openflag = TRUE; + } else + errmsg(p, errcode); + + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENclose() { return EN_close(_defaultModel); } + +int DLLEXPORT EN_close(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: frees all memory & files used by EPANET + **---------------------------------------------------------------- + */ +{ + out_file_t *out; + + EN_Project *p = (EN_Project*)ph; + + if (p->Openflag) { + writetime(p, FMT105); + } + freedata(p); + + out = &p->out_files; + + if (out->TmpOutFile != out->OutFile) { + if (out->TmpOutFile != NULL) { + fclose(out->TmpOutFile); + } + remove(out->TmpFname); + } + out->TmpOutFile = NULL; + + if (p->parser.InFile != NULL) { + fclose(p->parser.InFile); + p->parser.InFile = NULL; + } + if (p->report.RptFile != NULL && p->report.RptFile != stdout) { + fclose(p->report.RptFile); + p->report.RptFile = NULL; + } + if (out->HydFile != NULL) { + fclose(out->HydFile); + out->HydFile = NULL; + } + if (out->OutFile != NULL) { + fclose(out->OutFile); + out->OutFile = NULL; + } + + if (out->Hydflag == SCRATCH) + remove(out->HydFname); + if (out->Outflag == SCRATCH) + remove(out->OutFname); + + p->Openflag = FALSE; + p->hydraulics.OpenHflag = FALSE; + p->save_options.SaveHflag = FALSE; + p->quality.OpenQflag = FALSE; + p->save_options.SaveQflag = FALSE; + + return set_error(p->error_handle, 0); +} + + +int DLLEXPORT ENgetnodeindex(char *id, int *index) { + return EN_getnodeindex(_defaultModel, id, index); +} + +int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { + + EN_Project *p = (EN_Project*)ph; + + *index = 0; + if (!p->Openflag) + return set_error(p->error_handle, 102); + *index = findnode(&p->network,id); + if (*index == 0) + return set_error(p->error_handle, 203); + else + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetnodeid(int index, char *id) { + return EN_getnodeid(_defaultModel, index, id); +} + +int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project *p = (EN_Project*)ph; + + strcpy(id, ""); + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Nnodes) + return set_error(p->error_handle, 203); + strcpy(id, p->network.Node[index].ID); + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetnodetype(int index, int *code) { + return EN_getnodetype(_defaultModel, index, code); +} + +int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { + + EN_Project *p = (EN_Project*)ph; + + *code = -1; + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Nnodes) + return set_error(p->error_handle, 203); + if (index <= p->network.Njuncs) + *code = EN_JUNCTION; + else { + if (p->network.Tank[index - p->network.Njuncs].A == 0.0) + *code = EN_RESERVOIR; + else + *code = EN_TANK; + } + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) { + return EN_getnodevalue(_defaultModel, index, code, value); +} + +int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, + EN_API_FLOAT_TYPE *value) { + double v = 0.0; + Pdemand demand; + Psource source; + + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Snode *Node = net->Node; + Stank *Tank = net->Tank; + + const int Nnodes = net->Nnodes; + const int Njuncs = net->Njuncs; + + double *Ucf = p->Ucf; + double *NodeDemand = hyd->NodeDemand; + double *NodeQual = qu->NodeQual; + + + /* Check for valid arguments */ + *value = 0.0; + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index <= 0 || index > Nnodes) + return set_error(p->error_handle, 203); + + /* Retrieve called-for parameter */ + switch (code) { + case EN_ELEVATION: + v = Node[index].El * Ucf[ELEV]; + break; + + case EN_BASEDEMAND: + v = 0.0; + /* NOTE: primary demand category is last on demand list */ + if (index <= Njuncs) + for (demand = Node[index].D; demand != NULL; demand = demand->next) + v = (demand->Base); + v *= Ucf[FLOW]; + break; + + case EN_PATTERN: + v = 0.0; + /* NOTE: primary demand category is last on demand list */ + if (index <= Njuncs) { + for (demand = Node[index].D; demand != NULL; demand = demand->next) + v = (double)(demand->Pat); + } else + v = (double)(Tank[index - Njuncs].Pat); + break; + + case EN_EMITTER: + v = 0.0; + if (Node[index].Ke > 0.0) + v = Ucf[FLOW] / pow((Ucf[PRESSURE] * Node[index].Ke), (1.0 / hyd->Qexp)); + break; + + case EN_INITQUAL: + v = Node[index].C0 * Ucf[QUALITY]; + break; + + /*** Additional parameters added for retrieval ***/ + case EN_SOURCEQUAL: + case EN_SOURCETYPE: + case EN_SOURCEMASS: + case EN_SOURCEPAT: + source = Node[index].S; + if (source == NULL) + return set_error(p->error_handle, 240); + if (code == EN_SOURCEQUAL) + v = source->C0; + else if (code == EN_SOURCEMASS) + v = source->Smass * 60.0; + else if (code == EN_SOURCEPAT) + v = source->Pat; + else + v = source->Type; + break; + + case EN_TANKLEVEL: + if (index <= Njuncs) + return set_error(p->error_handle, 251); + v = (Tank[index - Njuncs].H0 - Node[index].El) * Ucf[ELEV]; + break; + + /*** New parameter added for retrieval ***/ + case EN_INITVOLUME: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].V0 * Ucf[VOLUME]; + break; + + /*** New parameter added for retrieval ***/ + case EN_MIXMODEL: + v = MIX1; + if (index > Njuncs) + v = Tank[index - Njuncs].MixModel; + break; + + /*** New parameter added for retrieval ***/ + case EN_MIXZONEVOL: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].V1max * Ucf[VOLUME]; + break; + + case EN_DEMAND: + v = NodeDemand[index] * Ucf[FLOW]; + break; + + case EN_HEAD: + v = hyd->NodeHead[index] * Ucf[HEAD]; + break; + + case EN_PRESSURE: + v = (hyd->NodeHead[index] - Node[index].El) * Ucf[PRESSURE]; + break; + + case EN_QUALITY: + v = NodeQual[index] * Ucf[QUALITY]; + break; + + /*** New parameters added for retrieval begins here ***/ + /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ + /*** de Montreal for suggesting some of these.) ***/ + + case EN_TANKDIAM: + v = 0.0; + if (index > Njuncs) { + v = sqrt(4.0 / PI * Tank[index - Njuncs].A) * Ucf[ELEV]; + } + break; + + case EN_MINVOLUME: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Vmin * Ucf[VOLUME]; + break; + + case EN_MAXVOLUME: // !sph + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Vmax * Ucf[VOLUME]; + break; + + case EN_VOLCURVE: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Vcurve; + break; + + case EN_MINLEVEL: + v = 0.0; + if (index > Njuncs) { + v = (Tank[index - Njuncs].Hmin - Node[index].El) * Ucf[ELEV]; + } + break; + + case EN_MAXLEVEL: + v = 0.0; + if (index > Njuncs) { + v = (Tank[index - Njuncs].Hmax - Node[index].El) * Ucf[ELEV]; + } + break; + + case EN_MIXFRACTION: + v = 1.0; + if (index > Njuncs && Tank[index - Njuncs].Vmax > 0.0) { + v = Tank[index - Njuncs].V1max / Tank[index - Njuncs].Vmax; + } + break; + + case EN_TANK_KBULK: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Kb * SECperDAY; + break; + + /*** New parameter additions ends here. ***/ + + case EN_TANKVOLUME: + if (index <= Njuncs) + return set_error(p->error_handle, 251); + v = tankvolume(p, index - Njuncs, hyd->NodeHead[index]) * Ucf[VOLUME]; + break; + + default: + return set_error(p->error_handle, 251); + } + *value = (EN_API_FLOAT_TYPE)v; + return set_error(p->error_handle, 0); +} + + +/* + ---------------------------------------------------------------- + Functions for retrieving link data + ---------------------------------------------------------------- + */ + +int DLLEXPORT ENgetlinkindex(char *id, int *index) { + return EN_getlinkindex(_defaultModel, id, index); +} + +int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { + + EN_Project *p = (EN_Project*)ph; + + *index = 0; + if (!p->Openflag) + return set_error(p->error_handle, 102); + *index = findlink(&p->network,id); + if (*index == 0) + return set_error(p->error_handle, 204); + else + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetlinkid(int index, char *id) { + return EN_getlinkid(_defaultModel, index, id); +} + +int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project *p = (EN_Project*)ph; + + strcpy(id, ""); + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Nlinks) + return set_error(p->error_handle, 204); + strcpy(id, p->network.Link[index].ID); + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) { + return EN_getlinktype(_defaultModel, index, code); +} + + +int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { + + EN_Project *p = (EN_Project*)ph; + + *code = -1; + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Nlinks) + return set_error(p->error_handle, 204); + *code = p->network.Link[index].Type; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) { + return EN_getlinknodes(_defaultModel, index, node1, node2); +} + +int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, + int *node2) { + + EN_Project *p = (EN_Project*)ph; + + *node1 = 0; + *node2 = 0; + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Nlinks) + return set_error(p->error_handle, 204); + *node1 = p->network.Link[index].N1; + *node2 = p->network.Link[index].N2; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) { + return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value); +} + +int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, + EN_LinkProperty code, EN_API_FLOAT_TYPE *value) +{ + double a, h, q, v = 0.0; + int returnValue = 0; + + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + + Slink *Link = net->Link; + Spump *Pump = net->Pump; + + const int Nlinks = net->Nlinks; + + double *Ucf = p->Ucf; + double *LinkFlows = hyd->LinkFlows; + double *LinkSetting = hyd->LinkSetting; + + + + /* Check for valid arguments */ + *value = 0.0; + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index <= 0 || index > Nlinks) + return set_error(p->error_handle, 204); + + /* Retrieve called-for parameter */ + switch (code) { + case EN_DIAMETER: + if (Link[index].Type == EN_PUMP) + v = 0.0; + else + v = Link[index].Diam * Ucf[DIAM]; + break; + + case EN_LENGTH: + v = Link[index].Len * Ucf[ELEV]; + break; + + case EN_ROUGHNESS: + if (Link[index].Type <= EN_PIPE) { + if (hyd->Formflag == DW) + v = Link[index].Kc * (1000.0 * Ucf[ELEV]); + else + v = Link[index].Kc; + } else + v = 0.0; + break; + + case EN_MINORLOSS: + if (Link[index].Type != EN_PUMP) { + v = Link[index].Km; + v *= (SQR(Link[index].Diam) * SQR(Link[index].Diam) / 0.02517); + } else + v = 0.0; + break; + + case EN_INITSTATUS: + if (Link[index].Stat <= CLOSED) + v = 0.0; + else + v = 1.0; + break; + + case EN_INITSETTING: + if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) + return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); + v = Link[index].Kc; + switch (Link[index].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + v *= Ucf[PRESSURE]; + break; + case EN_FCV: + v *= Ucf[FLOW]; + default: + break; + } + break; + + case EN_KBULK: + v = Link[index].Kb * SECperDAY; + break; + + case EN_KWALL: + v = Link[index].Kw * SECperDAY; + break; + + case EN_FLOW: + + /*** Updated 10/25/00 ***/ + if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + else + v = LinkFlows[index] * Ucf[FLOW]; + break; + + case EN_VELOCITY: + if (Link[index].Type == EN_PUMP) { + v = 0.0; + } + + /*** Updated 11/19/01 ***/ + else if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + + else { + q = ABS(LinkFlows[index]); + a = PI * SQR(Link[index].Diam) / 4.0; + v = q / a * Ucf[VELOCITY]; + } + break; + + case EN_HEADLOSS: + + /*** Updated 11/19/01 ***/ + if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + + else { + h = hyd->NodeHead[Link[index].N1] - hyd->NodeHead[Link[index].N2]; + if (Link[index].Type != EN_PUMP) + h = ABS(h); + v = h * Ucf[HEADLOSS]; + } + break; + + case EN_STATUS: + if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + else + v = 1.0; + break; + + case EN_SETTING: + if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) { + return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); + } + if (LinkSetting[index] == MISSING) { + v = 0.0; + } else { + v = LinkSetting[index]; + } + switch (Link[index].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + v *= Ucf[PRESSURE]; + break; + case EN_FCV: + v *= Ucf[FLOW]; + default: + break; + } + break; + + case EN_ENERGY: + getenergy(p, index, &v, &a); + break; + + case EN_LINKQUAL: + v = avgqual(p, index) * Ucf[LINKQUAL]; + break; + + case EN_LINKPATTERN: + if (Link[index].Type == EN_PUMP) + v = (double)Pump[findpump(&p->network, index)].Upat; + break; + + case EN_EFFICIENCY: + getenergy(p, index, &a, &v); + break; + + case EN_PRICEPATTERN: + if (Link[index].Type == EN_PUMP) + v = (double)Pump[findpump(&p->network, index)].Epat; + break; + + case EN_HEADCURVE: + if (Link[index].Type == EN_PUMP) { + v = (double)Pump[findpump(&p->network, index)].Hcurve; + if (v == 0) { + returnValue = 226; + } + } + else { + v = 0; + returnValue = 211; + } + break; + + case EN_EFFICIENCYCURVE: + if (Link[index].Type == EN_PUMP) { + v = (double)Pump[findpump(&p->network, index)].Ecurve; + if (v == 0) { + returnValue = 268; + } + } + else { + v = 0; + returnValue = 211; + } + + default: + v = 0; + returnValue = 251; + } + *value = (EN_API_FLOAT_TYPE)v; + + return set_error(p->error_handle, returnValue); +} + + +int DLLEXPORT ENgetpatternindex(char *id, int *index) { + return EN_getpatternindex(_defaultModel, id, index); +} + +int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { + int i; + + EN_Project *p = (EN_Project*)ph; + + *index = 0; + if (!p->Openflag) + return set_error(p->error_handle, 102); + for (i = 1; i <= p->network.Npats; i++) { + if (strcmp(id, p->network.Pattern[i].ID) == 0) { + *index = i; + return set_error(p->error_handle, 0); + } + } + *index = 0; + return set_error(p->error_handle, 205); +} + +int DLLEXPORT ENgetpatternid(int index, char *id) { + return EN_getpatternid(_defaultModel, index, id); +} + +int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project *p = (EN_Project*)ph; + + strcpy(id, ""); + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Npats) + return set_error(p->error_handle, 205); + strcpy(id, p->network.Pattern[index].ID); + return set_error(p->error_handle, 0); +} + + +int DLLEXPORT ENgetpatternlen(int index, int *len) { + return EN_getpatternlen(_defaultModel, index, len); +} + +int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index < 1 || index > p->network.Npats) + return set_error(p->error_handle, 205); + *len = p->network.Pattern[index].Length; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgetpatternvalue(int index, int period, + EN_API_FLOAT_TYPE *value) { + return EN_getpatternvalue(_defaultModel, index, period, value); +} + +int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, + EN_API_FLOAT_TYPE *value) { + + int errorcode = 0; + EN_Project *p = (EN_Project*)ph; + *value = 0.0; + + if (!p->Openflag) + errorcode = 102; + else if (index < 1 || index > p->network.Npats) + errorcode = 205; + else if (period < 1 || period > p->network.Pattern[index].Length) + errorcode = 251; + else + *value = (EN_API_FLOAT_TYPE)p->network.Pattern[index].F[period - 1]; + + return set_error(p->error_handle, errorcode); +} + +/* + ---------------------------------------------------------------- + Functions for retrieving network information + ---------------------------------------------------------------- + */ +int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, + EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) { + return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, level); +} + +int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *lindex, + EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) { + double s, lvl; + + EN_Project *pr = (EN_Project*)ph; + + EN_Network *net = &pr->network; + + Scontrol *Control = net->Control; + Snode *Node = net->Node; + Slink *Link = net->Link; + + const int Njuncs = net->Njuncs; + double *Ucf = pr->Ucf; + + s = 0.0; + lvl = 0.0; + *ctype = 0; + *lindex = 0; + *nindex = 0; + if (!pr->Openflag) + return set_error(pr->error_handle, 102); + if (cindex < 1 || cindex > net->Ncontrols) + return set_error(pr->error_handle, 241); + *ctype = Control[cindex].Type; + *lindex = Control[cindex].Link; + s = Control[cindex].Setting; + if (Control[cindex].Setting != MISSING) { + switch (Link[*lindex].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + s *= Ucf[PRESSURE]; + break; + case EN_FCV: + s *= Ucf[FLOW]; + default: + break; + } + } else if (Control[cindex].Status == OPEN) { + s = 1.0; + } + + /*** Updated 3/1/01 ***/ + else + s = 0.0; + + *nindex = Control[cindex].Node; + if (*nindex > Njuncs) + lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[ELEV]; + else if (*nindex > 0) + lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[PRESSURE]; + else + lvl = (EN_API_FLOAT_TYPE)Control[cindex].Time; + *setting = (EN_API_FLOAT_TYPE)s; + *level = (EN_API_FLOAT_TYPE)lvl; + + return set_error(pr->error_handle, 0); +} + +int DLLEXPORT ENgetcount(int code, int *count) { + return EN_getcount(_defaultModel, (EN_CountType)code, count); +} + +int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { + + EN_Project *pr = (EN_Project*)ph; + + EN_Network *net = &pr->network; + + *count = 0; + if (!pr->Openflag) + return set_error(pr->error_handle, 102); + switch (code) { + case EN_NODECOUNT: + *count = net->Nnodes; + break; + case EN_TANKCOUNT: + *count = net->Ntanks; + break; + case EN_LINKCOUNT: + *count = net->Nlinks; + break; + case EN_PATCOUNT: + *count = net->Npats; + break; + case EN_CURVECOUNT: + *count = net->Ncurves; + break; + case EN_CONTROLCOUNT: + *count = net->Ncontrols; + break; + case EN_RULECOUNT: + *count = net->Nrules; + break; + default: + return set_error(pr->error_handle, 251); + } + return set_error(pr->error_handle, 0); +} + +int DLLEXPORT ENgetflowunits(int *code) { + return EN_getflowunits(_defaultModel, code); +} + +int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { + + EN_Project *p = (EN_Project*)ph; + + *code = -1; + if (!p->Openflag) + return set_error(p->error_handle, 102); + *code = p->parser.Flowflag; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgettimeparam(int code, long *value) { + return EN_gettimeparam(_defaultModel, code, value); +} + +int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { + int i; + + EN_Project *pr = (EN_Project*)ph; + + report_options_t *rep = &pr->report; + quality_t *qu = &pr->quality; + time_options_t *time = &pr->time_options; + + + *value = 0; + if (!pr->Openflag) + return set_error(pr->error_handle, 102); + if (code < EN_DURATION || code > EN_NEXTEVENTIDX) + return set_error(pr->error_handle, 251); + switch (code) { + case EN_DURATION: + *value = time->Dur; + break; + case EN_HYDSTEP: + *value = time->Hstep; + break; + case EN_QUALSTEP: + *value = qu->Qstep; + break; + case EN_PATTERNSTEP: + *value = time->Pstep; + break; + case EN_PATTERNSTART: + *value = time->Pstart; + break; + case EN_REPORTSTEP: + *value = time->Rstep; + break; + case EN_REPORTSTART: + *value = time->Rstart; + break; + case EN_STATISTIC: + *value = rep->Tstatflag; + break; + case EN_RULESTEP: + *value = time->Rulestep; + break; + case EN_PERIODS: + *value = rep->Nperiods; + break; + case EN_STARTTIME: + *value = time->Tstart; + break; /* Added TNT 10/2/2009 */ + case EN_HTIME: + *value = time->Htime; + break; + case EN_NEXTEVENT: + *value = time->Hstep; // find the lesser of the hydraulic time step length, or the + // time to next fill/empty + tanktimestep(pr,value); + break; + case EN_NEXTEVENTIDX: + *value = time->Hstep; + i = tanktimestep(pr, value); + *value = i; + break; + } + return set_error(pr->error_handle, 0); +} + + +int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) { + return EN_getoption(_defaultModel, (EN_Option)code, value); +} + +int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, + EN_API_FLOAT_TYPE *value) { + + EN_Project *pr = (EN_Project*)ph; + + hydraulics_t *hyd = &pr->hydraulics; + quality_t *qu = &pr->quality; + double *Ucf = pr->Ucf; + + double v = 0.0; + *value = 0.0; + if (!pr->Openflag) + return set_error(pr->error_handle,102); + switch (code) { + case EN_TRIALS: + v = (double)hyd->MaxIter; + break; + case EN_ACCURACY: + v = hyd->Hacc; + break; + case EN_TOLERANCE: + v = qu->Ctol * Ucf[QUALITY]; + break; + case EN_EMITEXPON: + if (hyd->Qexp > 0.0) + v = 1.0 / hyd->Qexp; + break; + case EN_DEMANDMULT: + v = hyd->Dmult; + break; + + case EN_HEADERROR: + v = hyd->HeadErrorLimit * Ucf[HEAD]; + break; + case EN_FLOWCHANGE: + v = hyd->FlowChangeLimit * Ucf[FLOW]; + break; + + default: + return set_error(pr->error_handle, 251); + } + *value = (EN_API_FLOAT_TYPE)v; + + return set_error(pr->error_handle, 0); +} + +int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); } + +int DLLEXPORT EN_getversion(int *v) +/*---------------------------------------------------------------- + ** Input: none + ** Output: *v = version number of the source code + ** Returns: error code (should always be 0) + ** Purpose: retrieves a number assigned to the most recent + ** update of the source code. This number, set by the + ** constant CODEVERSION found in TYPES.H, is to be + ** interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" + **---------------------------------------------------------------- + */ +{ + *v = CODEVERSION; + return (0); +} + + +/* + ---------------------------------------------------------------- + Functions for changing network data + ---------------------------------------------------------------- + */ +int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, + EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) { + return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, level); +} + +int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, + EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) { + + char status = ACTIVE; + long t = 0; + double s = setting, lvl = level; + EN_Network *net; + Snode *Node; + Slink *Link; + Scontrol *Control; + + int Nnodes; + int Njuncs; + int Nlinks; + double *Ucf; + + EN_Project *p = (EN_Project*)ph; + + /* Check that input file opened */ + if (!p->Openflag) + return set_error(p->error_handle, 102); + + /* Check that control exists */ + if (cindex < 1 || cindex > p->network.Ncontrols) + return set_error(p->error_handle, 241); + + + net = &p->network; + + Node = net->Node; + Link = net->Link; + Control = net->Control; + + Nnodes = net->Nnodes; + Njuncs = net->Njuncs; + Nlinks = net->Nlinks; + + Ucf = p->Ucf; + + /* Check that controlled link exists */ + if (lindex == 0) { + Control[cindex].Link = 0; + return set_error(p->error_handle, 0); + } + if (lindex < 0 || lindex > Nlinks) + return set_error(p->error_handle, 204); + + /* Cannot control check valve. */ + if (Link[lindex].Type == EN_CVPIPE) + return set_error(p->error_handle, 207); + + /* Check for valid parameters */ + if (ctype < 0 || ctype > EN_TIMEOFDAY) + return set_error(p->error_handle, 251); + if (ctype == EN_LOWLEVEL || ctype == EN_HILEVEL) { + if (nindex < 1 || nindex > Nnodes) + return set_error(p->error_handle, 203); + } else + nindex = 0; + if (s < 0.0 || lvl < 0.0) + return set_error(p->error_handle, 202); + + /* Adjust units of control parameters */ + switch (Link[lindex].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + s /= Ucf[PRESSURE]; + break; + case EN_FCV: + s /= Ucf[FLOW]; + break; + + /*** Updated 9/7/00 ***/ + case EN_GPV: + if (s == 0.0) + status = CLOSED; + else if (s == 1.0) + status = OPEN; + else + return set_error(p->error_handle, 202); + s = Link[lindex].Kc; + break; + + case EN_PIPE: + case EN_PUMP: + status = OPEN; + if (s == 0.0) + status = CLOSED; + default: + break; + } + if (ctype == LOWLEVEL || ctype == HILEVEL) { + if (nindex > Njuncs) + lvl = Node[nindex].El + level / Ucf[ELEV]; + else + lvl = Node[nindex].El + level / Ucf[PRESSURE]; + } + if (ctype == TIMER) + t = (long)ROUND(lvl); + if (ctype == TIMEOFDAY) + t = (long)ROUND(lvl) % SECperDAY; + + /* Reset control's parameters */ + Control[cindex].Type = (char)ctype; + Control[cindex].Link = lindex; + Control[cindex].Node = nindex; + Control[cindex].Status = status; + Control[cindex].Setting = s; + Control[cindex].Grade = lvl; + Control[cindex].Time = t; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) { + return EN_setnodevalue(_defaultModel, index, code, v); +} + +int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) +/*---------------------------------------------------------------- + ** Input: index = node index + ** code = node parameter code (see EPANET2.H) + ** value = parameter value + ** Output: none + ** Returns: error code + ** Purpose: sets input parameter value for a node + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Snode *Node = net->Node; + Stank *Tank = net->Tank; + + const int Nnodes = net->Nnodes; + const int Njuncs = net->Njuncs; + const int Npats = net->Npats; + + double *Ucf = p->Ucf; + + int j; + Pdemand demand; + Psource source; + double Htmp; + double value = v; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index <= 0 || index > Nnodes) + return set_error(p->error_handle, 203); + switch (code) { + case EN_ELEVATION: + if (index <= Njuncs) + Node[index].El = value / Ucf[ELEV]; + else { + value = (value / Ucf[ELEV]) - Node[index].El; + j = index - Njuncs; + Tank[j].H0 += value; + Tank[j].Hmin += value; + Tank[j].Hmax += value; + Node[index].El += value; + hyd->NodeHead[index] += value; + } + break; + + case EN_BASEDEMAND: + /* NOTE: primary demand category is last on demand list */ + if (index <= Njuncs) { + for (demand = Node[index].D; demand != NULL; demand = demand->next) { + if (demand->next == NULL) + demand->Base = value / Ucf[FLOW]; + } + } + break; + + case EN_PATTERN: + /* NOTE: primary demand category is last on demand list */ + j = ROUND(value); + if (j < 0 || j > Npats) + return (205); + if (index <= Njuncs) { + for (demand = Node[index].D; demand != NULL; demand = demand->next) { + if (demand->next == NULL) + demand->Pat = j; + } + } else + Tank[index - Njuncs].Pat = j; + break; + + case EN_EMITTER: + if (index > Njuncs) + return set_error(p->error_handle, 203); + if (value < 0.0) + return set_error(p->error_handle, 202); + if (value > 0.0) + value = pow((Ucf[FLOW] / value), hyd->Qexp) / Ucf[PRESSURE]; + Node[index].Ke = value; + break; + + case EN_INITQUAL: + if (value < 0.0) + return set_error(p->error_handle, 202); + Node[index].C0 = value / Ucf[QUALITY]; + if (index > Njuncs) + Tank[index - Njuncs].C = Node[index].C0; + break; + + case EN_SOURCEQUAL: + case EN_SOURCETYPE: + case EN_SOURCEPAT: + if (value < 0.0) + return set_error(p->error_handle, 202); + source = Node[index].S; + if (source == NULL) { + source = (struct Ssource *)malloc(sizeof(struct Ssource)); + if (source == NULL) + return set_error(p->error_handle, 101); + source->Type = CONCEN; + source->C0 = 0.0; + source->Pat = 0; + Node[index].S = source; + } + if (code == EN_SOURCEQUAL) { + source->C0 = value; + } else if (code == EN_SOURCEPAT) { + j = ROUND(value); + if (j < 0 || j > Npats) + return set_error(p->error_handle, 205); + source->Pat = j; + } else // code == EN_SOURCETYPE + { + j = ROUND(value); + if (j < CONCEN || j > FLOWPACED) + return set_error(p->error_handle, 251); + else + source->Type = (char)j; + } + return (0); + + case EN_TANKLEVEL: + if (index <= Njuncs) + return set_error(p->error_handle, 251); + j = index - Njuncs; + if (Tank[j].A == 0.0) /* Tank is a reservoir */ + { + Tank[j].H0 = value / Ucf[ELEV]; + Tank[j].Hmin = Tank[j].H0; + Tank[j].Hmax = Tank[j].H0; + Node[index].El = Tank[j].H0; + hyd->NodeHead[index] = Tank[j].H0; + } else { + value = Node[index].El + value / Ucf[ELEV]; + if (value > Tank[j].Hmax || value < Tank[j].Hmin) + return set_error(p->error_handle, 202); + Tank[j].H0 = value; + Tank[j].V0 = tankvolume(p, j, Tank[j].H0); + // Resetting Volume in addition to initial volume + Tank[j].V = Tank[j].V0; + hyd->NodeHead[index] = Tank[j].H0; + } + break; + + /*** New parameters added for retrieval begins here ***/ + /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ + /*** de Montreal for suggesting some of these.) ***/ + + case EN_TANKDIAM: + if (value <= 0.0) + return set_error(p->error_handle, 202); + if (index <= Njuncs) + return set_error(p->error_handle, 251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + value /= Ucf[ELEV]; + Tank[j].A = PI * SQR(value) / 4.0; + Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); + Tank[j].V0 = tankvolume(p, j, Tank[j].H0); + Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); + } else { + return set_error(p->error_handle, 251); + } + break; + + case EN_MINVOLUME: + if (value < 0.0) + return set_error(p->error_handle, 202); + if (index <= Njuncs) + return set_error(p->error_handle, 251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + Tank[j].Vmin = value / Ucf[VOLUME]; + Tank[j].V0 = tankvolume(p, j, Tank[j].H0); + Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); + } else { + return set_error(p->error_handle, 251); + } + break; + + case EN_MINLEVEL: + if (value < 0.0) + return set_error(p->error_handle, 202); + if (index <= Njuncs) + return set_error(p->error_handle, 251); // not a tank or reservoir + j = index - Njuncs; + if (Tank[j].A == 0.0) + return set_error(p->error_handle, 251); // node is a reservoir + Htmp = value / Ucf[ELEV] + Node[index].El; + if (Htmp < Tank[j].Hmax && Htmp <= Tank[j].H0) { + if (Tank[j].Vcurve > 0) + return set_error(p->error_handle, 202); + Tank[j].Hmin = Htmp; + Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); + } else { + return set_error(p->error_handle, 251); + } + break; + + case EN_MAXLEVEL: + if (value < 0.0) + return set_error(p->error_handle, 202); + if (index <= Njuncs) + return set_error(p->error_handle, 251); // not a tank or reservoir + j = index - Njuncs; + if (Tank[j].A == 0.0) + return set_error(p->error_handle, 251); // node is a reservoir + Htmp = value / Ucf[ELEV] + Node[index].El; + if (Htmp > Tank[j].Hmin && Htmp >= Tank[j].H0) { + if (Tank[j].Vcurve > 0) + return set_error(p->error_handle, 202); + Tank[j].Hmax = Htmp; + Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); + } else { + return set_error(p->error_handle, 251); + } + break; + + case EN_MIXMODEL: + j = ROUND(value); + if (index <= Njuncs) + return set_error(p->error_handle, 251); + if (j < MIX1 || j > LIFO) + return set_error(p->error_handle, 202); + if (index > Njuncs && Tank[index - Njuncs].A > 0.0) { + Tank[index - Njuncs].MixModel = (char)j; + } else { + return set_error(p->error_handle, 251); + } + break; + + case EN_MIXFRACTION: + if (value < 0.0 || value > 1.0) + return set_error(p->error_handle, 202); + if (index <= Njuncs) + return set_error(p->error_handle, 251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + Tank[j].V1max = value * Tank[j].Vmax; + } + break; + + case EN_TANK_KBULK: + if (index <= Njuncs) + return set_error(p->error_handle, 251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + Tank[j].Kb = value / SECperDAY; + qu->Reactflag = 1; + } else { + return set_error(p->error_handle, 251); + } + break; + + /*** New parameter additions ends here. ***/ + + default: + return set_error(p->error_handle, 251); + } + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) { + return EN_setlinkvalue(_defaultModel, index, code, v); +} + +int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, + EN_API_FLOAT_TYPE v) +/*---------------------------------------------------------------- + ** Input: index = link index + ** code = link parameter code (see EPANET2.H) + ** v = parameter value + ** Output: none + ** Returns: error code + ** Purpose: sets input parameter value for a link + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Slink *Link = net->Link; + + const int Nlinks = net->Nlinks; + + double *Ucf = p->Ucf; + double *LinkSetting = hyd->LinkSetting; + + char s; + double r, value = v; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index <= 0 || index > Nlinks) + return set_error(p->error_handle, 204); + switch (code) { + case EN_DIAMETER: + if (Link[index].Type != EN_PUMP) { + if (value <= 0.0) + return set_error(p->error_handle, 202); + value /= Ucf[DIAM]; /* Convert to feet */ + r = Link[index].Diam / value; /* Ratio of old to new diam */ + Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */ + Link[index].Diam = value; /* Update diameter */ + resistcoeff(p, index); /* Update resistance coeff. */ + } + break; + + case EN_LENGTH: + if (Link[index].Type <= EN_PIPE) { + if (value <= 0.0) + return set_error(p->error_handle, 202); + Link[index].Len = value / Ucf[ELEV]; + resistcoeff(p, index); + } + break; + + case EN_ROUGHNESS: + if (Link[index].Type <= EN_PIPE) { + if (value <= 0.0) + return set_error(p->error_handle, 202); + Link[index].Kc = value; + if (hyd->Formflag == DW) + Link[index].Kc /= (1000.0 * Ucf[ELEV]); + resistcoeff(p, index); + } + break; + + case EN_MINORLOSS: + if (Link[index].Type != EN_PUMP) { + if (value <= 0.0) + return set_error(p->error_handle, 202); + Link[index].Km = + 0.02517 * value / SQR(Link[index].Diam) / SQR(Link[index].Diam); + } + break; + + case EN_INITSTATUS: + case EN_STATUS: + /* Cannot set status for a check valve */ + if (Link[index].Type == EN_CVPIPE) + return set_error(p->error_handle, 207); + s = (char)ROUND(value); + if (s < 0 || s > 1) + return set_error(p->error_handle, 251); + if (code == EN_INITSTATUS) + setlinkstatus(p, index, s, &Link[index].Stat, &Link[index].Kc); + else + setlinkstatus(p, index, s, &hyd->LinkStatus[index], &LinkSetting[index]); + break; + + case EN_INITSETTING: + case EN_SETTING: + if (value < 0.0) + return set_error(p->error_handle, 202); + if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) + return (ENsetlinkvalue(index, EN_ROUGHNESS, v)); + else { + switch (Link[index].Type) { + case EN_PUMP: + break; + case EN_PRV: + case EN_PSV: + case EN_PBV: + value /= Ucf[PRESSURE]; + break; + case EN_FCV: + value /= Ucf[FLOW]; + break; + case EN_TCV: + break; + + /*** Updated 9/7/00 ***/ + case EN_GPV: + return set_error(p->error_handle, 202); /* Cannot modify setting for GPV */ + + default: + return set_error(p->error_handle, 251); + } + if (code == EN_INITSETTING) + setlinksetting(p, index, value, &Link[index].Stat, &Link[index].Kc); + else + setlinksetting(p, index, value, &hyd->LinkStatus[index], + &LinkSetting[index]); + } + break; + + case EN_KBULK: + if (Link[index].Type <= EN_PIPE) { + Link[index].Kb = value / SECperDAY; + qu->Reactflag = 1; + } + break; + + case EN_KWALL: + if (Link[index].Type <= EN_PIPE) { + Link[index].Kw = value / SECperDAY; + qu->Reactflag = 1; + } + break; + + default: + return set_error(p->error_handle, 251); + } + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) { + return EN_setpattern(_defaultModel, index, f, n); +} + +int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { + int j; + + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + Spattern *Pattern = net->Pattern; + const int Npats = net->Npats; + + + /* Check for valid arguments */ + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (index <= 0 || index > Npats) + return set_error(p->error_handle, 205); + if (n <= 0) + return set_error(p->error_handle, 202); + + /* Re-set number of time periods & reallocate memory for multipliers */ + Pattern[index].Length = n; + Pattern[index].F = (double *)realloc(Pattern[index].F, n * sizeof(double)); + if (Pattern[index].F == NULL) + return set_error(p->error_handle, 101); + + /* Load multipliers into pattern */ + for (j = 0; j < n; j++) + Pattern[index].F[j] = f[j]; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value) { + return EN_setpatternvalue(_defaultModel, index, period, value); +} + +int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, + EN_API_FLOAT_TYPE value) { + int errorcode = 0; + + EN_Project *p = (EN_Project*)ph; + EN_Network *net = &p->network; + + Spattern *Pattern = net->Pattern; + const int Npats = net->Npats; + + + if (!p->Openflag) + errorcode = 102; + else if (index <= 0 || index > Npats) + errorcode = 205; + else if (period <= 0 || period > Pattern[index].Length) + errorcode = 251; + else + Pattern[index].F[period - 1] = value; + + return set_error(p->error_handle, errorcode); +} + +int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode) { + return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits, tracenode); +} + +int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, + char *chemunits, char *tracenode) { + + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + report_options_t *rep = &p->report; + quality_t *qu = &p->quality; + + double *Ucf = p->Ucf; + int i; + + /*** Updated 3/1/01 ***/ + double ccf = 1.0; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (qualcode < EN_NONE || qualcode > EN_TRACE) + return set_error(p->error_handle, 251); + qu->Qualflag = (char)qualcode; + qu->Ctol *= Ucf[QUALITY]; + if (qu->Qualflag == CHEM) /* Chemical constituent */ + { + strncpy(qu->ChemName, chemname, MAXID); + strncpy(qu->ChemUnits, chemunits, MAXID); + + /*** Updated 3/1/01 ***/ + strncpy(rep->Field[QUALITY].Units, qu->ChemUnits, MAXID); + strncpy(rep->Field[REACTRATE].Units, qu->ChemUnits, MAXID); + strcat(rep->Field[REACTRATE].Units, t_PERDAY); + ccf = 1.0 / LperFT3; + } + if (qu->Qualflag == TRACE) /* Source tracing option */ + { + qu->TraceNode = findnode(net,tracenode); + if (qu->TraceNode == 0) + return set_error(p->error_handle, 203); + strncpy(qu->ChemName, u_PERCENT, MAXID); + strncpy(qu->ChemUnits, tracenode, MAXID); + + /*** Updated 3/1/01 ***/ + strcpy(rep->Field[QUALITY].Units, u_PERCENT); + } + if (qu->Qualflag == AGE) /* Water age analysis */ + { + strncpy(qu->ChemName, w_AGE, MAXID); + strncpy(qu->ChemUnits, u_HOURS, MAXID); + + /*** Updated 3/1/01 ***/ + strcpy(rep->Field[QUALITY].Units, u_HOURS); + } + + /* when changing from CHEM to AGE or TRACE, nodes initial quality values must be returned to their original ones */ + if ((qu->Qualflag == AGE || qu->Qualflag == TRACE) & (Ucf[QUALITY] != 1)) { + for (i=1; i<=p->network.Nnodes; i++) { + p->network.Node[i].C0 *= Ucf[QUALITY]; + } + } + + /*** Updated 3/1/01 ***/ + Ucf[QUALITY] = ccf; + Ucf[LINKQUAL] = ccf; + Ucf[REACTRATE] = ccf; + qu->Ctol /= Ucf[QUALITY]; + + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsettimeparam(int code, long value) { + return EN_settimeparam(_defaultModel, code, value); +} + +int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) +{ + EN_Project *p = (EN_Project*)ph; + + report_options_t *rep = &p->report; + quality_t *qu = &p->quality; + time_options_t *time = &p->time_options; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (p->hydraulics.OpenHflag || p->quality.OpenQflag) { + // --> there's nothing wrong with changing certain time parameters during a + // simulation run, or before the run has started. + // todo -- how to tell? + /* + if (code == EN_DURATION || code == EN_HTIME || code == EN_REPORTSTEP || + code == EN_DURATION || Htime == 0) { + // it's ok + } + else { + return(109); + } + */ + } + if (value < 0) + return set_error(p->error_handle, 202); + switch (code) { + case EN_DURATION: + time->Dur = value; + if (time->Rstart > time->Dur) + time->Rstart = 0; + break; + + case EN_HYDSTEP: + if (value == 0) + return set_error(p->error_handle, 202); + time->Hstep = value; + time->Hstep = MIN(time->Pstep, time->Hstep); + time->Hstep = MIN(time->Rstep, time->Hstep); + qu->Qstep = MIN(qu->Qstep, time->Hstep); + break; + + case EN_QUALSTEP: + if (value == 0) + return set_error(p->error_handle, 202); + qu->Qstep = value; + qu->Qstep = MIN(qu->Qstep, time->Hstep); + break; + + case EN_PATTERNSTEP: + if (value == 0) + return set_error(p->error_handle, 202); + time->Pstep = value; + if (time->Hstep > time->Pstep) + time->Hstep = time->Pstep; + break; + + case EN_PATTERNSTART: + time->Pstart = value; + break; + + case EN_REPORTSTEP: + if (value == 0) + return set_error(p->error_handle, 202); + time->Rstep = value; + if (time->Hstep > time->Rstep) + time->Hstep = time->Rstep; + break; + + case EN_REPORTSTART: + if (time->Rstart > time->Dur) + return set_error(p->error_handle, 202); + time->Rstart = value; + break; + + case EN_RULESTEP: + if (value == 0) + return set_error(p->error_handle, 202); + time->Rulestep = value; + time->Rulestep = MIN(time->Rulestep, time->Hstep); + break; + + case EN_STATISTIC: + if (value > RANGE) + return set_error(p->error_handle, 202); + rep->Tstatflag = (char)value; + break; + + case EN_HTIME: + time->Htime = value; + break; + + case EN_QTIME: + qu->Qtime = value; + break; + + default: + return set_error(p->error_handle, 251); + } + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) { + return EN_setoption(_defaultModel, code, v); +} + +int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) +/*---------------------------------------------------------------- + ** Input: code = option code (see EPANET2.H) + ** v = option value + ** Output: none + ** Returns: error code + ** Purpose: sets value for an analysis option + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Snode *Node = net->Node; + const int Njuncs = net->Njuncs; + + double *Ucf = p->Ucf; + + int i, j; + double Ke, n, ucf, value = v; + if (!p->Openflag) + return set_error(p->error_handle, 102); + switch (code) { + case EN_TRIALS: + if (value < 1.0) + return set_error(p->error_handle, 202); + hyd->MaxIter = (int)value; + break; + case EN_ACCURACY: + if (value < 1.e-5 || value > 1.e-1) + return set_error(p->error_handle, 202); + hyd->Hacc = value; + break; + case EN_TOLERANCE: + if (value < 0.0) + return set_error(p->error_handle, 202); + qu->Ctol = value / Ucf[QUALITY]; + break; + case EN_EMITEXPON: + if (value <= 0.0) + return set_error(p->error_handle, 202); + n = 1.0 / value; + ucf = pow(Ucf[FLOW], n) / Ucf[PRESSURE]; + for (i = 1; i <= Njuncs; i++) { + j = ENgetnodevalue(i, EN_EMITTER, &v); + Ke = v; + if (j == 0 && Ke > 0.0) + Node[i].Ke = ucf / pow(Ke, n); + } + hyd->Qexp = n; + break; + case EN_DEMANDMULT: + if (value <= 0.0) + return set_error(p->error_handle, 202); + hyd->Dmult = value; + break; + + case EN_HEADERROR: + if (value < 0.0) + return set_error(p->error_handle, 202); + hyd->HeadErrorLimit = value / Ucf[HEAD]; + break; + case EN_FLOWCHANGE: + if (value < 0.0) + return set_error(p->error_handle, 202); + hyd->FlowChangeLimit = value / Ucf[FLOW]; + break; + + default: + return set_error(p->error_handle, 251); + } + return set_error(p->error_handle, 0); +} + + +int DLLEXPORT ENsavehydfile(char *filename) { + return EN_savehydfile(_defaultModel, filename); +} + +int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { + FILE *f; + int c; + FILE *HydFile; + + EN_Project *p = (EN_Project*)ph; + + /* Check that hydraulics results exist */ + if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) + return set_error(p->error_handle, 104); + + /* Open file */ + if ((f = fopen(filename, "w+b")) == NULL) + return set_error(p->error_handle, 305); + + /* Copy from HydFile to f */ + HydFile = p->out_files.HydFile; + fseek(HydFile, 0, SEEK_SET); + while ((c = fgetc(HydFile)) != EOF) { + fputc(c, f); + } + fclose(f); + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENusehydfile(char *filename) { + return EN_usehydfile(_defaultModel, filename); +} + +int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + /* Check that input data exists & hydraulics system closed */ + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (p->hydraulics.OpenHflag) + return set_error(p->error_handle, 108); + + /* Try to open hydraulics file */ + strncpy(p->out_files.HydFname, filename, MAXFNAME); + p->out_files.Hydflag = USE; + p->save_options.SaveHflag = TRUE; + errcode = openhydfile(p); + + /* If error, then reset flags */ + if (errcode) { + strcpy(p->out_files.HydFname, ""); + p->out_files.Hydflag = SCRATCH; + p->save_options.SaveHflag = FALSE; + } + return set_error(p->error_handle, errcode); +} + + +int DLLEXPORT ENaddpattern(char *id) { + return EN_addpattern(_defaultModel, id); } int DLLEXPORT ENsaveinpfile(char *filename) { return EN_saveinpfile(_defaultModel, filename); } -int DLLEXPORT ENclose() { return EN_close(_defaultModel); } + int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } @@ -200,13 +2194,7 @@ int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } -int DLLEXPORT ENsavehydfile(char *filename) { - return EN_savehydfile(_defaultModel, filename); -} -int DLLEXPORT ENusehydfile(char *filename) { - return EN_usehydfile(_defaultModel, filename); -} int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } @@ -234,51 +2222,14 @@ int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } -int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); } -int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, - EN_API_FLOAT_TYPE *setting, int *nindex, - EN_API_FLOAT_TYPE *level) { - return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, - level); -} -int DLLEXPORT ENgetcount(int code, int *count) { - return EN_getcount(_defaultModel, (EN_CountType)code, count); -} - -int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) { - return EN_getoption(_defaultModel, (EN_Option)code, value); -} - -int DLLEXPORT ENgettimeparam(int code, long *value) { - return EN_gettimeparam(_defaultModel, code, value); -} - -int DLLEXPORT ENgetflowunits(int *code) { - return EN_getflowunits(_defaultModel, code); -} int DLLEXPORT ENsetflowunits(int code) { return EN_setflowunits(_defaultModel, code); } -int DLLEXPORT ENgetpatternindex(char *id, int *index) { - return EN_getpatternindex(_defaultModel, id, index); -} -int DLLEXPORT ENgetpatternid(int index, char *id) { - return EN_getpatternid(_defaultModel, index, id); -} - -int DLLEXPORT ENgetpatternlen(int index, int *len) { - return EN_getpatternlen(_defaultModel, index, len); -} - -int DLLEXPORT ENgetpatternvalue(int index, int period, - EN_API_FLOAT_TYPE *value) { - return EN_getpatternvalue(_defaultModel, index, period, value); -} int DLLEXPORT ENgetcurveindex(char *id, int *index) { return EN_getcurveindex(_defaultModel, id, index); @@ -315,17 +2266,7 @@ int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) { return EN_getstatistic(_defaultModel, code, value); } -int DLLEXPORT ENgetnodeindex(char *id, int *index) { - return EN_getnodeindex(_defaultModel, id, index); -} -int DLLEXPORT ENgetnodeid(int index, char *id) { - return EN_getnodeid(_defaultModel, index, id); -} - -int DLLEXPORT ENgetnodetype(int index, int *code) { - return EN_getnodetype(_defaultModel, index, code); -} int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { @@ -336,29 +2277,6 @@ int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { return EN_setcoord(_defaultModel, index, x, y); } -int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) { - return EN_getnodevalue(_defaultModel, index, code, value); -} - -int DLLEXPORT ENgetlinkindex(char *id, int *index) { - return EN_getlinkindex(_defaultModel, id, index); -} - -int DLLEXPORT ENgetlinkid(int index, char *id) { - return EN_getlinkid(_defaultModel, index, id); -} - -int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) { - return EN_getlinktype(_defaultModel, index, code); -} - -int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) { - return EN_getlinknodes(_defaultModel, index, node1, node2); -} - -int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) { - return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value); -} int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues, EN_API_FLOAT_TYPE **xValues, @@ -366,33 +2284,9 @@ int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues, return EN_getcurve(_defaultModel, curveIndex, id, nValues, xValues, yValues); } -int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, - EN_API_FLOAT_TYPE setting, int nindex, - EN_API_FLOAT_TYPE level) { - return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, - level); -} -int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) { - return EN_setnodevalue(_defaultModel, index, code, v); -} -int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) { - return EN_setlinkvalue(_defaultModel, index, code, v); -} -int DLLEXPORT ENaddpattern(char *id) { - return EN_addpattern(_defaultModel, id); -} - -int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) { - return EN_setpattern(_defaultModel, index, f, n); -} - -int DLLEXPORT ENsetpatternvalue(int index, int period, - EN_API_FLOAT_TYPE value) { - return EN_setpatternvalue(_defaultModel, index, period, value); -} int DLLEXPORT ENaddcurve(char *id) { return EN_addcurve(_defaultModel, id); } @@ -406,23 +2300,15 @@ int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, return EN_setcurvevalue(_defaultModel, index, pnt, x, y); } -int DLLEXPORT ENsettimeparam(int code, long value) { - return EN_settimeparam(_defaultModel, code, value); -} -int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) { - return EN_setoption(_defaultModel, code, v); -} + + int DLLEXPORT ENsetstatusreport(int code) { return EN_setstatusreport(_defaultModel, code); } -int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, - char *tracenode) { - return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits, - tracenode); -} + int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex) { return EN_getheadcurveindex(_defaultModel, index, curveindex); @@ -573,25 +2459,7 @@ int DLLEXPORT EN_free(EN_ProjectHandle *ph) return 0; } -int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, - const char *f3, void(*pviewprog)(char *)) -{ - int errcode = 0; - EN_Project *_p = (EN_Project*)ph; - ERRCODE(EN_open(ph, f1, f2, f3)); - - _p->viewprog = pviewprog; - if (_p->out_files.Hydflag != USE) { - ERRCODE(EN_solveH(ph)); - } - - ERRCODE(EN_solveQ(ph)); - ERRCODE(EN_report(ph)); - EN_close(ph); - - return set_error(_p->error_handle, errcode); -} int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula) @@ -655,80 +2523,7 @@ int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, return (errcode); } -int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3) -/*---------------------------------------------------------------- - ** Input: f1 = pointer to name of input file - ** f2 = pointer to name of report file - ** f3 = pointer to name of binary output file - ** Output: none - ** Returns: error code - ** Purpose: opens EPANET input file & reads in network data - **---------------------------------------------------------------- - */ -{ - int errcode = 0; -/*** Updated 9/7/00 ***/ -/* Reset math coprocessor */ -#ifdef DLL - _fpreset(); -#endif - - EN_Project *p = (EN_Project*)ph; - - /* Set system flags */ - p->Openflag = FALSE; - p->hydraulics.OpenHflag = FALSE; - p->quality.OpenQflag = FALSE; - p->save_options.SaveHflag = FALSE; - p->save_options.SaveQflag = FALSE; - p->Warnflag = FALSE; - p->parser.Coordflag = TRUE; - - /*** Updated 9/7/00 ***/ - p->report.Messageflag = TRUE; - p->report.Rptflag = 1; - - /* Initialize global pointers to NULL. */ - initpointers(p); - - /* Open input & report files */ - ERRCODE(openfiles(p, f1, f2, f3)); - if (errcode > 0) { - errmsg(p, errcode); - return (errcode); - } - writelogo(p); - - /* Find network size & allocate memory for data */ - writecon(FMT02); - writewin(p->viewprog, FMT100); - ERRCODE(netsize(p)); - ERRCODE(allocdata(p)); - - /* Retrieve input data */ - ERRCODE(getdata(p)); - - /* Free temporary linked lists used for Patterns & Curves */ - freeTmplist(p->parser.Patlist); - freeTmplist(p->parser.Curvelist); - - /* If using previously saved hydraulics then open its file */ - if (p->out_files.Hydflag == USE) { - ERRCODE(openhydfile(p)); - } - - /* Write input summary to report file */ - if (!errcode) { - if (p->report.Summaryflag) { - writesummary(p); - } - writetime(p, FMT104); - p->Openflag = TRUE; - } else - errmsg(p, errcode); - return (errcode); -} int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) /*---------------------------------------------------------------- @@ -746,63 +2541,7 @@ int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) return (saveinpfile(p, filename)); } -int DLLEXPORT EN_close(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: frees all memory & files used by EPANET - **---------------------------------------------------------------- - */ -{ - out_file_t *out; - EN_Project *p = (EN_Project*)ph; - - if (p->Openflag) { - writetime(p, FMT105); - } - freedata(p); - - out = &p->out_files; - - if (out->TmpOutFile != out->OutFile) { - if (out->TmpOutFile != NULL) { - fclose(out->TmpOutFile); - } - remove(out->TmpFname); - } - out->TmpOutFile = NULL; - - if (p->parser.InFile != NULL) { - fclose(p->parser.InFile); - p->parser.InFile = NULL; - } - if (p->report.RptFile != NULL && p->report.RptFile != stdout) { - fclose(p->report.RptFile); - p->report.RptFile = NULL; - } - if (out->HydFile != NULL) { - fclose(out->HydFile); - out->HydFile = NULL; - } - if (out->OutFile != NULL) { - fclose(out->OutFile); - out->OutFile = NULL; - } - - if (out->Hydflag == SCRATCH) - remove(out->HydFname); - if (out->Outflag == SCRATCH) - remove(out->OutFname); - - p->Openflag = FALSE; - p->hydraulics.OpenHflag = FALSE; - p->save_options.SaveHflag = FALSE; - p->quality.OpenQflag = FALSE; - p->save_options.SaveQflag = FALSE; - return (0); -} /* ---------------------------------------------------------------- @@ -1029,56 +2768,7 @@ int DLLEXPORT EN_closeH(EN_ProjectHandle ph) return (0); } -int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { - FILE *f; - int c; - FILE *HydFile; - - EN_Project *p = (EN_Project*)ph; - /* Check that hydraulics results exist */ - if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) - return (104); - - /* Open file */ - if ((f = fopen(filename, "w+b")) == NULL) - return (305); - - /* Copy from HydFile to f */ - HydFile = p->out_files.HydFile; - fseek(HydFile, 0, SEEK_SET); - while ((c = fgetc(HydFile)) != EOF) { - fputc(c, f); - } - fclose(f); - return (0); -} - -int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - /* Check that input data exists & hydraulics system closed */ - if (!p->Openflag) - return (102); - if (p->hydraulics.OpenHflag) - return (108); - - /* Try to open hydraulics file */ - strncpy(p->out_files.HydFname, filename, MAXFNAME); - p->out_files.Hydflag = USE; - p->save_options.SaveHflag = TRUE; - errcode = openhydfile(p); - - /* If error, then reset flags */ - if (errcode) { - strcpy(p->out_files.HydFname, ""); - p->out_files.Hydflag = SCRATCH; - p->save_options.SaveHflag = FALSE; - } - return (errcode); -} /* ---------------------------------------------------------------- @@ -1299,247 +2989,11 @@ int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { return (0); } -/* - ---------------------------------------------------------------- - Functions for retrieving network information - ---------------------------------------------------------------- - */ - -/*** Updated 10/25/00 ***/ -int DLLEXPORT EN_getversion(int *v) -/*---------------------------------------------------------------- - ** Input: none - ** Output: *v = version number of the source code - ** Returns: error code (should always be 0) - ** Purpose: retrieves a number assigned to the most recent - ** update of the source code. This number, set by the - ** constant CODEVERSION found in TYPES.H, is to be - ** interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" - **---------------------------------------------------------------- - */ -{ - *v = CODEVERSION; - return (0); -} - -int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *lindex, - EN_API_FLOAT_TYPE *setting, int *nindex, - EN_API_FLOAT_TYPE *level) { - double s, lvl; - - EN_Project *pr = (EN_Project*)ph; - - EN_Network *net = &pr->network; - - Scontrol *Control = net->Control; - Snode *Node = net->Node; - Slink *Link = net->Link; - - const int Njuncs = net->Njuncs; - double *Ucf = pr->Ucf; - - s = 0.0; - lvl = 0.0; - *ctype = 0; - *lindex = 0; - *nindex = 0; - if (!pr->Openflag) - return (102); - if (cindex < 1 || cindex > net->Ncontrols) - return (241); - *ctype = Control[cindex].Type; - *lindex = Control[cindex].Link; - s = Control[cindex].Setting; - if (Control[cindex].Setting != MISSING) { - switch (Link[*lindex].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - s *= Ucf[PRESSURE]; - break; - case EN_FCV: - s *= Ucf[FLOW]; - default: - break; - } - } else if (Control[cindex].Status == OPEN) { - s = 1.0; - } - - /*** Updated 3/1/01 ***/ - else - s = 0.0; - - *nindex = Control[cindex].Node; - if (*nindex > Njuncs) - lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[ELEV]; - else if (*nindex > 0) - lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[PRESSURE]; - else - lvl = (EN_API_FLOAT_TYPE)Control[cindex].Time; - *setting = (EN_API_FLOAT_TYPE)s; - *level = (EN_API_FLOAT_TYPE)lvl; - return (0); -} - -int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { - - EN_Project *pr = (EN_Project*)ph; - - EN_Network *net = &pr->network; - - *count = 0; - if (!pr->Openflag) - return (102); - switch (code) { - case EN_NODECOUNT: - *count = net->Nnodes; - break; - case EN_TANKCOUNT: - *count = net->Ntanks; - break; - case EN_LINKCOUNT: - *count = net->Nlinks; - break; - case EN_PATCOUNT: - *count = net->Npats; - break; - case EN_CURVECOUNT: - *count = net->Ncurves; - break; - case EN_CONTROLCOUNT: - *count = net->Ncontrols; - break; - case EN_RULECOUNT: - *count = net->Nrules; - break; - default: - return (251); - } - return (0); -} - -int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, - EN_API_FLOAT_TYPE *value) { - - EN_Project *pr = (EN_Project*)ph; - - hydraulics_t *hyd = &pr->hydraulics; - quality_t *qu = &pr->quality; - double *Ucf = pr->Ucf; - - double v = 0.0; - *value = 0.0; - if (!pr->Openflag) - return (102); - switch (code) { - case EN_TRIALS: - v = (double)hyd->MaxIter; - break; - case EN_ACCURACY: - v = hyd->Hacc; - break; - case EN_TOLERANCE: - v = qu->Ctol * Ucf[QUALITY]; - break; - case EN_EMITEXPON: - if (hyd->Qexp > 0.0) - v = 1.0 / hyd->Qexp; - break; - case EN_DEMANDMULT: - v = hyd->Dmult; - break; - - case EN_HEADERROR: - v = hyd->HeadErrorLimit * Ucf[HEAD]; - break; - case EN_FLOWCHANGE: - v = hyd->FlowChangeLimit * Ucf[FLOW]; - break; - - default: - return (251); - } - *value = (EN_API_FLOAT_TYPE)v; - return (0); -} - -int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { - int i; - - EN_Project *pr = (EN_Project*)ph; - - report_options_t *rep = &pr->report; - quality_t *qu = &pr->quality; - time_options_t *time = &pr->time_options; - *value = 0; - if (!pr->Openflag) - return (102); - if (code < EN_DURATION || code > EN_NEXTEVENTIDX) - return (251); - switch (code) { - case EN_DURATION: - *value = time->Dur; - break; - case EN_HYDSTEP: - *value = time->Hstep; - break; - case EN_QUALSTEP: - *value = qu->Qstep; - break; - case EN_PATTERNSTEP: - *value = time->Pstep; - break; - case EN_PATTERNSTART: - *value = time->Pstart; - break; - case EN_REPORTSTEP: - *value = time->Rstep; - break; - case EN_REPORTSTART: - *value = time->Rstart; - break; - case EN_STATISTIC: - *value = rep->Tstatflag; - break; - case EN_RULESTEP: - *value = time->Rulestep; - break; - case EN_PERIODS: - *value = rep->Nperiods; - break; - case EN_STARTTIME: - *value = time->Tstart; - break; /* Added TNT 10/2/2009 */ - case EN_HTIME: - *value = time->Htime; - break; - case EN_NEXTEVENT: - *value = time->Hstep; // find the lesser of the hydraulic time step length, or the - // time to next fill/empty - tanktimestep(pr,value); - break; - case EN_NEXTEVENTIDX: - *value = time->Hstep; - i = tanktimestep(pr, value); - *value = i; - break; - } - return (0); -} -int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { - EN_Project *p = (EN_Project*)ph; - *code = -1; - if (!p->Openflag) - return (102); - *code = p->parser.Flowflag; - return (0); -} int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int i, j; @@ -1618,64 +3072,6 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { return(0); } -int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { - int i; - - EN_Project *p = (EN_Project*)ph; - - *index = 0; - if (!p->Openflag) - return (102); - for (i = 1; i <= p->network.Npats; i++) { - if (strcmp(id, p->network.Pattern[i].ID) == 0) { - *index = i; - return (0); - } - } - *index = 0; - return (205); -} - -int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { - - EN_Project *p = (EN_Project*)ph; - - strcpy(id, ""); - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Npats) - return (205); - strcpy(id, p->network.Pattern[index].ID); - return (0); -} - -int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Npats) - return (205); - *len = p->network.Pattern[index].Length; - return (0); -} - -int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, - EN_API_FLOAT_TYPE *value) { - - EN_Project *p = (EN_Project*)ph; - - *value = 0.0; - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Npats) - return (205); - if (period < 1 || period > p->network.Pattern[index].Length) - return (251); - *value = (EN_API_FLOAT_TYPE)p->network.Pattern[index].F[period - 1]; - return (0); -} int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { int i; @@ -1881,52 +3277,7 @@ int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE * ---------------------------------------------------------------- */ -int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { - EN_Project *p = (EN_Project*)ph; - - *index = 0; - if (!p->Openflag) - return (102); - *index = findnode(&p->network,id); - if (*index == 0) - return (203); - else - return (0); -} - -int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { - - EN_Project *p = (EN_Project*)ph; - - strcpy(id, ""); - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Nnodes) - return (203); - strcpy(id, p->network.Node[index].ID); - return (0); -} - -int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { - - EN_Project *p = (EN_Project*)ph; - - *code = -1; - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Nnodes) - return (203); - if (index <= p->network.Njuncs) - *code = EN_JUNCTION; - else { - if (p->network.Tank[index - p->network.Njuncs].A == 0.0) - *code = EN_RESERVOIR; - else - *code = EN_TANK; - } - return (0); -} int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { @@ -1968,478 +3319,8 @@ int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, return 0; } -int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, - EN_API_FLOAT_TYPE *value) { - double v = 0.0; - Pdemand demand; - Psource source; - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Snode *Node = net->Node; - Stank *Tank = net->Tank; - - const int Nnodes = net->Nnodes; - const int Njuncs = net->Njuncs; - - double *Ucf = p->Ucf; - double *NodeDemand = hyd->NodeDemand; - double *NodeQual = qu->NodeQual; - - - /* Check for valid arguments */ - *value = 0.0; - if (!p->Openflag) - return (102); - if (index <= 0 || index > Nnodes) - return (203); - /* Retrieve called-for parameter */ - switch (code) { - case EN_ELEVATION: - v = Node[index].El * Ucf[ELEV]; - break; - - case EN_BASEDEMAND: - v = 0.0; - /* NOTE: primary demand category is last on demand list */ - if (index <= Njuncs) - for (demand = Node[index].D; demand != NULL; demand = demand->next) - v = (demand->Base); - v *= Ucf[FLOW]; - break; - - case EN_PATTERN: - v = 0.0; - /* NOTE: primary demand category is last on demand list */ - if (index <= Njuncs) { - for (demand = Node[index].D; demand != NULL; demand = demand->next) - v = (double)(demand->Pat); - } else - v = (double)(Tank[index - Njuncs].Pat); - break; - - case EN_EMITTER: - v = 0.0; - if (Node[index].Ke > 0.0) - v = Ucf[FLOW] / pow((Ucf[PRESSURE] * Node[index].Ke), (1.0 / hyd->Qexp)); - break; - - case EN_INITQUAL: - v = Node[index].C0 * Ucf[QUALITY]; - break; - - /*** Additional parameters added for retrieval ***/ - case EN_SOURCEQUAL: - case EN_SOURCETYPE: - case EN_SOURCEMASS: - case EN_SOURCEPAT: - source = Node[index].S; - if (source == NULL) - return (240); - if (code == EN_SOURCEQUAL) - v = source->C0; - else if (code == EN_SOURCEMASS) - v = source->Smass * 60.0; - else if (code == EN_SOURCEPAT) - v = source->Pat; - else - v = source->Type; - break; - - case EN_TANKLEVEL: - if (index <= Njuncs) - return (251); - v = (Tank[index - Njuncs].H0 - Node[index].El) * Ucf[ELEV]; - break; - - /*** New parameter added for retrieval ***/ - case EN_INITVOLUME: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].V0 * Ucf[VOLUME]; - break; - - /*** New parameter added for retrieval ***/ - case EN_MIXMODEL: - v = MIX1; - if (index > Njuncs) - v = Tank[index - Njuncs].MixModel; - break; - - /*** New parameter added for retrieval ***/ - case EN_MIXZONEVOL: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].V1max * Ucf[VOLUME]; - break; - - case EN_DEMAND: - v = NodeDemand[index] * Ucf[FLOW]; - break; - - case EN_HEAD: - v = hyd->NodeHead[index] * Ucf[HEAD]; - break; - - case EN_PRESSURE: - v = (hyd->NodeHead[index] - Node[index].El) * Ucf[PRESSURE]; - break; - - case EN_QUALITY: - v = NodeQual[index] * Ucf[QUALITY]; - break; - - /*** New parameters added for retrieval begins here ***/ - /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ - /*** de Montreal for suggesting some of these.) ***/ - - case EN_TANKDIAM: - v = 0.0; - if (index > Njuncs) { - v = sqrt(4.0 / PI * Tank[index - Njuncs].A) * Ucf[ELEV]; - } - break; - - case EN_MINVOLUME: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Vmin * Ucf[VOLUME]; - break; - - case EN_MAXVOLUME: // !sph - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Vmax * Ucf[VOLUME]; - break; - - case EN_VOLCURVE: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Vcurve; - break; - - case EN_MINLEVEL: - v = 0.0; - if (index > Njuncs) { - v = (Tank[index - Njuncs].Hmin - Node[index].El) * Ucf[ELEV]; - } - break; - - case EN_MAXLEVEL: - v = 0.0; - if (index > Njuncs) { - v = (Tank[index - Njuncs].Hmax - Node[index].El) * Ucf[ELEV]; - } - break; - - case EN_MIXFRACTION: - v = 1.0; - if (index > Njuncs && Tank[index - Njuncs].Vmax > 0.0) { - v = Tank[index - Njuncs].V1max / Tank[index - Njuncs].Vmax; - } - break; - - case EN_TANK_KBULK: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Kb * SECperDAY; - break; - - /*** New parameter additions ends here. ***/ - - case EN_TANKVOLUME: - if (index <= Njuncs) - return (251); - v = tankvolume(p, index - Njuncs, hyd->NodeHead[index]) * Ucf[VOLUME]; - break; - - default: - return (251); - } - *value = (EN_API_FLOAT_TYPE)v; - return (0); -} - -/* - ---------------------------------------------------------------- - Functions for retrieving link data - ---------------------------------------------------------------- - */ - -int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { - - EN_Project *p = (EN_Project*)ph; - - *index = 0; - if (!p->Openflag) - return (102); - *index = findlink(&p->network,id); - if (*index == 0) - return (204); - else - return (0); -} - -int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { - - EN_Project *p = (EN_Project*)ph; - - strcpy(id, ""); - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Nlinks) - return (204); - strcpy(id, p->network.Link[index].ID); - return (0); -} - -int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { - - EN_Project *p = (EN_Project*)ph; - - *code = -1; - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Nlinks) - return (204); - *code = p->network.Link[index].Type; - return (0); -} - -int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, - int *node2) { - - EN_Project *p = (EN_Project*)ph; - - *node1 = 0; - *node2 = 0; - if (!p->Openflag) - return (102); - if (index < 1 || index > p->network.Nlinks) - return (204); - *node1 = p->network.Link[index].N1; - *node2 = p->network.Link[index].N2; - return (0); -} - -int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, - EN_API_FLOAT_TYPE *value) { - double a, h, q, v = 0.0; - int returnValue = 0; - - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - - Slink *Link = net->Link; - Spump *Pump = net->Pump; - - const int Nlinks = net->Nlinks; - - double *Ucf = p->Ucf; - double *LinkFlows = hyd->LinkFlows; - double *LinkSetting = hyd->LinkSetting; - - - - /* Check for valid arguments */ - *value = 0.0; - if (!p->Openflag) - return (102); - if (index <= 0 || index > Nlinks) - return (204); - - /* Retrieve called-for parameter */ - switch (code) { - case EN_DIAMETER: - if (Link[index].Type == EN_PUMP) - v = 0.0; - else - v = Link[index].Diam * Ucf[DIAM]; - break; - - case EN_LENGTH: - v = Link[index].Len * Ucf[ELEV]; - break; - - case EN_ROUGHNESS: - if (Link[index].Type <= EN_PIPE) { - if (hyd->Formflag == DW) - v = Link[index].Kc * (1000.0 * Ucf[ELEV]); - else - v = Link[index].Kc; - } else - v = 0.0; - break; - - case EN_MINORLOSS: - if (Link[index].Type != EN_PUMP) { - v = Link[index].Km; - v *= (SQR(Link[index].Diam) * SQR(Link[index].Diam) / 0.02517); - } else - v = 0.0; - break; - - case EN_INITSTATUS: - if (Link[index].Stat <= CLOSED) - v = 0.0; - else - v = 1.0; - break; - - case EN_INITSETTING: - if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) - return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); - v = Link[index].Kc; - switch (Link[index].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - v *= Ucf[PRESSURE]; - break; - case EN_FCV: - v *= Ucf[FLOW]; - default: - break; - } - break; - - case EN_KBULK: - v = Link[index].Kb * SECperDAY; - break; - - case EN_KWALL: - v = Link[index].Kw * SECperDAY; - break; - - case EN_FLOW: - - /*** Updated 10/25/00 ***/ - if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - else - v = LinkFlows[index] * Ucf[FLOW]; - break; - - case EN_VELOCITY: - if (Link[index].Type == EN_PUMP) { - v = 0.0; - } - - /*** Updated 11/19/01 ***/ - else if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - - else { - q = ABS(LinkFlows[index]); - a = PI * SQR(Link[index].Diam) / 4.0; - v = q / a * Ucf[VELOCITY]; - } - break; - - case EN_HEADLOSS: - - /*** Updated 11/19/01 ***/ - if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - - else { - h = hyd->NodeHead[Link[index].N1] - hyd->NodeHead[Link[index].N2]; - if (Link[index].Type != EN_PUMP) - h = ABS(h); - v = h * Ucf[HEADLOSS]; - } - break; - - case EN_STATUS: - if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - else - v = 1.0; - break; - - case EN_SETTING: - if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) { - return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); - } - if (LinkSetting[index] == MISSING) { - v = 0.0; - } else { - v = LinkSetting[index]; - } - switch (Link[index].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - v *= Ucf[PRESSURE]; - break; - case EN_FCV: - v *= Ucf[FLOW]; - default: - break; - } - break; - - case EN_ENERGY: - getenergy(p, index, &v, &a); - break; - - case EN_LINKQUAL: - v = avgqual(p, index) * Ucf[LINKQUAL]; - break; - - case EN_LINKPATTERN: - if (Link[index].Type == EN_PUMP) - v = (double)Pump[findpump(&p->network, index)].Upat; - break; - - case EN_EFFICIENCY: - getenergy(p, index, &a, &v); - break; - - case EN_PRICEPATTERN: - if (Link[index].Type == EN_PUMP) - v = (double)Pump[findpump(&p->network, index)].Epat; - break; - - case EN_HEADCURVE: - if (Link[index].Type == EN_PUMP) { - v = (double)Pump[findpump(&p->network, index)].Hcurve; - if (v == 0) { - returnValue = 226; - } - } - else { - v = 0; - returnValue = 211; - } - break; - - case EN_EFFICIENCYCURVE: - if (Link[index].Type == EN_PUMP) { - v = (double)Pump[findpump(&p->network, index)].Ecurve; - if (v == 0) { - returnValue = 268; - } - } - else { - v = 0; - returnValue = 211; - } - - default: - v = 0; - returnValue = 251; - } - *value = (EN_API_FLOAT_TYPE)v; - return returnValue; -} int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nValues, EN_API_FLOAT_TYPE **xValues, @@ -2476,536 +3357,10 @@ int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nV return (0); } -/* - ---------------------------------------------------------------- - Functions for changing network data - ---------------------------------------------------------------- - */ -int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, - EN_API_FLOAT_TYPE setting, int nindex, - EN_API_FLOAT_TYPE level) { - char status = ACTIVE; - long t = 0; - double s = setting, lvl = level; - EN_Network *net; - Snode *Node; - Slink *Link; - Scontrol *Control; - - int Nnodes; - int Njuncs; - int Nlinks; - double *Ucf; - EN_Project *p = (EN_Project*)ph; - /* Check that input file opened */ - if (!p->Openflag) - return (102); - /* Check that control exists */ - if (cindex < 1 || cindex > p->network.Ncontrols) - return (241); - - - net = &p->network; - - Node = net->Node; - Link = net->Link; - Control = net->Control; - - Nnodes = net->Nnodes; - Njuncs = net->Njuncs; - Nlinks = net->Nlinks; - - Ucf = p->Ucf; - - /* Check that controlled link exists */ - if (lindex == 0) { - Control[cindex].Link = 0; - return (0); - } - if (lindex < 0 || lindex > Nlinks) - return (204); - - /* Cannot control check valve. */ - if (Link[lindex].Type == EN_CVPIPE) - return (207); - - /* Check for valid parameters */ - if (ctype < 0 || ctype > EN_TIMEOFDAY) - return (251); - if (ctype == EN_LOWLEVEL || ctype == EN_HILEVEL) { - if (nindex < 1 || nindex > Nnodes) - return (203); - } else - nindex = 0; - if (s < 0.0 || lvl < 0.0) - return (202); - - /* Adjust units of control parameters */ - switch (Link[lindex].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - s /= Ucf[PRESSURE]; - break; - case EN_FCV: - s /= Ucf[FLOW]; - break; - - /*** Updated 9/7/00 ***/ - case EN_GPV: - if (s == 0.0) - status = CLOSED; - else if (s == 1.0) - status = OPEN; - else - return (202); - s = Link[lindex].Kc; - break; - - case EN_PIPE: - case EN_PUMP: - status = OPEN; - if (s == 0.0) - status = CLOSED; - default: - break; - } - if (ctype == LOWLEVEL || ctype == HILEVEL) { - if (nindex > Njuncs) - lvl = Node[nindex].El + level / Ucf[ELEV]; - else - lvl = Node[nindex].El + level / Ucf[PRESSURE]; - } - if (ctype == TIMER) - t = (long)ROUND(lvl); - if (ctype == TIMEOFDAY) - t = (long)ROUND(lvl) % SECperDAY; - - /* Reset control's parameters */ - Control[cindex].Type = (char)ctype; - Control[cindex].Link = lindex; - Control[cindex].Node = nindex; - Control[cindex].Status = status; - Control[cindex].Setting = s; - Control[cindex].Grade = lvl; - Control[cindex].Time = t; - return (0); -} - -int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) -/*---------------------------------------------------------------- - ** Input: index = node index - ** code = node parameter code (see EPANET2.H) - ** value = parameter value - ** Output: none - ** Returns: error code - ** Purpose: sets input parameter value for a node - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Snode *Node = net->Node; - Stank *Tank = net->Tank; - - const int Nnodes = net->Nnodes; - const int Njuncs = net->Njuncs; - const int Npats = net->Npats; - - double *Ucf = p->Ucf; - - int j; - Pdemand demand; - Psource source; - double Htmp; - double value = v; - - if (!p->Openflag) - return (102); - if (index <= 0 || index > Nnodes) - return (203); - switch (code) { - case EN_ELEVATION: - if (index <= Njuncs) - Node[index].El = value / Ucf[ELEV]; - else { - value = (value / Ucf[ELEV]) - Node[index].El; - j = index - Njuncs; - Tank[j].H0 += value; - Tank[j].Hmin += value; - Tank[j].Hmax += value; - Node[index].El += value; - hyd->NodeHead[index] += value; - } - break; - - case EN_BASEDEMAND: - /* NOTE: primary demand category is last on demand list */ - if (index <= Njuncs) { - for (demand = Node[index].D; demand != NULL; demand = demand->next) { - if (demand->next == NULL) - demand->Base = value / Ucf[FLOW]; - } - } - break; - - case EN_PATTERN: - /* NOTE: primary demand category is last on demand list */ - j = ROUND(value); - if (j < 0 || j > Npats) - return (205); - if (index <= Njuncs) { - for (demand = Node[index].D; demand != NULL; demand = demand->next) { - if (demand->next == NULL) - demand->Pat = j; - } - } else - Tank[index - Njuncs].Pat = j; - break; - - case EN_EMITTER: - if (index > Njuncs) - return (203); - if (value < 0.0) - return (202); - if (value > 0.0) - value = pow((Ucf[FLOW] / value), hyd->Qexp) / Ucf[PRESSURE]; - Node[index].Ke = value; - break; - - case EN_INITQUAL: - if (value < 0.0) - return (202); - Node[index].C0 = value / Ucf[QUALITY]; - if (index > Njuncs) - Tank[index - Njuncs].C = Node[index].C0; - break; - - case EN_SOURCEQUAL: - case EN_SOURCETYPE: - case EN_SOURCEPAT: - if (value < 0.0) - return (202); - source = Node[index].S; - if (source == NULL) { - source = (struct Ssource *)malloc(sizeof(struct Ssource)); - if (source == NULL) - return (101); - source->Type = CONCEN; - source->C0 = 0.0; - source->Pat = 0; - Node[index].S = source; - } - if (code == EN_SOURCEQUAL) { - source->C0 = value; - } else if (code == EN_SOURCEPAT) { - j = ROUND(value); - if (j < 0 || j > Npats) - return (205); - source->Pat = j; - } else // code == EN_SOURCETYPE - { - j = ROUND(value); - if (j < CONCEN || j > FLOWPACED) - return (251); - else - source->Type = (char)j; - } - return (0); - - case EN_TANKLEVEL: - if (index <= Njuncs) - return (251); - j = index - Njuncs; - if (Tank[j].A == 0.0) /* Tank is a reservoir */ - { - Tank[j].H0 = value / Ucf[ELEV]; - Tank[j].Hmin = Tank[j].H0; - Tank[j].Hmax = Tank[j].H0; - Node[index].El = Tank[j].H0; - hyd->NodeHead[index] = Tank[j].H0; - } else { - value = Node[index].El + value / Ucf[ELEV]; - if (value > Tank[j].Hmax || value < Tank[j].Hmin) - return (202); - Tank[j].H0 = value; - Tank[j].V0 = tankvolume(p, j, Tank[j].H0); - // Resetting Volume in addition to initial volume - Tank[j].V = Tank[j].V0; - hyd->NodeHead[index] = Tank[j].H0; - } - break; - - /*** New parameters added for retrieval begins here ***/ - /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ - /*** de Montreal for suggesting some of these.) ***/ - - case EN_TANKDIAM: - if (value <= 0.0) - return (202); - if (index <= Njuncs) - return (251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - value /= Ucf[ELEV]; - Tank[j].A = PI * SQR(value) / 4.0; - Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); - Tank[j].V0 = tankvolume(p, j, Tank[j].H0); - Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); - } else { - return (251); - } - break; - - case EN_MINVOLUME: - if (value < 0.0) - return (202); - if (index <= Njuncs) - return (251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - Tank[j].Vmin = value / Ucf[VOLUME]; - Tank[j].V0 = tankvolume(p, j, Tank[j].H0); - Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); - } else { - return (251); - } - break; - - case EN_MINLEVEL: - if (value < 0.0) - return (202); - if (index <= Njuncs) - return (251); // not a tank or reservoir - j = index - Njuncs; - if (Tank[j].A == 0.0) - return (251); // node is a reservoir - Htmp = value / Ucf[ELEV] + Node[index].El; - if (Htmp < Tank[j].Hmax && Htmp <= Tank[j].H0) { - if (Tank[j].Vcurve > 0) - return (202); - Tank[j].Hmin = Htmp; - Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); - } else { - return (251); - } - break; - - case EN_MAXLEVEL: - if (value < 0.0) - return (202); - if (index <= Njuncs) - return (251); // not a tank or reservoir - j = index - Njuncs; - if (Tank[j].A == 0.0) - return (251); // node is a reservoir - Htmp = value / Ucf[ELEV] + Node[index].El; - if (Htmp > Tank[j].Hmin && Htmp >= Tank[j].H0) { - if (Tank[j].Vcurve > 0) - return (202); - Tank[j].Hmax = Htmp; - Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); - } else { - return (251); - } - break; - - case EN_MIXMODEL: - j = ROUND(value); - if (index <= Njuncs) - return (251); - if (j < MIX1 || j > LIFO) - return (202); - if (index > Njuncs && Tank[index - Njuncs].A > 0.0) { - Tank[index - Njuncs].MixModel = (char)j; - } else { - return (251); - } - break; - - case EN_MIXFRACTION: - if (value < 0.0 || value > 1.0) - return (202); - if (index <= Njuncs) - return (251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - Tank[j].V1max = value * Tank[j].Vmax; - } - break; - - case EN_TANK_KBULK: - if (index <= Njuncs) - return (251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - Tank[j].Kb = value / SECperDAY; - qu->Reactflag = 1; - } else { - return (251); - } - break; - - /*** New parameter additions ends here. ***/ - - default: - return (251); - } - return (0); -} - -int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, - EN_API_FLOAT_TYPE v) - -/*---------------------------------------------------------------- - ** Input: index = link index - ** code = link parameter code (see EPANET2.H) - ** v = parameter value - ** Output: none - ** Returns: error code - ** Purpose: sets input parameter value for a link - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Slink *Link = net->Link; - - const int Nlinks = net->Nlinks; - - double *Ucf = p->Ucf; - double *LinkSetting = hyd->LinkSetting; - - char s; - double r, value = v; - - if (!p->Openflag) - return (102); - if (index <= 0 || index > Nlinks) - return (204); - switch (code) { - case EN_DIAMETER: - if (Link[index].Type != EN_PUMP) { - if (value <= 0.0) - return (202); - value /= Ucf[DIAM]; /* Convert to feet */ - r = Link[index].Diam / value; /* Ratio of old to new diam */ - Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */ - Link[index].Diam = value; /* Update diameter */ - resistcoeff(p, index); /* Update resistance coeff. */ - } - break; - - case EN_LENGTH: - if (Link[index].Type <= EN_PIPE) { - if (value <= 0.0) - return (202); - Link[index].Len = value / Ucf[ELEV]; - resistcoeff(p, index); - } - break; - - case EN_ROUGHNESS: - if (Link[index].Type <= EN_PIPE) { - if (value <= 0.0) - return (202); - Link[index].Kc = value; - if (hyd->Formflag == DW) - Link[index].Kc /= (1000.0 * Ucf[ELEV]); - resistcoeff(p, index); - } - break; - - case EN_MINORLOSS: - if (Link[index].Type != EN_PUMP) { - if (value <= 0.0) - return (202); - Link[index].Km = - 0.02517 * value / SQR(Link[index].Diam) / SQR(Link[index].Diam); - } - break; - - case EN_INITSTATUS: - case EN_STATUS: - /* Cannot set status for a check valve */ - if (Link[index].Type == EN_CVPIPE) - return (207); - s = (char)ROUND(value); - if (s < 0 || s > 1) - return (251); - if (code == EN_INITSTATUS) - setlinkstatus(p, index, s, &Link[index].Stat, &Link[index].Kc); - else - setlinkstatus(p, index, s, &hyd->LinkStatus[index], &LinkSetting[index]); - break; - - case EN_INITSETTING: - case EN_SETTING: - if (value < 0.0) - return (202); - if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) - return (ENsetlinkvalue(index, EN_ROUGHNESS, v)); - else { - switch (Link[index].Type) { - case EN_PUMP: - break; - case EN_PRV: - case EN_PSV: - case EN_PBV: - value /= Ucf[PRESSURE]; - break; - case EN_FCV: - value /= Ucf[FLOW]; - break; - case EN_TCV: - break; - - /*** Updated 9/7/00 ***/ - case EN_GPV: - return (202); /* Cannot modify setting for GPV */ - - default: - return (251); - } - if (code == EN_INITSETTING) - setlinksetting(p, index, value, &Link[index].Stat, &Link[index].Kc); - else - setlinksetting(p, index, value, &hyd->LinkStatus[index], - &LinkSetting[index]); - } - break; - - case EN_KBULK: - if (Link[index].Type <= EN_PIPE) { - Link[index].Kb = value / SECperDAY; - qu->Reactflag = 1; - } - break; - - case EN_KWALL: - if (Link[index].Type <= EN_PIPE) { - Link[index].Kw = value / SECperDAY; - qu->Reactflag = 1; - } - break; - - default: - return (251); - } - return (0); -} int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int i, j, n, err = 0; @@ -3084,56 +3439,8 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { return 0; } -int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { - int j; - EN_Project *p = (EN_Project*)ph; - EN_Network *net = &p->network; - Spattern *Pattern = net->Pattern; - const int Npats = net->Npats; - - - /* Check for valid arguments */ - if (!p->Openflag) - return (102); - if (index <= 0 || index > Npats) - return (205); - if (n <= 0) - return (202); - - /* Re-set number of time periods & reallocate memory for multipliers */ - Pattern[index].Length = n; - Pattern[index].F = (double *)realloc(Pattern[index].F, n * sizeof(double)); - if (Pattern[index].F == NULL) - return (101); - - /* Load multipliers into pattern */ - for (j = 0; j < n; j++) - Pattern[index].F[j] = f[j]; - return (0); -} - -int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value) { - - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - - Spattern *Pattern = net->Pattern; - - const int Npats = net->Npats; - - - if (!p->Openflag) - return (102); - if (index <= 0 || index > Npats) - return (205); - if (period <= 0 || period > Pattern[index].Length) - return (251); - Pattern[index].F[period - 1] = value; - return (0); -} int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { @@ -3282,184 +3589,9 @@ int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_F return (0); } -int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) -{ - EN_Project *p = (EN_Project*)ph; - report_options_t *rep = &p->report; - quality_t *qu = &p->quality; - time_options_t *time = &p->time_options; - - if (!p->Openflag) - return (102); - if (p->hydraulics.OpenHflag || p->quality.OpenQflag) { - // --> there's nothing wrong with changing certain time parameters during a - // simulation run, or before the run has started. - // todo -- how to tell? - /* - if (code == EN_DURATION || code == EN_HTIME || code == EN_REPORTSTEP || - code == EN_DURATION || Htime == 0) { - // it's ok - } - else { - return(109); - } - */ - } - if (value < 0) - return (202); - switch (code) { - case EN_DURATION: - time->Dur = value; - if (time->Rstart > time->Dur) - time->Rstart = 0; - break; - case EN_HYDSTEP: - if (value == 0) - return (202); - time->Hstep = value; - time->Hstep = MIN(time->Pstep, time->Hstep); - time->Hstep = MIN(time->Rstep, time->Hstep); - qu->Qstep = MIN(qu->Qstep, time->Hstep); - break; - case EN_QUALSTEP: - if (value == 0) - return (202); - qu->Qstep = value; - qu->Qstep = MIN(qu->Qstep, time->Hstep); - break; - - case EN_PATTERNSTEP: - if (value == 0) - return (202); - time->Pstep = value; - if (time->Hstep > time->Pstep) - time->Hstep = time->Pstep; - break; - - case EN_PATTERNSTART: - time->Pstart = value; - break; - - case EN_REPORTSTEP: - if (value == 0) - return (202); - time->Rstep = value; - if (time->Hstep > time->Rstep) - time->Hstep = time->Rstep; - break; - - case EN_REPORTSTART: - if (time->Rstart > time->Dur) - return (202); - time->Rstart = value; - break; - - case EN_RULESTEP: - if (value == 0) - return (202); - time->Rulestep = value; - time->Rulestep = MIN(time->Rulestep, time->Hstep); - break; - - case EN_STATISTIC: - if (value > RANGE) - return (202); - rep->Tstatflag = (char)value; - break; - - case EN_HTIME: - time->Htime = value; - break; - - case EN_QTIME: - qu->Qtime = value; - break; - - default: - return (251); - } - return (0); -} - -int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) -/*---------------------------------------------------------------- - ** Input: code = option code (see EPANET2.H) - ** v = option value - ** Output: none - ** Returns: error code - ** Purpose: sets value for an analysis option - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Snode *Node = net->Node; - const int Njuncs = net->Njuncs; - - double *Ucf = p->Ucf; - - int i, j; - double Ke, n, ucf, value = v; - if (!p->Openflag) - return (102); - switch (code) { - case EN_TRIALS: - if (value < 1.0) - return (202); - hyd->MaxIter = (int)value; - break; - case EN_ACCURACY: - if (value < 1.e-5 || value > 1.e-1) - return (202); - hyd->Hacc = value; - break; - case EN_TOLERANCE: - if (value < 0.0) - return (202); - qu->Ctol = value / Ucf[QUALITY]; - break; - case EN_EMITEXPON: - if (value <= 0.0) - return (202); - n = 1.0 / value; - ucf = pow(Ucf[FLOW], n) / Ucf[PRESSURE]; - for (i = 1; i <= Njuncs; i++) { - j = ENgetnodevalue(i, EN_EMITTER, &v); - Ke = v; - if (j == 0 && Ke > 0.0) - Node[i].Ke = ucf / pow(Ke, n); - } - hyd->Qexp = n; - break; - case EN_DEMANDMULT: - if (value <= 0.0) - return (202); - hyd->Dmult = value; - break; - - case EN_HEADERROR: - if (value < 0.0) - return (202); - hyd->HeadErrorLimit = value / Ucf[HEAD]; - break; - case EN_FLOWCHANGE: - if (value < 0.0) - return (202); - hyd->FlowChangeLimit = value / Ucf[FLOW]; - break; - - default: - return (251); - } - return (0); -} int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int errcode = 0; @@ -3473,72 +3605,7 @@ int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { return (errcode); } -int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode) { - - EN_Project *p = (EN_Project*)ph; - EN_Network *net = &p->network; - report_options_t *rep = &p->report; - quality_t *qu = &p->quality; - - double *Ucf = p->Ucf; - int i; - - /*** Updated 3/1/01 ***/ - double ccf = 1.0; - - if (!p->Openflag) - return (102); - if (qualcode < EN_NONE || qualcode > EN_TRACE) - return (251); - qu->Qualflag = (char)qualcode; - qu->Ctol *= Ucf[QUALITY]; - if (qu->Qualflag == CHEM) /* Chemical constituent */ - { - strncpy(qu->ChemName, chemname, MAXID); - strncpy(qu->ChemUnits, chemunits, MAXID); - - /*** Updated 3/1/01 ***/ - strncpy(rep->Field[QUALITY].Units, qu->ChemUnits, MAXID); - strncpy(rep->Field[REACTRATE].Units, qu->ChemUnits, MAXID); - strcat(rep->Field[REACTRATE].Units, t_PERDAY); - ccf = 1.0 / LperFT3; - } - if (qu->Qualflag == TRACE) /* Source tracing option */ - { - qu->TraceNode = findnode(net,tracenode); - if (qu->TraceNode == 0) - return (203); - strncpy(qu->ChemName, u_PERCENT, MAXID); - strncpy(qu->ChemUnits, tracenode, MAXID); - - /*** Updated 3/1/01 ***/ - strcpy(rep->Field[QUALITY].Units, u_PERCENT); - } - if (qu->Qualflag == AGE) /* Water age analysis */ - { - strncpy(qu->ChemName, w_AGE, MAXID); - strncpy(qu->ChemUnits, u_HOURS, MAXID); - - /*** Updated 3/1/01 ***/ - strcpy(rep->Field[QUALITY].Units, u_HOURS); - } - - /* when changing from CHEM to AGE or TRACE, nodes initial quality values must be returned to their original ones */ - if ((qu->Qualflag == AGE || qu->Qualflag == TRACE) & (Ucf[QUALITY] != 1)) { - for (i=1; i<=p->network.Nnodes; i++) { - p->network.Node[i].C0 *= Ucf[QUALITY]; - } - } - - /*** Updated 3/1/01 ***/ - Ucf[QUALITY] = ccf; - Ucf[LINKQUAL] = ccf; - Ucf[REACTRATE] = ccf; - qu->Ctol /= Ucf[QUALITY]; - - return (0); -} int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveindex) { From 8ff88f86b8803c20309a79f793eb91375df81141 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 19 Jul 2018 11:16:49 -0400 Subject: [PATCH 31/45] Reorganizing / refactoring api functions for swig wrap --- src/epanet.c | 1038 +++++++++++++++++++++++++------------------------- 1 file changed, 528 insertions(+), 510 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 8248ca8..a7e6baf 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -137,11 +137,10 @@ execute function x and set the error code equal to its return value. // Local functions void errorLookup(int errcode, char *errmsg, int len); -/**************************************************************** - LEGACY (v <= 2.1) API: uses global project variable - -*****************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +//-------------------- CANONICAL API - ORGANIZED BY TASK ---------------------// +//////////////////////////////////////////////////////////////////////////////// int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *)) @@ -2170,57 +2169,549 @@ int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { } -int DLLEXPORT ENaddpattern(char *id) { - return EN_addpattern(_defaultModel, id); +/* + ---------------------------------------------------------------- + Functions for running a hydraulic analysis + ---------------------------------------------------------------- + */ +int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } + +int DLLEXPORT EN_solveH(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: solves for network hydraulics in all time periods + **---------------------------------------------------------------- + */ +{ + int errcode; + long t, tstep; + + EN_Project *p = (EN_Project*)ph; + + /* Open hydraulics solver */ + errcode = EN_openH(ph); + if (!errcode) { + /* Initialize hydraulics */ + errcode = EN_initH(ph, EN_SAVE); + writecon(FMT14); + + /* Analyze each hydraulic period */ + if (!errcode) + do { + + /* Display progress message */ + + /*** Updated 6/24/02 ***/ + sprintf(p->Msg, "%-10s", + clocktime(p->report.Atime, p->time_options.Htime)); + + writecon(p->Msg); + sprintf(p->Msg, FMT101, p->report.Atime); + writewin(p->viewprog, p->Msg); + + /* Solve for hydraulics & advance to next time period */ + tstep = 0; + ERRCODE(EN_runH(ph, &t)); + ERRCODE(EN_nextH(ph, &tstep)); + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b\b\b"); + } while (tstep > 0); + } + + /* Close hydraulics solver */ + + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b "); + + EN_closeH(ph); + errcode = MAX(errcode, p->Warnflag); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); } + +int DLLEXPORT EN_openH(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: sets up data structures for hydraulic analysis + **---------------------------------------------------------------- + */ +{ + int errcode = 0; + + EN_Project *p = (EN_Project*)ph; + + /* Check that input data exists */ + p->hydraulics.OpenHflag = FALSE; + p->save_options.SaveHflag = FALSE; + if (!p->Openflag) { + return set_error(p->error_handle, 102); + } + + /* Check that previously saved hydraulics file not in use */ + if (p->out_files.Hydflag == USE) { + return set_error(p->error_handle, 107); + } + + /* Open hydraulics solver */ + ERRCODE(openhyd(p)); + if (!errcode) + p->hydraulics.OpenHflag = TRUE; + else + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); } + +int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) +/*---------------------------------------------------------------- + ** Input: flag = 2-digit flag where 1st (left) digit indicates + ** if link flows should be re-initialized (1) or + ** not (0) and 2nd digit indicates if hydraulic + ** results should be saved to file (1) or not (0) + ** Output: none + ** Returns: error code + ** Purpose: initializes hydraulic analysis + **---------------------------------------------------------------- + */ +{ + int errcode = 0; + int sflag, fflag; + + EN_Project *p = (EN_Project*)ph; + + /* Reset status flags */ + p->save_options.SaveHflag = FALSE; + p->Warnflag = FALSE; + + /* Get values of save-to-file flag and reinitialize-flows flag */ + fflag = flag / EN_INITFLOW; + sflag = flag - fflag * EN_INITFLOW; + + /* Check that hydraulics solver was opened */ + if (!p->hydraulics.OpenHflag) + return set_error(p->error_handle, 103); + + /* Open hydraulics file */ + p->save_options.Saveflag = FALSE; + if (sflag > 0) { + errcode = openhydfile(p); + if (!errcode) + p->save_options.Saveflag = TRUE; + else { + errmsg(p, errcode); + return errcode; + } + } + + /* Initialize hydraulics */ + inithyd(p, fflag); + if (p->report.Statflag > 0) + writeheader(p, STATHDR, 0); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); } + +int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *t = 0; + if (!p->hydraulics.OpenHflag) + return set_error(p->error_handle, 103); + errcode = runhyd(p, t); + if (errcode) + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } + +int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *tstep = 0; + if (!p->hydraulics.OpenHflag) + return set_error(p->error_handle, 103); + errcode = nexthyd(p, tstep); + if (errcode) + errmsg(p, errcode); + else if (p->save_options.Saveflag && *tstep == 0) + p->save_options.SaveHflag = TRUE; + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } + +int DLLEXPORT EN_closeH(EN_ProjectHandle ph) +{ + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) { + return set_error(p->error_handle, 102); + } + if (p->hydraulics.OpenHflag) { + closehyd(p); + } + p->hydraulics.OpenHflag = FALSE; + return set_error(p->error_handle, 0); +} + + +/* + ---------------------------------------------------------------- + Functions for running a WQ analysis + ---------------------------------------------------------------- + */ +int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } + +int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { + int errcode; + long t, tstep; + + EN_Project *p = (EN_Project*)ph; + + /* Open WQ solver */ + errcode = EN_openQ(ph); + if (!errcode) { + /* Initialize WQ */ + errcode = EN_initQ(ph, EN_SAVE); + if (p->quality.Qualflag) + writecon(FMT15); + else { + writecon(FMT16); + writewin(p->viewprog, FMT103); + } + + /* Analyze each hydraulic period */ + if (!errcode) + do { + + /* Display progress message */ + + /*** Updated 6/24/02 ***/ + sprintf(p->Msg, "%-10s", + clocktime(p->report.Atime, p->time_options.Htime)); + + writecon(p->Msg); + if (p->quality.Qualflag) { + sprintf(p->Msg, FMT102, p->report.Atime); + writewin(p->viewprog, p->Msg); + } + + /* Retrieve current network solution & update WQ to next time period */ + tstep = 0; + ERRCODE(EN_runQ(ph, &t)); + ERRCODE(EN_nextQ(ph, &tstep)); + + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b\b\b"); + + } while (tstep > 0); + } + + /* Close WQ solver */ + + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b "); + EN_closeQ(ph); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); } + +int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { + int errcode = 0; + + EN_Project *p = (EN_Project*)ph; + + /* Check that hydraulics results exist */ + p->quality.OpenQflag = FALSE; + p->save_options.SaveQflag = FALSE; + if (!p->Openflag) + return set_error(p->error_handle, 102); + // !LT! todo - check for p->save_options.SaveHflag / set sequential/step mode + // if (!p->save_options.SaveHflag) return(104); + + /* Open WQ solver */ + ERRCODE(openqual(p)); + if (!errcode) + p->quality.OpenQflag = TRUE; + else + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENinitQ(int saveflag) { return EN_initQ(_defaultModel, saveflag); } + +int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { + int errcode = 0; + + EN_Project *p = (EN_Project*)ph; + + if (!p->quality.OpenQflag) + return set_error(p->error_handle, 105); + initqual(p); + p->save_options.SaveQflag = FALSE; + p->save_options.Saveflag = FALSE; + if (saveflag) { + errcode = openoutfile(p); + if (!errcode) + p->save_options.Saveflag = TRUE; + } + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); } + +int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *t = 0; + if (!p->quality.OpenQflag) + return set_error(p->error_handle, 105); + errcode = runqual(p, t); + if (errcode) + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); } + +int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *tstep = 0; + if (!p->quality.OpenQflag) + return set_error(p->error_handle, 105); + errcode = nextqual(p, tstep); + if (!errcode && p->save_options.Saveflag && *tstep == 0) { + p->save_options.SaveQflag = TRUE; + } + if (errcode) + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); } + +int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *tleft = 0; + if (!p->quality.OpenQflag) + return set_error(p->error_handle, 105); + errcode = stepqual(p, tleft); + if (!errcode && p->save_options.Saveflag && *tleft == 0) { + p->save_options.SaveQflag = TRUE; + } + if (errcode) + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); } + +int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + closequal(p); + p->quality.OpenQflag = FALSE; + return set_error(p->error_handle, 0); +} + + +/* + * Functions for generating output reports + */ +int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } + +int DLLEXPORT EN_saveH(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: saves hydraulic results to binary file. + ** + ** Must be called before ENreport() if no WQ simulation made. + ** Should not be called if ENsolveQ() will be used. + **---------------------------------------------------------------- + */ +{ + char tmpflag; + int errcode; + + EN_Project *p = (EN_Project*)ph; + + /* Check if hydraulic results exist */ + if (!p->save_options.SaveHflag) + return set_error(p->error_handle, 104); + + /* Temporarily turn off WQ analysis */ + tmpflag = p->quality.Qualflag; + p->quality.Qualflag = NONE; + + /* Call WQ solver to simply transfer results */ + /* from Hydraulics file to Output file at */ + /* fixed length reporting time intervals. */ + errcode = EN_solveQ(p); + + /* Restore WQ analysis option */ + p->quality.Qualflag = tmpflag; + if (errcode) { + errmsg(p, errcode); + } + return set_error(p->error_handle, errcode); } int DLLEXPORT ENsaveinpfile(char *filename) { return EN_saveinpfile(_defaultModel, filename); } +int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) +/*---------------------------------------------------------------- + ** Input: filename = name of INP file + ** Output: none + ** Returns: error code + ** Purpose: saves current data base to file + **---------------------------------------------------------------- + */ +{ + int errcode = 0; + EN_Project *p = (EN_Project*)ph; + if (!p->Openflag) + return set_error(p->error_handle, 102); + errcode = saveinpfile(p, filename); -int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } - -int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } - -int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); } - -int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); } - -int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); } - -int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } - -int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } - - - -int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } - -int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); } - -int DLLEXPORT ENinitQ(int saveflag) { - return EN_initQ(_defaultModel, saveflag); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENreport() { return EN_report(_defaultModel); } + +int DLLEXPORT EN_report(EN_ProjectHandle ph) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + /* Check if results saved to binary output file */ + if (!p->save_options.SaveQflag) + return set_error(p->error_handle, 106); + errcode = writereport(p); + if (errcode) + errmsg(p, errcode); + return set_error(p->error_handle, errcode); +} + +int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } + +int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { + int i; + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + initreport(&p->report); + for (i = 1; i <= p->network.Nnodes; i++) + p->network.Node[i].Rpt = 0; + for (i = 1; i <= p->network.Nlinks; i++) + p->network.Link[i].Rpt = 0; + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } + +int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { + char s1[MAXLINE + 1]; + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return set_error(p->error_handle, 102); + if (strlen(s) > MAXLINE) + return set_error(p->error_handle, 250); + strcpy(s1, s); + if (setreport(p, s1) > 0) + return set_error(p->error_handle, 250); + else + return set_error(p->error_handle, 0); +} + +int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) { + return EN_geterror(errcode, errmsg, n); +} + +int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { + char newMsg[MAXMSG+1]; + + switch (errcode) { + case 1: + strncpy(errmsg, WARN1, n); + break; + case 2: + strncpy(errmsg, WARN2, n); + break; + case 3: + strncpy(errmsg, WARN3, n); + break; + case 4: + strncpy(errmsg, WARN4, n); + break; + case 5: + strncpy(errmsg, WARN5, n); + break; + case 6: + strncpy(errmsg, WARN6, n); + break; + default: + geterrmsg(errcode, newMsg); + strncpy(errmsg, newMsg, n); + } + if (strlen(errmsg) == 0) + return (251); + else + return (0); +} + + +//////////////////////////////////////////////////////////////////////////////// +//-------------------------------- NEW API -----------------------------------// +//////////////////////////////////////////////////////////////////////////////// + +int DLLEXPORT ENaddpattern(char *id) { + return EN_addpattern(_defaultModel, id); } -int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); } -int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); } -int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); } -int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); } int DLLEXPORT ENwriteline(char *line) { return EN_writeline(_defaultModel, line); } -int DLLEXPORT ENreport() { return EN_report(_defaultModel); } -int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } -int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } + @@ -2258,9 +2749,7 @@ int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, tracenode); } -int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) { - return EN_geterror(errcode, errmsg, n); -} + int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) { return EN_getstatistic(_defaultModel, code, value); @@ -2525,409 +3014,10 @@ int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, -int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) -/*---------------------------------------------------------------- - ** Input: filename = name of INP file - ** Output: none - ** Returns: error code - ** Purpose: saves current data base to file - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - if (!p->Openflag) - return (102); - return (saveinpfile(p, filename)); -} -/* - ---------------------------------------------------------------- - Functions for running a hydraulic analysis - ---------------------------------------------------------------- - */ - -int DLLEXPORT EN_solveH(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: solves for network hydraulics in all time periods - **---------------------------------------------------------------- - */ -{ - int errcode; - long t, tstep; - - EN_Project *p = (EN_Project*)ph; - - /* Open hydraulics solver */ - errcode = EN_openH(ph); - if (!errcode) { - /* Initialize hydraulics */ - errcode = EN_initH(ph, EN_SAVE); - writecon(FMT14); - - /* Analyze each hydraulic period */ - if (!errcode) - do { - - /* Display progress message */ - - /*** Updated 6/24/02 ***/ - sprintf(p->Msg, "%-10s", - clocktime(p->report.Atime, p->time_options.Htime)); - - writecon(p->Msg); - sprintf(p->Msg, FMT101, p->report.Atime); - writewin(p->viewprog, p->Msg); - - /* Solve for hydraulics & advance to next time period */ - tstep = 0; - ERRCODE(EN_runH(ph, &t)); - ERRCODE(EN_nextH(ph, &tstep)); - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b\b\b"); - } while (tstep > 0); - } - - /* Close hydraulics solver */ - - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b "); - - EN_closeH(ph); - errcode = MAX(errcode, p->Warnflag); - return (errcode); -} - -int DLLEXPORT EN_saveH(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: saves hydraulic results to binary file. - ** - ** Must be called before ENreport() if no WQ simulation made. - ** Should not be called if ENsolveQ() will be used. - **---------------------------------------------------------------- - */ -{ - char tmpflag; - int errcode; - - EN_Project *p = (EN_Project*)ph; - - /* Check if hydraulic results exist */ - if (!p->save_options.SaveHflag) - return (104); - - /* Temporarily turn off WQ analysis */ - tmpflag = p->quality.Qualflag; - p->quality.Qualflag = NONE; - - /* Call WQ solver to simply transfer results */ - /* from Hydraulics file to Output file at */ - /* fixed length reporting time intervals. */ - errcode = EN_solveQ(p); - - /* Restore WQ analysis option */ - p->quality.Qualflag = tmpflag; - if (errcode) { - errmsg(p, errcode); - } - return (errcode); -} - -int DLLEXPORT EN_openH(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: sets up data structures for hydraulic analysis - **---------------------------------------------------------------- - */ -{ - int errcode = 0; - - EN_Project *p = (EN_Project*)ph; - - /* Check that input data exists */ - p->hydraulics.OpenHflag = FALSE; - p->save_options.SaveHflag = FALSE; - if (!p->Openflag) { - return (102); - } - - /* Check that previously saved hydraulics file not in use */ - if (p->out_files.Hydflag == USE) { - return (107); - } - - /* Open hydraulics solver */ - ERRCODE(openhyd(p)); - if (!errcode) - p->hydraulics.OpenHflag = TRUE; - else - errmsg(p, errcode); - return (errcode); -} - -/*** Updated 3/1/01 ***/ -int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) -/*---------------------------------------------------------------- - ** Input: flag = 2-digit flag where 1st (left) digit indicates - ** if link flows should be re-initialized (1) or - ** not (0) and 2nd digit indicates if hydraulic - ** results should be saved to file (1) or not (0) - ** Output: none - ** Returns: error code - ** Purpose: initializes hydraulic analysis - **---------------------------------------------------------------- - */ -{ - int errcode = 0; - int sflag, fflag; - - EN_Project *p = (EN_Project*)ph; - - /* Reset status flags */ - p->save_options.SaveHflag = FALSE; - p->Warnflag = FALSE; - - /* Get values of save-to-file flag and reinitialize-flows flag */ - fflag = flag / EN_INITFLOW; - sflag = flag - fflag * EN_INITFLOW; - - /* Check that hydraulics solver was opened */ - if (!p->hydraulics.OpenHflag) - return (103); - - /* Open hydraulics file */ - p->save_options.Saveflag = FALSE; - if (sflag > 0) { - errcode = openhydfile(p); - if (!errcode) - p->save_options.Saveflag = TRUE; - else { - errmsg(p, errcode); - return errcode; - } - } - - /* Initialize hydraulics */ - inithyd(p, fflag); - if (p->report.Statflag > 0) - writeheader(p, STATHDR, 0); - return (errcode); -} - -int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *t = 0; - if (!p->hydraulics.OpenHflag) - return (103); - errcode = runhyd(p, t); - if (errcode) - errmsg(p, errcode); - return (errcode); -} - -int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *tstep = 0; - if (!p->hydraulics.OpenHflag) - return (103); - errcode = nexthyd(p, tstep); - if (errcode) - errmsg(p, errcode); - else if (p->save_options.Saveflag && *tstep == 0) - p->save_options.SaveHflag = TRUE; - return (errcode); -} - -int DLLEXPORT EN_closeH(EN_ProjectHandle ph) -{ - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) { - return (102); - } - if (p->hydraulics.OpenHflag) { - closehyd(p); - } - p->hydraulics.OpenHflag = FALSE; - return (0); -} - - - -/* - ---------------------------------------------------------------- - Functions for running a WQ analysis - ---------------------------------------------------------------- - */ - -int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { - int errcode; - long t, tstep; - - EN_Project *p = (EN_Project*)ph; - - /* Open WQ solver */ - errcode = EN_openQ(ph); - if (!errcode) { - /* Initialize WQ */ - errcode = EN_initQ(ph, EN_SAVE); - if (p->quality.Qualflag) - writecon(FMT15); - else { - writecon(FMT16); - writewin(p->viewprog, FMT103); - } - - /* Analyze each hydraulic period */ - if (!errcode) - do { - - /* Display progress message */ - - /*** Updated 6/24/02 ***/ - sprintf(p->Msg, "%-10s", - clocktime(p->report.Atime, p->time_options.Htime)); - - writecon(p->Msg); - if (p->quality.Qualflag) { - sprintf(p->Msg, FMT102, p->report.Atime); - writewin(p->viewprog, p->Msg); - } - - /* Retrieve current network solution & update WQ to next time period */ - tstep = 0; - ERRCODE(EN_runQ(ph, &t)); - ERRCODE(EN_nextQ(ph, &tstep)); - - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b\b\b"); - - } while (tstep > 0); - } - - /* Close WQ solver */ - - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b "); - EN_closeQ(ph); - return (errcode); -} - -int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { - int errcode = 0; - - EN_Project *p = (EN_Project*)ph; - - /* Check that hydraulics results exist */ - p->quality.OpenQflag = FALSE; - p->save_options.SaveQflag = FALSE; - if (!p->Openflag) - return (102); - // !LT! todo - check for p->save_options.SaveHflag / set sequential/step mode - // if (!p->save_options.SaveHflag) return(104); - - /* Open WQ solver */ - ERRCODE(openqual(p)); - if (!errcode) - p->quality.OpenQflag = TRUE; - else - errmsg(p, errcode); - return (errcode); -} - -int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { - int errcode = 0; - - EN_Project *p = (EN_Project*)ph; - - if (!p->quality.OpenQflag) - return (105); - initqual(p); - p->save_options.SaveQflag = FALSE; - p->save_options.Saveflag = FALSE; - if (saveflag) { - errcode = openoutfile(p); - if (!errcode) - p->save_options.Saveflag = TRUE; - } - return (errcode); -} - -int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *t = 0; - if (!p->quality.OpenQflag) - return (105); - errcode = runqual(p, t); - if (errcode) - errmsg(p, errcode); - return (errcode); -} - -int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *tstep = 0; - if (!p->quality.OpenQflag) - return (105); - errcode = nextqual(p, tstep); - if (!errcode && p->save_options.Saveflag && *tstep == 0) { - p->save_options.SaveQflag = TRUE; - } - if (errcode) - errmsg(p, errcode); - return (errcode); -} - -int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *tleft = 0; - if (!p->quality.OpenQflag) - return (105); - errcode = stepqual(p, tleft); - if (!errcode && p->save_options.Saveflag && *tleft == 0) { - p->save_options.SaveQflag = TRUE; - } - if (errcode) - errmsg(p, errcode); - return (errcode); -} - -int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return (102); - closequal(p); - p->quality.OpenQflag = FALSE; - return (0); -} - /* ---------------------------------------------------------------- Functions for generating an output report @@ -2944,50 +3034,8 @@ int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { return (0); } -int DLLEXPORT EN_report(EN_ProjectHandle ph) { - int errcode; - EN_Project *p = (EN_Project*)ph; - /* Check if results saved to binary output file */ - if (!p->save_options.SaveQflag) - return (106); - errcode = writereport(p); - if (errcode) - errmsg(p, errcode); - return (errcode); -} - -int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { - int i; - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return (102); - initreport(&p->report); - for (i = 1; i <= p->network.Nnodes; i++) - p->network.Node[i].Rpt = 0; - for (i = 1; i <= p->network.Nlinks; i++) - p->network.Link[i].Rpt = 0; - return (0); -} - -int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { - char s1[MAXLINE + 1]; - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return (102); - if (strlen(s) > MAXLINE) - return (250); - strcpy(s1, s); - if (setreport(p, s1) > 0) - return (250); - else - return (0); -} @@ -3222,37 +3270,7 @@ int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer) return errorcode; } -int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { - char newMsg[MAXMSG+1]; - - switch (errcode) { - case 1: - strncpy(errmsg, WARN1, n); - break; - case 2: - strncpy(errmsg, WARN2, n); - break; - case 3: - strncpy(errmsg, WARN3, n); - break; - case 4: - strncpy(errmsg, WARN4, n); - break; - case 5: - strncpy(errmsg, WARN5, n); - break; - case 6: - strncpy(errmsg, WARN6, n); - break; - default: - geterrmsg(errcode, newMsg); - strncpy(errmsg, newMsg, n); - } - if (strlen(errmsg) == 0) - return (251); - else - return (0); -} + int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE *value) { From 606101af899f72a82fd7d4050ed55c0ee6c5979a Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 14 Aug 2018 11:10:27 -0400 Subject: [PATCH 32/45] Adding support for chem units --- tests/data/example1.out | Bin 0 -> 16832 bytes tests/test_output.cpp | 11 +- tools/epanet-output/include/epanet_output.h | 66 ++++++++---- tools/epanet-output/src/epanet_output.c | 39 ++++++- tools/epanet-output/src/messages.h | 2 +- .../epanet-output/test/epanet_output_test.py | 102 ------------------ 6 files changed, 89 insertions(+), 131 deletions(-) create mode 100644 tests/data/example1.out delete mode 100644 tools/epanet-output/test/epanet_output_test.py diff --git a/tests/data/example1.out b/tests/data/example1.out new file mode 100644 index 0000000000000000000000000000000000000000..416c98bde53c34b136525b364ade3842ec5d0f1d GIT binary patch literal 16832 zcmeI4cT^Nf_xA?`K~PB|f`K5CgCJ3;xc%a_o;BnI;#s`kK();^UzAHF5P-J5@IXLvY zjsE|^|K~@5`-puT(}Fj7-dgge$lLF8khorsx8IK`@qho`UR*D3ufSU?-oCwtxK4Z>alN>YpEYqG z;=aT>#9P*=dM1drk($7o2`*bQ!S7|Xh4gRnae)`#W*`&98hQu>d)@!rytx0a6Sos@ ztK9^GF}&%0HNuydiL_o^C*Bu)HF3Rkj#kf^Km~#gbgRw?=CI&0Ri1K%-~V=N&-W>| z>wLYq6l?f>|2o~_UYzN+9GGkS+3aH9NH!xToaH!%v&OgKOwK)=^)?M>s@Y+z%e1hs z_ZQBdxBEgbF8n~>DwWXXgUjeb-%@HBQ$`2QtfVO^g*1NM3yFrphJNA_er(Zvn`q#* zu$>;8+3i6x+-wuzrVOm4pHWxJ>&t9xsNh_ZTsi+^C2n)?wdNGkr-`+*QR~~2_#K8M zg($%CLQhbq$8m4%GHlm-Ivkd5gjb5K;7S_c-kKAjbA`EBi{NQM5v*;nbn! zSXb@V{SKsy$DX9-W{cidV%o(L#P+ z{ro1IE`t^=mq+ba*rHjBOpwb-CsgOAnCZ#ctg1PZ?eP*a^9G)$?Ly|IAY^%^;mkcDoGDs_OL!W=gzV!60T)+L zLGzQ|(}ad{dhksdUDvIGzUf#^+x97;k1bzIcyjg`#Fx<^9Q6(dX}-q#p3m{RBag6> z>2thY8i1@|3Qi0cIVkZATUEFgz*N@!Q2sN#WDt(?*BWnSQ*Z3KHV z`(}(-H2{XLevMV9J;xdGPw;i_EjDnyA-OMy?JscY(O3A=-j^6Q-os<*4aq(IJWFE! zeugD++h~w~u0rNsz5&|04(}rdo&DH$%|^-CpY#j?UJJVuw}w5cvEVeHwdefXHB*z9 zCY0Bgd4EYQ=hd{9^M2|_mpK}6?^h>^wKIFxj=b#Ok)*w{gNlotVNy&AR&%exi{*?V ztx!OW=MI8Y^`rRVk{GbA3Xt%$;LaP!t~Vr!FSD?*|7L9bCBGk%g`Dw`1{rJ@;m?sqrSh`QVE=vH`@P8c}o3kN}AdrqI5MGVD$y)x@RQ_SC+x@_p4xI)=)A;e+PW7+XaoJ0G#G4 z5b?8dYAcH-oN9?iw=zfRu~sO=+Y#OOc1PN8I-z?r)REpheWWAffrOdHDB8vD8~^lu zo;ZuV%+@CxIqTU`EHiI9D_ACC1w2#F{YC6`osezI5wZeVAv?cH%F}PLBG#cshO=%_ zP3u%D>Au7&S}?7GDow4T6Nh}FU9XhV&?RpqJf*fDCE>|@u0N#fc|#An4PQPDkali2 zwt96GPdm8^#|@h$8T;MolY!U5Ooy*#%jQ^elNPq)-pe)7o%SY_*OxKLtA=}27ta~j z4x*FW7;x74iB#M^#an~yZ>2*H1lhxGm!r7NTm0f{ah3~=`to)8!V zYl6l~csi}}3RcfF;K%hk4ys#^MFD3~(wt*h(7ziF8EZ}g;RTMdZixd9Er6t3v2gzV zfDFa#VE9nr2iGhVVCA$DeD&=S+{bD@u2%I1|66^brbHb)R_(+qwkd<)*4kgnQ}%sR zay!X|ygemH(o0@}@|!3yNw@<08$W=_lW;=%HNw@l`@v+9Eio~vmyE$ND_NBGq9s~g zV}{}?tkAu&j!0{gI~qK&GiqF?j_#e)M}m{?sNtqDs<-%-CtuzliLLe5GVYuG*4)V1 z?=q*CE$6BZMX^pDXRy}F5zO6P#HRHVv4!d)mRTWW+`4e~@~eOHSBhY7JY~66m#V4N z?T<7^SWR!cRnVf0Dr&js6W!@nLes8G{nLq!0TQ0H7y5(ykzSBBIRSgD1h_BLh%Ji~ zu&N%wLEk5mls?yHOgWBW@`n^*?Tlf%iGL!HUfk~mo7Ih<@Ys+5euek6DC*9}g`&1F*T+%9Q(E+B z;I%OCXR%DAGn7kj`?yA=Lm8U6v{P5PV!MqrIntS1uYQ4w+jr@&P9C>Z zC#RbNVDp6cxNc@TZcvp2oAD=bY=s;#k6#6Tr|WRRq6B!>SIU!;UoQArXb^1E9<=i9 zaLn0TC~-3%^AJCjW$H*&tr5f&N8@1``(fmY4DedzmofZEFeDlIL1dy8_>b-g?LQpF zMZBNg73&G1ANxX=*$%Mb)Gq9-VFE+k-u_bmgjSo9M`g|=soH_Osc1v&W<-Ib%15~4 zb{hul7Lr?UO$f<84Z%Ccl2`GV_sasonSQe9V7UV7FsB>ZZsdR*U)ZB20}dVdV2(8I zs-cDDI%wHG7j$E$AzG^QCr{#dNg6ZheJywVvCn^(9i_iph zFuF*@@;DI->MCM6O+psgKAb(BF8zMji9hanM3$4=Q$yX8tLdQuHT02o1zpx$MVCGJ zL|3dRq7E0N-|xag0wp}1iS>tWOFiLKr6w%&1Sox>4IyKOV7+~+;5GT$osk=T6GvUUf(YHY(DIr3rTJ*Nh0nKNmnva zUCKL@KB$7%q33cq$%C}ES^*BGcks<_k6`t584?}um!Y*K7`n*&!RRMeaI3F25cg}i zyIKZ*Jlqr7zwHaB+#FzOTsq$BZvwX>1bjc@?_Gp{c0X%BACKG3FeNF;&LnrdBYCt^ zncO(G8oaNml5t;d!nyfE!o4sdmdBsL4f}Cq;M-9Wo@#lX6e<)^h_gN#>Ig`dvqMpn z2|D0C1l2xQMWfobN16BR(2`mD=&GanAO7h_Jl&f8HgnL-el)o}iVc}OgI(Dh!LF_q zv33JQ>{@pbb5Rzt<6Xm<_97`ysr>Oamt?sMcWY=wUNw!5uA$33E9gUuYFhH;6CIaU zM9oX3JUzQ3p`{`Ld_fLeB&7cDs25_TVDjXzC-{ZZ8=J0N$!Y}2i({xi}HqnXD^+0wyeS)&ugYe4RfS9)qfJB1`GJj5Y zvNpaAX?{J0Trdii@HEj+78%tjB5fyq)XNW0Yo4c7K?J$%bw|@*s-mf_+atZ(cBqu+ zDdiiUq_NXK$4|~n-(@MX(F+MQr3p5%WnAu@@Ue>^Datb2=rR z@8tR82d!Ih^7m@##&$JyR7x$~7Wt8GlC7l`?>^I=Gv3oM*|)r3;`4rH;@ns?+~au) z()R#)|BmoPp1{Y!dJwC194`vhgoYm1B|LRIH2`=m>{jIx);xPC*Z0&*DjOrubzWjm zd3_mYM>cWZQuicNCD0N&pCw&UdT&<-qE(YD93nJp_HU#y9ufL~qJ?9hW`O`X+mlGzo)N z=LJ}I$A0jBkpU^`12f(x1jC?MU(m3(f$#BexLFTm(Ji|@#KC`JJ<>Ot*^oM zv(3S-RjXgh)0S{kVlc{y6f6bO^593vJC+7Z#~YD-2S-7TP6V0Ptvgw*sX;2|PbCeV zMG~G=C&{9-YKq7zyc?>Fb3nq6_GqLvhc1*@AoNBJ^?t5{#>cpzkx_{A45vW{SPdPJ~S^&++^Tf`R66f%bzDNk2wdEVk$a5=j^ z(cWKbXw=S6R5+}P`WM$y{af{P$cQp(TPWoz;mbq`PeF11u+rQUZuHlJjU51{;e_HSJqS`ZsS!+@55ukJE#D^j=h2#54M2B<@>OXi5&3=S`9ZI*5mR?2{2@V zl&A2*XK>U&mF!l~g53)(aCY7ey( zb|fYrS`yfB4$61wlMyek!#X=5sW@Un|Z0=qW`(h`OcUCqbQ5CUMV^egI+nC~K7#KPDHYKMRJ@lwVpm(R7c}lHqZ&%Khcn^ zdTMi~nciyrNblY)lJKM=A0*+a)jEIZ+{p`k5>+AbD1vTd)Zu!EOL%8NYv`$RQZn{i zpE2OIuv4DPnQ5vuH~yFscXW9jtytWR^7=AV6)U*sIvcrtMWg8X0DUgjbt@IOk2hB# z>O0zz*_k{~E!7}l-f3Jqr2^OQREG^M8ldO<5wN!N8Elxn5ZuO$m+*9S_alf@=|FDY zzKsueh`~7YB+?pv5DRuF;PiclMDbA(PRvxr0}joHvW8{Q>HN@)4nu>%=G@8G;VPteZwfyZ995OwAiK38N2D#hYh?AOKPi_}d?wtP?0w8?@zQ_>`( z4UU7aix%mystBewgc3!AE=1>EA+%E;P73OJOL+R6DvN5@DIkwsW@zo1?kMJ+Bhq;7 zjuxlsqTn_f=!mL5YBirB<9uUu|KqnjegAz+*PYKZJ*gp!zciP5&z!|R8Bb?*zeO@t z|LJUWZX`RL9?5zSjbuJG5fcBj*>E~*`A(jDSlvjSbnB_>&?Y+cemxBiZld1F0&Zx( zPxQ1;nS>{75h~$HX_G&U|Lh5adba^pTLc{<)IhIADpsDZ1SDIUOP=zW0I!8<#jj#A zrY*VTX4V0Rm9=+itrqqi%cFIedd%}!>peo!ZvdgMJmYkwWP z9`*!Y;-2=)|wN#Rg>K4a|qIOG{~{k0w`S` zN?M-oOva3V1-gfalF!If!c#)2EVBOG5+!f2L1l}~(SzI0$n3r+%8J%PMQz)m_~~Xy z-_s8no-{`{QhI*lpT5tN*!L+!FU>Su7sy-%P_+^Y3BwizPg9CLwhH=_sf;+Y6!` zU18qF*3fyr9ZY`Q5u9G`!&iJ;Lb2=~$=JUwafRAG{;8*}PGxwlapmSF#-+bZji3vL z5OAI}+l35#{#ILd*Ro;5UvJ;Gb>bb%)i z3bEhtx%_#A{G18+_CK315D022%dl}QvbM!HxR!_rIhVc70Q2;ANbH}CWz$=3|X z)B~U3fSfmZR|$L{(oJTh9{MfU1dX4{p(CC9pdDrX5$)F+X^t~OZRY79hbTvswapT} zSn2QwPvUoU(sy?|zLw%Vl=xlVj;|(Or!XQjcv}P$+vHafeEc23a=Jz^Y{$puRuN2Q zm542!Eaj6*HVPdNWQu;(>I}&vhN7`3?y>6k^f2bJ*dC z3^=?9z}bu6;5VzaCFdknPk@>nGYG^6a4bgvWbSJmbMrJ7>prM%4kmLh$Jt+1COibfTd|Ucqe>@?D2M_?aj_41b>0<6k37ID+az$-aciU zgeMwl16PXsrWVN!$*A;vOLwK3q<0S0poN>4^8TqCo6@SD`aKQf@>UI`=O%2XD{Rdr zeFU#rWbYiFk0$E1etEl(0hXlIlC|)WD{EvnbrI{ov+*68VmGF*8z=A@_Z1fBLsPh4vFNv8|5~vTM#lHiuvP)JaXq6xs@z z?ul@wzge1ps+%EXHM)6JY)AW+(QS__XzK^1bRVB1cUW6Zd+aKqGY(7F7gV1cOl<~E zf@|h-FlD0!?7mr!y9~dEj|MA3b8rIApvhQZw_L*0wcC~uFuG4_;a8q^{!5-Vl`XV) z`pQ%NPw@1>Qp%GS`i7?&f92`T=s$V7^mHgB&Cvo`GgY`Aeh({mx{bFEU4g~A=iVy7 zj(4;n)bI+E%|yS9rZXzE)9l$R#`8Akd zw;+Sz=#BDW6sR%6HMJVvX@LXF1 zo-S5~rHNTMX!un;tJ_>G*4^CVIZjE`gyjy&c)ZUp+;HtG-f$`Gm+^Fd!V~<#H48Kr zH^ame3qT>v9=Zg_K}GaqaB#Q-n$w$M-2HPPH!2k_HK>!{$G~WtBbpcBhS;Uis3LeW zN*xx07QWO&dsbl-{-Hav>+Flv9($mU8Uz0DPyd!DQSWdjv611-#Vwpg^Xq(-tisuP zeqAOLgtK=w()V|5M~AaZn_pA0?O9k%+fFZ|arcU7tX&yRjj5ztNf9*+m#$Zd*6K&! zW{iR|)sNUp*bT0}e1^xAY{wQ=by#?JF?QUv5U*H1LBdnyDI)+Y&(s57c`E#uJZ+AT zwtw}Nr&izaWc~x5;;jDUDXG^A7u_vVo^EDIc}n$~h0+WE;`!6wFXMgRq(o`+lT{Fo;-P;)~QTEM`;L(;dxS6 zCgo|Yu`kMd_E(<%&3xCIkDt;r!R2U0d9L9z&3}d0)!dSS9lqc^G zVeIL(msD(VwS{y}R4FZ;Q9xtLOQ>ega;oN?Plx#BO8iqwt3LFG{&2`|&c~*$4B*1% zTlndh_4urH87}dhjm@r2!aZaMN_cuqyF!c>OD*_1-|hHjzT@@%WBfGGY>vId*ZJ=A zH}jp-zl@*$GT-s>leN;H@zb~S-P(lS@MNnZj5_-TKRIv)=Les~ZEkpDi?&@MO*S3p zxGRB9`W7rwo`WY3K8W*GgMJxLgW~Vt@hW>jZR9;T`otSFgWB-lbzMQUKMl_A-UT*F zPvA@Ka#&p!4c=w1{@`iB*Z8T=H}l;pK7KNa{4;*~&-w1(@|4&yjEU`%TNta94`T-& zg)+|(vAuC~Q=y;UBy+FL{~mA|KHU*6It z#T*Gw@)4eN#Ku9eeaRbq?0OeSZgUL_($?Xu14USQeGu+7kzns@-V&Zh<>^9?Ch|j` z-u*{B{>WtJ4|!Vtop}6ro;>>f8ILD9Z^R>4%V9B3F`m+Re1*R!IF3?)wV#@?-TdQN zUHv4UDzL#~-7~At<8?2TKv8uA?&A`K`@i0Yt!_{GWjtN!a|6FOJp(&6i(uoI3DEwo z0le?Pz;fF)@JK%acMq0AizS<2YRzI;V)N-Ad3rM<0Eu}L$KzXe7@@p3?num2cK)C7 z_`k_NDf9U!*Fm97Yz`YjnP2x%wm&C?DVK(@oB1K^u6qa@tQR8TsVOm(J-?Gp#kOJC zJ9@yUfQH5N-1sn+)2Bs>j!O=)}M0bs$sz^~?a1f>t@c=ofkI4rOX z%P9n4L9Gp*lkFzqDLJ7NXy>`6uKAjOy3OaG#Q6eyKL5n)W7S{tPyd-O2zV*9&-$8w zD&zA{;(S3NpMUDg=bwVV=AZs9U!Yp>_xY!~)W6R^wR7O$-6wgli*LdUOb_D9qla;L zv^Ey&o>h{9Gd8t?n+j`i%(Fl|yKo;~9xu*=67q8<;M@OvKC`0JRlL*ZH1x_XfX=H& z!JN#_;HP8;2j*qK&blKo{$(*J^;!pZu?xU7r}ht?dR~;~pFH^d(|bPu)QZnP9p>{- zCiT+%6Z>D}pEex*kh$S#G_#1G$@cSWQ+5msWy$uTEYl&3Rr!Rn8oN-oc2X!SsFdsZ|S0lXA+*yy(D}Y4ZB;|K(O`~ z%u;UStG)N(yeT(vW#&Yj|IrRB%rcSiw3%oFuZ2B)wVPQ!I!xqzOcPOM$M|BoU$fg|AAdr*CD%KT9KQ_PvJu|BO&tiUL507hbQRo10~aX z=%3|}HR5$pj90H}2@9&$ z;M~_CIJEO&$vyoXOTV-Cvphw^i_5BH%pSw}wmabbzF;`dudlvVoCN)x+Y(g2 z8*Z$#!t(dmgZkaAf2m1UR z$j^OW(n6W2k959E8^*^^G!l>+)?bTLhiDx?`}i>dSCGP)-B9i4hSTf)<= z7G4sb#^F(r*T)bhWu@b>hjpO*$Rcd?AsUa(rTEDD&XTc@Y|sQ=3yXNPg&ngNa07f8 zw`WHcH5=58^7=CSJ*eW&SUPdRbKbc19@K{W?a&k|ZvXUn2Vy_Wm>9Nc2|K-fz^&{A z-eFLI+b7QhtIy5QbXgvPoSkrK`2-M7HIt0x?Vt~EIS7&6qsL?2DGfO3^C4s`!@m#a zV{GHOrsQyrBaV616)8URhPd7OAV~4bh~wky;re#asr^SjSWU<0Z*0dZsxnx7UwxNZ zK;o4qoSC&6YYaM$jc5JZ_2bK)m=VDf9Wt--7HBGE!GVhb@U9kvLDX}2;>5_ieu)ru z))My@K87OK$C5F)IY$O)oV|)(UZNj#UD<78^-_dhW`OdoLkTU literal 0 HcmV?d00001 diff --git a/tests/test_output.cpp b/tests/test_output.cpp index 3a0607e..c7fdc7a 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -22,7 +22,7 @@ #include "epanet_output.h" -#define DATA_PATH "./net1.out" +#define DATA_PATH "./example1.out" using namespace std; @@ -142,6 +142,15 @@ BOOST_FIXTURE_TEST_CASE(test_getNetSize, Fixture) ENR_free((void**)&i_array); } +BOOST_FIXTURE_TEST_CASE(test_getUnits, Fixture) { + int flag; + + error = ENR_getUnits(p_handle, ENR_chemUnits, &flag); + BOOST_REQUIRE(error == 0); + + BOOST_CHECK_EQUAL(flag, ENR_MGL); +} + BOOST_FIXTURE_TEST_CASE(test_getElementName, Fixture) { char* name = new char[MAXID]; int length, index = 1; diff --git a/tools/epanet-output/include/epanet_output.h b/tools/epanet-output/include/epanet_output.h index 0066d16..8a9b70e 100644 --- a/tools/epanet-output/include/epanet_output.h +++ b/tools/epanet-output/include/epanet_output.h @@ -18,22 +18,42 @@ typedef void* ENR_Handle; typedef enum { - ENR_node = 1, - ENR_link = 2 + ENR_node = 1, + ENR_link = 2 } ENR_ElementType; typedef enum { - ENR_getSeries = 1, - ENR_getAttribute = 2, - ENR_getResult = 3, - ENR_getReacts = 4, - ENR_getEnergy = 5 -} ENR_ApiFunction; + ENR_flowUnits = 1, + ENR_pressUnits = 2, + ENR_chemUnits = 3 +} ENR_Units; typedef enum { - ENR_flowUnits = 1, - ENR_pressUnits = 2 -} ENR_Units; + ENR_CFS = 0, + ENR_GPM = 1, + ENR_MGD = 2, + ENR_IMGD = 3, + ENR_AFD = 4, + ENR_LPS = 5, + ENR_LPM = 6, + ENR_MLD = 7, + ENR_CMH = 8, + ENR_CMD = 9 +} ENR_FlowUnits; + +typedef enum { + ENR_PSI = 0, + ENR_MTRS = 1, + ENR_KPA = 2 +} ENR_PressUnits; + +typedef enum { + ENR_NONE = 0, + ENR_MGL = 1, + ENR_UGL = 2, + ENR_HOURS = 3, + ENR_PRCNT = 4 +} ENR_ChemUnits; typedef enum { ENR_reportStart = 1, @@ -43,21 +63,21 @@ typedef enum { }ENR_Time; typedef enum { - ENR_demand = 1, - ENR_head = 2, - ENR_pressure = 3, - ENR_quality = 4 + ENR_demand = 1, + ENR_head = 2, + ENR_pressure = 3, + ENR_quality = 4 } ENR_NodeAttribute; typedef enum { - ENR_flow = 1, - ENR_velocity = 2, - ENR_headloss = 3, - ENR_avgQuality = 4, - ENR_status = 5, - ENR_setting = 6, - ENR_rxRate = 7, - ENR_frctnFctr = 8 + ENR_flow = 1, + ENR_velocity = 2, + ENR_headloss = 3, + ENR_avgQuality = 4, + ENR_status = 5, + ENR_setting = 6, + ENR_rxRate = 7, + ENR_frctnFctr = 8 } ENR_LinkAttribute; diff --git a/tools/epanet-output/src/epanet_output.c b/tools/epanet-output/src/epanet_output.c index 486ef81..7f21bee 100644 --- a/tools/epanet-output/src/epanet_output.c +++ b/tools/epanet-output/src/epanet_output.c @@ -57,7 +57,8 @@ #define MINNREC 14 // Minimum allowable number of records #define PROLOGUE 884 // Preliminary fixed length section of header -#define MAXID_P1 32 // Max. # characters in ID name +#define MAXID_P1 32 // EPANET max characters in ID name PLUS 1 +#define MAXMSG_P1 80 // EPANET max characters in message text PLUS 1 #define NELEMENTTYPES 5 // Number of element types #define NENERGYRESULTS 6 // Number of energy results @@ -303,6 +304,8 @@ int DLLEXPORT ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFlag) */ { int errorcode = 0; + F_OFF offset; + char temp[MAXID_P1]; data_t* p_data; *unitFlag = -1; @@ -315,15 +318,37 @@ int DLLEXPORT ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFlag) switch (code) { case ENR_flowUnits: - fseek(p_data->file, 9*WORDSIZE, SEEK_SET); + _fseek(p_data->file, 9*WORDSIZE, SEEK_SET); fread(unitFlag, WORDSIZE, 1, p_data->file); break; case ENR_pressUnits: - fseek(p_data->file, 10*WORDSIZE, SEEK_SET); + _fseek(p_data->file, 10*WORDSIZE, SEEK_SET); fread(unitFlag, WORDSIZE, 1, p_data->file); break; + case ENR_chemUnits: + offset = 7*WORDSIZE; + _fseek(p_data->file, offset, SEEK_SET); + fread(unitFlag, WORDSIZE, 1, p_data->file); + + if (*unitFlag == 0) *unitFlag = ENR_NONE; + + else if (*unitFlag == 1) { + offset = 15*WORDSIZE + 3*MAXMSG_P1 + 2*(MAXFNAME+1) + MAXID_P1; + _fseek(p_data->file, offset, SEEK_SET); + fread(temp, MAXID_P1, 1, p_data->file); + + if (!strcmp(temp, "mg/L")) *unitFlag = ENR_MGL; + else *unitFlag = ENR_UGL; + } + + else if (*unitFlag == 2) *unitFlag = ENR_HOURS; + + else *unitFlag = ENR_PRCNT; + + break; + default: errorcode = 421; } } @@ -378,6 +403,12 @@ int DLLEXPORT ENR_getTimes(ENR_Handle p_handle, ENR_Time code, int* time) return set_error(p_data->error_handle, errorcode); } +int DLLEXPORT ENR_getChemData(ENR_Handle p_handle, char** name, int* length) + +{ + return 0; +} + int DLLEXPORT ENR_getElementName(ENR_Handle p_handle, ENR_ElementType type, int elementIndex, char** name, int* length) /*------------------------------------------------------------------------ @@ -815,7 +846,7 @@ void errorLookup(int errcode, char* dest_msg, int dest_len) default: msg = ERRERR; } - strncpy(dest_msg, msg, MAXMSG); + strncpy(dest_msg, msg, MSGMAXLEN); } int validateFile(ENR_Handle p_handle) diff --git a/tools/epanet-output/src/messages.h b/tools/epanet-output/src/messages.h index 78725a1..d2515e9 100644 --- a/tools/epanet-output/src/messages.h +++ b/tools/epanet-output/src/messages.h @@ -10,7 +10,7 @@ #ifndef MESSAGES_H_ #define MESSAGES_H_ /*------------------- Error Messages --------------------*/ -#define MAXMSG 53 +#define MSGMAXLEN 53 #define WARN10 "Warning: model run issued warnings" diff --git a/tools/epanet-output/test/epanet_output_test.py b/tools/epanet-output/test/epanet_output_test.py deleted file mode 100644 index fa23d62..0000000 --- a/tools/epanet-output/test/epanet_output_test.py +++ /dev/null @@ -1,102 +0,0 @@ -# -# epanet_output_test.py -# -# Created: 11/8/2017 -# Author: Michael E. Tryby -# US EPA - ORD/NRMRL -# -# Unit testing for EPANET Output API using pytest. -# - -import pytest -import numpy as np - -import epanet_output as oapi - -from data import OUTPUT_FILE_EXAMPLE1 - -@pytest.fixture() -def enr_handle(request): - _handle = oapi.enr_init() - oapi.enr_open(_handle, OUTPUT_FILE_EXAMPLE1) - - def enr_close(): - oapi.enr_close() - - request.addfinalizer(enr_close) - return _handle - - -def test_get_times(enr_handle): - num_periods = oapi.enr_get_times(enr_handle, oapi.Time.NUM_PERIODS) - assert num_periods == 25 - - -# def test_get_size(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# size = oapi.enr_get_net_size(handle) -# -# print(size) -# -# handle = oapi.enr_close() -# -# def test_get_names(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# name = oapi.enr_get_element_name(handle, oapi.ElementType.NODE, 10) -# -# print(name) -# -# handle = oapi.enr_close() -# -# def test_get_energy(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# result = oapi.enr_get_energy_usage(handle, 1) -# -# print(result) -# -# handle = oapi.enr_close() -# -# def test_get_react(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# result = oapi.enr_get_net_reacts(handle) -# -# print(result) -# -# handle = oapi.enr_close() -# -def test_get_node_attribute(enr_handle): - ref_array = np.array([ 1., 0.44407997, 0.43766347, 0.42827705, 0.41342604, - 0.42804748, 0.44152543, 0.40502965, 0.38635802, 1., 0.96745253]) - - array = oapi.enr_get_node_attribute(enr_handle, 1, oapi.NodeAttribute.QUALITY) - assert len(array) == 11 - assert np.allclose(array, ref_array) - -def test_get_link_attribute(enr_handle): - ref_array = np.array([ 1848.58117676, 1220.42736816, 130.11161804, - 187.68930054, 119.88839722, 40.46448898, -748.58111572, 478.15377808, - 191.73458862, 30.11160851, 140.4644928, 59.53551483, 1848.58117676]) - - array = oapi.enr_get_link_attribute(enr_handle, 1, oapi.LinkAttribute.FLOW) - assert len(array) == 13 - assert np.allclose(array, ref_array) - -# if __name__ == "__main__": -# -# file_path = "M:\\net mydocuments\\EPA Projects\\EPAnet Examples\\net1.out" -# test_get_times(file_path) -# test_get_size(file_path) -# test_get_names(file_path) -# test_get_energy(file_path) -# test_get_react(file_path) -# test_get_node_attribute(file_path) -# test_get_link_attribute(file_path) -# \ No newline at end of file From efc44215f3ddf4ed3d54de69de4c3b504bc248a7 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 16 Aug 2018 10:26:32 -0400 Subject: [PATCH 33/45] Implementing metadata support --- tests/test_output.cpp | 2 +- tools/epanet-output/include/epanet_output.h | 6 +++--- tools/epanet-output/src/epanet_output.c | 4 ++-- tools/epanet-output/src/messages.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_output.cpp b/tests/test_output.cpp index c7fdc7a..78f55ed 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -145,7 +145,7 @@ BOOST_FIXTURE_TEST_CASE(test_getNetSize, Fixture) BOOST_FIXTURE_TEST_CASE(test_getUnits, Fixture) { int flag; - error = ENR_getUnits(p_handle, ENR_chemUnits, &flag); + error = ENR_getUnits(p_handle, ENR_qualUnits, &flag); BOOST_REQUIRE(error == 0); BOOST_CHECK_EQUAL(flag, ENR_MGL); diff --git a/tools/epanet-output/include/epanet_output.h b/tools/epanet-output/include/epanet_output.h index 8a9b70e..93a8425 100644 --- a/tools/epanet-output/include/epanet_output.h +++ b/tools/epanet-output/include/epanet_output.h @@ -25,7 +25,7 @@ typedef enum { typedef enum { ENR_flowUnits = 1, ENR_pressUnits = 2, - ENR_chemUnits = 3 + ENR_qualUnits = 3 } ENR_Units; typedef enum { @@ -43,7 +43,7 @@ typedef enum { typedef enum { ENR_PSI = 0, - ENR_MTRS = 1, + ENR_MTR = 1, ENR_KPA = 2 } ENR_PressUnits; @@ -53,7 +53,7 @@ typedef enum { ENR_UGL = 2, ENR_HOURS = 3, ENR_PRCNT = 4 -} ENR_ChemUnits; +} ENR_QualUnits; typedef enum { ENR_reportStart = 1, diff --git a/tools/epanet-output/src/epanet_output.c b/tools/epanet-output/src/epanet_output.c index 7f21bee..741304f 100644 --- a/tools/epanet-output/src/epanet_output.c +++ b/tools/epanet-output/src/epanet_output.c @@ -327,7 +327,7 @@ int DLLEXPORT ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFlag) fread(unitFlag, WORDSIZE, 1, p_data->file); break; - case ENR_chemUnits: + case ENR_qualUnits: offset = 7*WORDSIZE; _fseek(p_data->file, offset, SEEK_SET); fread(unitFlag, WORDSIZE, 1, p_data->file); @@ -846,7 +846,7 @@ void errorLookup(int errcode, char* dest_msg, int dest_len) default: msg = ERRERR; } - strncpy(dest_msg, msg, MSGMAXLEN); + strncpy(dest_msg, msg, MSG_MAXLEN); } int validateFile(ENR_Handle p_handle) diff --git a/tools/epanet-output/src/messages.h b/tools/epanet-output/src/messages.h index d2515e9..bc04a7d 100644 --- a/tools/epanet-output/src/messages.h +++ b/tools/epanet-output/src/messages.h @@ -10,7 +10,7 @@ #ifndef MESSAGES_H_ #define MESSAGES_H_ /*------------------- Error Messages --------------------*/ -#define MSGMAXLEN 53 +#define MSG_MAXLEN 53 #define WARN10 "Warning: model run issued warnings" From 26ce95673a68777ff96a75c7d121215dd5ceaf06 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 11:35:44 -0400 Subject: [PATCH 34/45] Renaming test --- tests/test_toolkit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index efb144c..b08211c 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -183,7 +183,7 @@ BOOST_FIXTURE_TEST_CASE(test_qual_step, Fixture) BOOST_REQUIRE(error == 0); } -BOOST_FIXTURE_TEST_CASE(test_hyd_qual_step, Fixture) +BOOST_FIXTURE_TEST_CASE(test_progressive_stepping, Fixture) { int flag = EN_NOSAVE; long t, tstep_h, tstep_q; From bd4c369f8339a88c9c56efb630feb6bd56d3fbed Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 14:46:45 -0400 Subject: [PATCH 35/45] Revert "Reorganizing / refactoring api functions for swig wrap" This reverts commit 8ff88f86b8803c20309a79f793eb91375df81141. --- src/epanet.c | 1038 +++++++++++++++++++++++++------------------------- 1 file changed, 510 insertions(+), 528 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index a7e6baf..8248ca8 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -137,10 +137,11 @@ execute function x and set the error code equal to its return value. // Local functions void errorLookup(int errcode, char *errmsg, int len); +/**************************************************************** -//////////////////////////////////////////////////////////////////////////////// -//-------------------- CANONICAL API - ORGANIZED BY TASK ---------------------// -//////////////////////////////////////////////////////////////////////////////// + LEGACY (v <= 2.1) API: uses global project variable + +*****************************************************************/ int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *)) @@ -2169,549 +2170,57 @@ int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { } -/* - ---------------------------------------------------------------- - Functions for running a hydraulic analysis - ---------------------------------------------------------------- - */ -int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } - -int DLLEXPORT EN_solveH(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: solves for network hydraulics in all time periods - **---------------------------------------------------------------- - */ -{ - int errcode; - long t, tstep; - - EN_Project *p = (EN_Project*)ph; - - /* Open hydraulics solver */ - errcode = EN_openH(ph); - if (!errcode) { - /* Initialize hydraulics */ - errcode = EN_initH(ph, EN_SAVE); - writecon(FMT14); - - /* Analyze each hydraulic period */ - if (!errcode) - do { - - /* Display progress message */ - - /*** Updated 6/24/02 ***/ - sprintf(p->Msg, "%-10s", - clocktime(p->report.Atime, p->time_options.Htime)); - - writecon(p->Msg); - sprintf(p->Msg, FMT101, p->report.Atime); - writewin(p->viewprog, p->Msg); - - /* Solve for hydraulics & advance to next time period */ - tstep = 0; - ERRCODE(EN_runH(ph, &t)); - ERRCODE(EN_nextH(ph, &tstep)); - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b\b\b"); - } while (tstep > 0); - } - - /* Close hydraulics solver */ - - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b "); - - EN_closeH(ph); - errcode = MAX(errcode, p->Warnflag); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); } - -int DLLEXPORT EN_openH(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: sets up data structures for hydraulic analysis - **---------------------------------------------------------------- - */ -{ - int errcode = 0; - - EN_Project *p = (EN_Project*)ph; - - /* Check that input data exists */ - p->hydraulics.OpenHflag = FALSE; - p->save_options.SaveHflag = FALSE; - if (!p->Openflag) { - return set_error(p->error_handle, 102); - } - - /* Check that previously saved hydraulics file not in use */ - if (p->out_files.Hydflag == USE) { - return set_error(p->error_handle, 107); - } - - /* Open hydraulics solver */ - ERRCODE(openhyd(p)); - if (!errcode) - p->hydraulics.OpenHflag = TRUE; - else - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); } - -int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) -/*---------------------------------------------------------------- - ** Input: flag = 2-digit flag where 1st (left) digit indicates - ** if link flows should be re-initialized (1) or - ** not (0) and 2nd digit indicates if hydraulic - ** results should be saved to file (1) or not (0) - ** Output: none - ** Returns: error code - ** Purpose: initializes hydraulic analysis - **---------------------------------------------------------------- - */ -{ - int errcode = 0; - int sflag, fflag; - - EN_Project *p = (EN_Project*)ph; - - /* Reset status flags */ - p->save_options.SaveHflag = FALSE; - p->Warnflag = FALSE; - - /* Get values of save-to-file flag and reinitialize-flows flag */ - fflag = flag / EN_INITFLOW; - sflag = flag - fflag * EN_INITFLOW; - - /* Check that hydraulics solver was opened */ - if (!p->hydraulics.OpenHflag) - return set_error(p->error_handle, 103); - - /* Open hydraulics file */ - p->save_options.Saveflag = FALSE; - if (sflag > 0) { - errcode = openhydfile(p); - if (!errcode) - p->save_options.Saveflag = TRUE; - else { - errmsg(p, errcode); - return errcode; - } - } - - /* Initialize hydraulics */ - inithyd(p, fflag); - if (p->report.Statflag > 0) - writeheader(p, STATHDR, 0); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); } - -int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *t = 0; - if (!p->hydraulics.OpenHflag) - return set_error(p->error_handle, 103); - errcode = runhyd(p, t); - if (errcode) - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } - -int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *tstep = 0; - if (!p->hydraulics.OpenHflag) - return set_error(p->error_handle, 103); - errcode = nexthyd(p, tstep); - if (errcode) - errmsg(p, errcode); - else if (p->save_options.Saveflag && *tstep == 0) - p->save_options.SaveHflag = TRUE; - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } - -int DLLEXPORT EN_closeH(EN_ProjectHandle ph) -{ - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) { - return set_error(p->error_handle, 102); - } - if (p->hydraulics.OpenHflag) { - closehyd(p); - } - p->hydraulics.OpenHflag = FALSE; - return set_error(p->error_handle, 0); -} - - -/* - ---------------------------------------------------------------- - Functions for running a WQ analysis - ---------------------------------------------------------------- - */ -int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } - -int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { - int errcode; - long t, tstep; - - EN_Project *p = (EN_Project*)ph; - - /* Open WQ solver */ - errcode = EN_openQ(ph); - if (!errcode) { - /* Initialize WQ */ - errcode = EN_initQ(ph, EN_SAVE); - if (p->quality.Qualflag) - writecon(FMT15); - else { - writecon(FMT16); - writewin(p->viewprog, FMT103); - } - - /* Analyze each hydraulic period */ - if (!errcode) - do { - - /* Display progress message */ - - /*** Updated 6/24/02 ***/ - sprintf(p->Msg, "%-10s", - clocktime(p->report.Atime, p->time_options.Htime)); - - writecon(p->Msg); - if (p->quality.Qualflag) { - sprintf(p->Msg, FMT102, p->report.Atime); - writewin(p->viewprog, p->Msg); - } - - /* Retrieve current network solution & update WQ to next time period */ - tstep = 0; - ERRCODE(EN_runQ(ph, &t)); - ERRCODE(EN_nextQ(ph, &tstep)); - - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b\b\b"); - - } while (tstep > 0); - } - - /* Close WQ solver */ - - /*** Updated 6/24/02 ***/ - writecon("\b\b\b\b\b\b\b\b "); - EN_closeQ(ph); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); } - -int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { - int errcode = 0; - - EN_Project *p = (EN_Project*)ph; - - /* Check that hydraulics results exist */ - p->quality.OpenQflag = FALSE; - p->save_options.SaveQflag = FALSE; - if (!p->Openflag) - return set_error(p->error_handle, 102); - // !LT! todo - check for p->save_options.SaveHflag / set sequential/step mode - // if (!p->save_options.SaveHflag) return(104); - - /* Open WQ solver */ - ERRCODE(openqual(p)); - if (!errcode) - p->quality.OpenQflag = TRUE; - else - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENinitQ(int saveflag) { return EN_initQ(_defaultModel, saveflag); } - -int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { - int errcode = 0; - - EN_Project *p = (EN_Project*)ph; - - if (!p->quality.OpenQflag) - return set_error(p->error_handle, 105); - initqual(p); - p->save_options.SaveQflag = FALSE; - p->save_options.Saveflag = FALSE; - if (saveflag) { - errcode = openoutfile(p); - if (!errcode) - p->save_options.Saveflag = TRUE; - } - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); } - -int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *t = 0; - if (!p->quality.OpenQflag) - return set_error(p->error_handle, 105); - errcode = runqual(p, t); - if (errcode) - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); } - -int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *tstep = 0; - if (!p->quality.OpenQflag) - return set_error(p->error_handle, 105); - errcode = nextqual(p, tstep); - if (!errcode && p->save_options.Saveflag && *tstep == 0) { - p->save_options.SaveQflag = TRUE; - } - if (errcode) - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); } - -int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - *tleft = 0; - if (!p->quality.OpenQflag) - return set_error(p->error_handle, 105); - errcode = stepqual(p, tleft); - if (!errcode && p->save_options.Saveflag && *tleft == 0) { - p->save_options.SaveQflag = TRUE; - } - if (errcode) - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); } - -int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - closequal(p); - p->quality.OpenQflag = FALSE; - return set_error(p->error_handle, 0); -} - - -/* - * Functions for generating output reports - */ -int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } - -int DLLEXPORT EN_saveH(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: saves hydraulic results to binary file. - ** - ** Must be called before ENreport() if no WQ simulation made. - ** Should not be called if ENsolveQ() will be used. - **---------------------------------------------------------------- - */ -{ - char tmpflag; - int errcode; - - EN_Project *p = (EN_Project*)ph; - - /* Check if hydraulic results exist */ - if (!p->save_options.SaveHflag) - return set_error(p->error_handle, 104); - - /* Temporarily turn off WQ analysis */ - tmpflag = p->quality.Qualflag; - p->quality.Qualflag = NONE; - - /* Call WQ solver to simply transfer results */ - /* from Hydraulics file to Output file at */ - /* fixed length reporting time intervals. */ - errcode = EN_solveQ(p); - - /* Restore WQ analysis option */ - p->quality.Qualflag = tmpflag; - if (errcode) { - errmsg(p, errcode); - } - return set_error(p->error_handle, errcode); +int DLLEXPORT ENaddpattern(char *id) { + return EN_addpattern(_defaultModel, id); } int DLLEXPORT ENsaveinpfile(char *filename) { return EN_saveinpfile(_defaultModel, filename); } -int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) -/*---------------------------------------------------------------- - ** Input: filename = name of INP file - ** Output: none - ** Returns: error code - ** Purpose: saves current data base to file - **---------------------------------------------------------------- - */ -{ - int errcode = 0; - EN_Project *p = (EN_Project*)ph; - if (!p->Openflag) - return set_error(p->error_handle, 102); - errcode = saveinpfile(p, filename); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENreport() { return EN_report(_defaultModel); } - -int DLLEXPORT EN_report(EN_ProjectHandle ph) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - /* Check if results saved to binary output file */ - if (!p->save_options.SaveQflag) - return set_error(p->error_handle, 106); - errcode = writereport(p); - if (errcode) - errmsg(p, errcode); - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } - -int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { - int i; - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - initreport(&p->report); - for (i = 1; i <= p->network.Nnodes; i++) - p->network.Node[i].Rpt = 0; - for (i = 1; i <= p->network.Nlinks; i++) - p->network.Link[i].Rpt = 0; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } - -int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { - char s1[MAXLINE + 1]; - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (strlen(s) > MAXLINE) - return set_error(p->error_handle, 250); - strcpy(s1, s); - if (setreport(p, s1) > 0) - return set_error(p->error_handle, 250); - else - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) { - return EN_geterror(errcode, errmsg, n); -} - -int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { - char newMsg[MAXMSG+1]; - - switch (errcode) { - case 1: - strncpy(errmsg, WARN1, n); - break; - case 2: - strncpy(errmsg, WARN2, n); - break; - case 3: - strncpy(errmsg, WARN3, n); - break; - case 4: - strncpy(errmsg, WARN4, n); - break; - case 5: - strncpy(errmsg, WARN5, n); - break; - case 6: - strncpy(errmsg, WARN6, n); - break; - default: - geterrmsg(errcode, newMsg); - strncpy(errmsg, newMsg, n); - } - if (strlen(errmsg) == 0) - return (251); - else - return (0); -} - - -//////////////////////////////////////////////////////////////////////////////// -//-------------------------------- NEW API -----------------------------------// -//////////////////////////////////////////////////////////////////////////////// - -int DLLEXPORT ENaddpattern(char *id) { - return EN_addpattern(_defaultModel, id); +int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } + +int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } + +int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); } + +int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); } + +int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); } + +int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } + +int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } + + + +int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } + +int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); } + +int DLLEXPORT ENinitQ(int saveflag) { + return EN_initQ(_defaultModel, saveflag); } +int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); } +int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); } +int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); } +int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); } int DLLEXPORT ENwriteline(char *line) { return EN_writeline(_defaultModel, line); } +int DLLEXPORT ENreport() { return EN_report(_defaultModel); } +int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } - +int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } @@ -2749,7 +2258,9 @@ int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, tracenode); } - +int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) { + return EN_geterror(errcode, errmsg, n); +} int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) { return EN_getstatistic(_defaultModel, code, value); @@ -3014,9 +2525,408 @@ int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, +int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) +/*---------------------------------------------------------------- + ** Input: filename = name of INP file + ** Output: none + ** Returns: error code + ** Purpose: saves current data base to file + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return (102); + return (saveinpfile(p, filename)); +} +/* + ---------------------------------------------------------------- + Functions for running a hydraulic analysis + ---------------------------------------------------------------- + */ + +int DLLEXPORT EN_solveH(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: solves for network hydraulics in all time periods + **---------------------------------------------------------------- + */ +{ + int errcode; + long t, tstep; + + EN_Project *p = (EN_Project*)ph; + + /* Open hydraulics solver */ + errcode = EN_openH(ph); + if (!errcode) { + /* Initialize hydraulics */ + errcode = EN_initH(ph, EN_SAVE); + writecon(FMT14); + + /* Analyze each hydraulic period */ + if (!errcode) + do { + + /* Display progress message */ + + /*** Updated 6/24/02 ***/ + sprintf(p->Msg, "%-10s", + clocktime(p->report.Atime, p->time_options.Htime)); + + writecon(p->Msg); + sprintf(p->Msg, FMT101, p->report.Atime); + writewin(p->viewprog, p->Msg); + + /* Solve for hydraulics & advance to next time period */ + tstep = 0; + ERRCODE(EN_runH(ph, &t)); + ERRCODE(EN_nextH(ph, &tstep)); + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b\b\b"); + } while (tstep > 0); + } + + /* Close hydraulics solver */ + + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b "); + + EN_closeH(ph); + errcode = MAX(errcode, p->Warnflag); + return (errcode); +} + +int DLLEXPORT EN_saveH(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: saves hydraulic results to binary file. + ** + ** Must be called before ENreport() if no WQ simulation made. + ** Should not be called if ENsolveQ() will be used. + **---------------------------------------------------------------- + */ +{ + char tmpflag; + int errcode; + + EN_Project *p = (EN_Project*)ph; + + /* Check if hydraulic results exist */ + if (!p->save_options.SaveHflag) + return (104); + + /* Temporarily turn off WQ analysis */ + tmpflag = p->quality.Qualflag; + p->quality.Qualflag = NONE; + + /* Call WQ solver to simply transfer results */ + /* from Hydraulics file to Output file at */ + /* fixed length reporting time intervals. */ + errcode = EN_solveQ(p); + + /* Restore WQ analysis option */ + p->quality.Qualflag = tmpflag; + if (errcode) { + errmsg(p, errcode); + } + return (errcode); +} + +int DLLEXPORT EN_openH(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: sets up data structures for hydraulic analysis + **---------------------------------------------------------------- + */ +{ + int errcode = 0; + + EN_Project *p = (EN_Project*)ph; + + /* Check that input data exists */ + p->hydraulics.OpenHflag = FALSE; + p->save_options.SaveHflag = FALSE; + if (!p->Openflag) { + return (102); + } + + /* Check that previously saved hydraulics file not in use */ + if (p->out_files.Hydflag == USE) { + return (107); + } + + /* Open hydraulics solver */ + ERRCODE(openhyd(p)); + if (!errcode) + p->hydraulics.OpenHflag = TRUE; + else + errmsg(p, errcode); + return (errcode); +} + +/*** Updated 3/1/01 ***/ +int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) +/*---------------------------------------------------------------- + ** Input: flag = 2-digit flag where 1st (left) digit indicates + ** if link flows should be re-initialized (1) or + ** not (0) and 2nd digit indicates if hydraulic + ** results should be saved to file (1) or not (0) + ** Output: none + ** Returns: error code + ** Purpose: initializes hydraulic analysis + **---------------------------------------------------------------- + */ +{ + int errcode = 0; + int sflag, fflag; + + EN_Project *p = (EN_Project*)ph; + + /* Reset status flags */ + p->save_options.SaveHflag = FALSE; + p->Warnflag = FALSE; + + /* Get values of save-to-file flag and reinitialize-flows flag */ + fflag = flag / EN_INITFLOW; + sflag = flag - fflag * EN_INITFLOW; + + /* Check that hydraulics solver was opened */ + if (!p->hydraulics.OpenHflag) + return (103); + + /* Open hydraulics file */ + p->save_options.Saveflag = FALSE; + if (sflag > 0) { + errcode = openhydfile(p); + if (!errcode) + p->save_options.Saveflag = TRUE; + else { + errmsg(p, errcode); + return errcode; + } + } + + /* Initialize hydraulics */ + inithyd(p, fflag); + if (p->report.Statflag > 0) + writeheader(p, STATHDR, 0); + return (errcode); +} + +int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *t = 0; + if (!p->hydraulics.OpenHflag) + return (103); + errcode = runhyd(p, t); + if (errcode) + errmsg(p, errcode); + return (errcode); +} + +int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *tstep = 0; + if (!p->hydraulics.OpenHflag) + return (103); + errcode = nexthyd(p, tstep); + if (errcode) + errmsg(p, errcode); + else if (p->save_options.Saveflag && *tstep == 0) + p->save_options.SaveHflag = TRUE; + return (errcode); +} + +int DLLEXPORT EN_closeH(EN_ProjectHandle ph) +{ + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) { + return (102); + } + if (p->hydraulics.OpenHflag) { + closehyd(p); + } + p->hydraulics.OpenHflag = FALSE; + return (0); +} + + + +/* + ---------------------------------------------------------------- + Functions for running a WQ analysis + ---------------------------------------------------------------- + */ + +int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { + int errcode; + long t, tstep; + + EN_Project *p = (EN_Project*)ph; + + /* Open WQ solver */ + errcode = EN_openQ(ph); + if (!errcode) { + /* Initialize WQ */ + errcode = EN_initQ(ph, EN_SAVE); + if (p->quality.Qualflag) + writecon(FMT15); + else { + writecon(FMT16); + writewin(p->viewprog, FMT103); + } + + /* Analyze each hydraulic period */ + if (!errcode) + do { + + /* Display progress message */ + + /*** Updated 6/24/02 ***/ + sprintf(p->Msg, "%-10s", + clocktime(p->report.Atime, p->time_options.Htime)); + + writecon(p->Msg); + if (p->quality.Qualflag) { + sprintf(p->Msg, FMT102, p->report.Atime); + writewin(p->viewprog, p->Msg); + } + + /* Retrieve current network solution & update WQ to next time period */ + tstep = 0; + ERRCODE(EN_runQ(ph, &t)); + ERRCODE(EN_nextQ(ph, &tstep)); + + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b\b\b"); + + } while (tstep > 0); + } + + /* Close WQ solver */ + + /*** Updated 6/24/02 ***/ + writecon("\b\b\b\b\b\b\b\b "); + EN_closeQ(ph); + return (errcode); +} + +int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { + int errcode = 0; + + EN_Project *p = (EN_Project*)ph; + + /* Check that hydraulics results exist */ + p->quality.OpenQflag = FALSE; + p->save_options.SaveQflag = FALSE; + if (!p->Openflag) + return (102); + // !LT! todo - check for p->save_options.SaveHflag / set sequential/step mode + // if (!p->save_options.SaveHflag) return(104); + + /* Open WQ solver */ + ERRCODE(openqual(p)); + if (!errcode) + p->quality.OpenQflag = TRUE; + else + errmsg(p, errcode); + return (errcode); +} + +int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { + int errcode = 0; + + EN_Project *p = (EN_Project*)ph; + + if (!p->quality.OpenQflag) + return (105); + initqual(p); + p->save_options.SaveQflag = FALSE; + p->save_options.Saveflag = FALSE; + if (saveflag) { + errcode = openoutfile(p); + if (!errcode) + p->save_options.Saveflag = TRUE; + } + return (errcode); +} + +int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *t = 0; + if (!p->quality.OpenQflag) + return (105); + errcode = runqual(p, t); + if (errcode) + errmsg(p, errcode); + return (errcode); +} + +int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *tstep = 0; + if (!p->quality.OpenQflag) + return (105); + errcode = nextqual(p, tstep); + if (!errcode && p->save_options.Saveflag && *tstep == 0) { + p->save_options.SaveQflag = TRUE; + } + if (errcode) + errmsg(p, errcode); + return (errcode); +} + +int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + *tleft = 0; + if (!p->quality.OpenQflag) + return (105); + errcode = stepqual(p, tleft); + if (!errcode && p->save_options.Saveflag && *tleft == 0) { + p->save_options.SaveQflag = TRUE; + } + if (errcode) + errmsg(p, errcode); + return (errcode); +} + +int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return (102); + closequal(p); + p->quality.OpenQflag = FALSE; + return (0); +} /* ---------------------------------------------------------------- @@ -3034,8 +2944,50 @@ int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { return (0); } +int DLLEXPORT EN_report(EN_ProjectHandle ph) { + int errcode; + EN_Project *p = (EN_Project*)ph; + /* Check if results saved to binary output file */ + if (!p->save_options.SaveQflag) + return (106); + errcode = writereport(p); + if (errcode) + errmsg(p, errcode); + return (errcode); +} + +int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { + int i; + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return (102); + initreport(&p->report); + for (i = 1; i <= p->network.Nnodes; i++) + p->network.Node[i].Rpt = 0; + for (i = 1; i <= p->network.Nlinks; i++) + p->network.Link[i].Rpt = 0; + return (0); +} + +int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { + char s1[MAXLINE + 1]; + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return (102); + if (strlen(s) > MAXLINE) + return (250); + strcpy(s1, s); + if (setreport(p, s1) > 0) + return (250); + else + return (0); +} @@ -3270,7 +3222,37 @@ int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer) return errorcode; } - +int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { + char newMsg[MAXMSG+1]; + + switch (errcode) { + case 1: + strncpy(errmsg, WARN1, n); + break; + case 2: + strncpy(errmsg, WARN2, n); + break; + case 3: + strncpy(errmsg, WARN3, n); + break; + case 4: + strncpy(errmsg, WARN4, n); + break; + case 5: + strncpy(errmsg, WARN5, n); + break; + case 6: + strncpy(errmsg, WARN6, n); + break; + default: + geterrmsg(errcode, newMsg); + strncpy(errmsg, newMsg, n); + } + if (strlen(errmsg) == 0) + return (251); + else + return (0); +} int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE *value) { From f66d4c68d925e41c48ecd02da068289f16111f00 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 14:48:20 -0400 Subject: [PATCH 36/45] Revert "Reorganizing / refactoring api functions for swig wrap" This reverts commit 437a7c70e0f481ee08d0f1c66d20c993c5fe45a9. --- src/epanet.c | 3949 +++++++++++++++++++++++++------------------------- 1 file changed, 1941 insertions(+), 2008 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 8248ca8..90b790f 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -143,20 +143,6 @@ void errorLookup(int errcode, char *errmsg, int len); *****************************************************************/ -int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, - void (*pviewprog)(char *)) -{ - int errcode = 0; - - ERRCODE(EN_alloc(&_defaultModel)); - ERRCODE(EN_epanet(_defaultModel, f1, f2, f3, pviewprog)); - ERRCODE(EN_free(&_defaultModel)); - - return errcode; -} - -int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, - const char *f3, void(*pviewprog)(char *)) /*------------------------------------------------------------------------ ** Input: f1 = pointer to name of input file ** f2 = pointer to name of report file @@ -174,2011 +160,31 @@ int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, ** needed then the argument should be NULL. **------------------------------------------------------------------------- */ -{ - int errcode = 0; - EN_Project *_p = (EN_Project*)ph; - - ERRCODE(EN_open(ph, f1, f2, f3)); - - _p->viewprog = pviewprog; - if (_p->out_files.Hydflag != USE) { - ERRCODE(EN_solveH(ph)); - } - - ERRCODE(EN_solveQ(ph)); - ERRCODE(EN_report(ph)); - EN_close(ph); - - return set_error(_p->error_handle, errcode); -} - -int DLLEXPORT ENopen(char *f1, char *f2, char *f3) +int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *)) { int errcode = 0; ERRCODE(EN_alloc(&_defaultModel)); - EN_open(_defaultModel, f1, f2, f3); + + ERRCODE(EN_epanet(_defaultModel, f1, f2, f3, pviewprog)); + + ERRCODE(EN_free(&_defaultModel)); - return (errcode); + return errcode; } -int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3) -/*---------------------------------------------------------------- - ** Input: f1 = pointer to name of input file - ** f2 = pointer to name of report file - ** f3 = pointer to name of binary output file - ** Output: none - ** Returns: error code - ** Purpose: opens EPANET input file & reads in network data - **---------------------------------------------------------------- - */ -{ +int DLLEXPORT ENopen(char *f1, char *f2, char *f3) { int errcode = 0; - -/*** Updated 9/7/00 ***/ -/* Reset math coprocessor */ -#ifdef DLL - _fpreset(); -#endif - - EN_Project *p = (EN_Project*)ph; - - /* Set system flags */ - p->Openflag = FALSE; - p->hydraulics.OpenHflag = FALSE; - p->quality.OpenQflag = FALSE; - p->save_options.SaveHflag = FALSE; - p->save_options.SaveQflag = FALSE; - p->Warnflag = FALSE; - p->parser.Coordflag = TRUE; - - /*** Updated 9/7/00 ***/ - p->report.Messageflag = TRUE; - p->report.Rptflag = 1; - - /* Initialize global pointers to NULL. */ - initpointers(p); - - /* Open input & report files */ - ERRCODE(openfiles(p, f1, f2, f3)); - if (errcode > 0) { - errmsg(p, errcode); - return set_error(p->error_handle, errcode); - } - writelogo(p); - - /* Find network size & allocate memory for data */ - writecon(FMT02); - writewin(p->viewprog, FMT100); - ERRCODE(netsize(p)); - ERRCODE(allocdata(p)); - - /* Retrieve input data */ - ERRCODE(getdata(p)); - - /* Free temporary linked lists used for Patterns & Curves */ - freeTmplist(p->parser.Patlist); - freeTmplist(p->parser.Curvelist); - - /* If using previously saved hydraulics then open its file */ - if (p->out_files.Hydflag == USE) { - ERRCODE(openhydfile(p)); - } - - /* Write input summary to report file */ - if (!errcode) { - if (p->report.Summaryflag) { - writesummary(p); - } - writetime(p, FMT104); - p->Openflag = TRUE; - } else - errmsg(p, errcode); - - return set_error(p->error_handle, errcode); -} - -int DLLEXPORT ENclose() { return EN_close(_defaultModel); } - -int DLLEXPORT EN_close(EN_ProjectHandle ph) -/*---------------------------------------------------------------- - ** Input: none - ** Output: none - ** Returns: error code - ** Purpose: frees all memory & files used by EPANET - **---------------------------------------------------------------- - */ -{ - out_file_t *out; - - EN_Project *p = (EN_Project*)ph; - - if (p->Openflag) { - writetime(p, FMT105); - } - freedata(p); - - out = &p->out_files; - - if (out->TmpOutFile != out->OutFile) { - if (out->TmpOutFile != NULL) { - fclose(out->TmpOutFile); - } - remove(out->TmpFname); - } - out->TmpOutFile = NULL; - - if (p->parser.InFile != NULL) { - fclose(p->parser.InFile); - p->parser.InFile = NULL; - } - if (p->report.RptFile != NULL && p->report.RptFile != stdout) { - fclose(p->report.RptFile); - p->report.RptFile = NULL; - } - if (out->HydFile != NULL) { - fclose(out->HydFile); - out->HydFile = NULL; - } - if (out->OutFile != NULL) { - fclose(out->OutFile); - out->OutFile = NULL; - } - - if (out->Hydflag == SCRATCH) - remove(out->HydFname); - if (out->Outflag == SCRATCH) - remove(out->OutFname); - - p->Openflag = FALSE; - p->hydraulics.OpenHflag = FALSE; - p->save_options.SaveHflag = FALSE; - p->quality.OpenQflag = FALSE; - p->save_options.SaveQflag = FALSE; - - return set_error(p->error_handle, 0); -} - - -int DLLEXPORT ENgetnodeindex(char *id, int *index) { - return EN_getnodeindex(_defaultModel, id, index); -} - -int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { - - EN_Project *p = (EN_Project*)ph; - - *index = 0; - if (!p->Openflag) - return set_error(p->error_handle, 102); - *index = findnode(&p->network,id); - if (*index == 0) - return set_error(p->error_handle, 203); - else - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetnodeid(int index, char *id) { - return EN_getnodeid(_defaultModel, index, id); -} - -int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { - - EN_Project *p = (EN_Project*)ph; - - strcpy(id, ""); - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Nnodes) - return set_error(p->error_handle, 203); - strcpy(id, p->network.Node[index].ID); - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetnodetype(int index, int *code) { - return EN_getnodetype(_defaultModel, index, code); -} - -int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { - - EN_Project *p = (EN_Project*)ph; - - *code = -1; - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Nnodes) - return set_error(p->error_handle, 203); - if (index <= p->network.Njuncs) - *code = EN_JUNCTION; - else { - if (p->network.Tank[index - p->network.Njuncs].A == 0.0) - *code = EN_RESERVOIR; - else - *code = EN_TANK; - } - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) { - return EN_getnodevalue(_defaultModel, index, code, value); -} - -int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, - EN_API_FLOAT_TYPE *value) { - double v = 0.0; - Pdemand demand; - Psource source; - - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Snode *Node = net->Node; - Stank *Tank = net->Tank; - - const int Nnodes = net->Nnodes; - const int Njuncs = net->Njuncs; - - double *Ucf = p->Ucf; - double *NodeDemand = hyd->NodeDemand; - double *NodeQual = qu->NodeQual; - - - /* Check for valid arguments */ - *value = 0.0; - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index <= 0 || index > Nnodes) - return set_error(p->error_handle, 203); - - /* Retrieve called-for parameter */ - switch (code) { - case EN_ELEVATION: - v = Node[index].El * Ucf[ELEV]; - break; - - case EN_BASEDEMAND: - v = 0.0; - /* NOTE: primary demand category is last on demand list */ - if (index <= Njuncs) - for (demand = Node[index].D; demand != NULL; demand = demand->next) - v = (demand->Base); - v *= Ucf[FLOW]; - break; - - case EN_PATTERN: - v = 0.0; - /* NOTE: primary demand category is last on demand list */ - if (index <= Njuncs) { - for (demand = Node[index].D; demand != NULL; demand = demand->next) - v = (double)(demand->Pat); - } else - v = (double)(Tank[index - Njuncs].Pat); - break; - - case EN_EMITTER: - v = 0.0; - if (Node[index].Ke > 0.0) - v = Ucf[FLOW] / pow((Ucf[PRESSURE] * Node[index].Ke), (1.0 / hyd->Qexp)); - break; - - case EN_INITQUAL: - v = Node[index].C0 * Ucf[QUALITY]; - break; - - /*** Additional parameters added for retrieval ***/ - case EN_SOURCEQUAL: - case EN_SOURCETYPE: - case EN_SOURCEMASS: - case EN_SOURCEPAT: - source = Node[index].S; - if (source == NULL) - return set_error(p->error_handle, 240); - if (code == EN_SOURCEQUAL) - v = source->C0; - else if (code == EN_SOURCEMASS) - v = source->Smass * 60.0; - else if (code == EN_SOURCEPAT) - v = source->Pat; - else - v = source->Type; - break; - - case EN_TANKLEVEL: - if (index <= Njuncs) - return set_error(p->error_handle, 251); - v = (Tank[index - Njuncs].H0 - Node[index].El) * Ucf[ELEV]; - break; - - /*** New parameter added for retrieval ***/ - case EN_INITVOLUME: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].V0 * Ucf[VOLUME]; - break; - - /*** New parameter added for retrieval ***/ - case EN_MIXMODEL: - v = MIX1; - if (index > Njuncs) - v = Tank[index - Njuncs].MixModel; - break; - - /*** New parameter added for retrieval ***/ - case EN_MIXZONEVOL: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].V1max * Ucf[VOLUME]; - break; - - case EN_DEMAND: - v = NodeDemand[index] * Ucf[FLOW]; - break; - - case EN_HEAD: - v = hyd->NodeHead[index] * Ucf[HEAD]; - break; - - case EN_PRESSURE: - v = (hyd->NodeHead[index] - Node[index].El) * Ucf[PRESSURE]; - break; - - case EN_QUALITY: - v = NodeQual[index] * Ucf[QUALITY]; - break; - - /*** New parameters added for retrieval begins here ***/ - /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ - /*** de Montreal for suggesting some of these.) ***/ - - case EN_TANKDIAM: - v = 0.0; - if (index > Njuncs) { - v = sqrt(4.0 / PI * Tank[index - Njuncs].A) * Ucf[ELEV]; - } - break; - - case EN_MINVOLUME: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Vmin * Ucf[VOLUME]; - break; - - case EN_MAXVOLUME: // !sph - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Vmax * Ucf[VOLUME]; - break; - - case EN_VOLCURVE: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Vcurve; - break; - - case EN_MINLEVEL: - v = 0.0; - if (index > Njuncs) { - v = (Tank[index - Njuncs].Hmin - Node[index].El) * Ucf[ELEV]; - } - break; - - case EN_MAXLEVEL: - v = 0.0; - if (index > Njuncs) { - v = (Tank[index - Njuncs].Hmax - Node[index].El) * Ucf[ELEV]; - } - break; - - case EN_MIXFRACTION: - v = 1.0; - if (index > Njuncs && Tank[index - Njuncs].Vmax > 0.0) { - v = Tank[index - Njuncs].V1max / Tank[index - Njuncs].Vmax; - } - break; - - case EN_TANK_KBULK: - v = 0.0; - if (index > Njuncs) - v = Tank[index - Njuncs].Kb * SECperDAY; - break; - - /*** New parameter additions ends here. ***/ - - case EN_TANKVOLUME: - if (index <= Njuncs) - return set_error(p->error_handle, 251); - v = tankvolume(p, index - Njuncs, hyd->NodeHead[index]) * Ucf[VOLUME]; - break; - - default: - return set_error(p->error_handle, 251); - } - *value = (EN_API_FLOAT_TYPE)v; - return set_error(p->error_handle, 0); -} - - -/* - ---------------------------------------------------------------- - Functions for retrieving link data - ---------------------------------------------------------------- - */ - -int DLLEXPORT ENgetlinkindex(char *id, int *index) { - return EN_getlinkindex(_defaultModel, id, index); -} - -int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { - - EN_Project *p = (EN_Project*)ph; - - *index = 0; - if (!p->Openflag) - return set_error(p->error_handle, 102); - *index = findlink(&p->network,id); - if (*index == 0) - return set_error(p->error_handle, 204); - else - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetlinkid(int index, char *id) { - return EN_getlinkid(_defaultModel, index, id); -} - -int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { - - EN_Project *p = (EN_Project*)ph; - - strcpy(id, ""); - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Nlinks) - return set_error(p->error_handle, 204); - strcpy(id, p->network.Link[index].ID); - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) { - return EN_getlinktype(_defaultModel, index, code); -} - - -int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { - - EN_Project *p = (EN_Project*)ph; - - *code = -1; - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Nlinks) - return set_error(p->error_handle, 204); - *code = p->network.Link[index].Type; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) { - return EN_getlinknodes(_defaultModel, index, node1, node2); -} - -int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, - int *node2) { - - EN_Project *p = (EN_Project*)ph; - - *node1 = 0; - *node2 = 0; - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Nlinks) - return set_error(p->error_handle, 204); - *node1 = p->network.Link[index].N1; - *node2 = p->network.Link[index].N2; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) { - return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value); -} - -int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, - EN_LinkProperty code, EN_API_FLOAT_TYPE *value) -{ - double a, h, q, v = 0.0; - int returnValue = 0; - - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - - Slink *Link = net->Link; - Spump *Pump = net->Pump; - - const int Nlinks = net->Nlinks; - - double *Ucf = p->Ucf; - double *LinkFlows = hyd->LinkFlows; - double *LinkSetting = hyd->LinkSetting; - - - - /* Check for valid arguments */ - *value = 0.0; - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index <= 0 || index > Nlinks) - return set_error(p->error_handle, 204); - - /* Retrieve called-for parameter */ - switch (code) { - case EN_DIAMETER: - if (Link[index].Type == EN_PUMP) - v = 0.0; - else - v = Link[index].Diam * Ucf[DIAM]; - break; - - case EN_LENGTH: - v = Link[index].Len * Ucf[ELEV]; - break; - - case EN_ROUGHNESS: - if (Link[index].Type <= EN_PIPE) { - if (hyd->Formflag == DW) - v = Link[index].Kc * (1000.0 * Ucf[ELEV]); - else - v = Link[index].Kc; - } else - v = 0.0; - break; - - case EN_MINORLOSS: - if (Link[index].Type != EN_PUMP) { - v = Link[index].Km; - v *= (SQR(Link[index].Diam) * SQR(Link[index].Diam) / 0.02517); - } else - v = 0.0; - break; - - case EN_INITSTATUS: - if (Link[index].Stat <= CLOSED) - v = 0.0; - else - v = 1.0; - break; - - case EN_INITSETTING: - if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) - return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); - v = Link[index].Kc; - switch (Link[index].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - v *= Ucf[PRESSURE]; - break; - case EN_FCV: - v *= Ucf[FLOW]; - default: - break; - } - break; - - case EN_KBULK: - v = Link[index].Kb * SECperDAY; - break; - - case EN_KWALL: - v = Link[index].Kw * SECperDAY; - break; - - case EN_FLOW: - - /*** Updated 10/25/00 ***/ - if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - else - v = LinkFlows[index] * Ucf[FLOW]; - break; - - case EN_VELOCITY: - if (Link[index].Type == EN_PUMP) { - v = 0.0; - } - - /*** Updated 11/19/01 ***/ - else if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - - else { - q = ABS(LinkFlows[index]); - a = PI * SQR(Link[index].Diam) / 4.0; - v = q / a * Ucf[VELOCITY]; - } - break; - - case EN_HEADLOSS: - - /*** Updated 11/19/01 ***/ - if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - - else { - h = hyd->NodeHead[Link[index].N1] - hyd->NodeHead[Link[index].N2]; - if (Link[index].Type != EN_PUMP) - h = ABS(h); - v = h * Ucf[HEADLOSS]; - } - break; - - case EN_STATUS: - if (hyd->LinkStatus[index] <= CLOSED) - v = 0.0; - else - v = 1.0; - break; - - case EN_SETTING: - if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) { - return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); - } - if (LinkSetting[index] == MISSING) { - v = 0.0; - } else { - v = LinkSetting[index]; - } - switch (Link[index].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - v *= Ucf[PRESSURE]; - break; - case EN_FCV: - v *= Ucf[FLOW]; - default: - break; - } - break; - - case EN_ENERGY: - getenergy(p, index, &v, &a); - break; - - case EN_LINKQUAL: - v = avgqual(p, index) * Ucf[LINKQUAL]; - break; - - case EN_LINKPATTERN: - if (Link[index].Type == EN_PUMP) - v = (double)Pump[findpump(&p->network, index)].Upat; - break; - - case EN_EFFICIENCY: - getenergy(p, index, &a, &v); - break; - - case EN_PRICEPATTERN: - if (Link[index].Type == EN_PUMP) - v = (double)Pump[findpump(&p->network, index)].Epat; - break; - - case EN_HEADCURVE: - if (Link[index].Type == EN_PUMP) { - v = (double)Pump[findpump(&p->network, index)].Hcurve; - if (v == 0) { - returnValue = 226; - } - } - else { - v = 0; - returnValue = 211; - } - break; - - case EN_EFFICIENCYCURVE: - if (Link[index].Type == EN_PUMP) { - v = (double)Pump[findpump(&p->network, index)].Ecurve; - if (v == 0) { - returnValue = 268; - } - } - else { - v = 0; - returnValue = 211; - } - - default: - v = 0; - returnValue = 251; - } - *value = (EN_API_FLOAT_TYPE)v; - - return set_error(p->error_handle, returnValue); -} - - -int DLLEXPORT ENgetpatternindex(char *id, int *index) { - return EN_getpatternindex(_defaultModel, id, index); -} - -int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { - int i; - - EN_Project *p = (EN_Project*)ph; - - *index = 0; - if (!p->Openflag) - return set_error(p->error_handle, 102); - for (i = 1; i <= p->network.Npats; i++) { - if (strcmp(id, p->network.Pattern[i].ID) == 0) { - *index = i; - return set_error(p->error_handle, 0); - } - } - *index = 0; - return set_error(p->error_handle, 205); -} - -int DLLEXPORT ENgetpatternid(int index, char *id) { - return EN_getpatternid(_defaultModel, index, id); -} - -int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { - - EN_Project *p = (EN_Project*)ph; - - strcpy(id, ""); - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Npats) - return set_error(p->error_handle, 205); - strcpy(id, p->network.Pattern[index].ID); - return set_error(p->error_handle, 0); -} - - -int DLLEXPORT ENgetpatternlen(int index, int *len) { - return EN_getpatternlen(_defaultModel, index, len); -} - -int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { - - EN_Project *p = (EN_Project*)ph; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index < 1 || index > p->network.Npats) - return set_error(p->error_handle, 205); - *len = p->network.Pattern[index].Length; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgetpatternvalue(int index, int period, - EN_API_FLOAT_TYPE *value) { - return EN_getpatternvalue(_defaultModel, index, period, value); -} - -int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, - EN_API_FLOAT_TYPE *value) { - - int errorcode = 0; - EN_Project *p = (EN_Project*)ph; - *value = 0.0; - - if (!p->Openflag) - errorcode = 102; - else if (index < 1 || index > p->network.Npats) - errorcode = 205; - else if (period < 1 || period > p->network.Pattern[index].Length) - errorcode = 251; - else - *value = (EN_API_FLOAT_TYPE)p->network.Pattern[index].F[period - 1]; - - return set_error(p->error_handle, errorcode); -} - -/* - ---------------------------------------------------------------- - Functions for retrieving network information - ---------------------------------------------------------------- - */ -int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, - EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) { - return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, level); -} - -int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *lindex, - EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) { - double s, lvl; - - EN_Project *pr = (EN_Project*)ph; - - EN_Network *net = &pr->network; - - Scontrol *Control = net->Control; - Snode *Node = net->Node; - Slink *Link = net->Link; - - const int Njuncs = net->Njuncs; - double *Ucf = pr->Ucf; - - s = 0.0; - lvl = 0.0; - *ctype = 0; - *lindex = 0; - *nindex = 0; - if (!pr->Openflag) - return set_error(pr->error_handle, 102); - if (cindex < 1 || cindex > net->Ncontrols) - return set_error(pr->error_handle, 241); - *ctype = Control[cindex].Type; - *lindex = Control[cindex].Link; - s = Control[cindex].Setting; - if (Control[cindex].Setting != MISSING) { - switch (Link[*lindex].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - s *= Ucf[PRESSURE]; - break; - case EN_FCV: - s *= Ucf[FLOW]; - default: - break; - } - } else if (Control[cindex].Status == OPEN) { - s = 1.0; - } - - /*** Updated 3/1/01 ***/ - else - s = 0.0; - - *nindex = Control[cindex].Node; - if (*nindex > Njuncs) - lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[ELEV]; - else if (*nindex > 0) - lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[PRESSURE]; - else - lvl = (EN_API_FLOAT_TYPE)Control[cindex].Time; - *setting = (EN_API_FLOAT_TYPE)s; - *level = (EN_API_FLOAT_TYPE)lvl; - - return set_error(pr->error_handle, 0); -} - -int DLLEXPORT ENgetcount(int code, int *count) { - return EN_getcount(_defaultModel, (EN_CountType)code, count); -} - -int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { - - EN_Project *pr = (EN_Project*)ph; - - EN_Network *net = &pr->network; - - *count = 0; - if (!pr->Openflag) - return set_error(pr->error_handle, 102); - switch (code) { - case EN_NODECOUNT: - *count = net->Nnodes; - break; - case EN_TANKCOUNT: - *count = net->Ntanks; - break; - case EN_LINKCOUNT: - *count = net->Nlinks; - break; - case EN_PATCOUNT: - *count = net->Npats; - break; - case EN_CURVECOUNT: - *count = net->Ncurves; - break; - case EN_CONTROLCOUNT: - *count = net->Ncontrols; - break; - case EN_RULECOUNT: - *count = net->Nrules; - break; - default: - return set_error(pr->error_handle, 251); - } - return set_error(pr->error_handle, 0); -} - -int DLLEXPORT ENgetflowunits(int *code) { - return EN_getflowunits(_defaultModel, code); -} - -int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { - - EN_Project *p = (EN_Project*)ph; - - *code = -1; - if (!p->Openflag) - return set_error(p->error_handle, 102); - *code = p->parser.Flowflag; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENgettimeparam(int code, long *value) { - return EN_gettimeparam(_defaultModel, code, value); -} - -int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { - int i; - - EN_Project *pr = (EN_Project*)ph; - - report_options_t *rep = &pr->report; - quality_t *qu = &pr->quality; - time_options_t *time = &pr->time_options; - - - *value = 0; - if (!pr->Openflag) - return set_error(pr->error_handle, 102); - if (code < EN_DURATION || code > EN_NEXTEVENTIDX) - return set_error(pr->error_handle, 251); - switch (code) { - case EN_DURATION: - *value = time->Dur; - break; - case EN_HYDSTEP: - *value = time->Hstep; - break; - case EN_QUALSTEP: - *value = qu->Qstep; - break; - case EN_PATTERNSTEP: - *value = time->Pstep; - break; - case EN_PATTERNSTART: - *value = time->Pstart; - break; - case EN_REPORTSTEP: - *value = time->Rstep; - break; - case EN_REPORTSTART: - *value = time->Rstart; - break; - case EN_STATISTIC: - *value = rep->Tstatflag; - break; - case EN_RULESTEP: - *value = time->Rulestep; - break; - case EN_PERIODS: - *value = rep->Nperiods; - break; - case EN_STARTTIME: - *value = time->Tstart; - break; /* Added TNT 10/2/2009 */ - case EN_HTIME: - *value = time->Htime; - break; - case EN_NEXTEVENT: - *value = time->Hstep; // find the lesser of the hydraulic time step length, or the - // time to next fill/empty - tanktimestep(pr,value); - break; - case EN_NEXTEVENTIDX: - *value = time->Hstep; - i = tanktimestep(pr, value); - *value = i; - break; - } - return set_error(pr->error_handle, 0); -} - - -int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) { - return EN_getoption(_defaultModel, (EN_Option)code, value); -} - -int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, - EN_API_FLOAT_TYPE *value) { - - EN_Project *pr = (EN_Project*)ph; - - hydraulics_t *hyd = &pr->hydraulics; - quality_t *qu = &pr->quality; - double *Ucf = pr->Ucf; - - double v = 0.0; - *value = 0.0; - if (!pr->Openflag) - return set_error(pr->error_handle,102); - switch (code) { - case EN_TRIALS: - v = (double)hyd->MaxIter; - break; - case EN_ACCURACY: - v = hyd->Hacc; - break; - case EN_TOLERANCE: - v = qu->Ctol * Ucf[QUALITY]; - break; - case EN_EMITEXPON: - if (hyd->Qexp > 0.0) - v = 1.0 / hyd->Qexp; - break; - case EN_DEMANDMULT: - v = hyd->Dmult; - break; - - case EN_HEADERROR: - v = hyd->HeadErrorLimit * Ucf[HEAD]; - break; - case EN_FLOWCHANGE: - v = hyd->FlowChangeLimit * Ucf[FLOW]; - break; - - default: - return set_error(pr->error_handle, 251); - } - *value = (EN_API_FLOAT_TYPE)v; - - return set_error(pr->error_handle, 0); -} - -int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); } - -int DLLEXPORT EN_getversion(int *v) -/*---------------------------------------------------------------- - ** Input: none - ** Output: *v = version number of the source code - ** Returns: error code (should always be 0) - ** Purpose: retrieves a number assigned to the most recent - ** update of the source code. This number, set by the - ** constant CODEVERSION found in TYPES.H, is to be - ** interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" - **---------------------------------------------------------------- - */ -{ - *v = CODEVERSION; - return (0); -} - - -/* - ---------------------------------------------------------------- - Functions for changing network data - ---------------------------------------------------------------- - */ -int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, - EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) { - return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, level); -} - -int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, - EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) { - - char status = ACTIVE; - long t = 0; - double s = setting, lvl = level; - EN_Network *net; - Snode *Node; - Slink *Link; - Scontrol *Control; - - int Nnodes; - int Njuncs; - int Nlinks; - double *Ucf; - - EN_Project *p = (EN_Project*)ph; - - /* Check that input file opened */ - if (!p->Openflag) - return set_error(p->error_handle, 102); - - /* Check that control exists */ - if (cindex < 1 || cindex > p->network.Ncontrols) - return set_error(p->error_handle, 241); - - - net = &p->network; - - Node = net->Node; - Link = net->Link; - Control = net->Control; - - Nnodes = net->Nnodes; - Njuncs = net->Njuncs; - Nlinks = net->Nlinks; - - Ucf = p->Ucf; - - /* Check that controlled link exists */ - if (lindex == 0) { - Control[cindex].Link = 0; - return set_error(p->error_handle, 0); - } - if (lindex < 0 || lindex > Nlinks) - return set_error(p->error_handle, 204); - - /* Cannot control check valve. */ - if (Link[lindex].Type == EN_CVPIPE) - return set_error(p->error_handle, 207); - - /* Check for valid parameters */ - if (ctype < 0 || ctype > EN_TIMEOFDAY) - return set_error(p->error_handle, 251); - if (ctype == EN_LOWLEVEL || ctype == EN_HILEVEL) { - if (nindex < 1 || nindex > Nnodes) - return set_error(p->error_handle, 203); - } else - nindex = 0; - if (s < 0.0 || lvl < 0.0) - return set_error(p->error_handle, 202); - - /* Adjust units of control parameters */ - switch (Link[lindex].Type) { - case EN_PRV: - case EN_PSV: - case EN_PBV: - s /= Ucf[PRESSURE]; - break; - case EN_FCV: - s /= Ucf[FLOW]; - break; - - /*** Updated 9/7/00 ***/ - case EN_GPV: - if (s == 0.0) - status = CLOSED; - else if (s == 1.0) - status = OPEN; - else - return set_error(p->error_handle, 202); - s = Link[lindex].Kc; - break; - - case EN_PIPE: - case EN_PUMP: - status = OPEN; - if (s == 0.0) - status = CLOSED; - default: - break; - } - if (ctype == LOWLEVEL || ctype == HILEVEL) { - if (nindex > Njuncs) - lvl = Node[nindex].El + level / Ucf[ELEV]; - else - lvl = Node[nindex].El + level / Ucf[PRESSURE]; - } - if (ctype == TIMER) - t = (long)ROUND(lvl); - if (ctype == TIMEOFDAY) - t = (long)ROUND(lvl) % SECperDAY; - - /* Reset control's parameters */ - Control[cindex].Type = (char)ctype; - Control[cindex].Link = lindex; - Control[cindex].Node = nindex; - Control[cindex].Status = status; - Control[cindex].Setting = s; - Control[cindex].Grade = lvl; - Control[cindex].Time = t; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) { - return EN_setnodevalue(_defaultModel, index, code, v); -} - -int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) -/*---------------------------------------------------------------- - ** Input: index = node index - ** code = node parameter code (see EPANET2.H) - ** value = parameter value - ** Output: none - ** Returns: error code - ** Purpose: sets input parameter value for a node - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Snode *Node = net->Node; - Stank *Tank = net->Tank; - - const int Nnodes = net->Nnodes; - const int Njuncs = net->Njuncs; - const int Npats = net->Npats; - - double *Ucf = p->Ucf; - - int j; - Pdemand demand; - Psource source; - double Htmp; - double value = v; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index <= 0 || index > Nnodes) - return set_error(p->error_handle, 203); - switch (code) { - case EN_ELEVATION: - if (index <= Njuncs) - Node[index].El = value / Ucf[ELEV]; - else { - value = (value / Ucf[ELEV]) - Node[index].El; - j = index - Njuncs; - Tank[j].H0 += value; - Tank[j].Hmin += value; - Tank[j].Hmax += value; - Node[index].El += value; - hyd->NodeHead[index] += value; - } - break; - - case EN_BASEDEMAND: - /* NOTE: primary demand category is last on demand list */ - if (index <= Njuncs) { - for (demand = Node[index].D; demand != NULL; demand = demand->next) { - if (demand->next == NULL) - demand->Base = value / Ucf[FLOW]; - } - } - break; - - case EN_PATTERN: - /* NOTE: primary demand category is last on demand list */ - j = ROUND(value); - if (j < 0 || j > Npats) - return (205); - if (index <= Njuncs) { - for (demand = Node[index].D; demand != NULL; demand = demand->next) { - if (demand->next == NULL) - demand->Pat = j; - } - } else - Tank[index - Njuncs].Pat = j; - break; - - case EN_EMITTER: - if (index > Njuncs) - return set_error(p->error_handle, 203); - if (value < 0.0) - return set_error(p->error_handle, 202); - if (value > 0.0) - value = pow((Ucf[FLOW] / value), hyd->Qexp) / Ucf[PRESSURE]; - Node[index].Ke = value; - break; - - case EN_INITQUAL: - if (value < 0.0) - return set_error(p->error_handle, 202); - Node[index].C0 = value / Ucf[QUALITY]; - if (index > Njuncs) - Tank[index - Njuncs].C = Node[index].C0; - break; - - case EN_SOURCEQUAL: - case EN_SOURCETYPE: - case EN_SOURCEPAT: - if (value < 0.0) - return set_error(p->error_handle, 202); - source = Node[index].S; - if (source == NULL) { - source = (struct Ssource *)malloc(sizeof(struct Ssource)); - if (source == NULL) - return set_error(p->error_handle, 101); - source->Type = CONCEN; - source->C0 = 0.0; - source->Pat = 0; - Node[index].S = source; - } - if (code == EN_SOURCEQUAL) { - source->C0 = value; - } else if (code == EN_SOURCEPAT) { - j = ROUND(value); - if (j < 0 || j > Npats) - return set_error(p->error_handle, 205); - source->Pat = j; - } else // code == EN_SOURCETYPE - { - j = ROUND(value); - if (j < CONCEN || j > FLOWPACED) - return set_error(p->error_handle, 251); - else - source->Type = (char)j; - } - return (0); - - case EN_TANKLEVEL: - if (index <= Njuncs) - return set_error(p->error_handle, 251); - j = index - Njuncs; - if (Tank[j].A == 0.0) /* Tank is a reservoir */ - { - Tank[j].H0 = value / Ucf[ELEV]; - Tank[j].Hmin = Tank[j].H0; - Tank[j].Hmax = Tank[j].H0; - Node[index].El = Tank[j].H0; - hyd->NodeHead[index] = Tank[j].H0; - } else { - value = Node[index].El + value / Ucf[ELEV]; - if (value > Tank[j].Hmax || value < Tank[j].Hmin) - return set_error(p->error_handle, 202); - Tank[j].H0 = value; - Tank[j].V0 = tankvolume(p, j, Tank[j].H0); - // Resetting Volume in addition to initial volume - Tank[j].V = Tank[j].V0; - hyd->NodeHead[index] = Tank[j].H0; - } - break; - - /*** New parameters added for retrieval begins here ***/ - /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ - /*** de Montreal for suggesting some of these.) ***/ - - case EN_TANKDIAM: - if (value <= 0.0) - return set_error(p->error_handle, 202); - if (index <= Njuncs) - return set_error(p->error_handle, 251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - value /= Ucf[ELEV]; - Tank[j].A = PI * SQR(value) / 4.0; - Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); - Tank[j].V0 = tankvolume(p, j, Tank[j].H0); - Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); - } else { - return set_error(p->error_handle, 251); - } - break; - - case EN_MINVOLUME: - if (value < 0.0) - return set_error(p->error_handle, 202); - if (index <= Njuncs) - return set_error(p->error_handle, 251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - Tank[j].Vmin = value / Ucf[VOLUME]; - Tank[j].V0 = tankvolume(p, j, Tank[j].H0); - Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); - } else { - return set_error(p->error_handle, 251); - } - break; - - case EN_MINLEVEL: - if (value < 0.0) - return set_error(p->error_handle, 202); - if (index <= Njuncs) - return set_error(p->error_handle, 251); // not a tank or reservoir - j = index - Njuncs; - if (Tank[j].A == 0.0) - return set_error(p->error_handle, 251); // node is a reservoir - Htmp = value / Ucf[ELEV] + Node[index].El; - if (Htmp < Tank[j].Hmax && Htmp <= Tank[j].H0) { - if (Tank[j].Vcurve > 0) - return set_error(p->error_handle, 202); - Tank[j].Hmin = Htmp; - Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); - } else { - return set_error(p->error_handle, 251); - } - break; - - case EN_MAXLEVEL: - if (value < 0.0) - return set_error(p->error_handle, 202); - if (index <= Njuncs) - return set_error(p->error_handle, 251); // not a tank or reservoir - j = index - Njuncs; - if (Tank[j].A == 0.0) - return set_error(p->error_handle, 251); // node is a reservoir - Htmp = value / Ucf[ELEV] + Node[index].El; - if (Htmp > Tank[j].Hmin && Htmp >= Tank[j].H0) { - if (Tank[j].Vcurve > 0) - return set_error(p->error_handle, 202); - Tank[j].Hmax = Htmp; - Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); - } else { - return set_error(p->error_handle, 251); - } - break; - - case EN_MIXMODEL: - j = ROUND(value); - if (index <= Njuncs) - return set_error(p->error_handle, 251); - if (j < MIX1 || j > LIFO) - return set_error(p->error_handle, 202); - if (index > Njuncs && Tank[index - Njuncs].A > 0.0) { - Tank[index - Njuncs].MixModel = (char)j; - } else { - return set_error(p->error_handle, 251); - } - break; - - case EN_MIXFRACTION: - if (value < 0.0 || value > 1.0) - return set_error(p->error_handle, 202); - if (index <= Njuncs) - return set_error(p->error_handle, 251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - Tank[j].V1max = value * Tank[j].Vmax; - } - break; - - case EN_TANK_KBULK: - if (index <= Njuncs) - return set_error(p->error_handle, 251); - j = index - Njuncs; - if (j > 0 && Tank[j].A > 0.0) { - Tank[j].Kb = value / SECperDAY; - qu->Reactflag = 1; - } else { - return set_error(p->error_handle, 251); - } - break; - - /*** New parameter additions ends here. ***/ - - default: - return set_error(p->error_handle, 251); - } - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) { - return EN_setlinkvalue(_defaultModel, index, code, v); -} - -int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, - EN_API_FLOAT_TYPE v) -/*---------------------------------------------------------------- - ** Input: index = link index - ** code = link parameter code (see EPANET2.H) - ** v = parameter value - ** Output: none - ** Returns: error code - ** Purpose: sets input parameter value for a link - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Slink *Link = net->Link; - - const int Nlinks = net->Nlinks; - - double *Ucf = p->Ucf; - double *LinkSetting = hyd->LinkSetting; - - char s; - double r, value = v; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index <= 0 || index > Nlinks) - return set_error(p->error_handle, 204); - switch (code) { - case EN_DIAMETER: - if (Link[index].Type != EN_PUMP) { - if (value <= 0.0) - return set_error(p->error_handle, 202); - value /= Ucf[DIAM]; /* Convert to feet */ - r = Link[index].Diam / value; /* Ratio of old to new diam */ - Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */ - Link[index].Diam = value; /* Update diameter */ - resistcoeff(p, index); /* Update resistance coeff. */ - } - break; - - case EN_LENGTH: - if (Link[index].Type <= EN_PIPE) { - if (value <= 0.0) - return set_error(p->error_handle, 202); - Link[index].Len = value / Ucf[ELEV]; - resistcoeff(p, index); - } - break; - - case EN_ROUGHNESS: - if (Link[index].Type <= EN_PIPE) { - if (value <= 0.0) - return set_error(p->error_handle, 202); - Link[index].Kc = value; - if (hyd->Formflag == DW) - Link[index].Kc /= (1000.0 * Ucf[ELEV]); - resistcoeff(p, index); - } - break; - - case EN_MINORLOSS: - if (Link[index].Type != EN_PUMP) { - if (value <= 0.0) - return set_error(p->error_handle, 202); - Link[index].Km = - 0.02517 * value / SQR(Link[index].Diam) / SQR(Link[index].Diam); - } - break; - - case EN_INITSTATUS: - case EN_STATUS: - /* Cannot set status for a check valve */ - if (Link[index].Type == EN_CVPIPE) - return set_error(p->error_handle, 207); - s = (char)ROUND(value); - if (s < 0 || s > 1) - return set_error(p->error_handle, 251); - if (code == EN_INITSTATUS) - setlinkstatus(p, index, s, &Link[index].Stat, &Link[index].Kc); - else - setlinkstatus(p, index, s, &hyd->LinkStatus[index], &LinkSetting[index]); - break; - - case EN_INITSETTING: - case EN_SETTING: - if (value < 0.0) - return set_error(p->error_handle, 202); - if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) - return (ENsetlinkvalue(index, EN_ROUGHNESS, v)); - else { - switch (Link[index].Type) { - case EN_PUMP: - break; - case EN_PRV: - case EN_PSV: - case EN_PBV: - value /= Ucf[PRESSURE]; - break; - case EN_FCV: - value /= Ucf[FLOW]; - break; - case EN_TCV: - break; - - /*** Updated 9/7/00 ***/ - case EN_GPV: - return set_error(p->error_handle, 202); /* Cannot modify setting for GPV */ - - default: - return set_error(p->error_handle, 251); - } - if (code == EN_INITSETTING) - setlinksetting(p, index, value, &Link[index].Stat, &Link[index].Kc); - else - setlinksetting(p, index, value, &hyd->LinkStatus[index], - &LinkSetting[index]); - } - break; - - case EN_KBULK: - if (Link[index].Type <= EN_PIPE) { - Link[index].Kb = value / SECperDAY; - qu->Reactflag = 1; - } - break; - - case EN_KWALL: - if (Link[index].Type <= EN_PIPE) { - Link[index].Kw = value / SECperDAY; - qu->Reactflag = 1; - } - break; - - default: - return set_error(p->error_handle, 251); - } - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) { - return EN_setpattern(_defaultModel, index, f, n); -} - -int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { - int j; - - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - Spattern *Pattern = net->Pattern; - const int Npats = net->Npats; - - - /* Check for valid arguments */ - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (index <= 0 || index > Npats) - return set_error(p->error_handle, 205); - if (n <= 0) - return set_error(p->error_handle, 202); - - /* Re-set number of time periods & reallocate memory for multipliers */ - Pattern[index].Length = n; - Pattern[index].F = (double *)realloc(Pattern[index].F, n * sizeof(double)); - if (Pattern[index].F == NULL) - return set_error(p->error_handle, 101); - - /* Load multipliers into pattern */ - for (j = 0; j < n; j++) - Pattern[index].F[j] = f[j]; - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value) { - return EN_setpatternvalue(_defaultModel, index, period, value); -} - -int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, - EN_API_FLOAT_TYPE value) { - int errorcode = 0; - - EN_Project *p = (EN_Project*)ph; - EN_Network *net = &p->network; - - Spattern *Pattern = net->Pattern; - const int Npats = net->Npats; - - - if (!p->Openflag) - errorcode = 102; - else if (index <= 0 || index > Npats) - errorcode = 205; - else if (period <= 0 || period > Pattern[index].Length) - errorcode = 251; - else - Pattern[index].F[period - 1] = value; - - return set_error(p->error_handle, errorcode); -} - -int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode) { - return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits, tracenode); -} - -int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, - char *chemunits, char *tracenode) { - - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - report_options_t *rep = &p->report; - quality_t *qu = &p->quality; - - double *Ucf = p->Ucf; - int i; - - /*** Updated 3/1/01 ***/ - double ccf = 1.0; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (qualcode < EN_NONE || qualcode > EN_TRACE) - return set_error(p->error_handle, 251); - qu->Qualflag = (char)qualcode; - qu->Ctol *= Ucf[QUALITY]; - if (qu->Qualflag == CHEM) /* Chemical constituent */ - { - strncpy(qu->ChemName, chemname, MAXID); - strncpy(qu->ChemUnits, chemunits, MAXID); - - /*** Updated 3/1/01 ***/ - strncpy(rep->Field[QUALITY].Units, qu->ChemUnits, MAXID); - strncpy(rep->Field[REACTRATE].Units, qu->ChemUnits, MAXID); - strcat(rep->Field[REACTRATE].Units, t_PERDAY); - ccf = 1.0 / LperFT3; - } - if (qu->Qualflag == TRACE) /* Source tracing option */ - { - qu->TraceNode = findnode(net,tracenode); - if (qu->TraceNode == 0) - return set_error(p->error_handle, 203); - strncpy(qu->ChemName, u_PERCENT, MAXID); - strncpy(qu->ChemUnits, tracenode, MAXID); - - /*** Updated 3/1/01 ***/ - strcpy(rep->Field[QUALITY].Units, u_PERCENT); - } - if (qu->Qualflag == AGE) /* Water age analysis */ - { - strncpy(qu->ChemName, w_AGE, MAXID); - strncpy(qu->ChemUnits, u_HOURS, MAXID); - - /*** Updated 3/1/01 ***/ - strcpy(rep->Field[QUALITY].Units, u_HOURS); - } - - /* when changing from CHEM to AGE or TRACE, nodes initial quality values must be returned to their original ones */ - if ((qu->Qualflag == AGE || qu->Qualflag == TRACE) & (Ucf[QUALITY] != 1)) { - for (i=1; i<=p->network.Nnodes; i++) { - p->network.Node[i].C0 *= Ucf[QUALITY]; - } - } - - /*** Updated 3/1/01 ***/ - Ucf[QUALITY] = ccf; - Ucf[LINKQUAL] = ccf; - Ucf[REACTRATE] = ccf; - qu->Ctol /= Ucf[QUALITY]; - - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsettimeparam(int code, long value) { - return EN_settimeparam(_defaultModel, code, value); -} - -int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) -{ - EN_Project *p = (EN_Project*)ph; - - report_options_t *rep = &p->report; - quality_t *qu = &p->quality; - time_options_t *time = &p->time_options; - - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (p->hydraulics.OpenHflag || p->quality.OpenQflag) { - // --> there's nothing wrong with changing certain time parameters during a - // simulation run, or before the run has started. - // todo -- how to tell? - /* - if (code == EN_DURATION || code == EN_HTIME || code == EN_REPORTSTEP || - code == EN_DURATION || Htime == 0) { - // it's ok - } - else { - return(109); - } - */ - } - if (value < 0) - return set_error(p->error_handle, 202); - switch (code) { - case EN_DURATION: - time->Dur = value; - if (time->Rstart > time->Dur) - time->Rstart = 0; - break; - - case EN_HYDSTEP: - if (value == 0) - return set_error(p->error_handle, 202); - time->Hstep = value; - time->Hstep = MIN(time->Pstep, time->Hstep); - time->Hstep = MIN(time->Rstep, time->Hstep); - qu->Qstep = MIN(qu->Qstep, time->Hstep); - break; - - case EN_QUALSTEP: - if (value == 0) - return set_error(p->error_handle, 202); - qu->Qstep = value; - qu->Qstep = MIN(qu->Qstep, time->Hstep); - break; - - case EN_PATTERNSTEP: - if (value == 0) - return set_error(p->error_handle, 202); - time->Pstep = value; - if (time->Hstep > time->Pstep) - time->Hstep = time->Pstep; - break; - - case EN_PATTERNSTART: - time->Pstart = value; - break; - - case EN_REPORTSTEP: - if (value == 0) - return set_error(p->error_handle, 202); - time->Rstep = value; - if (time->Hstep > time->Rstep) - time->Hstep = time->Rstep; - break; - - case EN_REPORTSTART: - if (time->Rstart > time->Dur) - return set_error(p->error_handle, 202); - time->Rstart = value; - break; - - case EN_RULESTEP: - if (value == 0) - return set_error(p->error_handle, 202); - time->Rulestep = value; - time->Rulestep = MIN(time->Rulestep, time->Hstep); - break; - - case EN_STATISTIC: - if (value > RANGE) - return set_error(p->error_handle, 202); - rep->Tstatflag = (char)value; - break; - - case EN_HTIME: - time->Htime = value; - break; - - case EN_QTIME: - qu->Qtime = value; - break; - - default: - return set_error(p->error_handle, 251); - } - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) { - return EN_setoption(_defaultModel, code, v); -} - -int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) -/*---------------------------------------------------------------- - ** Input: code = option code (see EPANET2.H) - ** v = option value - ** Output: none - ** Returns: error code - ** Purpose: sets value for an analysis option - **---------------------------------------------------------------- - */ -{ - EN_Project *p = (EN_Project*)ph; - - EN_Network *net = &p->network; - hydraulics_t *hyd = &p->hydraulics; - quality_t *qu = &p->quality; - - Snode *Node = net->Node; - const int Njuncs = net->Njuncs; - - double *Ucf = p->Ucf; - - int i, j; - double Ke, n, ucf, value = v; - if (!p->Openflag) - return set_error(p->error_handle, 102); - switch (code) { - case EN_TRIALS: - if (value < 1.0) - return set_error(p->error_handle, 202); - hyd->MaxIter = (int)value; - break; - case EN_ACCURACY: - if (value < 1.e-5 || value > 1.e-1) - return set_error(p->error_handle, 202); - hyd->Hacc = value; - break; - case EN_TOLERANCE: - if (value < 0.0) - return set_error(p->error_handle, 202); - qu->Ctol = value / Ucf[QUALITY]; - break; - case EN_EMITEXPON: - if (value <= 0.0) - return set_error(p->error_handle, 202); - n = 1.0 / value; - ucf = pow(Ucf[FLOW], n) / Ucf[PRESSURE]; - for (i = 1; i <= Njuncs; i++) { - j = ENgetnodevalue(i, EN_EMITTER, &v); - Ke = v; - if (j == 0 && Ke > 0.0) - Node[i].Ke = ucf / pow(Ke, n); - } - hyd->Qexp = n; - break; - case EN_DEMANDMULT: - if (value <= 0.0) - return set_error(p->error_handle, 202); - hyd->Dmult = value; - break; - - case EN_HEADERROR: - if (value < 0.0) - return set_error(p->error_handle, 202); - hyd->HeadErrorLimit = value / Ucf[HEAD]; - break; - case EN_FLOWCHANGE: - if (value < 0.0) - return set_error(p->error_handle, 202); - hyd->FlowChangeLimit = value / Ucf[FLOW]; - break; - - default: - return set_error(p->error_handle, 251); - } - return set_error(p->error_handle, 0); -} - - -int DLLEXPORT ENsavehydfile(char *filename) { - return EN_savehydfile(_defaultModel, filename); -} - -int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { - FILE *f; - int c; - FILE *HydFile; - - EN_Project *p = (EN_Project*)ph; - - /* Check that hydraulics results exist */ - if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) - return set_error(p->error_handle, 104); - - /* Open file */ - if ((f = fopen(filename, "w+b")) == NULL) - return set_error(p->error_handle, 305); - - /* Copy from HydFile to f */ - HydFile = p->out_files.HydFile; - fseek(HydFile, 0, SEEK_SET); - while ((c = fgetc(HydFile)) != EOF) { - fputc(c, f); - } - fclose(f); - return set_error(p->error_handle, 0); -} - -int DLLEXPORT ENusehydfile(char *filename) { - return EN_usehydfile(_defaultModel, filename); -} - -int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { - int errcode; - - EN_Project *p = (EN_Project*)ph; - - /* Check that input data exists & hydraulics system closed */ - if (!p->Openflag) - return set_error(p->error_handle, 102); - if (p->hydraulics.OpenHflag) - return set_error(p->error_handle, 108); - - /* Try to open hydraulics file */ - strncpy(p->out_files.HydFname, filename, MAXFNAME); - p->out_files.Hydflag = USE; - p->save_options.SaveHflag = TRUE; - errcode = openhydfile(p); - - /* If error, then reset flags */ - if (errcode) { - strcpy(p->out_files.HydFname, ""); - p->out_files.Hydflag = SCRATCH; - p->save_options.SaveHflag = FALSE; - } - return set_error(p->error_handle, errcode); -} - - -int DLLEXPORT ENaddpattern(char *id) { - return EN_addpattern(_defaultModel, id); + ERRCODE(EN_alloc(&_defaultModel)); + EN_open(_defaultModel, f1, f2, f3); + return (errcode); } int DLLEXPORT ENsaveinpfile(char *filename) { return EN_saveinpfile(_defaultModel, filename); } - +int DLLEXPORT ENclose() { return EN_close(_defaultModel); } int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } @@ -2194,7 +200,13 @@ int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } +int DLLEXPORT ENsavehydfile(char *filename) { + return EN_savehydfile(_defaultModel, filename); +} +int DLLEXPORT ENusehydfile(char *filename) { + return EN_usehydfile(_defaultModel, filename); +} int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } @@ -2222,14 +234,51 @@ int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } +int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); } +int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, + EN_API_FLOAT_TYPE *setting, int *nindex, + EN_API_FLOAT_TYPE *level) { + return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, + level); +} +int DLLEXPORT ENgetcount(int code, int *count) { + return EN_getcount(_defaultModel, (EN_CountType)code, count); +} + +int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) { + return EN_getoption(_defaultModel, (EN_Option)code, value); +} + +int DLLEXPORT ENgettimeparam(int code, long *value) { + return EN_gettimeparam(_defaultModel, code, value); +} + +int DLLEXPORT ENgetflowunits(int *code) { + return EN_getflowunits(_defaultModel, code); +} int DLLEXPORT ENsetflowunits(int code) { return EN_setflowunits(_defaultModel, code); } +int DLLEXPORT ENgetpatternindex(char *id, int *index) { + return EN_getpatternindex(_defaultModel, id, index); +} +int DLLEXPORT ENgetpatternid(int index, char *id) { + return EN_getpatternid(_defaultModel, index, id); +} + +int DLLEXPORT ENgetpatternlen(int index, int *len) { + return EN_getpatternlen(_defaultModel, index, len); +} + +int DLLEXPORT ENgetpatternvalue(int index, int period, + EN_API_FLOAT_TYPE *value) { + return EN_getpatternvalue(_defaultModel, index, period, value); +} int DLLEXPORT ENgetcurveindex(char *id, int *index) { return EN_getcurveindex(_defaultModel, id, index); @@ -2266,7 +315,17 @@ int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) { return EN_getstatistic(_defaultModel, code, value); } +int DLLEXPORT ENgetnodeindex(char *id, int *index) { + return EN_getnodeindex(_defaultModel, id, index); +} +int DLLEXPORT ENgetnodeid(int index, char *id) { + return EN_getnodeid(_defaultModel, index, id); +} + +int DLLEXPORT ENgetnodetype(int index, int *code) { + return EN_getnodetype(_defaultModel, index, code); +} int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { @@ -2277,6 +336,29 @@ int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { return EN_setcoord(_defaultModel, index, x, y); } +int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) { + return EN_getnodevalue(_defaultModel, index, code, value); +} + +int DLLEXPORT ENgetlinkindex(char *id, int *index) { + return EN_getlinkindex(_defaultModel, id, index); +} + +int DLLEXPORT ENgetlinkid(int index, char *id) { + return EN_getlinkid(_defaultModel, index, id); +} + +int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) { + return EN_getlinktype(_defaultModel, index, code); +} + +int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) { + return EN_getlinknodes(_defaultModel, index, node1, node2); +} + +int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) { + return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value); +} int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues, EN_API_FLOAT_TYPE **xValues, @@ -2284,9 +366,33 @@ int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues, return EN_getcurve(_defaultModel, curveIndex, id, nValues, xValues, yValues); } +int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, + EN_API_FLOAT_TYPE setting, int nindex, + EN_API_FLOAT_TYPE level) { + return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, + level); +} +int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) { + return EN_setnodevalue(_defaultModel, index, code, v); +} +int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) { + return EN_setlinkvalue(_defaultModel, index, code, v); +} +int DLLEXPORT ENaddpattern(char *id) { + return EN_addpattern(_defaultModel, id); +} + +int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) { + return EN_setpattern(_defaultModel, index, f, n); +} + +int DLLEXPORT ENsetpatternvalue(int index, int period, + EN_API_FLOAT_TYPE value) { + return EN_setpatternvalue(_defaultModel, index, period, value); +} int DLLEXPORT ENaddcurve(char *id) { return EN_addcurve(_defaultModel, id); } @@ -2300,15 +406,23 @@ int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, return EN_setcurvevalue(_defaultModel, index, pnt, x, y); } +int DLLEXPORT ENsettimeparam(int code, long value) { + return EN_settimeparam(_defaultModel, code, value); +} - - +int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) { + return EN_setoption(_defaultModel, code, v); +} int DLLEXPORT ENsetstatusreport(int code) { return EN_setstatusreport(_defaultModel, code); } - +int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, + char *tracenode) { + return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits, + tracenode); +} int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex) { return EN_getheadcurveindex(_defaultModel, index, curveindex); @@ -2459,7 +573,25 @@ int DLLEXPORT EN_free(EN_ProjectHandle *ph) return 0; } +int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, + const char *f3, void(*pviewprog)(char *)) +{ + int errcode = 0; + EN_Project *_p = (EN_Project*)ph; + ERRCODE(EN_open(ph, f1, f2, f3)); + + _p->viewprog = pviewprog; + if (_p->out_files.Hydflag != USE) { + ERRCODE(EN_solveH(ph)); + } + + ERRCODE(EN_solveQ(ph)); + ERRCODE(EN_report(ph)); + EN_close(ph); + + return set_error(_p->error_handle, errcode); +} int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula) @@ -2523,7 +655,80 @@ int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, return (errcode); } +int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3) +/*---------------------------------------------------------------- + ** Input: f1 = pointer to name of input file + ** f2 = pointer to name of report file + ** f3 = pointer to name of binary output file + ** Output: none + ** Returns: error code + ** Purpose: opens EPANET input file & reads in network data + **---------------------------------------------------------------- + */ +{ + int errcode = 0; +/*** Updated 9/7/00 ***/ +/* Reset math coprocessor */ +#ifdef DLL + _fpreset(); +#endif + + EN_Project *p = (EN_Project*)ph; + + /* Set system flags */ + p->Openflag = FALSE; + p->hydraulics.OpenHflag = FALSE; + p->quality.OpenQflag = FALSE; + p->save_options.SaveHflag = FALSE; + p->save_options.SaveQflag = FALSE; + p->Warnflag = FALSE; + p->parser.Coordflag = TRUE; + + /*** Updated 9/7/00 ***/ + p->report.Messageflag = TRUE; + p->report.Rptflag = 1; + + /* Initialize global pointers to NULL. */ + initpointers(p); + + /* Open input & report files */ + ERRCODE(openfiles(p, f1, f2, f3)); + if (errcode > 0) { + errmsg(p, errcode); + return (errcode); + } + writelogo(p); + + /* Find network size & allocate memory for data */ + writecon(FMT02); + writewin(p->viewprog, FMT100); + ERRCODE(netsize(p)); + ERRCODE(allocdata(p)); + + /* Retrieve input data */ + ERRCODE(getdata(p)); + + /* Free temporary linked lists used for Patterns & Curves */ + freeTmplist(p->parser.Patlist); + freeTmplist(p->parser.Curvelist); + + /* If using previously saved hydraulics then open its file */ + if (p->out_files.Hydflag == USE) { + ERRCODE(openhydfile(p)); + } + + /* Write input summary to report file */ + if (!errcode) { + if (p->report.Summaryflag) { + writesummary(p); + } + writetime(p, FMT104); + p->Openflag = TRUE; + } else + errmsg(p, errcode); + return (errcode); +} int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) /*---------------------------------------------------------------- @@ -2541,7 +746,63 @@ int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) return (saveinpfile(p, filename)); } +int DLLEXPORT EN_close(EN_ProjectHandle ph) +/*---------------------------------------------------------------- + ** Input: none + ** Output: none + ** Returns: error code + ** Purpose: frees all memory & files used by EPANET + **---------------------------------------------------------------- + */ +{ + out_file_t *out; + EN_Project *p = (EN_Project*)ph; + + if (p->Openflag) { + writetime(p, FMT105); + } + freedata(p); + + out = &p->out_files; + + if (out->TmpOutFile != out->OutFile) { + if (out->TmpOutFile != NULL) { + fclose(out->TmpOutFile); + } + remove(out->TmpFname); + } + out->TmpOutFile = NULL; + + if (p->parser.InFile != NULL) { + fclose(p->parser.InFile); + p->parser.InFile = NULL; + } + if (p->report.RptFile != NULL && p->report.RptFile != stdout) { + fclose(p->report.RptFile); + p->report.RptFile = NULL; + } + if (out->HydFile != NULL) { + fclose(out->HydFile); + out->HydFile = NULL; + } + if (out->OutFile != NULL) { + fclose(out->OutFile); + out->OutFile = NULL; + } + + if (out->Hydflag == SCRATCH) + remove(out->HydFname); + if (out->Outflag == SCRATCH) + remove(out->OutFname); + + p->Openflag = FALSE; + p->hydraulics.OpenHflag = FALSE; + p->save_options.SaveHflag = FALSE; + p->quality.OpenQflag = FALSE; + p->save_options.SaveQflag = FALSE; + return (0); +} /* ---------------------------------------------------------------- @@ -2768,7 +1029,56 @@ int DLLEXPORT EN_closeH(EN_ProjectHandle ph) return (0); } +int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { + FILE *f; + int c; + FILE *HydFile; + + EN_Project *p = (EN_Project*)ph; + /* Check that hydraulics results exist */ + if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) + return (104); + + /* Open file */ + if ((f = fopen(filename, "w+b")) == NULL) + return (305); + + /* Copy from HydFile to f */ + HydFile = p->out_files.HydFile; + fseek(HydFile, 0, SEEK_SET); + while ((c = fgetc(HydFile)) != EOF) { + fputc(c, f); + } + fclose(f); + return (0); +} + +int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { + int errcode; + + EN_Project *p = (EN_Project*)ph; + + /* Check that input data exists & hydraulics system closed */ + if (!p->Openflag) + return (102); + if (p->hydraulics.OpenHflag) + return (108); + + /* Try to open hydraulics file */ + strncpy(p->out_files.HydFname, filename, MAXFNAME); + p->out_files.Hydflag = USE; + p->save_options.SaveHflag = TRUE; + errcode = openhydfile(p); + + /* If error, then reset flags */ + if (errcode) { + strcpy(p->out_files.HydFname, ""); + p->out_files.Hydflag = SCRATCH; + p->save_options.SaveHflag = FALSE; + } + return (errcode); +} /* ---------------------------------------------------------------- @@ -2989,11 +1299,247 @@ int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { return (0); } +/* + ---------------------------------------------------------------- + Functions for retrieving network information + ---------------------------------------------------------------- + */ + +/*** Updated 10/25/00 ***/ +int DLLEXPORT EN_getversion(int *v) +/*---------------------------------------------------------------- + ** Input: none + ** Output: *v = version number of the source code + ** Returns: error code (should always be 0) + ** Purpose: retrieves a number assigned to the most recent + ** update of the source code. This number, set by the + ** constant CODEVERSION found in TYPES.H, is to be + ** interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" + **---------------------------------------------------------------- + */ +{ + *v = CODEVERSION; + return (0); +} + +int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *lindex, + EN_API_FLOAT_TYPE *setting, int *nindex, + EN_API_FLOAT_TYPE *level) { + double s, lvl; + + EN_Project *pr = (EN_Project*)ph; + + EN_Network *net = &pr->network; + + Scontrol *Control = net->Control; + Snode *Node = net->Node; + Slink *Link = net->Link; + + const int Njuncs = net->Njuncs; + double *Ucf = pr->Ucf; + + s = 0.0; + lvl = 0.0; + *ctype = 0; + *lindex = 0; + *nindex = 0; + if (!pr->Openflag) + return (102); + if (cindex < 1 || cindex > net->Ncontrols) + return (241); + *ctype = Control[cindex].Type; + *lindex = Control[cindex].Link; + s = Control[cindex].Setting; + if (Control[cindex].Setting != MISSING) { + switch (Link[*lindex].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + s *= Ucf[PRESSURE]; + break; + case EN_FCV: + s *= Ucf[FLOW]; + default: + break; + } + } else if (Control[cindex].Status == OPEN) { + s = 1.0; + } + + /*** Updated 3/1/01 ***/ + else + s = 0.0; + + *nindex = Control[cindex].Node; + if (*nindex > Njuncs) + lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[ELEV]; + else if (*nindex > 0) + lvl = (Control[cindex].Grade - Node[*nindex].El) * Ucf[PRESSURE]; + else + lvl = (EN_API_FLOAT_TYPE)Control[cindex].Time; + *setting = (EN_API_FLOAT_TYPE)s; + *level = (EN_API_FLOAT_TYPE)lvl; + return (0); +} + +int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { + + EN_Project *pr = (EN_Project*)ph; + + EN_Network *net = &pr->network; + + *count = 0; + if (!pr->Openflag) + return (102); + switch (code) { + case EN_NODECOUNT: + *count = net->Nnodes; + break; + case EN_TANKCOUNT: + *count = net->Ntanks; + break; + case EN_LINKCOUNT: + *count = net->Nlinks; + break; + case EN_PATCOUNT: + *count = net->Npats; + break; + case EN_CURVECOUNT: + *count = net->Ncurves; + break; + case EN_CONTROLCOUNT: + *count = net->Ncontrols; + break; + case EN_RULECOUNT: + *count = net->Nrules; + break; + default: + return (251); + } + return (0); +} + +int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, + EN_API_FLOAT_TYPE *value) { + + EN_Project *pr = (EN_Project*)ph; + + hydraulics_t *hyd = &pr->hydraulics; + quality_t *qu = &pr->quality; + double *Ucf = pr->Ucf; + + double v = 0.0; + *value = 0.0; + if (!pr->Openflag) + return (102); + switch (code) { + case EN_TRIALS: + v = (double)hyd->MaxIter; + break; + case EN_ACCURACY: + v = hyd->Hacc; + break; + case EN_TOLERANCE: + v = qu->Ctol * Ucf[QUALITY]; + break; + case EN_EMITEXPON: + if (hyd->Qexp > 0.0) + v = 1.0 / hyd->Qexp; + break; + case EN_DEMANDMULT: + v = hyd->Dmult; + break; + + case EN_HEADERROR: + v = hyd->HeadErrorLimit * Ucf[HEAD]; + break; + case EN_FLOWCHANGE: + v = hyd->FlowChangeLimit * Ucf[FLOW]; + break; + + default: + return (251); + } + *value = (EN_API_FLOAT_TYPE)v; + return (0); +} + +int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { + int i; + + EN_Project *pr = (EN_Project*)ph; + + report_options_t *rep = &pr->report; + quality_t *qu = &pr->quality; + time_options_t *time = &pr->time_options; + *value = 0; + if (!pr->Openflag) + return (102); + if (code < EN_DURATION || code > EN_NEXTEVENTIDX) + return (251); + switch (code) { + case EN_DURATION: + *value = time->Dur; + break; + case EN_HYDSTEP: + *value = time->Hstep; + break; + case EN_QUALSTEP: + *value = qu->Qstep; + break; + case EN_PATTERNSTEP: + *value = time->Pstep; + break; + case EN_PATTERNSTART: + *value = time->Pstart; + break; + case EN_REPORTSTEP: + *value = time->Rstep; + break; + case EN_REPORTSTART: + *value = time->Rstart; + break; + case EN_STATISTIC: + *value = rep->Tstatflag; + break; + case EN_RULESTEP: + *value = time->Rulestep; + break; + case EN_PERIODS: + *value = rep->Nperiods; + break; + case EN_STARTTIME: + *value = time->Tstart; + break; /* Added TNT 10/2/2009 */ + case EN_HTIME: + *value = time->Htime; + break; + case EN_NEXTEVENT: + *value = time->Hstep; // find the lesser of the hydraulic time step length, or the + // time to next fill/empty + tanktimestep(pr,value); + break; + case EN_NEXTEVENTIDX: + *value = time->Hstep; + i = tanktimestep(pr, value); + *value = i; + break; + } + return (0); +} +int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { + EN_Project *p = (EN_Project*)ph; + *code = -1; + if (!p->Openflag) + return (102); + *code = p->parser.Flowflag; + return (0); +} int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { int i, j; @@ -3072,6 +1618,64 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { return(0); } +int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { + int i; + + EN_Project *p = (EN_Project*)ph; + + *index = 0; + if (!p->Openflag) + return (102); + for (i = 1; i <= p->network.Npats; i++) { + if (strcmp(id, p->network.Pattern[i].ID) == 0) { + *index = i; + return (0); + } + } + *index = 0; + return (205); +} + +int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project *p = (EN_Project*)ph; + + strcpy(id, ""); + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Npats) + return (205); + strcpy(id, p->network.Pattern[index].ID); + return (0); +} + +int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { + + EN_Project *p = (EN_Project*)ph; + + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Npats) + return (205); + *len = p->network.Pattern[index].Length; + return (0); +} + +int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, + EN_API_FLOAT_TYPE *value) { + + EN_Project *p = (EN_Project*)ph; + + *value = 0.0; + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Npats) + return (205); + if (period < 1 || period > p->network.Pattern[index].Length) + return (251); + *value = (EN_API_FLOAT_TYPE)p->network.Pattern[index].F[period - 1]; + return (0); +} int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { int i; @@ -3277,7 +1881,52 @@ int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE * ---------------------------------------------------------------- */ +int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { + EN_Project *p = (EN_Project*)ph; + + *index = 0; + if (!p->Openflag) + return (102); + *index = findnode(&p->network,id); + if (*index == 0) + return (203); + else + return (0); +} + +int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project *p = (EN_Project*)ph; + + strcpy(id, ""); + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Nnodes) + return (203); + strcpy(id, p->network.Node[index].ID); + return (0); +} + +int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { + + EN_Project *p = (EN_Project*)ph; + + *code = -1; + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Nnodes) + return (203); + if (index <= p->network.Njuncs) + *code = EN_JUNCTION; + else { + if (p->network.Tank[index - p->network.Njuncs].A == 0.0) + *code = EN_RESERVOIR; + else + *code = EN_TANK; + } + return (0); +} int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) { @@ -3319,8 +1968,478 @@ int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, return 0; } +int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, + EN_API_FLOAT_TYPE *value) { + double v = 0.0; + Pdemand demand; + Psource source; + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Snode *Node = net->Node; + Stank *Tank = net->Tank; + + const int Nnodes = net->Nnodes; + const int Njuncs = net->Njuncs; + + double *Ucf = p->Ucf; + double *NodeDemand = hyd->NodeDemand; + double *NodeQual = qu->NodeQual; + + + /* Check for valid arguments */ + *value = 0.0; + if (!p->Openflag) + return (102); + if (index <= 0 || index > Nnodes) + return (203); + /* Retrieve called-for parameter */ + switch (code) { + case EN_ELEVATION: + v = Node[index].El * Ucf[ELEV]; + break; + + case EN_BASEDEMAND: + v = 0.0; + /* NOTE: primary demand category is last on demand list */ + if (index <= Njuncs) + for (demand = Node[index].D; demand != NULL; demand = demand->next) + v = (demand->Base); + v *= Ucf[FLOW]; + break; + + case EN_PATTERN: + v = 0.0; + /* NOTE: primary demand category is last on demand list */ + if (index <= Njuncs) { + for (demand = Node[index].D; demand != NULL; demand = demand->next) + v = (double)(demand->Pat); + } else + v = (double)(Tank[index - Njuncs].Pat); + break; + + case EN_EMITTER: + v = 0.0; + if (Node[index].Ke > 0.0) + v = Ucf[FLOW] / pow((Ucf[PRESSURE] * Node[index].Ke), (1.0 / hyd->Qexp)); + break; + + case EN_INITQUAL: + v = Node[index].C0 * Ucf[QUALITY]; + break; + + /*** Additional parameters added for retrieval ***/ + case EN_SOURCEQUAL: + case EN_SOURCETYPE: + case EN_SOURCEMASS: + case EN_SOURCEPAT: + source = Node[index].S; + if (source == NULL) + return (240); + if (code == EN_SOURCEQUAL) + v = source->C0; + else if (code == EN_SOURCEMASS) + v = source->Smass * 60.0; + else if (code == EN_SOURCEPAT) + v = source->Pat; + else + v = source->Type; + break; + + case EN_TANKLEVEL: + if (index <= Njuncs) + return (251); + v = (Tank[index - Njuncs].H0 - Node[index].El) * Ucf[ELEV]; + break; + + /*** New parameter added for retrieval ***/ + case EN_INITVOLUME: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].V0 * Ucf[VOLUME]; + break; + + /*** New parameter added for retrieval ***/ + case EN_MIXMODEL: + v = MIX1; + if (index > Njuncs) + v = Tank[index - Njuncs].MixModel; + break; + + /*** New parameter added for retrieval ***/ + case EN_MIXZONEVOL: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].V1max * Ucf[VOLUME]; + break; + + case EN_DEMAND: + v = NodeDemand[index] * Ucf[FLOW]; + break; + + case EN_HEAD: + v = hyd->NodeHead[index] * Ucf[HEAD]; + break; + + case EN_PRESSURE: + v = (hyd->NodeHead[index] - Node[index].El) * Ucf[PRESSURE]; + break; + + case EN_QUALITY: + v = NodeQual[index] * Ucf[QUALITY]; + break; + + /*** New parameters added for retrieval begins here ***/ + /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ + /*** de Montreal for suggesting some of these.) ***/ + + case EN_TANKDIAM: + v = 0.0; + if (index > Njuncs) { + v = sqrt(4.0 / PI * Tank[index - Njuncs].A) * Ucf[ELEV]; + } + break; + + case EN_MINVOLUME: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Vmin * Ucf[VOLUME]; + break; + + case EN_MAXVOLUME: // !sph + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Vmax * Ucf[VOLUME]; + break; + + case EN_VOLCURVE: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Vcurve; + break; + + case EN_MINLEVEL: + v = 0.0; + if (index > Njuncs) { + v = (Tank[index - Njuncs].Hmin - Node[index].El) * Ucf[ELEV]; + } + break; + + case EN_MAXLEVEL: + v = 0.0; + if (index > Njuncs) { + v = (Tank[index - Njuncs].Hmax - Node[index].El) * Ucf[ELEV]; + } + break; + + case EN_MIXFRACTION: + v = 1.0; + if (index > Njuncs && Tank[index - Njuncs].Vmax > 0.0) { + v = Tank[index - Njuncs].V1max / Tank[index - Njuncs].Vmax; + } + break; + + case EN_TANK_KBULK: + v = 0.0; + if (index > Njuncs) + v = Tank[index - Njuncs].Kb * SECperDAY; + break; + + /*** New parameter additions ends here. ***/ + + case EN_TANKVOLUME: + if (index <= Njuncs) + return (251); + v = tankvolume(p, index - Njuncs, hyd->NodeHead[index]) * Ucf[VOLUME]; + break; + + default: + return (251); + } + *value = (EN_API_FLOAT_TYPE)v; + return (0); +} + +/* + ---------------------------------------------------------------- + Functions for retrieving link data + ---------------------------------------------------------------- + */ + +int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { + + EN_Project *p = (EN_Project*)ph; + + *index = 0; + if (!p->Openflag) + return (102); + *index = findlink(&p->network,id); + if (*index == 0) + return (204); + else + return (0); +} + +int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { + + EN_Project *p = (EN_Project*)ph; + + strcpy(id, ""); + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Nlinks) + return (204); + strcpy(id, p->network.Link[index].ID); + return (0); +} + +int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { + + EN_Project *p = (EN_Project*)ph; + + *code = -1; + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Nlinks) + return (204); + *code = p->network.Link[index].Type; + return (0); +} + +int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, + int *node2) { + + EN_Project *p = (EN_Project*)ph; + + *node1 = 0; + *node2 = 0; + if (!p->Openflag) + return (102); + if (index < 1 || index > p->network.Nlinks) + return (204); + *node1 = p->network.Link[index].N1; + *node2 = p->network.Link[index].N2; + return (0); +} + +int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, + EN_API_FLOAT_TYPE *value) { + double a, h, q, v = 0.0; + int returnValue = 0; + + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + + Slink *Link = net->Link; + Spump *Pump = net->Pump; + + const int Nlinks = net->Nlinks; + + double *Ucf = p->Ucf; + double *LinkFlows = hyd->LinkFlows; + double *LinkSetting = hyd->LinkSetting; + + + + /* Check for valid arguments */ + *value = 0.0; + if (!p->Openflag) + return (102); + if (index <= 0 || index > Nlinks) + return (204); + + /* Retrieve called-for parameter */ + switch (code) { + case EN_DIAMETER: + if (Link[index].Type == EN_PUMP) + v = 0.0; + else + v = Link[index].Diam * Ucf[DIAM]; + break; + + case EN_LENGTH: + v = Link[index].Len * Ucf[ELEV]; + break; + + case EN_ROUGHNESS: + if (Link[index].Type <= EN_PIPE) { + if (hyd->Formflag == DW) + v = Link[index].Kc * (1000.0 * Ucf[ELEV]); + else + v = Link[index].Kc; + } else + v = 0.0; + break; + + case EN_MINORLOSS: + if (Link[index].Type != EN_PUMP) { + v = Link[index].Km; + v *= (SQR(Link[index].Diam) * SQR(Link[index].Diam) / 0.02517); + } else + v = 0.0; + break; + + case EN_INITSTATUS: + if (Link[index].Stat <= CLOSED) + v = 0.0; + else + v = 1.0; + break; + + case EN_INITSETTING: + if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) + return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); + v = Link[index].Kc; + switch (Link[index].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + v *= Ucf[PRESSURE]; + break; + case EN_FCV: + v *= Ucf[FLOW]; + default: + break; + } + break; + + case EN_KBULK: + v = Link[index].Kb * SECperDAY; + break; + + case EN_KWALL: + v = Link[index].Kw * SECperDAY; + break; + + case EN_FLOW: + + /*** Updated 10/25/00 ***/ + if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + else + v = LinkFlows[index] * Ucf[FLOW]; + break; + + case EN_VELOCITY: + if (Link[index].Type == EN_PUMP) { + v = 0.0; + } + + /*** Updated 11/19/01 ***/ + else if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + + else { + q = ABS(LinkFlows[index]); + a = PI * SQR(Link[index].Diam) / 4.0; + v = q / a * Ucf[VELOCITY]; + } + break; + + case EN_HEADLOSS: + + /*** Updated 11/19/01 ***/ + if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + + else { + h = hyd->NodeHead[Link[index].N1] - hyd->NodeHead[Link[index].N2]; + if (Link[index].Type != EN_PUMP) + h = ABS(h); + v = h * Ucf[HEADLOSS]; + } + break; + + case EN_STATUS: + if (hyd->LinkStatus[index] <= CLOSED) + v = 0.0; + else + v = 1.0; + break; + + case EN_SETTING: + if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) { + return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); + } + if (LinkSetting[index] == MISSING) { + v = 0.0; + } else { + v = LinkSetting[index]; + } + switch (Link[index].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + v *= Ucf[PRESSURE]; + break; + case EN_FCV: + v *= Ucf[FLOW]; + default: + break; + } + break; + + case EN_ENERGY: + getenergy(p, index, &v, &a); + break; + + case EN_LINKQUAL: + v = avgqual(p, index) * Ucf[LINKQUAL]; + break; + + case EN_LINKPATTERN: + if (Link[index].Type == EN_PUMP) + v = (double)Pump[findpump(&p->network, index)].Upat; + break; + + case EN_EFFICIENCY: + getenergy(p, index, &a, &v); + break; + + case EN_PRICEPATTERN: + if (Link[index].Type == EN_PUMP) + v = (double)Pump[findpump(&p->network, index)].Epat; + break; + + case EN_HEADCURVE: + if (Link[index].Type == EN_PUMP) { + v = (double)Pump[findpump(&p->network, index)].Hcurve; + if (v == 0) { + returnValue = 226; + } + } + else { + v = 0; + returnValue = 211; + } + break; + + case EN_EFFICIENCYCURVE: + if (Link[index].Type == EN_PUMP) { + v = (double)Pump[findpump(&p->network, index)].Ecurve; + if (v == 0) { + returnValue = 268; + } + } + else { + v = 0; + returnValue = 211; + } + + default: + v = 0; + returnValue = 251; + } + *value = (EN_API_FLOAT_TYPE)v; + return returnValue; +} int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nValues, EN_API_FLOAT_TYPE **xValues, @@ -3357,10 +2476,536 @@ int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nV return (0); } +/* + ---------------------------------------------------------------- + Functions for changing network data + ---------------------------------------------------------------- + */ +int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, + EN_API_FLOAT_TYPE setting, int nindex, + EN_API_FLOAT_TYPE level) { + char status = ACTIVE; + long t = 0; + double s = setting, lvl = level; + EN_Network *net; + Snode *Node; + Slink *Link; + Scontrol *Control; + + int Nnodes; + int Njuncs; + int Nlinks; + double *Ucf; + EN_Project *p = (EN_Project*)ph; + /* Check that input file opened */ + if (!p->Openflag) + return (102); + /* Check that control exists */ + if (cindex < 1 || cindex > p->network.Ncontrols) + return (241); + + + net = &p->network; + + Node = net->Node; + Link = net->Link; + Control = net->Control; + + Nnodes = net->Nnodes; + Njuncs = net->Njuncs; + Nlinks = net->Nlinks; + + Ucf = p->Ucf; + + /* Check that controlled link exists */ + if (lindex == 0) { + Control[cindex].Link = 0; + return (0); + } + if (lindex < 0 || lindex > Nlinks) + return (204); + + /* Cannot control check valve. */ + if (Link[lindex].Type == EN_CVPIPE) + return (207); + + /* Check for valid parameters */ + if (ctype < 0 || ctype > EN_TIMEOFDAY) + return (251); + if (ctype == EN_LOWLEVEL || ctype == EN_HILEVEL) { + if (nindex < 1 || nindex > Nnodes) + return (203); + } else + nindex = 0; + if (s < 0.0 || lvl < 0.0) + return (202); + + /* Adjust units of control parameters */ + switch (Link[lindex].Type) { + case EN_PRV: + case EN_PSV: + case EN_PBV: + s /= Ucf[PRESSURE]; + break; + case EN_FCV: + s /= Ucf[FLOW]; + break; + + /*** Updated 9/7/00 ***/ + case EN_GPV: + if (s == 0.0) + status = CLOSED; + else if (s == 1.0) + status = OPEN; + else + return (202); + s = Link[lindex].Kc; + break; + + case EN_PIPE: + case EN_PUMP: + status = OPEN; + if (s == 0.0) + status = CLOSED; + default: + break; + } + if (ctype == LOWLEVEL || ctype == HILEVEL) { + if (nindex > Njuncs) + lvl = Node[nindex].El + level / Ucf[ELEV]; + else + lvl = Node[nindex].El + level / Ucf[PRESSURE]; + } + if (ctype == TIMER) + t = (long)ROUND(lvl); + if (ctype == TIMEOFDAY) + t = (long)ROUND(lvl) % SECperDAY; + + /* Reset control's parameters */ + Control[cindex].Type = (char)ctype; + Control[cindex].Link = lindex; + Control[cindex].Node = nindex; + Control[cindex].Status = status; + Control[cindex].Setting = s; + Control[cindex].Grade = lvl; + Control[cindex].Time = t; + return (0); +} + +int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) +/*---------------------------------------------------------------- + ** Input: index = node index + ** code = node parameter code (see EPANET2.H) + ** value = parameter value + ** Output: none + ** Returns: error code + ** Purpose: sets input parameter value for a node + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Snode *Node = net->Node; + Stank *Tank = net->Tank; + + const int Nnodes = net->Nnodes; + const int Njuncs = net->Njuncs; + const int Npats = net->Npats; + + double *Ucf = p->Ucf; + + int j; + Pdemand demand; + Psource source; + double Htmp; + double value = v; + + if (!p->Openflag) + return (102); + if (index <= 0 || index > Nnodes) + return (203); + switch (code) { + case EN_ELEVATION: + if (index <= Njuncs) + Node[index].El = value / Ucf[ELEV]; + else { + value = (value / Ucf[ELEV]) - Node[index].El; + j = index - Njuncs; + Tank[j].H0 += value; + Tank[j].Hmin += value; + Tank[j].Hmax += value; + Node[index].El += value; + hyd->NodeHead[index] += value; + } + break; + + case EN_BASEDEMAND: + /* NOTE: primary demand category is last on demand list */ + if (index <= Njuncs) { + for (demand = Node[index].D; demand != NULL; demand = demand->next) { + if (demand->next == NULL) + demand->Base = value / Ucf[FLOW]; + } + } + break; + + case EN_PATTERN: + /* NOTE: primary demand category is last on demand list */ + j = ROUND(value); + if (j < 0 || j > Npats) + return (205); + if (index <= Njuncs) { + for (demand = Node[index].D; demand != NULL; demand = demand->next) { + if (demand->next == NULL) + demand->Pat = j; + } + } else + Tank[index - Njuncs].Pat = j; + break; + + case EN_EMITTER: + if (index > Njuncs) + return (203); + if (value < 0.0) + return (202); + if (value > 0.0) + value = pow((Ucf[FLOW] / value), hyd->Qexp) / Ucf[PRESSURE]; + Node[index].Ke = value; + break; + + case EN_INITQUAL: + if (value < 0.0) + return (202); + Node[index].C0 = value / Ucf[QUALITY]; + if (index > Njuncs) + Tank[index - Njuncs].C = Node[index].C0; + break; + + case EN_SOURCEQUAL: + case EN_SOURCETYPE: + case EN_SOURCEPAT: + if (value < 0.0) + return (202); + source = Node[index].S; + if (source == NULL) { + source = (struct Ssource *)malloc(sizeof(struct Ssource)); + if (source == NULL) + return (101); + source->Type = CONCEN; + source->C0 = 0.0; + source->Pat = 0; + Node[index].S = source; + } + if (code == EN_SOURCEQUAL) { + source->C0 = value; + } else if (code == EN_SOURCEPAT) { + j = ROUND(value); + if (j < 0 || j > Npats) + return (205); + source->Pat = j; + } else // code == EN_SOURCETYPE + { + j = ROUND(value); + if (j < CONCEN || j > FLOWPACED) + return (251); + else + source->Type = (char)j; + } + return (0); + + case EN_TANKLEVEL: + if (index <= Njuncs) + return (251); + j = index - Njuncs; + if (Tank[j].A == 0.0) /* Tank is a reservoir */ + { + Tank[j].H0 = value / Ucf[ELEV]; + Tank[j].Hmin = Tank[j].H0; + Tank[j].Hmax = Tank[j].H0; + Node[index].El = Tank[j].H0; + hyd->NodeHead[index] = Tank[j].H0; + } else { + value = Node[index].El + value / Ucf[ELEV]; + if (value > Tank[j].Hmax || value < Tank[j].Hmin) + return (202); + Tank[j].H0 = value; + Tank[j].V0 = tankvolume(p, j, Tank[j].H0); + // Resetting Volume in addition to initial volume + Tank[j].V = Tank[j].V0; + hyd->NodeHead[index] = Tank[j].H0; + } + break; + + /*** New parameters added for retrieval begins here ***/ + /*** (Thanks to Nicolas Basile of Ecole Polytechnique ***/ + /*** de Montreal for suggesting some of these.) ***/ + + case EN_TANKDIAM: + if (value <= 0.0) + return (202); + if (index <= Njuncs) + return (251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + value /= Ucf[ELEV]; + Tank[j].A = PI * SQR(value) / 4.0; + Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); + Tank[j].V0 = tankvolume(p, j, Tank[j].H0); + Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); + } else { + return (251); + } + break; + + case EN_MINVOLUME: + if (value < 0.0) + return (202); + if (index <= Njuncs) + return (251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + Tank[j].Vmin = value / Ucf[VOLUME]; + Tank[j].V0 = tankvolume(p, j, Tank[j].H0); + Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); + } else { + return (251); + } + break; + + case EN_MINLEVEL: + if (value < 0.0) + return (202); + if (index <= Njuncs) + return (251); // not a tank or reservoir + j = index - Njuncs; + if (Tank[j].A == 0.0) + return (251); // node is a reservoir + Htmp = value / Ucf[ELEV] + Node[index].El; + if (Htmp < Tank[j].Hmax && Htmp <= Tank[j].H0) { + if (Tank[j].Vcurve > 0) + return (202); + Tank[j].Hmin = Htmp; + Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); + } else { + return (251); + } + break; + + case EN_MAXLEVEL: + if (value < 0.0) + return (202); + if (index <= Njuncs) + return (251); // not a tank or reservoir + j = index - Njuncs; + if (Tank[j].A == 0.0) + return (251); // node is a reservoir + Htmp = value / Ucf[ELEV] + Node[index].El; + if (Htmp > Tank[j].Hmin && Htmp >= Tank[j].H0) { + if (Tank[j].Vcurve > 0) + return (202); + Tank[j].Hmax = Htmp; + Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); + } else { + return (251); + } + break; + + case EN_MIXMODEL: + j = ROUND(value); + if (index <= Njuncs) + return (251); + if (j < MIX1 || j > LIFO) + return (202); + if (index > Njuncs && Tank[index - Njuncs].A > 0.0) { + Tank[index - Njuncs].MixModel = (char)j; + } else { + return (251); + } + break; + + case EN_MIXFRACTION: + if (value < 0.0 || value > 1.0) + return (202); + if (index <= Njuncs) + return (251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + Tank[j].V1max = value * Tank[j].Vmax; + } + break; + + case EN_TANK_KBULK: + if (index <= Njuncs) + return (251); + j = index - Njuncs; + if (j > 0 && Tank[j].A > 0.0) { + Tank[j].Kb = value / SECperDAY; + qu->Reactflag = 1; + } else { + return (251); + } + break; + + /*** New parameter additions ends here. ***/ + + default: + return (251); + } + return (0); +} + +int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, + EN_API_FLOAT_TYPE v) + +/*---------------------------------------------------------------- + ** Input: index = link index + ** code = link parameter code (see EPANET2.H) + ** v = parameter value + ** Output: none + ** Returns: error code + ** Purpose: sets input parameter value for a link + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Slink *Link = net->Link; + + const int Nlinks = net->Nlinks; + + double *Ucf = p->Ucf; + double *LinkSetting = hyd->LinkSetting; + + char s; + double r, value = v; + + if (!p->Openflag) + return (102); + if (index <= 0 || index > Nlinks) + return (204); + switch (code) { + case EN_DIAMETER: + if (Link[index].Type != EN_PUMP) { + if (value <= 0.0) + return (202); + value /= Ucf[DIAM]; /* Convert to feet */ + r = Link[index].Diam / value; /* Ratio of old to new diam */ + Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */ + Link[index].Diam = value; /* Update diameter */ + resistcoeff(p, index); /* Update resistance coeff. */ + } + break; + + case EN_LENGTH: + if (Link[index].Type <= EN_PIPE) { + if (value <= 0.0) + return (202); + Link[index].Len = value / Ucf[ELEV]; + resistcoeff(p, index); + } + break; + + case EN_ROUGHNESS: + if (Link[index].Type <= EN_PIPE) { + if (value <= 0.0) + return (202); + Link[index].Kc = value; + if (hyd->Formflag == DW) + Link[index].Kc /= (1000.0 * Ucf[ELEV]); + resistcoeff(p, index); + } + break; + + case EN_MINORLOSS: + if (Link[index].Type != EN_PUMP) { + if (value <= 0.0) + return (202); + Link[index].Km = + 0.02517 * value / SQR(Link[index].Diam) / SQR(Link[index].Diam); + } + break; + + case EN_INITSTATUS: + case EN_STATUS: + /* Cannot set status for a check valve */ + if (Link[index].Type == EN_CVPIPE) + return (207); + s = (char)ROUND(value); + if (s < 0 || s > 1) + return (251); + if (code == EN_INITSTATUS) + setlinkstatus(p, index, s, &Link[index].Stat, &Link[index].Kc); + else + setlinkstatus(p, index, s, &hyd->LinkStatus[index], &LinkSetting[index]); + break; + + case EN_INITSETTING: + case EN_SETTING: + if (value < 0.0) + return (202); + if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) + return (ENsetlinkvalue(index, EN_ROUGHNESS, v)); + else { + switch (Link[index].Type) { + case EN_PUMP: + break; + case EN_PRV: + case EN_PSV: + case EN_PBV: + value /= Ucf[PRESSURE]; + break; + case EN_FCV: + value /= Ucf[FLOW]; + break; + case EN_TCV: + break; + + /*** Updated 9/7/00 ***/ + case EN_GPV: + return (202); /* Cannot modify setting for GPV */ + + default: + return (251); + } + if (code == EN_INITSETTING) + setlinksetting(p, index, value, &Link[index].Stat, &Link[index].Kc); + else + setlinksetting(p, index, value, &hyd->LinkStatus[index], + &LinkSetting[index]); + } + break; + + case EN_KBULK: + if (Link[index].Type <= EN_PIPE) { + Link[index].Kb = value / SECperDAY; + qu->Reactflag = 1; + } + break; + + case EN_KWALL: + if (Link[index].Type <= EN_PIPE) { + Link[index].Kw = value / SECperDAY; + qu->Reactflag = 1; + } + break; + + default: + return (251); + } + return (0); +} int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { int i, j, n, err = 0; @@ -3439,8 +3084,56 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { return 0; } +int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { + int j; + EN_Project *p = (EN_Project*)ph; + EN_Network *net = &p->network; + Spattern *Pattern = net->Pattern; + const int Npats = net->Npats; + + + /* Check for valid arguments */ + if (!p->Openflag) + return (102); + if (index <= 0 || index > Npats) + return (205); + if (n <= 0) + return (202); + + /* Re-set number of time periods & reallocate memory for multipliers */ + Pattern[index].Length = n; + Pattern[index].F = (double *)realloc(Pattern[index].F, n * sizeof(double)); + if (Pattern[index].F == NULL) + return (101); + + /* Load multipliers into pattern */ + for (j = 0; j < n; j++) + Pattern[index].F[j] = f[j]; + return (0); +} + +int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value) { + + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + + Spattern *Pattern = net->Pattern; + + const int Npats = net->Npats; + + + if (!p->Openflag) + return (102); + if (index <= 0 || index > Npats) + return (205); + if (period <= 0 || period > Pattern[index].Length) + return (251); + Pattern[index].F[period - 1] = value; + return (0); +} int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { @@ -3589,9 +3282,184 @@ int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_F return (0); } +int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) +{ + EN_Project *p = (EN_Project*)ph; + report_options_t *rep = &p->report; + quality_t *qu = &p->quality; + time_options_t *time = &p->time_options; + + if (!p->Openflag) + return (102); + if (p->hydraulics.OpenHflag || p->quality.OpenQflag) { + // --> there's nothing wrong with changing certain time parameters during a + // simulation run, or before the run has started. + // todo -- how to tell? + /* + if (code == EN_DURATION || code == EN_HTIME || code == EN_REPORTSTEP || + code == EN_DURATION || Htime == 0) { + // it's ok + } + else { + return(109); + } + */ + } + if (value < 0) + return (202); + switch (code) { + case EN_DURATION: + time->Dur = value; + if (time->Rstart > time->Dur) + time->Rstart = 0; + break; + case EN_HYDSTEP: + if (value == 0) + return (202); + time->Hstep = value; + time->Hstep = MIN(time->Pstep, time->Hstep); + time->Hstep = MIN(time->Rstep, time->Hstep); + qu->Qstep = MIN(qu->Qstep, time->Hstep); + break; + case EN_QUALSTEP: + if (value == 0) + return (202); + qu->Qstep = value; + qu->Qstep = MIN(qu->Qstep, time->Hstep); + break; + + case EN_PATTERNSTEP: + if (value == 0) + return (202); + time->Pstep = value; + if (time->Hstep > time->Pstep) + time->Hstep = time->Pstep; + break; + + case EN_PATTERNSTART: + time->Pstart = value; + break; + + case EN_REPORTSTEP: + if (value == 0) + return (202); + time->Rstep = value; + if (time->Hstep > time->Rstep) + time->Hstep = time->Rstep; + break; + + case EN_REPORTSTART: + if (time->Rstart > time->Dur) + return (202); + time->Rstart = value; + break; + + case EN_RULESTEP: + if (value == 0) + return (202); + time->Rulestep = value; + time->Rulestep = MIN(time->Rulestep, time->Hstep); + break; + + case EN_STATISTIC: + if (value > RANGE) + return (202); + rep->Tstatflag = (char)value; + break; + + case EN_HTIME: + time->Htime = value; + break; + + case EN_QTIME: + qu->Qtime = value; + break; + + default: + return (251); + } + return (0); +} + +int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) +/*---------------------------------------------------------------- + ** Input: code = option code (see EPANET2.H) + ** v = option value + ** Output: none + ** Returns: error code + ** Purpose: sets value for an analysis option + **---------------------------------------------------------------- + */ +{ + EN_Project *p = (EN_Project*)ph; + + EN_Network *net = &p->network; + hydraulics_t *hyd = &p->hydraulics; + quality_t *qu = &p->quality; + + Snode *Node = net->Node; + const int Njuncs = net->Njuncs; + + double *Ucf = p->Ucf; + + int i, j; + double Ke, n, ucf, value = v; + if (!p->Openflag) + return (102); + switch (code) { + case EN_TRIALS: + if (value < 1.0) + return (202); + hyd->MaxIter = (int)value; + break; + case EN_ACCURACY: + if (value < 1.e-5 || value > 1.e-1) + return (202); + hyd->Hacc = value; + break; + case EN_TOLERANCE: + if (value < 0.0) + return (202); + qu->Ctol = value / Ucf[QUALITY]; + break; + case EN_EMITEXPON: + if (value <= 0.0) + return (202); + n = 1.0 / value; + ucf = pow(Ucf[FLOW], n) / Ucf[PRESSURE]; + for (i = 1; i <= Njuncs; i++) { + j = ENgetnodevalue(i, EN_EMITTER, &v); + Ke = v; + if (j == 0 && Ke > 0.0) + Node[i].Ke = ucf / pow(Ke, n); + } + hyd->Qexp = n; + break; + case EN_DEMANDMULT: + if (value <= 0.0) + return (202); + hyd->Dmult = value; + break; + + case EN_HEADERROR: + if (value < 0.0) + return (202); + hyd->HeadErrorLimit = value / Ucf[HEAD]; + break; + case EN_FLOWCHANGE: + if (value < 0.0) + return (202); + hyd->FlowChangeLimit = value / Ucf[FLOW]; + break; + + default: + return (251); + } + return (0); +} int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { int errcode = 0; @@ -3605,7 +3473,72 @@ int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { return (errcode); } +int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode) { + + EN_Project *p = (EN_Project*)ph; + EN_Network *net = &p->network; + report_options_t *rep = &p->report; + quality_t *qu = &p->quality; + + double *Ucf = p->Ucf; + int i; + + /*** Updated 3/1/01 ***/ + double ccf = 1.0; + + if (!p->Openflag) + return (102); + if (qualcode < EN_NONE || qualcode > EN_TRACE) + return (251); + qu->Qualflag = (char)qualcode; + qu->Ctol *= Ucf[QUALITY]; + if (qu->Qualflag == CHEM) /* Chemical constituent */ + { + strncpy(qu->ChemName, chemname, MAXID); + strncpy(qu->ChemUnits, chemunits, MAXID); + + /*** Updated 3/1/01 ***/ + strncpy(rep->Field[QUALITY].Units, qu->ChemUnits, MAXID); + strncpy(rep->Field[REACTRATE].Units, qu->ChemUnits, MAXID); + strcat(rep->Field[REACTRATE].Units, t_PERDAY); + ccf = 1.0 / LperFT3; + } + if (qu->Qualflag == TRACE) /* Source tracing option */ + { + qu->TraceNode = findnode(net,tracenode); + if (qu->TraceNode == 0) + return (203); + strncpy(qu->ChemName, u_PERCENT, MAXID); + strncpy(qu->ChemUnits, tracenode, MAXID); + + /*** Updated 3/1/01 ***/ + strcpy(rep->Field[QUALITY].Units, u_PERCENT); + } + if (qu->Qualflag == AGE) /* Water age analysis */ + { + strncpy(qu->ChemName, w_AGE, MAXID); + strncpy(qu->ChemUnits, u_HOURS, MAXID); + + /*** Updated 3/1/01 ***/ + strcpy(rep->Field[QUALITY].Units, u_HOURS); + } + + /* when changing from CHEM to AGE or TRACE, nodes initial quality values must be returned to their original ones */ + if ((qu->Qualflag == AGE || qu->Qualflag == TRACE) & (Ucf[QUALITY] != 1)) { + for (i=1; i<=p->network.Nnodes; i++) { + p->network.Node[i].C0 *= Ucf[QUALITY]; + } + } + + /*** Updated 3/1/01 ***/ + Ucf[QUALITY] = ccf; + Ucf[LINKQUAL] = ccf; + Ucf[REACTRATE] = ccf; + qu->Ctol /= Ucf[QUALITY]; + + return (0); +} int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveindex) { From fafad2a070c0bee855ba08f61ee9b4a1d1292212 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 15:05:48 -0400 Subject: [PATCH 37/45] Revert "Reorganizing epanet header" This reverts commit c8803a9f1b5fe789dd99392d8ad795487cbfbd90. --- include/epanet2.h | 1700 +++++++++++++++++++--------------------- tests/test_toolkit.cpp | 4 +- 2 files changed, 824 insertions(+), 880 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index 726678c..3b75915 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -1,13 +1,13 @@ /** @file epanet2.h @see http://github.com/openwateranalytics/epanet - + */ /* ******************************************************************* - + EPANET2.H - Prototypes for EPANET Functions Exported to DLL Toolkit - + VERSION: 2.00 DATE: 5/8/00 10/25/00 @@ -16,7 +16,7 @@ 2/14/08 (2.00.12) AUTHORS: L. Rossman - US EPA - NRMRL OpenWaterAnalytics members: see git stats for contributors - + ******************************************************************* */ @@ -27,7 +27,7 @@ // the toolkit can be compiled with support for double-precision as well. // just make sure that you use the correct #define in your client code. #ifndef EN_API_FLOAT_TYPE -#define EN_API_FLOAT_TYPE float + #define EN_API_FLOAT_TYPE float #endif // // --- define WINDOWS @@ -66,197 +66,197 @@ /// Node property codes typedef enum { - EN_ELEVATION = 0, /**< Node Elevation */ - EN_BASEDEMAND = 1, /**< Node Base Demand, from last demand category */ - EN_PATTERN = 2, /**< Node Demand Pattern */ - EN_EMITTER = 3, /**< Node Emitter Coefficient */ - EN_INITQUAL = 4, /**< Node initial quality */ - EN_SOURCEQUAL = 5, /**< Node source quality */ - EN_SOURCEPAT = 6, /**< Node source pattern index */ - EN_SOURCETYPE = 7, /**< Node source type */ - EN_TANKLEVEL = 8, /**< Tank Level */ - EN_DEMAND = 9, /**< Node current simulated demand */ - EN_HEAD = 10, /**< Node Head value */ - EN_PRESSURE = 11, /**< Node pressure value */ - EN_QUALITY = 12, /**< Node quality value */ - EN_SOURCEMASS = 13, /**< Node source mass value */ - EN_INITVOLUME = 14, /**< Tank or Reservoir initial volume */ - EN_MIXMODEL = 15, /**< Tank mixing model */ - EN_MIXZONEVOL = 16, /**< Tank mixing zone volume */ - EN_TANKDIAM = 17, /**< Tank diameter */ - EN_MINVOLUME = 18, /**< Tank minimum volume */ - EN_VOLCURVE = 19, /**< Tank volume curve index */ - EN_MINLEVEL = 20, /**< Tank minimum level */ - EN_MAXLEVEL = 21, /**< Tank maximum level */ - EN_MIXFRACTION = 22, /**< Tank mixing fraction */ - EN_TANK_KBULK = 23, /**< Tank bulk decay coefficient */ - EN_TANKVOLUME = 24, /**< Tank current volume */ - EN_MAXVOLUME = 25 /**< Tank maximum volume */ + EN_ELEVATION = 0, /**< Node Elevation */ + EN_BASEDEMAND = 1, /**< Node Base Demand, from last demand category */ + EN_PATTERN = 2, /**< Node Demand Pattern */ + EN_EMITTER = 3, /**< Node Emitter Coefficient */ + EN_INITQUAL = 4, /**< Node initial quality */ + EN_SOURCEQUAL = 5, /**< Node source quality */ + EN_SOURCEPAT = 6, /**< Node source pattern index */ + EN_SOURCETYPE = 7, /**< Node source type */ + EN_TANKLEVEL = 8, /**< Tank Level */ + EN_DEMAND = 9, /**< Node current simulated demand */ + EN_HEAD = 10, /**< Node Head value */ + EN_PRESSURE = 11, /**< Node pressure value */ + EN_QUALITY = 12, /**< Node quality value */ + EN_SOURCEMASS = 13, /**< Node source mass value */ + EN_INITVOLUME = 14, /**< Tank or Reservoir initial volume */ + EN_MIXMODEL = 15, /**< Tank mixing model */ + EN_MIXZONEVOL = 16, /**< Tank mixing zone volume */ + EN_TANKDIAM = 17, /**< Tank diameter */ + EN_MINVOLUME = 18, /**< Tank minimum volume */ + EN_VOLCURVE = 19, /**< Tank volume curve index */ + EN_MINLEVEL = 20, /**< Tank minimum level */ + EN_MAXLEVEL = 21, /**< Tank maximum level */ + EN_MIXFRACTION = 22, /**< Tank mixing fraction */ + EN_TANK_KBULK = 23, /**< Tank bulk decay coefficient */ + EN_TANKVOLUME = 24, /**< Tank current volume */ + EN_MAXVOLUME = 25 /**< Tank maximum volume */ } EN_NodeProperty; /// Link property codes typedef enum { - EN_DIAMETER = 0, - EN_LENGTH = 1, - EN_ROUGHNESS = 2, - EN_MINORLOSS = 3, - EN_INITSTATUS = 4, - EN_INITSETTING = 5, - EN_KBULK = 6, - EN_KWALL = 7, - EN_FLOW = 8, - EN_VELOCITY = 9, - EN_HEADLOSS = 10, - EN_STATUS = 11, - EN_SETTING = 12, - EN_ENERGY = 13, - EN_LINKQUAL = 14, - EN_LINKPATTERN = 15, - EN_EFFICIENCY = 16, - EN_HEADCURVE = 17, - EN_EFFICIENCYCURVE = 18, - EN_PRICEPATTERN = 19 + EN_DIAMETER = 0, + EN_LENGTH = 1, + EN_ROUGHNESS = 2, + EN_MINORLOSS = 3, + EN_INITSTATUS = 4, + EN_INITSETTING = 5, + EN_KBULK = 6, + EN_KWALL = 7, + EN_FLOW = 8, + EN_VELOCITY = 9, + EN_HEADLOSS = 10, + EN_STATUS = 11, + EN_SETTING = 12, + EN_ENERGY = 13, + EN_LINKQUAL = 14, + EN_LINKPATTERN = 15, + EN_EFFICIENCY = 16, + EN_HEADCURVE = 17, + EN_EFFICIENCYCURVE = 18, + EN_PRICEPATTERN = 19 } EN_LinkProperty; /// Time parameter codes typedef enum { - EN_DURATION = 0, - EN_HYDSTEP = 1, - EN_QUALSTEP = 2, - EN_PATTERNSTEP = 3, - EN_PATTERNSTART = 4, - EN_REPORTSTEP = 5, - EN_REPORTSTART = 6, - EN_RULESTEP = 7, - EN_STATISTIC = 8, - EN_PERIODS = 9, - EN_STARTTIME = 10, - EN_HTIME = 11, - EN_QTIME = 12, - EN_HALTFLAG = 13, - EN_NEXTEVENT = 14, - EN_NEXTEVENTIDX = 15 + EN_DURATION = 0, + EN_HYDSTEP = 1, + EN_QUALSTEP = 2, + EN_PATTERNSTEP = 3, + EN_PATTERNSTART = 4, + EN_REPORTSTEP = 5, + EN_REPORTSTART = 6, + EN_RULESTEP = 7, + EN_STATISTIC = 8, + EN_PERIODS = 9, + EN_STARTTIME = 10, + EN_HTIME = 11, + EN_QTIME = 12, + EN_HALTFLAG = 13, + EN_NEXTEVENT = 14, + EN_NEXTEVENTIDX = 15 } EN_TimeProperty; typedef enum { - EN_ITERATIONS = 0, - EN_RELATIVEERROR = 1 + EN_ITERATIONS = 0, + EN_RELATIVEERROR = 1 } EN_AnalysisStatistic; typedef enum { - EN_NODECOUNT = 0, /**< Number of Nodes (Juntions + Tanks + Reservoirs) */ - EN_TANKCOUNT = 1, /**< Number of Tanks and Reservoirs */ - EN_LINKCOUNT = 2, /**< Number of Links (Pipes + Pumps + Valves) */ - EN_PATCOUNT = 3, /**< Number of Time Patterns */ - EN_CURVECOUNT = 4, /**< Number of Curves */ - EN_CONTROLCOUNT = 5, /**< Number of Control Statements */ - EN_RULECOUNT = 6 /**< Number of Rule-based Control Statements */ + EN_NODECOUNT = 0, /**< Number of Nodes (Juntions + Tanks + Reservoirs) */ + EN_TANKCOUNT = 1, /**< Number of Tanks and Reservoirs */ + EN_LINKCOUNT = 2, /**< Number of Links (Pipes + Pumps + Valves) */ + EN_PATCOUNT = 3, /**< Number of Time Patterns */ + EN_CURVECOUNT = 4, /**< Number of Curves */ + EN_CONTROLCOUNT = 5, /**< Number of Control Statements */ + EN_RULECOUNT = 6 /**< Number of Rule-based Control Statements */ } EN_CountType; typedef enum { - EN_JUNCTION = 0, - EN_RESERVOIR = 1, - EN_TANK = 2 + EN_JUNCTION = 0, + EN_RESERVOIR = 1, + EN_TANK = 2 } EN_NodeType; typedef enum { - EN_CVPIPE = 0, /* Link types. */ - EN_PIPE = 1, /* See LinkType in TYPES.H */ - EN_PUMP = 2, - EN_PRV = 3, - EN_PSV = 4, - EN_PBV = 5, - EN_FCV = 6, - EN_TCV = 7, - EN_GPV = 8 + EN_CVPIPE = 0, /* Link types. */ + EN_PIPE = 1, /* See LinkType in TYPES.H */ + EN_PUMP = 2, + EN_PRV = 3, + EN_PSV = 4, + EN_PBV = 5, + EN_FCV = 6, + EN_TCV = 7, + EN_GPV = 8 } EN_LinkType; typedef enum { - EN_NONE = 0, /* Quality analysis types. */ - EN_CHEM = 1, /* See QualType in TYPES.H */ - EN_AGE = 2, - EN_TRACE = 3 + EN_NONE = 0, /* Quality analysis types. */ + EN_CHEM = 1, /* See QualType in TYPES.H */ + EN_AGE = 2, + EN_TRACE = 3 } EN_QualityType; typedef enum { - EN_CONCEN = 0, /* Source quality types. */ - EN_MASS = 1, /* See SourceType in TYPES.H. */ - EN_SETPOINT = 2, - EN_FLOWPACED = 3 + EN_CONCEN = 0, /* Source quality types. */ + EN_MASS = 1, /* See SourceType in TYPES.H. */ + EN_SETPOINT = 2, + EN_FLOWPACED = 3 } EN_SourceType; typedef enum { /* Head loss formula: */ - EN_HW = 0, /* Hazen-Williams */ - EN_DW = 1, /* Darcy-Weisbach */ - EN_CM = 2 /* Chezy-Manning */ + EN_HW = 0, /* Hazen-Williams */ + EN_DW = 1, /* Darcy-Weisbach */ + EN_CM = 2 /* Chezy-Manning */ } EN_FormType; /* See FormType in TYPES.H */ typedef enum { - EN_CFS = 0, /* Flow units types. */ - EN_GPM = 1, /* See FlowUnitsType */ - EN_MGD = 2, /* in TYPES.H. */ - EN_IMGD = 3, - EN_AFD = 4, - EN_LPS = 5, - EN_LPM = 6, - EN_MLD = 7, - EN_CMH = 8, - EN_CMD = 9 + EN_CFS = 0, /* Flow units types. */ + EN_GPM = 1, /* See FlowUnitsType */ + EN_MGD = 2, /* in TYPES.H. */ + EN_IMGD = 3, + EN_AFD = 4, + EN_LPS = 5, + EN_LPM = 6, + EN_MLD = 7, + EN_CMH = 8, + EN_CMD = 9 } EN_FlowUnits; /// Simulation Option codes typedef enum { - EN_TRIALS = 0, - EN_ACCURACY = 1, - EN_TOLERANCE = 2, - EN_EMITEXPON = 3, - EN_DEMANDMULT = 4, - EN_HEADERROR = 5, - EN_FLOWCHANGE = 6 + EN_TRIALS = 0, + EN_ACCURACY = 1, + EN_TOLERANCE = 2, + EN_EMITEXPON = 3, + EN_DEMANDMULT = 4, + EN_HEADERROR = 5, + EN_FLOWCHANGE = 6 } EN_Option; typedef enum { - EN_LOWLEVEL = 0, /* Control types. */ - EN_HILEVEL = 1, /* See ControlType */ - EN_TIMER = 2, /* in TYPES.H. */ - EN_TIMEOFDAY = 3 + EN_LOWLEVEL = 0, /* Control types. */ + EN_HILEVEL = 1, /* See ControlType */ + EN_TIMER = 2, /* in TYPES.H. */ + EN_TIMEOFDAY = 3 } EN_ControlType; typedef enum { - EN_AVERAGE = 1, /* Time statistic types. */ - EN_MINIMUM = 2, /* See TstatType in TYPES.H */ - EN_MAXIMUM = 3, - EN_RANGE = 4 + EN_AVERAGE = 1, /* Time statistic types. */ + EN_MINIMUM = 2, /* See TstatType in TYPES.H */ + EN_MAXIMUM = 3, + EN_RANGE = 4 } EN_StatisticType; typedef enum { - EN_MIX1 = 0, /* Tank mixing models */ - EN_MIX2 = 1, - EN_FIFO = 2, - EN_LIFO = 3 + EN_MIX1 = 0, /* Tank mixing models */ + EN_MIX2 = 1, + EN_FIFO = 2, + EN_LIFO = 3 } EN_MixingModel; typedef enum { - EN_NOSAVE = 0, - EN_SAVE = 1, - EN_INITFLOW = 10, - EN_SAVE_AND_INIT = 11 + EN_NOSAVE = 0, + EN_SAVE = 1, + EN_INITFLOW = 10, + EN_SAVE_AND_INIT = 11 } EN_SaveOption; typedef enum { - EN_CONST_HP = 0, /* constant horsepower */ - EN_POWER_FUNC = 1, /* power function */ - EN_CUSTOM = 2 /* user-defined custom curve */ + EN_CONST_HP = 0, /* constant horsepower */ + EN_POWER_FUNC = 1, /* power function */ + EN_CUSTOM = 2 /* user-defined custom curve */ } EN_CurveType; @@ -265,201 +265,217 @@ typedef enum { #if defined(__cplusplus) extern "C" { #endif - -/** + + /** @brief The EPANET Project wrapper object - */ -typedef void *EN_ProjectHandle; - -typedef struct EN_Pattern EN_Pattern; -typedef struct EN_Curve EN_Curve; - - -//////////////////////////////////////////////////////////////////////////////// -//-------------------- CANONICAL API - ORGANIZED BY TASK ---------------------// -//////////////////////////////////////////////////////////////////////////////// - -// RUNNING A COMPLETE SIMULATION -/** + */ + typedef void *EN_ProjectHandle; +// typedef struct EN_Project EN_Project; + typedef struct EN_Pattern EN_Pattern; + typedef struct EN_Curve EN_Curve; + + /** @brief runs a complete EPANET simulation @param inpFile pointer to name of input file (must exist) @param rptFile pointer to name of report file (to be created) @param binOutFile pointer to name of binary output file (to be created) @param callback a callback function that takes a character string (char *) as its only parameter. @return error code - + The callback function should reside in and be used by the calling code to display the progress messages that EPANET generates as it carries out its computations. If this feature is not needed then the argument should be NULL. - */ -int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile, - const char *binOutFile, void (*callback) (char *)); -int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *inpFile, - const char *rptFile, const char *binOutFile, void(*callback) (char *)); - -// OPENING A CLOSING THE EPANET TOOLKIT SYSTEM -/** + */ + int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile, + const char *binOutFile, void (*callback) (char *)); + + /** + @brief Initializes an EPANET session + @param rptFile pointer to name of report file (to be created) + @param binOutFile pointer to name of binary output file (to be created) + @param UnitsType flow units flag + @param HeadlossFormula headloss formula flag + @return error code + */ + int DLLEXPORT ENinit(char *rptFile, char *binOutFile, int UnitsType, int HeadlossFormula); + + /** @brief Opens EPANET input file & reads in network data @param inpFile pointer to name of input file (must exist) @param rptFile pointer to name of report file (to be created) @param binOutFile pointer to name of binary output file (to be created) @return error code - */ -int DLLEXPORT ENopen(char *inpFile, char *rptFile, char *binOutFile); -int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, - const char *rptFile, const char *binOutFile); - -/** + */ + int DLLEXPORT ENopen(char *inpFile, char *rptFile, char *binOutFile); + + /** + @brief Saves current data to "INP" formatted text file. + @param filename The file path to create + @return Error code + */ + int DLLEXPORT ENsaveinpfile(char *filename); + + /** @brief Frees all memory and files used by EPANET @return Error code - */ -int DLLEXPORT ENclose(); -int DLLEXPORT EN_close(EN_ProjectHandle ph); - - -// RETREIVING INFORMATION ABOUT NETWORK NODES -/** - @brief Get index of node with specified ID - @param id The string ID of the node - @param[out] index The node's index (first node is index 1) + */ + int DLLEXPORT ENclose(); + + /** + @brief Solves the network hydraulics for all time periods @return Error code - @see ENgetnodeid - */ -int DLLEXPORT ENgetnodeindex(char *id, int *index); -int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index); - -/** - @brief Get the string ID of the specified node. - @param index The index of the node (first node is index 1) - @param[out] id The string ID of the specified node. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. + */ + int DLLEXPORT ENsolveH(); + + /** + @brief Saves hydraulic results to binary file @return Error code - @see ENgetnodeindex - */ -int DLLEXPORT ENgetnodeid(int index, char *id); -int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id); - -/** - @brief Get the type of node with specified index. - @param index The index of a node (first node is index 1) - @param[out] code The type code for the node. + + Must be called before ENreport() if no WQ simulation has been made. + Should not be called if ENsolveQ() will be used. + */ + int DLLEXPORT ENsaveH(); + + /** + @brief Sets up data structures for hydraulic analysis @return Error code - */ -int DLLEXPORT ENgetnodetype(int index, int *code); -int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code); - -/** - @brief Get a property value for specified node - @param index The index of a node (first node is index 1). - @param code The property type code - @param[out] value The value of the node's property. + */ + int DLLEXPORT ENopenH(); + + /** + @brief Initializes hydraulic analysis + @param initFlag 2-digit flag where 1st (left) digit indicates if link flows should be re-initialized (1) or not (0), and 2nd digit indicates if hydraulic results should be saved to file (1) or not (0). @return Error code - @see EN_NodeProperty - */ -int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value); -int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, - EN_API_FLOAT_TYPE *value); - - -// RETREIVING INFORMATION ABOUT NETWORK LINKS -/** - @brief Get the index of a Link with specified ID. - @param id The string ID of a link. - @param[out] index The index of the named link (first link is index 1) + */ + int DLLEXPORT ENinitH(int initFlag); + + /** + @brief Run a hydraulic solution period + @param[out] currentTime The current simulation time in seconds + @return Error or warning code + @see ENsolveH + + This function is used in a loop with ENnextH() to run + an extended period hydraulic simulation. + See ENsolveH() for an example. + */ + int DLLEXPORT ENrunH(long *currentTime); + + /** + @brief Determine time (in seconds) until next hydraulic event + @param[out] tStep Time (seconds) until next hydraulic event. 0 marks end of simulation period. @return Error code - @see ENgetlinkid - */ -int DLLEXPORT ENgetlinkindex(char *id, int *index); -int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index); - -/** - @brief Get the string ID of a link with specified index - @param index The index of a link (first link is index 1) - @param[out] id The ID of the link. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. + + This function is used in a loop with ENrunH() to run an extended period hydraulic simulation. + See ENsolveH() for an example. + */ + int DLLEXPORT ENnextH(long *tStep); + + + /** + @brief Frees data allocated by hydraulics solver @return Error code - @see ENgetlinkindex - */ -int DLLEXPORT ENgetlinkid(int index, char *id); -int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id); - -/** - @brief Get the link type code for a specified link - @param index The index of a link (first link is index 1) - @param[out] code The type code of the link. + */ + int DLLEXPORT ENcloseH(); + + /** + @brief Copies binary hydraulics file to disk + @param filename Name of file to be created @return Error code - @see EN_LinkType - */ -int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code); -int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code); - -/** - @brief Get the indexes of a link's start- and end-nodes. - @param index The index of a link (first link is index 1) - @param[out] node1 The index of the link's start node (first node is index 1). - @param[out] node2 The index of the link's end node (first node is index 1). + */ + int DLLEXPORT ENsavehydfile(char *filename); + + /** + @brief Opens previously saved binary hydraulics file + @param filename Name of file to be used @return Error code - @see ENgetnodeid, ENgetlinkid - */ -int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2); -int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2); - -/** - @brief Get a property value for specified link. - @param index The index of a node (first node is index 1). - @param code The parameter desired. - @param[out] value The value of the link's specified property. + */ + int DLLEXPORT ENusehydfile(char *filename); + + /** + @brief Solves for network water quality in all time periods @return Error code - @see ENgetnodevalue, EN_LinkProperty - */ -int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value); -int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, - EN_LinkProperty code, EN_API_FLOAT_TYPE *value); - - -// RETREIVING INFORMATION ABOUT TIME PATTERNS -/** - @brief Retrieves ID of a time pattern with specific index. - @param index The index of a time pattern. - @param[out] id The string ID of the time pattern. + */ + int DLLEXPORT ENsolveQ(); + + /** + @brief Sets up data structures for WQ analysis @return Error code - @see ENgetpatternindex - */ -int DLLEXPORT ENgetpatternid(int index, char *id); -int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id); - -/** - @brief Retrieves the index of the time pattern with specified ID - @param id String ID of the time pattern - @param[out] index Index of the specified time pattern + */ + int DLLEXPORT ENopenQ(); + + /** + @brief Initializes water quality analysis + @param saveFlag EN_SAVE (1) if results saved to file, EN_NOSAVE (0) if not @return Error code - @see ENgetpatternid - */ -int DLLEXPORT ENgetpatternindex(char *id, int *index); -int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index); - -/** - @brief Retrieves the number of multipliers in a time pattern. - @param index The index of a time pattern. - @param[out] len The length of the time pattern. + */ + int DLLEXPORT ENinitQ(int saveFlag); + + /** + @brief Retrieves hydraulic & WQ results at time t. + @param[out] currentTime Current simulation time, in seconds. @return Error code - */ -int DLLEXPORT ENgetpatternlen(int index, int *len); -int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len); - -/** - @brief Retrive a multiplier from a pattern for a specific time period. - @param index The index of a time pattern - @param period The pattern time period. First time period is 1. - @param[out] value Pattern multiplier + + This function is used in a loop with ENnextQ() to run + an extended period WQ simulation. See ENsolveQ() for + an example. + */ + int DLLEXPORT ENrunQ(long *currentTime); + + /** + @brief Advances WQ simulation to next hydraulic event. + @param[out] tStep Time in seconds until next hydraulic event. 0 marks end of simulation period. @return Error code - */ -int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value); -int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, - EN_API_FLOAT_TYPE *value); - - -// RETREIVING OTHER NETWORK INFORMATION -/** + + This function is used in a loop with ENrunQ() to run + an extended period WQ simulation. See ENsolveQ() for + an example. + */ + int DLLEXPORT ENnextQ(long *tStep); + + /** + @brief Advances WQ simulation by a single WQ time step + @param[out] timeLeft Time left in overall simulation (in seconds) + @return Error code + + This function is used in a loop with ENrunQ() to run + an extended period WQ simulation. + */ + int DLLEXPORT ENstepQ(long *timeLeft); + + /** + @brief Frees data allocated by water quality solver. + @return Error code. + */ + int DLLEXPORT ENcloseQ(); + + /** + @brief Writes line of text to the report file. + @param line Text string to write + @return Error code. + */ + int DLLEXPORT ENwriteline(char *line); + + /** + @brief Writes simulation report to the report file + @return Error code + */ + int DLLEXPORT ENreport(); + + /** + @brief Resets report options to default values + @return Error code + */ + int DLLEXPORT ENresetreport(); + + /** + @brief Processes a reporting format command + @return Error code + */ + int DLLEXPORT ENsetreport(char *reportFormat); + + /** @brief Retrieves parameters that define a simple control @param controlIndex Control index (position of control statement in the input file, starting from 1) @param[out] controlType Control type code (see EPANET2.H) @@ -468,471 +484,254 @@ int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, @param[out] nodeIndex Index of controlling node (0 for TIMER or TIMEOFDAY control) @param[out] level Control level (tank level, junction pressure, or time (seconds)) @return Error code - */ -int DLLEXPORT ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, - EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); -int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int controlIndex, int *controlType, - int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); - -/** + */ + int DLLEXPORT ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); + + /** @brief Retrieves the number of components of a given type in the network. @param code Component code (see EPANET2.H) @param[out] count Number of components in network @return Error code - */ -int DLLEXPORT ENgetcount(int code, int *count); -int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count); - -/** - @brief Retrieves the flow units code - @param[out] code Code of flow units in use - @return Error code - */ -int DLLEXPORT ENgetflowunits(int *code); -int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code); - -/** - @brief Retrieves value of specific time parameter. - @param code Time parameter code - @param[out] value Value of time parameter. - @return Error code - */ -int DLLEXPORT ENgettimeparam(int code, long *value); -int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value); - -/** + */ + int DLLEXPORT ENgetcount(int code, int *count); + + /** @brief Gets value for an analysis option @param code Option code (see EPANET2.H) @param[out] value Option value @return Error code - */ -int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value); -int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option opt, EN_API_FLOAT_TYPE *value); - -/** - @brief Get the version number. This number is to be interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" - @param[out] version The version of EPANET - @return Error code. - */ -int DLLEXPORT ENgetversion(int *version); -int DLLEXPORT EN_getversion(int *version); - - -// SETTING NEW VALUES FOR NETWORK PARAMETERS -/** - @brief Specify parameters to define a simple control - @param cindex The index of the control to edit. First control is index 1. - @param ctype The type code to set for this control. - @param lindex The index of a link to control. - @param setting The control setting applied to the link. - @param nindex The index of a node used to control the link, or 0 for TIMER / TIMEOFDAY control. - @param level control point (tank level, junction pressure, or time in seconds). - @return Error code. - */ -int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); -int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); - -/** - @brief Set a property value for a node. - @param index The index of a node. First node is index 1. - @param code The code for the proprty to set. - @param v The value to set for this node and property. - @return Error code. - @see EN_NodeProperty - */ -int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v); -int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); - -/** - @brief Set a proprty value for a link. - @param index The index of a link. First link is index 1. - @param code The code for the property to set. - @param v The value to set for this link and property. - @return Error code. - @see EN_LinkProperty - */ -int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v); -int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); - -/** - @brief Set multipliers for a specific pattern - @param index The index of a pattern. First pattern is index 1. - @param f An array of multipliers - @param len The length of array f. - @return Error code. - @see ENgetpatternindex - */ -int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len); -int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int len); - -/** - @brief Set the multiplier for a specific pattern at a specific period. - @param index The index of a pattern. First pattern is index 1. - @param period The period of the pattern to set. - @param value The value of the multiplier to set. - @return Error code. - */ -int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value); -int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value); - -/** - @brief Sets type of quality analysis called for - @param qualcode WQ parameter code, EN_QualityType - @param chemname Name of WQ constituent - @param chemunits Concentration units of WQ constituent - @param tracenode ID of node being traced (if applicable) - @return Error code. - @see EN_QualityType - - chemname and chemunits only apply when WQ analysis is for chemical. tracenode only applies when WQ analysis is source tracing. - */ -int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); -int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode); - -/** - @brief Set the value for a time parameter. - @param code The code for the parameter to set. - @param value The desired value of the parameter. - @return Error code. - @see EN_TimeProperty - */ -int DLLEXPORT ENsettimeparam(int code, long value); -int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value); - -/** - @brief Set a value for an anlysis option. - @param code The code for the desired option. - @param v The desired value for the option specified. - @return Error code. - @see EN_Option - */ -int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v); -int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v); - - -// SAVING AND USING HYDRAULIC ANALYSIS RESULTS FILES -/** - @brief Copies binary hydraulics file to disk - @param filename Name of file to be created + */ + int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value); + + /** + @brief Retrieves value of specific time parameter. + @param code Time parameter code + @param[out] value Value of time parameter. @return Error code - */ -int DLLEXPORT ENsavehydfile(char *filename); -int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename); - -/** - @brief Opens previously saved binary hydraulics file - @param filename Name of file to be used + */ + int DLLEXPORT ENgettimeparam(int code, long *value); + + /** + @brief Retrieves the flow units code + @param[out] code Code of flow units in use @return Error code - */ -int DLLEXPORT ENusehydfile(char *filename); -int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename); - - -// RUNNING A HYDRAULIC ANALYSIS -/** - @brief Solves the network hydraulics for all time periods - @return Error code - */ -int DLLEXPORT ENsolveH(); -int DLLEXPORT EN_solveH(EN_ProjectHandle ph); - -/** - @brief Sets up data structures for hydraulic analysis - @return Error code - */ -int DLLEXPORT ENopenH(); -int DLLEXPORT EN_openH(EN_ProjectHandle ph); - -/** - @brief Initializes hydraulic analysis - @param initFlag 2-digit flag where 1st (left) digit indicates if link flows should be re-initialized (1) or not (0), and 2nd digit indicates if hydraulic results should be saved to file (1) or not (0). - @return Error code - */ -int DLLEXPORT ENinitH(int initFlag); -int DLLEXPORT EN_initH(EN_ProjectHandle ph, int EN_SaveOption); - -/** - @brief Run a hydraulic solution period - @param[out] currentTime The current simulation time in seconds - @return Error or warning code - @see ENsolveH - - This function is used in a loop with ENnextH() to run - an extended period hydraulic simulation. - See ENsolveH() for an example. - */ -int DLLEXPORT ENrunH(long *currentTime); -int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *currentTime); - -/** - @brief Determine time (in seconds) until next hydraulic event - @param[out] tStep Time (seconds) until next hydraulic event. 0 marks end of simulation period. - @return Error code - - This function is used in a loop with ENrunH() to run an extended period hydraulic simulation. - See ENsolveH() for an example. - */ -int DLLEXPORT ENnextH(long *tStep); -int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tStep); - -/** - @brief Frees data allocated by hydraulics solver - @return Error code - */ -int DLLEXPORT ENcloseH(); -int DLLEXPORT EN_closeH(EN_ProjectHandle ph); - - -// RUNNING A WATER QUALITY ANALYSIS -/** - @brief Solves for network water quality in all time periods - @return Error code - */ -int DLLEXPORT ENsolveQ(); -int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); - -/** - @brief Sets up data structures for WQ analysis - @return Error code - */ -int DLLEXPORT ENopenQ(); -int DLLEXPORT EN_openQ(EN_ProjectHandle ph); - -/** - @brief Initializes water quality analysis - @param saveFlag EN_SAVE (1) if results saved to file, EN_NOSAVE (0) if not - @return Error code - */ -int DLLEXPORT ENinitQ(int saveFlag); -int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveFlag); - -/** - @brief Retrieves hydraulic & WQ results at time t. - @param[out] currentTime Current simulation time, in seconds. - @return Error code - - This function is used in a loop with ENnextQ() to run - an extended period WQ simulation. See ENsolveQ() for - an example. - */ -int DLLEXPORT ENrunQ(long *currentTime); -int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *currentTime); - -/** - @brief Advances WQ simulation to next hydraulic event. - @param[out] tStep Time in seconds until next hydraulic event. 0 marks end of simulation period. - @return Error code - - This function is used in a loop with ENrunQ() to run - an extended period WQ simulation. See ENsolveQ() for - an example. - */ -int DLLEXPORT ENnextQ(long *tStep); -int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tStep); - -/** - @brief Advances WQ simulation by a single WQ time step - @param[out] timeLeft Time left in overall simulation (in seconds) - @return Error code - - This function is used in a loop with ENrunQ() to run - an extended period WQ simulation. - */ -int DLLEXPORT ENstepQ(long *timeLeft); -int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *timeLeft); - -/** - @brief Frees data allocated by water quality solver. - @return Error code. - */ -int DLLEXPORT ENcloseQ(); -int DLLEXPORT EN_closeQ(EN_ProjectHandle ph); - - -// GENERATING AN OUTPUT REPORT -/** - @brief Saves hydraulic results to binary file - @return Error code - - Must be called before ENreport() if no WQ simulation has been made. - Should not be called if ENsolveQ() will be used. - */ -int DLLEXPORT ENsaveH(); -int DLLEXPORT EN_saveH(EN_ProjectHandle ph); - -/** - @brief Saves current data to "INP" formatted text file. - @param filename The file path to create - @return Error code - */ -int DLLEXPORT ENsaveinpfile(char *filename); -int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename); - -/** - @brief Writes simulation report to the report file - @return Error code - */ -int DLLEXPORT ENreport(); -int DLLEXPORT EN_report(EN_ProjectHandle ph); - -/** - @brief Resets report options to default values - @return Error code - */ -int DLLEXPORT ENresetreport(); -int DLLEXPORT EN_resetreport(EN_ProjectHandle ph); - -/** - @brief Processes a reporting format command - @return Error code - */ -int DLLEXPORT ENsetreport(char *reportFormat); -int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *reportFormat); - -/** - @brief Sets the level of hydraulic status reporting. - @param code Status reporting code. - @return Error code. - */ -int DLLEXPORT ENsetstatusreport(int code); -int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code); - -/** - @brief Get the text of an error code. - @param errcode The error code - @param[out] errmsg The error string represented by the code - @param maxLen The maximum number of characters to copy into the char pointer errmsg - @return Error code - */ -int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen); -int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); - - - -//////////////////////////////////////////////////////////////////////////////// -//-------------------------------- NEW API -----------------------------------// -//////////////////////////////////////////////////////////////////////////////// - -/** - @brief Initializes an EPANET session - @param rptFile pointer to name of report file (to be created) - @param binOutFile pointer to name of binary output file (to be created) - @param UnitsType flow units flag - @param HeadlossFormula headloss formula flag - @return error code - */ -int DLLEXPORT ENinit(char *rptFile, char *binOutFile, int UnitsType, - int HeadlossFormula); -int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *rptFile, char *binOutFile, - EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); - -/** - @brief Writes line of text to the report file. - @param line Text string to write - @return Error code. - */ -int DLLEXPORT ENwriteline(char *line); -int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line); - -/** + */ + int DLLEXPORT ENgetflowunits(int *code); + + /** @brief Sets the flow units @param code Code of flow units to use @return Error code - */ -int DLLEXPORT ENsetflowunits(int code); -int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code); + */ + int DLLEXPORT ENsetflowunits(int code); + + /** + @brief Retrieves the index of the time pattern with specified ID + @param id String ID of the time pattern + @param[out] index Index of the specified time pattern + @return Error code + @see ENgetpatternid + */ + int DLLEXPORT ENgetpatternindex(char *id, int *index); + + /** + @brief Retrieves ID of a time pattern with specific index. + @param index The index of a time pattern. + @param[out] id The string ID of the time pattern. + @return Error code + @see ENgetpatternindex + */ + int DLLEXPORT ENgetpatternid(int index, char *id); - -/** + /** + @brief Retrieves the number of multipliers in a time pattern. + @param index The index of a time pattern. + @param[out] len The length of the time pattern. + @return Error code + */ + int DLLEXPORT ENgetpatternlen(int index, int *len); + + /** + @brief Retrive a multiplier from a pattern for a specific time period. + @param index The index of a time pattern + @param period The pattern time period. First time period is 1. + @param[out] value Pattern multiplier + @return Error code + */ + int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value); + + /** @brief Retrieve the average multiplier value in a time pattern @param index The index of a time pattern @param[out] value The average of all of this time pattern's values @return Error code - */ -int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); -int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value); - - -/** + */ + int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); + + /** @brief Retrieve the type of quality analytis to be run. @param[out] qualcode The quality analysis code number. @param[out] tracenode The index of node being traced, if qualcode == trace @return Error code @see ENsetqualtype - */ -int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode); - - -/** + */ + int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode); + + /** + @brief Get the text of an error code. + @param errcode The error code + @param[out] errmsg The error string represented by the code + @param maxLen The maximum number of characters to copy into the char pointer errmsg + @return Error code + */ + int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen); + + /** @brief Get hydraulic simulation statistic @param code The type of statistic to get @param[out] value The value of the statistic @return Error code - */ -int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value); - -/** + */ + int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value); + + /** + @brief Get index of node with specified ID + @param id The string ID of the node + @param[out] index The node's index (first node is index 1) + @return Error code + @see ENgetnodeid + */ + int DLLEXPORT ENgetnodeindex(char *id, int *index); + + /** + @brief Get the string ID of the specified node. + @param index The index of the node (first node is index 1) + @param[out] id The string ID of the specified node. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. + @return Error code + @see ENgetnodeindex + */ + int DLLEXPORT ENgetnodeid(int index, char *id); + + /** + @brief Get the type of node with specified index. + @param index The index of a node (first node is index 1) + @param[out] code The type code for the node. + @return Error code + */ + int DLLEXPORT ENgetnodetype(int index, int *code); + + /** + @brief Get a property value for specified node + @param index The index of a node (first node is index 1). + @param code The property type code + @param[out] value The value of the node's property. + @return Error code + @see EN_NodeProperty + */ + int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value); + + /** @brief Get coordinates (x,y) for a node. @param index The index of a node (first node is index 1). @param[out] x X-value of node's coordinate @param[out] y Y-value of node's coordinate @return Error code @see ENsetcoord - */ -int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - - -/** + */ + int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + + /** @brief Set coordinates (x,y) for a node. @param index The index of a node (first node is index 1) @param x X-value of node's coordinate @param y Y-value of node's coordinate @return Error code @see ENgetcoord - */ -int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - - -/** + */ + int DLLEXPORT ENsetcoord(int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + + /** @brief Get the number of demand categories for a node. @param nodeIndex The index of a node (first node is index 1) @param[out] numDemands The number of demand categories @return Error code - */ -int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands); - - -/** + */ + int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands); + + /** @brief Get a node's base demand for a specified category. @param nodeIndex The index of a node (first node is index 1) @param demandIndex The index of the demand category (starting at 1) @return Error code - */ -int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); - - -/** + */ + int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); + + /** @brief Get the index of the demand pattern assigned to a node for a category index. @param nodeIndex The index of a node (first node is index 1). @param demandIndex The index of a category (first category is index 1). @param[out] pattIndex The index of the pattern for this node and category. @return Error code - */ -int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIndex); + */ + int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIndex); + + /** + @brief Get the index of a Link with specified ID. + @param id The string ID of a link. + @param[out] index The index of the named link (first link is index 1) + @return Error code + @see ENgetlinkid + */ + int DLLEXPORT ENgetlinkindex(char *id, int *index); + + /** + @brief Get the string ID of a link with specified index + @param index The index of a link (first link is index 1) + @param[out] id The ID of the link. Up to MAXID characters will be copied, so id must be pre-allocated by the calling code to hold at least that many characters. + @return Error code + @see ENgetlinkindex + */ + int DLLEXPORT ENgetlinkid(int index, char *id); + + /** + @brief Get the link type code for a specified link + @param index The index of a link (first link is index 1) + @param[out] code The type code of the link. + @return Error code + @see EN_LinkType + */ + int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code); - -/** + /** @brief Set the link type code for a specified link @param id The id of a link @param type The type code of the link. @return Error code @see EN_LinkType - */ -int DLLEXPORT ENsetlinktype(char *id, EN_LinkType type); -int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); - - -/** + */ + int DLLEXPORT ENsetlinktype(char *id, EN_LinkType type); + + /** + @brief Get the indexes of a link's start- and end-nodes. + @param index The index of a link (first link is index 1) + @param[out] node1 The index of the link's start node (first node is index 1). + @param[out] node2 The index of the link's end node (first node is index 1). + @return Error code + @see ENgetnodeid, ENgetlinkid + */ + int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2); + + /** + @brief Get a property value for specified link. + @param index The index of a node (first node is index 1). + @param code The parameter desired. + @param[out] value The value of the link's specified property. + @return Error code + @see ENgetnodevalue, EN_LinkProperty + */ + int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value); + + /** @brief Get a curve's properties. @param curveIndex The index of a curve (first curve is index 1). @param[out] id The curve's string ID. Client code must preallocate at least MAXID characters. @@ -940,48 +739,139 @@ int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); @param[out] xValues The curve's x-values. Pointer must be freed by client. @param[out] yValues The curve's y-values. Pointer must be freed by client. @return Error code. - */ -int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); - - -/** + */ + int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); + + /** @brief Retrieves the curve index for a specified pump index. @param pumpIndex The index of a pump @param[out] curveIndex The index of the curve used by the pump. @return Error code. - */ -int DLLEXPORT ENgetheadcurveindex(int pumpIndex, int *curveIndex); - - -/** + */ + int DLLEXPORT ENgetheadcurveindex(int pumpIndex, int *curveIndex); + + /** @brief Sets the curve id for a specified pump index. @param pumpIndex The index of the pump @param curveIndex The index of the curve used by the pump @return Error code. - */ -int DLLEXPORT ENsetheadcurveindex(int pumpIndex, int curveIndex); - - -/** + */ + int DLLEXPORT ENsetheadcurveindex(int pumpIndex, int curveIndex); + + /** @brief Get the type of pump @param linkIndex The index of the pump element @param[out] outType The integer-typed pump curve type signifier (output parameter) @return Error code @see EN_CurveType - */ -int DLLEXPORT ENgetpumptype(int linkIndex, int *outType); - - -/** + */ + int DLLEXPORT ENgetpumptype(int linkIndex, int *outType); + + /** + @brief Get the version number. This number is to be interpreted with implied decimals, i.e., "20100" == "2(.)01(.)00" + @param[out] version The version of EPANET + @return Error code. + */ + int DLLEXPORT ENgetversion(int *version); + + /** + @brief Specify parameters to define a simple control + @param cindex The index of the control to edit. First control is index 1. + @param ctype The type code to set for this control. + @param lindex The index of a link to control. + @param setting The control setting applied to the link. + @param nindex The index of a node used to control the link, or 0 for TIMER / TIMEOFDAY control. + @param level control point (tank level, junction pressure, or time in seconds). + @return Error code. + */ + int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); + + /** + @brief Set a property value for a node. + @param index The index of a node. First node is index 1. + @param code The code for the proprty to set. + @param v The value to set for this node and property. + @return Error code. + @see EN_NodeProperty + */ + int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v); + + /** + @brief Set a proprty value for a link. + @param index The index of a link. First link is index 1. + @param code The code for the property to set. + @param v The value to set for this link and property. + @return Error code. + @see EN_LinkProperty + */ + int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v); + + /** @brief Add a new time pattern. @param id The string ID of the pattern to add. @return Error code. @see ENgetpatternindex - */ -int DLLEXPORT ENaddpattern(char *id); - - -/** + */ + int DLLEXPORT ENaddpattern(char *id); + + /** + @brief Set multipliers for a specific pattern + @param index The index of a pattern. First pattern is index 1. + @param f An array of multipliers + @param len The length of array f. + @return Error code. + @see ENgetpatternindex + */ + int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len); + + /** + @brief Set the multiplier for a specific pattern at a specific period. + @param index The index of a pattern. First pattern is index 1. + @param period The period of the pattern to set. + @param value The value of the multiplier to set. + @return Error code. + */ + int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value); + + /** + @brief Set the value for a time parameter. + @param code The code for the parameter to set. + @param value The desired value of the parameter. + @return Error code. + @see EN_TimeProperty + */ + int DLLEXPORT ENsettimeparam(int code, long value); + + /** + @brief Set a value for an anlysis option. + @param code The code for the desired option. + @param v The desired value for the option specified. + @return Error code. + @see EN_Option + */ + int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v); + + /** + @brief Sets the level of hydraulic status reporting. + @param code Status reporting code. + @return Error code. + */ + int DLLEXPORT ENsetstatusreport(int code); + + /** + @brief Sets type of quality analysis called for + @param qualcode WQ parameter code, EN_QualityType + @param chemname Name of WQ constituent + @param chemunits Concentration units of WQ constituent + @param tracenode ID of node being traced (if applicable) + @return Error code. + @see EN_QualityType + + chemname and chemunits only apply when WQ analysis is for chemical. tracenode only applies when WQ analysis is source tracing. + */ + int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); + + /** @brief Get quality analysis information (type, chemical name, units, trace node ID) @param[out] qualcode The EN_QualityType code being used. @param[out] chemname The name of the WQ constituent. @@ -989,54 +879,49 @@ int DLLEXPORT ENaddpattern(char *id); @param[out] tracenode The trace node ID. @return Error code. @see EN_QualityType - */ -int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode); - -/** + */ + int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode); + + /** @brief Sets the node's base demand for a category. @param nodeIndex The index of a node. @param demandIdx The index of a demand category. @param baseDemand The base demand multiplier for the selected category. @return Error code. @see ENgetbasedemand - */ -int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); - - -// RETREIVING AND SETTING CURVES -/** + */ + int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + + /** @brief Retrieves index of curve with specific ID. @param id The ID of a curve. @param[out] index The index of the named curve @return Error code. @see ENgetcurveid - */ -int DLLEXPORT ENgetcurveindex(char *id, int *index); - - -/** + */ + int DLLEXPORT ENgetcurveindex(char *id, int *index); + + /** @brief Retrieves ID of a curve with specific index. @param index The index of a curve. @param[out] id The ID of the curve specified. @return Error code. @see ENsetcurveindex - + NOTE: 'id' must be able to hold MAXID characters - */ -int DLLEXPORT ENgetcurveid(int index, char *id); - - -/** + */ + int DLLEXPORT ENgetcurveid(int index, char *id); + + /** @brief Retrieves number of points in a curve @param index The index of a curve. @param[out] len The length of the curve coordinate list @return Error code. @see ENgetcurvevalue - */ -int DLLEXPORT ENgetcurvelen(int index, int *len); - - -/** + */ + int DLLEXPORT ENgetcurvelen(int index, int *len); + + /** @brief retrieves x,y point for a specific point number and curve @param curveIndex The index of a curve @param pointIndex The index of a point in the curve @@ -1044,41 +929,39 @@ int DLLEXPORT ENgetcurvelen(int index, int *len); @param[out] y The y-value of the specified point. @return Error code. @see ENgetcurvelen ENsetcurvevalue - */ -int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - -/** + */ + int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + + /** @brief Sets x,y point for a specific point and curve. @param curveIndex The index of a curve. @param pointIndex The index of a point in the curve. @param x The x-value of the point. @param y The y-value of the point. @return Error code. - */ -int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - -/** + */ + int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + + /** @brief Sets x,y values for a specified curve. @param index The index of a curve. @param x An array of x-values for the curve. @param y An array of y-values for the curve. @param len The length of the arrays x and y. @return Error code. - */ -int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); - - -/** + */ + int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); + + /** @brief Adds a new curve appended to the end of the existing curves. @param id The name of the curve to be added. @return Error code. @see ENgetcurveindex ENsetcurve - */ -int DLLEXPORT ENaddcurve(char *id); + */ + int DLLEXPORT ENaddcurve(char *id); + - -// CONTROL API -/** + /** @brief Gets the number of premises, true actions, and false actions and the priority of an existing rule-based control. @param index The index of a rule-based control. @param nPremises The number of conditions in a rule-based control. @@ -1086,20 +969,18 @@ int DLLEXPORT ENaddcurve(char *id); @param nFalseActions The number of actions that are executed when the conditions in the rule-based control are not met. @param priority The priority of a rule-based control. @return Error code. - */ -int DLLEXPORT ENgetrule(int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); -int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); + */ + int DLLEXPORT ENgetrule(int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); -/** + /** @brief Sets the priority of the existing rule-based control. @param index The index of a rule-based control. @param priority The priority to be set in the rule-based control. @return Error code. - */ -int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority); -int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority); + */ + int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority); -/** + /** @brief Gets the components of a premise/condition in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @@ -1111,11 +992,10 @@ int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TY @param status The status of the object to be checked (e.g. CLOSED) @param value The value of the variable to be checked (e.g. 5.5) @return Error code. - */ -int DLLEXPORT ENgetpremise(int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); -int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); + */ + int DLLEXPORT ENgetpremise(int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); -/** + /** @brief Sets the components of a premise/condition in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @@ -1127,41 +1007,37 @@ int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int indexPremise @param status The status of the object to be checked (e.g. CLOSED) @param value The value of the variable to be checked (e.g. 5.5) @return Error code. - */ -int DLLEXPORT ENsetpremise(int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); -int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); + */ + int DLLEXPORT ENsetpremise(int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); -/** + /** @brief Sets the index of an object in a premise of an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @param indexObj The index of the object (e.g. the index of the tank). @return Error code. - */ -int DLLEXPORT ENsetpremiseindex(int indexRule, int indexPremise, int indexObj); -int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj); + */ + int DLLEXPORT ENsetpremiseindex(int indexRule, int indexPremise, int indexObj); -/** + /** @brief Sets the status in a premise of an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @param status The status of the object to be checked (e.g. CLOSED) @return Error code. - */ -int DLLEXPORT ENsetpremisestatus(int indexRule, int indexPremise, int status); -int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status); + */ + int DLLEXPORT ENsetpremisestatus(int indexRule, int indexPremise, int status); -/** + /** @brief Sets the value in a premise of an existing rule-based control. @param indexRule The index of a rule-based control. @param indexPremise The index of the premise. @param value The value of the variable to be checked (e.g. 5.5) @return Error code. - */ -int DLLEXPORT ENsetpremisevalue(int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); -int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); - -/** + */ + int DLLEXPORT ENsetpremisevalue(int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); + + /** @brief Gets the components of a true-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are met. @@ -1169,11 +1045,10 @@ int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPr @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ -int DLLEXPORT ENgettrueaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); -int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + */ + int DLLEXPORT ENgettrueaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); -/** + /** @brief Sets the components of a true-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are met. @@ -1181,11 +1056,10 @@ int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexActi @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ -int DLLEXPORT ENsettrueaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); -int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); - -/** + */ + int DLLEXPORT ENsettrueaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + + /** @brief Gets the components of a false-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are not met. @@ -1193,11 +1067,10 @@ int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexActi @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ -int DLLEXPORT ENgetfalseaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); -int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + */ + int DLLEXPORT ENgetfalseaction(int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); -/** + /** @brief Sets the components of a false-action in an existing rule-based control. @param indexRule The index of a rule-based control. @param indexAction The index of the action when the conditions in the rule are not met. @@ -1205,102 +1078,171 @@ int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct @param status The status of the link (e.g. CLOSED) @param setting The value of the link (e.g. pump speed 0.9) @return Error code. - */ -int DLLEXPORT ENsetfalseaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); -int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + */ + int DLLEXPORT ENsetfalseaction(int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); -/** + /** @brief Returns the ID of a rule. @param indexRule The index of a rule-based control. @param id The ID of the rule @return Error code. - */ -int DLLEXPORT ENgetruleID(int indexRule, char* id); -int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char* id); + */ + int DLLEXPORT ENgetruleID(int indexRule, char* id); - -// ADDING AND DELETING NETWORK OBJECTS -/** + /** @brief Adds a new node @param id The name of the node to be added. @param nodeType The node type code @return Error code. - */ -int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType); -int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType); - -/** + */ + int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType); + + /** @brief Adds a new link @param id The name of the link to be added. @param linkType The link type code @param fromNode The id of the from node @param toNode The id of the to node @return Error code. - */ -int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode); -int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode); - -/** + */ + int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, char *toNode); + + /** @brief Deletes a node @param nodeIndex The node index @return Error code. - */ -int DLLEXPORT ENdeletenode(int nodeIndex); -int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int nodeIndex); - -/** + */ + int DLLEXPORT ENdeletenode(int nodeIndex); + + /** @brief Deletes a link @param linkIndex The link index @return Error code. - */ -int DLLEXPORT ENdeletelink(int linkIndex); -int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex); - -/*************************************************** + */ + int DLLEXPORT ENdeletelink(int linkIndex); + + + + + /*************************************************** + Threadsafe versions of all epanet functions - ***************************************************/ -int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); -int DLLEXPORT EN_free(EN_ProjectHandle *ph); + + ***************************************************/ + int DLLEXPORT EN_alloc(EN_ProjectHandle *ph); + int DLLEXPORT EN_free(EN_ProjectHandle *ph); -void DLLEXPORT EN_clearError(EN_ProjectHandle ph); -int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char **msg_buffer); + void DLLEXPORT EN_clearError(EN_ProjectHandle ph); + int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer); + int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, + const char *f3, void(*pviewprog)(char *)); + int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *rptFile, char *binOutFile, + EN_FlowUnits UnitsType, EN_FormType HeadlossFormula); -int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); + int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *inpFile, + const char *rptFile, const char *binOutFile); + int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename); -int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE* value); - -int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); -int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - -int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands); -int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); -int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIndex, int *pattIndex); - -int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); -int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int *curveIndex); -int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int curveIndex); -int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int linkIndex, int *outType); - -int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id); - -int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode); -int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); - -int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index); -int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id); -int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len); -int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); -int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); -int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); -int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id); + int DLLEXPORT EN_close(EN_ProjectHandle ph); + int DLLEXPORT EN_solveH(EN_ProjectHandle ph); + int DLLEXPORT EN_saveH(EN_ProjectHandle ph); + int DLLEXPORT EN_openH(EN_ProjectHandle ph); + int DLLEXPORT EN_initH(EN_ProjectHandle ph, int EN_SaveOption); + int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *currentTime); + int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tStep); + int DLLEXPORT EN_closeH(EN_ProjectHandle ph); + int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename); + int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename); + int DLLEXPORT EN_solveQ(EN_ProjectHandle ph); + int DLLEXPORT EN_openQ(EN_ProjectHandle ph); + int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveFlag); + int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *currentTime); + int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tStep); + int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *timeLeft); + int DLLEXPORT EN_closeQ(EN_ProjectHandle ph); + int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line); + int DLLEXPORT EN_report(EN_ProjectHandle ph); + int DLLEXPORT EN_resetreport(EN_ProjectHandle ph); + int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *reportFormat); + int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level); + int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count); + int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option opt, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value); + int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code); + int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code); + int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len); + int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); + int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); + int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE* value); + int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code); + int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands); + int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); + int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIndex, int *pattIndex); + int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code); + int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); + int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2); + int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); + int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int *curveIndex); + int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int curveIndex); + int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int linkIndex, int *outType); + int DLLEXPORT EN_getversion(int *version); + int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); + int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id); + int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int len); + int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value); + int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value); + int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code); + int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode); + int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, char *chemunits, int *tracenode); + int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); + int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len); + int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len); + int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id); + int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority); + int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority); + int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int *logop, int *object, int *indexObj, int *variable, int *relop, int *status, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, int object, int indexObj, int variable, int relop, int status, EN_API_FLOAT_TYPE value); + int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj); + int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status); + int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, EN_API_FLOAT_TYPE value); + int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, int *status, EN_API_FLOAT_TYPE *setting); + int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, int status, EN_API_FLOAT_TYPE setting); + int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char* id); + int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType); + int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode); + int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int nodeIndex); + int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex); + + #if defined(__cplusplus) } #endif diff --git a/tests/test_toolkit.cpp b/tests/test_toolkit.cpp index b08211c..d09ac80 100644 --- a/tests/test_toolkit.cpp +++ b/tests/test_toolkit.cpp @@ -134,7 +134,7 @@ BOOST_FIXTURE_TEST_CASE(test_epanet, Fixture) BOOST_FIXTURE_TEST_CASE(test_hyd_step, Fixture) { - int flag = EN_NOSAVE; + int flag = 00; long t, tstep; error = EN_openH(ph); @@ -201,6 +201,8 @@ BOOST_FIXTURE_TEST_CASE(test_progressive_stepping, Fixture) BOOST_REQUIRE(error == 0); do { + + error = EN_runH(ph, &t); BOOST_REQUIRE(error == 0); From c6fe1230d04f920d7349de8895b73f91a67a75cf Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 15:20:53 -0400 Subject: [PATCH 38/45] Fixing merge conflict --- include/epanet2.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index c73d69b..85e1170 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -1195,27 +1195,27 @@ extern "C" { int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode); int DLLEXPORT EN_geterror(int errcode, char *errmsg, int maxLen); - int DLLEXPORT EN_getstatistic(EN_Project *p, int code, EN_API_FLOAT_TYPE* value); - int DLLEXPORT EN_getnodeindex(EN_Project *p, char *id, int *index); - int DLLEXPORT EN_getnodeid(EN_Project *p, int index, char *id); - int DLLEXPORT EN_getnodetype(EN_Project *p, int index, int *code); - int DLLEXPORT EN_getnodevalue(EN_Project *p, int index, int code, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - int DLLEXPORT EN_setcoord(EN_Project *p, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); - int DLLEXPORT EN_getnumdemands(EN_Project *p, int nodeIndex, int *numDemands); - int DLLEXPORT EN_getbasedemand(EN_Project *p, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); - int DLLEXPORT EN_getdemandpattern(EN_Project *p, int nodeIndex, int demandIndex, int *pattIndex); - int DLLEXPORT EN_getlinkindex(EN_Project *p, char *id, int *index); - int DLLEXPORT EN_getlinkid(EN_Project *p, int index, char *id); - int DLLEXPORT EN_getlinktype(EN_Project *p, int index, EN_LinkType *code); - int DLLEXPORT EN_setlinktype(EN_Project *p, char *id, EN_LinkType type); - int DLLEXPORT EN_getlinknodes(EN_Project *p, int index, int *node1, int *node2); - int DLLEXPORT EN_getlinkvalue(EN_Project *p, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value); - int DLLEXPORT EN_getcurve(EN_Project *p, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); - int DLLEXPORT EN_getheadcurveindex(EN_Project *p, int pumpIndex, int *curveIndex); - int DLLEXPORT EN_setheadcurveindex(EN_Project *p, int pumpIndex, int curveIndex); - int DLLEXPORT EN_getpumptype(EN_Project *p, int linkIndex, int *outType); - int DLLEXPORT EN_getcurvetype(EN_Project *p, int curveIndex, int *outType); + int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE* value); + int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code); + int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); + int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y); + int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDemands); + int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIndex, EN_API_FLOAT_TYPE *baseDemand); + int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIndex, int *pattIndex); + int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index); + int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id); + int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code); + int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType type); + int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, int *node2); + int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); + int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int *curveIndex); + int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int pumpIndex, int curveIndex); + int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int linkIndex, int *outType); + int DLLEXPORT EN_getcurvetype(EN_ProjectHandle ph, int curveIndex, int *outType); int DLLEXPORT EN_getversion(int *version); int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); From 0938f82c32b3c5a99008a54ee29cea3a785c9707 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 15:46:24 -0400 Subject: [PATCH 39/45] Adding adding GEN_X macro for cmake export header --- CMakeLists.txt | 15 +++++++----- include/epanet2.h | 61 +++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acb522c..d5bf92b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,12 +80,15 @@ target_include_directories(epanet PUBLIC ${PROJECT_SOURCE_DIR}/include) # create export lib so we can link against dll using Visual Studio -include(GenerateExportHeader) -GENERATE_EXPORT_HEADER(epanet - BASE_NAME epanet - EXPORT_MACRO_NAME DLLEXPORT - EXPORT_FILE_NAME epanet_export.h - STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC) +IF (GEN_X) + include(GenerateExportHeader) + GENERATE_EXPORT_HEADER(epanet + BASE_NAME epanet + EXPORT_MACRO_NAME DLLEXPORT + EXPORT_FILE_NAME epanet_export.h + STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC) + file(COPY ${CMAKE_CURRENT_BINARY_DIR}/epanet_export.h DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include) +ENDIF (GEN_X) diff --git a/include/epanet2.h b/include/epanet2.h index 85e1170..02b9033 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -30,37 +30,40 @@ #define EN_API_FLOAT_TYPE float #endif -// // --- define WINDOWS -// #undef WINDOWS -// #ifdef _WIN32 -// #define WINDOWS -// #endif -// #ifdef __WIN32__ -// #define WINDOWS -// #endif +#ifdef GEN_X + #include "epanet_export.h" +#else + // --- define WINDOWS + #undef WINDOWS + #ifdef _WIN32 + #define WINDOWS + #endif + #ifdef __WIN32__ + #define WINDOWS + #endif -// // --- define DLLEXPORT -// #ifndef DLLEXPORT -// #ifdef WINDOWS -// #ifdef __cplusplus -// #define DLLEXPORT __declspec(dllexport) -// #else -// #define DLLEXPORT __declspec(dllexport) __stdcall -// #endif // __cplusplus -// #elif defined(CYGWIN) -// #define DLLEXPORT __stdcall -// #elif defined(__APPLE__) -// #ifdef __cplusplus -// #define DLLEXPORT -// #else -// #define DLLEXPORT -// #endif -// #else -// #define DLLEXPORT -// #endif -// #endif + // --- define DLLEXPORT + #ifndef DLLEXPORT + #ifdef WINDOWS + #ifdef __cplusplus + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllexport) __stdcall + #endif // __cplusplus + #elif defined(CYGWIN) + #define DLLEXPORT __stdcall + #elif defined(__APPLE__) + #ifdef __cplusplus + #define DLLEXPORT + #else + #define DLLEXPORT + #endif + #else + #define DLLEXPORT + #endif + #endif +#endif -#include "epanet_export.h" // --- Define the EPANET toolkit constants From 888e447ad92eec0073faf110ebb1245e3faaf79d Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Wed, 22 Aug 2018 16:14:21 -0400 Subject: [PATCH 40/45] Adding GEN_X to cmake invocation --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 258b330..1c7c3ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -48,7 +48,8 @@ before_build: - mkdir %BUILD_HOME% - cd %BUILD_HOME% - cmake -G "%GENERATOR%" - -DBUILD_TESTS=1 + -DBUILD_TESTS=1 + -DGEN_X=1 -DBOOST_ROOT="%BOOST_ROOT%" -DBoost_USE_STATIC_LIBS="ON" .. From e8acc1b177ba27e434c5458b70df5de59cc1426e Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 23 Aug 2018 07:48:01 -0400 Subject: [PATCH 41/45] Fixing build --- CMakeLists.txt | 16 +++++++--------- appveyor.yml | 3 +-- include/epanet2.h | 2 +- run/CMakeLists.txt | 1 + 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5bf92b..466e964 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,15 +80,13 @@ target_include_directories(epanet PUBLIC ${PROJECT_SOURCE_DIR}/include) # create export lib so we can link against dll using Visual Studio -IF (GEN_X) - include(GenerateExportHeader) - GENERATE_EXPORT_HEADER(epanet - BASE_NAME epanet - EXPORT_MACRO_NAME DLLEXPORT - EXPORT_FILE_NAME epanet_export.h - STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC) - +add_definitions(-D WITH_GENX) +include(GenerateExportHeader) +GENERATE_EXPORT_HEADER(epanet + BASE_NAME epanet + EXPORT_MACRO_NAME DLLEXPORT + EXPORT_FILE_NAME epanet_export.h + STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC) file(COPY ${CMAKE_CURRENT_BINARY_DIR}/epanet_export.h DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include) -ENDIF (GEN_X) diff --git a/appveyor.yml b/appveyor.yml index 1c7c3ba..258b330 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -48,8 +48,7 @@ before_build: - mkdir %BUILD_HOME% - cd %BUILD_HOME% - cmake -G "%GENERATOR%" - -DBUILD_TESTS=1 - -DGEN_X=1 + -DBUILD_TESTS=1 -DBOOST_ROOT="%BOOST_ROOT%" -DBoost_USE_STATIC_LIBS="ON" .. diff --git a/include/epanet2.h b/include/epanet2.h index 02b9033..042b83e 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -30,7 +30,7 @@ #define EN_API_FLOAT_TYPE float #endif -#ifdef GEN_X +#ifdef WITH_GENX #include "epanet_export.h" #else // --- define WINDOWS diff --git a/run/CMakeLists.txt b/run/CMakeLists.txt index 4822e95..53e792b 100644 --- a/run/CMakeLists.txt +++ b/run/CMakeLists.txt @@ -19,6 +19,7 @@ source_group("CLI" FILES ${EPANET_CLI_SOURCES}) # Creates the EPANET command line executable +add_definitions(-D WITH_GENX) add_executable(runepanet ${EPANET_CLI_SOURCES}) if(NOT WIN32) target_link_libraries(runepanet LINK_PUBLIC epanet m) From 670440b55c1a9aa040b1210f65acc6a72f21f615 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 23 Aug 2018 07:56:11 -0400 Subject: [PATCH 42/45] Fixing function definition for EN_getcurve --- src/epanet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/epanet.c b/src/epanet.c index 7f297ee..57879f0 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -3648,7 +3648,7 @@ int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { return (0); } -int DLLEXPORT EN_getcurvetype(EN_Project *p, int curveindex, int *type) { +int DLLEXPORT EN_getcurvetype(EN_ProjectHandle ph, int curveindex, int *type) { EN_Network *net = &p->network; From 40cd25748c63880390ee9a74a5ed28d6cbfde3e9 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 23 Aug 2018 08:00:30 -0400 Subject: [PATCH 43/45] Fixing bug EN_getcurvetype --- src/epanet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/epanet.c b/src/epanet.c index 57879f0..2ec819b 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -3650,6 +3650,8 @@ int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { int DLLEXPORT EN_getcurvetype(EN_ProjectHandle ph, int curveindex, int *type) { + EN_Project *p = (EN_Project*)ph; + EN_Network *net = &p->network; if (!p->Openflag) From a2fdd86a4d71cb21f2982ab66bfff3ee5d53cf5f Mon Sep 17 00:00:00 2001 From: Elad Salomons Date: Thu, 23 Aug 2018 23:20:16 +0300 Subject: [PATCH 44/45] Updating windows build script --- win_build/WinSDK/Makefile.bat | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win_build/WinSDK/Makefile.bat b/win_build/WinSDK/Makefile.bat index 22fb38f..310df56 100644 --- a/win_build/WinSDK/Makefile.bat +++ b/win_build/WinSDK/Makefile.bat @@ -21,9 +21,9 @@ Find /i "x86" < checkOS.tmp > StringCheck.tmp If %ERRORLEVEL% == 1 ( CALL "%SDK_PATH%bin\"SetEnv.cmd /x64 /release rem : create EPANET2.DLL - cl -o epanet2.dll epanet.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /link /DLL + cl -o epanet2.dll epanet.c util\errormanager.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /link /DLL rem : create EPANET2.EXE - cl -o epanet2.exe epanet.c ..\run\main.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /I ..\src /link + cl -o epanet2.exe epanet.c util\errormanager.c ..\run\main.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /I ..\src /link md "%Build_PATH%"\64bit move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\64bit move /y "%SRC_PATH%"\*.exe "%Build_PATH%"\64bit @@ -35,9 +35,9 @@ rem : 32 bit with DEF CALL "%SDK_PATH%bin\"SetEnv.cmd /x86 /release echo "32 bit with epanet2.def mapping" rem : create EPANET2.DLL -cl -o epanet2.dll epanet.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /link /DLL /def:..\win_build\WinSDK\epanet2.def /MAP +cl -o epanet2.dll epanet.c util\errormanager.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /link /DLL /def:..\win_build\WinSDK\epanet2.def /MAP rem : create EPANET2.EXE -cl -o epanet2.exe epanet.c ..\run\main.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /I ..\src /link +cl -o epanet2.exe epanet.c util\errormanager.c ..\run\main.c hash.c hydraul.c hydcoeffs.c hydsolver.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c genmmd.c /I ..\include /I ..\run /I ..\src /link md "%Build_PATH%"\32bit move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\32bit move /y "%SRC_PATH%"\*.exe "%Build_PATH%"\32bit From d5aeae893c784d46945385d2594a5156050ce54b Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 27 Aug 2018 12:16:55 -0400 Subject: [PATCH 45/45] Updating toolkit function to use errormanager --- src/epanet.c | 821 +++++++++++++++++++++++---------------------------- 1 file changed, 374 insertions(+), 447 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 5e5afe5..6463c08 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -556,12 +556,6 @@ int DLLEXPORT ENdeletenode(int index) { return EN_deletenode(_defaultModel, index); } - -// int DLLEXPORT EN_epanet(char *inpFile, char *rptFile, char *binOutFile, void(*callback) (char *)) -// { -// return ENepanet(inpFile, rptFile, binOutFile, callback); -// } - /* ---------------------------------------------------------------- Functions for opening & closing the EPANET system @@ -570,6 +564,7 @@ int DLLEXPORT ENdeletenode(int index) { /// allocate a project pointer int DLLEXPORT EN_createproject(EN_ProjectHandle *ph) +// Note: No error handling available until project allocation { int errorcode = 0; EN_Project *project = calloc(1, sizeof(EN_Project)); @@ -585,6 +580,7 @@ int DLLEXPORT EN_createproject(EN_ProjectHandle *ph) } int DLLEXPORT EN_deleteproject(EN_ProjectHandle *ph) +// Note: No error handling available after project deallocation { int errorcode = 0; EN_Project *p = (EN_Project*)(*ph); @@ -602,43 +598,6 @@ int DLLEXPORT EN_deleteproject(EN_ProjectHandle *ph) return 0; } -// int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2, -// const char *f3, void(*pviewprog)(char *)) -// { -// int errcode = 0; -// EN_Project *_p = (EN_Project*)ph; - -// ERRCODE(EN_open(ph, f1, f2, f3)); - -// _p->viewprog = pviewprog; -// if (_p->out_files.Hydflag != USE) { -// ERRCODE(EN_solveH(ph)); -// } - -// ERRCODE(EN_solveQ(ph)); -// ERRCODE(EN_report(ph)); -// EN_close(ph); - -// return set_error(_p->error_handle, errcode); -// ======= - -/// Create an EPANET project -// int DLLEXPORT EN_createproject(EN_Project **p) -// { -// EN_Project *project = calloc(1, sizeof(EN_Project)); -// if (project == NULL) return 101; -// *p = project; -// return 0; -// } - -// /// Delete an EPANET project -// int DLLEXPORT EN_deleteproject(EN_Project *p) -// { -// if (p) free(p); -// p = NULL; -// return 0; -// >>>>>>> c4b7c90634c73c1f800b2a18ea01f4be5b6711c1 -// } int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, EN_FlowUnits UnitsType, EN_FormType HeadlossFormula) @@ -663,7 +622,6 @@ int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, EN_Project *pr = (EN_Project*)*ph; - /* Set system flags */ pr->Openflag = TRUE; pr->hydraulics.OpenHflag = FALSE; @@ -698,7 +656,7 @@ int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3, // initialize default pattern getpatterns(pr); - return (errcode); + return set_error(pr->error_handle, errcode); } int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3) @@ -742,7 +700,7 @@ int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const ERRCODE(openfiles(p, f1, f2, f3)); if (errcode > 0) { errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } writelogo(p); @@ -773,7 +731,7 @@ int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const p->Openflag = TRUE; } else errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) @@ -786,10 +744,11 @@ int DLLEXPORT EN_saveinpfile(EN_ProjectHandle ph, char *filename) */ { EN_Project *p = (EN_Project*)ph; - + if (!p->Openflag) - return (102); - return (saveinpfile(p, filename)); + return set_error(p->error_handle, 102); + + return set_error(p->error_handle, saveinpfile(p, filename)); } int DLLEXPORT EN_close(EN_ProjectHandle ph) @@ -847,7 +806,8 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph) p->save_options.SaveHflag = FALSE; p->quality.OpenQflag = FALSE; p->save_options.SaveQflag = FALSE; - return (0); + + return set_error(p->error_handle, 0); } /* @@ -907,7 +867,8 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph) EN_closeH(ph); errcode = MAX(errcode, p->Warnflag); - return (errcode); + + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_saveH(EN_ProjectHandle ph) @@ -929,7 +890,7 @@ int DLLEXPORT EN_saveH(EN_ProjectHandle ph) /* Check if hydraulic results exist */ if (!p->save_options.SaveHflag) - return (104); + return set_error(p->error_handle, 104); /* Temporarily turn off WQ analysis */ tmpflag = p->quality.Qualflag; @@ -945,7 +906,7 @@ int DLLEXPORT EN_saveH(EN_ProjectHandle ph) if (errcode) { errmsg(p, errcode); } - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_openH(EN_ProjectHandle ph) @@ -965,12 +926,12 @@ int DLLEXPORT EN_openH(EN_ProjectHandle ph) p->hydraulics.OpenHflag = FALSE; p->save_options.SaveHflag = FALSE; if (!p->Openflag) { - return (102); + return set_error(p->error_handle, 102); } /* Check that previously saved hydraulics file not in use */ if (p->out_files.Hydflag == USE) { - return (107); + return set_error(p->error_handle, 107); } /* Open hydraulics solver */ @@ -979,7 +940,8 @@ int DLLEXPORT EN_openH(EN_ProjectHandle ph) p->hydraulics.OpenHflag = TRUE; else errmsg(p, errcode); - return (errcode); + + return set_error(p->error_handle, errcode); } /*** Updated 3/1/01 ***/ @@ -1010,7 +972,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) /* Check that hydraulics solver was opened */ if (!p->hydraulics.OpenHflag) - return (103); + return set_error(p->error_handle, 103); /* Open hydraulics file */ p->save_options.Saveflag = FALSE; @@ -1020,7 +982,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) p->save_options.Saveflag = TRUE; else { errmsg(p, errcode); - return errcode; + return set_error(p->error_handle, errcode); } } @@ -1028,7 +990,7 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag) inithyd(p, fflag); if (p->report.Statflag > 0) writeheader(p, STATHDR, 0); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { @@ -1038,11 +1000,11 @@ int DLLEXPORT EN_runH(EN_ProjectHandle ph, long *t) { *t = 0; if (!p->hydraulics.OpenHflag) - return (103); + return set_error(p->error_handle, 103); errcode = runhyd(p, t); if (errcode) errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { @@ -1052,13 +1014,13 @@ int DLLEXPORT EN_nextH(EN_ProjectHandle ph, long *tstep) { *tstep = 0; if (!p->hydraulics.OpenHflag) - return (103); + return set_error(p->error_handle, 103); errcode = nexthyd(p, tstep); if (errcode) errmsg(p, errcode); else if (p->save_options.Saveflag && *tstep == 0) p->save_options.SaveHflag = TRUE; - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_closeH(EN_ProjectHandle ph) @@ -1066,13 +1028,13 @@ int DLLEXPORT EN_closeH(EN_ProjectHandle ph) EN_Project *p = (EN_Project*)ph; if (!p->Openflag) { - return (102); + return set_error(p->error_handle, 102); } if (p->hydraulics.OpenHflag) { closehyd(p); } p->hydraulics.OpenHflag = FALSE; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { @@ -1084,11 +1046,11 @@ int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { /* Check that hydraulics results exist */ if (p->out_files.HydFile == NULL || !p->save_options.SaveHflag) - return (104); + return set_error(p->error_handle, 104); /* Open file */ if ((f = fopen(filename, "w+b")) == NULL) - return (305); + return set_error(p->error_handle, 305); /* Copy from HydFile to f */ HydFile = p->out_files.HydFile; @@ -1097,7 +1059,7 @@ int DLLEXPORT EN_savehydfile(EN_ProjectHandle ph, char *filename) { fputc(c, f); } fclose(f); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { @@ -1107,9 +1069,9 @@ int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { /* Check that input data exists & hydraulics system closed */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (p->hydraulics.OpenHflag) - return (108); + return set_error(p->error_handle, 108); /* Try to open hydraulics file */ strncpy(p->out_files.HydFname, filename, MAXFNAME); @@ -1123,7 +1085,7 @@ int DLLEXPORT EN_usehydfile(EN_ProjectHandle ph, char *filename) { p->out_files.Hydflag = SCRATCH; p->save_options.SaveHflag = FALSE; } - return (errcode); + return set_error(p->error_handle, errcode); } /* @@ -1182,7 +1144,7 @@ int DLLEXPORT EN_solveQ(EN_ProjectHandle ph) { /*** Updated 6/24/02 ***/ writecon("\b\b\b\b\b\b\b\b "); EN_closeQ(ph); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { @@ -1194,7 +1156,7 @@ int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { p->quality.OpenQflag = FALSE; p->save_options.SaveQflag = FALSE; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); // !LT! todo - check for p->save_options.SaveHflag / set sequential/step mode // if (!p->save_options.SaveHflag) return(104); @@ -1204,7 +1166,7 @@ int DLLEXPORT EN_openQ(EN_ProjectHandle ph) { p->quality.OpenQflag = TRUE; else errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { @@ -1213,7 +1175,7 @@ int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { EN_Project *p = (EN_Project*)ph; if (!p->quality.OpenQflag) - return (105); + return set_error(p->error_handle, 105); initqual(p); p->save_options.SaveQflag = FALSE; p->save_options.Saveflag = FALSE; @@ -1222,7 +1184,7 @@ int DLLEXPORT EN_initQ(EN_ProjectHandle ph, int saveflag) { if (!errcode) p->save_options.Saveflag = TRUE; } - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { @@ -1232,11 +1194,11 @@ int DLLEXPORT EN_runQ(EN_ProjectHandle ph, long *t) { *t = 0; if (!p->quality.OpenQflag) - return (105); + return set_error(p->error_handle, 105); errcode = runqual(p, t); if (errcode) errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { @@ -1246,14 +1208,14 @@ int DLLEXPORT EN_nextQ(EN_ProjectHandle ph, long *tstep) { *tstep = 0; if (!p->quality.OpenQflag) - return (105); + return set_error(p->error_handle, 105); errcode = nextqual(p, tstep); if (!errcode && p->save_options.Saveflag && *tstep == 0) { p->save_options.SaveQflag = TRUE; } if (errcode) errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { @@ -1263,14 +1225,14 @@ int DLLEXPORT EN_stepQ(EN_ProjectHandle ph, long *tleft) { *tleft = 0; if (!p->quality.OpenQflag) - return (105); + return set_error(p->error_handle, 105); errcode = stepqual(p, tleft); if (!errcode && p->save_options.Saveflag && *tleft == 0) { p->save_options.SaveQflag = TRUE; } if (errcode) errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { @@ -1278,10 +1240,10 @@ int DLLEXPORT EN_closeQ(EN_ProjectHandle ph) { EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); closequal(p); p->quality.OpenQflag = FALSE; - return (0); + return set_error(p->error_handle, 0); } /* @@ -1295,9 +1257,9 @@ int DLLEXPORT EN_writeline(EN_ProjectHandle ph, char *line) { EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); writeline(p, line); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_report(EN_ProjectHandle ph) { @@ -1307,11 +1269,11 @@ int DLLEXPORT EN_report(EN_ProjectHandle ph) { /* Check if results saved to binary output file */ if (!p->save_options.SaveQflag) - return (106); + return set_error(p->error_handle, 106); errcode = writereport(p); if (errcode) errmsg(p, errcode); - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { @@ -1320,13 +1282,13 @@ int DLLEXPORT EN_resetreport(EN_ProjectHandle ph) { EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); initreport(&p->report); for (i = 1; i <= p->network.Nnodes; i++) p->network.Node[i].Rpt = 0; for (i = 1; i <= p->network.Nlinks; i++) p->network.Link[i].Rpt = 0; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { @@ -1335,14 +1297,14 @@ int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) { EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (strlen(s) > MAXLINE) - return (250); + return set_error(p->error_handle, 250); strcpy(s1, s); if (setreport(p, s1) > 0) - return (250); + return set_error(p->error_handle, 250); else - return (0); + return set_error(p->error_handle, 0); } /* @@ -1365,7 +1327,7 @@ int DLLEXPORT EN_getversion(int *v) */ { *v = CODEVERSION; - return (0); + return 0; } int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *lindex, @@ -1390,9 +1352,9 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li *lindex = 0; *nindex = 0; if (!pr->Openflag) - return (102); + return set_error(pr->error_handle, 102); if (cindex < 1 || cindex > net->Ncontrols) - return (241); + return set_error(pr->error_handle, 241); *ctype = Control[cindex].Type; *lindex = Control[cindex].Link; s = Control[cindex].Setting; @@ -1425,7 +1387,7 @@ int DLLEXPORT EN_getcontrol(EN_ProjectHandle ph, int cindex, int *ctype, int *li lvl = (EN_API_FLOAT_TYPE)Control[cindex].Time; *setting = (EN_API_FLOAT_TYPE)s; *level = (EN_API_FLOAT_TYPE)lvl; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { @@ -1436,7 +1398,7 @@ int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { *count = 0; if (!pr->Openflag) - return (102); + return set_error(pr->error_handle, 102); switch (code) { case EN_NODECOUNT: *count = net->Nnodes; @@ -1460,9 +1422,9 @@ int DLLEXPORT EN_getcount(EN_ProjectHandle ph, EN_CountType code, int *count) { *count = net->Nrules; break; default: - return (251); + return set_error(pr->error_handle, 251); } - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, @@ -1477,7 +1439,7 @@ int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, double v = 0.0; *value = 0.0; if (!pr->Openflag) - return (102); + return set_error(pr->error_handle, 102); switch (code) { case EN_TRIALS: v = (double)hyd->MaxIter; @@ -1504,10 +1466,10 @@ int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code, break; default: - return (251); + return set_error(pr->error_handle, 251); } *value = (EN_API_FLOAT_TYPE)v; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { @@ -1522,9 +1484,9 @@ int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { *value = 0; if (!pr->Openflag) - return (102); + return set_error(pr->error_handle, 102); if (code < EN_DURATION || code > EN_NEXTEVENTIDX) - return (251); + return set_error(pr->error_handle, 251); switch (code) { case EN_DURATION: *value = time->Dur; @@ -1573,7 +1535,7 @@ int DLLEXPORT EN_gettimeparam(EN_ProjectHandle ph, int code, long *value) { *value = i; break; } - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { @@ -1582,9 +1544,9 @@ int DLLEXPORT EN_getflowunits(EN_ProjectHandle ph, int *code) { *code = -1; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); *code = p->parser.Flowflag; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { @@ -1597,7 +1559,7 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { EN_Network *net = &p->network; if (!p->Openflag) { - return(102); + return set_error(p->error_handle, 102); } /* Determine unit system based on flow units */ @@ -1661,13 +1623,9 @@ int DLLEXPORT EN_setflowunits(EN_ProjectHandle ph, int code) { } } - return(0); + return set_error(p->error_handle, 0); } -// <<<<<<< HEAD -// int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { -// ======= - int DLLEXPORT EN_getdemandmodel(EN_ProjectHandle ph, int *type, EN_API_FLOAT_TYPE *pmin, EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp) { @@ -1677,7 +1635,8 @@ int DLLEXPORT EN_getdemandmodel(EN_ProjectHandle ph, int *type, EN_API_FLOAT_TYP *pmin = (EN_API_FLOAT_TYPE)(p->hydraulics.Pmin * p->Ucf[PRESSURE]); *preq = (EN_API_FLOAT_TYPE)(p->hydraulics.Preq * p->Ucf[PRESSURE]); *pexp = (EN_API_FLOAT_TYPE)(p->hydraulics.Pexp); - return 0; + + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setdemandmodel(EN_ProjectHandle ph, int type, EN_API_FLOAT_TYPE pmin, @@ -1685,33 +1644,33 @@ int DLLEXPORT EN_setdemandmodel(EN_ProjectHandle ph, int type, EN_API_FLOAT_TYPE { EN_Project *p = (EN_Project*)ph; - if (type < 0 || type > EN_PDA) return 251; - if (pmin > preq || pexp <= 0.0) return 202; + if (type < 0 || type > EN_PDA) return set_error(p->error_handle, 251); + if (pmin > preq || pexp <= 0.0) return set_error(p->error_handle, 202); p->hydraulics.DemandModel = type; p->hydraulics.Pmin = pmin / p->Ucf[PRESSURE]; p->hydraulics.Preq = preq / p->Ucf[PRESSURE]; p->hydraulics.Pexp = pexp; - return 0; + + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getpatternindex(EN_ProjectHandle ph, char *id, int *index) { -//>>>>>>> c4b7c90634c73c1f800b2a18ea01f4be5b6711c1 int i; EN_Project *p = (EN_Project*)ph; *index = 0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); for (i = 1; i <= p->network.Npats; i++) { if (strcmp(id, p->network.Pattern[i].ID) == 0) { *index = i; - return (0); + return set_error(p->error_handle, 0); } } *index = 0; - return (205); + return set_error(p->error_handle, 205); } int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { @@ -1720,11 +1679,11 @@ int DLLEXPORT EN_getpatternid(EN_ProjectHandle ph, int index, char *id) { strcpy(id, ""); if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Npats) - return (205); + return set_error(p->error_handle, 205); strcpy(id, p->network.Pattern[index].ID); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { @@ -1732,11 +1691,11 @@ int DLLEXPORT EN_getpatternlen(EN_ProjectHandle ph, int index, int *len) { EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Npats) - return (205); + return set_error(p->error_handle, 205); *len = p->network.Pattern[index].Length; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, @@ -1746,13 +1705,13 @@ int DLLEXPORT EN_getpatternvalue(EN_ProjectHandle ph, int index, int period, *value = 0.0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Npats) - return (205); + return set_error(p->error_handle, 205); if (period < 1 || period > p->network.Pattern[index].Length) - return (251); + return set_error(p->error_handle, 251); *value = (EN_API_FLOAT_TYPE)p->network.Pattern[index].F[period - 1]; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { @@ -1762,15 +1721,15 @@ int DLLEXPORT EN_getcurveindex(EN_ProjectHandle ph, char *id, int *index) { *index = 0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); for (i = 1; i <= p->network.Ncurves; i++) { if (strcmp(id, p->network.Curve[i].ID) == 0) { *index = i; - return (0); + return set_error(p->error_handle, 0); } } *index = 0; - return (206); + return set_error(p->error_handle, 206); } int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { @@ -1779,11 +1738,11 @@ int DLLEXPORT EN_getcurveid(EN_ProjectHandle ph, int index, char *id) { strcpy(id, ""); if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Ncurves) - return (206); + return set_error(p->error_handle, 206); strcpy(id, p->network.Curve[index].ID); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { @@ -1791,11 +1750,11 @@ int DLLEXPORT EN_getcurvelen(EN_ProjectHandle ph, int index, int *len) { EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Ncurves) - return (206); + return set_error(p->error_handle, 206); *len = p->network.Curve[index].Npts; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, @@ -1806,14 +1765,14 @@ int DLLEXPORT EN_getcurvevalue(EN_ProjectHandle ph, int index, int pnt, *x = 0.0; *y = 0.0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Ncurves) - return (206); + return set_error(p->error_handle, 206); if (pnt < 1 || pnt > p->network.Curve[index].Npts) - return (251); + return set_error(p->error_handle, 251); *x = (EN_API_FLOAT_TYPE)p->network.Curve[index].X[pnt - 1]; *y = (EN_API_FLOAT_TYPE)p->network.Curve[index].Y[pnt - 1]; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) { @@ -1822,11 +1781,11 @@ int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode) *tracenode = 0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); *qualcode = p->quality.Qualflag; if (p->quality.Qualflag == TRACE) *tracenode = p->quality.TraceNode; - return (0); + return set_error(p->error_handle, 0); } @@ -1844,7 +1803,7 @@ int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname, strncpy(chemname, p->quality.ChemName, MAXID); strncpy(chemunits, p->quality.ChemUnits, MAXID); } - return 0; + return set_error(p->error_handle, 0); } void errorLookup(int errcode, char *dest_msg, int dest_len) @@ -1905,6 +1864,7 @@ int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer) } int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { + // Deprecate? char newMsg[MAXMSG+1]; switch (errcode) { @@ -1931,9 +1891,9 @@ int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) { strncpy(errmsg, newMsg, n); } if (strlen(errmsg) == 0) - return (251); + return 251; else - return (0); + return 0; } int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE *value) { @@ -1956,7 +1916,7 @@ int DLLEXPORT EN_getstatistic(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE * default: break; } - return 0; + return set_error(p->error_handle, 0); } /* @@ -1971,12 +1931,12 @@ int DLLEXPORT EN_getnodeindex(EN_ProjectHandle ph, char *id, int *index) { *index = 0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); *index = findnode(&p->network,id); if (*index == 0) - return (203); + return set_error(p->error_handle, 203); else - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { @@ -1985,11 +1945,11 @@ int DLLEXPORT EN_getnodeid(EN_ProjectHandle ph, int index, char *id) { strcpy(id, ""); if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nnodes) - return (203); + return set_error(p->error_handle, 203); strcpy(id, p->network.Node[index].ID); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { @@ -1998,9 +1958,9 @@ int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { *code = -1; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nnodes) - return (203); + return set_error(p->error_handle, 203); if (index <= p->network.Njuncs) *code = EN_JUNCTION; else { @@ -2009,7 +1969,7 @@ int DLLEXPORT EN_getnodetype(EN_ProjectHandle ph, int index, int *code) { else *code = EN_TANK; } - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, @@ -2018,23 +1978,20 @@ int DLLEXPORT EN_getcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nnodes) - return (203); + return set_error(p->error_handle, 203); if (!p->parser.Coordflag) - return (255); + return set_error(p->error_handle, 255); // check if node have coords if (p->network.Coord[index].HaveCoords == FALSE) - return (254); + return set_error(p->error_handle, 254); *x = (EN_API_FLOAT_TYPE)p->network.Coord[index].X; *y = (EN_API_FLOAT_TYPE)p->network.Coord[index].Y; -// <<<<<<< HEAD -// ======= -// >>>>>>> c4b7c90634c73c1f800b2a18ea01f4be5b6711c1 - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, @@ -2043,16 +2000,16 @@ int DLLEXPORT EN_setcoord(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE x, EN_Project *p = (EN_Project*)ph; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nnodes) - return (203); + return set_error(p->error_handle, 203); if (!p->parser.Coordflag) - return (255); + return set_error(p->error_handle, 255); p->network.Coord[index].X = x; p->network.Coord[index].Y = y; p->network.Coord[index].HaveCoords = TRUE; - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, @@ -2081,9 +2038,9 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, /* Check for valid arguments */ *value = 0.0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Nnodes) - return (203); + return set_error(p->error_handle, 203); /* Retrieve called-for parameter */ switch (code) { @@ -2127,7 +2084,7 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, case EN_SOURCEPAT: source = Node[index].S; if (source == NULL) - return (240); + return set_error(p->error_handle, 240); if (code == EN_SOURCEQUAL) v = source->C0; else if (code == EN_SOURCEMASS) @@ -2140,7 +2097,7 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, case EN_TANKLEVEL: if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); v = (Tank[index - Njuncs].H0 - Node[index].El) * Ucf[ELEV]; break; @@ -2241,15 +2198,15 @@ int DLLEXPORT EN_getnodevalue(EN_ProjectHandle ph, int index, int code, case EN_TANKVOLUME: if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); v = tankvolume(p, index - Njuncs, hyd->NodeHead[index]) * Ucf[VOLUME]; break; default: - return (251); + return set_error(p->error_handle, 251); } *value = (EN_API_FLOAT_TYPE)v; - return (0); + return set_error(p->error_handle, 0); } /* @@ -2264,12 +2221,12 @@ int DLLEXPORT EN_getlinkindex(EN_ProjectHandle ph, char *id, int *index) { *index = 0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); *index = findlink(&p->network,id); if (*index == 0) - return (204); + return set_error(p->error_handle, 204); else - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { @@ -2278,11 +2235,11 @@ int DLLEXPORT EN_getlinkid(EN_ProjectHandle ph, int index, char *id) { strcpy(id, ""); if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nlinks) - return (204); + return set_error(p->error_handle, 204); strcpy(id, p->network.Link[index].ID); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) { @@ -2291,11 +2248,11 @@ int DLLEXPORT EN_getlinktype(EN_ProjectHandle ph, int index, EN_LinkType *code) *code = -1; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nlinks) - return (204); + return set_error(p->error_handle, 204); *code = p->network.Link[index].Type; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, @@ -2306,12 +2263,12 @@ int DLLEXPORT EN_getlinknodes(EN_ProjectHandle ph, int index, int *node1, *node1 = 0; *node2 = 0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > p->network.Nlinks) - return (204); + return set_error(p->error_handle, 204); *node1 = p->network.Link[index].N1; *node2 = p->network.Link[index].N2; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty code, @@ -2337,9 +2294,9 @@ int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty co /* Check for valid arguments */ *value = 0.0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Nlinks) - return (204); + return set_error(p->error_handle, 204); /* Retrieve called-for parameter */ switch (code) { @@ -2381,7 +2338,7 @@ int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty co case EN_INITSETTING: if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) - return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); + return set_error(p->error_handle, ENgetlinkvalue(index, EN_ROUGHNESS, value)); v = Link[index].Kc; switch (Link[index].Type) { case EN_PRV: @@ -2484,7 +2441,7 @@ int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty co case EN_SETTING: if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) { - return (ENgetlinkvalue(index, EN_ROUGHNESS, value)); + return set_error(p->error_handle, ENgetlinkvalue(index, EN_ROUGHNESS, value)); } if (LinkSetting[index] == MISSING) { v = 0.0; @@ -2556,7 +2513,7 @@ int DLLEXPORT EN_getlinkvalue(EN_ProjectHandle ph, int index, EN_LinkProperty co returnValue = 251; } *value = (EN_API_FLOAT_TYPE)v; - return returnValue; + return set_error(p->error_handle, returnValue); } int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nValues, @@ -2570,7 +2527,7 @@ int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nV /* Check that input file opened */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); curve = p->network.Curve[curveIndex]; nPoints = curve.Npts; @@ -2591,7 +2548,7 @@ int DLLEXPORT EN_getcurve(EN_ProjectHandle ph, int curveIndex, char *id, int *nV *xValues = pointX; *yValues = pointY; - return (0); + return set_error(p->error_handle, 0); } /* @@ -2620,11 +2577,11 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind /* Check that input file opened */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); /* Check that control exists */ if (cindex < 1 || cindex > p->network.Ncontrols) - return (241); + return set_error(p->error_handle, 241); net = &p->network; @@ -2642,25 +2599,25 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind /* Check that controlled link exists */ if (lindex == 0) { Control[cindex].Link = 0; - return (0); + return set_error(p->error_handle, 0); } if (lindex < 0 || lindex > Nlinks) - return (204); + return set_error(p->error_handle, 204); /* Cannot control check valve. */ if (Link[lindex].Type == EN_CVPIPE) - return (207); + return set_error(p->error_handle, 207); /* Check for valid parameters */ if (ctype < 0 || ctype > EN_TIMEOFDAY) - return (251); + return set_error(p->error_handle, 251); if (ctype == EN_LOWLEVEL || ctype == EN_HILEVEL) { if (nindex < 1 || nindex > Nnodes) - return (203); + return set_error(p->error_handle, 203); } else nindex = 0; if (s < 0.0 || lvl < 0.0) - return (202); + return set_error(p->error_handle, 202); /* Adjust units of control parameters */ switch (Link[lindex].Type) { @@ -2680,7 +2637,7 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind else if (s == 1.0) status = OPEN; else - return (202); + return set_error(p->error_handle, 202); s = Link[lindex].Kc; break; @@ -2711,7 +2668,7 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind Control[cindex].Setting = s; Control[cindex].Grade = lvl; Control[cindex].Time = t; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v) @@ -2747,9 +2704,9 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F double value = v; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Nnodes) - return (203); + return set_error(p->error_handle, 203); switch (code) { case EN_ELEVATION: if (index <= Njuncs) @@ -2779,7 +2736,7 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F /* NOTE: primary demand category is last on demand list */ j = ROUND(value); if (j < 0 || j > Npats) - return (205); + return set_error(p->error_handle, 205); if (index <= Njuncs) { for (demand = Node[index].D; demand != NULL; demand = demand->next) { if (demand->next == NULL) @@ -2791,9 +2748,9 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F case EN_EMITTER: if (index > Njuncs) - return (203); + return set_error(p->error_handle, 203); if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); if (value > 0.0) value = pow((Ucf[FLOW] / value), hyd->Qexp) / Ucf[PRESSURE]; Node[index].Ke = value; @@ -2801,7 +2758,7 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F case EN_INITQUAL: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); Node[index].C0 = value / Ucf[QUALITY]; if (index > Njuncs) Tank[index - Njuncs].C = Node[index].C0; @@ -2811,12 +2768,12 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F case EN_SOURCETYPE: case EN_SOURCEPAT: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); source = Node[index].S; if (source == NULL) { source = (struct Ssource *)malloc(sizeof(struct Ssource)); if (source == NULL) - return (101); + return set_error(p->error_handle, 101); source->Type = CONCEN; source->C0 = 0.0; source->Pat = 0; @@ -2827,21 +2784,21 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F } else if (code == EN_SOURCEPAT) { j = ROUND(value); if (j < 0 || j > Npats) - return (205); + return set_error(p->error_handle, 205); source->Pat = j; } else // code == EN_SOURCETYPE { j = ROUND(value); if (j < CONCEN || j > FLOWPACED) - return (251); + return set_error(p->error_handle, 251); else source->Type = (char)j; } - return (0); + return set_error(p->error_handle, 0); case EN_TANKLEVEL: if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); j = index - Njuncs; if (Tank[j].A == 0.0) /* Tank is a reservoir */ { @@ -2853,7 +2810,7 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F } else { value = Node[index].El + value / Ucf[ELEV]; if (value > Tank[j].Hmax || value < Tank[j].Hmin) - return (202); + return set_error(p->error_handle, 202); Tank[j].H0 = value; Tank[j].V0 = tankvolume(p, j, Tank[j].H0); // Resetting Volume in addition to initial volume @@ -2868,9 +2825,9 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F case EN_TANKDIAM: if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); j = index - Njuncs; if (j > 0 && Tank[j].A > 0.0) { value /= Ucf[ELEV]; @@ -2879,81 +2836,81 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F Tank[j].V0 = tankvolume(p, j, Tank[j].H0); Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); } else { - return (251); + return set_error(p->error_handle, 251); } break; case EN_MINVOLUME: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); j = index - Njuncs; if (j > 0 && Tank[j].A > 0.0) { Tank[j].Vmin = value / Ucf[VOLUME]; Tank[j].V0 = tankvolume(p, j, Tank[j].H0); Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); } else { - return (251); + return set_error(p->error_handle, 251); } break; case EN_MINLEVEL: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); if (index <= Njuncs) - return (251); // not a tank or reservoir + return set_error(p->error_handle, 251); // not a tank or reservoir j = index - Njuncs; if (Tank[j].A == 0.0) - return (251); // node is a reservoir + return set_error(p->error_handle, 251); // node is a reservoir Htmp = value / Ucf[ELEV] + Node[index].El; if (Htmp < Tank[j].Hmax && Htmp <= Tank[j].H0) { if (Tank[j].Vcurve > 0) - return (202); + return set_error(p->error_handle, 202); Tank[j].Hmin = Htmp; Tank[j].Vmin = tankvolume(p, j, Tank[j].Hmin); } else { - return (251); + return set_error(p->error_handle, 251); } break; case EN_MAXLEVEL: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); if (index <= Njuncs) - return (251); // not a tank or reservoir + return set_error(p->error_handle, 251); // not a tank or reservoir j = index - Njuncs; if (Tank[j].A == 0.0) - return (251); // node is a reservoir + return set_error(p->error_handle, 251); // node is a reservoir Htmp = value / Ucf[ELEV] + Node[index].El; if (Htmp > Tank[j].Hmin && Htmp >= Tank[j].H0) { if (Tank[j].Vcurve > 0) - return (202); + return set_error(p->error_handle, 202); Tank[j].Hmax = Htmp; Tank[j].Vmax = tankvolume(p, j, Tank[j].Hmax); } else { - return (251); + return set_error(p->error_handle, 251); } break; case EN_MIXMODEL: j = ROUND(value); if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); if (j < MIX1 || j > LIFO) - return (202); + return set_error(p->error_handle, 202); if (index > Njuncs && Tank[index - Njuncs].A > 0.0) { Tank[index - Njuncs].MixModel = (char)j; } else { - return (251); + return set_error(p->error_handle, 251); } break; case EN_MIXFRACTION: if (value < 0.0 || value > 1.0) - return (202); + return set_error(p->error_handle, 202); if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); j = index - Njuncs; if (j > 0 && Tank[j].A > 0.0) { Tank[j].V1max = value * Tank[j].Vmax; @@ -2962,22 +2919,22 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F case EN_TANK_KBULK: if (index <= Njuncs) - return (251); + return set_error(p->error_handle, 251); j = index - Njuncs; if (j > 0 && Tank[j].A > 0.0) { Tank[j].Kb = value / SECperDAY; qu->Reactflag = 1; } else { - return (251); + return set_error(p->error_handle, 251); } break; /*** New parameter additions ends here. ***/ default: - return (251); + return set_error(p->error_handle, 251); } - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, @@ -3010,14 +2967,14 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, double r, value = v; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Nlinks) - return (204); + return set_error(p->error_handle, 204); switch (code) { case EN_DIAMETER: if (Link[index].Type != EN_PUMP) { if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); value /= Ucf[DIAM]; /* Convert to feet */ r = Link[index].Diam / value; /* Ratio of old to new diam */ Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */ @@ -3029,7 +2986,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, case EN_LENGTH: if (Link[index].Type <= EN_PIPE) { if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); Link[index].Len = value / Ucf[ELEV]; resistcoeff(p, index); } @@ -3038,7 +2995,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, case EN_ROUGHNESS: if (Link[index].Type <= EN_PIPE) { if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); Link[index].Kc = value; if (hyd->Formflag == DW) Link[index].Kc /= (1000.0 * Ucf[ELEV]); @@ -3049,7 +3006,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, case EN_MINORLOSS: if (Link[index].Type != EN_PUMP) { if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); Link[index].Km = 0.02517 * value / SQR(Link[index].Diam) / SQR(Link[index].Diam); } @@ -3059,10 +3016,10 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, case EN_STATUS: /* Cannot set status for a check valve */ if (Link[index].Type == EN_CVPIPE) - return (207); + return set_error(p->error_handle, 207); s = (char)ROUND(value); if (s < 0 || s > 1) - return (251); + return set_error(p->error_handle, 251); if (code == EN_INITSTATUS) setlinkstatus(p, index, s, &Link[index].Stat, &Link[index].Kc); else @@ -3072,9 +3029,9 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, case EN_INITSETTING: case EN_SETTING: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); if (Link[index].Type == EN_PIPE || Link[index].Type == EN_CVPIPE) - return (ENsetlinkvalue(index, EN_ROUGHNESS, v)); + return set_error(p->error_handle, ENsetlinkvalue(index, EN_ROUGHNESS, v)); else { switch (Link[index].Type) { case EN_PUMP: @@ -3092,10 +3049,10 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, /*** Updated 9/7/00 ***/ case EN_GPV: - return (202); /* Cannot modify setting for GPV */ + return set_error(p->error_handle, 202); /* Cannot modify setting for GPV */ default: - return (251); + return set_error(p->error_handle, 251); } if (code == EN_INITSETTING) setlinksetting(p, index, value, &Link[index].Stat, &Link[index].Kc); @@ -3120,9 +3077,9 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, break; default: - return (251); + return set_error(p->error_handle, 251); } - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { @@ -3142,21 +3099,21 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { /* Check if a pattern with same id already exists */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (ENgetpatternindex(id, &i) == 0) - return (215); + return set_error(p->error_handle, 215); /* Check that id name is not too long */ if (strlen(id) > MAXID) - return (250); + return set_error(p->error_handle, 250); /* Allocate memory for a new array of patterns */ n = Npats + 1; tmpPat = (Spattern *)calloc(n + 1, sizeof(Spattern)); if (tmpPat == NULL) - return (101); + return set_error(p->error_handle, 101); /* Copy contents of old pattern array to new one */ @@ -3188,7 +3145,7 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { if (tmpPat[i].F) free(tmpPat[i].F); free(tmpPat); - return (101); + return set_error(p->error_handle, 101); } // Replace old pattern array with new one @@ -3199,7 +3156,7 @@ int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id) { Pattern = tmpPat; net->Npats = n; par->MaxPats = n; - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int n) { @@ -3214,22 +3171,22 @@ int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f /* Check for valid arguments */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Npats) - return (205); + return set_error(p->error_handle, 205); if (n <= 0) - return (202); + return set_error(p->error_handle, 202); /* Re-set number of time periods & reallocate memory for multipliers */ Pattern[index].Length = n; Pattern[index].F = (double *)realloc(Pattern[index].F, n * sizeof(double)); if (Pattern[index].F == NULL) - return (101); + return set_error(p->error_handle, 101); /* Load multipliers into pattern */ for (j = 0; j < n; j++) Pattern[index].F[j] = f[j]; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_API_FLOAT_TYPE value) { @@ -3244,13 +3201,13 @@ int DLLEXPORT EN_setpatternvalue(EN_ProjectHandle ph, int index, int period, EN_ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Npats) - return (205); + return set_error(p->error_handle, 205); if (period <= 0 || period > Pattern[index].Length) - return (251); + return set_error(p->error_handle, 251); Pattern[index].F[period - 1] = value; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { @@ -3267,21 +3224,21 @@ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { /* Check if a curve with same id already exists */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (ENgetcurveindex(id, &i) == 0) - return (215); + return set_error(p->error_handle, 215); /* Check that id name is not too long */ if (strlen(id) > MAXID) - return (250); + return set_error(p->error_handle, 250); /* Allocate memory for a new array of curves */ n = net->Ncurves + 1; tmpCur = (Scurve *)calloc(n + 1, sizeof(Scurve)); if (tmpCur == NULL) - return (101); + return set_error(p->error_handle, 101); /* Copy contents of old curve array to new one */ @@ -3327,7 +3284,7 @@ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { free(tmpCur[i].Y); } free(tmpCur); - return (101); + return set_error(p->error_handle, 101); } // Replace old curves array with new one @@ -3340,7 +3297,7 @@ int DLLEXPORT EN_addcurve(EN_ProjectHandle ph, char *id) { net->Curve = tmpCur; net->Ncurves = n; par->MaxCurves = n; - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int n) { @@ -3353,27 +3310,27 @@ int DLLEXPORT EN_setcurve(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *x, /* Check for valid arguments */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > net->Ncurves) - return (206); + return set_error(p->error_handle, 206); if (n <= 0) - return (202); + return set_error(p->error_handle, 202); /* Re-set number of points & reallocate memory for values */ Curve[index].Npts = n; Curve[index].X = (double *)realloc(Curve[index].X, n * sizeof(double)); Curve[index].Y = (double *)realloc(Curve[index].Y, n * sizeof(double)); if (Curve[index].X == NULL) - return (101); + return set_error(p->error_handle, 101); if (Curve[index].Y == NULL) - return (101); + return set_error(p->error_handle, 101); /* Load values into curve */ for (j = 0; j < n; j++) { Curve[index].X[j] = x[j]; Curve[index].Y[j] = y[j]; } - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y) { @@ -3385,14 +3342,14 @@ int DLLEXPORT EN_setcurvevalue(EN_ProjectHandle ph, int index, int pnt, EN_API_F const int Ncurves = net->Ncurves; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > Ncurves) - return (206); + return set_error(p->error_handle, 206); if (pnt <= 0 || pnt > Curve[index].Npts) - return (251); + return set_error(p->error_handle, 251); Curve[index].X[pnt - 1] = x; Curve[index].Y[pnt - 1] = y; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) @@ -3404,7 +3361,7 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) time_options_t *time = &p->time_options; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (p->hydraulics.OpenHflag || p->quality.OpenQflag) { // --> there's nothing wrong with changing certain time parameters during a // simulation run, or before the run has started. @@ -3420,7 +3377,7 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) */ } if (value < 0) - return (202); + return set_error(p->error_handle, 202); switch (code) { case EN_DURATION: time->Dur = value; @@ -3430,7 +3387,7 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) case EN_HYDSTEP: if (value == 0) - return (202); + return set_error(p->error_handle, 202); time->Hstep = value; time->Hstep = MIN(time->Pstep, time->Hstep); time->Hstep = MIN(time->Rstep, time->Hstep); @@ -3439,14 +3396,14 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) case EN_QUALSTEP: if (value == 0) - return (202); + return set_error(p->error_handle, 202); qu->Qstep = value; qu->Qstep = MIN(qu->Qstep, time->Hstep); break; case EN_PATTERNSTEP: if (value == 0) - return (202); + return set_error(p->error_handle, 202); time->Pstep = value; if (time->Hstep > time->Pstep) time->Hstep = time->Pstep; @@ -3458,7 +3415,7 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) case EN_REPORTSTEP: if (value == 0) - return (202); + return set_error(p->error_handle, 202); time->Rstep = value; if (time->Hstep > time->Rstep) time->Hstep = time->Rstep; @@ -3466,20 +3423,20 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) case EN_REPORTSTART: if (time->Rstart > time->Dur) - return (202); + return set_error(p->error_handle, 202); time->Rstart = value; break; case EN_RULESTEP: if (value == 0) - return (202); + return set_error(p->error_handle, 202); time->Rulestep = value; time->Rulestep = MIN(time->Rulestep, time->Hstep); break; case EN_STATISTIC: if (value > RANGE) - return (202); + return set_error(p->error_handle, 202); rep->Tstatflag = (char)value; break; @@ -3492,9 +3449,9 @@ int DLLEXPORT EN_settimeparam(EN_ProjectHandle ph, int code, long value) break; default: - return (251); + return set_error(p->error_handle, 251); } - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) @@ -3521,26 +3478,26 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) int i, j; double Ke, n, ucf, value = v; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); switch (code) { case EN_TRIALS: if (value < 1.0) - return (202); + return set_error(p->error_handle, 202); hyd->MaxIter = (int)value; break; case EN_ACCURACY: if (value < 1.e-5 || value > 1.e-1) - return (202); + return set_error(p->error_handle, 202); hyd->Hacc = value; break; case EN_TOLERANCE: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); qu->Ctol = value / Ucf[QUALITY]; break; case EN_EMITEXPON: if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); n = 1.0 / value; ucf = pow(Ucf[FLOW], n) / Ucf[PRESSURE]; for (i = 1; i <= Njuncs; i++) { @@ -3553,25 +3510,25 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v) break; case EN_DEMANDMULT: if (value <= 0.0) - return (202); + return set_error(p->error_handle, 202); hyd->Dmult = value; break; case EN_HEADERROR: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); hyd->HeadErrorLimit = value / Ucf[HEAD]; break; case EN_FLOWCHANGE: if (value < 0.0) - return (202); + return set_error(p->error_handle, 202); hyd->FlowChangeLimit = value / Ucf[FLOW]; break; default: - return (251); + return set_error(p->error_handle, 251); } - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { @@ -3583,7 +3540,7 @@ int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code) { p->report.Statflag = (char)code; else errcode = 202; - return (errcode); + return set_error(p->error_handle, errcode); } int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, char *chemunits, char *tracenode) { @@ -3601,9 +3558,9 @@ int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, double ccf = 1.0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (qualcode < EN_NONE || qualcode > EN_TRACE) - return (251); + return set_error(p->error_handle, 251); qu->Qualflag = (char)qualcode; qu->Ctol *= Ucf[QUALITY]; if (qu->Qualflag == CHEM) /* Chemical constituent */ @@ -3621,7 +3578,7 @@ int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, { qu->TraceNode = findnode(net,tracenode); if (qu->TraceNode == 0) - return (203); + return set_error(p->error_handle, 203); strncpy(qu->ChemName, u_PERCENT, MAXID); strncpy(qu->ChemUnits, tracenode, MAXID); @@ -3650,7 +3607,7 @@ int DLLEXPORT EN_setqualtype(EN_ProjectHandle ph, int qualcode, char *chemname, Ucf[REACTRATE] = ccf; qu->Ctol /= Ucf[QUALITY]; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveindex) { @@ -3663,11 +3620,11 @@ int DLLEXPORT EN_getheadcurveindex(EN_ProjectHandle ph, int index, int *curveind const int Nlinks = net->Nlinks; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > Nlinks || EN_PUMP != Link[index].Type) - return (204); + return set_error(p->error_handle, 204); *curveindex = Pump[findpump(net, index)].Hcurve; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveindex) { @@ -3685,12 +3642,12 @@ int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveinde Spump *pump; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > Nlinks || EN_PUMP != Link[index].Type) { - return (204); + return set_error(p->error_handle, 204); } if (curveindex <= 0 || curveindex > Ncurves) { - return (206); + return set_error(p->error_handle, 206); } pIdx = findpump(net, index); pump = &p->network.Pump[pIdx]; @@ -3709,7 +3666,7 @@ int DLLEXPORT EN_setheadcurveindex(EN_ProjectHandle ph, int index, int curveinde pump->Hmax /= Ucf[HEAD]; p->network.Curve[curveindex].Type = P_CURVE; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { @@ -3724,11 +3681,11 @@ int DLLEXPORT EN_getpumptype(EN_ProjectHandle ph, int index, int *type) { *type = -1; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > Nlinks || EN_PUMP != Link[index].Type) - return (204); + return set_error(p->error_handle, 204); *type = Pump[findpump(&p->network, index)].Ptype; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getcurvetype(EN_ProjectHandle ph, int curveindex, int *type) { @@ -3738,11 +3695,11 @@ int DLLEXPORT EN_getcurvetype(EN_ProjectHandle ph, int curveindex, int *type) { EN_Network *net = &p->network; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (curveindex < 1 || curveindex > net->Ncurves) - return (206); + return set_error(p->error_handle, 206); *type = net->Curve[curveindex].Type; - return (0); + return set_error(p->error_handle, 0); } /* @@ -3786,23 +3743,23 @@ int openfiles(EN_Project *p, const char *f1, const char *f2, const char *f3) if (strcomp(f1, f2) || strcomp(f1, f3) || (strcomp(f2, f3) && (strlen(f2) > 0 || strlen(f3) > 0))) { writecon(FMT04); - return (301); + return set_error(p->error_handle, 301); } /* Attempt to open input and report files */ if ((par->InFile = fopen(f1, "rt")) == NULL) { writecon(FMT05); writecon(f1); - return (302); + return set_error(p->error_handle, 302); } if (strlen(f2) == 0) rep->RptFile = stdout; else if ((rep->RptFile = fopen(f2, "wt")) == NULL) { writecon(FMT06); - return (303); + return set_error(p->error_handle, 303); } - return (0); + return set_error(p->error_handle, 0); } /* End of openfiles */ int openhydfile(EN_Project *p) @@ -3833,7 +3790,7 @@ int openhydfile(EN_Project *p) /* If HydFile currently open, then close it if its not a scratch file */ if (out->HydFile != NULL) { if (out->Hydflag == SCRATCH) - return (0); + return set_error(p->error_handle, 0); fclose(out->HydFile); } @@ -3853,7 +3810,7 @@ int openhydfile(EN_Project *p) break; } if (out->HydFile == NULL) - return (305); + return set_error(p->error_handle, 305); /* If a previous hydraulics solution is not being used, then */ /* save the current network size parameters to the file. */ @@ -3877,22 +3834,22 @@ int openhydfile(EN_Project *p) if (out->Hydflag == USE) { fread(&magic, sizeof(INT4), 1, out->HydFile); if (magic != MAGICNUMBER) - return (306); + return set_error(p->error_handle, 306); fread(&version, sizeof(INT4), 1, out->HydFile); if (version != ENGINE_VERSION) - return (306); + return set_error(p->error_handle, 306); if (fread(nsize, sizeof(INT4), 6, out->HydFile) < 6) - return (306); + return set_error(p->error_handle, 306); if (nsize[0] != Nnodes || nsize[1] != Nlinks || nsize[2] != Ntanks || nsize[3] != Npumps || nsize[4] != Nvalves || nsize[5] != time->Dur) - return (306); + return set_error(p->error_handle, 306); p->save_options.SaveHflag = TRUE; } /* Save current position in hydraulics file */ /* where storage of hydraulic results begins */ out->HydOffset = ftell(out->HydFile); - return (errcode); + return set_error(p->error_handle, errcode); } int openoutfile(EN_Project *p) @@ -3960,7 +3917,7 @@ int openoutfile(EN_Project *p) } else out->TmpOutFile = out->OutFile; } - return (errcode); + return set_error(p->error_handle, errcode); } /* @@ -4134,7 +4091,7 @@ int allocdata(EN_Project *p) /* Allocate memory for rule base (see RULES.C) */ if (!errcode) errcode = allocrules(p); - return (errcode); + return set_error(p->error_handle, errcode); } /* End of allocdata */ void freeTmplist(STmplist *t) @@ -4284,35 +4241,6 @@ char *getTmpName(EN_Project *p, char *fname) // --- free the pointer returned by _tempnam if (name) free(name); -/* -/////////////////// DEPRECATED ///////////////////////////////////// -// --- for Windows systems: -#ifdef WINDOWS - // --- use system function tmpnam() to create a temporary file name - char name[MAXFNAME + 1]; - int n; - - tmpnam(name); - - // --- if user supplied the name of a temporary directory, - // then make it be the prefix of the full file name - n = (int)strlen(out->TmpDir); - if (n > 0) { - strcpy(fname, out->TmpDir); - if (fname[n - 1] != '\\') - strcat(fname, "\\"); - } - - // --- otherwise, use the relative path notation as the file name - // prefix so that the file will be placed in the current directory - else { - strcpy(fname, ".\\"); - } - - // --- now add the prefix to the file name - strcat(fname, name); -*/ - // --- for non-Windows systems: #else // --- use system function mkstemp() to create a temporary file name @@ -4525,13 +4453,13 @@ int DLLEXPORT EN_getnumdemands(EN_ProjectHandle ph, int nodeIndex, int *numDeman /* Check for valid arguments */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) - return (203); + return set_error(p->error_handle, 203); for (d = p->network.Node[nodeIndex].D; d != NULL; d = d->next) n++; *numDemands = n; - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { @@ -4542,21 +4470,21 @@ int DLLEXPORT EN_getbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx /* Check for valid arguments */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) - return (203); + return set_error(p->error_handle, 203); if (nodeIndex <= p->network.Njuncs) { for (d = p->network.Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) { n++; } if (n != demandIdx) { - return (253); + return set_error(p->error_handle, 253); } *baseDemand = (EN_API_FLOAT_TYPE)(d->Base * p->Ucf[FLOW]); } else { *baseDemand = (EN_API_FLOAT_TYPE)(0.0); } - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) { @@ -4575,17 +4503,17 @@ int DLLEXPORT EN_setbasedemand(EN_ProjectHandle ph, int nodeIndex, int demandIdx int n = 1; /* Check for valid arguments */ if (!pr->Openflag) - return (102); + return set_error(pr->error_handle, 102); if (nodeIndex <= 0 || nodeIndex > Nnodes) - return (203); + return set_error(pr->error_handle, 203); if (nodeIndex <= Njuncs) { for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; if (n != demandIdx) - return (253); + return set_error(pr->error_handle, 253); d->Base = baseDemand / Ucf[FLOW]; } - return 0; + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demandIdx, int *pattIdx) { @@ -4600,15 +4528,15 @@ int DLLEXPORT EN_getdemandpattern(EN_ProjectHandle ph, int nodeIndex, int demand int n = 1; /* Check for valid arguments */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (nodeIndex <= 0 || nodeIndex > Nnodes) - return (203); + return set_error(p->error_handle, 203); for (d = Node[nodeIndex].D; n < demandIdx && d != NULL; d = d->next) n++; if (n != demandIdx) - return (253); + return set_error(p->error_handle, 253); *pattIdx = d->Pat; - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *value) { @@ -4623,15 +4551,15 @@ int DLLEXPORT EN_getaveragepatternvalue(EN_ProjectHandle ph, int index, EN_API_F int i; *value = 0.0; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index < 1 || index > Npats) - return (205); + return set_error(p->error_handle, 205); // if (period < 1 || period > Pattern[index].Length) return(251); for (i = 0; i < Pattern[index].Length; i++) { *value += (EN_API_FLOAT_TYPE)Pattern[index].F[i]; } *value /= (EN_API_FLOAT_TYPE)Pattern[index].Length; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType toType) { @@ -4643,16 +4571,16 @@ int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType toType) EN_Network *net = &p->network; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); /* Check if a link with the id exists */ if (EN_getlinkindex(p, id, &i) != 0) - return (215); + return set_error(p->error_handle, 215); /* Get the current type of the link */ ENgetlinktype(i, &fromType); if (fromType == toType) - return (0); + return set_error(p->error_handle, 0); /* Change link from Pipe */ if (toType <= EN_PIPE) { @@ -4670,7 +4598,7 @@ int DLLEXPORT EN_setlinktype(EN_ProjectHandle ph, char *id, EN_LinkType toType) } else if (fromType == EN_PUMP) { net->Npumps--; } - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) { @@ -4689,13 +4617,13 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) { /* Check if a node with same id already exists */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (ENgetnodeindex(id, &i) == 0) - return (215); + return set_error(p->error_handle, 215); /* Check that id name is not too long */ if (strlen(id) > MAXID) - return (250); + return set_error(p->error_handle, 250); /* Grow arrays to accomodate the new values */ net->Node = (Snode *)realloc(net->Node, (net->Nnodes + 2) * sizeof(Snode)); @@ -4787,7 +4715,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) { /* Insert new node into hash table */ ENHashTableInsert(net->NodeHashTable, node->ID, nIdx); /* see HASH.C */ - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, char *fromNode, @@ -4804,21 +4732,21 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch /* Check if a link with same id already exists */ if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (ENgetlinkindex(id, &i) == 0) - return (215); + return set_error(p->error_handle, 215); /* Lookup the from and to nodes */ N1 = ENHashTableFind(net->NodeHashTable, fromNode); N2 = ENHashTableFind(net->NodeHashTable, toNode); if (N1 == 0 || N2 == 0) { - return (203); + return set_error(p->error_handle, 203); } /* Check that id name is not too long */ if (strlen(id) > MAXID) - return (250); + return set_error(p->error_handle, 250); net->Nlinks++; n = net->Nlinks; @@ -4900,7 +4828,7 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch } ENHashTableInsert(net->LinkHashTable, link->ID, n); - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { @@ -4913,9 +4841,9 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { Slink *link; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > net->Nlinks) - return (203); + return set_error(p->error_handle, 203); EN_getlinktype(p, index, &linkType); @@ -4962,7 +4890,7 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) { net->Nvalves--; } - return 0; + return set_error(p->error_handle, 0); } int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) { @@ -4974,9 +4902,9 @@ int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) { int i, nodeType; if (!p->Openflag) - return (102); + return set_error(p->error_handle, 102); if (index <= 0 || index > net->Nnodes) - return (203); + return set_error(p->error_handle, 203); EN_getnodetype(p, index, &nodeType); @@ -5032,7 +4960,7 @@ int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) { net->Nnodes--; - return (0); + return set_error(p->error_handle, 0); } int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nTrueActions, int *nFalseActions, EN_API_FLOAT_TYPE *priority) @@ -5056,7 +4984,7 @@ int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nT EN_Network *net = &pr->network; if (index > net->Nrules) - return (257); + return set_error(pr->error_handle, 257); *priority = (EN_API_FLOAT_TYPE)pr->rules.Rule[index].priority; count = 1; p = pr->rules.Rule[index].Pchain; @@ -5083,7 +5011,7 @@ int DLLEXPORT EN_getrule(EN_ProjectHandle ph, int index, int *nPremises, int *nT } } *nFalseActions = count; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int idxPremise, int *logop, @@ -5093,15 +5021,14 @@ int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int idxPremise, EN_API_FLOAT_TYPE priority; Premise *p; - EN_Project *pr; - pr = (EN_Project*)ph; + EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); if (idxPremise > nPremises) { - return (258); + return set_error(pr->error_handle, 258); } p = pr->rules.Rule[indexRule].Pchain; @@ -5116,7 +5043,7 @@ int DLLEXPORT EN_getpremise(EN_ProjectHandle ph, int indexRule, int idxPremise, *relop = p->relop; *status = p->status; *value = (EN_API_FLOAT_TYPE)p[0].value; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE priority) @@ -5131,11 +5058,11 @@ int DLLEXPORT EN_setrulepriority(EN_ProjectHandle ph, int index, EN_API_FLOAT_TY EN_Project *pr = (EN_Project*)ph; if (index > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } pr->rules.Rule[index].priority = priority; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise, int logop, @@ -5149,11 +5076,11 @@ int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); if (indexPremise > nPremises) { - return (258); + return set_error(pr->error_handle, 258); } p = pr->rules.Rule[indexRule].Pchain; while (count < indexPremise) { @@ -5167,7 +5094,7 @@ int DLLEXPORT EN_setpremise(EN_ProjectHandle ph, int indexRule, int indexPremise p->relop = relop; p->status = status; p->value = value; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPremise, int indexObj) { @@ -5178,10 +5105,10 @@ int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPr EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) - return (257); + return set_error(pr->error_handle, 257); error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); if (indexPremise > nPremises) { - return (258); + return set_error(pr->error_handle, 258); } p = pr->rules.Rule[indexRule].Pchain; while (count < indexPremise) { @@ -5189,7 +5116,7 @@ int DLLEXPORT EN_setpremiseindex(EN_ProjectHandle ph, int indexRule, int indexPr p = p->next; } p->index = indexObj; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexPremise, int status) { @@ -5200,11 +5127,11 @@ int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexP EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); if (indexPremise > nPremises) { - return (258); + return set_error(pr->error_handle, 258); } p = pr->rules.Rule[indexRule].Pchain; while (count < indexPremise) { @@ -5212,7 +5139,7 @@ int DLLEXPORT EN_setpremisestatus(EN_ProjectHandle ph, int indexRule, int indexP p = p->next; } p->status = status; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPremise, @@ -5224,10 +5151,10 @@ int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPr EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) - return (257); + return set_error(pr->error_handle, 257); error = EN_getrule(pr, indexRule, &nPremises, &a, &b, &priority); if (indexPremise > nPremises) { - return (258); + return set_error(pr->error_handle, 258); } p = pr->rules.Rule[indexRule].Pchain; while (count < indexPremise) { @@ -5235,7 +5162,7 @@ int DLLEXPORT EN_setpremisevalue(EN_ProjectHandle ph, int indexRule, int indexPr p = p->next; } p->value = value; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, @@ -5247,11 +5174,11 @@ int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexActi EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (252); + return set_error(pr->error_handle, 252); } error = EN_getrule(pr, indexRule, &c, &nTrueAction, &b, &priority); if (indexAction > nTrueAction) { - return (253); + return set_error(pr->error_handle, 253); } a = pr->rules.Rule[indexRule].Tchain; while (count < indexAction) { @@ -5261,7 +5188,7 @@ int DLLEXPORT EN_gettrueaction(EN_ProjectHandle ph, int indexRule, int indexActi *indexLink = a->link; *status = a->status; *setting = (EN_API_FLOAT_TYPE)a->setting; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, @@ -5273,11 +5200,11 @@ int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexActi EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } error = EN_getrule(pr, indexRule, &c, &nTrueAction, &b, &priority); if (indexAction > nTrueAction) { - return (258); + return set_error(pr->error_handle, 258); } a = pr->rules.Rule[indexRule].Tchain; while (count < indexAction) { @@ -5287,7 +5214,7 @@ int DLLEXPORT EN_settrueaction(EN_ProjectHandle ph, int indexRule, int indexActi a->link = indexLink; a->status = status; a->setting = setting; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int *indexLink, @@ -5299,11 +5226,11 @@ int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } error = EN_getrule(pr, indexRule, &c, &b, &nFalseAction, &priority); if (indexAction > nFalseAction) { - return (258); + return set_error(pr->error_handle, 258); } a = pr->rules.Rule[indexRule].Fchain; while (count < indexAction) { @@ -5313,7 +5240,7 @@ int DLLEXPORT EN_getfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct *indexLink = a->link; *status = a->status; *setting = (EN_API_FLOAT_TYPE)a->setting; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAction, int indexLink, @@ -5325,11 +5252,11 @@ int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct EN_Project *pr = (EN_Project*)ph; if (indexRule > pr->network.Nrules) { - return (257); + return set_error(pr->error_handle, 257); } error = EN_getrule(pr, indexRule, &c, &b, &nFalseAction, &priority); if (indexAction > nFalseAction) { - return (258); + return set_error(pr->error_handle, 258); } a = pr->rules.Rule[indexRule].Fchain; while (count < indexAction) { @@ -5340,7 +5267,7 @@ int DLLEXPORT EN_setfalseaction(EN_ProjectHandle ph, int indexRule, int indexAct a->status = status; a->setting = setting; - return (0); + return set_error(pr->error_handle, 0); } int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char *id) { @@ -5349,11 +5276,11 @@ int DLLEXPORT EN_getruleID(EN_ProjectHandle ph, int indexRule, char *id) { strcpy(id, ""); if (!pr->Openflag) - return (102); + return set_error(pr->error_handle, 102); if (indexRule < 1 || indexRule > pr->network.Nrules) - return (257); + return set_error(pr->error_handle, 257); strcpy(id, pr->rules.Rule[indexRule].label); - return (0); + return set_error(pr->error_handle, 0); } /*************************** END OF EPANET.C ***************************/