Merging latest from dev, trying to get import lib generated

This commit is contained in:
Michael Tryby
2018-07-03 17:38:40 -04:00
73 changed files with 3622 additions and 16583 deletions

View File

@@ -7,3 +7,7 @@ Yunier Soad <yunier.soad@gmail.com>
Jinduan Chen <jinduan.uc@gmail.com> Jinduan Chen <jinduan.uc@gmail.com>
Maurizio Cingi <mrzcng2@gmail.com> Maurizio Cingi <mrzcng2@gmail.com>
Elad Salomons <selad@optiwater.com> <elad.salomons@gmail.com> Elad Salomons <selad@optiwater.com> <elad.salomons@gmail.com>
Angela Marchi <angela.marchi@adelaide.edu.au>
Angela Marchi <angela.marchi@adelaide.edu.au> <a1219261@adelaide.edu.au>
Bryant McDonnell <bemcdonnell@gmail.com>
Marios Kyriakou <mariosmsk@gmail.com>

View File

@@ -3,23 +3,28 @@ language: python
env: env:
global: global:
- EPANET_HOME=`pwd` - EPANET_HOME=`pwd`
- BUILD_HOME=buildproducts - BUILD_HOME=buildprod
- TEST_HOME=tests/epanet-nrtestsuite - TEST_HOME=nrtestsuite
before_install: before_install:
- sudo apt-get -qq update - sudo apt-get -qq update
- sudo apt-get install -y libboost-test-dev
- sudo apt-get install -y swig - sudo apt-get install -y swig
install: #install:
- pip install --src build/packages -r tools/requirements.txt
before_script: before_script:
- mkdir -p $BUILD_HOME - mkdir -p $BUILD_HOME
- cd $BUILD_HOME - cd $BUILD_HOME
- cmake .. - cmake -DBUILD_TESTS=1 ..
script: script:
- make - cmake --build .
# run unit tests
- cd tests
- ctest
# run regression tests
- cd $EPANET_HOME - cd $EPANET_HOME
- tools/gen-config.sh $EPANET_HOME/$BUILD_HOME/bin > $TEST_HOME/apps/epanet-$TRAVIS_COMMIT.json - pip install -r tools/requirements.txt
- tools/before-test.sh $TEST_HOME $EPANET_HOME/$BUILD_HOME/bin $TRAVIS_COMMIT
- tools/run-nrtest.sh $TEST_HOME $TRAVIS_COMMIT - tools/run-nrtest.sh $TEST_HOME $TRAVIS_COMMIT

View File

@@ -1,8 +1,9 @@
# Authors ordered by first contribution. # Authors ordered by first contribution.
# Generated by tools/update-authors.sh # Generated by tools/update-authors.sh
# and modified to reflect works in the public domain (denoted by ***)
Lew Rossman <LRossman@cinci.rr.com> Lew Rossman <LRossman@cinci.rr.com> ***
Michael Tryby <tryby.michael@epa.gov> Michael Tryby <tryby.michael@epa.gov> ***
Sam Hatchett <samhatchett@gmail.com> Sam Hatchett <samhatchett@gmail.com>
Feng Shang <fshang> Feng Shang <fshang>
James Uber <jim@citilogics.com> James Uber <jim@citilogics.com>
@@ -14,7 +15,8 @@ Mike Kane <muke195@gmail.com>
Demetrios Eliades <eldemet@gmail.com> Demetrios Eliades <eldemet@gmail.com>
Will Furnass <will@thearete.co.uk> Will Furnass <will@thearete.co.uk>
Steffen Macke <sdteffen@sdteffen.de> Steffen Macke <sdteffen@sdteffen.de>
Mariosmsk <mariosmsk@gmail.com> Marios Kyriakou <mariosmsk@gmail.com>
Elad Salomons <selad@optiwater.com> Elad Salomons <selad@optiwater.com>
Maurizio Cingi <mrzcng2@gmail.com> Maurizio Cingi <mrzcng2@gmail.com>
Bryant McDonnell <bemcdonnell@gmail.com> Bryant McDonnell <bemcdonnell@gmail.com>
Angela Marchi <angela.marchi@adelaide.edu.au>

View File

@@ -10,7 +10,6 @@
# properly installed. Build using Visual Studio requires msbuild shell. # properly installed. Build using Visual Studio requires msbuild shell.
# #
# Example Usage: # Example Usage:
# cd build/cmake
# mkdir buildproducts # mkdir buildproducts
# cd buildproducts # cd buildproducts
# cmake .. # cmake ..
@@ -29,7 +28,7 @@
# Generic Invocation: # Generic Invocation:
# cmake -E make_directory buildprod # cmake -E make_directory buildprod
# cd build # cd build
# cmake -G GENERATOR -DCMAKE_BUILD_TYPE=Release .. # cmake -G GENERATOR -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=1 ..
# cmake --build . --target SOME_TARGET --config Release # cmake --build . --target SOME_TARGET --config Release
# #
# More information: # More information:
@@ -41,14 +40,25 @@
cmake_minimum_required (VERSION 2.8.8) cmake_minimum_required (VERSION 2.8.8)
project(EPANET) project(EPANET)
add_subdirectory(run)
add_subdirectory(tools/epanet-output)
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) IF (BUILD_TESTS)
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) add_subdirectory(tests)
ENDIF (BUILD_TESTS)
# Sets for output directory for executables and libraries.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# Sets the position independent code property for all targets
SET(CMAKE_POSITION_INDEPENDENT_CODE ON) SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
IF (APPLE) IF (APPLE)
SET(CMAKE_INSTALL_NAME_DIR @executable_path) SET(INSTALL_NAME_DIR @executable_path/../lib)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH ON) SET(CMAKE_MACOSX_RPATH 1)
ENDIF (APPLE) ENDIF (APPLE)
IF (MSVC) IF (MSVC)
@@ -56,31 +66,28 @@ IF (MSVC)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF (MSVC) ENDIF (MSVC)
include_directories(include src tools/epanet-output/src)
# configure file groups # configure file groups
file(GLOB EPANET_SOURCES src/*.c) 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("Library" FILES ${EPANET_LIB_ALL})
source_group("CLI" REGULAR_EXPRESSION "run/.*") source_group("CLI" REGULAR_EXPRESSION "run/.*")
source_group("Output" FILES ${EPANET_OUT_SOURCES})
# the shared library # the shared library
add_library(epanet SHARED ${EPANET_SOURCES} ${EPANET_API_HEADER}) add_library(epanet SHARED ${EPANET_SOURCES}) #${EPANET_API_HEADER})
target_include_directories(epanet PUBLIC ${PROJECT_SOURCE_DIR}/include)
# the standalone executable
add_executable(runepanet ${EPANET_CLI_SOURCES})
if(NOT MSVC) # create export lib so we can link against dll using Visual Studio
target_link_libraries(runepanet LINK_PUBLIC epanet m) include(GenerateExportHeader)
else(NOT MSVC) GENERATE_EXPORT_HEADER(epanet
target_link_libraries(runepanet LINK_PUBLIC epanet) BASE_NAME epanet
endif(NOT MSVC) EXPORT_MACRO_NAME DLLEXPORT
EXPORT_FILE_NAME epanet_export.h
STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC)
# the binary hydraulics file API file(COPY ${CMAKE_CURRENT_BINARY_DIR}/epanet_export.h
add_library(epanet-output SHARED ${EPANET_OUT_SOURCES} ${EPANET_OUT_HEADERS}) DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/include)

26
LICENSE Normal file
View File

@@ -0,0 +1,26 @@
MIT License
<<<<<<< HEAD
Works are copyright (c) 2018 their respective AUTHORS,
unless such work is in the Public Domain (again, see AUTHORS)
=======
Copyright (c) 2017 Open Water Analytics
>>>>>>> master
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -5,9 +5,11 @@ EPANET {#epanet-readme}
[![Build status](https://ci.appveyor.com/api/projects/status/19wpg4g2cmj3oihl?svg=true)](https://ci.appveyor.com/project/OpenWaterAnalytics/epanet) [![Build status](https://ci.appveyor.com/api/projects/status/19wpg4g2cmj3oihl?svg=true)](https://ci.appveyor.com/project/OpenWaterAnalytics/epanet)
[![Build Status](https://travis-ci.org/OpenWaterAnalytics/EPANET.svg?branch=master)](https://travis-ci.org/OpenWaterAnalytics/EPANET) [![Build Status](https://travis-ci.org/OpenWaterAnalytics/EPANET.svg?branch=master)](https://travis-ci.org/OpenWaterAnalytics/EPANET)
The EPANET Library is a pressurized pipe network hydraulic and water quality analysis toolkit written in C. ## For EPANET-related questions and discussion
For community discussion, FAQ, and roadmapping of the project, go to the [Community Forum](http://community.wateranalytics.org/category/epanet).
If you are interested in using/extending EPANET for academic, personal, or commercial use, then you've come to the right place. For community discussion, FAQ, and roadmapping of the project, go to the [Community Forum](http://community.wateranalytics.org/category/epanet). ## What is on this Repository?
The EPANET Library is a pressurized pipe network hydraulic and water quality analysis toolkit written in C. If you are interested in using/extending EPANET for academic, personal, or commercial use, then you've come to the right place.
Please see the [`version 2.1` Release Notes](https://github.com/OpenWaterAnalytics/EPANET/blob/master/ReleaseNotes2_1.md) for information relevant to users of the previous official version (2.00.12). If you would like to contribute by addressing any of the outstanding [Issues](https://github.com/OpenWaterAnalytics/EPANET/issues), then please comment on the Issue, then Fork this repo to your own account and base your commits on the [`dev` branch](https://github.com/OpenWaterAnalytics/EPANET/tree/dev). Once you are finished, you can open a Pull Request to test the code and discuss merging your changes back into the community respository. Please see the [`version 2.1` Release Notes](https://github.com/OpenWaterAnalytics/EPANET/blob/master/ReleaseNotes2_1.md) for information relevant to users of the previous official version (2.00.12). If you would like to contribute by addressing any of the outstanding [Issues](https://github.com/OpenWaterAnalytics/EPANET/issues), then please comment on the Issue, then Fork this repo to your own account and base your commits on the [`dev` branch](https://github.com/OpenWaterAnalytics/EPANET/tree/dev). Once you are finished, you can open a Pull Request to test the code and discuss merging your changes back into the community respository.

View File

@@ -9,40 +9,62 @@
version: 2.0.{build} version: 2.0.{build}
image: matrix:
- Visual Studio 2013 allow_failures:
#GROUP: (SUPPORTED/EXPERIMENTAL)
#EXPERIMENTAL is allowed to fail under build matrix
- GROUP: "EXPERIMENTAL"
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
GENERATOR: "Visual Studio 10 2010"
GROUP: "SUPPORTED"
BOOST_ROOT: "C:/Libraries/boost"
# New build on Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
GENERATOR: "Visual Studio 15 2017"
GROUP: "EXPERIMENTAL"
BOOST_ROOT: "C:/Libraries/boost_1_67_0"
# called before repo cloning # called before repo cloning
init: init:
- set EPANET_HOME=%APPVEYOR_BUILD_FOLDER% - set EPANET_HOME=%APPVEYOR_BUILD_FOLDER%
- set BUILD_HOME=buildprod - set BUILD_HOME=buildprod
- set TEST_HOME=tests\epanet-nrtestsuite - set TEST_HOME=nrtestsuite
- set NRTEST_SCRIPT=%EPANET_HOME%\%BUILD_HOME%\packages\nrtest\scripts - set NRTEST_SCRIPT=C:\Python27\Scripts
- set GENERATOR="Visual Studio 10 2010" # See values set
- echo %APPVEYOR_BUILD_WORKER_IMAGE%
cache: - echo %BUILD_HOME%
- C:\ProgramData\chocolatey\bin -> appveyor.yml - echo %GENERATOR%
- C:\ProgramData\chocolatey\lib -> appveyor.yml - echo %BOOST_ROOT%
- '%BUILD_HOME% -> CMakeLists.txt'
# called after repo clone # called after repo clone
install: install:
- choco install swig - python -m pip install -r tools\requirements-appveyor.txt
- python -m pip install --src %BUILD_HOME%\packages -r tools\requirements.txt
# called before build # called before build
before_build: before_build:
- mkdir %BUILD_HOME%
- cd %BUILD_HOME% - cd %BUILD_HOME%
- cmake -G %GENERATOR% -DCMAKE_BUILD_TYPE=Release .. - cmake -G "%GENERATOR%"
-DBUILD_TESTS=1
-DBOOST_ROOT="%BOOST_ROOT%"
-DBoost_USE_STATIC_LIBS="ON" ..
# run custom build script # run custom build script
build_script: build_script:
- cmake --build . --target runepanet --config Release - cmake --build . --config Release
before_test: before_test:
- cd %EPANET_HOME% - cd %EPANET_HOME%
- tools\gen-config.cmd %EPANET_HOME%\%BUILD_HOME%\bin\Release > %TEST_HOME%\apps\epanet-%APPVEYOR_REPO_COMMIT%.json - tools\before-test.cmd %TEST_HOME% %EPANET_HOME%\%BUILD_HOME%\bin\Release %APPVEYOR_REPO_COMMIT%
# run custom test script # run custom test script
test_script: test_script:
# run unit tests
- cd %BUILD_HOME%\tests
- ctest -C Release
# run regression tests
- cd %EPANET_HOME%
- tools\run-nrtest.cmd %NRTEST_SCRIPT% %TEST_HOME% %APPVEYOR_REPO_COMMIT% - tools\run-nrtest.cmd %NRTEST_SCRIPT% %TEST_HOME% %APPVEYOR_REPO_COMMIT%

View File

@@ -128,6 +128,8 @@ Public Const EN_ACCURACY = 1
Public Const EN_TOLERANCE = 2 Public Const EN_TOLERANCE = 2
Public Const EN_EMITEXPON = 3 Public Const EN_EMITEXPON = 3
Public Const EN_DEMANDMULT = 4 Public Const EN_DEMANDMULT = 4
Public Const EN_HEADERROR = 5
Public Const EN_FLOWCHANGE = 6
Public Const EN_LOWLEVEL = 0 ' Control types Public Const EN_LOWLEVEL = 0 ' Control types
Public Const EN_HILEVEL = 1 Public Const EN_HILEVEL = 1

View File

@@ -30,36 +30,37 @@
#define EN_API_FLOAT_TYPE float #define EN_API_FLOAT_TYPE float
#endif #endif
// --- define WINDOWS // // --- define WINDOWS
#undef WINDOWS // #undef WINDOWS
#ifdef _WIN32 // #ifdef _WIN32
#define WINDOWS // #define WINDOWS
#endif // #endif
#ifdef __WIN32__ // #ifdef __WIN32__
#define WINDOWS // #define WINDOWS
#endif // #endif
// --- define DLLEXPORT // // --- define DLLEXPORT
#ifndef DLLEXPORT // #ifndef DLLEXPORT
#ifdef WINDOWS // #ifdef WINDOWS
#ifdef __cplusplus // #ifdef __cplusplus
#define DLLEXPORT __declspec(dllexport) // #define DLLEXPORT __declspec(dllexport)
#else // #else
#define DLLEXPORT __declspec(dllexport) __stdcall // #define DLLEXPORT __declspec(dllexport) __stdcall
#endif // __cplusplus // #endif // __cplusplus
#elif defined(CYGWIN) // #elif defined(CYGWIN)
#define DLLEXPORT __stdcall // #define DLLEXPORT __stdcall
#elif defined(__APPLE__) // #elif defined(__APPLE__)
#ifdef __cplusplus // #ifdef __cplusplus
#define DLLEXPORT // #define DLLEXPORT
#else // #else
#define DLLEXPORT // #define DLLEXPORT
#endif // #endif
#else // #else
#define DLLEXPORT // #define DLLEXPORT
#endif // #endif
#endif // #endif
#include "epanet_export.h"
// --- Define the EPANET toolkit constants // --- Define the EPANET toolkit constants
@@ -211,7 +212,9 @@ typedef enum {
EN_ACCURACY = 1, EN_ACCURACY = 1,
EN_TOLERANCE = 2, EN_TOLERANCE = 2,
EN_EMITEXPON = 3, EN_EMITEXPON = 3,
EN_DEMANDMULT = 4 EN_DEMANDMULT = 4,
EN_HEADERROR = 5,
EN_FLOWCHANGE = 6
} EN_Option; } EN_Option;
typedef enum { typedef enum {

View File

@@ -121,6 +121,8 @@ Public Const EN_ACCURACY = 1
Public Const EN_TOLERANCE = 2 Public Const EN_TOLERANCE = 2
Public Const EN_EMITEXPON = 3 Public Const EN_EMITEXPON = 3
Public Const EN_DEMANDMULT = 4 Public Const EN_DEMANDMULT = 4
Public Const EN_HEADERROR = 5
Public Const EN_FLOWCHANGE = 6
Public Const EN_LOWLEVEL = 0 ' Control types Public Const EN_LOWLEVEL = 0 ' Control types
Public Const EN_HILEVEL = 1 Public Const EN_HILEVEL = 1

27
run/CMakeLists.txt Normal file
View File

@@ -0,0 +1,27 @@
# EPANET COMMAND LINE EXECUTABLE
cmake_minimum_required (VERSION 3.0.2)
# Sets for output directory for executables and libraries.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# Sets the position independent code property for all targets.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Set up file groups for exe target
set(EPANET_CLI_SOURCES main.c)
include_directories(include)
source_group("CLI" FILES ${EPANET_CLI_SOURCES})
# Creates the EPANET command line executable
add_executable(runepanet ${EPANET_CLI_SOURCES})
if(NOT WIN32)
target_link_libraries(runepanet LINK_PUBLIC epanet m)
else(NOT WIN32)
target_link_libraries(runepanet LINK_PUBLIC epanet)
endif(NOT WIN32)

View File

@@ -5,9 +5,9 @@
#define MAXMSG 255 /* Max. # characters in message text */ #define MAXMSG 255 /* Max. # characters in message text */
#define MAXWARNCODE 99 #define MAXWARNCODE 99
/* text copied here, no more need of include "text.h" */ /* text copied here, no more need of include "text.h" */
#define FMT01 "\nEPANET Version %d.%d.%d\n" #define FMT01 "\nEPANET Version %d.%d.%d"
#define FMT03 "\n Correct syntax is:\n %s <input file> <output file>\n" #define FMT03 "\n Correct syntax is:\n %s <input file> <output file>\n"
#define FMT09 "\nEPANET completed.\n" #define FMT09 "\n\nEPANET completed."
#define FMT10 "\nEPANET completed. There are warnings." #define FMT10 "\nEPANET completed. There are warnings."
#define FMT11 "\nEPANET completed. There are errors." #define FMT11 "\nEPANET completed. There are errors."
@@ -87,7 +87,8 @@ int main(int argc, char *argv[])
/* Call the main control function */ /* Call the main control function */
if (strlen(f2)> 0) { if (strlen(f2)> 0) {
/* use stdout for progress messages */ /* use stdout for progress messages */
errcode = ENepanet(f1,f2,f3,writeConsole); //errcode = ENepanet(f1,f2,f3,writeConsole);
errcode = ENepanet(f1, f2, f3, NULL);
} }
else { else {
/* use stdout for reporting, no progress messages */ /* use stdout for reporting, no progress messages */
@@ -101,21 +102,21 @@ int main(int argc, char *argv[])
return(0); return(0);
} }
else { else {
if (errcode > MAXWARNCODE) printf("\n Fatal Error: ");
ENgeterror(errcode, errmsg, MAXMSG); ENgeterror(errcode, errmsg, MAXMSG);
writeConsole(errmsg); writeConsole(errmsg);
if (errcode > MAXWARNCODE) { if (errcode > MAXWARNCODE) {
/* error */ // error //
writeConsole(FMT11); writeConsole(FMT11);
return(errcode); return(errcode);
} }
else { else {
/* warning */ // warning //
writeConsole(FMT10); writeConsole(FMT10);
return(0); return(0);
} }
} }
} /* End of main */ } /* End of main */

View File

@@ -71,11 +71,12 @@ This module calls the following functions that reside in other modules:
runhyd() runhyd()
nexthyd() nexthyd()
closehyd() closehyd()
resistance()
tankvolume() tankvolume()
getenergy() getenergy()
setlinkstatus() setlinkstatus()
setlinksetting() setlinksetting()
HYDCOEFFS
resistcoeff()
QUALITY.C QUALITY.C
openqual() openqual()
initqual() initqual()
@@ -108,6 +109,10 @@ execute function x and set the error code equal to its return value.
#ifdef __WIN32__ #ifdef __WIN32__
#define WINDOWS #define WINDOWS
#endif #endif
#ifdef WINDOWS
#include <windows.h>
#endif
/************************************************************/ /************************************************************/
#include <stdio.h> #include <stdio.h>
@@ -125,7 +130,7 @@ execute function x and set the error code equal to its return value.
#include "text.h" #include "text.h"
#include "types.h" #include "types.h"
#define EXTERN #define EXTERN
#include "epanet2.h" ////////////////////////////////////////////#include "epanet2.h"
#include "vars.h" #include "vars.h"
/**************************************************************** /****************************************************************
@@ -186,208 +191,282 @@ int DLLEXPORT ENsaveinpfile(char *filename) {
} }
int DLLEXPORT ENclose() { return EN_close(_defaultModel); } int DLLEXPORT ENclose() { return EN_close(_defaultModel); }
int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); } int DLLEXPORT ENsolveH() { return EN_solveH(_defaultModel); }
int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); } int DLLEXPORT ENsaveH() { return EN_saveH(_defaultModel); }
int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); } int DLLEXPORT ENopenH() { return EN_openH(_defaultModel); }
int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); } int DLLEXPORT ENinitH(int flag) { return EN_initH(_defaultModel, flag); }
int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); } int DLLEXPORT ENrunH(long *t) { return EN_runH(_defaultModel, t); }
int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); } int DLLEXPORT ENnextH(long *tstep) { return EN_nextH(_defaultModel, tstep); }
int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); } int DLLEXPORT ENcloseH() { return EN_closeH(_defaultModel); }
int DLLEXPORT ENsavehydfile(char *filename) { int DLLEXPORT ENsavehydfile(char *filename) {
return EN_savehydfile(_defaultModel, filename); return EN_savehydfile(_defaultModel, filename);
} }
int DLLEXPORT ENusehydfile(char *filename) { int DLLEXPORT ENusehydfile(char *filename) {
return EN_usehydfile(_defaultModel, filename); return EN_usehydfile(_defaultModel, filename);
} }
int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); } int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultModel); }
int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); } int DLLEXPORT ENopenQ() { return EN_openQ(_defaultModel); }
int DLLEXPORT ENinitQ(int saveflag) { int DLLEXPORT ENinitQ(int saveflag) {
return EN_initQ(_defaultModel, saveflag); return EN_initQ(_defaultModel, saveflag);
} }
int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); } int DLLEXPORT ENrunQ(long *t) { return EN_runQ(_defaultModel, t); }
int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); } int DLLEXPORT ENnextQ(long *tstep) { return EN_nextQ(_defaultModel, tstep); }
int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); } int DLLEXPORT ENstepQ(long *tleft) { return EN_stepQ(_defaultModel, tleft); }
int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); } int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultModel); }
int DLLEXPORT ENwriteline(char *line) { int DLLEXPORT ENwriteline(char *line) {
return EN_writeline(_defaultModel, line); return EN_writeline(_defaultModel, line);
} }
int DLLEXPORT ENreport() { return EN_report(_defaultModel); } int DLLEXPORT ENreport() { return EN_report(_defaultModel); }
int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); } int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultModel); }
int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); } int DLLEXPORT ENsetreport(char *s) { return EN_setreport(_defaultModel, s); }
int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); } int DLLEXPORT ENgetversion(int *v) { return EN_getversion(v); }
int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex,
EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *setting, int *nindex,
EN_API_FLOAT_TYPE *level) { EN_API_FLOAT_TYPE *level) {
return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, return EN_getcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex,
level); level);
} }
int DLLEXPORT ENgetcount(int code, int *count) { int DLLEXPORT ENgetcount(int code, int *count) {
return EN_getcount(_defaultModel, (EN_CountType)code, count); return EN_getcount(_defaultModel, (EN_CountType)code, count);
} }
int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) { int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) {
return EN_getoption(_defaultModel, (EN_Option)code, value); return EN_getoption(_defaultModel, (EN_Option)code, value);
} }
int DLLEXPORT ENgettimeparam(int code, long *value) { int DLLEXPORT ENgettimeparam(int code, long *value) {
return EN_gettimeparam(_defaultModel, code, value); return EN_gettimeparam(_defaultModel, code, value);
} }
int DLLEXPORT ENgetflowunits(int *code) { int DLLEXPORT ENgetflowunits(int *code) {
return EN_getflowunits(_defaultModel, code); return EN_getflowunits(_defaultModel, code);
} }
int DLLEXPORT ENsetflowunits(int code) { int DLLEXPORT ENsetflowunits(int code) {
return EN_setflowunits(_defaultModel, code); return EN_setflowunits(_defaultModel, code);
} }
int DLLEXPORT ENgetpatternindex(char *id, int *index) { int DLLEXPORT ENgetpatternindex(char *id, int *index) {
return EN_getpatternindex(_defaultModel, id, index); return EN_getpatternindex(_defaultModel, id, index);
} }
int DLLEXPORT ENgetpatternid(int index, char *id) { int DLLEXPORT ENgetpatternid(int index, char *id) {
return EN_getpatternid(_defaultModel, index, id); return EN_getpatternid(_defaultModel, index, id);
} }
int DLLEXPORT ENgetpatternlen(int index, int *len) { int DLLEXPORT ENgetpatternlen(int index, int *len) {
return EN_getpatternlen(_defaultModel, index, len); return EN_getpatternlen(_defaultModel, index, len);
} }
int DLLEXPORT ENgetpatternvalue(int index, int period, int DLLEXPORT ENgetpatternvalue(int index, int period,
EN_API_FLOAT_TYPE *value) { EN_API_FLOAT_TYPE *value) {
return EN_getpatternvalue(_defaultModel, index, period, value); return EN_getpatternvalue(_defaultModel, index, period, value);
} }
int DLLEXPORT ENgetcurveindex(char *id, int *index) { int DLLEXPORT ENgetcurveindex(char *id, int *index) {
return EN_getcurveindex(_defaultModel, id, index); return EN_getcurveindex(_defaultModel, id, index);
} }
int DLLEXPORT ENgetcurveid(int index, char *id) { int DLLEXPORT ENgetcurveid(int index, char *id) {
return EN_getcurveid(_defaultModel, index, id); return EN_getcurveid(_defaultModel, index, id);
} }
int DLLEXPORT ENgetcurvelen(int index, int *len) { int DLLEXPORT ENgetcurvelen(int index, int *len) {
return EN_getcurvelen(_defaultModel, index, len); return EN_getcurvelen(_defaultModel, index, len);
} }
int DLLEXPORT ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x, int DLLEXPORT ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y) { EN_API_FLOAT_TYPE *y) {
return EN_getcurvevalue(_defaultModel, index, pnt, x, y); return EN_getcurvevalue(_defaultModel, index, pnt, x, y);
} }
int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode) { int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode) {
return EN_getqualtype(_defaultModel, qualcode, tracenode); return EN_getqualtype(_defaultModel, qualcode, tracenode);
} }
int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits,
int *tracenode) { int *tracenode) {
return EN_getqualinfo(_defaultModel, qualcode, chemname, chemunits, return EN_getqualinfo(_defaultModel, qualcode, chemname, chemunits,
tracenode); tracenode);
} }
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) { int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) {
return EN_geterror(errcode, errmsg, n); return EN_geterror(errcode, errmsg, n);
} }
int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) { int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE *value) {
return EN_getstatistic(_defaultModel, code, value); return EN_getstatistic(_defaultModel, code, value);
} }
int DLLEXPORT ENgetnodeindex(char *id, int *index) { int DLLEXPORT ENgetnodeindex(char *id, int *index) {
return EN_getnodeindex(_defaultModel, id, index); return EN_getnodeindex(_defaultModel, id, index);
} }
int DLLEXPORT ENgetnodeid(int index, char *id) { int DLLEXPORT ENgetnodeid(int index, char *id) {
return EN_getnodeid(_defaultModel, index, id); return EN_getnodeid(_defaultModel, index, id);
} }
int DLLEXPORT ENgetnodetype(int index, int *code) { int DLLEXPORT ENgetnodetype(int index, int *code) {
return EN_getnodetype(_defaultModel, index, code); return EN_getnodetype(_defaultModel, index, code);
} }
int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x,
EN_API_FLOAT_TYPE *y) { EN_API_FLOAT_TYPE *y) {
return EN_getcoord(_defaultModel, index, x, y); return EN_getcoord(_defaultModel, index, x, y);
} }
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) {
return EN_setcoord(_defaultModel, index, x, y); return EN_setcoord(_defaultModel, index, x, y);
} }
int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) { int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) {
return EN_getnodevalue(_defaultModel, index, code, value); return EN_getnodevalue(_defaultModel, index, code, value);
} }
int DLLEXPORT ENgetlinkindex(char *id, int *index) { int DLLEXPORT ENgetlinkindex(char *id, int *index) {
return EN_getlinkindex(_defaultModel, id, index); return EN_getlinkindex(_defaultModel, id, index);
} }
int DLLEXPORT ENgetlinkid(int index, char *id) { int DLLEXPORT ENgetlinkid(int index, char *id) {
return EN_getlinkid(_defaultModel, index, id); return EN_getlinkid(_defaultModel, index, id);
} }
int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) { int DLLEXPORT ENgetlinktype(int index, EN_LinkType *code) {
return EN_getlinktype(_defaultModel, index, code); return EN_getlinktype(_defaultModel, index, code);
} }
int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) { int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) {
return EN_getlinknodes(_defaultModel, index, node1, node2); return EN_getlinknodes(_defaultModel, index, node1, node2);
} }
int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) { int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) {
return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value); return EN_getlinkvalue(_defaultModel, index, (EN_LinkProperty)code, value);
} }
int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues, int DLLEXPORT ENgetcurve(int curveIndex, char *id, int *nValues,
EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **xValues,
EN_API_FLOAT_TYPE **yValues) { EN_API_FLOAT_TYPE **yValues) {
return EN_getcurve(_defaultModel, curveIndex, id, nValues, xValues, yValues); return EN_getcurve(_defaultModel, curveIndex, id, nValues, xValues, yValues);
} }
int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex,
EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE setting, int nindex,
EN_API_FLOAT_TYPE level) { EN_API_FLOAT_TYPE level) {
return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex, return EN_setcontrol(_defaultModel, cindex, ctype, lindex, setting, nindex,
level); level);
} }
int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) { int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) {
return EN_setnodevalue(_defaultModel, index, code, v); return EN_setnodevalue(_defaultModel, index, code, v);
} }
int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) { int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) {
return EN_setlinkvalue(_defaultModel, index, code, v); return EN_setlinkvalue(_defaultModel, index, code, v);
} }
int DLLEXPORT ENaddpattern(char *id) { int DLLEXPORT ENaddpattern(char *id) {
return EN_addpattern(_defaultModel, id); return EN_addpattern(_defaultModel, id);
} }
int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) { int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) {
return EN_setpattern(_defaultModel, index, f, n); return EN_setpattern(_defaultModel, index, f, n);
} }
int DLLEXPORT ENsetpatternvalue(int index, int period, int DLLEXPORT ENsetpatternvalue(int index, int period,
EN_API_FLOAT_TYPE value) { EN_API_FLOAT_TYPE value) {
return EN_setpatternvalue(_defaultModel, index, period, value); return EN_setpatternvalue(_defaultModel, index, period, value);
} }
int DLLEXPORT ENaddcurve(char *id) { return EN_addcurve(_defaultModel, id); } int DLLEXPORT ENaddcurve(char *id) { return EN_addcurve(_defaultModel, id); }
int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y,
int n) { int n) {
return EN_setcurve(_defaultModel, index, x, y, n); return EN_setcurve(_defaultModel, index, x, y, n);
} }
int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, int DLLEXPORT ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x,
EN_API_FLOAT_TYPE y) { EN_API_FLOAT_TYPE y) {
return EN_setcurvevalue(_defaultModel, index, pnt, x, y); return EN_setcurvevalue(_defaultModel, index, pnt, x, y);
} }
int DLLEXPORT ENsettimeparam(int code, long value) { int DLLEXPORT ENsettimeparam(int code, long value) {
return EN_settimeparam(_defaultModel, code, value); return EN_settimeparam(_defaultModel, code, value);
} }
int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) { int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) {
return EN_setoption(_defaultModel, code, v); return EN_setoption(_defaultModel, code, v);
} }
int DLLEXPORT ENsetstatusreport(int code) { int DLLEXPORT ENsetstatusreport(int code) {
return EN_setstatusreport(_defaultModel, code); return EN_setstatusreport(_defaultModel, code);
} }
int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits,
char *tracenode) { char *tracenode) {
return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits, return EN_setqualtype(_defaultModel, qualcode, chemname, chemunits,
tracenode); tracenode);
} }
int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex) { int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex) {
return EN_getheadcurveindex(_defaultModel, index, curveindex); return EN_getheadcurveindex(_defaultModel, index, curveindex);
} }
int DLLEXPORT ENsetheadcurveindex(int index, int curveindex) { int DLLEXPORT ENsetheadcurveindex(int index, int curveindex) {
return EN_setheadcurveindex(_defaultModel, index, curveindex); return EN_setheadcurveindex(_defaultModel, index, curveindex);
} }
int DLLEXPORT ENgetpumptype(int index, int *type) { int DLLEXPORT ENgetpumptype(int index, int *type) {
return EN_getpumptype(_defaultModel, index, type); return EN_getpumptype(_defaultModel, index, type);
} }
int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands) { int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands) {
return EN_getnumdemands(_defaultModel, nodeIndex, numDemands); return EN_getnumdemands(_defaultModel, nodeIndex, numDemands);
} }
int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx,
EN_API_FLOAT_TYPE *baseDemand) { EN_API_FLOAT_TYPE *baseDemand) {
return EN_getbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand); return EN_getbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand);
} }
int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx,
EN_API_FLOAT_TYPE baseDemand) { EN_API_FLOAT_TYPE baseDemand) {
return EN_setbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand); return EN_setbasedemand(_defaultModel, nodeIndex, demandIdx, baseDemand);
} }
int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) { int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) {
return EN_getdemandpattern(_defaultModel, nodeIndex, demandIdx, pattIdx); return EN_getdemandpattern(_defaultModel, nodeIndex, demandIdx, pattIdx);
} }
int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value) { int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value) {
return EN_getaveragepatternvalue(_defaultModel, index, value); return EN_getaveragepatternvalue(_defaultModel, index, value);
} }
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) {
return EN_getrule(_defaultModel, index, nPremises, nTrueActions, nFalseActions, priority); return EN_getrule(_defaultModel, index, nPremises, nTrueActions, nFalseActions, priority);
} }
@@ -415,19 +494,23 @@ int DLLEXPORT ENsetpremisevalue(int indexRule, int indexPremise, EN_API_FLOAT_TY
return EN_setpremisevalue(_defaultModel, indexRule, indexPremise, value); return EN_setpremisevalue(_defaultModel, indexRule, indexPremise, value);
} }
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){
return EN_gettrueaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); return EN_gettrueaction(_defaultModel, indexRule, indexAction, indexLink, status, setting);
} }
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){
return EN_settrueaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); return EN_settrueaction(_defaultModel, indexRule, indexAction, indexLink, status, setting);
} }
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){
return EN_getfalseaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); return EN_getfalseaction(_defaultModel, indexRule, indexAction, indexLink, status, setting);
} }
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){
return EN_setfalseaction(_defaultModel, indexRule, indexAction, indexLink, status, setting); return EN_setfalseaction(_defaultModel, indexRule, indexAction, indexLink, status, setting);
} }
@@ -438,16 +521,20 @@ int DLLEXPORT ENgetruleID(int indexRule, char* id){
int DLLEXPORT ENsetlinktype(char *id, EN_LinkType toType) { int DLLEXPORT ENsetlinktype(char *id, EN_LinkType toType) {
return EN_setlinktype(_defaultModel, id, toType); return EN_setlinktype(_defaultModel, id, toType);
} }
int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType) { int DLLEXPORT ENaddnode(char *id, EN_NodeType nodeType) {
return EN_addnode(_defaultModel, id, nodeType); return EN_addnode(_defaultModel, id, nodeType);
} }
int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode, int DLLEXPORT ENaddlink(char *id, EN_LinkType linkType, char *fromNode,
char *toNode) { char *toNode) {
return EN_addlink(_defaultModel, id, linkType, fromNode, toNode); return EN_addlink(_defaultModel, id, linkType, fromNode, toNode);
} }
int DLLEXPORT ENdeletelink(int index) { int DLLEXPORT ENdeletelink(int index) {
return EN_deletelink(_defaultModel, index); return EN_deletelink(_defaultModel, index);
} }
int DLLEXPORT ENdeletenode(int index) { int DLLEXPORT ENdeletenode(int index) {
return EN_deletenode(_defaultModel, index); return EN_deletenode(_defaultModel, index);
} }
@@ -734,7 +821,6 @@ int DLLEXPORT EN_solveH(EN_ProjectHandle ph)
tstep = 0; tstep = 0;
ERRCODE(EN_runH(ph, &t)); ERRCODE(EN_runH(ph, &t));
ERRCODE(EN_nextH(ph, &tstep)); ERRCODE(EN_nextH(ph, &tstep));
/*** Updated 6/24/02 ***/ /*** Updated 6/24/02 ***/
writecon("\b\b\b\b\b\b\b\b\b\b"); writecon("\b\b\b\b\b\b\b\b\b\b");
} while (tstep > 0); } while (tstep > 0);
@@ -858,8 +944,10 @@ int DLLEXPORT EN_initH(EN_ProjectHandle ph, int flag)
errcode = openhydfile(p); errcode = openhydfile(p);
if (!errcode) if (!errcode)
p->save_options.Saveflag = TRUE; p->save_options.Saveflag = TRUE;
else else {
errmsg(p, errcode); errmsg(p, errcode);
return errcode;
}
} }
/* Initialize hydraulics */ /* Initialize hydraulics */
@@ -1333,6 +1421,14 @@ int DLLEXPORT EN_getoption(EN_ProjectHandle ph, EN_Option code,
case EN_DEMANDMULT: case EN_DEMANDMULT:
v = hyd->Dmult; v = hyd->Dmult;
break; break;
case EN_HEADERROR:
v = hyd->HeadErrorLimit * Ucf[HEAD];
break;
case EN_FLOWCHANGE:
v = hyd->FlowChangeLimit * Ucf[FLOW];
break;
default: default:
return (251); return (251);
} }
@@ -1627,11 +1723,12 @@ int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode)
return (0); return (0);
} }
int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname,
char *chemunits, int *tracenode) {
EN_Project *p = (EN_Project*)ph;
ENgetqualtype(qualcode, tracenode); int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname,
char *chemunits, int *tracenode) {
EN_getqualtype(p, qualcode, tracenode);
if (p->quality.Qualflag == TRACE) { if (p->quality.Qualflag == TRACE) {
strncpy(chemname, "", MAXID); strncpy(chemname, "", MAXID);
strncpy(chemunits, "dimensionless", MAXID); strncpy(chemunits, "dimensionless", MAXID);
@@ -1665,7 +1762,7 @@ int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) {
strncpy(errmsg, WARN6, n); strncpy(errmsg, WARN6, n);
break; break;
default: default:
geterrmsg(n, newMsg); geterrmsg(errcode, newMsg);
strncpy(errmsg, newMsg, n); strncpy(errmsg, newMsg, n);
} }
if (strlen(errmsg) == 0) if (strlen(errmsg) == 0)
@@ -2720,7 +2817,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code,
r = Link[index].Diam / value; /* Ratio of old to new diam */ r = Link[index].Diam / value; /* Ratio of old to new diam */
Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */ Link[index].Km *= SQR(r) * SQR(r); /* Adjust minor loss factor */
Link[index].Diam = value; /* Update diameter */ Link[index].Diam = value; /* Update diameter */
resistance(p, index); /* Update resistance factor */ resistcoeff(p, index); /* Update resistance coeff. */
} }
break; break;
@@ -2729,7 +2826,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code,
if (value <= 0.0) if (value <= 0.0)
return (202); return (202);
Link[index].Len = value / Ucf[ELEV]; Link[index].Len = value / Ucf[ELEV];
resistance(p, index); resistcoeff(p, index);
} }
break; break;
@@ -2740,7 +2837,7 @@ int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code,
Link[index].Kc = value; Link[index].Kc = value;
if (hyd->Formflag == DW) if (hyd->Formflag == DW)
Link[index].Kc /= (1000.0 * Ucf[ELEV]); Link[index].Kc /= (1000.0 * Ucf[ELEV]);
resistance(p, index); resistcoeff(p, index);
} }
break; break;
@@ -3259,6 +3356,18 @@ int DLLEXPORT EN_setoption(EN_ProjectHandle ph, int code, EN_API_FLOAT_TYPE v)
return (202); return (202);
hyd->Dmult = value; hyd->Dmult = value;
break; 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: default:
return (251); return (251);
} }
@@ -3936,7 +4045,6 @@ void freedata(EN_Project *p)
---------------------------------------------------------------- ----------------------------------------------------------------
*/ */
/*** New function for 2.00.12 ***/
char *getTmpName(EN_Project *p, char *fname) char *getTmpName(EN_Project *p, char *fname)
// //
// Input: fname = file name string // Input: fname = file name string
@@ -3944,7 +4052,25 @@ char *getTmpName(EN_Project *p, char *fname)
// Purpose: creates a temporary file name with path prepended to it. // Purpose: creates a temporary file name with path prepended to it.
// //
{ {
out_file_t *out = &p->out_files;
#ifdef _WIN32
char* name = NULL;
// --- use Windows _tempnam function to get a pointer to an
// unused file name that begins with "en"
name = _tempnam(NULL, "en");
if (name == NULL) return NULL;
// --- copy the file name to fname
if (strlen(name) < MAXFNAME) strncpy(fname, name, MAXFNAME);
else fname = NULL;
// --- free the pointer returned by _tempnam
if (name) free(name);
/*
/////////////////// DEPRECATED /////////////////////////////////////
// --- for Windows systems: // --- for Windows systems:
#ifdef WINDOWS #ifdef WINDOWS
// --- use system function tmpnam() to create a temporary file name // --- use system function tmpnam() to create a temporary file name
@@ -3970,6 +4096,7 @@ char *getTmpName(EN_Project *p, char *fname)
// --- now add the prefix to the file name // --- now add the prefix to the file name
strcat(fname, name); strcat(fname, name);
*/
// --- for non-Windows systems: // --- for non-Windows systems:
#else #else
@@ -4362,16 +4489,15 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
qu->NodeQual = (double *)realloc(qu->NodeQual, (net->Nnodes + 2) * sizeof(double)); qu->NodeQual = (double *)realloc(qu->NodeQual, (net->Nnodes + 2) * sizeof(double));
hyd->NodeHead = (double *)realloc(hyd->NodeHead, (net->Nnodes + 2) * sizeof(double)); hyd->NodeHead = (double *)realloc(hyd->NodeHead, (net->Nnodes + 2) * sizeof(double));
nIdx = net->Nnodes + 1;
node = &net->Node[nIdx];
coord = &net->Coord[nIdx];
if (nodeType == EN_JUNCTION) { if (nodeType == EN_JUNCTION) {
net->Njuncs++; net->Njuncs++;
nIdx = net->Njuncs;
node = &net->Node[nIdx];
coord = &net->Coord[nIdx];
demand = (struct Sdemand *)malloc(sizeof(struct Sdemand)); demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
demand->Base = 0.0; demand->Base = 0.0;
demand->Pat = 0; demand->Pat = hyd->DefPat; // Use default pattern
demand->next = NULL; demand->next = NULL;
node->D = demand; node->D = demand;
@@ -4396,6 +4522,9 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
} }
} }
} else { } else {
nIdx = net->Nnodes++;
node = &net->Node[nIdx];
coord = &net->Coord[nIdx];
net->Ntanks++; net->Ntanks++;
/* resize tanks array */ /* resize tanks array */
@@ -4437,7 +4566,6 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
node->Ke = 0; node->Ke = 0;
node->Rpt = 0; node->Rpt = 0;
coord->HaveCoords = FALSE; coord->HaveCoords = FALSE;
coord->X = 0; coord->X = 0;
coord->Y = 0; coord->Y = 0;

View File

@@ -31,32 +31,34 @@ AUTHOR: L. Rossman
#include "types.h" #include "types.h"
void initpointers(EN_Project *p); /* Initializes pointers */ void initpointers(EN_Project *pr); /* Initializes pointers */
int allocdata(EN_Project *p); /* Allocates memory */ int allocdata(EN_Project *pr); /* Allocates memory */
void freeTmplist(STmplist *); /* Frees items in linked list */ void freeTmplist(STmplist *); /* Frees items in linked list */
void freeFloatlist(SFloatlist *); /* Frees list of floats */ void freeFloatlist(SFloatlist *); /* Frees list of floats */
void freedata(EN_Project *p); /* Frees allocated memory */ void freedata(EN_Project *pr); /* Frees allocated memory */
int openfiles(EN_Project *p, const char *, const char *, const char *); /* Opens input & report files */ int openfiles(EN_Project *pr, const char *,
int openhydfile(EN_Project *p); /* Opens hydraulics file */ const char *,const char *); /* Opens input & report files */
int openoutfile(EN_Project *p); /* Opens binary output file */ int openhydfile(EN_Project *pr); /* Opens hydraulics file */
int strcomp(const char *, const char *); /* Compares two strings */ int openoutfile(EN_Project *pr); /* Opens binary output file */
char* getTmpName(EN_Project *p, char* fname); /* Gets temporary file name */ int strcomp(const char *, const char *); /* Compares two strings */
double interp(int, double *,double *, double); /* Interpolates a data curve */ char* getTmpName(EN_Project *p, char* fname); /* Gets temporary file name */
double interp(int n, double x[], double y[],
double xx); /* Interpolates a data curve */
int findnode(EN_Network *n, char *); /* Finds node's index from ID */ int findnode(EN_Network *n, char *); /* Finds node's index from ID */
int findlink(EN_Network *n, char *); /* Finds link's index from ID */ int findlink(EN_Network *n, char *); /* Finds link's index from ID */
int findtank(EN_Network *n, int); /* Find tank index from node index */ // (AH) int findtank(EN_Network *n, int); /* Find tank index from node index */ // (AH)
int findvalve(EN_Network *n, int); /* Find valve index from node index */ // (AH) int findvalve(EN_Network *n, int); /* Find valve index from node index */ // (AH)
int findpump(EN_Network *n, int); /* Find pump index from node index */ // (AH) int findpump(EN_Network *n, int); /* Find pump index from node index */ // (AH)
char *geterrmsg(int errcode, char *msg); /* Gets text of error message */ char *geterrmsg(int errcode, char *msg); /* Gets text of error message */
void errmsg(EN_Project *p, int); /* Reports program error */ void errmsg(EN_Project *p, int); /* Reports program error */
void writecon(const char *); /* Writes text to console */ void writecon(const char *); /* Writes text to console */
void writewin(void (*vp)(char *), char *); /* Passes text to calling app */ void writewin(void (*vp)(char *), char *); /* Passes text to calling app */
/* ------- INPUT1.C --------------------*/ /* ------- INPUT1.C --------------------*/
int getdata(EN_Project *pr); /* Gets network data */ int getdata(EN_Project *pr); /* Gets network data */
void setdefaults(EN_Project *pr); /* Sets default values */ void setdefaults(EN_Project *pr); /* Sets default values */
void initreport(report_options_t *r); /* Initializes report options */ void initreport(report_options_t *r); /* Initializes report options */
void adjustdata(EN_Project *pr); /* Adjusts input data */ void adjustdata(EN_Project *pr); /* Adjusts input data */
int inittanks(EN_Project *pr); /* Initializes tank levels */ int inittanks(EN_Project *pr); /* Initializes tank levels */
void initunits(EN_Project *pr); /* Determines reporting units */ void initunits(EN_Project *pr); /* Determines reporting units */
@@ -65,23 +67,24 @@ void convertunits(EN_Project *pr); /* Converts data to std. uni
/* -------- INPUT2.C -------------------*/ /* -------- INPUT2.C -------------------*/
int netsize(EN_Project *pr); /* Determines network size */ int netsize(EN_Project *pr); /* Determines network size */
int readdata(EN_Project *pr); /* Reads in network data */ int readdata(EN_Project *pr); /* Reads in network data */
int newline(EN_Project *pr, int, char *); /* Processes new line of data */ int newline(EN_Project *pr, int, char *); /* Processes new line of data */
int addnodeID(EN_Network *n, int, char *); /* Adds node ID to data base */ int addnodeID(EN_Network *n, int, char *); /* Adds node ID to data base */
int addlinkID(EN_Network *n, int, char *); /* Adds link ID to data base */ int addlinkID(EN_Network *n, int, char *); /* Adds link ID to data base */
int addpattern(parser_data_t *par, char *); /* Adds pattern to data base */ int addpattern(parser_data_t *par, char *); /* Adds pattern to data base */
int addcurve(parser_data_t *par, char *); /* Adds curve to data base */ int addcurve(parser_data_t *par, char *); /* Adds curve to data base */
STmplist *findID(char *, STmplist *); /* Locates ID on linked list */ STmplist *findID(char *, STmplist *); /* Locates ID on linked list */
int unlinked(EN_Project *pr); /* Checks for unlinked nodes */ int unlinked(EN_Project *pr); /* Checks for unlinked nodes */
int getpumpparams(EN_Project *pr); /* Computes pump curve coeffs.*/ int getpumpparams(EN_Project *pr); /* Computes pump curve coeffs.*/
int getpatterns(EN_Project *pr); /* Gets pattern data from list*/ int getpatterns(EN_Project *pr); /* Gets pattern data from list*/
int getcurves(EN_Project *pr); /* Gets curve data from list */ int getcurves(EN_Project *pr); /* Gets curve data from list */
int findmatch(char *, char *[]); /* Finds keyword in line */ int findmatch(char *, char *[]); /* Finds keyword in line */
int match(const char *, const char *); /* Checks for word match */ int match(const char *, const char *); /* Checks for word match */
int gettokens(char *s, char** Tok, int maxToks, char *comment); /* Tokenizes input line */ int gettokens(char *s, char** Tok, int maxToks,
int getfloat(char *, double *); /* Converts string to double */ char *comment); /* Tokenizes input line */
double hour(char *, char *); /* Converts time to hours */ int getfloat(char *, double *); /* Converts string to double */
int setreport(EN_Project *pr, char *); /* Processes reporting command*/ double hour(char *, char *); /* Converts time to hours */
void inperrmsg(EN_Project *pr, int,int,char *); /* Input error message */ int setreport(EN_Project *pr, char *); /* Processes reporting command*/
void inperrmsg(EN_Project *pr, int,int,char *); /* Input error message */
/* ---------- INPUT3.C -----------------*/ /* ---------- INPUT3.C -----------------*/
int juncdata(EN_Project *pr); /* Processes junction data */ int juncdata(EN_Project *pr); /* Processes junction data */
@@ -104,22 +107,25 @@ int statusdata(EN_Project *pr); /* Processes link status dat
int reportdata(EN_Project *pr); /* Processes report options */ int reportdata(EN_Project *pr); /* Processes report options */
int timedata(EN_Project *pr); /* Processes time options */ int timedata(EN_Project *pr); /* Processes time options */
int optiondata(EN_Project *pr); /* Processes analysis options */ int optiondata(EN_Project *pr); /* Processes analysis options */
int optionchoice(EN_Project *pr, int); /* Processes option choices */ int optionchoice(EN_Project *pr, int); /* Processes option choices */
int optionvalue(EN_Project *pr, int); /* Processes option values */ int optionvalue(EN_Project *pr, int); /* Processes option values */
int getpumpcurve(EN_Project *pr, int); /* Constructs a pump curve */ int getpumpcurve(EN_Project *pr, int); /* Constructs a pump curve */
int powercurve(double, double, double,/* Coeffs. of power pump curve*/ int powercurve(double, double, double, /* Coeffs. of power pump curve*/
double, double, double *, double, double, double *,
double *, double *); double *, double *);
int valvecheck(EN_Project *pr, int, int, int); /* Checks valve placement */ int valvecheck(EN_Project *pr, int, int, int); /* Checks valve placement */
void changestatus(EN_Network *net, int, StatType, double); /* Changes status of a link */ void changestatus(EN_Network *net, int, StatType,
double); /* Changes status of a link */
/* -------------- RULES.C --------------*/ /* -------------- RULES.C --------------*/
void initrules(rules_t *rules); /* Initializes rule base */ void initrules(rules_t *rules); /* Initializes rule base */
void addrule(parser_data_t *par, char *); /* Adds rule to rule base */ void addrule(parser_data_t *par, char *); /* Adds rule to rule base */
int allocrules(EN_Project *pr); /* Allocates memory for rule */ int allocrules(EN_Project *pr); /* Allocates memory for rule */
int ruledata(EN_Project *pr); /* Processes rule input data */ int ruledata(EN_Project *pr); /* Processes rule input data */
int checkrules(EN_Project *pr, long); /* Checks all rules */ int checkrules(EN_Project *pr, long); /* Checks all rules */
void freerules(EN_Project *pr); /* Frees rule base memory */ void freerules(EN_Project *pr); /* Frees rule base memory */
int writeRuleinInp(EN_Project *pr, FILE *f, /* Writes rule to an INP file */
int RuleIdx);
int writeRuleinInp(EN_Project *pr, FILE *f, int RuleIdx); int writeRuleinInp(EN_Project *pr, FILE *f, int RuleIdx);
@@ -127,167 +133,147 @@ int writeRuleinInp(EN_Project *pr, FILE *f, int RuleIdx);
int writereport(EN_Project *pr); /* Writes formatted report */ int writereport(EN_Project *pr); /* Writes formatted report */
void writelogo(EN_Project *pr); /* Writes program logo */ void writelogo(EN_Project *pr); /* Writes program logo */
void writesummary(EN_Project *pr); /* Writes network summary */ void writesummary(EN_Project *pr); /* Writes network summary */
void writehydstat(EN_Project *pr, int,double); /* Writes hydraulic status */ void writehydstat(EN_Project *pr, int,double); /* Writes hydraulic status */
void writeenergy(EN_Project *pr); /* Writes energy usage */ void writeenergy(EN_Project *pr); /* Writes energy usage */
int writeresults(EN_Project *pr); /* Writes node/link results */ int writeresults(EN_Project *pr); /* Writes node/link results */
void writeheader(EN_Project *pr, int,int); /* Writes heading on report */ void writeheader(EN_Project *pr, int,int); /* Writes heading on report */
void writeline(EN_Project *pr, char *); /* Writes line to report file */ void writeline(EN_Project *pr, char *); /* Writes line to report file */
void writerelerr(EN_Project *pr, int, double); /* Writes convergence error */ void writerelerr(EN_Project *pr, int, double); /* Writes convergence error */
void writestatchange(EN_Project *pr, int,char,char); /* Writes link status change */ void writestatchange(EN_Project *pr, int,char,char); /* Writes link status change */
void writecontrolaction(EN_Project *pr, int, int); /* Writes control action taken*/ void writecontrolaction(EN_Project *pr, int, int); /* Writes control action taken*/
void writeruleaction(EN_Project *pr, int, char *); /* Writes rule action taken */ void writeruleaction(EN_Project *pr, int, char *); /* Writes rule action taken */
int writehydwarn(EN_Project *pr, int,double); /* Writes hydraulic warnings */ int writehydwarn(EN_Project *pr, int,double); /* Writes hydraulic warnings */
void writehyderr(EN_Project *pr, int); /* Writes hydraulic error msg.*/ void writehyderr(EN_Project *pr, int); /* Writes hydraulic error msg.*/
int disconnected(EN_Project *pr); /* Checks for disconnections */ int disconnected(EN_Project *pr); /* Checks for disconnections */
void marknodes(EN_Project *pr, int, int *, char *); /* Identifies connected nodes */ void marknodes(EN_Project *pr, int, int *, char *); /* Identifies connected nodes */
void getclosedlink(EN_Project *pr, int, char *); /* Finds a disconnecting link */ void getclosedlink(EN_Project *pr, int, char *); /* Finds a disconnecting link */
void writelimits(EN_Project *pr, int,int); /* Writes reporting limits */ void writelimits(EN_Project *pr, int,int); /* Writes reporting limits */
int checklimits(report_options_t *rep, double *,int,int); /* Checks variable limits */ int checklimits(report_options_t *rep, double *,
int,int); /* Checks variable limits */
void writetime(EN_Project *pr, char *); /* Writes current clock time */ void writetime(EN_Project *pr, char *); /* Writes current clock time */
char *clocktime(char *, long); /* Converts time to hrs:min */ char *clocktime(char *, long); /* Converts time to hrs:min */
char *fillstr(char *, char, int); /* Fills string with character*/ char *fillstr(char *, char, int); /* Fills string with character*/
int getnodetype(EN_Network *net, int); /* Determines node type */ int getnodetype(EN_Network *net, int); /* Determines node type */
/* --------- HYDRAUL.C -----------------*/ /* --------- HYDRAUL.C -----------------*/
int openhyd(EN_Project *pr); /* Opens hydraulics solver */ int openhyd(EN_Project *pr); /* Opens hydraulics solver */
void inithyd(EN_Project *pr, int initFlags); /* Re-sets initial conditions */
/*** Updated 3/1/01 ***/ int runhyd(EN_Project *pr, long *); /* Solves 1-period hydraulics */
void inithyd(EN_Project *pr, int initFlags); /* Re-sets initial conditions */ int nexthyd(EN_Project *pr, long *); /* Moves to next time period */
int runhyd(EN_Project *pr, long *); /* Solves 1-period hydraulics */
int nexthyd(EN_Project *pr, long *); /* Moves to next time period */
void closehyd(EN_Project *pr); /* Closes hydraulics solver */ void closehyd(EN_Project *pr); /* Closes hydraulics solver */
int allocmatrix(EN_Project *pr); /* Allocates matrix coeffs. */ int allocmatrix(EN_Project *pr); /* Allocates matrix coeffs. */
void freematrix(EN_Project *pr); /* Frees matrix coeffs. */ void freematrix(EN_Project *pr); /* Frees matrix coeffs. */
void initlinkflow(EN_Project *pr, int, char, double); /* Initializes link flow */ void initlinkflow(EN_Project *pr, int, char,
void setlinkflow(EN_Project *pr, int, double); /* Sets link flow via headloss*/ double); /* Initializes link flow */
void setlinkstatus(EN_Project *pr, int, char, StatType *, double *); /* Sets link status */ void setlinkflow(EN_Project *pr, int, double); /* Sets link flow via headloss*/
void setlinkstatus(EN_Project *pr, int, char,
StatType *, double *); /* Sets link status */
void setlinksetting(EN_Project *pr, int, double,
StatType *, double *); /* Sets pump/valve setting */
void setlinksetting(EN_Project *pr, int, double, StatType *, double *); /* Sets pump/valve setting */
void resistance(EN_Project *pr, int); /* Computes resistance coeff. */
void demands(EN_Project *pr); /* Computes current demands */ void demands(EN_Project *pr); /* Computes current demands */
int controls(EN_Project *pr); /* Controls link settings */ int controls(EN_Project *pr); /* Controls link settings */
long timestep(EN_Project *pr); /* Computes new time step */ long timestep(EN_Project *pr); /* Computes new time step */
int tanktimestep(EN_Project *pr, long *); /* Time till tanks fill/drain */ int tanktimestep(EN_Project *pr, long *); /* Time till tanks fill/drain */
void controltimestep(EN_Project *pr, long *); /* Time till control action */ void controltimestep(EN_Project *pr, long *); /* Time till control action */
void ruletimestep(EN_Project *pr, long *); /* Time till rule action */ void ruletimestep(EN_Project *pr, long *); /* Time till rule action */
void addenergy(EN_Project *pr, long); /* Accumulates energy usage */
void getenergy(EN_Project *pr, int, double *, double *); /* Computes link energy use */
void tanklevels(EN_Project *pr, long); /* Computes new tank levels */
double tankvolume(EN_Project *pr, int,double); /* Finds tank vol. from grade */
double tankgrade(EN_Project *pr, int,double); /* Finds tank grade from vol. */
int netsolve(EN_Project *pr, int *,double *); /* Solves network equations */
int badvalve(EN_Project *pr, int); /* Checks for bad valve */
int valvestatus(EN_Project *pr); /* Updates valve status */
int linkstatus(EN_Project *pr); /* Updates link status */
StatType cvstatus(EN_Project *pr, StatType,double,double); /* Updates CV status */
StatType pumpstatus(EN_Project *pr, int,double); /* Updates pump status */
StatType prvstatus(EN_Project *pr, int,StatType,double,double,double); /* Updates PRV status */
StatType psvstatus(EN_Project *pr, int,StatType,double,double,double); /* Updates PSV status */ void addenergy(EN_Project *pr, long); /* Accumulates energy usage */
void getenergy(EN_Project *pr, int, double *,
double *); /* Computes link energy use */
StatType fcvstatus(EN_Project *pr, int,StatType,double,double); /* Updates FCV status */ void tanklevels(EN_Project *pr, long); /* Computes new tank levels */
double tankvolume(EN_Project *pr, int,double); /* Finds tank vol. from grade */
double tankgrade(EN_Project *pr, int,double); /* Finds tank grade from vol. */
void tankstatus(EN_Project *pr, int,int,int); /* Checks if tank full/empty */ /* ----------- HYDSOLVER.C - ----------*/
int pswitch(EN_Project *pr); /* Pressure switch controls */ int hydsolve(EN_Project *pr, int *,double *); /* Solves network equations */
double newflows(EN_Project *pr); /* Updates link flows */
void newcoeffs(EN_Project *pr); /* Computes matrix coeffs. */
void linkcoeffs(EN_Project *pr); /* Computes link coeffs. */
void nodecoeffs(EN_Project *pr); /* Computes node coeffs. */
void valvecoeffs(EN_Project *pr); /* Computes valve coeffs. */
void pipecoeff(EN_Project *pr, int); /* Computes pipe coeff. */
double DWcoeff(EN_Project *pr, int, double *); /* Computes D-W coeff. */
void pumpcoeff(EN_Project *pr, int); /* Computes pump coeff. */
/*** Updated 10/25/00 ***/ /* ----------- HYDCOEFFS.C --------------*/
/*** Updated 12/29/00 ***/ void resistcoeff(EN_Project *pr, int k); /* Finds pipe flow resistance */
void curvecoeff(EN_Project *pr, int,double,double *,double *); /* Computes curve coeffs. */ void hlosscoeff(EN_Project *pr, int k); /* Finds link head loss coeff */
void matrixcoeffs(EN_Project *pr); /* Finds hyd. matrix coeffs. */
void gpvcoeff(EN_Project *pr, int iLink); /* Computes GPV coeff. */
void pbvcoeff(EN_Project *pr, int iLink); /* Computes PBV coeff. */
void tcvcoeff(EN_Project *pr, int iLink); /* Computes TCV coeff. */
void prvcoeff(EN_Project *pr, int iLink, int n1, int n2); /* Computes PRV coeff. */
void psvcoeff(EN_Project *pr, int iLink, int n1, int n2); /* Computes PSV coeff. */
void fcvcoeff(EN_Project *pr, int iLink, int n1, int n2); /* Computes FCV coeff. */
void emittercoeffs(EN_Project *pr); /* Computes emitter coeffs. */
double emitflowchange(EN_Project *pr, int); /* Computes new emitter flow */
/* ----------- SMATRIX.C ---------------*/ /* ----------- SMATRIX.C ---------------*/
int createsparse(EN_Project *pr); /* Creates sparse matrix */ int createsparse(EN_Project *pr); /* Creates sparse matrix */
int allocsparse(EN_Project *pr); /* Allocates matrix memory */ int allocsparse(EN_Project *pr); /* Allocates matrix memory */
void freesparse(EN_Project *pr); /* Frees matrix memory */ void freesparse(EN_Project *pr); /* Frees matrix memory */
int buildlists(EN_Project *pr, int); /* Builds adjacency lists */ int buildlists(EN_Project *pr, int); /* Builds adjacency lists */
int paralink(EN_Project *pr, int, int, int); /* Checks for parallel links */ int paralink(EN_Project *pr, int, int, int); /* Checks for parallel links */
void xparalinks(EN_Project *pr); /* Removes parallel links */ void xparalinks(EN_Project *pr); /* Removes parallel links */
void freelists(EN_Project *pr); /* Frees adjacency lists */ void freelists(EN_Project *pr); /* Frees adjacency lists */
void countdegree(EN_Project *pr); /* Counts links at each node */ void countdegree(EN_Project *pr); /* Counts links at each node */
int reordernodes(EN_Project *pr); /* Finds a node re-ordering */ int reordernodes(EN_Project *pr); /* Finds a node re-ordering */
int mindegree(solver_t *s, int, int); /* Finds min. degree node */ int mindegree(solver_t *s, int, int); /* Finds min. degree node */
int growlist(EN_Project *pr, int); /* Augments adjacency list */ int growlist(EN_Project *pr, int); /* Augments adjacency list */
int newlink(EN_Project *pr, Padjlist); /* Adds fill-ins for a node */ int newlink(EN_Project *pr, Padjlist); /* Adds fill-ins for a node */
int linked(EN_Network *net, int, int); /* Checks if 2 nodes linked */ int linked(EN_Network *net, int, int); /* Checks if 2 nodes linked */
int addlink(EN_Network *net, int, int, int); /* Creates new fill-in */ int addlink(EN_Network *net, int, int, int); /* Creates new fill-in */
int storesparse(EN_Project *pr, int); /* Stores sparse matrix */ int storesparse(EN_Project *pr, int); /* Stores sparse matrix */
int ordersparse(hydraulics_t *h, int); /* Orders matrix storage */ int ordersparse(hydraulics_t *h, int); /* Orders matrix storage */
void transpose(int,int *,int *, /* Transposes sparse matrix */ void transpose(int,int *,int *, /* Transposes sparse matrix */
int *,int *,int *,int *,int *); int *,int *,int *,int *,int *);
int linsolve(solver_t *s, int); /* via Cholesky factorization */ int linsolve(solver_t *s, int); /* Solves set of inear eqns. */
/* ----------- QUALITY.C ---------------*/ /* ----------- QUALITY.C ---------------*/
int openqual(EN_Project *pr); /* Opens WQ solver system */ int openqual(EN_Project *pr); /* Opens WQ solver system */
void initqual(EN_Project *pr); /* Initializes WQ solver */ void initqual(EN_Project *pr); /* Initializes WQ solver */
int runqual(EN_Project *pr, long *); /* Gets current WQ results */ int runqual(EN_Project *pr, long *); /* Gets current WQ results */
int nextqual(EN_Project *pr, long *); /* Updates WQ by hyd.timestep */ int nextqual(EN_Project *pr, long *); /* Updates WQ by hyd.timestep */
int stepqual(EN_Project *pr, long *); /* Updates WQ by WQ time step */ int stepqual(EN_Project *pr, long *); /* Updates WQ by WQ time step */
int closequal(EN_Project *pr); /* Closes WQ solver system */ int closequal(EN_Project *pr); /* Closes WQ solver system */
int gethyd(EN_Project *pr, long *, long *); /* Gets next hyd. results */ int gethyd(EN_Project *pr, long *, long *); /* Gets next hyd. results */
char setReactflag(EN_Project *pr); /* Checks for reactive chem. */ char setReactflag(EN_Project *pr); /* Checks for reactive chem. */
void transport(EN_Project *pr, long); /* Transports mass in network */ void transport(EN_Project *pr, long); /* Transports mass in network */
void initsegs(EN_Project *pr); /* Initializes WQ segments */ void initsegs(EN_Project *pr); /* Initializes WQ segments */
void reorientsegs(EN_Project *pr); /* Re-orients WQ segments */ void reorientsegs(EN_Project *pr); /* Re-orients WQ segments */
void updatesegs(EN_Project *pr, long); /* Updates quality in segments*/ void updatesegs(EN_Project *pr, long); /* Updates quality in segments*/
void removesegs(EN_Project *pr, int); /* Removes a WQ segment */ void removesegs(EN_Project *pr, int); /* Removes a WQ segment */
void addseg(EN_Project *pr, int,double,double); /* Adds a WQ segment to pipe */ void addseg(EN_Project *pr, int,double,double); /* Adds a WQ segment to pipe */
void accumulate(EN_Project *pr, long); /* Sums mass flow into node */ void accumulate(EN_Project *pr, long); /* Sums mass flow into node */
void updatenodes(EN_Project *pr, long); /* Updates WQ at nodes */ void updatenodes(EN_Project *pr, long); /* Updates WQ at nodes */
void sourceinput(EN_Project *pr, long); /* Computes source inputs */ void sourceinput(EN_Project *pr, long); /* Computes source inputs */
void release(EN_Project *pr, long); /* Releases mass from nodes */ void release(EN_Project *pr, long); /* Releases mass from nodes */
void updatetanks(EN_Project *pr, long); /* Updates WQ in tanks */ void updatetanks(EN_Project *pr, long); /* Updates WQ in tanks */
void updatesourcenodes(EN_Project *pr, long); /* Updates WQ at source nodes */ void updatesourcenodes(EN_Project *pr, long); /* Updates WQ at source nodes */
void tankmix1(EN_Project *pr, int, long); /* Complete mix tank model */ void tankmix1(EN_Project *pr, int, long); /* Complete mix tank model */
void tankmix2(EN_Project *pr, int, long); /* 2-compartment tank model */ void tankmix2(EN_Project *pr, int, long); /* 2-compartment tank model */
void tankmix3(EN_Project *pr, int, long); /* FIFO tank model */ void tankmix3(EN_Project *pr, int, long); /* FIFO tank model */
void tankmix4(EN_Project *pr, int, long); /* LIFO tank model */ void tankmix4(EN_Project *pr, int, long); /* LIFO tank model */
double sourcequal(EN_Project *pr, Psource); /* Finds WQ input from source */ double sourcequal(EN_Project *pr, Psource); /* Finds WQ input from source */
double avgqual(EN_Project *pr, int); /* Finds avg. quality in pipe */ double avgqual(EN_Project *pr, int); /* Finds avg. quality in pipe */
void ratecoeffs(EN_Project *pr); /* Finds wall react. coeffs. */ void ratecoeffs(EN_Project *pr); /* Finds wall react. coeffs. */
double piperate(EN_Project *pr, int); /* Finds wall react. coeff. */ double piperate(EN_Project *pr, int); /* Finds wall react. coeff. */
double pipereact(EN_Project *pr, int,double,double,long);/* Reacts water in a pipe */ double pipereact(EN_Project *pr, int,double,
double tankreact(EN_Project *pr, double,double,double,long); /* Reacts water in a tank */ double,long); /* Reacts water in a pipe */
double bulkrate(EN_Project *pr, double,double,double); /* Finds bulk reaction rate */ double tankreact(EN_Project *pr, double,double,
double wallrate(EN_Project *pr, double,double,double,double);/* Finds wall reaction rate */ double,long); /* Reacts water in a tank */
double bulkrate(EN_Project *pr, double,double,
double); /* Finds bulk reaction rate */
double wallrate(EN_Project *pr, double,double,
double,double); /* Finds wall reaction rate */
/* ------------ OUTPUT.C ---------------*/ /* ------------ OUTPUT.C ---------------*/
int savenetdata(EN_Project *pr); /* Saves basic data to file */ int savenetdata(EN_Project *pr); /* Saves basic data to file */
int savehyd(EN_Project *pr, long *); /* Saves hydraulic solution */ int savehyd(EN_Project *pr, long *); /* Saves hydraulic solution */
int savehydstep(EN_Project *pr, long *); /* Saves hydraulic timestep */ int savehydstep(EN_Project *pr, long *); /* Saves hydraulic timestep */
int saveenergy(EN_Project *pr); /* Saves energy usage */ int saveenergy(EN_Project *pr); /* Saves energy usage */
int readhyd(EN_Project *pr, long *); /* Reads hydraulics from file */ int readhyd(EN_Project *pr, long *); /* Reads hydraulics from file */
int readhydstep(FILE *hydFile, long *); /* Reads time step from file */ int readhydstep(FILE *hydFile, long *); /* Reads time step from file */
int saveoutput(EN_Project *pr); /* Saves results to file */ int saveoutput(EN_Project *pr); /* Saves results to file */
int nodeoutput(EN_Project *pr, int, REAL4 *, double); /* Saves node results to file */ int nodeoutput(EN_Project *pr, int, REAL4 *,
int linkoutput(EN_Project *pr, int, REAL4 *, double); /* Saves link results to file */ double); /* Saves node results to file */
int linkoutput(EN_Project *pr, int, REAL4 *,
double); /* Saves link results to file */
int savefinaloutput(EN_Project *pr); /* Finishes saving output */ int savefinaloutput(EN_Project *pr); /* Finishes saving output */
int savetimestat(EN_Project *pr, REAL4 *, HdrType); /* Saves time stats to file */ int savetimestat(EN_Project *pr, REAL4 *,
int savenetreacts(EN_Project *pr, double, double,double, double); HdrType); /* Saves time stats to file */
/* Saves react. rates to file */ int savenetreacts(EN_Project *pr, double,
double,double, double); /* Saves react. rates to file */
int saveepilog(EN_Project *pr); /* Saves output file epilog */ int saveepilog(EN_Project *pr); /* Saves output file epilog */
/* ------------ INPFILE.C --------------*/ /* ------------ INPFILE.C --------------*/
int saveinpfile(EN_Project *pr, char *); /* Saves network to text file */ int saveinpfile(EN_Project *pr, char *); /* Saves network to text file */
#endif #endif

933
src/hydcoeffs.c Normal file
View File

@@ -0,0 +1,933 @@
/*
*********************************************************************
HYDCOEFFS.C -- hydraulic coefficients for the EPANET Program
*******************************************************************
*/
#include <stdio.h>
#include <string.h>
#ifndef __APPLE__
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#include <math.h>
#include "types.h"
#include "funcs.h"
// Constants used for computing Darcy-Weisbach friction factor
const double A1 = 0.314159265359e04; // 1000*PI
const double A2 = 0.157079632679e04; // 500*PI
const double A3 = 0.502654824574e02; // 16*PI
const double A4 = 6.283185307; // 2*PI
const double A8 = 4.61841319859; // 5.74*(PI/4)^.9
const double A9 = -8.685889638e-01; // -2/ln(10)
const double AA = -1.5634601348; // -2*.9*2/ln(10)
const double AB = 3.28895476345e-03; // 5.74/(4000^.9)
const double AC = -5.14214965799e-03; // AA*AB
// External functions
//void resistcoeff(EN_Project *pr, int k);
//void hlosscoeff(EN_Project *pr, int k);
//void matrixcoeffs(EN_Project *pr);
// Local functions
static void linkcoeffs(EN_Project *pr);
static void nodecoeffs(EN_Project *pr);
static void valvecoeffs(EN_Project *pr);
static void emittercoeffs(EN_Project *pr);
static void pipecoeff(EN_Project *pr, int k);
static void DWpipecoeff(EN_Project *pr, int k);
static double frictionFactor(EN_Project *pr, int k, double *dfdq);
static void pumpcoeff(EN_Project *pr, int k);
static void curvecoeff(EN_Project *pr, int i, double q, double *h0, double *r);
static void valvecoeff(EN_Project *pr, int k);
static void gpvcoeff(EN_Project *pr, int k);
static void pbvcoeff(EN_Project *pr, int k);
static void tcvcoeff(EN_Project *pr, int k);
static void prvcoeff(EN_Project *pr, int k, int n1, int n2);
static void psvcoeff(EN_Project *pr, int k, int n1, int n2);
static void fcvcoeff(EN_Project *pr, int k, int n1, int n2);
void resistcoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes link flow resistance coefficient
**--------------------------------------------------------------------
*/
{
double e, d, L;
EN_Network *net = &pr->network;
hydraulics_t *hyd = &pr->hydraulics;
Slink *link = &net->Link[k];
switch (link->Type) {
// ... Link is a pipe. Compute resistance based on headloss formula.
// Friction factor for D-W formula gets included during head loss
// calculation.
case EN_CVPIPE:
case EN_PIPE:
e = link->Kc; // Roughness coeff.
d = link->Diam; // Diameter
L = link->Len; // Length
switch (hyd->Formflag)
{
case HW:
link->R = 4.727*L / pow(e, hyd->Hexp) / pow(d, 4.871);
break;
case DW:
link->R = L / 2.0 / 32.2 / d / SQR(PI*SQR(d) / 4.0);
break;
case CM:
link->R = SQR(4.0*e / (1.49*PI*d*d)) * pow((d / 4.0), -1.333)*L;
}
break;
// ... Link is a pump. Use huge resistance.
case EN_PUMP:
link->R = CBIG;
break;
// ... For all other links (e.g. valves) use a small resistance
default:
link->R = CSMALL;
break;
}
}
void hlosscoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes P and Y coefficients for a link
**--------------------------------------------------------------
*/
{
EN_Network *net = &pr->network;
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
Slink *link = &net->Link[k];
switch (link->Type)
{
case EN_CVPIPE:
case EN_PIPE:
pipecoeff(pr, k);
break;
case EN_PUMP:
pumpcoeff(pr, k);
break;
case EN_PBV:
pbvcoeff(pr, k);
break;
case EN_TCV:
tcvcoeff(pr, k);
break;
case EN_GPV:
gpvcoeff(pr, k);
break;
case EN_FCV:
case EN_PRV:
case EN_PSV:
if (hyd->LinkSetting[k] == MISSING) {
valvecoeff(pr, k);
}
else sol->P[k] = 0.0;
}
}
void matrixcoeffs(EN_Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: none
** Purpose: computes coefficients of linearized network eqns.
**--------------------------------------------------------------
*/
{
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
EN_Network *net = &pr->network;
memset(sol->Aii, 0, (net->Nnodes + 1) * sizeof(double));
memset(sol->Aij, 0, (hyd->Ncoeffs + 1) * sizeof(double));
memset(sol->F, 0, (net->Nnodes + 1) * sizeof(double));
memset(hyd->X_tmp, 0, (net->Nnodes + 1) * sizeof(double));
linkcoeffs(pr);
emittercoeffs(pr);
nodecoeffs(pr);
valvecoeffs(pr);
}
void linkcoeffs(EN_Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: none
** Purpose: computes matrix coefficients for links
**--------------------------------------------------------------
*/
{
int k, n1, n2;
EN_Network *net = &pr->network;
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
Slink *link;
// Examine each link of network */
for (k = 1; k <= net->Nlinks; k++)
{
if (sol->P[k] == 0.0) continue;
link = &net->Link[k];
n1 = link->N1; // Start node of link
n2 = link->N2; // End node of link
// Update net nodal inflows (X), solution matrix (A) and RHS array (F)
// (Use covention that flow out of node is (-), flow into node is (+))
hyd->X_tmp[n1] -= hyd->LinkFlows[k];
hyd->X_tmp[n2] += hyd->LinkFlows[k];
// Off-diagonal coeff.
sol->Aij[sol->Ndx[k]] -= sol->P[k];
// Node n1 is junction
if (n1 <= net->Njuncs)
{
sol->Aii[sol->Row[n1]] += sol->P[k]; // Diagonal coeff.
sol->F[sol->Row[n1]] += sol->Y[k]; // RHS coeff.
}
// Node n1 is a tank
else {
sol->F[sol->Row[n2]] += (sol->P[k] * hyd->NodeHead[n1]);
}
// Node n2 is junction
if (n2 <= net->Njuncs) {
sol->Aii[sol->Row[n2]] += sol->P[k]; // Diagonal coeff.
sol->F[sol->Row[n2]] -= sol->Y[k]; // RHS coeff.
}
// Node n2 is a tank
else {
sol->F[sol->Row[n1]] += (sol->P[k] * hyd->NodeHead[n2]);
}
}
}
void nodecoeffs(EN_Project *pr)
/*
**----------------------------------------------------------------
** Input: none
** Output: none
** Purpose: completes calculation of nodal flow imbalance (X)
** & flow correction (F) arrays
**----------------------------------------------------------------
*/
{
int i;
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
EN_Network *net = &pr->network;
// For junction nodes, subtract demand flow from net
// flow imbalance & add imbalance to RHS array F.
for (i = 1; i <= net->Njuncs; i++)
{
hyd->X_tmp[i] -= hyd->NodeDemand[i];
sol->F[sol->Row[i]] += hyd->X_tmp[i];
}
}
void valvecoeffs(EN_Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: none
** Purpose: computes matrix coeffs. for PRVs, PSVs & FCVs
** whose status is not fixed to OPEN/CLOSED
**--------------------------------------------------------------
*/
{
int i, k, n1, n2;
hydraulics_t *hyd = &pr->hydraulics;
EN_Network *net = &pr->network;
Slink *link;
Svalve *valve;
// Examine each valve
for (i = 1; i <= net->Nvalves; i++)
{
valve = &net->Valve[i];
k = valve->Link; // Link index of valve
link = &net->Link[k];
if (hyd->LinkSetting[k] == MISSING) {
continue; // Valve status fixed
}
n1 = link->N1; // Start & end nodes
n2 = link->N2;
switch (link->Type) // Call valve-specific function
{
case EN_PRV:
prvcoeff(pr, k, n1, n2);
break;
case EN_PSV:
psvcoeff(pr, k, n1, n2);
break;
case EN_FCV:
fcvcoeff(pr, k, n1, n2);
break;
default: continue;
}
}
}
void emittercoeffs(EN_Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: none
** Purpose: computes matrix coeffs. for emitters
**
** Note: Emitters consist of a fictitious pipe connected to
** a fictitious reservoir whose elevation equals that
** of the junction. The headloss through this pipe is
** Ke*(Flow)^hyd->Qexp, where Ke = emitter headloss coeff.
**--------------------------------------------------------------
*/
{
int i;
double ke;
double p;
double q;
double y;
double z;
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
EN_Network *net = &pr->network;
Snode *node;
for (i = 1; i <= net->Njuncs; i++)
{
node = &net->Node[i];
if (node->Ke == 0.0) {
continue;
}
ke = MAX(CSMALL, node->Ke); // emitter coeff.
q = hyd->EmitterFlows[i]; // emitter flow
z = ke * pow(ABS(q), hyd->Qexp); // emitter head loss
p = hyd->Qexp * z / ABS(q); // head loss gradient
if (p < hyd->RQtol) {
p = 1.0 / hyd->RQtol;
}
else {
p = 1.0 / p; // inverse head loss gradient
}
y = SGN(q)*z*p; // head loss / gradient
sol->Aii[sol->Row[i]] += p; // addition to main diagonal
sol->F[sol->Row[i]] += y + p * node->El; // addition to r.h.s.
hyd->X_tmp[i] -= q; // addition to net node inflow
}
}
void pipecoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes P & Y coefficients for pipe k
**
** P = inverse head loss gradient = 1/(dh/dQ)
** Y = flow correction term = h*P
**--------------------------------------------------------------
*/
{
double hpipe, // Normal head loss
hml, // Minor head loss
ml, // Minor loss coeff.
p, // q*(dh/dq)
q, // Abs. value of flow
r; // Resistance coeff.
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
Slink *link = &pr->network.Link[k];
// For closed pipe use headloss formula: h = CBIG*q
if (hyd->LinkStatus[k] <= CLOSED)
{
sol->P[k] = 1.0 / CBIG;
sol->Y[k] = hyd->LinkFlows[k];
return;
}
// ... head loss formula is Darcy-Weisbach
if (hyd->Formflag == DW) {
DWpipecoeff(pr, k);
return;
}
// Evaluate headloss coefficients
q = ABS(hyd->LinkFlows[k]); // Absolute flow
ml = link->Km; // Minor loss coeff.
r = link->R; // Resistance coeff.
// Use large P coefficient for small flow resistance product
if ( (r+ml)*q < hyd->RQtol)
{
sol->P[k] = 1.0 / hyd->RQtol;
sol->Y[k] = hyd->LinkFlows[k] / hyd->Hexp;
return;
}
// Compute P and Y coefficients
hpipe = r*pow(q, hyd->Hexp); // Friction head loss
p = hyd->Hexp*hpipe; // Q*dh(friction)/dQ
if (ml > 0.0)
{
hml = ml*q*q; // Minor head loss
p += 2.0*hml; // Q*dh(Total)/dQ
}
else hml = 0.0;
p = hyd->LinkFlows[k] / p; // 1 / (dh/dQ)
sol->P[k] = ABS(p);
sol->Y[k] = p*(hpipe + hml);
}
void DWpipecoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes pipe head loss coeffs. for Darcy-Weisbach
** formula.
**--------------------------------------------------------------
*/
{
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
Slink *link = &pr->network.Link[k];
double q = ABS(hyd->LinkFlows[k]);
double dfdq = 0.0;
double r, r1, f, ml, p, hloss;
ml = link->Km; // Minor loss coeff.
r = link->R; // Resistance coeff.
f = frictionFactor(pr,k,&dfdq); // D-W friction factor
r1 = f*r+ml;
// Use large P coefficient for small flow resistance product
if (r1*q < hyd->RQtol)
{
sol->P[k] = 1.0/hyd->RQtol;
sol->Y[k] = hyd->LinkFlows[k]/hyd->Hexp;
return;
}
// Compute P and Y coefficients
hloss = r1*SQR(q); // Total head loss
p = 2.0*r1*q; // |dHloss/dQ|
// + dfdq*r*q*q; // Ignore df/dQ term
p = 1.0 / p;
sol->P[k] = p;
sol->Y[k] = SGN(hyd->LinkFlows[k]) * hloss * p;
}
double frictionFactor(EN_Project *pr, int k, double *dfdq)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: returns friction factor and
** replaces dfdq (derivative of f w.r.t. flow)
** Purpose: computes Darcy-Weisbach friction factor and its
** derivative as a function of Reynolds Number (Re).
**
** Note: Current formulas for dfdq need to be corrected
** so dfdq returned as 0.
**--------------------------------------------------------------
*/
{
double q, // Abs. value of flow
f; // Friction factor
double x1,x2,x3,x4,
y1,y2,y3,
fa,fb,r;
double s,w;
hydraulics_t *hyd = &pr->hydraulics;
Slink *link = &pr->network.Link[k];
*dfdq = 0.0;
if (link->Type > EN_PIPE)
return(1.0); // Only apply to pipes
q = ABS(hyd->LinkFlows[k]);
s = hyd->Viscos * link->Diam;
w = q/s; // w = Re(Pi/4)
// For Re >= 4000 use Colebrook Formula
if (w >= A1)
{
y1 = A8/pow(w,0.9);
y2 = link->Kc/(3.7*link->Diam) + y1;
y3 = A9*log(y2);
f = 1.0/SQR(y3);
/* *dfdq = (2.0+AA*y1/(y2*y3))*f; */ /* df/dq */
}
// For Re > 2000 use Interpolation Formula
else if (w > A2)
{
y2 = link->Kc/(3.7*link->Diam) + AB;
y3 = A9*log(y2);
fa = 1.0/SQR(y3);
fb = (2.0+AC/(y2*y3))*fa;
r = w/A2;
x1 = 7.0*fa - fb;
x2 = 0.128 - 17.0*fa + 2.5*fb;
x3 = -0.128 + 13.0*fa - (fb+fb);
x4 = r*(0.032 - 3.0*fa + 0.5*fb);
f = x1 + r*(x2 + r*(x3+x4));
/* *dfdq = (x1 + x1 + r*(3.0*x2 + r*(4.0*x3 + 5.0*x4))); */
}
// For Re > 8 (Laminar Flow) use Hagen-Poiseuille Formula
else if (w > A4)
{
f = A3*s/q; // 16 * PI * Viscos * Diam / Flow
/* *dfdq = A3*s; */
}
else
{
f = 8.0;
*dfdq = 0.0;
}
return(f);
}
void pumpcoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes P & Y coeffs. for pump in link k
**--------------------------------------------------------------
*/
{
int p; // Pump index
double h0, // Shutoff head
q, // Abs. value of flow
r, // Flow resistance coeff.
n; // Flow exponent coeff.
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
double setting = hyd->LinkSetting[k];
Spump *pump;
// Use high resistance pipe if pump closed or cannot deliver head
if (hyd->LinkStatus[k] <= CLOSED || setting == 0.0) {
sol->P[k] = 1.0 / CBIG;
sol->Y[k] = hyd->LinkFlows[k];
return;
}
q = ABS(hyd->LinkFlows[k]);
q = MAX(q, TINY);
// Obtain reference to pump object
p = findpump(&pr->network, k);
pump = &pr->network.Pump[p];
// Get pump curve coefficients for custom pump curve.
if (pump->Ptype == CUSTOM)
{
// Find intercept (h0) & slope (r) of pump curve
// line segment which contains speed-adjusted flow.
curvecoeff(pr, pump->Hcurve, q / setting, &h0, &r);
// Determine head loss coefficients.
pump->H0 = -h0;
pump->R = -r;
pump->N = 1.0;
}
// Adjust head loss coefficients for pump speed.
h0 = SQR(setting) * pump->H0;
n = pump->N;
r = pump->R * pow(setting, 2.0 - n);
if (n != 1.0) {
r = n * r * pow(q, n - 1.0);
}
// Compute inverse headloss gradient (P) and flow correction factor (Y)
sol->P[k] = 1.0 / MAX(r, hyd->RQtol);
sol->Y[k] = hyd->LinkFlows[k] / n + sol->P[k] * h0;
}
void curvecoeff(EN_Project *pr, int i, double q, double *h0, double *r)
/*
**-------------------------------------------------------------------
** Input: i = curve index
** q = flow rate
** Output: *h0 = head at zero flow (y-intercept)
** *r = dHead/dFlow (slope)
** Purpose: computes intercept and slope of head v. flow curve
** at current flow.
**-------------------------------------------------------------------
*/
{
int k1, k2, npts;
double *x, *y;
Scurve *curve;
// Remember that curve is stored in untransformed units
q *= pr->Ucf[FLOW];
curve = &pr->network.Curve[i];
x = curve->X; // x = flow
y = curve->Y; // y = head
npts = curve->Npts;
// Find linear segment of curve that brackets flow q
k2 = 0;
while (k2 < npts && x[k2] < q)
k2++;
if (k2 == 0)
k2++;
else if (k2 == npts)
k2--;
k1 = k2 - 1;
// Compute slope and intercept of this segment
*r = (y[k2] - y[k1]) / (x[k2] - x[k1]);
*h0 = y[k1] - (*r)*x[k1];
// Convert units
*h0 = (*h0) / pr->Ucf[HEAD];
*r = (*r) * pr->Ucf[FLOW] / pr->Ucf[HEAD];
}
void gpvcoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes P & Y coeffs. for general purpose valve
**--------------------------------------------------------------
*/
{
double h0, // Headloss curve intercept
q, // Abs. value of flow
r; // Flow resistance coeff.
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
// Treat as a pipe if valve closed
if (hyd->LinkStatus[k] == CLOSED) {
valvecoeff(pr, k);
}
// Otherwise utilize headloss curve
// whose index is stored in K
else {
// Find slope & intercept of headloss curve.
q = ABS(hyd->LinkFlows[k]);
q = MAX(q, TINY);
curvecoeff(pr, (int)ROUND(hyd->LinkSetting[k]), q, &h0, &r);
// Compute inverse headloss gradient (P)
// and flow correction factor (Y).
sol->P[k] = 1.0 / MAX(r, hyd->RQtol);
sol->Y[k] = sol->P[k] * (h0 + r*q) * SGN(hyd->LinkFlows[k]);
}
}
void pbvcoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes P & Y coeffs. for pressure breaker valve
**--------------------------------------------------------------
*/
{
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
Slink *link = &pr->network.Link[k];
// If valve fixed OPEN or CLOSED then treat as a pipe
if (hyd->LinkSetting[k] == MISSING || hyd->LinkSetting[k] == 0.0) {
valvecoeff(pr, k);
}
// If valve is active
else {
// Treat as a pipe if minor loss > valve setting
if (link->Km * SQR(hyd->LinkFlows[k]) > hyd->LinkSetting[k]) {
valvecoeff(pr, k);
}
// Otherwise force headloss across valve to be equal to setting
else {
sol->P[k] = CBIG;
sol->Y[k] = hyd->LinkSetting[k] * CBIG;
}
}
}
void tcvcoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes P & Y coeffs. for throttle control valve
**--------------------------------------------------------------
*/
{
double km;
hydraulics_t *hyd = &pr->hydraulics;
Slink *link = &pr->network.Link[k];
// Save original loss coeff. for open valve
km = link->Km;
// If valve not fixed OPEN or CLOSED, compute its loss coeff.
if (hyd->LinkSetting[k] != MISSING) {
link->Km = 0.02517 * hyd->LinkSetting[k] / (SQR(link->Diam)*SQR(link->Diam));
}
// Then apply usual valve formula
valvecoeff(pr, k);
// Restore original loss coeff.
link->Km = km;
}
void prvcoeff(EN_Project *pr, int k, int n1, int n2)
/*
**--------------------------------------------------------------
** Input: k = link index
** n1 = upstream node of valve
** n2 = downstream node of valve
** Output: none
** Purpose: computes solution matrix coeffs. for pressure
** reducing valves
**--------------------------------------------------------------
*/
{
int i, j; // Rows of solution matrix
double hset; // Valve head setting
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
i = sol->Row[n1]; // Matrix rows of nodes
j = sol->Row[n2];
hset = pr->network.Node[n2].El +
hyd->LinkSetting[k]; // Valve setting
if (hyd->LinkStatus[k] == ACTIVE)
{
// Set coeffs. to force head at downstream
// node equal to valve setting & force flow
// to equal to flow imbalance at downstream node.
sol->P[k] = 0.0;
sol->Y[k] = hyd->LinkFlows[k] + hyd->X_tmp[n2]; // Force flow balance
sol->F[j] += (hset * CBIG); // Force head = hset
sol->Aii[j] += CBIG; // at downstream node
if (hyd->X_tmp[n2] < 0.0) {
sol->F[i] += hyd->X_tmp[n2];
}
return;
}
// For OPEN, CLOSED, or XPRESSURE valve
// compute matrix coeffs. using the valvecoeff() function.
valvecoeff(pr, k);
sol->Aij[sol->Ndx[k]] -= sol->P[k];
sol->Aii[i] += sol->P[k];
sol->Aii[j] += sol->P[k];
sol->F[i] += (sol->Y[k] - hyd->LinkFlows[k]);
sol->F[j] -= (sol->Y[k] - hyd->LinkFlows[k]);
}
void psvcoeff(EN_Project *pr, int k, int n1, int n2)
/*
**--------------------------------------------------------------
** Input: k = link index
** n1 = upstream node of valve
** n2 = downstream node of valve
** Output: none
** Purpose: computes solution matrix coeffs. for pressure
** sustaining valve
**--------------------------------------------------------------
*/
{
int i, j; // Rows of solution matrix
double hset; // Valve head setting
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
i = sol->Row[n1]; // Matrix rows of nodes
j = sol->Row[n2];
hset = pr->network.Node[n1].El +
hyd->LinkSetting[k]; // Valve setting
if (hyd->LinkStatus[k] == ACTIVE)
{
// Set coeffs. to force head at upstream
// node equal to valve setting & force flow
// equal to flow imbalance at upstream node.
sol->P[k] = 0.0;
sol->Y[k] = hyd->LinkFlows[k] - hyd->X_tmp[n1]; // Force flow balance
sol->F[i] += (hset * CBIG); // Force head = hset
sol->Aii[i] += CBIG; // at upstream node
if (hyd->X_tmp[n1] > 0.0) {
sol->F[j] += hyd->X_tmp[n1];
}
return;
}
// For OPEN, CLOSED, or XPRESSURE valve
// compute matrix coeffs. using the valvecoeff() function.
valvecoeff(pr, k);
sol->Aij[sol->Ndx[k]] -= sol->P[k];
sol->Aii[i] += sol->P[k];
sol->Aii[j] += sol->P[k];
sol->F[i] += (sol->Y[k] - hyd->LinkFlows[k]);
sol->F[j] -= (sol->Y[k] - hyd->LinkFlows[k]);
}
void fcvcoeff(EN_Project *pr, int k, int n1, int n2)
/*
**--------------------------------------------------------------
** Input: k = link index
** n1 = upstream node of valve
** n2 = downstream node of valve
** Output: none
** Purpose: computes solution matrix coeffs. for flow control
** valve
**--------------------------------------------------------------
*/
{
int i, j; // Rows in solution matrix
double q; // Valve flow setting
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
q = hyd->LinkSetting[k];
i = hyd->solver.Row[n1];
j = hyd->solver.Row[n2];
// If valve active, break network at valve and treat
// flow setting as external demand at upstream node
// and external supply at downstream node.
if (hyd->LinkStatus[k] == ACTIVE)
{
hyd->X_tmp[n1] -= q;
sol->F[i] -= q;
hyd->X_tmp[n2] += q;
sol->F[j] += q;
sol->P[k] = 1.0 / CBIG;
sol->Aij[sol->Ndx[k]] -= sol->P[k];
sol->Aii[i] += sol->P[k];
sol->Aii[j] += sol->P[k];
sol->Y[k] = hyd->LinkFlows[k] - q;
}
// Otherwise treat valve as an open pipe
else
{
valvecoeff(pr, k);
sol->Aij[sol->Ndx[k]] -= sol->P[k];
sol->Aii[i] += sol->P[k];
sol->Aii[j] += sol->P[k];
sol->F[i] += (sol->Y[k] - hyd->LinkFlows[k]);
sol->F[j] -= (sol->Y[k] - hyd->LinkFlows[k]);
}
}
void valvecoeff(EN_Project *pr, int k)
/*
**--------------------------------------------------------------
** Input: k = link index
** Output: none
** Purpose: computes solution matrix coeffs. for a completely
** open, closed, or throttled control valve.
**--------------------------------------------------------------
*/
{
double p;
EN_Network *net = &pr->network;
hydraulics_t *hyd = &pr->hydraulics;
solver_t *sol = &hyd->solver;
Slink *link = &net->Link[k];
double flow = hyd->LinkFlows[k];
// Valve is closed. Use a very small matrix coeff.
if (hyd->LinkStatus[k] <= CLOSED)
{
sol->P[k] = 1.0 / CBIG;
sol->Y[k] = flow;
return;
}
// Account for any minor headloss through the valve
if (link->Km > 0.0)
{
p = 2.0 * link->Km * fabs(flow);
if (p < hyd->RQtol) {
p = hyd->RQtol;
}
sol->P[k] = 1.0 / p;
sol->Y[k] = flow / 2.0;
}
else
{
sol->P[k] = 1.0 / hyd->RQtol;
sol->Y[k] = flow;
}
}

File diff suppressed because it is too large Load Diff

1049
src/hydsolver.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -618,6 +618,12 @@ int saveinpfile(EN_Project *pr, char *fname)
fprintf(f, "\n CHECKFREQ %-d", hyd->CheckFreq); fprintf(f, "\n CHECKFREQ %-d", hyd->CheckFreq);
fprintf(f, "\n MAXCHECK %-d", hyd->MaxCheck); fprintf(f, "\n MAXCHECK %-d", hyd->MaxCheck);
fprintf(f, "\n DAMPLIMIT %-.8f", hyd->DampLimit); fprintf(f, "\n DAMPLIMIT %-.8f", hyd->DampLimit);
if (hyd->HeadErrorLimit > 0.0) {
fprintf(f, "\n HEADERROR %-.8f", hyd->HeadErrorLimit * pr->Ucf[HEAD]);
}
if (hyd->FlowChangeLimit > 0.0) {
fprintf(f, "\n FLOWCHANGE %-.8f", hyd->FlowChangeLimit * pr->Ucf[FLOW]);
}
/* Write [REPORT] section */ /* Write [REPORT] section */

View File

@@ -40,10 +40,9 @@ AUTHOR: L. Rossman
--------------------- Module Global Variables ---------------------- --------------------- Module Global Variables ----------------------
*/ */
#define MAXITER \ #define MAXITER 200 /* Default max. # hydraulic iterations */
200 /* Default max. # hydraulic iterations */ #define HACC 0.001 /* Default hydraulics convergence ratio */
#define HACC 0.001 /* Default hydraulics convergence ratio */ #define HTOL 0.0005 /* Default hydraulic head tolerance (ft) */
#define HTOL 0.0005 /* Default hydraulic head tolerance (ft) */
/*** Updated 11/19/01 ***/ /*** Updated 11/19/01 ***/
#define QTOL 0.0001 /* Default flow rate tolerance (cfs) */ #define QTOL 0.0001 /* Default flow rate tolerance (cfs) */
@@ -62,8 +61,7 @@ AUTHOR: L. Rossman
#define RQTOL 1E-7 /* Default low flow resistance tolerance */ #define RQTOL 1E-7 /* Default low flow resistance tolerance */
#define CHECKFREQ 2 /* Default status check frequency */ #define CHECKFREQ 2 /* Default status check frequency */
#define MAXCHECK 10 /* Default # iterations for status checks */ #define MAXCHECK 10 /* Default # iterations for status checks */
#define DAMPLIMIT \ #define DAMPLIMIT 0 /* Default damping threshold */
0 /* Default damping threshold */
extern char *Fldname[]; /* Defined in enumstxt.h in EPANET.C */ extern char *Fldname[]; /* Defined in enumstxt.h in EPANET.C */
extern char *RptFlowUnitsTxt[]; extern char *RptFlowUnitsTxt[];
@@ -119,19 +117,23 @@ void setdefaults(EN_Project *pr)
strncpy(qu->ChemUnits, u_MGperL, MAXID); strncpy(qu->ChemUnits, u_MGperL, MAXID);
strncpy(par->DefPatID, DEFPATID, MAXID); strncpy(par->DefPatID, DEFPATID, MAXID);
out->Hydflag = SCRATCH; /* No external hydraulics file */ out->Hydflag = SCRATCH; /* No external hydraulics file */
qu->Qualflag = NONE; /* No quality simulation */ qu->Qualflag = NONE; /* No quality simulation */
hyd->Formflag = HW; /* Use Hazen-Williams formula */ hyd->Formflag = HW; /* Use Hazen-Williams formula */
par->Unitsflag = US; /* US unit system */ par->Unitsflag = US; /* US unit system */
par->Flowflag = GPM; /* Flow units are gpm */ par->Flowflag = GPM; /* Flow units are gpm */
par->Pressflag = PSI; /* Pressure units are psi */ par->Pressflag = PSI; /* Pressure units are psi */
rep->Tstatflag = SERIES; /* Generate time series output */ rep->Tstatflag = SERIES; /* Generate time series output */
pr->Warnflag = FALSE; /* Warning flag is off */ pr->Warnflag = FALSE; /* Warning flag is off */
hyd->Htol = HTOL; /* Default head tolerance */ hyd->Htol = HTOL; /* Default head tolerance */
hyd->Qtol = QTOL; /* Default flow tolerance */ hyd->Qtol = QTOL; /* Default flow tolerance */
hyd->Hacc = HACC; /* Default hydraulic accuracy */ hyd->Hacc = HACC; /* Default hydraulic accuracy */
hyd->FlowChangeLimit = 0.0; /* Default flow change limit */
hyd->HeadErrorLimit = 0.0; /* Default head error limit */
qu->Ctol = MISSING; /* No pre-set quality tolerance */ qu->Ctol = MISSING; /* No pre-set quality tolerance */
hyd->MaxIter = MAXITER; /* Default max. hydraulic trials */ hyd->MaxIter = MAXITER; /* Default max. hydraulic trials */
hyd->ExtraIter = -1; /* Stop if network unbalanced */ hyd->ExtraIter = -1; /* Stop if network unbalanced */
time->Dur = 0; /* 0 sec duration (steady state) */ time->Dur = 0; /* 0 sec duration (steady state) */
time->Tstart = 0; /* Starting time of day */ time->Tstart = 0; /* Starting time of day */
time->Pstart = 0; /* Starting pattern period */ time->Pstart = 0; /* Starting pattern period */
@@ -531,8 +533,8 @@ void initunits(EN_Project *pr)
pr->Ucf[POWER] = wcf; pr->Ucf[POWER] = wcf;
pr->Ucf[VOLUME] = hcf * hcf * hcf; pr->Ucf[VOLUME] = hcf * hcf * hcf;
if (time->Hstep < 1800) /* Report time in mins. */ if (time->Hstep < 1800) /* Report time in mins. */
{ /* if hydraulic time step */ { /* if hydraulic time step */
pr->Ucf[TIME] = 1.0 / 60.0; /* is less than 1/2 hour. */ pr->Ucf[TIME] = 1.0 / 60.0; /* is less than 1/2 hour. */
strcpy(rep->Field[TIME].Units, u_MINUTES); strcpy(rep->Field[TIME].Units, u_MINUTES);
} else { } else {
pr->Ucf[TIME] = 1.0 / 3600.0; pr->Ucf[TIME] = 1.0 / 3600.0;
@@ -606,6 +608,10 @@ void convertunits(EN_Project *pr)
tank->V1max *= tank->Vmax; tank->V1max *= tank->Vmax;
} }
/* Convert hydraulic convergence criteria */
hyd->FlowChangeLimit /= pr->Ucf[FLOW];
hyd->HeadErrorLimit /= pr->Ucf[HEAD];
/* Convert WQ option concentration units */ /* Convert WQ option concentration units */
qu->Climit /= pr->Ucf[QUALITY]; qu->Climit /= pr->Ucf[QUALITY];
qu->Ctol /= pr->Ucf[QUALITY]; qu->Ctol /= pr->Ucf[QUALITY];
@@ -678,8 +684,9 @@ void convertunits(EN_Project *pr)
} }
////// Moved to inithyd() in hydraul.c ///////
/* Compute flow resistances */ /* Compute flow resistances */
resistance(pr, k); //resistance(pr, k);
} }
/* Convert units on control settings */ /* Convert units on control settings */

View File

@@ -112,7 +112,7 @@ int juncdata(EN_Project *pr)
} }
demand->Base = y; demand->Base = y;
demand->Pat = p; demand->Pat = p;
demand->next = node->D; demand->next = NULL;
node->D = demand; node->D = demand;
hyd->NodeDemand[Njuncs] = y; hyd->NodeDemand[Njuncs] = y;
@@ -737,6 +737,7 @@ int demanddata(EN_Project *pr)
int j, n, p = 0; int j, n, p = 0;
double y; double y;
Pdemand demand; Pdemand demand;
Pdemand cur_demand;
STmplist *pat; STmplist *pat;
/* Extract data from tokens */ /* Extract data from tokens */
@@ -778,13 +779,17 @@ int demanddata(EN_Project *pr)
hyd->NodeDemand[j] = MISSING; // marker - next iteration will append a new category. hyd->NodeDemand[j] = MISSING; // marker - next iteration will append a new category.
} }
else { // add new demand to junction else { // add new demand to junction
cur_demand = net->Node[j].D;
while (cur_demand->next != NULL) {
cur_demand = cur_demand->next;
}
demand = (struct Sdemand *)malloc(sizeof(struct Sdemand)); demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
if (demand == NULL) if (demand == NULL)
return (101); return (101);
demand->Base = y; demand->Base = y;
demand->Pat = p; demand->Pat = p;
demand->next = net->Node[j].D; demand->next = NULL;
net->Node[j].D = demand; cur_demand->next = demand;
} }
return (0); return (0);
} /* end of demanddata */ } /* end of demanddata */
@@ -1908,6 +1913,10 @@ int optionvalue(EN_Project *pr, int n)
** SPECIFIC GRAVITY value ** SPECIFIC GRAVITY value
** TRIALS value ** TRIALS value
** ACCURACY value ** ACCURACY value
** HEADLIMIT value
** FLOWLIMIT value
** TOLERANCE value ** TOLERANCE value
** SEGMENTS value (not used) ** SEGMENTS value (not used)
** ------ Undocumented Options ----- ** ------ Undocumented Options -----
@@ -1923,18 +1932,20 @@ int optionvalue(EN_Project *pr, int n)
hydraulics_t *hyd = &pr->hydraulics; hydraulics_t *hyd = &pr->hydraulics;
quality_t *qu = &pr->quality; quality_t *qu = &pr->quality;
parser_data_t *par = &pr->parser; parser_data_t *par = &pr->parser;
char* tok0 = par->Tok[0];
int nvalue = 1; /* Index of token with numerical value */ int nvalue = 1; /* Index of token with numerical value */
double y; double y;
/* Check for obsolete SEGMENTS keyword */ /* Check for obsolete SEGMENTS keyword */
if (match(par->Tok[0], w_SEGMENTS)) //if (match(par->Tok[0], w_SEGMENTS))
return (0); if (match(tok0, w_SEGMENTS))
return (0);
/* Check for missing value (which is permissible) */ /* Check for missing value (which is permissible) */
if (match(par->Tok[0], w_SPECGRAV) || match(par->Tok[0], w_EMITTER) || if (match(tok0, w_SPECGRAV) || match(tok0, w_EMITTER) ||
match(par->Tok[0], w_DEMAND)) match(tok0, w_DEMAND))
nvalue = 2; nvalue = 2;
if (n < nvalue) if (n < nvalue)
return (0); return (0);
@@ -1944,7 +1955,7 @@ int optionvalue(EN_Project *pr, int n)
return (213); return (213);
/* Check for WQ tolerance option (which can be 0) */ /* Check for WQ tolerance option (which can be 0) */
if (match(par->Tok[0], w_TOLERANCE)) { if (match(tok0, w_TOLERANCE)) {
if (y < 0.0) if (y < 0.0)
return (213); return (213);
qu->Ctol = y; /* Quality tolerance*/ qu->Ctol = y; /* Quality tolerance*/
@@ -1952,7 +1963,7 @@ int optionvalue(EN_Project *pr, int n)
} }
/* Check for Diffusivity option */ /* Check for Diffusivity option */
if (match(par->Tok[0], w_DIFFUSIVITY)) { if (match(tok0, w_DIFFUSIVITY)) {
if (y < 0.0) if (y < 0.0)
return (213); return (213);
qu->Diffus = y; qu->Diffus = y;
@@ -1960,42 +1971,59 @@ int optionvalue(EN_Project *pr, int n)
} }
/* Check for Damping Limit option */ /* Check for Damping Limit option */
if (match(par->Tok[0], w_DAMPLIMIT)) { if (match(tok0, w_DAMPLIMIT)) {
hyd->DampLimit = y; hyd->DampLimit = y;
return (0); return (0);
} }
/* Check for flow change limit*/
else if (match(tok0, w_FLOWCHANGE))
{
if (y < 0.0) return 213;
hyd->FlowChangeLimit = y;
return 0;
}
/* Check for head error limit*/
else if (match(tok0, w_HEADERROR))
{
if (y < 0.0) return 213;
hyd->HeadErrorLimit = y;
return 0;
}
/* All other options must be > 0 */ /* All other options must be > 0 */
if (y <= 0.0) if (y <= 0.0)
return (213); return (213);
/* Assign value to specified option */ /* Assign value to specified option */
if (match(par->Tok[0], w_VISCOSITY)) if (match(tok0, w_VISCOSITY))
hyd->Viscos = y; /* Viscosity */ hyd->Viscos = y; /* Viscosity */
else if (match(par->Tok[0], w_SPECGRAV)) else if (match(tok0, w_SPECGRAV))
hyd->SpGrav = y; /* Spec. gravity */ hyd->SpGrav = y; /* Spec. gravity */
else if (match(par->Tok[0], w_TRIALS)) else if (match(tok0, w_TRIALS))
hyd->MaxIter = (int)y; /* Max. trials */ hyd->MaxIter = (int)y; /* Max. trials */
else if (match(par->Tok[0], w_ACCURACY)) /* Accuracy */ else if (match(tok0, w_ACCURACY)) /* Accuracy */
{ {
y = MAX(y, 1.e-5); y = MAX(y, 1.e-5);
y = MIN(y, 1.e-1); y = MIN(y, 1.e-1);
hyd->Hacc = y; hyd->Hacc = y;
} else if (match(par->Tok[0], w_HTOL)) }
else if (match(tok0, w_HTOL))
hyd->Htol = y; hyd->Htol = y;
else if (match(par->Tok[0], w_QTOL)) else if (match(tok0, w_QTOL))
hyd->Qtol = y; hyd->Qtol = y;
else if (match(par->Tok[0], w_RQTOL)) { else if (match(tok0, w_RQTOL)) {
if (y >= 1.0) if (y >= 1.0)
return (213); return (213);
hyd->RQtol = y; hyd->RQtol = y;
} else if (match(par->Tok[0], w_CHECKFREQ)) } else if (match(tok0, w_CHECKFREQ))
hyd->CheckFreq = (int)y; hyd->CheckFreq = (int)y;
else if (match(par->Tok[0], w_MAXCHECK)) else if (match(tok0, w_MAXCHECK))
hyd->MaxCheck = (int)y; hyd->MaxCheck = (int)y;
else if (match(par->Tok[0], w_EMITTER)) else if (match(tok0, w_EMITTER))
hyd->Qexp = 1.0 / y; hyd->Qexp = 1.0 / y;
else if (match(par->Tok[0], w_DEMAND)) else if (match(tok0, w_DEMAND))
hyd->Dmult = y; hyd->Dmult = y;
else else
return (201); return (201);

View File

@@ -70,7 +70,8 @@ int savenetdata(EN_Project *pr)
ibuf[0] = MAGICNUMBER; ibuf[0] = MAGICNUMBER;
/*** CODEVERSION replaces VERSION ***/ /*** CODEVERSION replaces VERSION ***/
ibuf[1] = CODEVERSION; //ibuf[1] = CODEVERSION;
ibuf[1] = 20012; // keep version at 2.00.12 so that GUI will run
ibuf[2] = net->Nnodes; ibuf[2] = net->Nnodes;
ibuf[3] = net->Ntanks; ibuf[3] = net->Ntanks;
@@ -251,60 +252,75 @@ int saveenergy(EN_Project *pr)
*/ */
{ {
EN_Network *net = &pr->network; EN_Network *net = &pr->network;
hydraulics_t *hyd = &pr->hydraulics; hydraulics_t *hyd = &pr->hydraulics;
out_file_t *out = &pr->out_files; out_file_t *out = &pr->out_files;
parser_data_t *par = &pr->parser; parser_data_t *par = &pr->parser;
time_options_t *time = &pr->time_options; time_options_t *time = &pr->time_options;
FILE *outFile = out->OutFile; FILE *outFile = out->OutFile;
Spump *pump;
int i, j; int i, j;
INT4 index; INT4 index;
REAL4 x[6]; /* work array */ REAL4 x[MAX_ENERGY_STATS]; // work array
double hdur, /* total time->Duration in hours */ double hdur, // total simulation duration in hours
t; /* pumping time->Duration */ t; // total pumping time duration
hdur = time->Dur / 3600.0; hdur = time->Dur / 3600.0;
for (i = 1; i <= net->Npumps; i++) { for (i = 1; i <= net->Npumps; i++) {
Spump *pump = &net->Pump[i]; pump = &net->Pump[i];
if (hdur == 0.0) { if (hdur == 0.0) {
for (j = 0; j < 5; j++) pump->Energy[TOTAL_COST] *= 24.0;
x[j] = (REAL4)pump->Energy[j];
x[5] = (REAL4)(pump->Energy[5] * 24.0);
} else {
t = pump->Energy[0];
x[0] = (REAL4)(t / hdur);
x[1] = 0.0f;
x[2] = 0.0f;
x[3] = 0.0f;
x[4] = 0.0f;
if (t > 0.0) {
x[1] = (REAL4)(pump->Energy[1] / t);
x[2] = (REAL4)(pump->Energy[2] / t);
x[3] = (REAL4)(pump->Energy[3] / t);
}
x[4] = (REAL4)pump->Energy[4];
x[5] = (REAL4)(pump->Energy[5] * 24.0 / hdur);
} }
x[0] *= 100.0f; else {
x[1] *= 100.0f; // ... convert total hrs. online to fraction of total time online
/* Compute Kw-hr per MilGal (or per cubic meter) */ t = pump->Energy[PCNT_ONLINE]; //currently holds total hrs. online
if (par->Unitsflag == SI) pump->Energy[PCNT_ONLINE] = t / hdur;
x[2] *= (REAL4)(1000.0 / LPSperCFS / 3600.0);
else // ... convert cumulative values to time-averaged ones
x[2] *= (REAL4)(1.0e6 / GPMperCFS / 60.0); if (t > 0.0) {
for (j = 0; j < 6; j++) pump->Energy[PCNT_EFFIC] /= t;
pump->Energy[j] = x[j]; pump->Energy[KWH_PER_FLOW] /= t;
pump->Energy[TOTAL_KWH] /= t;
}
// ... convert total cost to cost per day
pump->Energy[TOTAL_COST] *= 24.0 / hdur;
}
// ... express time online and avg. efficiency as percentages
pump->Energy[PCNT_ONLINE] *= 100.0;
pump->Energy[PCNT_EFFIC] *= 100.0;
// ... compute KWH per Million Gallons or per Cubic Meter
if (par->Unitsflag == SI) {
pump->Energy[KWH_PER_FLOW] *= (1000. / LPSperCFS / 3600.);
}
else {
pump->Energy[KWH_PER_FLOW] *= (1.0e6 / GPMperCFS / 60.);
}
// ... save energy stats to REAL4 work array
for (j = 0; j < MAX_ENERGY_STATS; j++) {
x[j] = (REAL4)pump->Energy[j];
}
// ... save energy results to output file
index = pump->Link; index = pump->Link;
if (fwrite(&index, sizeof(INT4), 1, outFile) < 1) if (fwrite(&index, sizeof(INT4), 1, outFile) < 1) {
return (308); return (308);
if (fwrite(x, sizeof(REAL4), 6, outFile) < 6) }
if (fwrite(x, sizeof(REAL4), MAX_ENERGY_STATS, outFile) < MAX_ENERGY_STATS) {
return (308); return (308);
}
} }
// ... compute and save demand charge
hyd->Emax = hyd->Emax * hyd->Dcost; hyd->Emax = hyd->Emax * hyd->Dcost;
x[0] = (REAL4)hyd->Emax; x[0] = (REAL4)hyd->Emax;
if (fwrite(&x[0], sizeof(REAL4), 1, outFile) < 1) if (fwrite(&x[0], sizeof(REAL4), 1, outFile) < 1) {
return (308); return (308);
}
return (0); return (0);
} }

View File

@@ -161,6 +161,9 @@ void initqual(EN_Project *pr)
net->Node[i].S->Smass = 0.0; net->Node[i].S->Smass = 0.0;
} }
qu->QTempVolumes =
calloc(net->Ntanks,
sizeof(double)); // keep track of next tank volumes.
qu->QTankVolumes = qu->QTankVolumes =
calloc(net->Ntanks, calloc(net->Ntanks,
sizeof(double)); // keep track of previous step's tank volumes. sizeof(double)); // keep track of previous step's tank volumes.
@@ -287,7 +290,7 @@ int nextqual(EN_Project *pr, long *tstep)
{ {
long hydstep; /* Hydraulic solution time step */ long hydstep; /* Hydraulic solution time step */
int errcode = 0; int errcode = 0;
double *tankVolumes; //double *tankVolumes = NULL;
int i; int i;
EN_Network *net; EN_Network *net;
hydraulics_t *hyd; hydraulics_t *hyd;
@@ -315,10 +318,10 @@ int nextqual(EN_Project *pr, long *tstep)
// if we're operating in stepwise mode, capture the tank levels so we can // if we're operating in stepwise mode, capture the tank levels so we can
// restore them later. // restore them later.
if (hyd->OpenHflag) { if (hyd->OpenHflag) {
tankVolumes = calloc(net->Ntanks, sizeof(double)); //tankVolumes = calloc(net->Ntanks, sizeof(double));
for (i = 1; i <= net->Ntanks; ++i) { for (i = 1; i <= net->Ntanks; ++i) {
if (net->Tank[i].A != 0) { // skip reservoirs if (net->Tank[i].A != 0) { // skip reservoirs
tankVolumes[i - 1] = net->Tank[i].V; qu->QTempVolumes[i - 1] = net->Tank[i].V;
} }
} }
@@ -359,7 +362,7 @@ int nextqual(EN_Project *pr, long *tstep)
for (i = 1; i <= net->Ntanks; i++) { for (i = 1; i <= net->Ntanks; i++) {
if (net->Tank[i].A != 0) { // skip reservoirs again if (net->Tank[i].A != 0) { // skip reservoirs again
int n = net->Tank[i].Node; int n = net->Tank[i].Node;
net->Tank[i].V = tankVolumes[i - 1]; net->Tank[i].V = qu->QTempVolumes[i - 1];
hyd->NodeHead[n] = tankgrade(pr, i, net->Tank[i].V); hyd->NodeHead[n] = tankgrade(pr, i, net->Tank[i].V);
} }
} }
@@ -370,7 +373,7 @@ int nextqual(EN_Project *pr, long *tstep)
} }
} }
free(tankVolumes); //free(tankVolumes);
} }
return (errcode); return (errcode);
@@ -448,6 +451,7 @@ int closequal(EN_Project *pr)
free(qu->MassIn); free(qu->MassIn);
free(qu->PipeRateCoeff); free(qu->PipeRateCoeff);
free(qu->TempQual); free(qu->TempQual);
free(qu->QTempVolumes);
free(qu->QTankVolumes); free(qu->QTankVolumes);
free(qu->QLinkFlow); free(qu->QLinkFlow);
return (errcode); return (errcode);

View File

@@ -229,6 +229,15 @@ void writesummary(EN_Project *pr)
sprintf(s, FMT27, hyd->Hacc); sprintf(s, FMT27, hyd->Hacc);
writeline(pr, s); writeline(pr, s);
if (hyd->HeadErrorLimit > 0.0) {
sprintf(s, FMT27d, hyd->HeadErrorLimit*pr->Ucf[HEAD], rep->Field[HEAD].Units);
writeline(pr, s);
}
if (hyd->FlowChangeLimit > 0.0) {
sprintf(s, FMT27e, hyd->FlowChangeLimit*pr->Ucf[FLOW], rep->Field[FLOW].Units);
writeline(pr, s);
}
sprintf(s, FMT27a, hyd->CheckFreq); sprintf(s, FMT27a, hyd->CheckFreq);
writeline(pr, s); writeline(pr, s);
sprintf(s, FMT27b, hyd->MaxCheck); sprintf(s, FMT27b, hyd->MaxCheck);
@@ -378,6 +387,7 @@ void writeenergy(EN_Project *pr)
EN_Network *net = &pr->network; EN_Network *net = &pr->network;
hydraulics_t *hyd = &pr->hydraulics; hydraulics_t *hyd = &pr->hydraulics;
report_options_t *rep = &pr->report; report_options_t *rep = &pr->report;
Spump *pump;
int j; int j;
double csum; double csum;
@@ -388,14 +398,14 @@ void writeenergy(EN_Project *pr)
writeheader(pr,ENERHDR, 0); writeheader(pr,ENERHDR, 0);
csum = 0.0; csum = 0.0;
for (j = 1; j <= net->Npumps; j++) { for (j = 1; j <= net->Npumps; j++) {
Spump *pump = &net->Pump[j]; pump = &net->Pump[j];
csum += pump->Energy[5]; csum += pump->Energy[TOTAL_COST];
if (rep->LineNum == (long)rep->PageSize) if (rep->LineNum == (long)rep->PageSize)
writeheader(pr, ENERHDR, 1); writeheader(pr, ENERHDR, 1);
sprintf(s, "%-8s %6.2f %6.2f %9.2f %9.2f %9.2f %9.2f", sprintf(s, "%-8s %6.2f %6.2f %9.2f %9.2f %9.2f %9.2f",
net->Link[pump->Link].ID, pump->Energy[0], pump->Energy[1], net->Link[pump->Link].ID, pump->Energy[PCNT_ONLINE], pump->Energy[PCNT_EFFIC],
pump->Energy[2], pump->Energy[3], pump->Energy[4], pump->Energy[KWH_PER_FLOW], pump->Energy[TOTAL_KWH], pump->Energy[MAX_KW],
pump->Energy[5]); pump->Energy[TOTAL_COST]);
writeline(pr, s); writeline(pr, s);
} }
fillstr(s, '-', 63); fillstr(s, '-', 63);

View File

@@ -142,6 +142,9 @@ AUTHOR: L. Rossman
#define w_MAXCHECK "MAXCHECK" #define w_MAXCHECK "MAXCHECK"
#define w_DAMPLIMIT "DAMPLIMIT" #define w_DAMPLIMIT "DAMPLIMIT"
#define w_FLOWCHANGE "FLOWCHANGE"
#define w_HEADERROR "HEADERROR"
#define w_SECONDS "SEC" #define w_SECONDS "SEC"
#define w_MINUTES "MIN" #define w_MINUTES "MIN"
#define w_HOURS "HOU" #define w_HOURS "HOU"
@@ -366,6 +369,9 @@ AUTHOR: L. Rossman
#define FMT27b " Maximum Trials Checked ............ %-d" #define FMT27b " Maximum Trials Checked ............ %-d"
#define FMT27c " Damping Limit Threshold ........... %-.6f" #define FMT27c " Damping Limit Threshold ........... %-.6f"
#define FMT27d " Headloss Error Limit .............. %-.6f %s"
#define FMT27e " Flow Change Limit ................. %-.6f %s"
#define FMT28 " Maximum Trials .................... %-d" #define FMT28 " Maximum Trials .................... %-d"
#define FMT29 " Quality Analysis .................. None" #define FMT29 " Quality Analysis .................. None"
#define FMT30 " Quality Analysis .................. %s" #define FMT30 " Quality Analysis .................. %s"
@@ -409,10 +415,13 @@ AUTHOR: L. Rossman
#define FMT61 "%10s: Valve %s caused ill-conditioning" #define FMT61 "%10s: Valve %s caused ill-conditioning"
#define FMT62 "%10s: System ill-conditioned at node %s" #define FMT62 "%10s: System ill-conditioned at node %s"
#define FMT63 "%10s: %s %s changed by rule %s" #define FMT63 "%10s: %s %s changed by rule %s"
#define FMT64 "%10s: Balancing the network:" #define FMT64 "%10s: Balancing the network:\n"
#define FMT65 " Trial %2d: relative flow change = %-.6f" #define FMT65 " Trial %2d: relative flow change = %-.6f"
/*** End of update ***/ /*** End of update ***/
#define FMT66 " maximum flow change = %.4f for Link %s"
#define FMT67 " maximum head error = %.4f for Link %s\n"
/* -------------------- Energy Report Table ------------------- */ /* -------------------- Energy Report Table ------------------- */
#define FMT71 "Energy Usage:" #define FMT71 "Energy Usage:"
#define FMT72 \ #define FMT72 \

View File

@@ -47,7 +47,7 @@ typedef int INT4;
#define EOFMARK 0x1A /* Use 0x04 for UNIX systems */ #define EOFMARK 0x1A /* Use 0x04 for UNIX systems */
#define MAXTITLE 3 /* Max. # title lines */ #define MAXTITLE 3 /* Max. # title lines */
#define MAXID 31 /* Max. # characters in ID name */ #define MAXID 31 /* Max. # characters in ID name */
#define MAXMSG 79 /* Max. # characters in message text */ #define MAXMSG 79 /* Max. # characters in message text */
#define MAXLINE 255 /* Max. # characters read from input line */ #define MAXLINE 255 /* Max. # characters read from input line */
#define MAXFNAME 259 /* Max. # characters in file name */ #define MAXFNAME 259 /* Max. # characters in file name */
#define MAXTOKS 40 /* Max. items per line of input */ #define MAXTOKS 40 /* Max. items per line of input */
@@ -59,6 +59,9 @@ typedef int INT4;
#define TINY 1.E-6 #define TINY 1.E-6
#define MISSING -1.E10 #define MISSING -1.E10
#define CBIG 1.e8 /* Big coefficient */
#define CSMALL 1.e-6 /* Small coefficient */
#ifdef M_PI #ifdef M_PI
#define PI M_PI #define PI M_PI
#else #else
@@ -135,21 +138,21 @@ typedef enum {
USE, /* use from previous run */ USE, /* use from previous run */
SAVE, /* save after current run */ SAVE, /* save after current run */
SCRATCH SCRATCH
} Hydtype; /* use temporary file */ } Hydtype; /* use temporary file */
typedef enum { typedef enum {
NONE, /* no quality analysis */ NONE, /* no quality analysis */
CHEM, /* analyze a chemical */ CHEM, /* analyze a chemical */
AGE, /* analyze water age */ AGE, /* analyze water age */
TRACE TRACE
} QualType; /* trace % of flow from a source */ } QualType; /* trace % of flow from a source */
typedef enum { typedef enum {
V_CURVE, /* volume curve */ V_CURVE, /* volume curve */
P_CURVE, /* pump curve */ P_CURVE, /* pump curve */
E_CURVE, /* efficiency curve */ E_CURVE, /* efficiency curve */
H_CURVE H_CURVE
} CurveType; /* head loss curve */ } CurveType; /* head loss curve */
typedef enum { typedef enum {
CONST_HP, /* constant horsepower */ CONST_HP, /* constant horsepower */
@@ -169,8 +172,8 @@ typedef enum {
LOWLEVEL, /* act when grade below set level */ LOWLEVEL, /* act when grade below set level */
HILEVEL, /* act when grade above set level */ HILEVEL, /* act when grade above set level */
TIMER, /* act when set time reached */ TIMER, /* act when set time reached */
TIMEOFDAY TIMEOFDAY /* act when time of day occurs */
} ControlType; /* act when time of day occurs */ } ControlType;
typedef enum { typedef enum {
XHEAD, /* pump cannot deliver head (closed) */ XHEAD, /* pump cannot deliver head (closed) */
@@ -183,18 +186,18 @@ typedef enum {
XPRESSURE, /* valve cannot supply pressure */ XPRESSURE, /* valve cannot supply pressure */
FILLING, /* tank filling */ FILLING, /* tank filling */
EMPTYING EMPTYING
} StatType; /* tank emptying */ } StatType; /* tank emptying */
typedef enum { typedef enum {
HW, /* Hazen-Williams */ HW, /* Hazen-Williams */
DW, /* Darcy-Weisbach */ DW, /* Darcy-Weisbach */
CM CM /* Chezy-Manning */
} FormType; /* Chezy-Manning */ } FormType;
typedef enum { typedef enum {
US, /* US */ US, /* US */
SI SI /* SI (metric) */
} UnitsType; /* SI (metric) */ } UnitsType;
typedef enum { typedef enum {
CFS, /* cubic feet per second */ CFS, /* cubic feet per second */
@@ -206,40 +209,41 @@ typedef enum {
LPM, /* liters per minute */ LPM, /* liters per minute */
MLD, /* megaliters per day */ MLD, /* megaliters per day */
CMH, /* cubic meters per hour */ CMH, /* cubic meters per hour */
CMD CMD /* cubic meters per day */
} FlowUnitsType; /* cubic meters per day */ } FlowUnitsType;
typedef enum { typedef enum {
PSI, /* pounds per square inch */ PSI, /* pounds per square inch */
KPA, /* kiloPascals */ KPA, /* kiloPascals */
METERS METERS /* meters */
} PressUnitsType; /* meters */
} PressUnitsType;
typedef enum { typedef enum {
LOW, /* lower limit */ LOW, /* lower limit */
HI, /* upper limit */ HI, /* upper limit */
PREC PREC /* precision */
} RangeType; /* precision */
} RangeType;
typedef enum { typedef enum {
MIX1, /* 1-compartment model */ MIX1, /* 1-compartment model */
MIX2, /* 2-compartment model */ MIX2, /* 2-compartment model */
FIFO, /* First in, first out model */ FIFO, /* First in, first out model */
LIFO LIFO /* Last in, first out model */
} MixType; /* Last in, first out model */ } MixType;
typedef enum { typedef enum {
SERIES, /* none */ SERIES, /* none */
AVG, /* time-averages */ AVG, /* time-averages */
MIN, /* minimum values */ MIN, /* minimum values */
MAX, /* maximum values */ MAX, /* maximum values */
RANGE RANGE /* max - min values */
} TstatType; /* max - min values */ } TstatType;
#define MAXVAR 21 /* Max. # types of network variables */
/* (equals # items enumed below) */ #define MAXVAR 21 /* Max. # types of network variables */
/* (equals # items enumed below) */
typedef enum { typedef enum {
ELEV = 0, /* nodal elevation */ ELEV = 0, /* nodal elevation */
DEMAND, /* nodal demand flow */ DEMAND, /* nodal demand flow */
HEAD, /* nodal hydraulic head */ HEAD, /* nodal hydraulic head */
PRESSURE, /* nodal pressure */ PRESSURE, /* nodal pressure */
@@ -273,17 +277,27 @@ typedef enum {
} SectType; } SectType;
typedef enum { typedef enum {
STATHDR, /* Hydraulic Status */ STATHDR, /* Hydraulic Status header */
ENERHDR, /* Energy Usage */ ENERHDR, /* Energy Usage header */
NODEHDR, /* Node Results */ NODEHDR, /* Node Results header */
LINKHDR LINKHDR /* Link Results header */
} HdrType; /* Link Results */ } HdrType;
typedef enum { typedef enum {
POSITIVE, POSITIVE,
NEGATIVE NEGATIVE
} FlowDirection; } FlowDirection;
typedef enum {
PCNT_ONLINE,
PCNT_EFFIC,
KWH_PER_FLOW,
TOTAL_KWH,
MAX_KW,
TOTAL_COST,
MAX_ENERGY_STATS
} EnergyStats;
/* /*
------------------------------------------------------ ------------------------------------------------------
Global Data Structures Global Data Structures
@@ -344,6 +358,16 @@ struct Sdemand /* DEMAND CATEGORY OBJECT */
}; };
typedef struct Sdemand *Pdemand; /* Pointer to demand object */ typedef struct Sdemand *Pdemand; /* Pointer to demand object */
typedef struct
{
double hrsOnLine; // hours pump is online
double efficiency; // total time wtd. efficiency
double kwHrsPerCFS; // total kw-hrs per cfs of flow
double kwHrs; // total kw-hrs consumed
double maxKwatts; // max. kw consumed
double totalCost; // total pumping cost
} Senergy;
struct Ssource /* WQ SOURCE OBJECT */ struct Ssource /* WQ SOURCE OBJECT */
{ {
/*int Node;*/ /* Node index of source */ /*int Node;*/ /* Node index of source */
@@ -422,13 +446,7 @@ typedef struct /* PUMP OBJECT */
int Upat; /* Utilization pattern index */ int Upat; /* Utilization pattern index */
int Epat; /* Energy cost pattern index */ int Epat; /* Energy cost pattern index */
double Ecost; /* Unit energy cost */ double Ecost; /* Unit energy cost */
double Energy[6]; /* Energy usage statistics: */ double Energy[MAX_ENERGY_STATS]; /* Energy usage statistics */
/* 0 = pump utilization */
/* 1 = avg. efficiency */
/* 2 = avg. kW/flow */
/* 3 = avg. kwatts */
/* 4 = peak kwatts */
/* 5 = cost/day */
} Spump; } Spump;
typedef struct /* VALVE OBJECT */ typedef struct /* VALVE OBJECT */
@@ -474,7 +492,7 @@ typedef struct /* FIELD OBJECT of report table */
double RptLim[2]; /* Lower/upper report limits */ double RptLim[2]; /* Lower/upper report limits */
} SField; } SField;
typedef struct s_Premise /* Rule Premise Clause */ typedef struct s_Premise /* Rule Premise Clause */
{ {
int logop; /* Logical operator */ int logop; /* Logical operator */
int object; /* Node or link */ int object; /* Node or link */
@@ -486,7 +504,7 @@ typedef struct s_Premise /* Rule Premise Clause */
struct s_Premise *next; struct s_Premise *next;
} Premise; } Premise;
typedef struct s_Action /* Rule Action Clause */ typedef struct s_Action /* Rule Action Clause */
{ {
int link; /* Link index */ int link; /* Link index */
int status; /* Link's status */ int status; /* Link's status */
@@ -494,19 +512,19 @@ typedef struct s_Action /* Rule Action Clause */
struct s_Action *next; struct s_Action *next;
} Action; } Action;
typedef struct s_aRule /* Control Rule Structure */ typedef struct s_aRule /* Control Rule Structure */
{ {
char label[MAXID+1]; /* Rule character label */ char label[MAXID+1]; /* Rule character label */
double priority; /* Priority level */ double priority; /* Priority level */
Premise *Pchain; /* Linked list of premises */ Premise *Pchain; /* Linked list of premises */
Action *Tchain; /* Linked list of actions if true */ Action *Tchain; /* Linked list of actions if true */
Action *Fchain; /* Linked list of actions if false */ Action *Fchain; /* Linked list of actions if false */
struct s_aRule *next; struct s_aRule *next;
} aRule; } aRule;
typedef struct s_ActItem /* Action list item */ typedef struct s_ActItem /* Action list item */
{ {
int ruleindex; /* Index of rule action belongs to */ int ruleindex; /* Index of rule action belongs to */
struct s_Action *action; /* An action structure */ struct s_Action *action; /* An action structure */
struct s_ActItem *next; struct s_ActItem *next;
} ActItem; } ActItem;
@@ -542,6 +560,7 @@ typedef struct {
Climit, /// Limiting potential quality Climit, /// Limiting potential quality
*NodeQual, /// Node quality state *NodeQual, /// Node quality state
*TempQual, /// General purpose array for water quality *TempQual, /// General purpose array for water quality
*QTempVolumes,
*QTankVolumes, *QTankVolumes,
*QLinkFlow, *QLinkFlow,
*PipeRateCoeff; *PipeRateCoeff;
@@ -551,12 +570,12 @@ typedef struct {
Qtime; /// Current quality time (sec) Qtime; /// Current quality time (sec)
char OutOfMemory; /* Out of memory indicator */ char OutOfMemory; /* Out of memory indicator */
alloc_handle_t *SegPool; // Memory pool for water quality segments alloc_handle_t *SegPool; // Memory pool for water quality segments
Pseg FreeSeg; /* Pointer to unused segment */ Pseg FreeSeg; /* Pointer to unused segment */
Pseg *FirstSeg, /* First (downstream) segment in each pipe */ Pseg *FirstSeg, /* First (downstream) segment in each pipe */
*LastSeg; /* Last (upstream) segment in each pipe */ *LastSeg; /* Last (upstream) segment in each pipe */
FlowDirection *FlowDir; /* Flow direction for each pipe */ FlowDirection *FlowDir; /* Flow direction for each pipe */
double *VolIn; /* Total volume inflow to node */ double *VolIn; /* Total volume inflow to node */
double *MassIn; /* Total mass inflow to node */ double *MassIn; /* Total mass inflow to node */
double Sc; /* Schmidt Number */ double Sc; /* Schmidt Number */
@@ -613,15 +632,15 @@ typedef struct {
*Patlist, /* Temporary time pattern list */ *Patlist, /* Temporary time pattern list */
*Curvelist; /* Temporary list of curves */ *Curvelist; /* Temporary list of curves */
double *X; // temporary array for curve data double *X; // temporary array for curve data
int int
Ntokens, /* Number of tokens in input line */ Ntokens, /* Number of tokens in input line */
Ntitle; /* Number of title lines */ Ntitle; /* Number of title lines */
char *Tok[MAXTOKS]; /* Array of token strings */ char *Tok[MAXTOKS]; /* Array of token strings */
char Comment[MAXMSG+1]; char Comment[MAXMSG+1];
STmplist *PrevPat; /* Pointer to pattern list element */ STmplist *PrevPat; /* Pointer to pattern list element */
STmplist *PrevCurve; /* Pointer to curve list element */ STmplist *PrevCurve; /* Pointer to curve list element */
} parser_data_t; } parser_data_t;
@@ -646,7 +665,7 @@ typedef struct {
Rpt1Fname[MAXFNAME+1], /* Primary report file name */ Rpt1Fname[MAXFNAME+1], /* Primary report file name */
Rpt2Fname[MAXFNAME+1]; /* Secondary report file name */ Rpt2Fname[MAXFNAME+1]; /* Secondary report file name */
SField Field[MAXVAR]; /* Output reporting fields */ SField Field[MAXVAR]; /* Output reporting fields */
long LineNum; /* Current line number */ long LineNum; /* Current line number */
long PageNum; /* Current page number */ long PageNum; /* Current page number */
@@ -693,12 +712,11 @@ typedef struct {
aRule *Rule; /* Array of rules */ aRule *Rule; /* Array of rules */
ActItem *ActList; /* Linked list of action items */ ActItem *ActList; /* Linked list of action items */
int RuleState; /* State of rule interpreter */ int RuleState; /* State of rule interpreter */
long Time1; /* Start of rule evaluation time interval (sec) */ long Time1; /* Start of rule evaluation time interval (sec) */
Premise *Plast; /* Previous premise clause */ Premise *Plast; /* Previous premise clause */
Action *Tlast; /* Previous true action */ Action *Tlast; /* Previous true action */
Action *Flast; /* Previous false action */ Action *Flast; /* Previous false action */
} rules_t; } rules_t;
/* /*
@@ -753,6 +771,10 @@ typedef struct {
Qexp, /* Exponent in orifice formula */ Qexp, /* Exponent in orifice formula */
Dmult, /* Demand multiplier */ Dmult, /* Demand multiplier */
Hacc, /* Hydraulics solution accuracy */ Hacc, /* Hydraulics solution accuracy */
FlowChangeLimit, /* Hydraulics flow change limit */
HeadErrorLimit, /* Hydraulics head error limit */
DampLimit, /* Solution damping threshold */ DampLimit, /* Solution damping threshold */
Viscos, /* Kin. viscosity (sq ft/sec) */ Viscos, /* Kin. viscosity (sq ft/sec) */
SpGrav, /* Specific gravity */ SpGrav, /* Specific gravity */
@@ -796,7 +818,7 @@ typedef struct {
} hydraulics_t; } hydraulics_t;
typedef struct { typedef struct {
int Nnodes, /* Number of network nodes */ int Nnodes, /* Number of network nodes */
Ntanks, /* Number of tanks */ Ntanks, /* Number of tanks */
Njuncs, /* Number of junction nodes */ Njuncs, /* Number of junction nodes */
Nlinks, /* Number of network links */ Nlinks, /* Number of network links */
@@ -809,17 +831,18 @@ typedef struct {
Ncurves, /* Number of data curves */ Ncurves, /* Number of data curves */
Ncoords; /* Number of Coords */ Ncoords; /* Number of Coords */
Snode *Node; /* Node data */ Snode *Node; /* Node data */
Slink *Link; /* Link data */ Slink *Link; /* Link data */
Stank *Tank; /* Tank data */ Stank *Tank; /* Tank data */
Spump *Pump; /* Pump data */ Spump *Pump; /* Pump data */
Svalve *Valve; /* Valve data */ Svalve *Valve; /* Valve data */
Spattern *Pattern; /* Time patterns */ Spattern *Pattern; /* Time patterns */
Scurve *Curve; /* Curve data */ Scurve *Curve; /* Curve data */
Scoord *Coord; /* Coordinate data */ Scoord *Coord; /* Coordinate data */
Scontrol *Control; /* Control data */ Scontrol *Control; /* Control data */
ENHashTable *NodeHashTable, *LinkHashTable; /* Hash tables for ID labels */ ENHashTable *NodeHashTable,
Padjlist *Adjlist; /* Node adjacency lists */ *LinkHashTable; /* Hash tables for ID labels */
Padjlist *Adjlist; /* Node adjacency lists */
} EN_Network; } EN_Network;
@@ -851,5 +874,4 @@ typedef struct EN_Project {
} EN_Project; } EN_Project;
#endif #endif

9
tests/.gitignore vendored
View File

@@ -1,9 +0,0 @@
# Ignore app description files generated for nrtest
apps/
# Ignore results generated during nrtest execution
benchmark/
# Except changes to reference benchmark
!benchmark/epanet-2012 # Results for EPANET 2.0.12 MSVC 2010 32-bit

46
tests/CMakeLists.txt Normal file
View File

@@ -0,0 +1,46 @@
#
# 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()
# Sets for output directory for executables and libraries.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
#Prep ourselves for compiling boost
find_package(Boost REQUIRED)
include_directories (${Boost_INCLUDE_DIRS})
#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)
#Finally add it to test execution -
#Notice the WORKING_DIRECTORY and COMMAND
add_test(NAME ${testName}
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${testName}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data)
endforeach(testSrc)

View File

@@ -1,7 +0,0 @@
{
"name" : "epanet",
"version" : "2.0.11a",
"description" : "Windows, MS VC2005 or older, 32 Bit",
"setup_script" : "",
"exe" : "epanet2011a.exe"
}

View File

@@ -1,7 +0,0 @@
{
"name" : "epanet",
"version" : "2.0.12",
"description" : "Windows, MS VC 2010, 32 Bit",
"setup_script" : "",
"exe" : "./epanet2012.exe"
}

View File

@@ -1,4 +0,0 @@
{
"duration": 0.87,
"max_memory_MB": 0.0
}

View File

@@ -1,4 +0,0 @@
{
"duration": 1.045,
"max_memory_MB": 0.0
}

View File

@@ -1,4 +0,0 @@
{
"duration": 0.246,
"max_memory_MB": 0.0
}

View File

@@ -1,42 +0,0 @@
{
"Application": {
"description": "Windows, MS VC 2010, 32 Bit",
"name": "epanet",
"version": "2.0.12"
},
"Tests": [
{
"description": "A simple example of modeling chlorine decay",
"error_msg": null,
"name": "Example 1",
"output_files": {
"example1.out": "epanet allclose",
"example1.rpt": "epanet report"
},
"passed": true,
"version": "1.0"
},
{
"description": "Example of modeling a 55-hour fluoride tracer study.",
"error_msg": null,
"name": "Example 2",
"output_files": {
"example2.out": "epanet allclose",
"example2.rpt": "epanet report"
},
"passed": true,
"version": "1.0"
},
{
"description": "Dual-source system example",
"error_msg": null,
"name": "Example 3",
"output_files": {
"example3.out": "epanet allclose",
"example3.rpt": "epanet report"
},
"passed": true,
"version": "1.0"
}
]
}

View File

@@ -1,180 +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
Nodes All
Links All
[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]

View File

@@ -1,17 +0,0 @@
{
"name": "Example 1",
"version": "1.0",
"description": "A simple example of modeling chlorine decay",
"args": [
"example1.inp",
"example1.rpt",
"example1.out"
],
"input_files": [
"example1.inp"
],
"output_files": {
"example1.rpt": "epanet report",
"example1.out": "epanet allclose"
}
}

View File

@@ -1,80 +0,0 @@
;Measured Fluoride for Net2
;Node Hour MG/L
11 2.50 1.02
11 5.38 0.87
11 8.30 0.70
11 11.75 1.01
11 13.02 0.62
11 14.48 0.26
11 17.43 0.17
11 20.30 0.20
11 23.35 0.90
11 27.00 0.13
11 29.67 0.13
11 33.70 0.54
11 35.40 0.90
11 38.30 0.17
11 41.62 0.10
11 44.42 0.12
11 47.25 0.71
11 51.00 0.13
11 53.27 0.58
19 0.25 1.04
19 2.75 1.04
19 5.70 1.08
19 8.60 1.00
19 12.00 0.81
19 13.25 0.95
19 14.73 1.02
19 17.77 1.01
19 20.52 0.87
19 23.53 0.28
19 27.17 0.98
19 29.87 0.85
19 33.92 0.12
19 35.67 0.17
19 38.48 0.64
19 42.08 0.79
19 44.68 0.87
19 47.50 0.16
19 51.17 0.56
19 53.45 0.70
25 0.58 1.04
3.00 1.00
5.87 1.03
8.80 1.00
12.25 1.02
13.50 0.88
14.97 0.36
18.15 0.91
20.75 0.92
23.73 0.94
27.42 0.19
30.08 0.12
34.12 0.83
35.87 0.82
38.67 0.72
42.40 0.76
44.92 0.78
47.75 0.87
51.50 0.42
53.75 0.48
34 2.67 1.03
5.50 1.04
8.45 0.98
11.87 1.01
13.15 1.02
14.62 1.04
17.60 1.02
20.42 1.02
23.43 1.00
27.08 1.02
29.75 0.94
33.82 0.89
35.53 0.75
38.40 0.80
41.85 0.84
44.55 0.92
47.42 0.91
51.08 0.81
53.37 0.47

View File

@@ -1,310 +0,0 @@
[TITLE]
EPANET Example Network 2
Example of modeling a 55-hour fluoride tracer study.
Measured fluoride data is contained in the file Net2-FL.dat
and should be registered with the project to produce a
Calibration Report (select Calibration Data from the Project
menu).
[JUNCTIONS]
;ID Elev Demand Pattern
1 50 -694.4 2 ;
2 100 8 ;
3 60 14 ;
4 60 8 ;
5 100 8 ;
6 125 5 ;
7 160 4 ;
8 110 9 ;
9 180 14 ;
10 130 5 ;
11 185 34.78 ;
12 210 16 ;
13 210 2 ;
14 200 2 ;
15 190 2 ;
16 150 20 ;
17 180 20 ;
18 100 20 ;
19 150 5 ;
20 170 19 ;
21 150 16 ;
22 200 10 ;
23 230 8 ;
24 190 11 ;
25 230 6 ;
27 130 8 ;
28 110 0 ;
29 110 7 ;
30 130 3 ;
31 190 17 ;
32 110 17 ;
33 180 1.5 ;
34 190 1.5 ;
35 110 0 ;
36 110 1 ;
[RESERVOIRS]
;ID Head Pattern
[TANKS]
;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve
26 235 56.7 50 70 50 0 ;
[PIPES]
;ID Node1 Node2 Length Diameter Roughness MinorLoss Status
1 1 2 2400 12 100 0 Open ;
2 2 5 800 12 100 0 Open ;
3 2 3 1300 8 100 0 Open ;
4 3 4 1200 8 100 0 Open ;
5 4 5 1000 12 100 0 Open ;
6 5 6 1200 12 100 0 Open ;
7 6 7 2700 12 100 0 Open ;
8 7 8 1200 12 140 0 Open ;
9 7 9 400 12 100 0 Open ;
10 8 10 1000 8 140 0 Open ;
11 9 11 700 12 100 0 Open ;
12 11 12 1900 12 100 0 Open ;
13 12 13 600 12 100 0 Open ;
14 13 14 400 12 100 0 Open ;
15 14 15 300 12 100 0 Open ;
16 13 16 1500 8 100 0 Open ;
17 15 17 1500 8 100 0 Open ;
18 16 17 600 8 100 0 Open ;
19 17 18 700 12 100 0 Open ;
20 18 32 350 12 100 0 Open ;
21 16 19 1400 8 100 0 Open ;
22 14 20 1100 12 100 0 Open ;
23 20 21 1300 8 100 0 Open ;
24 21 22 1300 8 100 0 Open ;
25 20 22 1300 8 100 0 Open ;
26 24 23 600 12 100 0 Open ;
27 15 24 250 12 100 0 Open ;
28 23 25 300 12 100 0 Open ;
29 25 26 200 12 100 0 Open ;
30 25 31 600 12 100 0 Open ;
31 31 27 400 8 100 0 Open ;
32 27 29 400 8 100 0 Open ;
34 29 28 700 8 100 0 Open ;
35 22 33 1000 8 100 0 Open ;
36 33 34 400 8 100 0 Open ;
37 32 19 500 8 100 0 Open ;
38 29 35 500 8 100 0 Open ;
39 35 30 1000 8 100 0 Open ;
40 28 35 700 8 100 0 Open ;
41 28 36 300 8 100 0 Open ;
[PUMPS]
;ID Node1 Node2 Parameters
[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.26 1.04 .97 .97 .89 1.19
1 1.28 .67 .67 1.34 2.46 .97
1 .92 .68 1.43 .61 .31 .78
1 .37 .67 1.26 1.56 1.19 1.26
1 .6 1.1 1.03 .73 .88 1.06
1 .99 1.72 1.12 1.34 1.12 .97
1 1.04 1.15 .91 .61 .68 .46
1 .51 .74 1.12 1.34 1.26 .97
1 .82 1.37 1.03 .81 .88 .81
1 .81
;Pump Station Outflow Pattern
2 .96 .96 .96 .96 .96 .96
2 .62 0 0 0 0 0
2 .8 1 1 1 1 .15
2 0 0 0 0 0 0
2 .55 .92 .92 .92 .92 .9
2 .9 .45 0 0 0 0
2 0 .7 1 1 1 1
2 .2 0 0 0 0 0
2 0 .74 .92 .92 .92 .92
2 .92
;Pump Station Fluoride Pattern
3 .98 1.02 1.05 .99 .64 .46
3 .35 .35 .35 .35 .35 .35
3 .17 .17 .13 .13 .13 .15
3 .15 .15 .15 .15 .15 .15
3 .15 .12 .1 .08 .11 .09
3 .09 .08 .08 .08 .08 .08
3 .08 .09 .07 .07 .09 .09
3 .09 .09 .09 .09 .09 .09
3 .09 .08 .35 .72 .82 .92
3 1
[CURVES]
;ID X-Value Y-Value
[CONTROLS]
[RULES]
[ENERGY]
Global Efficiency 75
Global Price 0.0
Demand Charge 0.0
[EMITTERS]
;Junction Coefficient
[QUALITY]
;Node InitQual
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
9 1.0
10 1.0
11 1.0
12 1.0
13 1.0
14 1.0
15 1.0
16 1.0
17 1.0
18 1.0
19 1.0
20 1.0
21 1.0
22 1.0
23 1.0
24 1.0
25 1.0
27 1.0
28 1.0
29 1.0
30 1.0
31 1.0
32 1.0
33 1.0
34 1.0
35 1.0
36 1.0
26 1.0
[SOURCES]
;Node Type Quality Pattern
1 CONCEN 1.0 3
[REACTIONS]
;Type Pipe/Tank Coefficient
[REACTIONS]
Order Bulk 1
Order Tank 1
Order Wall 1
Global Bulk 0.0
Global Wall 0.0
Limiting Potential 0.0
Roughness Correlation 0.0
[MIXING]
;Tank Model
[TIMES]
Duration 55:00
Hydraulic Timestep 1:00
Quality Timestep 0:05
Pattern Timestep 1:00
Pattern Start 0:00
Report Timestep 1:00
Report Start 0:00
Start ClockTime 8 am
Statistic None
[REPORT]
Status Yes
Summary No
Nodes All
Links All
[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 Fluoride mg/L
Diffusivity 1.0
Tolerance 0.01
[COORDINATES]
;Node X-Coord Y-Coord
1 21.00 4.00
2 19.00 20.00
3 11.00 21.00
4 14.00 28.00
5 19.00 25.00
6 28.00 23.00
7 36.00 39.00
8 38.00 30.00
9 36.00 42.00
10 37.00 23.00
11 37.00 49.00
12 39.00 60.00
13 38.00 64.00
14 38.00 66.00
15 37.00 69.00
16 27.00 65.00
17 27.00 69.00
18 23.00 68.00
19 21.00 59.00
20 45.00 68.00
21 51.00 62.00
22 54.00 69.00
23 35.00 74.00
24 37.00 71.00
25 35.00 76.00
27 39.00 87.00
28 49.00 85.00
29 42.00 86.00
30 47.00 80.00
31 37.00 80.00
32 23.00 64.00
33 56.00 73.00
34 56.00 77.00
35 43.00 81.00
36 53.00 87.00
26 33.00 76.00
[VERTICES]
;Link X-Coord Y-Coord
[LABELS]
;X-Coord Y-Coord Label & Anchor Node
24.00 7.00 "Pump"
24.00 4.00 "Station"
26.76 77.42 "Tank"
[BACKDROP]
DIMENSIONS 8.75 -0.15 58.25 91.15
UNITS None
FILE
OFFSET 0.00 0.00
[END]

View File

@@ -1,17 +0,0 @@
{
"name": "Example 2",
"version": "1.0",
"description": "Example of modeling a 55-hour fluoride tracer study.",
"args": [
"example2.inp",
"example2.rpt",
"example2.out"
],
"input_files": [
"example2.inp"
],
"output_files": {
"example2.rpt": "epanet report",
"example2.out": "epanet allclose"
}
}

View File

@@ -1,481 +0,0 @@
[TITLE]
EPANET Example Network 3
Example showing how the percent of Lake water in a dual-source
system changes over time.
[JUNCTIONS]
;ID Elev Demand Pattern
10 147 0 ;
15 32 1 3 ;
20 129 0 ;
35 12.5 1 4 ;
40 131.9 0 ;
50 116.5 0 ;
60 0 0 ;
601 0 0 ;
61 0 0 ;
101 42 189.95 ;
103 43 133.2 ;
105 28.5 135.37 ;
107 22 54.64 ;
109 20.3 231.4 ;
111 10 141.94 ;
113 2 20.01 ;
115 14 52.1 ;
117 13.6 117.71 ;
119 2 176.13 ;
120 0 0 ;
121 -2 41.63 ;
123 11 1 2 ;
125 11 45.6 ;
127 56 17.66 ;
129 51 0 ;
131 6 42.75 ;
139 31 5.89 ;
141 4 9.85 ;
143 -4.5 6.2 ;
145 1 27.63 ;
147 18.5 8.55 ;
149 16 27.07 ;
151 33.5 144.48 ;
153 66.2 44.17 ;
157 13.1 51.79 ;
159 6 41.32 ;
161 4 15.8 ;
163 5 9.42 ;
164 5 0 ;
166 -2 2.6 ;
167 -5 14.56 ;
169 -5 0 ;
171 -4 39.34 ;
173 -4 0 ;
177 8 58.17 ;
179 8 0 ;
181 8 0 ;
183 11 0 ;
184 16 0 ;
185 16 25.65 ;
187 12.5 0 ;
189 4 107.92 ;
191 25 81.9 ;
193 18 71.31 ;
195 15.5 0 ;
197 23 17.04 ;
199 -2 119.32 ;
201 0.1 44.61 ;
203 2 1 5 ;
204 21 0 ;
205 21 65.36 ;
206 1 0 ;
207 9 69.39 ;
208 16 0 ;
209 -2 0.87 ;
211 7 8.67 ;
213 7 13.94 ;
215 7 92.19 ;
217 6 24.22 ;
219 4 41.32 ;
225 8 22.8 ;
229 10.5 64.18 ;
231 5 16.48 ;
237 14 15.61 ;
239 13 44.61 ;
241 13 0 ;
243 14 4.34 ;
247 18 70.38 ;
249 18 0 ;
251 30 24.16 ;
253 36 54.52 ;
255 27 40.39 ;
257 17 0 ;
259 25 0 ;
261 0 0 ;
263 0 0 ;
265 0 0 ;
267 21 0 ;
269 0 0 ;
271 6 0 ;
273 8 0 ;
275 10 0 ;
[RESERVOIRS]
;ID Head Pattern
River 220.0 ;
Lake 167.0 ;
[TANKS]
;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve
1 131.9 13.1 .1 32.1 85 0 ;
2 116.5 23.5 6.5 40.3 50 0 ;
3 129.0 29.0 4.0 35.5 164 0 ;
[PIPES]
;ID Node1 Node2 Length Diameter Roughness MinorLoss Status
20 3 20 99 99 199 0 Open ;
40 1 40 99 99 199 0 Open ;
50 2 50 99 99 199 0 Open ;
60 River 60 1231 24 140 0 Open ;
101 10 101 14200 18 110 0 Open ;
103 101 103 1350 16 130 0 Open ;
105 101 105 2540 12 130 0 Open ;
107 105 107 1470 12 130 0 Open ;
109 103 109 3940 16 130 0 Open ;
111 109 111 2000 12 130 0 Open ;
112 115 111 1160 12 130 0 Open ;
113 111 113 1680 12 130 0 Open ;
114 115 113 2000 8 130 0 Open ;
115 107 115 1950 8 130 0 Open ;
116 113 193 1660 12 130 0 Open ;
117 263 105 2725 12 130 0 Open ;
119 115 117 2180 12 130 0 Open ;
120 119 120 730 12 130 0 Open ;
121 120 117 1870 12 130 0 Open ;
122 121 120 2050 8 130 0 Open ;
123 121 119 2000 30 141 0 Open ;
125 123 121 1500 30 141 0 Open ;
129 121 125 930 24 130 0 Open ;
131 125 127 3240 24 130 0 Open ;
133 20 127 785 20 130 0 Open ;
135 127 129 900 24 130 0 Open ;
137 129 131 6480 16 130 0 Open ;
145 129 139 2750 8 130 0 Open ;
147 139 141 2050 8 130 0 Open ;
149 143 141 1400 8 130 0 Open ;
151 15 143 1650 8 130 0 Open ;
153 145 141 3510 12 130 0 Open ;
155 147 145 2200 12 130 0 Open ;
159 147 149 880 12 130 0 Open ;
161 149 151 1020 8 130 0 Open ;
163 151 153 1170 12 130 0 Open ;
169 125 153 4560 8 130 0 Open ;
171 119 151 3460 12 130 0 Open ;
173 119 157 2080 30 141 0 Open ;
175 157 159 2910 30 141 0 Open ;
177 159 161 2000 30 141 0 Open ;
179 161 163 430 30 141 0 Open ;
180 163 164 150 14 130 0 Open ;
181 164 166 490 14 130 0 Open ;
183 265 169 590 30 141 0 Open ;
185 167 169 60 8 130 0 Open ;
186 187 204 99.9 8 130 0 Open ;
187 169 171 1270 30 141 0 Open ;
189 171 173 50 30 141 0 Open ;
191 271 171 760 24 130 0 Open ;
193 35 181 30 24 130 0 Open ;
195 181 177 30 12 130 0 Open ;
197 177 179 30 12 130 0 Open ;
199 179 183 210 12 130 0 Open ;
201 40 179 1190 12 130 0 Open ;
202 185 184 99.9 8 130 0 Open ;
203 183 185 510 8 130 0 Open ;
204 184 205 4530. 12 130 0 Open ;
205 204 185 1325. 12 130 0 Open ;
207 189 183 1350 12 130 0 Open ;
209 189 187 500 8 130 0 Open ;
211 169 269 646 12 130 0 Open ;
213 191 187 2560 12 130 0 Open ;
215 267 189 1230 12 130 0 Open ;
217 191 193 520 12 130 0 Open ;
219 193 195 360 12 130 0 Open ;
221 161 195 2300 8 130 0 Open ;
223 197 191 1150 12 130 0 Open ;
225 111 197 2790 12 130 0 Open ;
229 173 199 4000 24 141 0 Open ;
231 199 201 630 24 141 0 Open ;
233 201 203 120 24 130 0 Open ;
235 199 273 725 12 130 0 Open ;
237 205 207 1200 12 130 0 Open ;
238 207 206 450 12 130 0 Open ;
239 275 207 1430 12 130 0 Open ;
240 206 208 510 12 130 0 Open ;
241 208 209 885 12 130 0 Open ;
243 209 211 1210 16 130 0 Open ;
245 211 213 990 16 130 0 Open ;
247 213 215 4285 16 130 0 Open ;
249 215 217 1660 16 130 0 Open ;
251 217 219 2050 14 130 0 Open ;
257 217 225 1560 12 130 0 Open ;
261 213 229 2200 8 130 0 Open ;
263 229 231 1960 12 130 0 Open ;
269 211 237 2080 12 130 0 Open ;
271 237 229 790 8 130 0 Open ;
273 237 239 510 12 130 0 Open ;
275 239 241 35 12 130 0 Open ;
277 241 243 2200 12 130 0 Open ;
281 241 247 445 10 130 0 Open ;
283 239 249 430 12 130 0 Open ;
285 247 249 10 12 130 0 Open ;
287 247 255 1390 10 130 0 Open ;
289 50 255 925 10 130 0 Open ;
291 255 253 1100 10 130 0 Open ;
293 255 251 1100 8 130 0 Open ;
295 249 251 1450 12 130 0 Open ;
297 120 257 645 8 130 0 Open ;
299 257 259 350 8 130 0 Open ;
301 259 263 1400 8 130 0 Open ;
303 257 261 1400 8 130 0 Open ;
305 117 261 645 12 130 0 Open ;
307 261 263 350 12 130 0 Open ;
309 265 267 1580 8 130 0 Open ;
311 193 267 1170 12 130 0 Open ;
313 269 189 646 12 130 0 Open ;
315 181 271 260 24 130 0 Open ;
317 273 275 2230 8 130 0 Open ;
319 273 205 645 12 130 0 Open ;
321 163 265 1200 30 141 0 Open ;
323 201 275 300 12 130 0 Open ;
325 269 271 1290 8 130 0 Open ;
329 61 123 45500 30 140 0 Open ;
330 60 601 1 30 140 0 Closed ;
333 601 61 1 30 140 0 Open ;
[PUMPS]
;ID Node1 Node2 Parameters
10 Lake 10 HEAD 1 ;
335 60 61 HEAD 2 ;
[VALVES]
;ID Node1 Node2 Diameter Type Setting MinorLoss
[TAGS]
[DEMANDS]
;Junction Demand Pattern Category
[STATUS]
;ID Status/Setting
10 Closed
[PATTERNS]
;ID Multipliers
;General Default Demand Pattern
1 1.34 1.94 1.46 1.44 .76 .92
1 .85 1.07 .96 1.1 1.08 1.19
1 1.16 1.08 .96 .83 .79 .74
1 .64 .64 .85 .96 1.24 1.67
;Demand Pattern for Node 123
2 0 0 0 0 0 1219
2 0 0 0 1866 1836 1818
2 1818 1822 1822 1817 1824 1816
2 1833 1817 1830 1814 1840 1859
;Demand Pattern for Node 15
3 620 620 620 620 620 360
3 360 0 0 0 0 360
3 360 360 360 360 0 0
3 0 0 0 0 360 360
;Demand Pattern for Node 35
4 1637 1706 1719 1719 1791 1819
4 1777 1842 1815 1825 1856 1801
4 1819 1733 1664 1620 1613 1620
4 1616 1647 1627 1627 1671 1668
;Demand Pattern for Node 203
5 4439 4531 4511 4582 4531 4582
5 4572 4613 4643 4643 4592 4613
5 4531 4521 4449 4439 4449 4460
5 4439 4419 4368 4399 4470 4480
[CURVES]
;ID X-Value Y-Value
;PUMP: Pump Curve for Pump 10 (Lake Source)
1 0 104.
1 2000. 92.
1 4000. 63.
;PUMP: Pump Curve for Pump 335 (River Source)
2 0 200.
2 8000. 138.
2 14000. 86.
[CONTROLS]
;Lake source operates only part of the day
Link 10 OPEN AT TIME 1
Link 10 CLOSED AT TIME 15
;Pump 335 controlled by level in Tank 1
;When pump is closed, bypass pipe is opened
Link 335 OPEN IF Node 1 BELOW 17.1
Link 335 CLOSED IF Node 1 ABOVE 19.1
Link 330 CLOSED IF Node 1 BELOW 17.1
Link 330 OPEN IF Node 1 ABOVE 19.1
[RULES]
[ENERGY]
Global Efficiency 75
Global Price 0.0
Demand Charge 0.0
[EMITTERS]
;Junction Coefficient
[QUALITY]
;Node InitQual
[SOURCES]
;Node Type Quality Pattern
[REACTIONS]
;Type Pipe/Tank Coefficient
[REACTIONS]
Order Bulk 1
Order Tank 1
Order Wall 1
Global Bulk 0.0
Global Wall 0.0
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 1:00
Pattern Start 0:00
Report Timestep 1:00
Report Start 0:00
Start ClockTime 12 am
Statistic None
[REPORT]
Status Yes
Summary No
Nodes All
Links All
[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 Trace Lake
Diffusivity 1.0
Tolerance 0.01
[COORDINATES]
;Node X-Coord Y-Coord
10 9.00 27.85
15 38.68 23.76
20 29.44 26.91
35 25.46 10.52
40 27.02 9.81
50 33.01 3.01
60 23.90 29.94
601 23.00 29.49
61 23.71 29.03
101 13.81 22.94
103 12.96 21.31
105 16.97 21.28
107 18.45 20.46
109 17.64 18.92
111 20.21 17.53
113 22.04 16.61
115 20.98 19.18
117 21.69 21.28
119 23.70 22.76
120 22.08 23.10
121 23.54 25.50
123 23.37 27.31
125 24.59 25.64
127 29.29 26.40
129 30.32 26.39
131 37.89 29.55
139 33.28 24.54
141 35.68 23.08
143 37.47 21.97
145 33.02 19.29
147 30.24 20.38
149 29.62 20.74
151 28.29 21.39
153 28.13 22.63
157 24.85 20.16
159 23.12 17.50
161 25.10 15.28
163 25.39 14.98
164 25.98 15.14
166 26.48 15.13
167 25.88 12.98
169 25.68 12.74
171 26.65 11.80
173 26.87 11.59
179 25.71 10.40
181 25.72 10.74
183 25.45 10.18
184 25.15 9.52
185 25.01 9.67
187 23.64 11.04
189 24.15 11.37
191 22.10 14.07
193 22.88 14.35
195 23.18 14.72
197 20.97 15.18
199 29.42 8.44
201 30.89 8.57
203 31.14 8.89
204 23.80 10.90
205 29.20 6.46
206 31.66 6.64
207 31.00 6.61
208 32.54 6.81
209 33.76 6.59
211 34.20 5.54
213 35.26 6.16
215 39.95 8.73
217 42.11 8.67
219 44.86 9.32
225 43.53 7.38
229 36.16 3.49
231 38.38 2.54
237 35.37 3.08
239 35.76 2.31
241 35.87 2.11
243 37.04 0.00
247 35.02 2.05
249 35.02 1.81
251 34.15 1.10
253 32.17 1.88
255 33.51 2.45
257 21.17 23.32
259 20.80 23.40
261 20.79 21.45
263 20.32 21.57
265 25.39 13.60
267 23.38 12.95
269 25.03 12.14
271 25.97 11.00
273 29.16 7.38
275 31.07 8.29
River 24.15 31.06
Lake 8.00 27.53
1 27.46 9.84
2 32.99 3.45
3 29.41 27.27
[VERTICES]
;Link X-Coord Y-Coord
[LABELS]
;X-Coord Y-Coord Label & Anchor Node
8.00 29.42 "LAKE"
25.00 31.10 "RIVER"
[BACKDROP]
DIMENSIONS 6.16 -1.55 46.70 32.61
UNITS None
FILE
OFFSET 0.00 0.00
[END]

View File

@@ -1,17 +0,0 @@
{
"name": "Example 3",
"version": "1.0",
"description": "Dual-source system example",
"args": [
"example3.inp",
"example3.rpt",
"example3.out"
],
"input_files": [
"example3.inp"
],
"output_files": {
"example3.rpt": "epanet report",
"example3.out": "epanet allclose"
}
}

Binary file not shown.

View File

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

View File

@@ -1,35 +0,0 @@
Type=Exe
Form=frmMain.frm
Module=basShellSync; ShellSync.bas
Module=basNetRes; basNetRes.bas
IconForm="frmMain"
Startup="frmMain"
HelpFile=""
Title="Testing"
ExeName32="BinaryCompare.exe"
Command32=""
Name="BinaryCompare"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=1
AutoIncrementVer=1
ServerSupportFiles=0
VersionComments="by Elad Salomons"
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
DebugStartupOption=0

View File

@@ -1,39 +0,0 @@
Attribute VB_Name = "basShellSync"
Option Explicit
Private Const INFINITE = &HFFFFFFFF
Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_QUERY_INFORMATION = &H400&
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Public Function ShellSync(ByVal PathName As String, ByVal WindowStyle As VbAppWinStyle) As Long
'-----------------------------------------------------------------------------------------------
'Shell and wait. Return exit code result, raise an
'exception on any error.
Dim lngPid As Long
Dim lngHandle As Long
Dim lngExitCode As Long
lngPid = Shell(PathName, WindowStyle)
If lngPid <> 0 Then
lngHandle = OpenProcess(SYNCHRONIZE Or PROCESS_QUERY_INFORMATION, 0, lngPid)
If lngHandle <> 0 Then
WaitForSingleObject lngHandle, INFINITE
If GetExitCodeProcess(lngHandle, lngExitCode) <> 0 Then
ShellSync = lngExitCode
CloseHandle lngHandle
Else
CloseHandle lngHandle
Err.Raise &H8004AA00, "ShellSync", "Failed to retrieve exit code, error " & CStr(Err.LastDllError)
End If
Else
Err.Raise &H8004AA01, "ShellSync", "Failed to open child process"
End If
Else
Err.Raise &H8004AA02, "ShellSync", "Failed to Shell child process"
End If
End Function

View File

@@ -1,188 +0,0 @@
Attribute VB_Name = "basNetRes"
Public Type typNetRes
nNodes As Long
nLinks As Long
NodesID() As String
LinksID() As String
NodesDemand() As Single
NodesHead() As Single
NodesPressure() As Single
NodesQuality() As Single
LinksFlow() As Single
LinksHeadloss() As Single
LinksQuality() As Single
LinksSetting() As Single
LinksStatus() As Single
LinksVelocity() As Single
End Type
Public Function ReadOutputFile(OutFile As String, NetRes As typNetRes)
'---------------------------------------------------------------------------------------
Dim i As Long, F As Long, r As Long, nRep As Long, j As Long
Dim tmpArr() As Single
Dim pos As Long, N As Long
Dim tmpLong As Long, tmpSingle As Single
Dim ReportingTimeStep As Long, ReportingStartTime As Long
Dim SimulationDuration As Long
Dim ProblemTitletLine As String * 80
Dim NumberOfNodes As Long
Dim NumberOfLinks As Long
Dim NumberOfReservoirsAndTanks As Long
Dim NumberOfPumps As Long
Dim NumberOfValves As Long
Dim WaterQualityOption As Long
Dim FlowUnitsOption As Long, PressureUnitsOption As Long
Dim NameOfFile As String * 260, tmpString32 As String * 32
Dim ii As Long
Dim WarningFlag As Long
With NetRes
pos = 1: N = 0
F = FreeFile
Open OutFile For Binary As #F
Get #F, pos, tmpLong: pos = pos + 4
Get #F, pos, tmpLong: pos = pos + 4
Get #F, pos, NumberOfNodes: pos = pos + 4
Get #F, pos, NumberOfReservoirsAndTanks: pos = pos + 4
Get #F, pos, NumberOfLinks: pos = pos + 4
Get #F, pos, NumberOfPumps: pos = pos + 4
Get #F, pos, NumberOfValves: pos = pos + 4
Get #F, pos, WaterQualityOption: pos = pos + 4
Get #F, pos, tmpLong: pos = pos + 4
Get #F, pos, FlowUnitsOption: pos = pos + 4
Get #F, pos, PressureUnitsOption: pos = pos + 4
Get #F, pos, tmpLong: pos = pos + 4
Get #F, pos, ReportingStartTime: pos = pos + 4
Get #F, pos, ReportingTimeStep: pos = pos + 4
Get #F, pos, SimulationDuration: pos = pos + 4
Get #F, pos, ProblemTitletLine: pos = pos + 80
Get #F, pos, ProblemTitletLine: pos = pos + 80
Get #F, pos, ProblemTitletLine: pos = pos + 80
Get #F, pos, NameOfFile: pos = pos + 260
Get #F, pos, NameOfFile: pos = pos + 260
Get #F, pos, tmpString32: pos = pos + 32
Get #F, pos, tmpString32: pos = pos + 32
.nNodes = NumberOfNodes
.nLinks = NumberOfLinks
ReDim .NodesID(.nNodes)
For j = 1 To NumberOfNodes
Get #F, pos, tmpString32: pos = pos + 32
i = InStr(1, tmpString32, Chr(0))
.NodesID(j) = Mid(tmpString32, 1, i - 1)
Next j
ReDim .LinksID(.nLinks)
For j = 1 To NumberOfLinks
Get #F, pos, tmpString32: pos = pos + 32
i = InStr(1, tmpString32, Chr(0))
.LinksID(j) = Mid(tmpString32, 1, i - 1)
Next j
For j = 1 To NumberOfLinks * 3 'Index of Start Node of Each Link + Index of End Node of Each Link + Type Code of Each Link
Get #F, pos, tmpLong: pos = pos + 4
Next j
For j = 1 To NumberOfReservoirsAndTanks 'Node Index of Each Tank
Get #F, pos, tmpLong: pos = pos + 4
Next j
For j = 1 To NumberOfReservoirsAndTanks 'Cross-Sectional Area of Each Tank
Get #F, pos, tmpSingle: pos = pos + 4
Next j
For j = 1 To NumberOfNodes 'Elevation of Each Node
Get #F, pos, tmpSingle: pos = pos + 4
Next j
For j = 1 To NumberOfLinks 'Length of Each Link
Get #F, pos, tmpSingle: pos = pos + 4
Next j
For j = 1 To NumberOfLinks 'Diameter of Each Link
Get #F, pos, tmpSingle: pos = pos + 4
Next j
For j = 1 To NumberOfPumps 'Energy Use Section
Get #F, pos, tmpLong: pos = pos + 4 'Pump Index in List of Links
Get #F, pos, tmpSingle: pos = pos + 4 'Pump Utilization (%)
Get #F, pos, tmpSingle: pos = pos + 4 'Average Efficiency (%)
Get #F, pos, tmpSingle: pos = pos + 4 'Average Kwatts/Million Gallons (/Meter3)
Get #F, pos, tmpSingle: pos = pos + 4 'Average Kwatts
Get #F, pos, tmpSingle: pos = pos + 4 'Peak Kwatts
Get #F, pos, tmpSingle: pos = pos + 4 'Average Cost Per Day
Next j
Get #F, pos, tmpSingle: pos = pos + 4 'Overall Peak Energy Usage
'reporting
nRep = SimulationDuration / ReportingTimeStep + 1
ReDim tmpArr(nRep)
ReDim .NodesDemand(.nNodes, nRep)
ReDim .NodesHead(.nNodes, nRep)
ReDim .NodesPressure(.nNodes, nRep)
ReDim .NodesQuality(.nNodes, nRep)
ReDim .LinksFlow(.nLinks, nRep)
ReDim .LinksHeadloss(.nLinks, nRep)
ReDim .LinksQuality(.nLinks, nRep)
ReDim .LinksSetting(.nLinks, nRep)
ReDim .LinksStatus(.nLinks, nRep)
ReDim .LinksVelocity(.nLinks, nRep)
For r = 1 To nRep
For j = 1 To NumberOfNodes 'Demand at Each Node
Get #F, pos, tmpSingle: pos = pos + 4
.NodesDemand(j, r) = tmpSingle
Next j
For j = 1 To NumberOfNodes 'Hydraulic Head at Each Node
Get #F, pos, tmpSingle: pos = pos + 4
.NodesHead(j, r) = tmpSingle
Next j
For j = 1 To NumberOfNodes 'Pressure at Each Node
Get #F, pos, tmpSingle: pos = pos + 4
.NodesPressure(j, r) = tmpSingle
Next j
For j = 1 To NumberOfNodes 'Water Quality at Each Node
Get #F, pos, tmpSingle: pos = pos + 4
.NodesPressure(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Flow in Each Link
Get #F, pos, tmpSingle: pos = pos + 4
.LinksFlow(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Velocity in Each Link
Get #F, pos, tmpSingle: pos = pos + 4
.LinksVelocity(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Headloss per 1000 Units of Length for Each Link
Get #F, pos, tmpSingle: pos = pos + 4
.LinksHeadloss(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Average Water Quality in Each Link
Get #F, pos, tmpSingle: pos = pos + 4
.LinksQuality(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Status Code for Each Link
Get #F, pos, tmpSingle: pos = pos + 4
.LinksStatus(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Setting for Each Link
Get #F, pos, tmpSingle: pos = pos + 4
.LinksSetting(j, r) = tmpSingle
Next j
For j = 1 To NumberOfLinks 'Reaction Rate for Each Link (mass/L/day)
Get #F, pos, tmpSingle: pos = pos + 4
Next j
For j = 1 To NumberOfLinks 'Friction Factor for Each Link
Get #F, pos, tmpSingle: pos = pos + 4
Next j
Next r
'Epilog Section
Get #F, pos, tmpSingle: pos = pos + 4 'Average bulk reaction rate (mass/hr)
Get #F, pos, tmpSingle: pos = pos + 4 'Average wall reaction rate (mass/hr)
Get #F, pos, tmpSingle: pos = pos + 4 'Average tank reaction rate (mass/hr)
Get #F, pos, tmpSingle: pos = pos + 4 'Average source inflow rate (mass/hr)
Get #F, pos, tmpLong: pos = pos + 4 'Number of Reporting Periods
Get #F, pos, WarningFlag: pos = pos + 4 'Warning Flag
Get #F, pos, tmpLong: pos = pos + 4 'Magic Number ( = 516114521)
Close #F
End With
End Function

View File

@@ -1,179 +0,0 @@
VERSION 5.00
Begin VB.Form frmMain
Caption = "Form1"
ClientHeight = 5304
ClientLeft = 48
ClientTop = 396
ClientWidth = 9648
LinkTopic = "Form1"
ScaleHeight = 5304
ScaleWidth = 9648
StartUpPosition = 3 'Windows Default
Begin VB.ListBox List1
Height = 4272
Left = 1680
TabIndex = 1
Top = 360
Width = 7092
End
Begin VB.CommandButton cmdRun
Caption = "RUN"
Height = 372
Left = 360
TabIndex = 0
Top = 360
Width = 972
End
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Dim NetName As String
Dim net1 As typNetRes
Dim net2 As typNetRes
Private Sub CompareVersions(NetName As String)
'-----------------------------------------------
Dim i As Long
Dim v1 As Single, v2 As Single
Dim T As Long
Dim L As Long
Dim maxDiff As Single
Dim diff As Single
Dim nRep As Long
Dim F As Long
i = ShellSync("epanet2d.exe nets\" & NetName & ".inp nets\" & NetName & "_1.rep nets\" & NetName & "_1.out", vbNormalFocus)
i = ReadOutputFile("nets\" & NetName & "_1.out", net1)
i = ShellSync("epanet2.exe nets\" & NetName & ".inp nets\" & NetName & "_2.rep nets\" & NetName & "_2.out", vbNormalFocus)
i = ReadOutputFile("nets\" & NetName & "_2.out", net2)
F = FreeFile
Open App.Path & "\Nets\" & NetName & ".dif" For Output As #F
nRep = UBound(net1.LinksFlow, 2)
maxDiff = 100: diff = 101
For L = 1 To net1.nLinks
For T = 1 To nRep
v1 = net1.LinksFlow(L, T)
v2 = net2.LinksFlow(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Links Flow max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nLinks
For T = 1 To nRep
v1 = net1.LinksHeadloss(L, T)
v2 = net2.LinksHeadloss(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Links Headloss max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nLinks
For T = 1 To nRep
v1 = net1.LinksQuality(L, T)
v2 = net2.LinksQuality(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Links Quality max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nLinks
For T = 1 To nRep
v1 = net1.LinksVelocity(L, T)
v2 = net2.LinksVelocity(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Links Velocity max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nNodes
For T = 1 To nRep
v1 = net1.NodesDemand(L, T)
v2 = net2.NodesDemand(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Nodes Demand max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nNodes
For T = 1 To nRep
v1 = net1.NodesHead(L, T)
v2 = net2.NodesHead(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Nodes Head max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nNodes
For T = 1 To nRep
v1 = net1.NodesPressure(L, T)
v2 = net2.NodesPressure(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2)) / Log(10))
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Nodes Pressure max diff = " & Format(maxDiff, "0")
maxDiff = 100: diff = 101
For L = 1 To net1.nNodes
For T = 1 To nRep
v1 = net1.NodesQuality(L, T)
v2 = net2.NodesQuality(L, T)
If Abs(v1 - v2) > 0 Then diff = -Round(Log(Abs(v1 - v2))) / Log(10)
If diff < maxDiff Then maxDiff = diff
Next T
Next L
Print #F, "Nodes Quality max diff = " & Format(maxDiff, "0")
Close #F
End Sub
Private Sub cmdRun_Click()
'----------------------------------------------
Dim fName As String
fName = Dir(App.Path & "\Nets\*.inp")
If fName <> "" Then
Do
List1.AddItem fName: DoEvents
fName = StrReverse(fName)
fName = Mid(fName, 5)
fName = StrReverse(fName)
Call CompareVersions(fName)
fName = Dir
Loop Until fName = ""
End If
End Sub
Private Sub Form_Load()
List1.Clear
End Sub

View File

@@ -1,8 +0,0 @@
Links Flow max diff = 3
Links Headloss max diff = 4
Links Quality max diff = 3
Links Velocity max diff = 6
Nodes Demand max diff = 3
Nodes Head max diff = 5
Nodes Pressure max diff = 3
Nodes Quality max diff = 100

View File

@@ -1,311 +0,0 @@
[TITLE]
EPANET Example Network 2
Example of modeling a 55-hour fluoride tracer study.
Measured fluoride data is contained in the file Net2-FL.dat
and should be registered with the project to produce a
Calibration Report (select Calibration Data from the Project
menu).
[JUNCTIONS]
;ID Elev Demand Pattern
1 50 -694.4 2 ;
2 100 8 ;
3 60 14 ;
4 60 8 ;
5 100 8 ;
6 125 5 ;
7 160 4 ;
8 110 9 ;
9 180 14 ;
10 130 5 ;
11 185 34.78 ;
12 2100 16 ;
13 210 2 ;
14 200 2 ;
15 190 2 ;
16 150 20 ;
17 180 20 ;
18 100 20 ;
19 150 5 ;
20 170 19 ;
21 150 16 ;
22 200 10 ;
23 230 8 ;
24 190 11 ;
25 230 6 ;
27 130 8 ;
28 110 0 ;
29 110 7 ;
30 130 3 ;
31 190 17 ;
32 110 17 ;
33 180 1.5 ;
34 190 1.5 ;
35 110 0 ;
36 110 1 ;
[RESERVOIRS]
;ID Head Pattern
[TANKS]
;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve
26 235 56.7 50 70 50 0 ;
[PIPES]
;ID Node1 Node2 Length Diameter Roughness MinorLoss Status
1 1 2 2400 12 100 0 Open ;
2 2 5 800 12 100 0 Open ;
3 2 3 1300 8 100 0 Open ;
4 3 4 1200 8 100 0 Open ;
5 4 5 1000 12 100 0 Open ;
6 5 6 1200 12 100 0 Open ;
7 6 7 2700 12 100 0 Open ;
8 7 8 1200 12 140 0 Open ;
9 7 9 400 12 100 0 Open ;
10 8 10 1000 8 140 0 Open ;
11 9 11 700 12 100 0 Open ;
12 11 12 1900 12 100 0 Open ;
13 12 13 600 12 100 0 Open ;
14 13 14 400 12 100 0 Open ;
15 14 15 300 12 100 0 Open ;
16 13 16 1500 8 100 0 Open ;
17 15 17 1500 8 100 0 Open ;
18 16 17 600 8 100 0 Open ;
19 17 18 700 12 100 0 Open ;
20 18 32 350 12 100 0 Open ;
21 16 19 1400 8 100 0 Open ;
22 14 20 1100 12 100 0 Open ;
23 20 21 1300 8 100 0 Open ;
24 21 22 1300 8 100 0 Open ;
25 20 22 1300 8 100 0 Open ;
26 24 23 600 12 100 0 Open ;
27 15 24 250 12 100 0 Open ;
28 23 25 300 12 100 0 Open ;
29 25 26 200 12 100 0 Open ;
30 25 31 600 12 100 0 Open ;
31 31 27 400 8 100 0 Open ;
32 27 29 400 8 100 0 Open ;
34 29 28 700 8 100 0 Open ;
35 22 33 1000 8 100 0 Open ;
36 33 34 400 8 100 0 Open ;
37 32 19 500 8 100 0 Open ;
38 29 35 500 8 100 0 Open ;
39 35 30 1000 8 100 0 Open ;
40 28 35 700 8 100 0 Open ;
41 28 36 300 8 100 0 Open ;
[PUMPS]
;ID Node1 Node2 Parameters
[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.26 1.04 .97 .97 .89 1.19
1 1.28 .67 .67 1.34 2.46 .97
1 .92 .68 1.43 .61 .31 .78
1 .37 .67 1.26 1.56 1.19 1.26
1 .6 1.1 1.03 .73 .88 1.06
1 .99 1.72 1.12 1.34 1.12 .97
1 1.04 1.15 .91 .61 .68 .46
1 .51 .74 1.12 1.34 1.26 .97
1 .82 1.37 1.03 .81 .88 .81
1 .81
;Pump Station Outflow Pattern
2 .96 .96 .96 .96 .96 .96
2 .62 0 0 0 0 0
2 .8 1 1 1 1 .15
2 0 0 0 0 0 0
2 .55 .92 .92 .92 .92 .9
2 .9 .45 0 0 0 0
2 0 .7 1 1 1 1
2 .2 0 0 0 0 0
2 0 .74 .92 .92 .92 .92
2 .92
;Pump Station Fluoride Pattern
3 .98 1.02 1.05 .99 .64 .46
3 .35 .35 .35 .35 .35 .35
3 .17 .17 .13 .13 .13 .15
3 .15 .15 .15 .15 .15 .15
3 .15 .12 .1 .08 .11 .09
3 .09 .08 .08 .08 .08 .08
3 .08 .09 .07 .07 .09 .09
3 .09 .09 .09 .09 .09 .09
3 .09 .08 .35 .72 .82 .92
3 1
[CURVES]
;ID X-Value Y-Value
[CONTROLS]
[RULES]
[ENERGY]
Global Efficiency 75
Global Price 0.0
Demand Charge 0.0
[EMITTERS]
;Junction Coefficient
[QUALITY]
;Node InitQual
1 1.0
2 1.0
3 1.0
4 1.0
5 1.0
6 1.0
7 1.0
8 1.0
9 1.0
10 1.0
11 1.0
12 1.0
13 1.0
14 1.0
15 1.0
16 1.0
17 1.0
18 1.0
19 1.0
20 1.0
21 1.0
22 1.0
23 1.0
24 1.0
25 1.0
27 1.0
28 1.0
29 1.0
30 1.0
31 1.0
32 1.0
33 1.0
34 1.0
35 1.0
36 1.0
26 1.0
[SOURCES]
;Node Type Quality Pattern
1 CONCEN 1.0 3
[REACTIONS]
;Type Pipe/Tank Coefficient
[REACTIONS]
Order Bulk 1
Order Tank 1
Order Wall 1
Global Bulk 0.0
Global Wall 0.0
Limiting Potential 0.0
Roughness Correlation 0.0
[MIXING]
;Tank Model
[TIMES]
Duration 55:00
Hydraulic Timestep 1:00
Quality Timestep 0:05
Pattern Timestep 1:00
Pattern Start 0:00
Report Timestep 1:00
Report Start 0:00
Start ClockTime 8 am
Statistic NONE
[REPORT]
Status Full
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 Fluoride mg/L
Diffusivity 1.0
Tolerance 0.01
[COORDINATES]
;Node X-Coord Y-Coord
1 21.00 4.00
2 19.00 20.00
3 11.00 21.00
4 14.00 28.00
5 19.00 25.00
6 28.00 23.00
7 36.00 39.00
8 38.00 30.00
9 36.00 42.00
10 37.00 23.00
11 37.00 49.00
12 39.00 60.00
13 38.00 64.00
14 38.00 66.00
15 37.00 69.00
16 27.00 65.00
17 27.00 69.00
18 23.00 68.00
19 21.00 59.00
20 45.00 68.00
21 51.00 62.00
22 54.00 69.00
23 35.00 74.00
24 37.00 71.00
25 35.00 76.00
27 39.00 87.00
28 49.00 85.00
29 42.00 86.00
30 47.00 80.00
31 37.00 80.00
32 23.00 64.00
33 56.00 73.00
34 56.00 77.00
35 43.00 81.00
36 53.00 87.00
26 33.00 76.00
[VERTICES]
;Link X-Coord Y-Coord
[LABELS]
;X-Coord Y-Coord Label & Anchor Node
24.00 7.00 "Pump"
24.00 4.00 "Station"
26.76 77.42 "Tank"
[BACKDROP]
DIMENSIONS 8.75 -0.15 58.25 91.15
UNITS None
FILE
OFFSET 0.00 0.00
[END]

View File

@@ -1,12 +0,0 @@
The program will run all INP files in the Nets sub-directory.
A report, binary output files and a .dif file will be created for each INP file.
The report is the min(—log10(abs(X1-X2))) where X1 and X2 are the results arrays obtains from the two binary files.
Files needed in the code directory:
epanet2d.exe is the official EPANET standalone version.
epanet2.exe is the current development version (the one being tested).
How to use: run the program and click the RUN button.
By Elad Salomons
email: selad@optiwater.com

View File

@@ -1,35 +0,0 @@
#! /bin/bash
test_networks()
{
returnValue=0
for d in network_tests/*/ ; do
for netfile in `ls $d*.inp`; do
officialBinFile=${netfile%.*}.enb
candidateBinFile=${netfile%.*}-candidate.enb
echo "testing $netfile with known good binary output $officialBinFile"
if ../build/CMake/buildproducts/bin/runepanet $netfile ${netfile%.*}-candidate.rpt $candidateBinFile
then
echo "epanet run for $netfile SUCCESS"
else
echo "epanet run for $netfile FAILED"
returnValue=1
fi
if python ENBinaryOutDiff.py $officialBinFile $candidateBinFile
then
echo "binary output for $netfile PASSED"
else
echo "binary output for $netfile FAILED"
returnValue=1
fi
echo "+++++"
done
done
return $returnValue
}
cp ../build/CMake/buildproducts/bin/libENBinaryOut.* ./libENBinaryOut.so
cp ../tools/outputapi/*.py ./
test_networks

358
tests/test_output.cpp Normal file
View File

@@ -0,0 +1,358 @@
/*
* test_epanet_output.cpp
*
* Created: 8/4/2017
* Author: Michael E. Tryby
* US EPA - ORD/NRMRL
*
* Unit testing for EPANET Output API.
*/
// NOTE: Travis installs libboost test version 1.5.4
// NOTE: Can not dyn link boost using Visual Studio 10 2010
//#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE "output"
#include <boost/test/included/unit_test.hpp>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include "epanet_output.h"
#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<float>& test,
std::vector<float>& ref, long cdd_tol)
{
float tmp, min_cdd = 100.0;
// TODO: What is the vectors aren't the same length?
std::vector<float>::iterator test_it;
std::vector<float>::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 floor(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)
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());
array = NULL;
array_dim = 0;
}
~Fixture() {
ENR_free((void**)&array);
error = ENR_close(&p_handle);
}
std::string path;
int error;
ENR_Handle p_handle;
float* array;
int array_dim;
};
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<int> test;
test.assign(i_array, i_array + array_dim);
const int ref_dim = 5;
int ref_array[ref_dim] = {11,2,13,1,0};
std::vector<int> ref;
ref.assign(ref_array, ref_array + ref_dim);
BOOST_CHECK_EQUAL_COLLECTIONS(ref.begin(), ref.end(), test.begin(), test.end());
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);
std::string test (name);
std::string ref ("10");
BOOST_CHECK(check_string(test, ref));
delete(name);
}
BOOST_FIXTURE_TEST_CASE(test_getNodeAttribute, Fixture) {
error = ENR_getNodeAttribute(p_handle, 1, ENR_quality, &array, &array_dim);
BOOST_REQUIRE(error == 0);
const int ref_dim = 11;
float ref_array[ref_dim] = { 1.0f,
0.44407997f,
0.43766347f,
0.42827705f,
0.41342604f,
0.42804748f,
0.44152543f,
0.40502965f,
0.38635802f,
1.0f,
0.96745253f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(check_cdd(test_vec, ref_vec, 3));
}
BOOST_FIXTURE_TEST_CASE(test_getLinkAttribute, Fixture) {
error = ENR_getLinkAttribute(p_handle, 1, ENR_flow, &array ,&array_dim);
BOOST_REQUIRE(error == 0);
const int ref_dim = 13;
float ref_array[ref_dim] = { 1848.5812f,
1220.4274f,
130.11162f,
187.6893f,
119.8884f,
40.464489f,
-748.58112f,
478.15378f,
191.73459f,
30.111609f,
140.46449f,
59.535515f,
1848.5812f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(check_cdd(test_vec, ref_vec, 3));
}
BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) {
error = ENR_getNodeResult(p_handle, 1, 2, &array, &array_dim);
BOOST_REQUIRE(error == 0);
const int ref_dim = 4;
float ref_array[ref_dim] = {0.041142918f,
150.0f,
987.98358f,
120.45029f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(check_cdd(test_vec, ref_vec, 3));
}
BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) {
error = ENR_getLinkResult(p_handle, 24, 13, &array, &array_dim);
BOOST_REQUIRE(error == 0);
const int ref_dim = 8;
float ref_array[ref_dim] = {0.58586824f,
1892.2433f,
0.0f,
-200.71875f,
1.0f,
3.0f,
1.0f,
0.0f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(check_cdd(test_vec, ref_vec, 3));
}
BOOST_FIXTURE_TEST_CASE(test_getNodeSeries, Fixture){
error = ENR_getNodeSeries(p_handle, 2, ENR_pressure, 0, 10, &array, &array_dim);
BOOST_REQUIRE(error == 0);
const int ref_dim = 10;
float ref_array[ref_dim] = {119.25731f,
120.45029f,
121.19854f,
122.00622f,
122.37414f,
122.8122f,
122.82034f,
122.90379f,
123.40434f,
123.81807f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(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);
const int ref_dim = 10;
float ref_array[ref_dim] = {1234.2072f,
1220.4274f,
1164.4f,
1154.8175f,
1100.0635f,
1094.759f,
1041.7854f,
1040.7617f,
1087.556f,
1082.5011f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(check_cdd(test_vec, ref_vec, 3));
}
BOOST_FIXTURE_TEST_CASE(test_getNetReacts, Fixture) {
error = ENR_getNetReacts(p_handle, &array, &array_dim);
BOOST_REQUIRE(error == 0);
const int ref_dim = 4;
float ref_array[ref_dim] = {18806.59f,
85424.438f,
115174.05f,
238972.66f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(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);
const int ref_dim = 6;
float ref_array[ref_dim] = {57.712959f,
75.0f,
880.41583f,
96.254318f,
96.707115f,
0.0f};
std::vector<float> ref_vec;
ref_vec.assign(ref_array, ref_array + ref_dim);
std::vector<float> test_vec;
test_vec.assign(array, array + array_dim);
BOOST_CHECK(check_cdd(test_vec, ref_vec, 3));
}
BOOST_AUTO_TEST_SUITE_END()

46
tools/app-config.sh Executable file
View File

@@ -0,0 +1,46 @@
#! /bin/bash
#
# app-config.sh - Generates nrtest app configuration file for test executable
#
# Date Created: 3/19/2018
#
# Author: Michael E. Tryby
# US EPA - ORD/NRMRL
#
# Arguments:
# 1 - absolute path to test executable
#
# NOT IMPLEMENTED YET
# 2 - test executable version number
# 3 - build description
#
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) ;&
Darwin*) abs_build_path=$1
test_cmd="runepanet"
;;
MINGW*) ;&
MSYS*) # Remove leading '/c' from file path for nrtest
abs_build_path="$( echo "$1" | sed -e 's#/c##' )"
test_cmd="runepanet.exe"
;;
*) # Machine unknown
esac
version=""
build_description=""
cat<<EOF
{
"name" : "epanet",
"version" : "${version}",
"description" : "${build_description}",
"setup_script" : "",
"exe" : "${abs_build_path}/${test_cmd}"
}
EOF

62
tools/before-test.cmd Normal file
View File

@@ -0,0 +1,62 @@
::
:: before-test.cmd - Prepares AppVeyor CI worker to run epanet regression tests
::
:: Date Created: 4/3/2018
::
:: Author: Michael E. Tryby
:: US EPA - ORD/NRMRL
::
:: Arguments:
:: 1 - relative path regression test file staging location
:: 2 - absolute path to location of software under test
:: 3 - build identifier for software under test
::
:: Note:
:: Tests and benchmark files are stored in the epanet-example-networks repo.
:: This script retreives them using a stable URL associated with a release on
:: GitHub and stages the files for nrtest to run. The script assumes that
:: before-test.cmd and gen-config.cmd are located together in the same folder.
::
@echo off
setlocal
set SCRIPT_HOME=%~dp0
set TEST_HOME=%~1
set EXAMPLES_VER=1.0.2-dev
set BENCHMARK_VER=220dev-vs17
set TESTFILES_URL=https://github.com/OpenWaterAnalytics/epanet-example-networks/archive/v%EXAMPLES_VER%.zip
set BENCHFILES_URL=https://github.com/OpenWaterAnalytics/epanet-example-networks/releases/download/v%EXAMPLES_VER%/epanet-benchmark-%BENCHMARK_VER%.zip
echo INFO: Staging files for regression testing
:: create a clean directory for staging regression tests
if exist %TEST_HOME% (
rmdir /s /q %TEST_HOME%
)
mkdir %TEST_HOME%
cd %TEST_HOME%
:: retrieve epanet-examples for regression testing
curl -fsSL -o examples.zip %TESTFILES_URL%
:: retrieve epanet benchmark results
curl -fsSL -o benchmark.zip %BENCHFILES_URL%
:: extract tests and benchmarks
7z x examples.zip *\epanet-tests\* > nul
7z x benchmark.zip -obenchmark\ > nul
:: set up symlink for tests directory
mklink /D .\tests .\epanet-example-networks-%EXAMPLES_VER%\epanet-tests
:: generate json configuration file for software under test
mkdir apps
%SCRIPT_HOME%\gen-config.cmd %~2 > apps\epanet-%~3.json

58
tools/before-test.sh Executable file
View File

@@ -0,0 +1,58 @@
#! /bin/bash
#
# before-test.sh - Prepares Travis CI worker to run epanet regression tests
#
# Date Created: 04/04/2018
#
# Author: Michael E. Tryby
# US EPA - ORD/NRMRL
#
# Arguments:
# 1 - relative path regression test file staging location
# 2 - absolute path to location of software under test
# 3 - build identifier for software under test
#
# Note:
# Tests and benchmark files are stored in the epanet-example-networks repo.
# This script retreives them using a stable URL associated with a release on
# GitHub and stages the files for nrtest to run. The script assumes that
# before-test.sh and gen-config.sh are located together in the same folder.
SCRIPT_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEST_HOME=$1
EXAMPLES_VER="1.0.1"
BENCHMARK_VER="2012vs10"
TEST_URL="https://github.com/OpenWaterAnalytics/epanet-example-networks/archive/v${EXAMPLES_VER}.tar.gz"
BENCH_URL="https://github.com/OpenWaterAnalytics/epanet-example-networks/releases/download/v${EXAMPLES_VER}/epanet-benchmark-${BENCHMARK_VER}.tar.gz"
echo INFO: Staging files for regression testing
# create a clean directory for staging regression tests
if [ -d ${TEST_HOME} ]; then
rm -rf ${TEST_HOME}
fi
mkdir ${TEST_HOME}
cd ${TEST_HOME}
# retrieve epanet-examples for regression testing
curl -fsSL -o examples.tar.gz ${TEST_URL}
# retrieve epanet benchmark results
curl -fsSL -o benchmark.tar.gz ${BENCH_URL}
# extract tests and benchmarks
tar xzf examples.tar.gz
ln -s epanet-example-networks-${EXAMPLES_VER}/epanet-tests tests
mkdir benchmark
tar xzf benchmark.tar.gz -C benchmark
# generate json configuration file for software under test
mkdir apps
${SCRIPT_HOME}/gen-config.sh $2 > apps/epanet-$3.json

View File

@@ -0,0 +1,40 @@
#
# CMakeLists.txt - CMake configuration file for epanet-output library
#
# Created: March 9, 2018
# Author: Michael E. Tryby
# US EPA ORD/NRMRL
#
cmake_minimum_required (VERSION 3.0)
# Sets for output directory for executables and libraries.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# configure file groups
set(EPANET_OUT_SOURCES src/epanet_output.c src/errormanager.c)
# the binary output file API
add_library(epanet-output SHARED ${EPANET_OUT_SOURCES})
target_include_directories(epanet-output PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
include(GenerateExportHeader)
generate_export_header(epanet-output
BASE_NAME epanet_output
EXPORT_MACRO_NAME DLLEXPORT
EXPORT_FILE_NAME epanet_output_export.h
STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC)
file(COPY ${CMAKE_CURRENT_BINARY_DIR}/epanet_output_export.h DESTINATION
${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@@ -61,15 +61,19 @@ typedef enum {
} ENR_LinkAttribute; } ENR_LinkAttribute;
#ifdef WINDOWS // #ifdef WINDOWS
#ifdef __cplusplus // #ifdef __cplusplus
#define DLLEXPORT __declspec(dllexport) __cdecl // #define DLLEXPORT __declspec(dllexport) __cdecl
#else // #else
#define DLLEXPORT __declspec(dllexport) __stdcall // #define DLLEXPORT __declspec(dllexport) __stdcall
#endif // #endif
#else // #else
#define DLLEXPORT // #define DLLEXPORT
#endif // #endif
#include "epanet_output_export.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@@ -22,9 +22,11 @@ except ImportError:
setup( setup(
name = "epanet-output", name = "epanet-output",
version = "1.0", version = "0.1.0-alpha",
ext_modules = [ ext_modules = [
Extension("_epanet_output", Extension("_epanet_output",
define_macros = [('epanet_output_EXPORTS', None)],
include_dirs = ['include'],
sources = ['src/epanet_output.i', 'src/epanet_output.c', 'src/errormanager.c'], sources = ['src/epanet_output.i', 'src/epanet_output.c', 'src/errormanager.c'],
swig_opts=['-modern'], swig_opts=['-modern'],
language = 'C' language = 'C'

View File

@@ -107,8 +107,8 @@ def epanet_report_compare(path_test, path_ref, rtol, atol):
RunTimeError() RunTimeError()
... ...
''' '''
HEADER = 11 HEADER = 10
FOOTER = 3 FOOTER = 2
with open(path_test ,'r') as ftest, open(path_ref, 'r') as fref: with open(path_test ,'r') as ftest, open(path_ref, 'r') as fref:

View File

@@ -24,7 +24,7 @@ entry_points = {
setup( setup(
name='nrtest-epanet', name='nrtest-epanet',
version='0.3.0', version='0.4.0',
description="EPANET extension for nrtest", description="EPANET extension for nrtest",
author="Michael E. Tryby", author="Michael E. Tryby",
@@ -38,7 +38,7 @@ setup(
'header_detail_footer>=2.3', 'header_detail_footer>=2.3',
'nrtest>=0.2.0', 'nrtest>=0.2.0',
'numpy>=1.7.0', 'numpy>=1.7.0',
'epanet_output>=0.4.0' 'epanet_output'
], ],
keywords='nrtest_epanet' keywords='nrtest_epanet'
) )

View File

@@ -0,0 +1,19 @@
#
# requirements-appveyor.txt
#
# Date Created: 10/10/2017
# Author: Michael E. Tryby
# US EPA ORD/NRMRL
#
# Useful for configuring a python environment to run epanet-nrtestsuite
# on AppVeyor CI.
#
# command:
# $ pip install --src build/packages -r tools/requirements-appveyor.txt
#
nrtest>=0.2.3
-f https://github.com/OpenWaterAnalytics/epanet-python/releases/download/v0.1.0-alpha/epanet_output-0.1.0a0-cp27-cp27m-win32.whl
-e ./tools/nrtest-epanet

View File

@@ -11,6 +11,7 @@
# $ pip install --src build/packages -r tools/requirements.txt # $ pip install --src build/packages -r tools/requirements.txt
# #
-e git+https://github.com/OpenWaterAnalytics/nrtest.git@master#egg=nrtest #-e git+https://github.com/OpenWaterAnalytics/nrtest.git@master#egg=nrtest
nrtest>=0.2.3
-e ./tools/epanet-output -e ./tools/epanet-output
-e ./tools/nrtest-epanet -e ./tools/nrtest-epanet

View File

@@ -18,14 +18,17 @@ setlocal
set NRTEST_SCRIPT_PATH=%~1 set NRTEST_SCRIPT_PATH=%~1
set TEST_SUITE_PATH=%~2 set TEST_SUITE_PATH=%~2
set BENCHMARK_VER=220dev-vs17
set NRTEST_EXECUTE_CMD=python %NRTEST_SCRIPT_PATH%\nrtest execute set NRTEST_EXECUTE_CMD=python %NRTEST_SCRIPT_PATH%\nrtest execute
set TEST_APP_PATH=apps\epanet-%3.json set TEST_APP_PATH=apps\epanet-%3.json
set TESTS=tests\examples set TESTS=tests\examples tests\exeter tests\large tests\network_one tests\small tests\tanks tests\valves
set TEST_OUTPUT_PATH=benchmark\epanet-%3 set TEST_OUTPUT_PATH=benchmark\epanet-%3
set NRTEST_COMPARE_CMD=python %NRTEST_SCRIPT_PATH%\nrtest compare set NRTEST_COMPARE_CMD=python %NRTEST_SCRIPT_PATH%\nrtest compare
set REF_OUTPUT_PATH=benchmark\epanet-2012 set REF_OUTPUT_PATH=benchmark\epanet-%BENCHMARK_VER%
set RTOL_VALUE=0.1 set RTOL_VALUE=0.01
set ATOL_VALUE=0.0 set ATOL_VALUE=0.0
:: change current directory to test suite :: change current directory to test suite
@@ -41,6 +44,8 @@ set NRTEST_COMMAND=%NRTEST_EXECUTE_CMD% %TEST_APP_PATH% %TESTS% -o %TEST_OUTPUT_
:: if there is an error exit the script with error value 1 :: if there is an error exit the script with error value 1
%NRTEST_COMMAND% || exit /B 1 %NRTEST_COMMAND% || exit /B 1
echo.
echo INFO: Comparing test and ref benchmark echo INFO: Comparing test and ref benchmark
set NRTEST_COMMAND=%NRTEST_COMPARE_CMD% %TEST_OUTPUT_PATH% %REF_OUTPUT_PATH% --rtol %RTOL_VALUE% --atol %ATOL_VALUE% set NRTEST_COMMAND=%NRTEST_COMPARE_CMD% %TEST_OUTPUT_PATH% %REF_OUTPUT_PATH% --rtol %RTOL_VALUE% --atol %ATOL_VALUE% -o receipt.json
%NRTEST_COMMAND% %NRTEST_COMMAND%

View File

@@ -9,7 +9,7 @@
# US EPA - ORD/NRMRL # US EPA - ORD/NRMRL
# #
# Arguments: # Arguments:
# 1 - test suite path # 1 - relative path to location there test suite is staged
# 2 - version/build identifier # 2 - version/build identifier
# #
@@ -19,14 +19,16 @@ run-nrtest()
return_value=0 return_value=0
test_suite_path=$1 test_suite_path=$1
benchmark_ver="2012vs10"
nrtest_execute_cmd="nrtest execute" nrtest_execute_cmd="nrtest execute"
test_app_path="apps/epanet-$2.json" test_app_path="apps/epanet-$2.json"
tests="tests/examples" tests="tests/examples tests/exeter tests/large tests/network_one tests/small tests/tanks tests/valves"
test_output_path="benchmark/epanet-$2" test_output_path="benchmark/epanet-$2"
nrtest_compare_cmd="nrtest compare" nrtest_compare_cmd="nrtest compare"
ref_output_path="benchmark/epanet-2012" ref_output_path="benchmark/epanet-${benchmark_ver}"
rtol_value=0.1 rtol_value=0.1
atol_value=0.0 atol_value=0.0

43
tools/test-config.sh Normal file
View File

@@ -0,0 +1,43 @@
#! /bin/bash
#
# test-config.sh - Generates nrtest test configuration file for test case.
#
# Date Created: 3/19/2018
#
# Author: Michael E. Tryby
# US EPA - ORD/NRMRL
#
# Arguments:
# 1 - name
# 2 - version
# 3 - description
#
# Suggested Usage:
# $ for file in .//*; do ./test-config.sh $file 1.0 > "${file%.*}.json"; done
#
filename="$1"
name="${filename%.*}"
version="$2"
description="$3"
cat<<EOF
{
"name": "${name}",
"version": "${version}",
"description": "${description}",
"args": [
"${name}.inp",
"${name}.rpt",
"${name}.out"
],
"input_files": [
"${name}.inp"
],
"output_files": {
"${name}.rpt": "epanet report",
"${name}.out": "epanet allclose"
}
}
EOF

View File

@@ -25,7 +25,8 @@ END {
print "# Authors ordered by first contribution.\n"; print "# Authors ordered by first contribution.\n";
print "# Generated by tools/update-authors.sh\n"; print "# Generated by tools/update-authors.sh\n";
print "\n", @authors; print "\n", @authors;
print "\n*** = works in the public domain";
} }
' > ../AUTHORS '

View File

@@ -21,9 +21,9 @@ Find /i "x86" < checkOS.tmp > StringCheck.tmp
If %ERRORLEVEL% == 1 ( If %ERRORLEVEL% == 1 (
CALL "%SDK_PATH%bin\"SetEnv.cmd /x64 /release CALL "%SDK_PATH%bin\"SetEnv.cmd /x64 /release
rem : create EPANET2.DLL rem : create EPANET2.DLL
cl -o epanet2.dll epanet.c hash.c hydraul.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c /I ..\include /I ..\run /link /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 /I ..\include /I ..\run /link /DLL
rem : create EPANET2.EXE rem : create EPANET2.EXE
cl -o epanet2.exe epanet.c ..\run\main.c hash.c hydraul.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c /I ..\include /I ..\run /I ..\src /link 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 /I ..\include /I ..\run /I ..\src /link
md "%Build_PATH%"\64bit md "%Build_PATH%"\64bit
move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\64bit move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\64bit
move /y "%SRC_PATH%"\*.exe "%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 CALL "%SDK_PATH%bin\"SetEnv.cmd /x86 /release
echo "32 bit with epanet2.def mapping" echo "32 bit with epanet2.def mapping"
rem : create EPANET2.DLL rem : create EPANET2.DLL
cl -o epanet2.dll epanet.c hash.c hydraul.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c /I ..\include /I ..\run /link /DLL /def:..\win_build\WinSDK\epanet2.def /MAP 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 /I ..\include /I ..\run /link /DLL /def:..\win_build\WinSDK\epanet2.def /MAP
rem : create EPANET2.EXE rem : create EPANET2.EXE
cl -o epanet2.exe epanet.c ..\run\main.c hash.c hydraul.c inpfile.c input1.c input2.c input3.c mempool.c output.c quality.c report.c rules.c smatrix.c /I ..\include /I ..\run /I ..\src /link 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 /I ..\include /I ..\run /I ..\src /link
md "%Build_PATH%"\32bit md "%Build_PATH%"\32bit
move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\32bit move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\32bit
move /y "%SRC_PATH%"\*.exe "%Build_PATH%"\32bit move /y "%SRC_PATH%"\*.exe "%Build_PATH%"\32bit

View File

@@ -88,3 +88,8 @@ EXPORTS
ENsetfalseaction = _ENsetfalseaction@20 ENsetfalseaction = _ENsetfalseaction@20
ENgetruleID = _ENgetruleID@8 ENgetruleID = _ENgetruleID@8
ENsetflowunits = _ENsetflowunits@4 ENsetflowunits = _ENsetflowunits@4
ENaddnode = _ENaddnode@8
ENaddlink = _ENaddlink@16
ENdeletelink = _ENdeletelink@4
ENdeletenode = _ENdeletenode@4
ENsetlinktype = _ENsetlinktype@8