v2.2
* removing reference to strncpy * Fixing memory problems with test_toolkit Fixes memory leaks and some minor refactoring. * Update test_toolkit.hpp removing crtdbg.h from header * Update CMakeLists.txt Restoring test_net_builder to test_toolkit.exe * Cleaning up include statements adding crtdbg.h * Fixing index error in test * Add more analysis options to the API (issue #425) * Fixed epanet2_enums.h * Eliminates use of temporary linked lists to process Patterns & Curves (issue #449) * Update input2.c * Bug fix for 2Comp and LIFO tank mixing models (issue #448) * Triggering build to update benchmarks * Added new reg tests Updating reference build id * Initial commit list generic linked list * Update test_list.cpp Tests are passing * Update list.h Adding documentation * Fix typo * Fixing bug in head_list * Fixing indentation * Fixed memory leak Fixed memory leak in test_head_list * Clean up and inline comments * Updating file headers * Update list.c Updating in line comments. * Update test_list.cpp * Fixing indent Spaces not tabs * Update list.c Fixing indent * Update test_list.cpp Updating file header to reflect proper attribution * Expanding test Added test where data is a struct * Fixing indent * Work in progress * Reorganized to contain list abstraction * Update list.c * Refactoring head_list and tail_list Simplifying head and tail list. Adding delete_node() to list API. * Update test_list.cpp * Update test_list.cpp Fixing bug on gcc * Fixing bug * Fixing bug on gcc * Update CMakeLists.txt Adding test_list to ctest * Fixes memory leak in EN_addnode() (#455) * Fixing memory leak in EN_addnode() * Separating test_net_builder from test_toolkit Making test_net_builder a standalone test * Removing BOOST_TEST_MAIN * Work in progress * Updating unit tests * Fixing compilation bug on gcc * Work in progress compiles with warnings, definitely not working * Update demand.h * Work in progress Implementing demand_list * Work in progress Creating function for validateing element ID strings * Work in progress Refactoring cstr_copy and adding test * Update cstr_helper.c fixing indentation * Update cstr_helper.c Fixing indentation * Update test_cstrhelper.cpp Fixed mem leak * Adding element id validity checks * Adding element id validity check Adding checks for element set id functions * Fixing build warnings on gcc * Update errror code from 250 to 252 * Work in progress Implementing generic demand pattern lists. Compiles but does not run. * Update demand.c Work in progress * Return object index from EN_addnode and EN_addlink (issue #432) Adds an output argument to EN_addnode and EN_addlink that returns the index of the newly added object. Also refactors the validity check on object ID names. * Fixed compilation errors * Update test_node.cpp * Create test_demand_data.cpp * test demand data passing * Work in progress Fixing problems when demand lists are null * Passing open and close test * get/set demand name are passing * Updated criteria for valid object ID name * Work in progress * Work in progress Working on demand lists * Work in progress Fixing memory leaks Unit tests passing * Cleaning up build on gcc * Cleaning up gcc build * Fixing bug * Working on gcc bug Tests are passing on Appveyor * Update inpfile.c Trying to isolate bug * GCC Bug * Refactored xstrcpy function * Update inpfile.c Testing linux build * Update epanet.c Trying to isolate bug * updating get demand name and write demands Everything passing locally * Update test_project.cpp Isolating bug on gcc * Isolating bug Not writing demand section of input file should eliminate it * Update demand.c Fixing bug in get_category_name when category_name is NULL * Restoring write_demands section in saveinpfile * Update test_demand_data.cpp Adding index to addnode calls. Fixing indent * Update demand.c * Reverted handling of default pattern When creating demands, no pattern is marked with a zero. Then when data is adjusted it gets updated to default. * Update epanet.c Updating EN_getnodevalue() and EN_setnodevalue() to process the primary demand located at the head of the demand list * Update demand.c * Work in progress code cleanup, addressed issue raised in review, and implemented EN_adddemand() * Adding key and search to list * Adding remove node method to generic list * Adding remove demand method to toolkit * Fix bug and test remove demand * Fix problems with setting tank parameters (issue #464 ) * Fixed NULL pointer error, if no label is provided after the rule keyword. * Create Makefile2.bat Co-Authored-By: Demetrios G. Eliades <eldemet@users.noreply.github.com> Co-Authored-By: Elad Salomons <selad@optiwater.com> * Create LICENSE * Fixed NULL pointer error, if no label is provided after the rule keyword. Add NULL guard in freerules function. Use strncat and strncpy to ensure the buffer lengths are adhered to. * For "conditional" do delete a node connected to a link For "conditional" deletion the node is deleted only if all of its links have been explicitly deleted beforehand #473 Co-Authored-By: Lew Rossman <lrossman@outlook.com> * Create CODE_OF_CONDUCT.md * Refactors the API's demand editing functions * Update test_demand.cpp * Update CODE_OF_CONDUCT.md * Update rules.c Fix broken win build script * Updates to doc files * Documentation edits * Update Makefile.bat Updates on the Microsoft SDK 7.1 compilation script to generate runepanet.exe and to use the \include\epanet2.def * Update Makefile2.bat Modified epanet2.exe to runepanet.exe, for consistency. * Delete epanet2.def Deleted the redundant `epanet2.def` file in the WindSDK folder * Minor format change to status report * Removing status reports from CI testing * rm WinSDK folder and update Makefiles Co-Authored-By: Demetrios G. Eliades <eldemet@users.noreply.github.com> * Restored CI testing of status reports * Removes _DEBUG directives from all source files This commit removes the #ifdef _DEBUG statements at the top of all source code files per issue #482. It also updates the doc files to stress that the speedup observed for hydraulic analysis with the MMD node re-ordering method only applies to single period runs. * Fix refactor of types.h * updates authors * updates AUTHORS and generator script * Update run\CMakeLists.txt * add help file win_build.md Co-Authored-By: Elad Salomons <selad@optiwater.com> * move win_build.md to root dir and renaiming to BUILDING.md * Move BuildAndTest.md to the tools directory * Update BUILDING.md * Update BUILDING.md * Update BUILDING.md * Fixes problem with findpattern() function (issue #498) * Change default properties for new pipe created with EN_addlink (issue #500) * Numerous updates to project documentation * Adds tank overflow feature * Updating docs for tank overflow feature * Updating VB include files * Update input3.c * Identifies overflowing tank in Status Report * Update Makefile.bat * Update Makefile2.bat #508 * rethinking the python wrapper (#511) * renames certain function parameter declarations and removes double pointer call from the deleteproject function * deprecates conditonal compilation, removes python-specific headers and function renaming * fixes tests and docs * fixes test * PDA fixes * Minor update to force new CI test * Another minor change to force another CI test * Fixes Overflow and PDA tests not being run * Fix EN_getElseaction and EN_setelseaction Co-Authored-By: Andreas Ashikkis <andreasashikkis@users.noreply.github.com> * Add -MT switch for CMake Windows build * Updates to the docs * Update BUILDING.md * Build script updates * Fixes EN_setlinkvalue bug * fix in EN_deleteLink when pipes are deleted via deletelink it also deletes comment of last link Co-Authored-By: Pavlos Pavlou <pavlou.v.pavlos@ucy.ac.cy> * rm set to null in functions EN_deletenode, EN_deletelink * trial actions config * Update ccpp.yml * welcome to the Actions beta * fixes mkstemp file handle-leaking behavior (#529) * reverts posix include (#533) ... because it is not needed * Fixes bugs in pump and demand head loss gradients * Removed dependence on unistd.h in project.c Travis CI failed because system could not find unistd.h. * getTmpName() and xstrcpy() made safer * Fixed use of strncpy in xstrcpy() * Refactor of hydcoeffs.c Simplifies and unifies how limit on head gradient at low flow is handled. * Update ReleaseNotes2_2.md * Return error if node/link name is too long (#535) * co-authored with @ehsan-shafiee * removes errant slashes * Throws correct error for ID name too long * Revert "Throws correct error for ID name too long" This reverts commit 57b4873f5882cb9fd983f7e1e5a703b9e442cd74. * fixes #534 by bubbling error codes up from add node/link internal functions * fixes tests on Mac at least * fixes improper success code * Error 252 (not 250) returned for ID name too long. From errors.dat: DAT(252,"invalid ID name") * Fixes problems with EN_addnode() (#543) See issue #542 . Also modifies unit test test_node to check that fixup works. * Adds EN_getresultindex function to the API See issue #546 . Also fixes a small bug in project.c. * Adds link vertex get/set functions to the API * Fixes to EN_addlink and EN_deletelink * Updates the docs * Bug fix for EN_setcurve Adjusts params of any pump that uses the curve whose data is modified by EN_setcurve or EN_setcurvevalue (issue #550 ). * Bug fix for EN_getrule Fixes possible seg fault condition in EN_getrule. Also defines EN_MISSING as an API constant since it can be assigned internally to several variables that are retrievable by the API. * Updating the docs * Adds error check to EN_setheadcurveindex See issue #556 . * Update epanet2.pas * Incorrect characterd There was a character ’ instead of ' which created an error when compiling LaTeX. * fixes a crashing issue in freedata (#559) The freedata function used cached values for sizes of certain arrays found in the parser struct. However, now that the network is mutable, those values can become invalid. Relying instead on the actual array lengths prevents freeing unallocated memory, or ignoring cleanup on newly created elements. * Bug fix for valvecheck function See issue #561 * Restored prior update to project.c that got overwritten * Fixed editing errors made to project.c * PDF Guide PDF users' guide for EPANET, and some minor corrections to readme.md to fix some formatting issues. * HTML Users Guide * Fixes a "copy over" bug in input3.c The copying of one input line token over another was causing a compilation error under Clang. With v2.2 this copying is no longer needed so the line of code in question was simply deleted. This commit also deletes the HTML and Latex output generated by running Doxygen that got added from the previous update to dev since they don't really belong in a source code repo. * Correction made to doc files The output-format.dox file was deprecated and not included in the doxyfile so it was deleted. The description of the format of of the Energy Usage section of the binary output in toolkit-files.dox was corrected. * Update ReleaseNotes2_2.md I added the v2.2 contributing authors to the notes. I checked PR's from 2017 and beyond and these were the only names I could find. Please append any one I might have missed. * Fixes problem with re-opening const. HP pumps See latest comments in issue #528. Also, the setlinkflow() function was deleted as it was never called anywhere. * Update README.md (#539) * Update README.md * Update README.md Some section titles were re-named to conform to GitHub guidelines and the OWA info was moved to a CREDITS section. * Update README.md Added link to the Community Forum page. * Replaced OWA copyright with "(see AUTHORS)". * Update AUTHORS Copied format used by the OWA-SWMM project. * Update README.md The Disclaimer section was edited to reflect that there actually is a "collaborative" connection between USEPA and OWA. * updates CI badges * cleanup of readme links and unused files * possessive vs contraction * adding contributor to notes
This commit is contained in:
19
.github/workflows/ccpp.yml
vendored
Normal file
19
.github/workflows/ccpp.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: setup_build_dir
|
||||
run: mkdir buildproducts
|
||||
- name: cmake
|
||||
working-directory: ./buildproducts
|
||||
run: cmake ..
|
||||
- name: make
|
||||
working-directory: ./buildproducts
|
||||
run: make
|
||||
34
.gitignore
vendored
34
.gitignore
vendored
@@ -41,7 +41,6 @@ xcuserdata
|
||||
*~.nib/
|
||||
*.swp
|
||||
*~
|
||||
*.dat
|
||||
*.dep
|
||||
|
||||
*.xcodeproj/
|
||||
@@ -202,3 +201,36 @@ $RECYCLE.BIN/
|
||||
# WindSDK compiled folders
|
||||
build/WinSDK/32bit/
|
||||
build/WinSDK/64bit/
|
||||
=======
|
||||
|
||||
|
||||
# Python compiler files
|
||||
*.py[c]
|
||||
|
||||
# Python distribution and packaging
|
||||
dist/
|
||||
temp/
|
||||
*.cfg
|
||||
*.egg-info/
|
||||
|
||||
# Eclipse Stuff
|
||||
.metadata/
|
||||
.settings/
|
||||
.project
|
||||
.cproject
|
||||
.pydevproject
|
||||
|
||||
# Testing Stuff
|
||||
nrtestsuite/
|
||||
tests/data/
|
||||
tests/outfile/data/en*
|
||||
|
||||
|
||||
#Cmake stuff
|
||||
__cmake_systeminformation/
|
||||
buildprod*/
|
||||
*_export.h
|
||||
|
||||
|
||||
# git merge
|
||||
*.orig
|
||||
|
||||
15
.mailmap
15
.mailmap
@@ -1,4 +1,3 @@
|
||||
Sam Hatchett <samhatchett@gmail.com>
|
||||
James Uber <jim@citilogics.com>
|
||||
Demetrios Eliades <eldemet@gmail.com>
|
||||
Hyoungmin Woo <hyoungmin.woo@gmail.com>
|
||||
@@ -6,4 +5,16 @@ Hyoungmin Woo <hyoungmin.woo@gmail.com> <woohn@mail.uc.edu>
|
||||
Yunier Soad <yunier.soad@gmail.com>
|
||||
Jinduan Chen <jinduan.uc@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>
|
||||
Marios Kyriakou <mariosmsk@gmail.com> <mariosmsk@mariosmsk.com>
|
||||
Sam Hatchett <samhatchett@gmail.com>
|
||||
Sam Hatchett <samhatchett@gmail.com> <sam.hatchett@xyleminc.com>
|
||||
Markus Sunela <markus.sunela@fluidit.fi>
|
||||
Markus Sunela <markus.sunela@fluidit.fi> <30700548+makusuko@users.noreply.github.com>
|
||||
Lew Rossman <LRossman@cinci.rr.com>
|
||||
Lew Rossman <LRossman@cinci.rr.com> <LRossman@outlook.com>
|
||||
Michael Tryby <tryby.michael@epa.gov> michaeltryby <tryby.michael@epa.gov>
|
||||
|
||||
62
.travis.yml
62
.travis.yml
@@ -1,12 +1,58 @@
|
||||
language: c
|
||||
language: python
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# works on Precise and Trusty
|
||||
- os: linux
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'ppa:mhier/libboost-latest'
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-7
|
||||
- boost1.67
|
||||
env:
|
||||
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
|
||||
- PLATFORM="linux"
|
||||
- REF_BUILD_ID="220dev1"
|
||||
|
||||
python:
|
||||
- "3.6"
|
||||
|
||||
env:
|
||||
global:
|
||||
- SUT_BUILD_ID=$TRAVIS_JOB_NUMBER
|
||||
- EPANET_HOME=`pwd`
|
||||
- BUILD_HOME=buildprod
|
||||
- TEST_HOME=nrtestsuite
|
||||
|
||||
before_install:
|
||||
# - sudo apt-get -qq update
|
||||
- eval "${MATRIX_EVAL}"
|
||||
|
||||
#install:
|
||||
# - sudo apt-get install -y libboost-test-dev
|
||||
# - sudo apt-get install -y libboost-thread-dev
|
||||
|
||||
before_script:
|
||||
- cd build/CMake
|
||||
- mkdir buildproducts
|
||||
- cd buildproducts
|
||||
- cmake ..
|
||||
- mkdir -p $BUILD_HOME
|
||||
- cd $BUILD_HOME
|
||||
- cmake -DCMAKE_C_COMPILER=${CC}
|
||||
-DCMAKE_CXX_COMPILER=${CXX}
|
||||
-DBUILD_TESTS=ON
|
||||
-DBUILD_COVERAGE=ON ..
|
||||
|
||||
script:
|
||||
- make
|
||||
- cd ../../../tests
|
||||
- ./test_networks.sh
|
||||
- cmake --build .
|
||||
# run unit tests
|
||||
- cd tests
|
||||
- ctest --output-on-failure
|
||||
# run regression tests
|
||||
- cd $EPANET_HOME
|
||||
- pip install -r tools/requirements.txt
|
||||
- tools/before-test.sh $PLATFORM $REF_BUILD_ID $SUT_BUILD_ID $TRAVIS_COMMIT
|
||||
- tools/run-nrtest.sh -c -s $SUT_BUILD_ID
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
13
AUTHORS
13
AUTHORS
@@ -1,8 +1,12 @@
|
||||
# Authors ordered by first contribution.
|
||||
# Generated by tools/update-authors.sh
|
||||
|
||||
Lew Rossman <LRossman@cinci.rr.com>
|
||||
Authors with Contributions in the Public Domain:
|
||||
|
||||
Lewis Rossman <LRossman@cinci.rr.com>
|
||||
Michael Tryby <tryby.michael@epa.gov>
|
||||
|
||||
Authors with Contributions Subject to Copyright (see LICENSE):
|
||||
|
||||
Sam Hatchett <samhatchett@gmail.com>
|
||||
Feng Shang <fshang>
|
||||
James Uber <jim@citilogics.com>
|
||||
@@ -14,7 +18,10 @@ Mike Kane <muke195@gmail.com>
|
||||
Demetrios Eliades <eldemet@gmail.com>
|
||||
Will Furnass <will@thearete.co.uk>
|
||||
Steffen Macke <sdteffen@sdteffen.de>
|
||||
Mariosmsk <mariosmsk@gmail.com>
|
||||
Marios Kyriakou <mariosmsk@gmail.com>
|
||||
Elad Salomons <selad@optiwater.com>
|
||||
Maurizio Cingi <mrzcng2@gmail.com>
|
||||
Bryant McDonnell <bemcdonnell@gmail.com>
|
||||
Angela Marchi <angela.marchi@adelaide.edu.au>
|
||||
Markus Sunela <markus.sunela@fluidit.fi>
|
||||
Milad Ghiami <milad-ghiami@users.noreply.github.com>
|
||||
|
||||
19
BUILDING.md
Normal file
19
BUILDING.md
Normal file
@@ -0,0 +1,19 @@
|
||||
The most straightforward way to build the EPANET files is by using `CMake` ([https://cmake.org/](https://cmake.org/)). `CMake` is a cross-platform build tool that generates platform native build systems that can be used with your compiler of choice. It uses a generator concept to represent different build tooling. `CMake` automatically detects the platform it is running on and generates the appropriate makefiles for the platform default compiler. Different generators can also be specified.
|
||||
|
||||
The project's `CMake` file (`CMakeLists.txt`) is located in its root directory and supports builds for Linux, Mac OS and Windows. To build the EPANET library and its command line executable using `CMake`, first open a console window and navigate to the project's root directory. Then enter the following commands:
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
Note: under Windows, the third command should be `cmake .. -A Win32` for a 32-bit build or `cmake .. -A x64` for a 64-bit build when Microsoft Visual Studio is the default compiler.
|
||||
|
||||
For Windows the resulting EPANET toolkit library `epanet2.dll` and its command line executable `runepanet.exe` are placed in the `build\bin\Release` directory. The `build\lib\Release` directory will contain an `epanet2.lib` file which is needed to build C/C++ applications using the Windows version of the library. For Linux and Mac OS the EPANET toolkit shared library `libepanet2.so` appears in the `build/lib` directory and the command line executable `runepanet` is in the `build/bin` directory.
|
||||
|
||||
In addition, two Windows one-click-build scripts are included in the `win_build` directory:
|
||||
1. `Makefile2.bat`: this script uses the `CMake` file and requires the build tools for Visual Studio available from [https://visualstudio.microsoft.com/downloads/](https://visualstudio.microsoft.com/downloads/). The Community version will work just fine. This script was tested with Visual Studio 2017 and 2019.
|
||||
2. `Makefile.bat`: this is the legacy build script compatible with Visual Studio 2010 which conforms with the C89 Standard which was the standard EPANET supported from earlier versions. This script requires the installation of Microsoft Windows SDK 7.1 ([https://www.microsoft.com/en-us/download/details.aspx?id=8279](https://www.microsoft.com/en-us/download/details.aspx?id=8279)) and will probably not run correctly on later versions of the SDK. `CMake` is not used in this script.
|
||||
|
||||
These two scripts build EPANET binaries for both the 32 and 64 bit Windows platforms, placing them in the `win_build\32bit` and `win_build\64bit` directories, respectively.
|
||||
102
CMakeLists.txt
Normal file
102
CMakeLists.txt
Normal file
@@ -0,0 +1,102 @@
|
||||
# CMakeLists.txt - CMake configuration file for EPANET 2.0
|
||||
#
|
||||
# CMake is a cross-platform build tool. CMake generates platform native
|
||||
# build systems that can be used with your compiler of choice. CMake uses a
|
||||
# generator concept to represent different build tooling. CMake automatically
|
||||
# detects the platform it is running on and generates the appropriate makefiles
|
||||
# for the platform default compiler. Different generators can also be specified.
|
||||
#
|
||||
# Note: CMake requires that your platform build system and compiler are
|
||||
# properly installed. Build using Visual Studio requires msbuild shell.
|
||||
#
|
||||
# Build Options:
|
||||
# BUILD_TESTS = ON/OFF
|
||||
# BUILD_PY_LIB = ON/OFF
|
||||
#
|
||||
# Generic Invocation:
|
||||
# cmake -E make_directory buildprod
|
||||
# cd build
|
||||
# cmake -G GENERATOR -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ..
|
||||
# cmake --build . --target SOME_TARGET --config Release
|
||||
#
|
||||
# More information:
|
||||
# cmake --help
|
||||
#
|
||||
# CMake is available at https://cmake.org/download/
|
||||
#
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.8)
|
||||
|
||||
project(EPANET)
|
||||
|
||||
# Append local dir to module search path
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
option(BUILD_TESTS "Build tests (requires Boost)" OFF)
|
||||
option(BUILD_PY_LIB "Build library for Python wrapper" OFF)
|
||||
option(BUILD_COVERAGE "Build library for coverage" OFF)
|
||||
|
||||
|
||||
IF (NOT BUILD_PY_LIB)
|
||||
add_subdirectory(run)
|
||||
ENDIF (NOT BUILD_PY_LIB)
|
||||
add_subdirectory(src/outfile)
|
||||
|
||||
IF (BUILD_TESTS)
|
||||
#Prep ourselves for compiling with boost
|
||||
IF(WIN32)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
ELSE(TRUE)
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
add_definitions(-DBOOST_ALL_DYN_LINK)
|
||||
ENDIF(WIN32)
|
||||
|
||||
find_package(Boost COMPONENTS unit_test_framework system thread filesystem)
|
||||
include_directories (${Boost_INCLUDE_DIRS})
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
add_subdirectory(tests/outfile)
|
||||
add_subdirectory(tests/util)
|
||||
ENDIF (BUILD_TESTS)
|
||||
|
||||
|
||||
# Sets the 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)
|
||||
|
||||
|
||||
IF (APPLE)
|
||||
set(INSTALL_NAME_DIR @executable_path/../lib)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
ENDIF (APPLE)
|
||||
|
||||
IF (MSVC)
|
||||
set(CMAKE_C_FLAGS_RELEASE "/GL")
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -MT)
|
||||
ENDIF (MSVC)
|
||||
|
||||
# configure file groups
|
||||
file(GLOB EPANET_SOURCES RELATIVE ${PROJECT_SOURCE_DIR} src/*.c src/util/*.c)
|
||||
file(GLOB EPANET_LIB_ALL RELATIVE ${PROJECT_SOURCE_DIR} src/* src/util/*)
|
||||
# exclude epanet python API from the default build
|
||||
list(REMOVE_ITEM EPANET_LIB_ALL "src/epanet_py.c")
|
||||
source_group("Library" FILES ${EPANET_LIB_ALL})
|
||||
|
||||
# the shared library
|
||||
IF(MSVC AND "${CMAKE_VS_PLATFORM_NAME}" MATCHES "(Win32)")
|
||||
message(" ************************************")
|
||||
message(" Configuring with epanet2.def mapping")
|
||||
message(" ************************************")
|
||||
add_library(epanet2 SHARED ${EPANET_LIB_ALL} ${PROJECT_SOURCE_DIR}/include/epanet2.def)
|
||||
set_source_files_properties(${PROJECT_SOURCE_DIR}/include/epanet2.def PROPERTIES_HEADER_FILE_ONLY TRUE)
|
||||
ELSE(TRUE)
|
||||
add_library(epanet2 SHARED ${EPANET_LIB_ALL})
|
||||
ENDIF(MSVC AND "${CMAKE_VS_PLATFORM_NAME}" MATCHES "(Win32)")
|
||||
|
||||
target_include_directories(epanet2 PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting any member of the [project team](https://github.com/OpenWaterAnalytics/EPANET/wiki/Project-Team). All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Open Water Analytics
|
||||
Copyright (c) 2017 (see AUTHORS)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
33
README.md
33
README.md
@@ -1,14 +1,33 @@
|
||||
EPANET {#epanet-readme}
|
||||
OWA-EPANET
|
||||
======
|
||||
|
||||
[](https://travis-ci.org/OpenWaterAnalytics/EPANET)
|
||||
## Build Status
|
||||
[](https://ci.appveyor.com/project/OpenWaterAnalytics/epanet)
|
||||
[](https://travis-ci.org/OpenWaterAnalytics/EPANET)
|
||||
|
||||
The EPANET Library is a pressurized pipe network hydraulic and water quality analysis toolkit written in C.
|
||||
[](https://codecov.io/gh/OpenWaterAnalytics/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).
|
||||
## DESCRIPTION
|
||||
|
||||
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.
|
||||
**EPANET** is an industry-standard program for modeling the hydraulic and water quality behavior of water distribution system pipe networks. The EPANET Programmer's Toolkit is a library of functions (or API) written in C that allow programmers to customize the use of EPANET's solution engine for their own applications. Both EPANET and its toolkit were originally developed by the U.S. Environmental Protection Agency (USEPA). If you are interested in using/extending the EPANET engine and its API for academic, personal, or commercial use, then you've come to the right place. [Read more about EPANET on Wikipedia](https://en.wikipedia.org/wiki/EPANET). (Please note that this project covers only the EPANET hydraulic and water quality solver engine, not the graphical user interface.)
|
||||
|
||||
__Note:__ This repository is not affiliated with, or endorsed by, the USEPA. For the last "official" release of EPANET (2.00.12 UI and Toolkit) please go to the [EPA's GitHub repo](https://github.com/USEPA/Water-Distribution-Network-Model) or [the USEPA website](http://www2.epa.gov/water-research/epanet). It is also not the graphical user interface version. This is the hydraulic and water quality solver engine.
|
||||
## INSTALLATION
|
||||
|
||||
However, if you are interested in 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).
|
||||
Instructions for building the OWA-EPANET Toolkit's function library as well as its command line executable from the source files in this repository can be found [here](https://github.com/OpenWaterAnalytics/EPANET/blob/master/BUILDING.md).
|
||||
|
||||
## USAGE
|
||||
|
||||
See the [full documentation](http://wateranalytics.org/EPANET/) of the OWA-EPANET API, along with examples of how to use the toolkit for water distribution system analysis. Additional information may be found on this project's [Wiki](https://github.com/openwateranalytics/epanet/wiki).
|
||||
|
||||
## CONTRIBUTING
|
||||
|
||||
Everyone is welcome to participate in this project. Whether you are helping others to resolve issues, reporting a new issue that hasn't yet been discovered, suggesting a new feature that would benefit your workflow, or writing code (or tests, or scripts, or ...), we value your time and effort. The path for contribution starts with the [Issues](https://github.com/OpenWaterAnalytics/EPANET/issues). Look around at open Issues and the conversation around them, get engaged by commenting on an outstanding Issue or creating a new one. If you want to contribute code, it helps to give the community time to discuss the ideas you present and offer constructive feedback. Once you get a clear path forward, Fork this repo to your own account. Make your commits on your dev branch (or one based on dev). Once you are finished, you can open a Pull Request to test the code and discuss merging your changes back into the community repository. A [step-by-step tutorial](http://www.slideshare.net/demetriseliades/contributing-to-epanet-using-github-in-windows) on how to contribute to OWA-EPANET using GitHub is also available.
|
||||
|
||||
## CREDITS
|
||||
|
||||
The **Open Water Analytics** (OWA) Community is an international group of EPANET developers and users, whose objective is to provide group interaction and coordinated development of the EPANET codebase, to ensure that important new user interface and algorithmic features are identified and that these features progress efficiently from prototype code to production implementations. OWA is actively maintaining OWA-EPANET, a community-supported branch of USEPA EPANET, since May 2014. The full list of individuals contributing to this project can be found [here](https://github.com/OpenWaterAnalytics/EPANET/blob/dev/AUTHORS).
|
||||
|
||||
## DISCLAIMER
|
||||
Although OWA is not formally affiliated with nor endorsed by USEPA, this project has been a collaborative effort between the two that builds upon and extends the USEPA’s legacy EPANET 2.0 code base. For the last "official" release of EPANET please go to the [USEPA website](http://www2.epa.gov/water-research/epanet).
|
||||
|
||||
For more general community discussion, FAQ, and roadmapping of the project, please go to the [Community Forum](http://community/wateranalytics.org).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Release Notes for EPANET 2.1 {#release_2_1}
|
||||
============================
|
||||
|
||||
The last update to the EPANET engine was "Build 2.00.12" in February of 2008. Since that time, a community effort to update and extend the open-source code has emerged. This group has made a number of bug-fixes and API additions that help to improve the EPANET engine for everyone. Version 2.1 is now released after 8.5 years.
|
||||
The last update to the EPANET engine was "Build 2.00.12" in February of 2008. Since that time, a community effort to update and extend the open-source code has emerged. This group has made a number of bug-fixes and API additions that help to improve the EPANET engine for everyone. Version 2.1 was released in July 2016, after 8.5 years.
|
||||
|
||||
Contributors to this version (listed in order of first contribution):
|
||||
|
||||
@@ -80,14 +80,15 @@ Contributors to this version (listed in order of first contribution):
|
||||
|
||||
```
|
||||
ENopenH();
|
||||
ENopenQ();
|
||||
ENinitH(0);
|
||||
ENinitQ(EN_NOSAVE);
|
||||
do {
|
||||
ENrunH(&t);
|
||||
ENrunQ(&qt);
|
||||
ENnextQ(&qstep);
|
||||
// collect results
|
||||
ENnextH(&tstep);
|
||||
ENnextQ(&qstep);
|
||||
} while (tstep > 0);
|
||||
ENcloseQ();
|
||||
ENcloseH();
|
||||
|
||||
299
ReleaseNotes2_2.md
Normal file
299
ReleaseNotes2_2.md
Normal file
@@ -0,0 +1,299 @@
|
||||
Release Notes for EPANET 2.2
|
||||
============================
|
||||
This document describes the changes and updates that have been made in version 2.2 of EPANET.
|
||||
|
||||
## Thread-Safe API Functions
|
||||
|
||||
A duplicate set of API functions has been provided that allow multiple EPANET projects to be analyzed concurrently in a thread-safe manner. These functions maintain the same name as the original but use a `EN_` prefix instead of `EN`. In addition, the first argument to each of these functions is a handle that identifies the particular project being analyzed. For example, instead of writing:
|
||||
|
||||
`ENgetnodevalue(nodeIndex, EN_ELEVATION, &elev)`
|
||||
|
||||
one would use:
|
||||
|
||||
`EN_getnodevalue(ph, nodeIndex, EN_ELEVATION, &elev)`
|
||||
|
||||
where `ph` is the handle assigned to the project.
|
||||
|
||||
Two new functions have been added to the API to manage the creation and deletion of project handles. `EN_createproject` creates a new project along with its handle, while `EN_deleteproject` deletes a project. An example of using the thread-safe version of the API is shown below:
|
||||
```
|
||||
#include "epanet2_2.h"
|
||||
int runEpanet(char *finp, char *frpt)
|
||||
{
|
||||
EN_Project ph = 0;
|
||||
int err;
|
||||
err = EN_createproject(&ph);
|
||||
if (err) return err;
|
||||
err = EN_open(ph, finp, frpt, "");
|
||||
if (!err) err = EN_solveH(ph);
|
||||
if (!err) err = EN_report(ph);
|
||||
EN_close(ph);
|
||||
EN_deleteproject(ph);
|
||||
return err;
|
||||
}
|
||||
```
|
||||
Prototypes of the thread-safe functions appear in the `epanet2_2.h` header file while `epanet2.h` contains prototypes of the legacy-style API functions. The enumerated constants used with both types of functions have been moved to `epanet2_enums.h`.
|
||||
|
||||
## Network Building By Code
|
||||
|
||||
API users now have the ability to build a complete EPANET network model using just function calls, without the need to open an EPANET-formatted input file. All types of network objects can be created and have their properties set using these calls, including both simple and rule-based controls. Here is an example of building a simple 2-node, 1-pipe network just through code:
|
||||
```
|
||||
#include "epanet2_2.h"
|
||||
int buildandrunEpanet(char *rptfile)
|
||||
{
|
||||
// Create and initialize a project using gpm for flow
|
||||
// units and the Hazen-Williams formula for head loss
|
||||
EN_Project ph = 0;
|
||||
int err, index;
|
||||
err = EN_createproject(&ph);
|
||||
if (err) return err;
|
||||
EN_init(ph, rptfile, "", EN_GPM, EN_HW);
|
||||
|
||||
//Add a junction node with 710 ft elevation and 500 gpm demand
|
||||
EN_addnode(ph, "J1", EN_JUNCTION, &index);
|
||||
EN_setjuncdata(ph, index, 710, 500, "");
|
||||
|
||||
// Add a reservoir node at 800 ft elevation
|
||||
EN_addnode(ph, "R1", EN_RESERVOIR, &index);
|
||||
EN_setnodevalue(ph, index, EN_ELEVATION, 800);
|
||||
|
||||
// Add a 5280 ft long, 14-inch pipe with C-factor of 100
|
||||
// from the reservoir to the demand node
|
||||
EN_addlink(ph, "P1", EN_PIPE, "R1", "J1", &index);
|
||||
EN_setpipedata(ph, index, 5280, 14, 100, 0);
|
||||
|
||||
// Solve for hydraulics and report nodal results
|
||||
EN_setreport(ph, "NODES ALL");
|
||||
err = EN_solveH(ph);
|
||||
if (!err) err = EN_report(ph);
|
||||
|
||||
// Close and delete the project
|
||||
EN_close(ph);
|
||||
EN_deleteproject(ph);
|
||||
return err;
|
||||
}
|
||||
```
|
||||
Instead of using `EN_open` to load data from a file, `EN_init` is used to initialize a project with the names of its report and binary files, and its flow units and head loss formula. The legacy-style API has a complementary set of functions for building networks from code.
|
||||
|
||||
## Additional Convergence Parameters
|
||||
|
||||
Two new analysis options have been added to provide more rigorous convergence criteria for EPANET's hydraulic solver. In the API they are named `EN_HEADERROR` and `EN_FLOWCHANGE` while in the `[OPTIONS]` section of an EPANET input file they are named `HEADERROR` and `FLOWCHANGE`, respectively.
|
||||
|
||||
`EN_HEADERROR` is the maximum head loss error that any network link can have for hydraulic convergence to occur. A link's head loss error is the difference between the head loss found as a function of computed flow in the link (such as by the Hazen-Williams equation for a pipe) and the difference in computed heads for the link's end nodes. The units of this parameter are feet (or meters for SI units). The default value of 0 indicates that no head error limit applies.
|
||||
|
||||
`EN_FLOWCHANGE` is the largest change in flow that any network element (link, emitter, or pressure-dependent demand) can have for hydraulic convergence to occur. It is specified in whatever flow units the project is using. The default value of 0 indicates that no flow change limit applies.
|
||||
|
||||
These new parameters augment the current `EN_ACCURACY` option which always remains in effect. In addition, both `EN_HEADERROR` and `EN_FLOWCHANGE` can be used as parameters in the `EN_getstatistic` (or `ENgetstatistic`) function to retrieve their computed values (even when their option values are 0) after a hydraulic solution has been completed.
|
||||
|
||||
## More Efficient Node Re-ordering
|
||||
|
||||
EPANET's hydraulic solver requires solving a system of linear equations over a series of iterations until a set of convergence criteria are met. The coefficient matrix of this linear system is square and symmetric. It has a row for each network node and a non-zero off-diagonal coefficient for each link. The numerical effort needed to solve the linear system can be reduced if the nodes are re-ordered so that the non-zero coefficients cluster more tightly around the diagonal.
|
||||
|
||||
EPANET's original node re-ordering scheme has been replaced by the more efficient **Multiple Minimum Degree (MMD)** algorithm. On a series of eight networks ranging in size from 7,700 to 100,000 nodes MMD reduced the solution time for a single period (steady state) hydraulic analysis, where most of the work is for node-reordering, by an average of 55%. Since MMD did not reduce the time needed to solve the linear equations generated at each iteration of the hydraulic solver longer extended period simulations will not exhibit a similar speedup.
|
||||
|
||||
## Improved Handling of Near-Zero Flows
|
||||
|
||||
EPANET's hydraulic solver can generate an ill-conditioned solution matrix when pipe flows approach zero unless some adjustment is made (i.e., as a pipe's flow approaches 0 its head loss gradient also approaches 0 causing its reciprocal, which is used to form the solution matrix's coefficients, to approach infinity). EPANET 2.0 used an arbitrary cutoff on head loss gradient to prevent it from becoming 0. This approach doesn't allow a pipe to follow any head loss v. flow relation in the region below the cutoff and can produce incorrect solutions for some networks (see [Estrada et al., 2009](https://ascelibrary.org/doi/full/10.1061/%28ASCE%29IR.1943-4774.0000100)).
|
||||
|
||||
The hydraulic solver has been modified to use a linear head loss v. flow relation for flows approaching zero. For the Darcy-Weisbach equation, the linear Hagen-Poiseuille formula is used for laminar flow where the Reynolds Number is <= 2000. For the Hazen-Williams and Chezy-Manning equations, if the head loss gradient at a given flow is below the EPANET 2.0 gradient cutoff then a linear head loss relation is used whose slope equals the cutoff. EPANET 2.2 is now able to correctly solve the examples presented in Estrada et al. (2009) as well as those in [Gorev et al., (2013)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000694) and [Elhay and Simpson (2011)](https://ascelibrary.org/doi/10.1061/%28ASCE%29HY.1943-7900.0000411).
|
||||
|
||||
## Pressure Dependent Demands
|
||||
|
||||
EPANET has always employed a Demand Driven Analysis (**DDA**) when modeling network hydraulics. Under this approach nodal demands at a given point in time are fixed values that must be delivered no matter what nodal heads and link flows are produced by a hydraulic solution. This can result in situations where required demands are satisfied at nodes that have negative pressures - a physical impossibility.
|
||||
|
||||
To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand D delivered at a node depends on the node's available pressure P according to:
|
||||
|
||||
D = Dfull * [ (P - Pmin) / (Preq - Pmin) ]^Pexp
|
||||
|
||||
where Dfull is the full demand required, Pmin is the pressure below which demand is zero, Preq is the pressure required to deliver the full required demand and Pexp is an exponent. When P < Pmin demand is 0 and when P > Preq demand equals Dfull.
|
||||
|
||||
To implement pressure driven analysis four new parameters have been added to the [OPTIONS] section of the EPANET input file:
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|--------------|---------|
|
||||
| `DEMAND MODEL` | either DDA or PDA | DDA |
|
||||
| `MINIMUM PRESSURE` | value for Pmin | 0
|
||||
| `REQUIRED PRESSURE` | value for Preq | 0.1
|
||||
| `PRESSURE EXPONENT` | value for Pexp | 0.5 |
|
||||
|
||||
These parameters can also be set and retrieved in code using the following API functions
|
||||
```
|
||||
int ENsetdemandmodel(int modelType, double pMin, double pReq, double pExp);
|
||||
int ENgetdemandmodel(int *modelType, double *pMin, double *pReq, double *pExp);
|
||||
```
|
||||
for the legacy API and
|
||||
```
|
||||
int EN_setdemandmodel(EN_Project ph, int modelType, double pMin, double pReq, double pExp);
|
||||
int EN_getdemandmodel(EN_Project ph, int *modelType, double *pMin, double *pReq, double *pExp);
|
||||
```
|
||||
for the thread-safe API. Some additional points regarding the new **PDA** option are:
|
||||
- If no DEMAND MODEL and its parameters are specified then the analysis defaults to being demand driven (**DDA**).
|
||||
- This implementation of **PDA** assumes that the same parameters apply to all nodes in the network. Extending the framework to allow different parameters for specific nodes is left as a future feature to implement.
|
||||
- Preq must be at least 0.1 (either psi or m) higher than Pmin to avoid numerical issues caused by having too steep a demand curve.
|
||||
- Using `EN_DEFICIENTNODES` as the argument to `EN_getstatistic` (or `ENgetstatistic`) will retrieve the number of nodes that are pressure deficient. These are nodes with positive required demand whose pressure is below 0 under **DDA** or below Preq under **PDA**.
|
||||
- Using `EN_DEMANDREDUCTION` as an argument will retrieve the total percent reduction of demands at pressure deficient nodes under **PDA**.
|
||||
- Using `EN_DEMANDDEFICIT` with the `EN_getnodevalue` (or `ENgetnodevalue`) function will return the amount of demand reduction produced by a **PDA** at any particular node.
|
||||
|
||||
## Tank Overflows
|
||||
EPANET has always prevented tanks from overflowing by closing any links that supply inflow to a full tank. A new option `EN_CANOVERFLOW`, has been added to the list of Tank node properties. When set to 1 it will allow its tank to overflow when it becomes full. The spillage rate is returned in the tank's EN_DEMAND property. The default value for `EN_CANOVERFLOW` is 0 indicating that the tank cannot overflow.
|
||||
|
||||
For the input file, a new field has been appended to the data supplied for each tank in the `[TANKS]` section of the file. A value of **YES** indicates that the tank can over flow while **NO** (the default) indicates that it cannot. For the volume curve field that precedes it, an asterisk (*) can be used if the tank does not utilize a volume curve.
|
||||
|
||||
## Improved Water Quality Mass Balance
|
||||
|
||||
As described by [Davis et al. (2018)](https://www.drink-water-eng-sci.net/11/25/2018/dwes-11-25-2018.pdf) EPANET's water quality simulations can result in some significant mass balance errors when modeling short term mass injections (errors are much smaller for continuous source flows). The entire water quality engine has been re-written to eliminate these errors. It still uses the Lagrangian Time Driven transport method but now analyzes each network node in topologically sorted order rather than in arbitrary order.
|
||||
|
||||
A Mass Balance Report now appears the end of a simulation's Status Report that lists the various components (inflow, outflow, reaction) that comprise the network's overall mass balance. In addition `EN_MASSBALANCE` can be used as a parameter in the `EN_getstatistic` (or `ENgetstatistic`) function to retrieve the Mass Balance Ratio (Total Outflow Mass / Total Inflow Mass) at any point during a water quality simulation.
|
||||
|
||||
With this change EPANET 2.2 now produces perfect mass balances when tested against the networks used in Davis et al. (2018).
|
||||
|
||||
## New API functions
|
||||
|Function|Description|
|
||||
|--------|-----------|
|
||||
|`EN_createproject` | Creates a new EPANET project |
|
||||
|`EN_deleteproject` | Deletes an EPANET project |
|
||||
|`EN_init`|Initializes an EPANET project|
|
||||
|`EN_setflowunits`|Sets the project's flow units|
|
||||
|`EN_addnode`|Adds a new node to a project|
|
||||
|`EN_addlink`|Adds a new link to a project|
|
||||
|`EN_addcontrol`|Adds a new simple control to a project|
|
||||
|`EN_addrule`|Adds a new control rule to a project|
|
||||
|`EN_deletenode`|Deletes a node from the project|
|
||||
|`EN_deletelink`|Deletes a link from the project|
|
||||
|`EN_deletepattern`|Deletes a time pattern from the project|
|
||||
|`EN_deletecurve`|Deletes a data curve from the project|
|
||||
|`EN_deletecontrol`|Deletes a simple control from the project|
|
||||
|`EN_deleterule`|Deletes a rule-based control from the project|
|
||||
|`EN_setnodeid`|Changes the ID name for a node|
|
||||
|`EN_setjuncdata` |Sets values for a junction's parameters |
|
||||
|`EN_settankdata` |Sets values for a tank's parameters|
|
||||
|`EN_setlinkid`|Changes the ID name for a link|
|
||||
|`EN_setlinknodes`|Sets a link's start- and end-nodes|
|
||||
|`EN_setlinktype`|Changes the type of a specific link|
|
||||
|`EN_setpipedata`|Sets values for a pipe's parameters|
|
||||
|`EN_getdemandmodel`|Retrieves the type of demand model in use |
|
||||
|`EN_setdemandmodel`|Sets the type of demand model to use|
|
||||
|`EN_adddemand`|Adds a new demand category to a node|
|
||||
|`EN_deletedemand`|Deletes a demand category from a node|
|
||||
|`EN_getdemandindex`|Finds a demand category's index given its name|
|
||||
|`EN_getdemandname`|Gets the name of a node's demand category|
|
||||
|`EN_setdemandname`|Sets the name of a node's demand category|
|
||||
|`EN_setdemandpattern`|Assigns a time pattern to a node's demand category |
|
||||
|`EN_setpatternid`|Changes the ID name of a time pattern|
|
||||
|`EN_setcurveid`|Changes the ID name of a data curve|
|
||||
|`EN_getcurvetype`|Gets a curve's type|
|
||||
|`EN_setheadcurveindex`|Sets the index of a head curve used by a pump |
|
||||
|`EN_getruleinfo`|Gets the number of elements in a rule-based control |
|
||||
|`EN_getruleid` | Gets the name assigned to a rule-based control |
|
||||
|`EN_getpremise`|Gets the contents of a premise in a rule-based control|
|
||||
|`EN_setpremise`|Sets the contents of a premise in a rule-based control|
|
||||
|`EN_setpremiseindex`|Sets the index of an object in a premise of a rule-based control|
|
||||
|`EN_setpremisestatus`|Sets the status of an object in a premise of a rule-based control|
|
||||
|`EN_setpremisevalue`|Sets the value of a property in a premise of a rule-based control|
|
||||
|`EN_getthenaction`|Gets the contents of a THEN action in a rule-based control|
|
||||
|`EN_setthenaction`|Sets the contents of a THEN action in a rule-based control|
|
||||
|`EN_getelseaction`|Gets the contents of an ELSE action in a rule-based control|
|
||||
|`EN_setelseaction`|Sets the contents of an ELSE action in a rule-based control|
|
||||
|`EN_setrulepriority`|Sets the priority of a rule-based control|
|
||||
|`EN_gettitle` |Gets a project's title |
|
||||
|`EN_settitle` |Sets a project's title |
|
||||
|`EN_getcomment` |Gets the descriptive comment assigned to an object|
|
||||
|`EN_setcomment` |Assigns a descriptive comment to an object|
|
||||
|`EN_clearreport` |Clears the contents of a project's report file |
|
||||
|`EN_copyreport` | Copies the contents of a project's report file |
|
||||
|`EN_getresultindex` | Gets the order in which a node or link was saved to file |
|
||||
|`EN_getvertexcount` | Gets the number of vertex points in a link |
|
||||
|`EN_getvertex` | Gets the coordinates of a vertex point in a link |
|
||||
|`EN_setvertices` | Assigns a new set of vertex points to a link |
|
||||
|
||||
In addition to these new functions, a tank's volume curve `EN_VOLCURVE` can be set using `EN_setnodevalue` and `EN_setlinkvalue` can now be used to set the following pump properties:
|
||||
- `EN_PUMP_POWER` (constant power rating)
|
||||
- `EN_PUMP_HCURVE` (head characteristic curve)
|
||||
- `EN_PUMP_ECURVE` (efficiency curve)
|
||||
- `EN_PUMP_ECOST` (average energy price)
|
||||
- `EN_PUMP_EPAT` (energy pricing pattern)
|
||||
- `EN_LINKPATTERN` (speed setting pattern)
|
||||
|
||||
Access to the following global energy options have been added to `EN_getoption` and `EN_setoption`:
|
||||
- `EN_GLOBALEFFIC` (global pump efficiency)
|
||||
- `EN_GLOBALPRICE` (global average energy price per kW-Hour)
|
||||
- `EN_GLOBALPATTERN` (global energy price pattern)
|
||||
- `EN_DEMANDCHARGE` (price per maximum kW of energy consumption)
|
||||
|
||||
## New API Constants
|
||||
### Node value types:
|
||||
- `EN_CANOVERFLOW`
|
||||
- `EN_DEMANDDEFICIT`
|
||||
|
||||
### Link value types:
|
||||
- `EN_PUMP_STATE`
|
||||
- `EN_PUMP_EFFIC`
|
||||
- `EN_PUMP_POWER`
|
||||
- `EN_PUMP_HCURVE`
|
||||
- `EN_PUMP_ECURVE`
|
||||
- `EN_PUMP_ECOST`
|
||||
- `EN_PUMP_EPAT`
|
||||
|
||||
### Count types:
|
||||
- `EN_RULECOUNT`
|
||||
|
||||
### Head loss formula:
|
||||
- `EN_HW`
|
||||
- `EN_DW`
|
||||
- `EN_CM`
|
||||
|
||||
### Hydraulic option types:
|
||||
- `EN_HEADERROR`
|
||||
- `EN_FLOWCHANGE`
|
||||
- `EN_HEADLOSSFORM`
|
||||
- `EN_GLOBALEFFIC`
|
||||
- `EN_GLOBALPRICE`
|
||||
- `EN_GLOBALPATTERN`
|
||||
- `EN_DEMANDCHARGE`
|
||||
- `EN_SP_GRAVITY`
|
||||
- `EN_SP_VISCOS`
|
||||
- `EN_EXTRA_ITER`
|
||||
- `EN_CHECKFREQ`
|
||||
- `EN_MAXCHECK`
|
||||
- `EN_DAMPLIMIT`
|
||||
|
||||
### Quality option types:
|
||||
- `EN_SP_DIFFUS`
|
||||
- `EN_BULKORDER`
|
||||
- `EN_WALLORDER`
|
||||
- `EN_TANKORDER`
|
||||
- `EN_CONCENLIMIT`
|
||||
|
||||
### Simulation statistic types:
|
||||
- `EN_MAXHEADERROR`
|
||||
- `EN_MAXFLOWCHANGE`
|
||||
- `EN_MASSBALANCE`
|
||||
- `EN_DEFICIENTNODES`
|
||||
- `EN_DEMANDREDUCTION`
|
||||
|
||||
### Action code types:
|
||||
- `EN_UNCONDITIONAL`
|
||||
- `EN_CONDITIONAL`
|
||||
|
||||
### Curve types:
|
||||
- `EN_VOLUME_CURVE`
|
||||
- `EN_PUMP_CURVE`
|
||||
- `EN_EFFIC_CURVE`
|
||||
- `EN_HLOSS_CURVE`
|
||||
- `EN_GENERIC_CURVE`
|
||||
|
||||
### Demand model types:
|
||||
- `EN_DDA`
|
||||
- `EN_PDA`
|
||||
|
||||
## Documentation
|
||||
Doxygen files have been created to generate a complete Users Guide for version 2.2's API. The guide's format is similar to the original EPANET Programmer's Toolkit help file and can be produced as a set of HTML pages, a Windows help file or a PDF document.
|
||||
|
||||
## Authors contributing to this release:
|
||||
(In alphabetical order)
|
||||
- Demetrios Eliades
|
||||
- Sam Hatchett
|
||||
- Marios Kyriakou
|
||||
- Lewis Rossman
|
||||
- Elad Salomons
|
||||
- Markus Sunela
|
||||
- Michael Tryby
|
||||
85
appveyor.yml
Normal file
85
appveyor.yml
Normal file
@@ -0,0 +1,85 @@
|
||||
#
|
||||
# appveyor.yml - Appveyor CI configuration for OWA EPANET
|
||||
#
|
||||
# Date created: 01/09/2018
|
||||
#
|
||||
# Author: Michael E. Tryby
|
||||
# US EPA - ORD/NRMRL
|
||||
#
|
||||
|
||||
version: 2.0.{build}
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
#GROUP: (SUPPORTED/EXPERIMENTAL)
|
||||
#EXPERIMENTAL is allowed to fail under build matrix
|
||||
- GROUP: "EXPERIMENTAL"
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
GENERATOR: "Visual Studio 15 2017"
|
||||
GROUP: "SUPPORTED"
|
||||
BOOST_ROOT: "C:/Libraries/boost_1_67_0"
|
||||
PLATFORM: "win32"
|
||||
REF_BUILD_ID: "538_1"
|
||||
# New build on Visual Studio 15 2017
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
GENERATOR: "Visual Studio 15 2017 Win64"
|
||||
GROUP: "EXPERIMENTAL"
|
||||
BOOST_ROOT: "C:/Libraries/boost_1_67_0"
|
||||
PLATFORM: "win64"
|
||||
REF_BUILD_ID: "538_2"
|
||||
|
||||
# called before repo cloning
|
||||
init:
|
||||
- set SUT_BUILD_ID=%APPVEYOR_BUILD_NUMBER%_%APPVEYOR_JOB_NUMBER%
|
||||
- set EPANET_HOME=%APPVEYOR_BUILD_FOLDER%
|
||||
- set BUILD_HOME=buildprod
|
||||
- set TEST_HOME=nrtestsuite
|
||||
- set PATH=%PATH%;%BOOST_ROOT%/
|
||||
|
||||
# See values set
|
||||
- echo %APPVEYOR_BUILD_WORKER_IMAGE%
|
||||
- echo %BUILD_HOME%
|
||||
- echo %GENERATOR%
|
||||
- echo %BOOST_ROOT%
|
||||
|
||||
# called after repo clone
|
||||
install:
|
||||
- python -m pip install -r tools\requirements-appveyor.txt
|
||||
|
||||
# called before build
|
||||
before_build:
|
||||
- mkdir %BUILD_HOME%
|
||||
- cd %BUILD_HOME%
|
||||
- cmake -G "%GENERATOR%"
|
||||
-DBUILD_TESTS=ON
|
||||
-DBOOST_ROOT="%BOOST_ROOT%" ..
|
||||
|
||||
# run custom build script
|
||||
build_script:
|
||||
- cmake --build . --config Release
|
||||
|
||||
before_test:
|
||||
- cd %EPANET_HOME%
|
||||
- tools\before-test.cmd %PLATFORM% %REF_BUILD_ID% %SUT_BUILD_ID% %APPVEYOR_REPO_COMMIT%
|
||||
|
||||
# run custom test script
|
||||
test_script:
|
||||
# run unit tests
|
||||
- cd %BUILD_HOME%\tests
|
||||
- ctest -C Release --output-on-failure
|
||||
# run regression tests
|
||||
- cd %EPANET_HOME%
|
||||
- tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID%
|
||||
|
||||
on_success:
|
||||
- cd %TEST_HOME%\benchmark
|
||||
- appveyor PushArtifact receipt.json
|
||||
|
||||
on_failure:
|
||||
- cd %TEST_HOME%\benchmark
|
||||
# zip up the SUT benchmarks
|
||||
- 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID%
|
||||
- appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip
|
||||
@@ -1,28 +0,0 @@
|
||||
## cmake .
|
||||
## make
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
project (EPANET)
|
||||
|
||||
IF(APPLE)
|
||||
SET(CMAKE_INSTALL_NAME_DIR @executable_path)
|
||||
SET(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
ENDIF(APPLE)
|
||||
|
||||
# the library
|
||||
include_directories(../../include)
|
||||
file(GLOB EPANET_SOURCES ../../src/*.c)
|
||||
add_library(epanet STATIC ${EPANET_SOURCES})
|
||||
|
||||
# the standalone executable
|
||||
include_directories(../../src)
|
||||
add_executable(runepanet ../../run/main.c)
|
||||
target_link_libraries (runepanet LINK_PUBLIC epanet m)
|
||||
|
||||
# the binary hydraulics file API
|
||||
include_directories(../../tools/outputapi)
|
||||
add_library(ENBinaryOut SHARED ../../tools/outputapi/outputapi.c)
|
||||
@@ -1,109 +0,0 @@
|
||||
# Linux Makefile for EPANET
|
||||
|
||||
# This will build EPANET as a shared object library
|
||||
# (libepanet2.so) under Linux/Unix, and a standalone
|
||||
# executable (epanet2).
|
||||
|
||||
# The following targets are defined:
|
||||
# make
|
||||
# -Builds libepanet2.so, epanet2
|
||||
# make install
|
||||
# -Creates shell wrapper runepanet2.sh that executes epanet2.
|
||||
# The runepanet2.sh wrapper simply exports
|
||||
# environment variables that help locate the runtime library,
|
||||
# allowing you to specify your own library locations.
|
||||
# -Installs epanet2 and runepanet2.sh
|
||||
# in <prefix>/bin, where <prefix> defaults to ~ (and can be set
|
||||
# below to something different - see "Install directories")
|
||||
# -Installs libepanet2.so in <prefix>/lib
|
||||
# -Installs epanet2.h in <prefix>/include. This is the required
|
||||
# header file for the EPANET programmer's toolkit, and thus
|
||||
# <prefix>/include should be on your CPP include search path
|
||||
# for subsequent use of the toolkit and linking with the
|
||||
# library libepanet2.so
|
||||
# make clean
|
||||
# -Removes object and library files, returning the build directory
|
||||
# to its pristine state.
|
||||
|
||||
# You may wish to change the install path 'prefix',
|
||||
# or the compiler flags, but these defaults should be fine.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# Target filenames
|
||||
epanetrootname := epanet2
|
||||
libname := lib$(epanetrootname).so
|
||||
exename := $(epanetrootname)
|
||||
# Shell wrapper
|
||||
runcmdtemplate = runepanet.sh.template
|
||||
runcmdname = runepanet2.sh
|
||||
# Location of EPANET toolkit includes
|
||||
epanetincludedir = ../../include
|
||||
# Search path for sources
|
||||
epanetsrcdir = ../../src
|
||||
epanetrundir = ../../run
|
||||
VPATH = $(epanetsrcdir):$(epanetincludedir):$(epanetrundir)
|
||||
|
||||
# Install directories
|
||||
#prefix = /usr/local # GNU standard -- requires superuser rights
|
||||
prefix =~
|
||||
#
|
||||
exec_prefix = $(prefix)
|
||||
libdir = $(exec_prefix)/lib
|
||||
bindir = $(exec_prefix)/bin
|
||||
includedir = $(prefix)/include
|
||||
datarootdir = $(prefix)/share
|
||||
docdir = $(datarootdir)/doc/epanet
|
||||
|
||||
# Compiler and flags
|
||||
CC = gcc
|
||||
CFLAGS = -g -O3 -fPIC -std=c99
|
||||
CPPFLAGS = -I $(epanetincludedir)
|
||||
LDFLAGS = -L . -Wl,-rpath,$(libdir) -lm
|
||||
|
||||
# Installer
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL)
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
|
||||
# Files for the shared object library
|
||||
epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \
|
||||
input3.o mempool.o output.o quality.o report.o \
|
||||
rules.o smatrix.o epanet.o
|
||||
# Epanet header files
|
||||
epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h types.h vars.h
|
||||
# Epanet main program
|
||||
epanet_main=main
|
||||
# Epanet main program header files
|
||||
epanet_main_heads=epanet2.h
|
||||
|
||||
.PHONY: all
|
||||
all: $(libname) $(exename)
|
||||
|
||||
$(libname): $(epanet_objs)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^
|
||||
|
||||
$(exename): $(epanet_main).o $(epanet_main_heads)
|
||||
$(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS)
|
||||
|
||||
$(epanet_objs): $(epanet_heads)
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
cat $(runcmdtemplate) | sed 's|libdir|$(libdir)|' \
|
||||
| sed 's|exename|$(bindir)/$(exename)|' \
|
||||
> $(runcmdname)
|
||||
$(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename)
|
||||
$(INSTALL_PROGRAM) -D $(libname) $(libdir)/$(libname)
|
||||
$(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h
|
||||
$(INSTALL_PROGRAM) -D $(runcmdname) ~/$(runcmdname)
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-/bin/rm *.o $(libname) $(exename) $(runcmdname)
|
||||
@@ -1,111 +0,0 @@
|
||||
# Linux Makefile for EPANET
|
||||
|
||||
# This will build EPANET as a shared object library
|
||||
# (libepanet_gcc_<Rev>.so) under Linux/Unix, and a standalone
|
||||
# executable (epanet_gcc_<Rev>).
|
||||
|
||||
# The following targets are defined:
|
||||
# make
|
||||
# -Builds libepanet_gcc_<Rev>.so, epanet_gcc_<Rev>
|
||||
# make install
|
||||
# -Creates shell wrapper runepanet_<Rev>.sh that executes epanet_gcc_<Rev>.exe.
|
||||
# The runepanet_<Rev>.sh wrapper simply exports
|
||||
# environment variables that help locate the runtime library,
|
||||
# allowing you to specify your own library locations.
|
||||
# -Installs epanet_gcc_<Rev> and runepanet_<Rev>.sh
|
||||
# in <prefix>/bin, where <prefix> defaults to ~ (and can be set
|
||||
# below to something different - see "Install directories")
|
||||
# -Installs libepanet_gcc_<Rev>.so in <prefix>/lib
|
||||
# -Installs epanet2.h in <prefix>/include. This is the required
|
||||
# header file for the EPANET programmer's toolkit, and thus
|
||||
# <prefix>/include should be on your CPP include search path
|
||||
# for subsequent use of the toolkit and linking with the
|
||||
# library libepanet_gcc_<Rev>.so
|
||||
# make clean
|
||||
# -Removes object and library files, returning the build directory
|
||||
# to its pristine state.
|
||||
|
||||
# You may wish to change the install path 'prefix',
|
||||
# or the compiler flags, but these defaults should be fine.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# Target filenames
|
||||
# svnname.sh constructs a name: <prefix><root><Rev><postfix>
|
||||
# where <Rev> is the atomic revision number of the svn repo.
|
||||
epanetsvnpath = ../../..
|
||||
epanetrootname := $(shell ../svnname.sh $(epanetsvnpath) "" epanet_gcc_ "")
|
||||
libname := lib$(epanetrootname).so
|
||||
exename := $(epanetrootname)
|
||||
# Shell wrapper
|
||||
runcmdtemplate = runepanet.sh.template
|
||||
runcmdname = $(shell ../svnname.sh $(epanetsvnpath) "" runepanet_ .sh)
|
||||
# Location of EPANET toolkit includes
|
||||
epanetincludedir = ../../include
|
||||
# Search path for sources
|
||||
epanetsrcdir = ../../src
|
||||
VPATH = $(epanetsrcdir):$(epanetincludedir)
|
||||
|
||||
# Install directories
|
||||
prefix = ~
|
||||
exec_prefix = $(prefix)
|
||||
libdir = $(exec_prefix)/lib
|
||||
bindir = $(exec_prefix)/bin
|
||||
includedir = $(prefix)/include
|
||||
datarootdir = $(prefix)/share
|
||||
docdir = $(datarootdir)/doc/epanet
|
||||
|
||||
# Compiler and flags
|
||||
CC = gcc
|
||||
CFLAGS = -g -O3 -fPIC -std=c99
|
||||
CPPFLAGS = -I $(epanetincludedir)
|
||||
LDFLAGS = -L . -Wl,-rpath,$(libdir) -lm
|
||||
|
||||
# Installer
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL)
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
|
||||
# Files for the shared object library
|
||||
epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \
|
||||
input3.o mempool.o output.o quality.o report.o \
|
||||
rules.o smatrix.o
|
||||
# Epanet header files
|
||||
epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h
|
||||
# Epanet main program
|
||||
epanet_main=epanet
|
||||
# Epanet main program header files
|
||||
epanet_main_heads=epanet2.h
|
||||
|
||||
.PHONY: all
|
||||
all: $(libname) $(exename)
|
||||
|
||||
$(libname): $(epanet_objs)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -D SOL -c $(epanetsrcdir)/$(epanet_main).c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^
|
||||
|
||||
$(exename): $(libname) $(epanet_main_heads)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c
|
||||
$(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS)
|
||||
|
||||
$(epanet_objs): $(epanet_heads)
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
cat $(runcmdtemplate) | sed 's|libdir|$(libdir)|' \
|
||||
| sed 's|exename|$(bindir)/$(exename)|' \
|
||||
> $(runcmdname)
|
||||
$(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename)
|
||||
$(INSTALL_PROGRAM) -D $(libname) $(libdir)/$(libname)
|
||||
$(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h
|
||||
$(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname)
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-/bin/rm *.o $(libname) $(exename) $(runcmdname)
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
export LD_LIBRARY_PATH=libdir:$LD_LIBRARY_PATH
|
||||
exec exename $*
|
||||
@@ -1,78 +0,0 @@
|
||||
# MINGW32 Makefile for EPANET
|
||||
|
||||
# This will build EPANET as DLL
|
||||
# (epanet2.dll) under MINGW32 GCC, and a standalone
|
||||
# executable (epanet2d.exe).
|
||||
|
||||
# The following targets are defined:
|
||||
# make
|
||||
# -Builds epanet2.dll, epanet2d.exe
|
||||
# make install
|
||||
# -Copy epanet2.dll, epanet2d.exe, epanet2.def to $(prefix)
|
||||
# make clean
|
||||
# -Removes object and library files, returning the build directory
|
||||
# to its pristine state.
|
||||
|
||||
# You may wish to change the install path 'prefix',
|
||||
# or the compiler flags, but these defaults should be fine.
|
||||
|
||||
|
||||
# Target filenames
|
||||
epanetrootname := epanet2
|
||||
libname := $(epanetrootname).dll
|
||||
exename := $(epanetrootname)d.exe
|
||||
|
||||
# Location of EPANET toolkit includes
|
||||
epanetincludedir = ../../include
|
||||
# Search path for sources
|
||||
epanetsrcdir = ../../src
|
||||
# Search path for sources
|
||||
epanetmainsrcdir = ../../run
|
||||
VPATH = $(epanetsrcdir):$(epanetincludedir):$(epanetmainsrcdir)
|
||||
|
||||
# Install directories
|
||||
prefix = C:\discoD\EPA\EPAnet_util
|
||||
execdir = $(prefix)
|
||||
libdir = $(prefix)
|
||||
|
||||
|
||||
# Compiler and flags
|
||||
CC = gcc
|
||||
CFLAGS = -g -O3 -std=c99 -Wno-implicit-function-declaration -D DLL
|
||||
CPPFLAGS = -I $(epanetincludedir) -I $(epanetsrcdir)
|
||||
LDFLAGS = -L . -Wl,--kill-at,--enable-stdcall-fixup,-rpath,$(libdir) -lm
|
||||
|
||||
|
||||
# Files for the shared object library
|
||||
epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \
|
||||
input3.o mempool.o output.o quality.o report.o \
|
||||
rules.o smatrix.o epanet.o
|
||||
# Epanet header files
|
||||
epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h types.h vars.h epanet2.h
|
||||
# Epanet main program
|
||||
epanet_main=main
|
||||
# Epanet main program header files
|
||||
epanet_main_heads=epanet2.h
|
||||
|
||||
.PHONY: all
|
||||
all: $(libname) $(exename)
|
||||
|
||||
$(libname): $(epanet_objs)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -Wl,--output-def,$(epanetrootname).def
|
||||
|
||||
$(exename): $(epanet_main_heads) $(libname) $(epanet_main).o
|
||||
$(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS)
|
||||
|
||||
$(epanet_objs): $(epanet_heads)
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
del $(epanet_main).o $(epanet_objs) $(exename) $(libname) $(epanetrootname).def
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
copy $(exename) $(execdir)
|
||||
copy $(libname) $(libdir)
|
||||
copy $(epanetrootname).def $(libdir)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
rem : set path to Windows SDK
|
||||
Set Reg.Key=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows
|
||||
Set Reg.Val=CurrentInstallFolder
|
||||
Set Build_PATH=%CD%
|
||||
|
||||
rem : set path for source EPANET files
|
||||
cd ..\..\include
|
||||
Set H_PATH=%CD%
|
||||
cd ..\src
|
||||
Set SRC_PATH=%CD%
|
||||
|
||||
rem : set Windows SDK Path from registry
|
||||
For /F "Tokens=2*" %%A In ('Reg Query "%Reg.Key%" /v "%Reg.Val%" ^| Find /I "%Reg.Val%"' ) Do Call Set SDK_PATH=%%B
|
||||
|
||||
|
||||
rem : 64 bit
|
||||
rem : check pc architecture
|
||||
Set Reg.Qry=HKLM\Hardware\Description\System\CentralProcessor\0
|
||||
REG.exe Query %Reg.Qry% > checkOS.tmp
|
||||
Find /i "x86" < checkOS.tmp > StringCheck.tmp
|
||||
If %ERRORLEVEL% == 1 (
|
||||
CALL "%SDK_PATH%bin\"SetEnv.cmd /x64 /release
|
||||
rem : create EPANET2.DLL
|
||||
cl -o epanet2.dll epanet.c hash.c hydraul.c 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
|
||||
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
|
||||
md "%Build_PATH%"\64bit
|
||||
move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\64bit
|
||||
move /y "%SRC_PATH%"\*.exe "%Build_PATH%"\64bit
|
||||
copy "%H_PATH%"\*.h "%Build_PATH%"\64bit
|
||||
)
|
||||
|
||||
|
||||
rem : 32 bit with DEF
|
||||
CALL "%SDK_PATH%bin\"SetEnv.cmd /x86 /release
|
||||
echo "32 bit with epanet2.def mapping"
|
||||
rem : create EPANET2.DLL
|
||||
cl -o epanet2.dll epanet.c hash.c hydraul.c 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:..\build\WinSDK\epanet2.def /MAP
|
||||
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
|
||||
md "%Build_PATH%"\32bit
|
||||
move /y "%SRC_PATH%"\*.dll "%Build_PATH%"\32bit
|
||||
move /y "%SRC_PATH%"\*.exe "%Build_PATH%"\32bit
|
||||
|
||||
|
||||
rem : a bit of housekeeping and cleaning
|
||||
del "%SRC_PATH%"\*.obj
|
||||
del "%SRC_PATH%"\*.exp
|
||||
del "%SRC_PATH%"\*.lib
|
||||
del "%SRC_PATH%"\*.map
|
||||
del "%SRC_PATH%"\*.tmp
|
||||
|
||||
cd "%Build_PATH%"
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
LIBRARY EPANET2.DLL
|
||||
|
||||
EXPORTS
|
||||
ENaddpattern = _ENaddpattern@4
|
||||
ENclose = _ENclose@0
|
||||
ENcloseH = _ENcloseH@0
|
||||
ENcloseQ = _ENcloseQ@0
|
||||
ENepanet = _ENepanet@16
|
||||
ENgetcontrol = _ENgetcontrol@24
|
||||
ENgetcount = _ENgetcount@8
|
||||
ENgeterror = _ENgeterror@12
|
||||
ENgetflowunits = _ENgetflowunits@4
|
||||
ENgetlinkid = _ENgetlinkid@8
|
||||
ENgetlinkindex = _ENgetlinkindex@8
|
||||
ENgetlinknodes = _ENgetlinknodes@12
|
||||
ENgetlinktype = _ENgetlinktype@8
|
||||
ENgetlinkvalue = _ENgetlinkvalue@12
|
||||
ENgetnodeid = _ENgetnodeid@8
|
||||
ENgetnodeindex = _ENgetnodeindex@8
|
||||
ENgetnodetype = _ENgetnodetype@8
|
||||
ENgetnodevalue = _ENgetnodevalue@12
|
||||
ENgetoption = _ENgetoption@8
|
||||
ENgetpatternid = _ENgetpatternid@8
|
||||
ENgetpatternindex = _ENgetpatternindex@8
|
||||
ENgetpatternlen = _ENgetpatternlen@8
|
||||
ENgetpatternvalue = _ENgetpatternvalue@12
|
||||
ENgetqualtype = _ENgetqualtype@8
|
||||
ENgettimeparam = _ENgettimeparam@8
|
||||
ENgetversion = _ENgetversion@4
|
||||
ENinitH = _ENinitH@4
|
||||
ENinitQ = _ENinitQ@4
|
||||
ENnextH = _ENnextH@4
|
||||
ENnextQ = _ENnextQ@4
|
||||
ENopen = _ENopen@12
|
||||
ENopenH = _ENopenH@0
|
||||
ENopenQ = _ENopenQ@0
|
||||
ENreport = _ENreport@0
|
||||
ENresetreport = _ENresetreport@0
|
||||
ENrunH = _ENrunH@4
|
||||
ENrunQ = _ENrunQ@4
|
||||
ENsaveH = _ENsaveH@0
|
||||
ENsavehydfile = _ENsavehydfile@4
|
||||
ENsaveinpfile = _ENsaveinpfile@4
|
||||
ENsetcontrol = _ENsetcontrol@24
|
||||
ENsetlinkvalue = _ENsetlinkvalue@12
|
||||
ENsetnodevalue = _ENsetnodevalue@12
|
||||
ENsetoption = _ENsetoption@8
|
||||
ENsetpattern = _ENsetpattern@12
|
||||
ENsetpatternvalue = _ENsetpatternvalue@12
|
||||
ENsetqualtype = _ENsetqualtype@16
|
||||
ENsetreport = _ENsetreport@4
|
||||
ENsetstatusreport = _ENsetstatusreport@4
|
||||
ENsettimeparam = _ENsettimeparam@8
|
||||
ENsolveH = _ENsolveH@0
|
||||
ENsolveQ = _ENsolveQ@0
|
||||
ENstepQ = _ENstepQ@4
|
||||
ENusehydfile = _ENusehydfile@4
|
||||
ENwriteline = _ENwriteline@4
|
||||
ENgetnumdemands = _ENgetnumdemands@8
|
||||
ENgetbasedemand = _ENgetbasedemand@12
|
||||
ENgetdemandpattern = _ENgetdemandpattern@12
|
||||
ENgetcurve = _ENgetcurve@20
|
||||
ENgetstatistic = _ENgetstatistic@8
|
||||
ENgetcoord = _ENgetcoord@12
|
||||
ENsetcoord = _ENsetcoord@12
|
||||
ENgetqualinfo = _ENgetqualinfo@16
|
||||
ENsetbasedemand = _ENsetbasedemand@12
|
||||
ENgetaveragepatternvalue = _ENgetaveragepatternvalue@8
|
||||
ENgetheadcurveindex = _ENgetheadcurveindex@8
|
||||
ENgetpumptype = _ENgetpumptype@8
|
||||
ENgetcurveindex = _ENgetcurveindex@8
|
||||
ENgetcurveid = _ENgetcurveid@8
|
||||
ENgetcurvelen = _ENgetcurvelen@8
|
||||
ENgetcurvevalue = _ENgetcurvevalue@16
|
||||
ENsetcurvevalue = _ENsetcurvevalue@16
|
||||
ENsetcurve = _ENsetcurve@16
|
||||
ENaddcurve = _ENaddcurve@4
|
||||
@@ -1,773 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
223109E61BA865930030AAE8 /* Net3.inp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 223109E31BA8658A0030AAE8 /* Net3.inp */; };
|
||||
223109EB1BA869DA0030AAE8 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 22CD9A5D1B27898E00B65E83 /* main.c */; };
|
||||
223109ED1BA869DA0030AAE8 /* libepanet-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2255753B17551217009946B1 /* libepanet-static.a */; };
|
||||
223109EF1BA869DA0030AAE8 /* Net3.inp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 223109E31BA8658A0030AAE8 /* Net3.inp */; };
|
||||
223109F61BA869F30030AAE8 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; };
|
||||
223109F71BA869F30030AAE8 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; };
|
||||
223109F81BA869F30030AAE8 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; };
|
||||
223109F91BA869F30030AAE8 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; };
|
||||
223109FA1BA869F30030AAE8 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; };
|
||||
223109FB1BA869F30030AAE8 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; };
|
||||
223109FC1BA869F30030AAE8 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; };
|
||||
223109FD1BA869F30030AAE8 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; };
|
||||
223109FE1BA869F30030AAE8 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; };
|
||||
223109FF1BA869F30030AAE8 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; };
|
||||
22310A001BA869F30030AAE8 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; };
|
||||
22310A011BA869F30030AAE8 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; };
|
||||
22310A021BA869F30030AAE8 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; };
|
||||
22310A051BA869F30030AAE8 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; };
|
||||
22322F851068369500641384 /* enumstxt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F701068369500641384 /* enumstxt.h */; };
|
||||
22322F861068369500641384 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; };
|
||||
22322F871068369500641384 /* funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F721068369500641384 /* funcs.h */; };
|
||||
22322F881068369500641384 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; };
|
||||
22322F891068369500641384 /* hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F741068369500641384 /* hash.h */; };
|
||||
22322F8A1068369500641384 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; };
|
||||
22322F8B1068369500641384 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; };
|
||||
22322F8C1068369500641384 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; };
|
||||
22322F8D1068369500641384 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; };
|
||||
22322F8E1068369500641384 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; };
|
||||
22322F8F1068369500641384 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; };
|
||||
22322F901068369500641384 /* mempool.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F7B1068369500641384 /* mempool.h */; };
|
||||
22322F911068369500641384 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; };
|
||||
22322F921068369500641384 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; };
|
||||
22322F931068369500641384 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; };
|
||||
22322F941068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; };
|
||||
22322F951068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; };
|
||||
22322F961068369500641384 /* text.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F811068369500641384 /* text.h */; };
|
||||
22322F981068369500641384 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F831068369500641384 /* types.h */; };
|
||||
22322F991068369500641384 /* vars.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F841068369500641384 /* vars.h */; };
|
||||
22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
2255753F17551234009946B1 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; };
|
||||
2255754017551234009946B1 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; };
|
||||
2255754117551234009946B1 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; };
|
||||
2255754217551234009946B1 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; };
|
||||
2255754317551234009946B1 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; };
|
||||
2255754417551234009946B1 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; };
|
||||
2255754517551234009946B1 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; };
|
||||
2255754617551234009946B1 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; };
|
||||
2255754717551234009946B1 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; };
|
||||
2255754817551234009946B1 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; };
|
||||
2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; };
|
||||
2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; };
|
||||
2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; };
|
||||
225762C51C068A3900484EC7 /* Net1.inp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 225762C31C068A2A00484EC7 /* Net1.inp */; };
|
||||
225762C61C068A3B00484EC7 /* Net2.inp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 225762C41C068A2A00484EC7 /* Net2.inp */; };
|
||||
226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; };
|
||||
22CD9A5E1B27898E00B65E83 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 22CD9A5D1B27898E00B65E83 /* main.c */; };
|
||||
22CD9A611B278BB900B65E83 /* libepanet-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2255753B17551217009946B1 /* libepanet-static.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
223109E91BA869DA0030AAE8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2255753A17551217009946B1;
|
||||
remoteInfo = "epanet-static";
|
||||
};
|
||||
22CD9A5F1B278B0400B65E83 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2255753A17551217009946B1;
|
||||
remoteInfo = "epanet-static";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
223109E11BA865690030AAE8 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 6;
|
||||
files = (
|
||||
223109E61BA865930030AAE8 /* Net3.inp in CopyFiles */,
|
||||
225762C51C068A3900484EC7 /* Net1.inp in CopyFiles */,
|
||||
225762C61C068A3B00484EC7 /* Net2.inp in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
223109EE1BA869DA0030AAE8 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 6;
|
||||
files = (
|
||||
223109EF1BA869DA0030AAE8 /* Net3.inp in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
223109E31BA8658A0030AAE8 /* Net3.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = Net3.inp; path = "../../example-networks/Net3.inp"; sourceTree = "<group>"; };
|
||||
223109F31BA869DA0030AAE8 /* runepanet copy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "runepanet copy"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
22310A091BA869F30030AAE8 /* libepanet-static copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libepanet-static copy.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
22322F66106833BB00641384 /* runepanet */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = runepanet; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
22322F701068369500641384 /* enumstxt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = enumstxt.h; path = ../../src/enumstxt.h; sourceTree = SOURCE_ROOT; };
|
||||
22322F711068369500641384 /* epanet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 2; name = epanet.c; path = ../../src/epanet.c; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
22322F721068369500641384 /* funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = funcs.h; path = ../../src/funcs.h; sourceTree = SOURCE_ROOT; };
|
||||
22322F731068369500641384 /* hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../../src/hash.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F741068369500641384 /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hash.h; path = ../../src/hash.h; sourceTree = SOURCE_ROOT; };
|
||||
22322F751068369500641384 /* hydraul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hydraul.c; path = ../../src/hydraul.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F761068369500641384 /* inpfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inpfile.c; path = ../../src/inpfile.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F771068369500641384 /* input1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input1.c; path = ../../src/input1.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F781068369500641384 /* input2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input2.c; path = ../../src/input2.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F791068369500641384 /* input3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input3.c; path = ../../src/input3.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F7A1068369500641384 /* mempool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mempool.c; path = ../../src/mempool.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F7B1068369500641384 /* mempool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mempool.h; path = ../../src/mempool.h; sourceTree = SOURCE_ROOT; };
|
||||
22322F7C1068369500641384 /* output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = output.c; path = ../../src/output.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F7D1068369500641384 /* quality.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 2; name = quality.c; path = ../../src/quality.c; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
22322F7E1068369500641384 /* report.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = report.c; path = ../../src/report.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F7F1068369500641384 /* rules.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rules.c; path = ../../src/rules.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F801068369500641384 /* smatrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smatrix.c; path = ../../src/smatrix.c; sourceTree = SOURCE_ROOT; };
|
||||
22322F811068369500641384 /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = text.h; path = ../../src/text.h; sourceTree = SOURCE_ROOT; };
|
||||
22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../src/types.h; sourceTree = SOURCE_ROOT; };
|
||||
22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../src/vars.h; sourceTree = SOURCE_ROOT; };
|
||||
22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = epanet2.h; path = ../../include/epanet2.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
2255753B17551217009946B1 /* libepanet-static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libepanet-static.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
225762C31C068A2A00484EC7 /* Net1.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = Net1.inp; path = "../../example-networks/Net1.inp"; sourceTree = "<group>"; };
|
||||
225762C41C068A2A00484EC7 /* Net2.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = Net2.inp; path = "../../example-networks/Net2.inp"; sourceTree = "<group>"; };
|
||||
22CD9A5D1B27898E00B65E83 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = main.c; path = ../../run/main.c; sourceTree = "<group>"; };
|
||||
22E107B21C163E5300689CED /* outputapi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = outputapi.c; path = ../../tools/outputapi/outputapi.c; sourceTree = "<group>"; };
|
||||
22E107B31C163E5300689CED /* outputapi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = outputapi.h; path = ../../tools/outputapi/outputapi.h; sourceTree = "<group>"; };
|
||||
D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
223109EC1BA869DA0030AAE8 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
223109ED1BA869DA0030AAE8 /* libepanet-static.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
22310A031BA869F30030AAE8 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
22322F64106833BB00641384 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
22CD9A611B278BB900B65E83 /* libepanet-static.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2255753817551217009946B1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D289988505E68E00004EDB86 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
08FB7794FE84155DC02AAC07 /* epanet */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
22E107B11C163E3B00689CED /* Output API */,
|
||||
223109E21BA865790030AAE8 /* sample networks */,
|
||||
22CD9A5C1B27896200B65E83 /* run epanet */,
|
||||
22322FA8106836A000641384 /* Include */,
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
);
|
||||
name = epanet;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB7795FE84155DC02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
22322F711068369500641384 /* epanet.c */,
|
||||
22322F751068369500641384 /* hydraul.c */,
|
||||
22322F701068369500641384 /* enumstxt.h */,
|
||||
22322F721068369500641384 /* funcs.h */,
|
||||
22322F731068369500641384 /* hash.c */,
|
||||
22322F741068369500641384 /* hash.h */,
|
||||
22322F761068369500641384 /* inpfile.c */,
|
||||
22322F771068369500641384 /* input1.c */,
|
||||
22322F781068369500641384 /* input2.c */,
|
||||
22322F791068369500641384 /* input3.c */,
|
||||
22322F7A1068369500641384 /* mempool.c */,
|
||||
22322F7B1068369500641384 /* mempool.h */,
|
||||
22322F7C1068369500641384 /* output.c */,
|
||||
22322F7D1068369500641384 /* quality.c */,
|
||||
22322F7E1068369500641384 /* report.c */,
|
||||
22322F7F1068369500641384 /* rules.c */,
|
||||
22322F801068369500641384 /* smatrix.c */,
|
||||
22322F811068369500641384 /* text.h */,
|
||||
22322F831068369500641384 /* types.h */,
|
||||
22322F841068369500641384 /* vars.h */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2AAC0630554660B00DB518D /* libepanet.dylib */,
|
||||
22322F66106833BB00641384 /* runepanet */,
|
||||
2255753B17551217009946B1 /* libepanet-static.a */,
|
||||
223109F31BA869DA0030AAE8 /* runepanet copy */,
|
||||
22310A091BA869F30030AAE8 /* libepanet-static copy.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
223109E21BA865790030AAE8 /* sample networks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
223109E31BA8658A0030AAE8 /* Net3.inp */,
|
||||
225762C31C068A2A00484EC7 /* Net1.inp */,
|
||||
225762C41C068A2A00484EC7 /* Net2.inp */,
|
||||
);
|
||||
name = "sample networks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
22322FA8106836A000641384 /* Include */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
22322FA9106836B000641384 /* epanet2.h */,
|
||||
);
|
||||
name = Include;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
22CD9A5C1B27896200B65E83 /* run epanet */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
22CD9A5D1B27898E00B65E83 /* main.c */,
|
||||
);
|
||||
name = "run epanet";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
22E107B11C163E3B00689CED /* Output API */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
22E107B31C163E5300689CED /* outputapi.h */,
|
||||
22E107B21C163E5300689CED /* outputapi.c */,
|
||||
);
|
||||
name = "Output API";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
22310A041BA869F30030AAE8 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
22310A051BA869F30030AAE8 /* epanet2.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2255753917551217009946B1 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
226537E0179EDEEB00258C60 /* epanet2.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2AAC0600554660B00DB518D /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
22322FAA106836BC00641384 /* epanet2.h in Headers */,
|
||||
22322F851068369500641384 /* enumstxt.h in Headers */,
|
||||
22322F871068369500641384 /* funcs.h in Headers */,
|
||||
22322F891068369500641384 /* hash.h in Headers */,
|
||||
22322F901068369500641384 /* mempool.h in Headers */,
|
||||
22322F961068369500641384 /* text.h in Headers */,
|
||||
22322F981068369500641384 /* types.h in Headers */,
|
||||
22322F991068369500641384 /* vars.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
223109E71BA869DA0030AAE8 /* runepanet float-precision */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 223109F01BA869DA0030AAE8 /* Build configuration list for PBXNativeTarget "runepanet float-precision" */;
|
||||
buildPhases = (
|
||||
223109EA1BA869DA0030AAE8 /* Sources */,
|
||||
223109EC1BA869DA0030AAE8 /* Frameworks */,
|
||||
223109EE1BA869DA0030AAE8 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
223109E81BA869DA0030AAE8 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "runepanet float-precision";
|
||||
productName = runepanet;
|
||||
productReference = 223109F31BA869DA0030AAE8 /* runepanet copy */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
223109F41BA869F30030AAE8 /* epanet-static float-precision */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 22310A061BA869F30030AAE8 /* Build configuration list for PBXNativeTarget "epanet-static float-precision" */;
|
||||
buildPhases = (
|
||||
223109F51BA869F30030AAE8 /* Sources */,
|
||||
22310A031BA869F30030AAE8 /* Frameworks */,
|
||||
22310A041BA869F30030AAE8 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "epanet-static float-precision";
|
||||
productName = "epanet-static";
|
||||
productReference = 22310A091BA869F30030AAE8 /* libepanet-static copy.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
22322F65106833BB00641384 /* runepanet */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 22322F6A106833E600641384 /* Build configuration list for PBXNativeTarget "runepanet" */;
|
||||
buildPhases = (
|
||||
22322F63106833BB00641384 /* Sources */,
|
||||
22322F64106833BB00641384 /* Frameworks */,
|
||||
223109E11BA865690030AAE8 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
22CD9A601B278B0400B65E83 /* PBXTargetDependency */,
|
||||
);
|
||||
name = runepanet;
|
||||
productName = runepanet;
|
||||
productReference = 22322F66106833BB00641384 /* runepanet */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
2255753A17551217009946B1 /* epanet-static */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2255753E17551217009946B1 /* Build configuration list for PBXNativeTarget "epanet-static" */;
|
||||
buildPhases = (
|
||||
2255753717551217009946B1 /* Sources */,
|
||||
2255753817551217009946B1 /* Frameworks */,
|
||||
2255753917551217009946B1 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "epanet-static";
|
||||
productName = "epanet-static";
|
||||
productReference = 2255753B17551217009946B1 /* libepanet-static.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
D2AAC0620554660B00DB518D /* epanet */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */;
|
||||
buildPhases = (
|
||||
D2AAC0600554660B00DB518D /* Headers */,
|
||||
D2AAC0610554660B00DB518D /* Sources */,
|
||||
D289988505E68E00004EDB86 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = epanet;
|
||||
productName = epanet;
|
||||
productReference = D2AAC0630554660B00DB518D /* libepanet.dylib */;
|
||||
productType = "com.apple.product-type.library.dynamic";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0630;
|
||||
};
|
||||
buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
English,
|
||||
Japanese,
|
||||
French,
|
||||
German,
|
||||
);
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* epanet */;
|
||||
projectDirPath = "";
|
||||
projectRoot = ../../..;
|
||||
targets = (
|
||||
D2AAC0620554660B00DB518D /* epanet */,
|
||||
22322F65106833BB00641384 /* runepanet */,
|
||||
2255753A17551217009946B1 /* epanet-static */,
|
||||
223109E71BA869DA0030AAE8 /* runepanet float-precision */,
|
||||
223109F41BA869F30030AAE8 /* epanet-static float-precision */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
223109EA1BA869DA0030AAE8 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
223109EB1BA869DA0030AAE8 /* main.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
223109F51BA869F30030AAE8 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
223109F61BA869F30030AAE8 /* epanet.c in Sources */,
|
||||
223109F71BA869F30030AAE8 /* hash.c in Sources */,
|
||||
223109F81BA869F30030AAE8 /* hydraul.c in Sources */,
|
||||
223109F91BA869F30030AAE8 /* inpfile.c in Sources */,
|
||||
223109FA1BA869F30030AAE8 /* input1.c in Sources */,
|
||||
223109FB1BA869F30030AAE8 /* input2.c in Sources */,
|
||||
223109FC1BA869F30030AAE8 /* input3.c in Sources */,
|
||||
223109FD1BA869F30030AAE8 /* mempool.c in Sources */,
|
||||
223109FE1BA869F30030AAE8 /* output.c in Sources */,
|
||||
223109FF1BA869F30030AAE8 /* quality.c in Sources */,
|
||||
22310A001BA869F30030AAE8 /* report.c in Sources */,
|
||||
22310A011BA869F30030AAE8 /* rules.c in Sources */,
|
||||
22310A021BA869F30030AAE8 /* smatrix.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
22322F63106833BB00641384 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
22CD9A5E1B27898E00B65E83 /* main.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2255753717551217009946B1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2255753F17551234009946B1 /* epanet.c in Sources */,
|
||||
2255754017551234009946B1 /* hash.c in Sources */,
|
||||
2255754117551234009946B1 /* hydraul.c in Sources */,
|
||||
2255754217551234009946B1 /* inpfile.c in Sources */,
|
||||
2255754317551234009946B1 /* input1.c in Sources */,
|
||||
2255754417551234009946B1 /* input2.c in Sources */,
|
||||
2255754517551234009946B1 /* input3.c in Sources */,
|
||||
2255754617551234009946B1 /* mempool.c in Sources */,
|
||||
2255754717551234009946B1 /* output.c in Sources */,
|
||||
2255754817551234009946B1 /* quality.c in Sources */,
|
||||
2255754917551234009946B1 /* report.c in Sources */,
|
||||
2255754A17551234009946B1 /* rules.c in Sources */,
|
||||
2255754B17551234009946B1 /* smatrix.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2AAC0610554660B00DB518D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
22322F861068369500641384 /* epanet.c in Sources */,
|
||||
22322F881068369500641384 /* hash.c in Sources */,
|
||||
22322F8A1068369500641384 /* hydraul.c in Sources */,
|
||||
22322F8B1068369500641384 /* inpfile.c in Sources */,
|
||||
22322F8C1068369500641384 /* input1.c in Sources */,
|
||||
22322F8D1068369500641384 /* input2.c in Sources */,
|
||||
22322F8E1068369500641384 /* input3.c in Sources */,
|
||||
22322F8F1068369500641384 /* mempool.c in Sources */,
|
||||
22322F911068369500641384 /* output.c in Sources */,
|
||||
22322F921068369500641384 /* quality.c in Sources */,
|
||||
22322F931068369500641384 /* report.c in Sources */,
|
||||
22322F941068369500641384 /* rules.c in Sources */,
|
||||
22322F951068369500641384 /* smatrix.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
223109E81BA869DA0030AAE8 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2255753A17551217009946B1 /* epanet-static */;
|
||||
targetProxy = 223109E91BA869DA0030AAE8 /* PBXContainerItemProxy */;
|
||||
};
|
||||
22CD9A601B278B0400B65E83 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2255753A17551217009946B1 /* epanet-static */;
|
||||
targetProxy = 22CD9A5F1B278B0400B65E83 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DEB914B08733D8E0010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double";
|
||||
PRODUCT_NAME = epanet;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB914C08733D8E0010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double";
|
||||
PRODUCT_NAME = epanet;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1DEB914F08733D8E0010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c89;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = "";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB915008733D8E0010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c89;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = "";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
SDKROOT = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
223109F11BA869DA0030AAE8 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||
INFOPLIST_PREPROCESSOR_DEFINITIONS = "";
|
||||
PRODUCT_NAME = "runepanet copy";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
223109F21BA869DA0030AAE8 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||
INFOPLIST_PREPROCESSOR_DEFINITIONS = "";
|
||||
PRODUCT_NAME = "runepanet copy";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
22310A071BA869F30030AAE8 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
PRODUCT_NAME = "epanet-static copy";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
22310A081BA869F30030AAE8 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
PRODUCT_NAME = "epanet-static copy";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
22322F68106833BC00641384 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||
INFOPLIST_PREPROCESSOR_DEFINITIONS = "";
|
||||
PRODUCT_NAME = runepanet;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
22322F69106833BC00641384 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||
INFOPLIST_PREPROCESSOR_DEFINITIONS = "";
|
||||
PRODUCT_NAME = runepanet;
|
||||
SDKROOT = macosx;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2255753C17551217009946B1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double";
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2255753D17551217009946B1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB914B08733D8E0010E9CD /* Debug */,
|
||||
1DEB914C08733D8E0010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB914F08733D8E0010E9CD /* Debug */,
|
||||
1DEB915008733D8E0010E9CD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
223109F01BA869DA0030AAE8 /* Build configuration list for PBXNativeTarget "runepanet float-precision" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
223109F11BA869DA0030AAE8 /* Debug */,
|
||||
223109F21BA869DA0030AAE8 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
22310A061BA869F30030AAE8 /* Build configuration list for PBXNativeTarget "epanet-static float-precision" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
22310A071BA869F30030AAE8 /* Debug */,
|
||||
22310A081BA869F30030AAE8 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
22322F6A106833E600641384 /* Build configuration list for PBXNativeTarget "runepanet" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
22322F68106833BC00641384 /* Debug */,
|
||||
22322F69106833BC00641384 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
2255753E17551217009946B1 /* Build configuration list for PBXNativeTarget "epanet-static" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2255753C17551217009946B1 /* Debug */,
|
||||
2255753D17551217009946B1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
|
||||
}
|
||||
305
cmake/CodeCoverage.cmake
Normal file
305
cmake/CodeCoverage.cmake
Normal file
@@ -0,0 +1,305 @@
|
||||
# Copyright (c) 2012 - 2017, Lars Bilke
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# CHANGES:
|
||||
#
|
||||
# 2012-01-31, Lars Bilke
|
||||
# - Enable Code Coverage
|
||||
#
|
||||
# 2013-09-17, Joakim Söderberg
|
||||
# - Added support for Clang.
|
||||
# - Some additional usage instructions.
|
||||
#
|
||||
# 2016-02-03, Lars Bilke
|
||||
# - Refactored functions to use named parameters
|
||||
#
|
||||
# 2017-06-02, Lars Bilke
|
||||
# - Merged with modified version from github.com/ufz/ogs
|
||||
#
|
||||
#
|
||||
# USAGE:
|
||||
#
|
||||
# 1. Copy this file into your cmake modules path.
|
||||
#
|
||||
# 2. Add the following line to your CMakeLists.txt:
|
||||
# include(CodeCoverage)
|
||||
#
|
||||
# 3. Append necessary compiler flags:
|
||||
# APPEND_COVERAGE_COMPILER_FLAGS()
|
||||
#
|
||||
# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og
|
||||
#
|
||||
# 4. If you need to exclude additional directories from the report, specify them
|
||||
# using the COVERAGE_LCOV_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE_LCOV.
|
||||
# Example:
|
||||
# set(COVERAGE_LCOV_EXCLUDES 'dir1/*' 'dir2/*')
|
||||
#
|
||||
# 5. Use the functions described below to create a custom make target which
|
||||
# runs your test executable and produces a code coverage report.
|
||||
#
|
||||
# 6. Build a Debug build:
|
||||
# cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
# make
|
||||
# make my_coverage_target
|
||||
#
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
# Check prereqs
|
||||
find_program( GCOV_PATH gcov )
|
||||
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
|
||||
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
|
||||
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
||||
find_program( SIMPLE_PYTHON_EXECUTABLE python )
|
||||
|
||||
if(NOT GCOV_PATH)
|
||||
message(FATAL_ERROR "gcov not found! Aborting...")
|
||||
endif() # NOT GCOV_PATH
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
|
||||
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
|
||||
endif()
|
||||
elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
|
||||
message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
|
||||
endif()
|
||||
|
||||
set(COVERAGE_COMPILER_FLAGS "-g --coverage -fprofile-arcs -ftest-coverage"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE
|
||||
${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the C++ compiler during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_C_FLAGS_COVERAGE
|
||||
${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the C compiler during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
""
|
||||
CACHE STRING "Flags used for linking binaries during coverage builds."
|
||||
FORCE )
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||
""
|
||||
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
|
||||
FORCE )
|
||||
mark_as_advanced(
|
||||
CMAKE_CXX_FLAGS_COVERAGE
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
|
||||
endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
link_libraries(gcov)
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
|
||||
endif()
|
||||
|
||||
# Defines a target for running and collection code coverage information
|
||||
# Builds dependencies, runs the given executable and outputs reports.
|
||||
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||
# the coverage generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_LCOV(
|
||||
# NAME testrunner_coverage # New target name
|
||||
# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES testrunner # Dependencies to build first
|
||||
# )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_LCOV)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT LCOV_PATH)
|
||||
message(FATAL_ERROR "lcov not found! Aborting...")
|
||||
endif() # NOT LCOV_PATH
|
||||
|
||||
if(NOT GENHTML_PATH)
|
||||
message(FATAL_ERROR "genhtml not found! Aborting...")
|
||||
endif() # NOT GENHTML_PATH
|
||||
|
||||
# Setup target
|
||||
add_custom_target(${Coverage_NAME}
|
||||
|
||||
# Cleanup lcov
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . --zerocounters
|
||||
# Create baseline to make sure untouched files show up in the report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base
|
||||
|
||||
# Run tests
|
||||
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
|
||||
# Capturing lcov counters and generating report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . --capture --output-file ${Coverage_NAME}.info
|
||||
# add baseline counters
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.info --output-file ${Coverage_NAME}.total
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove ${Coverage_NAME}.total ${COVERAGE_LCOV_EXCLUDES} --output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
|
||||
COMMAND ${GENHTML_PATH} ${Coverage_GENHTML_ARGS} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
|
||||
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
|
||||
)
|
||||
|
||||
# Show where to find the lcov info report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_LCOV
|
||||
|
||||
# Defines a target for running and collection code coverage information
|
||||
# Builds dependencies, runs the given executable and outputs reports.
|
||||
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||
# the coverage generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_GCOVR_XML(
|
||||
# NAME ctest_coverage # New target name
|
||||
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES executable_target # Dependencies to build first
|
||||
# )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT SIMPLE_PYTHON_EXECUTABLE)
|
||||
message(FATAL_ERROR "python not found! Aborting...")
|
||||
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
endif() # NOT GCOVR_PATH
|
||||
|
||||
# Combine excludes to several -e arguments
|
||||
set(GCOVR_EXCLUDES "")
|
||||
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
|
||||
list(APPEND GCOVR_EXCLUDES "-e")
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${Coverage_NAME}
|
||||
# Run tests
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH} --xml
|
||||
-r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
|
||||
--object-directory=${PROJECT_BINARY_DIR}
|
||||
-o ${Coverage_NAME}.xml
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT "Running gcovr to produce Cobertura code coverage report."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml."
|
||||
)
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_XML
|
||||
|
||||
# Defines a target for running and collection code coverage information
|
||||
# Builds dependencies, runs the given executable and outputs reports.
|
||||
# NOTE! The executable should always have a ZERO as exit code otherwise
|
||||
# the coverage generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML(
|
||||
# NAME ctest_coverage # New target name
|
||||
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES executable_target # Dependencies to build first
|
||||
# )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(NOT SIMPLE_PYTHON_EXECUTABLE)
|
||||
message(FATAL_ERROR "python not found! Aborting...")
|
||||
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
endif() # NOT GCOVR_PATH
|
||||
|
||||
# Combine excludes to several -e arguments
|
||||
set(GCOVR_EXCLUDES "")
|
||||
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
|
||||
list(APPEND GCOVR_EXCLUDES "-e")
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${Coverage_NAME}
|
||||
# Run tests
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
|
||||
# Create folder
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
|
||||
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH} --html --html-details
|
||||
-r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
|
||||
--object-directory=${PROJECT_BINARY_DIR}
|
||||
-o ${Coverage_NAME}/index.html
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT "Running gcovr to produce HTML code coverage report."
|
||||
)
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML
|
||||
|
||||
function(APPEND_COVERAGE_COMPILER_FLAGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||
message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
|
||||
endfunction() # APPEND_COVERAGE_COMPILER_FLAGS
|
||||
15958
doc/DataFlow.eps
Normal file
15958
doc/DataFlow.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/DataFlow.png
Normal file
BIN
doc/DataFlow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
7265
doc/DistributionSystem.eps
Normal file
7265
doc/DistributionSystem.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/DistributionSystem.png
Normal file
BIN
doc/DistributionSystem.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
195
doc/DoxygenLayout.xml
Normal file
195
doc/DoxygenLayout.xml
Normal file
@@ -0,0 +1,195 @@
|
||||
<doxygenlayout version="1.0">
|
||||
<!-- Generated by doxygen 1.8.10 -->
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title=""/>
|
||||
<tab type="pages" visible="yes" title="" intro=""/>
|
||||
<tab type="modules" visible="yes" title="API Reference"
|
||||
intro="These topics describe the Toolkit's functions, enumerations, and error/warning codes."/>
|
||||
<tab type="namespaces" visible="yes" title="">
|
||||
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
||||
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="classes" visible="yes" title="">
|
||||
<tab type="classlist" visible="yes" title="" intro=""/>
|
||||
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
||||
<tab type="hierarchy" visible="yes" title="" intro=""/>
|
||||
<tab type="classmembers" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="files" visible="no" title="">
|
||||
<tab type="filelist" visible="no" title="" intro=""/>
|
||||
<tab type="globals" visible="no" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="examples" visible="yes" title="" intro=""/>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
<class>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
<publicstaticmethods title=""/>
|
||||
<publicattributes title=""/>
|
||||
<publicstaticattributes title=""/>
|
||||
<protectedtypes title=""/>
|
||||
<protectedslots title=""/>
|
||||
<protectedmethods title=""/>
|
||||
<protectedstaticmethods title=""/>
|
||||
<protectedattributes title=""/>
|
||||
<protectedstaticattributes title=""/>
|
||||
<packagetypes title=""/>
|
||||
<packagemethods title=""/>
|
||||
<packagestaticmethods title=""/>
|
||||
<packageattributes title=""/>
|
||||
<packagestaticattributes title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
<privatetypes title=""/>
|
||||
<privateslots title=""/>
|
||||
<privatemethods title=""/>
|
||||
<privatestaticmethods title=""/>
|
||||
<privateattributes title=""/>
|
||||
<privatestaticattributes title=""/>
|
||||
<friends title=""/>
|
||||
<related title="" subtitle=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
<variables title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<allmemberslink visible="yes"/>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
||||
<!-- Layout definition for a namespace page -->
|
||||
<namespace>
|
||||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</namespace>
|
||||
|
||||
<!-- Layout definition for a file page -->
|
||||
<file>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<classes visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection/>
|
||||
</file>
|
||||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="yes"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<nestedgroups visible="yes" title="File Sections"/>
|
||||
<dirs visible="yes" title=""/>
|
||||
<files visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title="Overview"/>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</group>
|
||||
|
||||
<!-- Layout definition for a directory page -->
|
||||
<directory>
|
||||
<briefdescription visible="yes"/>
|
||||
<directorygraph visible="yes"/>
|
||||
<memberdecl>
|
||||
<dirs visible="yes"/>
|
||||
<files visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
</directory>
|
||||
</doxygenlayout>
|
||||
5118
doc/Example2.eps
Normal file
5118
doc/Example2.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/Example2.png
Normal file
BIN
doc/Example2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
@page how-to-use How to Use the Toolkit
|
||||
|
||||
The following topics briefly describe how to accomplish some basic tasks for which the Toolkit would be used. See the Example Applications topic for code listings of complete applications of the Toolkit.
|
||||
|
||||
@section open-close Opening and Closing the Toolkit
|
||||
|
||||
The Toolkit must open an EPANET [Input File](Input-File) to obtain a description of the pipe network to be analyzed before any of its other functions can be called. (The exception to this is the @ref ENepanet function, which performs a complete hydraulic/water quality simulation similar to a command line execution of EPANET). Once all analysis is completed, it must close itself down to free all allocated memory. The functions for doing this are @ref ENopen and @ref ENclose, respectively. An example of using these functions is shown below.
|
||||
|
||||
~~~~~~~~~~~~~~~{.c}
|
||||
char *f1, // Name of input file
|
||||
*f2, // name of report file
|
||||
*f3; // name of output file (can be blank)
|
||||
int errcode;
|
||||
errcode = ENopen(f1, f2, f3);
|
||||
if (errcode > 0) {
|
||||
ENclose();
|
||||
return;
|
||||
}
|
||||
{ Call functions that perform desired analysis }
|
||||
ENclose();
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@section parameters Retrieving and Setting Network Parameters
|
||||
|
||||
The Toolkit has various functions available for retrieving and setting the parameters that define the design and operation of the pipe network being analyzed. The names of retrieval functions all begin with `ENget` (e.g., [ENgetnodevalue](ENgetnodevalue), [ENgetoption](ENgetoption), etc.) while the functions used for setting parameter values begin with `ENset` (e.g., [ENsetnodevalue](ENsetnodevalue), [ENsetoption](ENsetoption), etc.).
|
||||
|
||||
Most of these functions use an index number to reference a specific network component (such as a node, link, or time pattern). This number is simply the position of the component in the list of all components of similar type (e.g., node 10 is the tenth node, starting from 1, in the network) and is not the same as the ID label assigned to the component in the Input File being processed. A series of functions exist to determine a component's index number given its ID label (see [ENgetlinkindex](ENgetlinkindex), [ENgetnodeindex](ENgetnodeindex), and [ENgetpatternindex](ENgetpatternindex)). Likewise, functions exist to retrieve a component's ID label given its index number (see [ENgetlinkid](ENgetlinkid), [ENgetnodeid](ENgetnodeid), and [ENgetpatternid](ENgetpatternid)). The [ENgetcount](ENgetcount) function can be used to determine the number of different components in the network.
|
||||
|
||||
The code below is an example of using the parameter retrieval and setting functions. It changes all pipes with diameter of 10 inches to 12 inches.
|
||||
|
||||
~~~~~~~~~~~~~~~{.c}
|
||||
int i, Nlinks;
|
||||
float D;
|
||||
ENgetcount(EN_LINKCOUNT, &Nlinks);
|
||||
for (i = 1; i <= Nlinks; i++) {
|
||||
ENgetlinkvalue(i, EN_DIAMETER, &D);
|
||||
if (D == 10) ENsetlinkvalue(i, EN_DIAMETER, 12);
|
||||
}
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
*/
|
||||
8420
doc/Network.eps
Normal file
8420
doc/Network.eps
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/Network.png
Normal file
BIN
doc/Network.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
@page toolkit-overview Toolkit Overview
|
||||
|
||||
|
||||
The Programmer's Toolkit is an extension of the EPANET simulation package. EPANET performs extended period simulation of hydraulic and water quality behavior within pressurized pipe networks. A network can consist of pipes, nodes (pipe junctions), pumps, valves and storage tanks or reservoirs. EPANET tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank, and the concentration of a chemical species throughout the network during a multi-time period simulation. In addition to chemical species, water age and source tracing can also be simulated.
|
||||
|
||||
The Toolkit provides a series of functions that allow programmers to customize the use of EPANET's hydraulic and water quality solution engine to their own applications. Before using the Toolkit one should become familiar with the way that EPANET represents a pipe network and the design and operating information it requires to perform a simulation. This information can be obtained from reading EPANET's on-line Help file or from the EPANET Users Manual.
|
||||
|
||||
A typical usage of the Toolkit functions to analyze a distribution system might look as follows:
|
||||
|
||||
1. Use the @ref ENopen function to open the Toolkit system, along with an EPANET [Input file](Input-File).
|
||||
2. Use the `ENsetxxx` series of functions to change selected system characteristics.
|
||||
3. Run a full hydraulic simulation using the @ref ENsolveH function (which automatically saves results to a [Hydraulics file](Hydraulics-File)) or use the @ref ENopenH - @ref ENinitH - @ref ENrunH - @ref ENnextH - @ref ENcloseH series of functions to step through a hydraulic simulation, accessing results along the way with the `ENgetxxx` series of functions.
|
||||
4. Run a full water quality simulation using @ref ENsolveQ (which automatically saves hydraulic and water quality results to an [Output file](Output-File)) or use the @ref ENopenQ - @ref ENinitQ - @ref ENrunQ - @ref ENnextQ (or @ref ENstepQ) - @ref ENcloseQ series of functions to step through a water quality simulation, accessing results along the way with the `ENgetxxx` series of functions.
|
||||
5. Return to Step 2 to run additional analyses or use the @ref ENreport function to write a formatted report to the [Report file](Report-File).
|
||||
6. Call the @ref ENclose function to close all files and release system memory.
|
||||
|
||||
More specific examples of using the functions can be found in the [Example Applications](Example-Applications) topic.
|
||||
|
||||
|
||||
- @subpage how-to-use
|
||||
|
||||
*/
|
||||
93
doc/doxyfile
93
doc/doxyfile
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.8.11
|
||||
# Doxyfile 1.8.10
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
@@ -32,13 +32,13 @@ DOXYFILE_ENCODING = UTF-8
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = EPANET
|
||||
PROJECT_NAME = "OWA-EPANET Toolkit"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 2.1
|
||||
PROJECT_NUMBER = 2.2
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -58,7 +58,7 @@ PROJECT_LOGO =
|
||||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = ../epanet-owa-dox
|
||||
OUTPUT_DIRECTORY =
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
|
||||
# directories (in 2 levels) under the output directory of each output format and
|
||||
@@ -226,7 +226,7 @@ SEPARATE_MEMBER_PAGES = NO
|
||||
# uses this value to replace tabs by spaces in code fragments.
|
||||
# Minimum value: 1, maximum value: 16, default value: 4.
|
||||
|
||||
TAB_SIZE = 2
|
||||
TAB_SIZE = 4
|
||||
|
||||
# This tag can be used to specify a number of aliases that act as commands in
|
||||
# the documentation. An alias has the form:
|
||||
@@ -535,7 +535,7 @@ HIDE_COMPOUND_REFERENCE= NO
|
||||
# the files that are included by a file in the documentation of that file.
|
||||
# The default value is: YES.
|
||||
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
|
||||
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
|
||||
# grouped member an include statement to the documentation, telling the reader
|
||||
@@ -694,7 +694,7 @@ FILE_VERSION_FILTER =
|
||||
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
|
||||
# tag is left empty.
|
||||
|
||||
LAYOUT_FILE =
|
||||
LAYOUT_FILE = DoxygenLayout.xml
|
||||
|
||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||
# the reference definitions. This must be a list of .bib files. The .bib
|
||||
@@ -749,12 +749,6 @@ WARN_IF_DOC_ERROR = YES
|
||||
|
||||
WARN_NO_PARAMDOC = NO
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_AS_ERROR = NO
|
||||
|
||||
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
|
||||
# can produce. The string should contain the $file, $line, and $text tags, which
|
||||
# will be replaced by the file and line number from which the warning originated
|
||||
@@ -781,10 +775,15 @@ WARN_LOGFILE =
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = ../include \
|
||||
../src \
|
||||
../doc \
|
||||
../
|
||||
INPUT = main.dox \
|
||||
toolkit-usage.dox \
|
||||
toolkit-examples.dox \
|
||||
toolkit-files.dox \
|
||||
input-file.dox \
|
||||
toolkit-units.dox \
|
||||
modules.dox \
|
||||
../include/epanet2_enums.h \
|
||||
../include/epanet2_2.h
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@@ -806,8 +805,8 @@ INPUT_ENCODING = UTF-8
|
||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
|
||||
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
|
||||
# *.vhdl, *.ucf, *.qsf, *.as and *.js.
|
||||
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
@@ -856,7 +855,7 @@ FILE_PATTERNS = *.c \
|
||||
# be searched for input files as well.
|
||||
# The default value is: NO.
|
||||
|
||||
RECURSIVE = NO
|
||||
RECURSIVE = YES
|
||||
|
||||
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
@@ -918,7 +917,7 @@ EXAMPLE_RECURSIVE = NO
|
||||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
IMAGE_PATH = .
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
@@ -934,10 +933,6 @@ IMAGE_PATH =
|
||||
# Note that the filter must not add or remove lines; it is applied before the
|
||||
# code is scanned, but not when the output code is generated. If lines are added
|
||||
# or removed, the anchors will not be placed correctly.
|
||||
#
|
||||
# Note that for custom extensions or not directly supported extensions you also
|
||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# properly processed by doxygen.
|
||||
|
||||
INPUT_FILTER =
|
||||
|
||||
@@ -947,10 +942,6 @@ INPUT_FILTER =
|
||||
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
|
||||
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
|
||||
# patterns match the file name, INPUT_FILTER is applied.
|
||||
#
|
||||
# Note that for custom extensions or not directly supported extensions you also
|
||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# properly processed by doxygen.
|
||||
|
||||
FILTER_PATTERNS =
|
||||
|
||||
@@ -1068,7 +1059,7 @@ VERBATIM_HEADERS = YES
|
||||
# rich C++ code for which doxygen's built-in parser lacks the necessary type
|
||||
# information.
|
||||
# Note: The availability of this option depends on whether or not doxygen was
|
||||
# generated with the -Duse-libclang=ON option for CMake.
|
||||
# compiled with the --with-libclang option.
|
||||
# The default value is: NO.
|
||||
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
@@ -1122,7 +1113,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = ../../epanet-owa-dox
|
||||
HTML_OUTPUT = html
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
@@ -1149,7 +1140,7 @@ HTML_FILE_EXTENSION = .html
|
||||
# of the possible markers and block names see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_HEADER =
|
||||
HTML_HEADER =
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
||||
@@ -1159,7 +1150,7 @@ HTML_HEADER =
|
||||
# that doxygen normally uses.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FOOTER =
|
||||
HTML_FOOTER = newfooter.html
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||
@@ -1184,7 +1175,7 @@ HTML_STYLESHEET =
|
||||
# list). For an example see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET = extrastylesheet.css
|
||||
|
||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the HTML output directory. Note
|
||||
@@ -1323,7 +1314,7 @@ GENERATE_HTMLHELP = NO
|
||||
# written to the html output directory.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
CHM_FILE =
|
||||
CHM_FILE = owa_epanet.chm
|
||||
|
||||
# The HHC_LOCATION tag can be used to specify the location (absolute path
|
||||
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
|
||||
@@ -1331,7 +1322,7 @@ CHM_FILE =
|
||||
# The file has to be specified with full path.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
HHC_LOCATION =
|
||||
HHC_LOCATION = "c:\Program Files (x86)\HTML Help Workshop\hhc.exe"
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||
# (YES) or that it should be included in the master .chm file (NO).
|
||||
@@ -1453,7 +1444,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
DISABLE_INDEX = NO
|
||||
DISABLE_INDEX = YES
|
||||
|
||||
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
|
||||
# structure should be generated to display hierarchical information. If the tag
|
||||
@@ -1480,7 +1471,7 @@ GENERATE_TREEVIEW = YES
|
||||
# Minimum value: 0, maximum value: 20, default value: 4.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
ENUM_VALUES_PER_LINE = 0
|
||||
|
||||
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
|
||||
# to set the initial width (in pixels) of the frame in which the tree is shown.
|
||||
@@ -1658,7 +1649,7 @@ EXTRA_SEARCH_MAPPINGS =
|
||||
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
|
||||
# The default value is: YES.
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_LATEX = YES
|
||||
|
||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
|
||||
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||
@@ -1701,7 +1692,7 @@ COMPACT_LATEX = NO
|
||||
# The default value is: a4.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
PAPER_TYPE = a4
|
||||
PAPER_TYPE = letter
|
||||
|
||||
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
||||
# that should be included in the LaTeX output. The package can be specified just
|
||||
@@ -1729,7 +1720,7 @@ EXTRA_PACKAGES =
|
||||
# to HTML_HEADER.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_HEADER =
|
||||
LATEX_HEADER = header.tex
|
||||
|
||||
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
|
||||
# generated LaTeX document. The footer should contain everything after the last
|
||||
@@ -1740,7 +1731,7 @@ LATEX_HEADER =
|
||||
# Note: Only use a user-defined footer if you know what you are doing!
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_FOOTER =
|
||||
LATEX_FOOTER =
|
||||
|
||||
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
||||
# LaTeX style sheets that are included after the standard style sheets created
|
||||
@@ -1751,7 +1742,7 @@ LATEX_FOOTER =
|
||||
# list).
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_EXTRA_STYLESHEET =
|
||||
LATEX_EXTRA_STYLESHEET =
|
||||
|
||||
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the LATEX_OUTPUT output
|
||||
@@ -1785,14 +1776,14 @@ USE_PDFLATEX = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_BATCHMODE = YES
|
||||
|
||||
# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
|
||||
# index chapters (such as File Index, Compound Index, etc.) in the output.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_HIDE_INDICES = YES
|
||||
|
||||
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
|
||||
# code with syntax highlighting in the LaTeX output.
|
||||
@@ -1812,14 +1803,6 @@ LATEX_SOURCE_CODE = NO
|
||||
|
||||
LATEX_BIB_STYLE = plain
|
||||
|
||||
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
|
||||
# page will contain the date and time when the page was generated. Setting this
|
||||
# to NO can help when comparing the output of multiple runs.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_TIMESTAMP = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2059,7 +2042,7 @@ MACRO_EXPANSION = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
|
||||
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
|
||||
# INCLUDE_PATH will be searched if a #include is found.
|
||||
@@ -2175,7 +2158,7 @@ PERL_PATH = /usr/bin/perl
|
||||
# powerful graphs.
|
||||
# The default value is: YES.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
CLASS_DIAGRAMS = NO
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see:
|
||||
|
||||
2
doc/extrastylesheet.css
Normal file
2
doc/extrastylesheet.css
Normal file
@@ -0,0 +1,2 @@
|
||||
h1 { font-size:1.5em; }
|
||||
|
||||
12
doc/footer.tex
Normal file
12
doc/footer.tex
Normal file
@@ -0,0 +1,12 @@
|
||||
% Latex footer for doxygen 1.8.10
|
||||
%--- End generated contents ---
|
||||
|
||||
% Index
|
||||
\backmatter
|
||||
\newpage
|
||||
\phantomsection
|
||||
\clearemptydoublepage
|
||||
\addcontentsline{toc}{chapter}{Index}
|
||||
\printindex
|
||||
|
||||
\end{document}
|
||||
141
doc/header.tex
Normal file
141
doc/header.tex
Normal file
@@ -0,0 +1,141 @@
|
||||
% Latex header for doxygen 1.8.10
|
||||
\documentclass[twoside]{book}
|
||||
|
||||
% Packages required by doxygen
|
||||
\usepackage{fixltx2e}
|
||||
\usepackage{calc}
|
||||
\usepackage{doxygen}
|
||||
\usepackage[export]{adjustbox} % also loads graphicx
|
||||
\usepackage{graphicx}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{multirow}
|
||||
\PassOptionsToPackage{warn}{textcomp}
|
||||
\usepackage{textcomp}
|
||||
\usepackage[nointegrals]{wasysym}
|
||||
\usepackage[table]{xcolor}
|
||||
|
||||
% Font selection
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage[scaled=.90]{helvet}
|
||||
\usepackage{courier}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{sectsty}
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
\allsectionsfont{%
|
||||
\fontseries{bc}\selectfont%
|
||||
\color{darkgray}%
|
||||
}
|
||||
\renewcommand{\DoxyLabelFont}{%
|
||||
\fontseries{bc}\selectfont%
|
||||
\color{darkgray}%
|
||||
}
|
||||
\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}
|
||||
|
||||
% Page & text layout
|
||||
\usepackage{geometry}
|
||||
\geometry{%
|
||||
a4paper,%
|
||||
top=2.5cm,%
|
||||
bottom=2.5cm,%
|
||||
left=2.5cm,%
|
||||
right=2.5cm%
|
||||
}
|
||||
\tolerance=750
|
||||
\hfuzz=15pt
|
||||
\hbadness=750
|
||||
\setlength{\emergencystretch}{15pt}
|
||||
\setlength{\parindent}{0cm}
|
||||
\setlength{\parskip}{0.2cm}
|
||||
\makeatletter
|
||||
\renewcommand{\paragraph}{%
|
||||
\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%
|
||||
\normalfont\normalsize\bfseries\SS@parafont%
|
||||
}%
|
||||
}
|
||||
\renewcommand{\subparagraph}{%
|
||||
\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%
|
||||
\normalfont\normalsize\bfseries\SS@subparafont%
|
||||
}%
|
||||
}
|
||||
\makeatother
|
||||
|
||||
% Headers & footers
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancyplain}
|
||||
\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}}
|
||||
\fancyhead[CE]{\fancyplain{}{}}
|
||||
\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}}
|
||||
\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}}
|
||||
\fancyhead[CO]{\fancyplain{}{}}
|
||||
\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
|
||||
\fancyfoot[LE]{\fancyplain{}{}}
|
||||
\fancyfoot[CE]{\fancyplain{}{}}
|
||||
\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize OWA-EPANET 2.2 \textcopyright 2019}}
|
||||
\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize OWA-EPANET 2.2 \textcopyright 2019}}
|
||||
\fancyfoot[CO]{\fancyplain{}{}}
|
||||
\fancyfoot[RO]{\fancyplain{}{}}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
\renewcommand{\chaptermark}[1]{%
|
||||
\markboth{#1}{}%
|
||||
}
|
||||
\renewcommand{\sectionmark}[1]{%
|
||||
\markright{\thesection\ #1}%
|
||||
}
|
||||
|
||||
% Indices & bibliography
|
||||
\usepackage{natbib}
|
||||
\usepackage[titles]{tocloft}
|
||||
\setcounter{tocdepth}{1}
|
||||
\setcounter{secnumdepth}{5}
|
||||
\makeindex
|
||||
|
||||
% Hyperlinks (required, but should be loaded last)
|
||||
\usepackage{ifpdf}
|
||||
\ifpdf
|
||||
\usepackage[pdftex,pagebackref=true]{hyperref}
|
||||
\else
|
||||
\usepackage[ps2pdf,pagebackref=true]{hyperref}
|
||||
\fi
|
||||
\hypersetup{%
|
||||
colorlinks=true,%
|
||||
linkcolor=blue,%
|
||||
citecolor=blue,%
|
||||
unicode%
|
||||
}
|
||||
|
||||
% Custom commands
|
||||
\newcommand{\clearemptydoublepage}{%
|
||||
\newpage{\pagestyle{empty}\cleardoublepage}%
|
||||
}
|
||||
|
||||
|
||||
%===== C O N T E N T S =====
|
||||
|
||||
\begin{document}
|
||||
|
||||
% Titlepage & ToC
|
||||
\hypersetup{pageanchor=false,
|
||||
bookmarks=true,
|
||||
bookmarksnumbered=true,
|
||||
pdfencoding=unicode
|
||||
}
|
||||
\pagenumbering{roman}
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}%
|
||||
{\Large OWA-EPANET Toolkit\linebreak\linebreak 2.2}\\
|
||||
\vspace*{1cm}
|
||||
{\large January 2019}\\
|
||||
%\vspace*{0.5cm}
|
||||
%{\small Wed Jan 23 2019 17:57:36}\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
\clearemptydoublepage
|
||||
\tableofcontents
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{arabic}
|
||||
\hypersetup{pageanchor=true}
|
||||
|
||||
%--- Begin generated contents ---
|
||||
1152
doc/input-file.dox
Normal file
1152
doc/input-file.dox
Normal file
File diff suppressed because it is too large
Load Diff
121
doc/main.dox
121
doc/main.dox
@@ -1,12 +1,119 @@
|
||||
/**
|
||||
@mainpage EPANET Open Source
|
||||
/**
|
||||
@mainpage Overview
|
||||
|
||||
The EPANET Open-Source Library is a pressurized pipe network hydraulic and water quality analysis toolkit, originally developed by USEPA, written in C.
|
||||
EPANET is a program that performs extended period simulation of hydraulic and water quality behavior within water distribution system pipe networks. A network can consist of pipes, nodes (pipe junctions), pumps, valves and storage tanks or reservoirs. EPANET tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank, and the concentration of a chemical species throughout the network during a multi-time period simulation. In addition to chemical species, water age and source tracing can also be simulated.
|
||||
|
||||
__Note:__ This repository is not affiliated with, or endorsed by, the USEPA. For the "official" release of EPANET (2.00.12 UI and Toolkit) please go to the [EPA's GitHub repo](https://github.com/USEPA/Water-Distribution-Network-Model) or [the USEPA website](http://www2.epa.gov/water-research/epanet). It is also not the graphical user interface version. This is the hydraulic and water quality solver engine.
|
||||
<table style = "border: 0px solid black">
|
||||
<tr><td style="vertical-align: top">
|
||||
@image html DistributionSystem.png
|
||||
@image latex DistributionSystem.eps
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
However, if you are interested in 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).
|
||||
The EPANET Programmer's Toolkit is a library of functions (or API) written in C that allow programmers to customize the use of EPANET's hydraulic and water quality solution engine to their own applications. Both EPANET and its toolkit were originally developed by the U.S. Environmental Protection Agency (USEPA).
|
||||
|
||||
- @subpage toolkit-overview "Toolkit Overview"
|
||||
The OWA-EPANET Toolkit is an open-source version of the original EPANET Toolkit that extends its capabilities by:
|
||||
- providing a full set of functions to set and retrieve values for all parameters contained in a network model
|
||||
- allowing networks to be built completely from function calls instead of from an input file
|
||||
- allowing multiple projects to be analyzed in parallel in a thread-safe manner
|
||||
- adding the ability to use pressure dependent demands in hydraulic analyses
|
||||
- producing more robust results with regard to hydraulic convergence, low/zero flow conditions, and water quality mass balance
|
||||
- achieving faster run times for single period hydraulic analyses.
|
||||
|
||||
*/
|
||||
Before using the OWA-EPANET Toolkit one should be familiar with the way that EPANET represents a pipe network, the design and operating information it requires, and the steps it uses to simulate a network's behavior. The following topics provide some introductory material on these subjects:
|
||||
- @subpage DataModel "Network Data Model"
|
||||
- @subpage DataFlow "Data Flow Diagram"
|
||||
- @subpage ToolkitVersions "Toolkit Versions"
|
||||
|
||||
More detailed information can be obtained from reading the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>.
|
||||
|
||||
__Note:__ <a href="https://github.com/OpenWaterAnalytics">OWA (Open Water Analytics)</a> exists on GitHub as an open community for the exchange of information and ideas related to computing in the water & wastewater industries. Its activities and code projects are neither affiliated with nor endorsed by the USEPA.
|
||||
*/
|
||||
|
||||
/**
|
||||
@page DataModel Network Data Model
|
||||
|
||||
EPANET models a pipe network as a collection of links connected to nodes. The links represent pipes, pumps, and control valves. The nodes represent junctions, tanks, and reservoirs. The figure below illustrates how these objects can be connected to one another to form a network.
|
||||
|
||||
<table style = "border: 0px solid black">
|
||||
<tr><td>
|
||||
@image html Network.png
|
||||
@image latex Network.eps
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
Junctions have a user-supplied water withdrawal rate (i.e., consumer demand) associated with them. Tanks are storage units whose water level changes over time. Reservoirs are boundary points where a fixed hydraulic head applies.
|
||||
|
||||
Pipes have a length, diameter and roughness coefficient that determines their head loss as a function of flow rate. Pumps have either a constant power rating or a head curve that determines the head they add as a function of flow rate. Valves are used to regulate either flow or pressure. Controls can be applied to completely open or close a link or to adjust its setting (pump speed or valve setting).
|
||||
|
||||
In addition to these physical objects an EPANET model can also contain the following data objects:
|
||||
- time patterns that allow demands, quality source strength and pump speed settings to vary at fixed
|
||||
intervals of time
|
||||
- data curves that describe relationships between two quantities, such as head versus flow for pumps and
|
||||
volume versus water level for tanks
|
||||
- simple controls that adjust a link's setting (such as a pump's status) based on node pressure, tank
|
||||
level, elapsed time, ot time of day
|
||||
- rule-based controls that consist of one or more premises that if true result in one set of actions
|
||||
being taken and if false result in a different set of actions being taken
|
||||
- water quality sources that introduce a chemical constituent into the network at specified nodes.
|
||||
|
||||
An EPANET model also contains a number of analysis options that specify:
|
||||
- the project's flow units which in turn determines its unit system (US or SI)
|
||||
- the formula used to compute head loss
|
||||
- whether to use a demand driven or a pressure driven analysis
|
||||
- hydraulic convergence criteria
|
||||
- time steps used for hydraulic, water quality and reporting
|
||||
- the type of water quality analysis to perform (chemical reaction, source tracing or water age)
|
||||
- global values for chemical reaction coefficients that can be overridden for individual pipes
|
||||
- global values for energy usage parameters that can be overridden for individual pumps.
|
||||
|
||||
Please refer to the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>
|
||||
for more information on EPANET's data model.
|
||||
*/
|
||||
|
||||
/**
|
||||
@page DataFlow Data Flow Diagram
|
||||
|
||||
The EPANET Toolkit contains separate code modules for network building, hydraulic analysis, water quality analysis, and report generation. The data flow diagram for analyzing a pipe network is shown below. The processing steps depicted in this diagram can be summarized as follows:
|
||||
|
||||
<table style = "border: 0px solid black">
|
||||
<tr><td>
|
||||
@image html DataFlow.png
|
||||
@image latex DataFlow.eps
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
- The network builder receives a description of the network being simulated either from an external input file (.inp) or from a series of function calls that create network objects and assign their properties via code. These data are stored in a Project data structure.
|
||||
|
||||
- The hydraulics solver carries out an extended period hydraulic simulation. The results obtained at every time step can be written to an external, unformatted (binary) hydraulics file (.hyd). Some of these time steps might represent intermediate points in time where system conditions change because of tanks becoming full or empty or pumps turning on or off due to level controls or timed operation.
|
||||
|
||||
- If a water quality simulation is requested, the water quality solver accesses the flow data from the hydraulics file as it computes substance transport and reaction throughout the network over each hydraulic time step. During this process it can write both the formerly computed hydraulic results as well as its water quality results for each preset reporting interval to an unformatted (binary) output file (.out). If no water quality analysis was called for, then the hydraulic results stored in the .hyd file can simply be written out to the binary output file at uniform reporting intervals.
|
||||
|
||||
- If requested, a report writer reads back the computed simulation results from the binary output file (.out) for each reporting period and writes out selected values to a formatted report file (.rpt). Any error or warning messages generated during the run are also written to this file.
|
||||
|
||||
Toolkit functions exist to carry out all of these steps under the programmer's control, including the ability to read and modify the contents of the Project data structure.
|
||||
*/
|
||||
|
||||
/**
|
||||
@page ToolkitVersions Toolkit Versions
|
||||
|
||||
The Toolkit comes with two sets of identical functions that programmers can utilize:
|
||||
- the single-threaded version of the Toolkit is compatible with previous releases and only works
|
||||
with single threaded applications.
|
||||
- the multi-threaded version allows users to create multiple EPANET data sets (called projects) that can be
|
||||
analyzed concurrently.
|
||||
|
||||
Both Toolkit versions utilize identical function names and argument lists with the following exceptions:
|
||||
- The `#include "epanet2.h"` directive must appear in all C/C++ code modules that use the single-threaded library while `#include "epanet2_2.h"` must be used for the multi-threaded library.
|
||||
- Function names in the single-threaded library begin with \b EN while those in the multi-threaded
|
||||
library begin with \b EN_ .
|
||||
- The multi-threaded functions contain an additional argument that references a particular network project
|
||||
that the function is applied to.
|
||||
- The multi-threaded library contains two additional functions that allow users to create and delete
|
||||
EPANET projects.
|
||||
- The single-threaded library uses single precision for its floating point arguments while the
|
||||
multi-threaded library uses double precision.
|
||||
|
||||
To avoid unnecessary duplication this document only discusses the multi-threaded version of the
|
||||
Toolkit.
|
||||
*/
|
||||
|
||||
387
doc/modules.dox
Normal file
387
doc/modules.dox
Normal file
@@ -0,0 +1,387 @@
|
||||
/**
|
||||
@defgroup Project Project Functions
|
||||
These functions are used to manage a project.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Hydraulics Hydraulic Analysis Functions
|
||||
These functions are used to perform a hydraulic analysis.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Quality Water Quality Analysis Functions
|
||||
These functions are used to perform a water quality analysis.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Reporting Reporting Functions
|
||||
These functions are used to report simulation results.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Options Analysis Options Functions
|
||||
These functions are used to get and set analysis options.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Nodes Network Node Functions
|
||||
These functions are used for working with network nodes.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Demands Nodal Demand Functions
|
||||
These functions are used for managing nodal demands.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Links Network Link Functions
|
||||
These functions are used for working with network links.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Patterns Time Pattern Functions
|
||||
These functions are used for working with time patterns.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Curves Data Curve Functions
|
||||
These functions are used for working with data curves.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Controls Simple Control Functions
|
||||
These functions are used for working with simple conditional controls.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Rules Rule-Based Control Functions
|
||||
These functions are used for working with rule-based controls.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup Enumerations Enumerated Types
|
||||
These are the toolkit's enumerated types whose members are used as function arguments.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Project
|
||||
@{
|
||||
@fn int EN_createproject(EN_Project *ph)
|
||||
@fn int EN_deleteproject(EN_Project ph)
|
||||
@fn int EN_runproject(EN_Project ph, const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *))
|
||||
@fn int EN_init(EN_Project ph, const char *rptFile, const char *outFile, int unitsType, int headLossType)
|
||||
@fn int EN_open(EN_Project ph, const char *inpFile, const char *rptFile, const char *binOutFile)
|
||||
@fn int EN_getcount(EN_Project ph, int code, int *count)
|
||||
@fn int EN_gettitle(EN_Project ph, char *line1, char *line2, char *line3)
|
||||
@fn int EN_settitle(EN_Project ph, char *line1, char *line2, char *line3)
|
||||
@fn int EN_saveinpfile(EN_Project ph, const char *filename)
|
||||
@fn int EN_close(EN_Project ph)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Hydraulics
|
||||
@{
|
||||
@fn int EN_solveH(EN_Project ph)
|
||||
@fn int EN_usehydfile(EN_Project ph, const char *filename)
|
||||
@fn int EN_openH(EN_Project ph)
|
||||
@fn int EN_initH(EN_Project ph, int initFlag)
|
||||
@fn int EN_runH(EN_Project ph, long *currentTime)
|
||||
@fn int EN_nextH(EN_Project ph, long *tStep)
|
||||
@fn int EN_saveH(EN_Project ph)
|
||||
@fn int EN_savehydfile(EN_Project ph, const char *filename)
|
||||
@fn int EN_closeH(EN_Project ph)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Quality
|
||||
@{
|
||||
@fn int EN_solveQ(EN_Project ph)
|
||||
@fn int EN_openQ(EN_Project ph)
|
||||
@fn int EN_initQ(EN_Project ph, int saveFlag)
|
||||
@fn int EN_runQ(EN_Project ph, long *currentTime)
|
||||
@fn int EN_nextQ(EN_Project ph, long *tStep)
|
||||
@fn int EN_stepQ(EN_Project ph, long *timeLeft)
|
||||
@fn int EN_closeQ(EN_Project ph)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Reporting
|
||||
@{
|
||||
@fn int EN_writeline(EN_Project ph, char *line)
|
||||
@fn int EN_report(EN_Project ph)
|
||||
@fn int EN_copyreport(EN_Project ph, char *filename)
|
||||
@fn int EN_clearreport(EN_Project ph)
|
||||
@fn int EN_resetreport(EN_Project ph)
|
||||
@fn int EN_setreport(EN_Project ph, char *reportFormat)
|
||||
@fn int EN_setstatusreport(EN_Project ph, int code)
|
||||
@fn int EN_getversion(int *version)
|
||||
@fn int EN_geterror(int errcode, char *errmsg, int maxLen)
|
||||
@fn int EN_getstatistic(EN_Project ph, int type, double* value)
|
||||
@fn int EN_getresultindex(EN_Project ph, int type, int index, int *value)
|
||||
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Options
|
||||
@{
|
||||
@fn int EN_getoption(EN_Project ph, int option, double *value)
|
||||
@fn int EN_setoption(EN_Project ph, int option, double value)
|
||||
@fn int EN_getflowunits(EN_Project ph, int *units)
|
||||
@fn int EN_setflowunits(EN_Project ph, int units)
|
||||
@fn int EN_gettimeparam(EN_Project ph, int param, long *value)
|
||||
@fn int EN_settimeparam(EN_Project ph, int param, long value)
|
||||
@fn int EN_getqualinfo(EN_Project ph, int *qualType, char *chemName, char *chemUnits, int *traceNode)
|
||||
@fn int EN_getqualtype(EN_Project ph, int *qualType, int *traceNode)
|
||||
@fn int EN_setqualtype(EN_Project ph, int qualType, char *chemName, char *chemUnits, char *traceNode)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Nodes
|
||||
@{
|
||||
@fn int EN_addnode(EN_Project ph, char *id, int nodeType, int *index)
|
||||
@fn int EN_deletenode(EN_Project ph, int index, int actionCode)
|
||||
@fn int EN_getnodeindex(EN_Project ph, char *id, int *index)
|
||||
@fn int EN_getnodeid(EN_Project ph, int index, char *id)
|
||||
@fn int EN_setnodeid(EN_Project ph, int index, char *newid)
|
||||
@fn int EN_getnodetype(EN_Project ph, int index, int *code)
|
||||
@fn int EN_getnodevalue(EN_Project ph, int index, int code, double *value)
|
||||
@fn int EN_setnodevalue(EN_Project ph, int index, int code, double v)
|
||||
@fn int EN_setjuncdata(EN_Project ph, int index, double elev, double dmnd, char *dmndpat)
|
||||
@fn int EN_settankdata(EN_Project ph, int index, double elev, double initlvl,
|
||||
double minlvl, double maxlvl, double diam, double minvol, char *volcurve)
|
||||
@fn int EN_getcoord(EN_Project ph, int index, double *x, double *y)
|
||||
@fn int EN_setcoord(EN_Project ph, int index, double x, double y)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Demands
|
||||
@{
|
||||
@fn int EN_getdemandmodel(EN_Project ph, int *type, double *pmin, double *preq, double *pexp)
|
||||
@fn int EN_setdemandmodel(EN_Project ph, int type, double pmin, double preq, double pexp)
|
||||
@fn int EN_adddemand(EN_Project ph, int nodeIndex, double baseDemand, char *demandPattern, char *demandName)
|
||||
@fn int EN_deletedemand(EN_Project ph, int nodeIndex, int demandIndex)
|
||||
@fn int EN_getdemandindex(EN_Project p, int nodeIndex, char *demandName, int *demandIndex)
|
||||
@fn int EN_getnumdemands(EN_Project ph, int nodeIndex, int *numDemands)
|
||||
@fn int EN_getbasedemand(EN_Project ph, int nodeIndex, int demandIndex, double *baseDemand)
|
||||
@fn int EN_setbasedemand(EN_Project ph, int nodeIndex, int demandIndex, double baseDemand)
|
||||
@fn int EN_getdemandpattern(EN_Project ph, int nodeIndex, int demandIndex, int *pattIndex)
|
||||
@fn int EN_setdemandpattern(EN_Project ph, int nodeIndex, int demandIndex, int patIndex)
|
||||
@fn int EN_getdemandname(EN_Project ph, int nodeIndex, int demandIdx, char *demandName)
|
||||
@fn int EN_setdemandname(EN_Project ph, int nodeIndex, int demandIdx, char *demandName)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Links
|
||||
@{
|
||||
@fn int EN_addlink(EN_Project ph, char *id, int linkType, char *fromNode, char *toNode, int *index)
|
||||
@fn int EN_deletelink(EN_Project ph, int index, int actionCode)
|
||||
@fn int EN_getlinkindex(EN_Project ph, char *id, int *index)
|
||||
@fn int EN_getlinkid(EN_Project ph, int index, char *id)
|
||||
@fn int EN_setlinkid(EN_Project ph, int index, char *newid)
|
||||
@fn int EN_getlinktype(EN_Project ph, int index, int *linkType)
|
||||
@fn int EN_setlinktype(EN_Project ph, int *index, int linkType, int actionCode)
|
||||
@fn int EN_getlinknodes(EN_Project ph, int index, int *node1, int *node2)
|
||||
@fn int EN_setlinknodes(EN_Project ph, int index, int node1, int node2)
|
||||
@fn int EN_getlinkvalue(EN_Project ph, int index, int property, double *value)
|
||||
@fn int EN_setlinkvalue(EN_Project ph, int index, int property, double value)
|
||||
@fn int EN_setpipedata(EN_Project ph, int index, double length, double diam, double rough, double mloss)
|
||||
@fn int EN_getpumptype(EN_Project ph, int linkIndex, int *pumpType)
|
||||
@fn int EN_getheadcurveindex(EN_Project ph, int pumpIndex, int *curveIndex)
|
||||
@fn int EN_setheadcurveindex(EN_Project ph, int pumpIndex, int curveIndex)
|
||||
@fn int EN_getvertexcount(EN_Project ph, int index, int *count)
|
||||
@fn int EN_getvertex(EN_Project ph, int index, int vertex, double *x, double *y)
|
||||
@fn int EN_setvertices(EN_Project ph, int index, double *x, double *y, int count)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Patterns
|
||||
@{
|
||||
@fn int EN_addpattern(EN_Project ph, char *id)
|
||||
@fn int EN_deletepattern(EN_Project ph, int index)
|
||||
@fn int EN_getpatternindex(EN_Project ph, char *id, int *index)
|
||||
@fn int EN_getpatternid(EN_Project ph, int index, char *id)
|
||||
@fn int EN_setpatternid(EN_Project ph, int index, char *id)
|
||||
@fn int EN_getpatternlen(EN_Project ph, int index, int *len)
|
||||
@fn int EN_getpatternvalue(EN_Project ph, int index, int period, double *value)
|
||||
@fn int EN_setpatternvalue(EN_Project ph, int index, int period, double value)
|
||||
@fn int EN_getaveragepatternvalue(EN_Project ph, int index, double *value)
|
||||
@fn int EN_setpattern(EN_Project ph, int index, double *f, int len)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Curves
|
||||
@{
|
||||
@fn int EN_addcurve(EN_Project ph, char *id)
|
||||
@fn int EN_deletecurve(EN_Project ph, int index)
|
||||
@fn int EN_getcurveindex(EN_Project ph, char *id, int *index)
|
||||
@fn int EN_getcurveid(EN_Project ph, int index, char *id)
|
||||
@fn int EN_setcurveid(EN_Project ph, int index, char *id)
|
||||
@fn int EN_getcurvelen(EN_Project ph, int index, int *len)
|
||||
@fn int EN_getcurvetype(EN_Project ph, int index, int *type)
|
||||
@fn int EN_getcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double *x, double *y)
|
||||
@fn int EN_setcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double x, double y)
|
||||
@fn int EN_getcurve(EN_Project ph, int curveIndex, char* id, int *nPoints, double **xValues, double **yValues)
|
||||
@fn int EN_setcurve(EN_Project ph, int index, double *xValues, double *yValues, int nPoints)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Controls
|
||||
@{
|
||||
@fn int EN_addcontrol(EN_Project ph, int type, int linkIndex, double setting, int nodeIndex, double level, int *index)
|
||||
@fn int EN_deletecontrol(EN_Project ph, int index)
|
||||
@fn int EN_getcontrol(EN_Project ph, int index, int *type, int *linkIndex, double *setting, int *nodeIndex, double *level)
|
||||
@fn int EN_setcontrol(EN_Project ph, int index, int type, int linkIndex, double setting, int nodeIndex, double level)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Rules
|
||||
@{
|
||||
@fn int EN_addrule(EN_Project ph, char *rule)
|
||||
@fn int EN_deleterule(EN_Project ph, int index)
|
||||
@fn int EN_getrule(EN_Project ph, int index, int *nPremises, int *nThenActions, int *nElseActions, double *priority)
|
||||
@fn int EN_getruleID(EN_Project ph, int index, char* id);
|
||||
@fn int EN_getpremise(EN_Project ph, int ruleIndex, int premiseIndex, int *logop, int *object, int *objIndex,
|
||||
int *variable, int *relop, int *status, double *value)
|
||||
@fn int EN_setpremise(EN_Project ph, int ruleIndex, int premiseIndex,
|
||||
int logop, int object, int objIndex, int variable, int relop, int status, double value)
|
||||
@fn int EN_setpremiseindex(EN_Project ph, int ruleIndex, int premiseIndex, int objIndex)
|
||||
@fn int EN_setpremisestatus(EN_Project ph, int ruleIndex, int premiseIndex, int status)
|
||||
@fn int EN_setpremisevalue(EN_Project ph, int ruleIndex, int premiseIndex, double value)
|
||||
@fn int EN_getthenaction(EN_Project ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
|
||||
@fn int EN_setthenaction(EN_Project ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
|
||||
@fn int EN_getelseaction(EN_Project ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
|
||||
@fn int EN_setelseaction(EN_Project ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
|
||||
@fn int EN_setrulepriority(EN_Project ph, int index, double priority)
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup Enumerations
|
||||
@{
|
||||
\enum EN_SizeLimits
|
||||
\enum EN_ObjectType
|
||||
\enum EN_CountType
|
||||
\enum EN_NodeType
|
||||
\enum EN_LinkType
|
||||
\enum EN_PumpType
|
||||
\enum EN_PumpStateType
|
||||
\enum EN_CurveType
|
||||
\enum EN_QualityType
|
||||
\enum EN_SourceType
|
||||
\enum EN_ControlType
|
||||
\enum EN_HeadLossType
|
||||
\enum EN_NodeProperty
|
||||
\enum EN_LinkProperty
|
||||
\enum EN_LinkStatusType
|
||||
\enum EN_TimeParameter
|
||||
\enum EN_Option
|
||||
\enum EN_FlowUnits
|
||||
\enum EN_DemandModel
|
||||
\enum EN_MixingModel
|
||||
\enum EN_StatisticType
|
||||
\enum EN_InitHydOption
|
||||
\enum EN_ActionCodeType
|
||||
\enum EN_AnalysisStatistic
|
||||
\enum EN_StatusReport
|
||||
\enum EN_RuleObject
|
||||
\enum EN_RuleVariable
|
||||
\enum EN_RuleOperator
|
||||
\enum EN_RuleStatus
|
||||
\def EN_MISSING
|
||||
@}
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup ErrorCodes Error Codes
|
||||
|
||||
| Code | Meaning |
|
||||
|------|--------- |
|
||||
| 0 | No error |
|
||||
| 101 | Insufficient memory available |
|
||||
| 102 | No network data available |
|
||||
| 103 | Hydraulic solver not opened |
|
||||
| 104 | No hydraulics for water quality analysis |
|
||||
| 105 | Water quality solver not opened |
|
||||
| 106 | No results saved to report on |
|
||||
| 107 | Hydraulics supplied from external file |
|
||||
| 108 | Cannot use external file while hydraulics solver is open |
|
||||
| 110 | Cannot solve network hydraulic equations |
|
||||
| 120 | Cannot solve water quality transport equations |
|
||||
| ||
|
||||
| 200 | One or more errors in an input file |
|
||||
| 201 | Syntax error |
|
||||
| 202 | Function call contains an illegal numeric value |
|
||||
| 203 | Function call refers to an undefined node |
|
||||
| 204 | Function call refers to an undefined link |
|
||||
| 205 | Function call refers to an undefined time pattern |
|
||||
| 206 | Function call refers to an undefined curve |
|
||||
| 207 | Function call attempts to control a check valve pipe or a GPV valve |
|
||||
| 208 | Function call contains illegal PDA pressure limits |
|
||||
| 209 | Function call contains an illegal node property value |
|
||||
| 211 | Function call contains an illegal link property value |
|
||||
| 212 | Function call refers to an undefined Trace Node |
|
||||
| 213 | Function call contains an invalid option value |
|
||||
| 214 | Too many characters in a line of an input file |
|
||||
| 215 | Function call contains a duplicate ID label |
|
||||
| 216 | Function call refers to an undefined pump |
|
||||
| 217 | Invalid pump energy data |
|
||||
| 219 | Illegal valve connection to tank node |
|
||||
| 220 | Illegal valve connection to another valve |
|
||||
| 221 | Mis-placed clause in rule-based control |
|
||||
| 222 | Link assigned same start and end nodes |
|
||||
| 223 | Not enough nodes in network |
|
||||
| 224 | No tanks or reservoirs in network |
|
||||
| 225 | Invalid lower/upper levels for tank |
|
||||
| 226 | No head curve or power rating for pump |
|
||||
| 227 | Invalid head curve for pump |
|
||||
| 230 | Nonincreasing x-values for curve |
|
||||
| 233 | Network has unconnected node |
|
||||
| 240 | Function call refers to nonexistent water quality source |
|
||||
| 241 | Function call refers to nonexistent control |
|
||||
| 250 | Function call contains invalid format (e.g. too long an ID name) |
|
||||
| 251 | Function call contains invalid parameter code |
|
||||
| 253 | Function call refers to nonexistent demand category |
|
||||
| 254 | Function call refers to node with no coordinates |
|
||||
| 257 | Function call refers to nonexistent rule |
|
||||
| 258 | Function call refers to nonexistent rule clause |
|
||||
| 259 | Function call attempts to delete a node that still has links connected to it |
|
||||
| 260 | Function call attempts to delete node assigned as a Trace Node |
|
||||
| 261 | Function call attempts to delete a node or link contained in a control |
|
||||
| 262 | Function call attempts to modify network structure while a solver is open |
|
||||
| ||
|
||||
| 301 | Identical file names used for different types of files |
|
||||
| 302 | Cannot open input file |
|
||||
| 303 | Cannot open report file |
|
||||
| 304 | Cannot open output file |
|
||||
| 305 | Cannot open hydraulics file |
|
||||
| 306 | Hydraulics file does not match network data |
|
||||
| 307 | Cannot read hydraulics file |
|
||||
| 308 | Cannot save results to binary file |
|
||||
| 309 | Cannot save results to report file |
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup WarningCodes Warning Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|--------- |
|
||||
|1 | System hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials |
|
||||
|2 | System may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed |
|
||||
|3 | System disconnected - one or more nodes with positive demands were disconnected from all supply sources |
|
||||
|4 | Pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow |
|
||||
|5 | Valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open |
|
||||
|6 | System has negative pressures - negative pressures occurred at one or more junctions with positive demand |
|
||||
|
||||
*/
|
||||
@@ -1,12 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup Controls Managing Controls
|
||||
|
||||
|
||||
@addtogroup Controls
|
||||
@{
|
||||
@enum EN_ControlType
|
||||
@fn int ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level)
|
||||
@fn int ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level)
|
||||
@}
|
||||
*/
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup Curves
|
||||
|
||||
|
||||
@addtogroup Curves
|
||||
@{
|
||||
@fn int ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
|
||||
@fn int ENgetheadcurveindex(int index, int *curveindex)
|
||||
@fn int ENgetpumptype(int index, int *type)
|
||||
@fn int ENgetheadcurve(int linkIndex, char *curveId)
|
||||
@fn int ENgetcurveindex(char *id, int *index)
|
||||
@fn int ENgetcurveid(int index, char *id)
|
||||
@fn int ENgetcurvelen(int index, int *len)
|
||||
@fn int ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
|
||||
@fn int ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
|
||||
@fn int ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len)
|
||||
@fn int ENaddcurve(char *id)
|
||||
@}
|
||||
*/
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup FileManagement File Management
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@addtogroup FileManagement
|
||||
@{
|
||||
@fn int ENwriteline (char *line)
|
||||
@fn int ENreport ()
|
||||
@fn int ENresetreport ()
|
||||
@fn int ENsetreport (char *reportFormat)
|
||||
@fn int ENopen (char *inpFile, char *rptFile, char *binOutFile)
|
||||
@fn int ENsaveinpfile (char *filename)
|
||||
@fn int ENclose()
|
||||
@}
|
||||
*/
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup HydraulicFunctions Hydraulic Analysis
|
||||
|
||||
~~~~~~~~~~~~~~~{.c}
|
||||
int errcode;
|
||||
long t, tstep;
|
||||
|
||||
errcode = ENopenH();
|
||||
if (!errcode) {
|
||||
errcode = ENinitH(EN_SAVE);
|
||||
if (!errcode) {
|
||||
do {
|
||||
tstep = 0;
|
||||
ERRCODE(ENrunH(&t));
|
||||
ERRCODE(ENnextH(&tstep));
|
||||
} while (tstep > 0);
|
||||
}
|
||||
}
|
||||
|
||||
ENcloseH();
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
@addtogroup HydraulicFunctions
|
||||
@{
|
||||
|
||||
@fn int ENsolveH()
|
||||
@fn int ENsaveH()
|
||||
@fn int ENopenH()
|
||||
@fn int ENinitH(int initFlag)
|
||||
@fn int ENrunH(long *currentTime)
|
||||
@fn int ENnextH(long *tStep)
|
||||
@fn int ENcloseH()
|
||||
@fn int ENsavehydfile(char *filename)
|
||||
@fn int ENusehydfile(char *filename)
|
||||
@fn int ENgetstatistic(int code, EN_API_FLOAT_TYPE* value)
|
||||
|
||||
@}
|
||||
*/
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup NetworkInfo Network Info
|
||||
|
||||
|
||||
@addtogroup NetworkInfo
|
||||
@{
|
||||
@fn int ENgetcount (int code, int *count)
|
||||
@fn int ENgetnodeindex (char *id, int *index)
|
||||
@fn int ENgetnodeid (int index, char *id)
|
||||
@fn int ENgetnodetype (int index, int *code)
|
||||
@fn int ENgetnodevalue (int index, int code, EN_API_FLOAT_TYPE *value)
|
||||
@fn int ENgetcoord (int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
|
||||
@fn int ENsetcoord (int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
|
||||
@}
|
||||
*/
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup Patterns
|
||||
|
||||
|
||||
@addtogroup Patterns
|
||||
@{
|
||||
@fn int ENgetpatternindex (char *id, int *index)
|
||||
@fn int ENgetpatternid (int index, char *id)
|
||||
@fn int ENgetpatternlen (int index, int *len)
|
||||
@fn int ENgetpatternvalue (int index, int period, EN_API_FLOAT_TYPE *value)
|
||||
@fn int ENgetaveragepatternvalue (int index, EN_API_FLOAT_TYPE *value)
|
||||
@}
|
||||
*/
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup QualityFunctions Water Quality Functions
|
||||
|
||||
|
||||
|
||||
@addtogroup QualityFunctions
|
||||
@{
|
||||
@fn int ENsolveQ ()
|
||||
@fn int ENopenQ ()
|
||||
@fn int ENinitQ (int saveFlag)
|
||||
@fn int ENrunQ (long *currentTime)
|
||||
@fn int ENnextQ (long *tStep)
|
||||
@fn int ENstepQ (long *timeLeft)
|
||||
@fn int ENcloseQ ()
|
||||
@}
|
||||
*/
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
|
||||
@defgroup ToolkitOptions Toolkit Options
|
||||
|
||||
|
||||
@addtogroup ToolkitOptions
|
||||
@{
|
||||
@fn int ENgetoption (int code, EN_API_FLOAT_TYPE *value)
|
||||
@fn int ENgettimeparam (int code, long *value)
|
||||
@fn int ENgetflowunits (int *code)
|
||||
@fn int ENgetqualtype (int *qualcode, int *tracenode)
|
||||
@fn int ENgeterror (int errcode, char *errmsg, int maxLen)
|
||||
@}
|
||||
*/
|
||||
15
doc/newfooter.html
Normal file
15
doc/newfooter.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- HTML footer for doxygen 1.8.10-->
|
||||
<!-- start footer part -->
|
||||
<!--BEGIN GENERATE_TREEVIEW-->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
$navpath
|
||||
<!-- <li class="footer">OWA-EPANET Toolkit 2.2 © 2019</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
<!--END GENERATE_TREEVIEW-->
|
||||
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||
<!-- <li class="footer">OWA-EPANET Toolkit 2.2 © 2019</li> -->
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
</body>
|
||||
</html>
|
||||
30
doc/readme.md
Normal file
30
doc/readme.md
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
## Generating Documentation for OWA-EPANET 2.2
|
||||
|
||||
You must have [Doxygen](http://www.doxygen.nl) installed on your machine to generate documentation for the OWA-EPANET Toolkit. Assuming this is the case, open a terminal window, navigate to the project's `doc` directory and issue the command `doxygen`. This will generate HTML documentation placed in a sub-directory named `html`. From that directory you can launch the `index.html` file to view the full documentation in a web browser.
|
||||
|
||||
To generate a Windows compiled HTML Help file you must have [Microsoft's HTML Help Workshop](https://www.microsoft.com/en-us/download/details.aspx?id=21138) installed. You then need to edit the Doxygen configuration file `doxyfile` as follows:
|
||||
|
||||
1. Change the `GENERATE_HTMLHELP` setting to `YES`.
|
||||
|
||||
2. Enter the location where the Help Workshop system was installed next to the
|
||||
`HHC_LOCATION` setting.
|
||||
|
||||
After running Doxygen again the resulting Help file named `owa-epanet.chm` will appear in the `html` sub-directory.
|
||||
|
||||
Doxygen uses the special comments placed in the project's `epanet2_2.h` and `epanet2_enums.h` header files to document EPANET's API. It also uses supplementary material contained in the following files of the project's `doc` directory to generate additional pages of documentation:
|
||||
|
||||
- `main.dox`: generates the *Overview* section.
|
||||
- `usage.dox`: generates the *Usage* section.
|
||||
- `toolkit-examples.dox` : generates the *Examples* section.
|
||||
- `toolkit-files.dox`: generates the *Toolkit Files* section.
|
||||
- `input-file.dox`: generates the *Input File* sub-section.
|
||||
- `toolkit-units.dox`: generates the *Measurement Units* section.
|
||||
- `modules.dox`: defines the contents of the *API Reference* section.
|
||||
|
||||
Finally, a group of special Doxygen files are used to customize the format of the generated documentation. These include the following:
|
||||
- `doxyfile`: the main Doxygen configuration file
|
||||
- `DoxygenLayout.xml`: sets the title of the automatically generated *Modules* section to *API Reference* and hides the *Files* section in the tree view pane of the document.
|
||||
- `extrastylesheet.css`: reduces the size of the the h1 heading style.
|
||||
- `newfooter.html`: replaces the default Doxygen footer in HTML output with a custom one.
|
||||
229
doc/toolkit-examples.dox
Normal file
229
doc/toolkit-examples.dox
Normal file
@@ -0,0 +1,229 @@
|
||||
/** @page ToolkitExamples Examples
|
||||
Here are several examples of how the Toolkit can be used for different types of network analyses.
|
||||
|
||||
- @subpage Example1 "Embedded Engine Example"
|
||||
- @subpage Example2 "Network Building Example"
|
||||
- @subpage Example3 "Hydrant Rating Curve Example"
|
||||
- @subpage Example4 "Chlorine Dosage Example"
|
||||
|
||||
*/
|
||||
|
||||
/** @page Example1 Embedded Engine Example
|
||||
This example shows how simple it is for the Toolkit to provide a network analysis engine for other applications. There are three steps that the application would need to take:
|
||||
-# Have the application write network data to an EPANET-formatted input file.
|
||||
|
||||
-# Create a project and call @ref EN_runproject, supplying the name of the EPANET input file, the name of a Report file where status and error messages are written, and the name of a binary Output file which will contain analysis results.
|
||||
|
||||
-# Have the application access the output file to display desired analysis results (see @ref OutFile).
|
||||
|
||||
Here is an example where a callback function `writeConsole` is provided to write EPANET's progress messages to the console:
|
||||
|
||||
\code {.c}
|
||||
#include "epanet2_2.h"
|
||||
|
||||
void writeConsole(char *s)
|
||||
{
|
||||
fprintf(stdout, "\n%s", s);
|
||||
}
|
||||
|
||||
int runEpanet(char* inpFile, char* rptFile, char* outFile)
|
||||
{
|
||||
int errcode;
|
||||
EN_project ph;
|
||||
EN_createproject(&pH);
|
||||
errcode = EN_runproject(ph, inpFile, rptFile, outFile, &writeConsole);
|
||||
EN_deleteproject(ph);
|
||||
return errcode;
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/** @page Example2 Network Building Example
|
||||
This example shows how a network can be built just through toolkit function calls, eliminating the
|
||||
need to always use an EPANET formatted input file. This creates opportunities to use other sources
|
||||
of network data in one's code, such as relational database files or GIS/CAD files.
|
||||
|
||||
Below is a schematic of the network to be built.
|
||||
<table style = "border: 0px solid black">
|
||||
<tr><td>
|
||||
@image html Example2.png
|
||||
@image latex Example2.eps
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
\code {.c}
|
||||
#include "epanet2_2.h"
|
||||
|
||||
void netbuilder()
|
||||
{
|
||||
// Create a project that uses gpm for flow units and
|
||||
// the Hazen-Williams formula for head loss
|
||||
int index;
|
||||
EN_Project ph;
|
||||
EN_createproject(&ph);
|
||||
EN_init(ph, "", "", EN_GPM, EN_HW);
|
||||
|
||||
// Add the first junction node to the project with
|
||||
// an elevation of 700 ft and a demand of 0
|
||||
EN_addnode(ph, "J1", EN_JUNCTION, &index);
|
||||
EN_setjuncdata(ph, index, 700, 0, "");
|
||||
|
||||
// Add the remaining two junctions with elevations of
|
||||
// 710 ft and demands of 250 and 500 gpm, respectively
|
||||
EN_addnode(ph, "J2", EN_JUNCTION, &index);
|
||||
EN_setjuncdata(ph, index, 710, 250, "");
|
||||
EN_addnode(ph, "J3", EN_JUNCTION, &index);
|
||||
EN_setjuncdata(ph, index, 710, 500, "");
|
||||
|
||||
// Add the reservoir at an elevation of 650 ft
|
||||
EN_addnode(ph, "R1", EN_RESERVOIR, &index);
|
||||
EN_setnodevalue(ph, index, EN_ELEVATION, 650);
|
||||
|
||||
// Add the tank node at elevation of 850 ft, initial water level
|
||||
// at 120 ft, minimum level at 100 ft, maximum level at 150 ft
|
||||
// and a diameter of 50.5 ft
|
||||
EN_addnode(ph, "T1", EN_TANK, &index);
|
||||
EN_settankdata(ph, index, 850, 120, 100, 150, 50.5, 0, "");
|
||||
|
||||
// Add the pipes to the project, setting their length,
|
||||
// diameter, and roughness values
|
||||
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2", &index);
|
||||
EN_setpipedata(ph, index, 10560, 12, 100, 0);
|
||||
EN_addlink(ph, "P2", EN_PIPE, "J1", "T1", &index);
|
||||
EN_setpipedata(ph, index, 5280, 14, 100, 0);
|
||||
EN_addlink(ph, "P3", EN_PIPE, "J1", "J3", &index);
|
||||
EN_setpipedata(ph, index, 5280, 14, 100, 0);
|
||||
EN_addlink(ph, "P4", EN_PIPE, "J2", "J3", &index);
|
||||
EN_setpipedata(ph, index, 5280, 14, 100, 0);
|
||||
|
||||
// Add a pump to the project
|
||||
EN_addlink(ph, "PUMP", EN_PUMP, "R1", "J1", &index);
|
||||
|
||||
// Create a single point head curve (index = 1) and
|
||||
// assign it to the pump
|
||||
EN_addcurve(ph, "C1");
|
||||
EN_setcurvevalue(ph, 1, 1, 1500, 250);
|
||||
EN_setlinkvalue(ph, index, EN_PUMP_HCURVE, 1);
|
||||
|
||||
// Save the project for future use
|
||||
EN_saveinpfile(ph, "example2.inp");
|
||||
|
||||
// Delete the project
|
||||
EN_deleteproject(ph);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/** @page Example3 Hydrant Rating Curve Example
|
||||
|
||||
This example illustrates how the Toolkit could be used to develop a hydrant rating curve used in fire flow studies. This curve shows the amount of flow available at a node in the system as a function of pressure. The curve is generated by running a number of steady state hydraulic analyses with the node of interest subjected to a different demand in each analysis. For this example we assume that the ID label of the node of interest is `MyNode` and that `N` different demand levels stored in the array `D` need to be examined. The corresponding pressures will be stored in `P`. To keep the code more readable, no error checking is made on the results returned from the Toolkit function calls.
|
||||
|
||||
\code {.c}
|
||||
#include "epanet2_2.h"
|
||||
|
||||
void HydrantRating(char *MyNode, int N, double D[], double P[])
|
||||
{
|
||||
EN_Project ph;
|
||||
int i, nodeindex;
|
||||
long t;
|
||||
double pressure;
|
||||
|
||||
// Create a project
|
||||
EN_createproject(&ph);
|
||||
|
||||
// Retrieve network data from an input file
|
||||
EN_open(ph, "example2.inp", "example2.rpt", "");
|
||||
|
||||
// Open the hydraulic solver
|
||||
EN_openH(ph);
|
||||
|
||||
// Get the index of the node of interest
|
||||
EN_getnodeindex(ph, MyNode, &nodeindex);
|
||||
|
||||
// Iterate over all demands
|
||||
for (i=1; i<N; i++)
|
||||
{
|
||||
// Set nodal demand, initialize hydraulics, make a
|
||||
// single period run, and retrieve pressure
|
||||
EN_setnodevalue(ph, nodeindex, EN_BASEDEMAND, D[i]);
|
||||
EN_initH(ph, 0);
|
||||
EN_runH(ph, &t);
|
||||
EN_getnodevalue(ph, nodeindex, EN_PRESSURE, &pressure);
|
||||
P[i] = pressure;
|
||||
}
|
||||
|
||||
// Close hydraulics solver & delete the project
|
||||
EN_closeH(ph);
|
||||
EN_deleteproject(ph);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/** @page Example4 Chlorine Dosage Example
|
||||
|
||||
This example illustrates how the Toolkit could be used to determine the lowest dose of chlorine applied at the entrance to a distribution system needed to ensure that a minimum residual is met throughout the system. We assume that the EPANET input file contains the proper set of kinetic coefficients that describe the rate at which chlorine will decay in the system being studied. In the example code, the ID label of the source node is contained in `SourceID`, the minimum residual target is given by `Ctarget`, and the target is only checked after a start-up duration of 5 days (432,000 seconds). To keep the code more readable, no error checking is made on the results returned from the Toolkit function calls.
|
||||
|
||||
\code {.c}
|
||||
#include "epanet2_2.h"
|
||||
|
||||
double cl2dose(char *SourceID, double Ctarget)
|
||||
{
|
||||
int i, nnodes, sourceindex, violation;
|
||||
double c, csource;
|
||||
long t, tstep;
|
||||
EN_Project ph;
|
||||
|
||||
// Open the toolkit & obtain a hydraulic solution
|
||||
EN_createproject(&ph);
|
||||
EN_open(ph, "example3.inp", "example3.rpt", "");
|
||||
EN_solveH(ph);
|
||||
|
||||
// Get the number of nodes and the source node's index
|
||||
EN_getcount(ph, EN_NODECOUNT, &nnodes);
|
||||
EN_getnodeindex(ph, SourceID, &sourceindex);
|
||||
|
||||
// Setup the system to analyze for chlorine
|
||||
// (in case it was not done in the input file)
|
||||
EN_setqualtype(ph, EN_CHEM, "Chlorine", "mg/L", "");
|
||||
|
||||
// Open the water quality solver
|
||||
EN_openQ(ph);
|
||||
|
||||
// Begin the search for the source concentration
|
||||
csource = 0.0;
|
||||
do {
|
||||
|
||||
// Update source concentration to next level
|
||||
csource = csource + 0.1;
|
||||
EN_setnodevalue(ph, sourceindex, EN_SOURCEQUAL, csource);
|
||||
|
||||
// Run WQ simulation checking for target violations
|
||||
violation = 0;
|
||||
EN_initQ(ph, 0);
|
||||
do {
|
||||
EN_runQ(ph, &t);
|
||||
if (t > 432000) {
|
||||
for (i=1; i<=nnodes; i++) {
|
||||
EN_getnodevalue(ph, i, EN_QUALITY, &c);
|
||||
if (c < Ctarget) {
|
||||
violation = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EN_nextQ(ph, &tstep);
|
||||
|
||||
// End WQ run if violation found
|
||||
} while (!violation && tstep > 0);
|
||||
|
||||
// Continue search if violation found
|
||||
} while (violation && csource <= 4.0);
|
||||
|
||||
// Close up the WQ solver and delete the project
|
||||
EN_closeQ(ph);
|
||||
EN_deleteproject(ph);
|
||||
return csource;
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
163
doc/toolkit-files.dox
Normal file
163
doc/toolkit-files.dox
Normal file
@@ -0,0 +1,163 @@
|
||||
/** @page Files Toolkit Files
|
||||
The Toolkit can make use of several different types of files when analyzing a pipe network. These include:
|
||||
- @subpage InpFile "Input File"
|
||||
- @subpage RptFile "Report File"
|
||||
- @subpage OutFile "Output File"
|
||||
- @subpage HydFile "Hydraulics File"
|
||||
- @subpage HeaderFiles "Header Files"
|
||||
*/
|
||||
|
||||
/**
|
||||
@page RptFile Report File
|
||||
The Report file is the second file name supplied to the @ref EN_open function (or the first file name to @ref EN_init). It is used to log any error messages that occur when an Input file is being processed and to record all status messages that are generated during a hydraulic simulation. In addition, if the @ref EN_report function is called the resulting report can also be written to this file as can user-generated lines of text using the @ref EN_writeline function. The format of the report is controlled by statements placed in the @ref ReportPage section of the Input file and by similar statements included in calls to the @ref EN_setreport function. Only results at a specified uniform reporting time interval are written to this file.
|
||||
|
||||
To suppress the writing of all error and warning messages to the Report file either include the command <b>`MESSAGES NO`</b> in the @ref ReportPage section of the Input file or call the Toolkit function <b>`EN_setreport("MESSAGES NO")`</b>.
|
||||
|
||||
To route a formatted report to a different file than the Report file either include the command <b>`FILE filename`</b> in the @ref ReportPage section of the Input file or call the Toolkit function <b>`EN_setreport("FILE filename")`</b>, where `filename` is the name of the file to use.
|
||||
|
||||
Toolkit clients will not be able to access the contents of a Report file until a project is closed. If access is needed before then, the @ref EN_copyreport function can be used to copy its current contents to another file. A @ref EN_clearreport function is also available to clear the current contents of the Report file.
|
||||
*/
|
||||
|
||||
/**
|
||||
@page OutFile Output File
|
||||
|
||||
The Output file is an unformatted binary file used to store both hydraulic and water quality results at uniform reporting intervals. It is the third file name supplied to the @ref EN_open function (or second name to @ref EN_init). If an empty string ("") is used as its name then a scratch temporary file will be used. Otherwise the Output file will be saved after the @ref EN_close function is called. Saving this file is useful if further post-processing of the output results are needed.
|
||||
|
||||
The function @ref EN_saveH will transfer hydraulic results to the Output file if no water quality analysis will be made. Using @ref EN_solveQ to run a water quality analysis automatically saves both hydraulic and water quality results to this file. If the @ref EN_initQ - @ref EN_runQ - @ref EN_nextQ set of functions is used to perform a water quality analysis, then results will be saved only if the \b saveflag argument of @ref EN_initQ is set to <B>`EN_SAVE`</B>. Again, the need to save results to the Output file is application-dependent. If a formatted output report is to be generated using @ref EN_report, then results must first be saved to the Output file.
|
||||
|
||||
The data written to the file is either 4-byte integers, 4-byte floats, or fixed-size strings whose size is a multiple of 4 bytes. This allows the file to be divided conveniently into 4-byte records. The file consists of four sections of the following sizes in bytes:
|
||||
|
||||
| Section | Size in Bytes |
|
||||
|----------------|----------------------------------------|
|
||||
|Prolog | 884 + 36*Nnodes + 52*Nlinks + 8*Ntanks |
|
||||
|Energy Usage | 28*Npumps + 4 |
|
||||
|Dynamic Results | (16*Nnodes + 32*Nlinks)*Nperiods |
|
||||
|Epilog | 28 |
|
||||
|
||||
where:
|
||||
- Nnodes = number of nodes (junctions + reservoirs + tanks),
|
||||
- Nlinks = number of links (pipes + pumps + valves),
|
||||
- Ntanks = number of tanks and reservoirs,
|
||||
- Npumps = number of pumps,
|
||||
- Nperiods = number of reporting periods.
|
||||
|
||||
All of these counts are themselves written to the file's Prolog or Epilog sections.
|
||||
|
||||
@section Output_Prolog Prolog Section
|
||||
|
||||
The Prolog section of an EPANET binary output file contains the following data:
|
||||
|
||||
|Item | Type | # Bytes |
|
||||
|----------------|-----------|-----------|
|
||||
| Magic Number = 516114521 | Integer | 4 |
|
||||
| Version (= 200) | Integer | 4 |
|
||||
| Number of Nodes | Integer | 4 |
|
||||
| Number of Reservoirs & Tanks | Integer | 4|
|
||||
| Number of Links | Integer | 4 |
|
||||
| Number of Pumps | Integer | 4 |
|
||||
| Number of Valves | Integer | 4 |
|
||||
| Water Quality Option - see @ref EN_QualityType | Integer | 4 |
|
||||
| Traced Node Index | Integer | 4 |
|
||||
| Flow Units Option | Integer | 4 |
|
||||
| Pressure Units Option:<br>0 = psi<br>1 = meters<br>2 = kPa | Integer | 4 |
|
||||
| Report Statistic Type - see @ref EN_StatisticType | Integer | 4 |
|
||||
| Reporting Start Time (sec) | Integer | 4 |
|
||||
| Reporting Time Step (sec) | Integer | 4 |
|
||||
| Simulation Duration (sec) | Integer | 4 |
|
||||
| Project Title (1st line) | Char | 80 |
|
||||
| Project Title (2nd line) | Char | 80 |
|
||||
| Project Title (3rd line) | Char | 80 |
|
||||
| Name of Input File | Char | 260 |
|
||||
| Name of Report File | Char | 260 |
|
||||
| Name of Quality Chemical | Char | 32 |
|
||||
| Chemical Concentration Units | Char | 32 |
|
||||
| ID String of Each Node | Char | 32*Nnodes |
|
||||
| ID String of Each Link | Char | 32*Nlinks |
|
||||
| Index of Head Node of Each Link | Integer | 4*Nlinks |
|
||||
| Index of Tail Node of Each Link | Integer | 4*Nlinks |
|
||||
| Type Code of Each Link (see @ref EN_LinkType) | Integer | 4*Nlinks |
|
||||
| Node Index of Each Tank | Integer | 4*Ntanks |
|
||||
| Surface Area of Each Tank | Float | 4*Ntanks |
|
||||
| Elevation of Each Node | Float | 4*Nnodes |
|
||||
| Length of Each Link | Float | 4*Nlinks |
|
||||
| Diameter of Each Link | Float | 4*Nlinks |
|
||||
|
||||
@section Output_Energy Energy Usage Section
|
||||
|
||||
The Energy Usage section of an EPANET binary output file contains the following data:
|
||||
|
||||
|Item (Repeated for Each Pump) | Type | # Bytes |
|
||||
|------------------------------|---------|---------|
|
||||
| Pump Index in list of links | Integer | 4 |
|
||||
| Pump Utilization (%) | Float | 4 |
|
||||
| Average Efficiency (%) | Float | 4 |
|
||||
| Average kW/MGal (or kW/m^3) | Float | 4 |
|
||||
| Average kW | Float | 4 |
|
||||
| Peak kW | Float | 4 |
|
||||
| Average Cost per Day | Float | 4 |
|
||||
|
||||
These data are followed by a single 4-byte Float containing the overall Demand Charge for peak energy usage.
|
||||
|
||||
@section Output_Results Dynamic Results Section
|
||||
|
||||
The Dynamic Results section of an EPANET binary output file contains the following set of data for each reporting period (the reporting time step is written to the Output File's @ref Output_Prolog and the number of such steps is written to the @ref Output_Epilog):
|
||||
|
||||
| Item | Type | # Bytes |
|
||||
|------|------|---------|
|
||||
|Demand at Each Node | Float | 4*Nnodes |
|
||||
|Head (Grade) at Each Node | Float | 4*Nnodes |
|
||||
|Pressure at Each Node | Float | 4*Nnodes |
|
||||
|Water Quality at Each Node | Float | 4*Nnodes |
|
||||
|Flow in Each Link<br> (negative for reverse flow)| Float | 4*Nlinks |
|
||||
|Velocity in Each Link | Float | 4*Nlinks |
|
||||
|Head Loss per 1000 Units of Length for Each Link<br> (total head for pumps and head loss for valves) | Float | 4*Nlinks |
|
||||
|Average Water Quality in Each Link | Float | 4*Nlinks |
|
||||
| Status Code for Each Link:<br>0 = closed (pump shutoff head exceeded)<br>1 = temporarily closed<br>2 = closed<br>3 = open<br>4 = active (partially open)<br>5 = open (pump max. flow exceeded)<br>6 = open (FCV can't supply flow)<br>7 = open (PRV/PSV can't supply pressure) | Float | 4*Nlinks |
|
||||
| Setting for Each Link | Float | 4*Nlinks |
|
||||
|Reaction Rate for Each Link (mass/L/day) | Float | 4*Nlinks |
|
||||
|Friction Factor for Each Link | Float | 4*Nlinks |
|
||||
|
||||
@section Output_Epilog Epilog Section
|
||||
|
||||
The Epilog section of an EPANET binary output file contains the following data:
|
||||
|
||||
|Item | Type | # Bytes |
|
||||
|-----|------|---------|
|
||||
|Average bulk reaction rate (mass/hr) | Float | 4 |
|
||||
|Average wall reaction rate (mass/hr) | Float | 4 |
|
||||
|Average tank reaction rate (mass/hr) | Float | 4 |
|
||||
|Average source inflow rate (mass/hr) | Float | 4 |
|
||||
|Number of Reporting Periods | Integer | 4 |
|
||||
|Warning Flag:<br>0 = no warnings<br>1 = warnings were generated | Integer | 4 |
|
||||
|Magic Number = 516114521 | Integer | 4 |
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page HydFile Hydraulics File
|
||||
The Hydraulics file is an unformatted binary file used to store the results of a hydraulic analysis. Results for all time periods are stored, including those at intermediate times when special hydraulic events occur (e.g., pumps and tanks opening or closing because control conditions have been satisfied).
|
||||
|
||||
Normally it is a temporary file that is deleted after the @ref EN_deleteproject function is called. However, it will be saved if the @ref EN_savehydfile function is called before that.
|
||||
|
||||
Likewise, a previously saved Hydraulics file can be used if the command <b>`HYDRAULICS USE`</b> filename appears in the @ref OptionsPage section of the input file, or if the @ref EN_usehydfile function is called.
|
||||
|
||||
When the Toolkit function @ref EN_solveH is used to make a hydraulic analysis, results are automatically saved to the Hydraulics file. When the @ref EN_initH - @ref EN_runH - @ref EN_nextH set of functions is used, the \b initFlag argument to @ref EN_initH determines whether results are saved or not. The need to save hydraulic results is application-dependent. They must always be saved to the Hydraulics file if a water quality analysis will follow.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page HeaderFiles Header Files
|
||||
The Toolkit provides several header files that are needed to develop C/C++ applications:
|
||||
- <b>`epanet2.h`</b> contains declarations of the single-threaded version of the Toolkit (the ENxxx named functions).
|
||||
- <b>`epanet2_2.h`</b> contains declarations of the multi-threaded version of the Toolkit (the EN_xxx named functions).
|
||||
- <b>`epanet2_enums.h`</b> contains definitions of the symbolic constants used by the Toolkit.
|
||||
- <b>`epanet2.lib`</b> must be linked in to any Toolkit application compiled for Windows using MS Visual C++.
|
||||
Developers need to issue an include directive for either `epanet2.h` or `epanet2_2.h` in their C/C++ code depending on whether they are building a single-threaded or multi-threaded application. There is no need to explicitly include `epanet2_enums.h` as it is automatically included by both of the other header files.
|
||||
|
||||
Several additional function declaration files that provide bindings for other programming languages are included with the Toolkit package:
|
||||
- <b>`epanet2.bas`</b> for Visual Basic for Applications and Visual Basic 6
|
||||
- <b>`epanet2.vb`</b> for Visual Basic .NET
|
||||
- <b>`epanet2.pas`</b> for Delphi Pascal, Free Pascal or Lazarus.
|
||||
|
||||
These bindings only support the single-threaded version of the Toolkit.
|
||||
*/
|
||||
37
doc/toolkit-units.dox
Normal file
37
doc/toolkit-units.dox
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
/**
|
||||
@page Units Measurement Units
|
||||
|
||||
The toolkit can use data expressed in either US Customary of SI Metric units. A project's unit system depends on the unit system used for its choice of flow units. If the @ref EN_open function is used to supply data to a project from an Input File then its flow units are set in the @ref OptionsPage section of the file. If the @ref EN_init function is used to initialize a project then the choice of flow units is the fourth argument to the function. The following table lists the units used to express the various parameters in an EPANET model.
|
||||
|
||||
| Parameter | US Customary | SI Metric |
|
||||
|----------------|-------------------------|---------------------------|
|
||||
|Concentration | mg/L or ug/L | mg/L or ug/L |
|
||||
|Demand | (see Flow units) | (see Flow units) |
|
||||
|Diameter (Pipes)| inches | millimeters |
|
||||
|Diameter (Tanks)| feet | meters |
|
||||
|Efficiency | percent | percent |
|
||||
|Elevation | feet | meters |
|
||||
|Emitter Coeff. | flow units @ 1 psi drop | flow units @ 1 meter drop |
|
||||
|Energy | kwatt - hours | kwatt - hours |
|
||||
|Flow | CFS (cubic feet / sec) | LPS (liters / sec) |
|
||||
| | GPM (gallons / min) | LPM (liters / min) |
|
||||
| | MGD (million gal / day) | MLD (megaliters / day) |
|
||||
| | IMGD (Imperial MGD) | CMH (cubic meters / hr) |
|
||||
| | AFD (acre-feet / day) | CMD (cubic meters / day) |
|
||||
|Friction Factor | unitless | unitless |
|
||||
|Head | feet | meters |
|
||||
|Length | feet | meters |
|
||||
|Minor Loss Coeff. | unitless | unitless |
|
||||
|Power | horsepower | kwatts |
|
||||
|Pressure | psi | meters |
|
||||
|Reaction Coeff. (Bulk) | 1/day (1st-order)| 1/day (1st-order) |
|
||||
|Reaction Coeff. (Wall) | mass/sq-ft/day (0-order) | mass/sq-m/day (0-order) |
|
||||
| | ft/day (1st-order) | meters/day (1st-order) |
|
||||
|Roughness Coeff. | millifeet (Darcy-Weisbach) unitless otherwise| mm (Darcy-Weisbach) unitless otherwise |
|
||||
|Source Mass Injection | mass/minute | mass/minute |
|
||||
|Velocity | ft/sec | meters/sec |
|
||||
|Volume | cubic feet | cubic meters |
|
||||
|Water Age | hours | hours |
|
||||
|
||||
*/
|
||||
243
doc/toolkit-usage.dox
Normal file
243
doc/toolkit-usage.dox
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
@page toolkit-usage Usage
|
||||
|
||||
The following topics briefly describe how to accomplish some basic tasks using the OWA-EPANET Toolkit in C/C++ code. See the @ref ToolkitExamples topic for code listings of complete applications of the Toolkit.
|
||||
|
||||
@section CreateProject Creating a Project
|
||||
|
||||
Before any use is made of the Toolkit, a project and its handle must be created. After all processing is completed the project should be deleted. See the code snippet below:
|
||||
|
||||
\code {.c}
|
||||
EN_Project ph; // a project handle
|
||||
EN_createproject(&ph);
|
||||
|
||||
// Call functions that perform desired analysis
|
||||
|
||||
EN_deleteproject(ph);
|
||||
\endcode
|
||||
|
||||
@section DetectingErrors Detecting Error Conditions
|
||||
|
||||
All of the Toolkit functions return an error/warning code. A 0 indicates that the function ran successfully. A number greater than 0 but less than 100 indicates that a warning condition was generated while a number higher than 100 indicates that the function failed.
|
||||
|
||||
The meaning of specific error and warning codes are listed in the @ref ErrorCodes and @ref WarningCodes sections of this guide. The Toolkit function @ref EN_geterror can be used to obtain the text of a specific error/warning code. The following example uses a macro named `ERRCODE` along with a variable named `errcode` to execute Toolkit commands only if no fatal errors have already been detected:
|
||||
|
||||
\code {.c}
|
||||
#define ERRCODE(x) (errcode = ((errcode > 100) ? (errcode) : (x)))
|
||||
|
||||
void runHydraulics(EN_Project ph, char *inputFile, char *reportFile)
|
||||
{
|
||||
int errcode = 0;
|
||||
char errmsg[EN_MAXMSG + 1];
|
||||
|
||||
ERRCODE(EN_open(ph, inputFile, reportFile, ""));
|
||||
ERRCODE(EN_solveH(ph));
|
||||
ERRCODE(EN_saveH(ph));
|
||||
ERRCODE(EN_report(ph));
|
||||
EN_geterror(ph, errcode, errmsg);
|
||||
if (errcode) printf("\n%s\n", errmsg);
|
||||
}
|
||||
\endcode
|
||||
|
||||
@section NetworkData Providing Network Data
|
||||
|
||||
Once a project is created there are two ways in which it can be populated with data. The first is to use the @ref EN_open function to load an EPANET-formatted @ref InpFile that provides a description of the network to be analyzed. This function should be called immediately after a project is created. It takes as arguments the name of the input file to open and the names of a report file and a binary output file, both of which are optional. Here is a code sample showing this approach:
|
||||
|
||||
\code {.c}
|
||||
EN_Project ph;
|
||||
int errcode;
|
||||
EN_createproject(&ph);
|
||||
errcode = EN_open(ph, "net1.inp", "net1.rpt", "");
|
||||
if (errcode == 0)
|
||||
{
|
||||
// Call functions that perform desired analysis
|
||||
}
|
||||
EN_deleteproject(ph);
|
||||
\endcode
|
||||
|
||||
After an input file has been loaded in this fashion the resulting network can have objects added or deleted, and their properties set using the various Toolkit functions .
|
||||
|
||||
The second method for supplying network data to a project is to use the Toolkit's functions to add objects and to set their properties via code. In this case the @ref EN_init function should be called immediately after creating a project, passing in the names of a report and binary output files (both optional) as well as the choices of flow units and head loss formulas to use. After that the various \b EN_add functions, such as @ref EN_addnode, @ref EN_addlink, @ref EN_addpattern, @ref EN_addcontrol, etc., can be called to add new objects to the network. Here is a partial example of constructing a network from code:
|
||||
|
||||
\code {.c}
|
||||
int index;
|
||||
EN_Project ph;
|
||||
EN_createproject(&ph);
|
||||
EN_init(ph, "net1.rpt", "", EN_GPM, EN_HW);
|
||||
EN_addnode(ph, "J1", EN_JUNCTION, &index);
|
||||
EN_addnode(ph, "J2", EN_JUNCTION, &index);
|
||||
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2", &index);
|
||||
// additional function calls to complete building the network
|
||||
\endcode
|
||||
|
||||
See the @ref Example2 for a more complete example. The labels used to name objects cannot contain spaces, semi-colons, or double quotes nor exceed @ref EN_SizeLimits "EN_MAXID" characters in length. While adding objects their properties can be set as described in the next section. Attemtping to change a network's structure by adding or deleting nodes and links while the Toolkit's hydraulic or water quality solvers are open will result in an error condition.
|
||||
|
||||
@section Properties Setting Object Properties
|
||||
|
||||
The Toolkit contains several functions for retrieving and setting the properties of a network's objects and its analysis options. The names of retrieval functions all begin with \b EN_get (e.g., @ref EN_getnodevalue, @ref EN_getoption, etc.) while the functions used for setting parameter values begin with \b EN_set (e.g., @ref EN_setnodevalue, @ref EN_setoption, etc.).
|
||||
|
||||
Most of these functions use an index number to refer to a specific network component (such as a node, link, time pattern or data curve). This number is simply the position of the component in the list of all components of similar type (e.g., node 10 is the tenth node, starting from 1, in the network) and is not the same as the ID label assigned to the component. A series of functions exist to determine a component's index number given its ID label (see @ref EN_getnodeindex, @ref EN_getlinkindex, @ref EN_getpatternindex, and @ref EN_getcurveindex). Likewise, functions exist to retrieve a component's ID label given its index number (see @ref EN_getlinkid, @ref EN_getnodeid, @ref EN_getpatternid, and @ref EN_getcurveid). The @ref EN_getcount function can be used to determine the number of different components in the network. Be aware that a component's index can change as elements are added or deleted from the network. The @ref EN_addnode and @ref EN_addlink functions return the index of the newly added node or link as a convenience for immediately setting their properties.
|
||||
|
||||
The code below is an example of using the property retrieval and setting functions. It changes all links with diameter of 10 inches to 12 inches.
|
||||
|
||||
\code {.c}
|
||||
void changeDiameters(EN_Project ph)
|
||||
{
|
||||
int i, nLinks;
|
||||
double diam;
|
||||
EN_getcount(ph, EN_LINKCOUNT, &nLinks);
|
||||
for (i = 1; i <= nLinks; i++)
|
||||
{
|
||||
EN_getlinkvalue(ph, i, EN_DIAMETER, &diam);
|
||||
if (diam == 10) EN_setlinkvalue(ph, i, EN_DIAMETER, 12);
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
@section hydraulics Computing Hydraulics
|
||||
|
||||
There are two ways to use the Toolkit to run a hydraulic analysis:
|
||||
-# Use the @ref EN_solveH function to run a complete extended period analysis, without having access to intermediate results.
|
||||
-# Use the @ref EN_openH - @ref EN_initH - @ref EN_runH - @ref EN_nextH - @ref EN_closeH series of functions to step through the simulation one hydraulic time step at a time.
|
||||
|
||||
Method 1 is useful if you only want to run a single hydraulic analysis, perhaps to provide input to a water quality analysis. With this method hydraulic results are always saved to an intermediate hydraulics file at every time step.
|
||||
|
||||
Method 2 must be used if you need to access results between time steps or if you wish to run many analyses efficiently. To accomplish the latter, you would make only one call to \b EN_openH to begin the process, then make successive calls to <b>EN_initH - EN_runH - EN_nextH</b> to perform each analysis, and finally call \b EN_closeH to close down the hydraulics system. An example of this is shown below (calls to \b EN_nextH are not needed because we are only making a single period analysis in this example).
|
||||
|
||||
\code {.c}
|
||||
void runHydraulics(EN_Project ph, int nRuns)
|
||||
{
|
||||
int i;
|
||||
long t;
|
||||
EN_openH(ph);
|
||||
for (i = 1; i <= nRuns; i++)
|
||||
{
|
||||
// user-supplied function to set parameters
|
||||
setparams(ph, i);
|
||||
// initialize hydraulics; don't save them to file
|
||||
EN_initH(ph, EN_NOSAVE);
|
||||
// solve hydraulics
|
||||
EN_runH(ph, &t);
|
||||
// user-supplied function to process results
|
||||
getresults(ph, i);
|
||||
}
|
||||
EN_closeH(ph);
|
||||
}
|
||||
\endcode
|
||||
|
||||
@section quality Computing Water Quality
|
||||
|
||||
As with a hydraulic analysis, there are two ways to carry out a water quality analysis:
|
||||
|
||||
-# Use the @ref EN_solveQ function to run a complete extended period analysis, without having access to intermediate results. A complete set of hydraulic results must have been generated either from running a hydraulic analysis or from importing a saved hydraulics file from a previous run.
|
||||
-# Use the @ref EN_openQ - @ref EN_initQ - @ref EN_runQ - @ref EN_nextQ - @ref EN_closeQ series of functions to step through the simulation one hydraulic time step at a time. (Replacing @ref EN_nextQ with @ref EN_stepQ will step through one water quality time step at a time.)
|
||||
|
||||
The second option can either be carried out after a hydraulic analysis has been run or simultaneously as hydraulics are being computed. Example code for these two alternatives is shown below:
|
||||
|
||||
\code {.c}
|
||||
int runSequentialQuality(EN_Project ph)
|
||||
{
|
||||
int err;
|
||||
long t, tStep;
|
||||
err = EN_solveH(ph);
|
||||
if (err > 100) return err;
|
||||
EN_openQ(ph);
|
||||
EN_initQ(ph, EN_NOSAVE);
|
||||
do {
|
||||
EN_runQ(ph, &t);
|
||||
// Access quality results for time t here
|
||||
EN_nextQ(ph, &tStep);
|
||||
} while (tStep > 0);
|
||||
EN_closeQ(ph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int runConcurrentQuality(EN_Project ph)
|
||||
{
|
||||
int err = 0;
|
||||
long t, tStep;
|
||||
EN_openH(ph);
|
||||
EN_initH(ph, EN_NOSAVE);
|
||||
EN_openQ(ph);
|
||||
EN_initQ(ph, EN_NOSAVE);
|
||||
do {
|
||||
err = EN_runH(ph, &t);
|
||||
if (err > 100) break;
|
||||
EN_runQ(ph, &t);
|
||||
// Access hydraulic & quality results for time t here
|
||||
EN_nextH(ph, &tStep);
|
||||
EN_nextQ(ph, &tStep);
|
||||
} while (tStep > 0);
|
||||
EN_closeH(ph);
|
||||
EN_closeQ(ph);
|
||||
return err;
|
||||
}
|
||||
\endcode
|
||||
|
||||
@section results Retrieving Computed Results
|
||||
|
||||
The @ref EN_getnodevalue and @ref EN_getlinkvalue functions can also be used to retrieve the results of hydraulic and water quality simulations. The computed parameters (and their Toolkit codes) that can be retrieved are as follows:
|
||||
|For Nodes: | For Links: |
|
||||
|----------------------------------- | ----------------------------------------- |
|
||||
|\b EN_DEMAND (demand) |\b EN_FLOW (flow rate) |
|
||||
|\b EN_DEMANDDEFICIT (demand deficit) |\b EN_VELOCITY (flow velocity) |
|
||||
|\b EN_HEAD (hydraulic head) |\b EN_HEADLOSS (head loss) |
|
||||
|\b EN_PRESSURE (pressure) |\b EN_STATUS (link status) |
|
||||
|\b EN_TANKLEVEL (tank water level) |\b EN_SETTING (pump speed or valve setting) |
|
||||
|\b EN_TANKVOLUME (tank water volume) |\b EN_ENERGY (pump energy usage) |
|
||||
|\b EN_QUALITY (water quality) |\b EN_PUMP_EFFIC (pump efficiency) |
|
||||
|\b EN_SOURCEMASS (source mass inflow)| |
|
||||
|
||||
The following code shows how to retrieve the pressure at each node of a network after each time step of a hydraulic analysis (`writetofile` is a user-defined function that will write a record to a file):
|
||||
\code {.c}
|
||||
void getPressures(EN_Project ph)
|
||||
{
|
||||
int i, numNodes;
|
||||
long t, tStep;
|
||||
double p;
|
||||
char id[EN_MAXID + 1];
|
||||
EN_getcount(ph, EN_NODECOUNT, &numNodes);
|
||||
EN_openH(ph);
|
||||
EN_initH(ph, EN_NOSAVE);
|
||||
do {
|
||||
EN_runH(ph, &t);
|
||||
for (i = 1; i <= NumNodes; i++) {
|
||||
EN_getnodevalue(ph, i, EN_PRESSURE, &p);
|
||||
EN_getnodeid(ph, i, id);
|
||||
writetofile(t, id, p);
|
||||
}
|
||||
EN_nextH(&tStep);
|
||||
} while (tStep > 0);
|
||||
EN_closeH(ph);
|
||||
}
|
||||
\endcode
|
||||
|
||||
@section report Producing a Report
|
||||
|
||||
The Toolkit has some built-in capabilities to produce formatted output results saved to a file. More specialized reporting needs can always be handled by writing custom code.
|
||||
|
||||
The @ref EN_setreport function is used to define the format of a report while the @ref EN_report function actually writes the report. The latter should be called only after a hydraulic or water quality analysis has been made. An example of creating a report that lists all nodes where the pressure variation over the duration of the simulation exceeds 20 psi is shown below:
|
||||
|
||||
\code {.c}
|
||||
void reportPressureVariation(EN_Project ph)
|
||||
{
|
||||
// Compute ranges (max - min)
|
||||
EN_settimeparam(ph, EN_STATISTIC, EN_RANGE);
|
||||
|
||||
// Solve and save hydraulics
|
||||
EN_solveH(ph);
|
||||
EN_saveH(ph);
|
||||
|
||||
// Define contents of the report
|
||||
EN_resetreport(ph);
|
||||
EN_setreport(ph, "FILE myfile.rpt");
|
||||
EN_setreport(ph, "NODES ALL");
|
||||
EN_setreport(ph, "PRESSURE PRECISION 1");
|
||||
EN_setreport(ph, "PRESSURE ABOVE 20");
|
||||
|
||||
// Write the report to file
|
||||
EN_report(ph);
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
@@ -5,229 +5,391 @@ Attribute VB_Name = "Module1"
|
||||
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
|
||||
'(EPANET2.DLL)
|
||||
|
||||
'Last updated on 4/3/07
|
||||
'Last updated on 11/04/2019
|
||||
|
||||
' These are codes used by the DLL functions
|
||||
Global Const EN_ELEVATION = 0 ' Node parameters
|
||||
Global Const EN_BASEDEMAND = 1
|
||||
Global Const EN_PATTERN = 2
|
||||
Global Const EN_EMITTER = 3
|
||||
Global Const EN_INITQUAL = 4
|
||||
Global Const EN_SOURCEQUAL = 5
|
||||
Global Const EN_SOURCEPAT = 6
|
||||
Global Const EN_SOURCETYPE = 7
|
||||
Global Const EN_TANKLEVEL = 8
|
||||
Global Const EN_DEMAND = 9
|
||||
Global Const EN_HEAD = 10
|
||||
Global Const EN_PRESSURE = 11
|
||||
Global Const EN_QUALITY = 12
|
||||
Global Const EN_SOURCEMASS = 13
|
||||
Global Const EN_INITVOLUME = 14
|
||||
Global Const EN_MIXMODEL = 15
|
||||
Global Const EN_MIXZONEVOL = 16
|
||||
Public Const EN_ELEVATION = 0 ' Node parameters
|
||||
Public Const EN_BASEDEMAND = 1
|
||||
Public Const EN_PATTERN = 2
|
||||
Public Const EN_EMITTER = 3
|
||||
Public Const EN_INITQUAL = 4
|
||||
Public Const EN_SOURCEQUAL = 5
|
||||
Public Const EN_SOURCEPAT = 6
|
||||
Public Const EN_SOURCETYPE = 7
|
||||
Public Const EN_TANKLEVEL = 8
|
||||
Public Const EN_DEMAND = 9
|
||||
Public Const EN_HEAD = 10
|
||||
Public Const EN_PRESSURE = 11
|
||||
Public Const EN_QUALITY = 12
|
||||
Public Const EN_SOURCEMASS = 13
|
||||
Public Const EN_INITVOLUME = 14
|
||||
Public Const EN_MIXMODEL = 15
|
||||
Public Const EN_MIXZONEVOL = 16
|
||||
|
||||
Global Const EN_TANKDIAM = 17
|
||||
Global Const EN_MINVOLUME = 18
|
||||
Global Const EN_VOLCURVE = 19
|
||||
Global Const EN_MINLEVEL = 20
|
||||
Global Const EN_MAXLEVEL = 21
|
||||
Global Const EN_MIXFRACTION = 22
|
||||
Global Const EN_TANK_KBULK = 23
|
||||
Global Const EN_TANKVOLUME = 24
|
||||
Global Const EN_MAXVOLUME = 25
|
||||
Public Const EN_TANKDIAM = 17
|
||||
Public Const EN_MINVOLUME = 18
|
||||
Public Const EN_VOLCURVE = 19
|
||||
Public Const EN_MINLEVEL = 20
|
||||
Public Const EN_MAXLEVEL = 21
|
||||
Public Const EN_MIXFRACTION = 22
|
||||
Public Const EN_TANK_KBULK = 23
|
||||
Public Const EN_TANKVOLUME = 24
|
||||
Public Const EN_MAXVOLUME = 25
|
||||
Public Const EN_CANOVERFLOW = 26
|
||||
Public Const EN_DEMANDDEFICIT = 27
|
||||
|
||||
Global Const EN_DIAMETER = 0 ' Link parameters
|
||||
Global Const EN_LENGTH = 1
|
||||
Global Const EN_ROUGHNESS = 2
|
||||
Global Const EN_MINORLOSS = 3
|
||||
Global Const EN_INITSTATUS = 4
|
||||
Global Const EN_INITSETTING = 5
|
||||
Global Const EN_KBULK = 6
|
||||
Global Const EN_KWALL = 7
|
||||
Global Const EN_FLOW = 8
|
||||
Global Const EN_VELOCITY = 9
|
||||
Global Const EN_HEADLOSS = 10
|
||||
Global Const EN_STATUS = 11
|
||||
Global Const EN_SETTING = 12
|
||||
Global Const EN_ENERGY = 13
|
||||
Global Const EN_LINKQUAL = 14 'ES
|
||||
Global Const EN_LINKPATTERN = 15
|
||||
Public Const EN_DIAMETER = 0 ' Link parameters
|
||||
Public Const EN_LENGTH = 1
|
||||
Public Const EN_ROUGHNESS = 2
|
||||
Public Const EN_MINORLOSS = 3
|
||||
Public Const EN_INITSTATUS = 4
|
||||
Public Const EN_INITSETTING = 5
|
||||
Public Const EN_KBULK = 6
|
||||
Public Const EN_KWALL = 7
|
||||
Public Const EN_FLOW = 8
|
||||
Public Const EN_VELOCITY = 9
|
||||
Public Const EN_HEADLOSS = 10
|
||||
Public Const EN_STATUS = 11
|
||||
Public Const EN_SETTING = 12
|
||||
Public Const EN_ENERGY = 13
|
||||
Public Const EN_LINKQUAL = 14
|
||||
Public Const EN_LINKPATTERN = 15
|
||||
|
||||
Global Const EN_DURATION = 0 ' Time parameters
|
||||
Global Const EN_HYDSTEP = 1
|
||||
Global Const EN_QUALSTEP = 2
|
||||
Global Const EN_PATTERNSTEP = 3
|
||||
Global Const EN_PATTERNSTART = 4
|
||||
Global Const EN_REPORTSTEP = 5
|
||||
Global Const EN_REPORTSTART = 6
|
||||
Global Const EN_RULESTEP = 7
|
||||
Global Const EN_STATISTIC = 8
|
||||
Global Const EN_PERIODS = 9
|
||||
Global Const EN_STARTTIME = 10
|
||||
Global Const EN_HTIME = 11
|
||||
Global Const EN_QTIME = 12
|
||||
Global Const EN_HALTFLAG = 13
|
||||
Global Const EN_NEXTEVENT = 14
|
||||
Public Const EN_PUMP_STATE = 16
|
||||
Public Const EN_PUMP_EFFIC = 17
|
||||
Public Const EN_PUMP_POWER = 18
|
||||
Public Const EN_PUMP_HCURVE = 19
|
||||
Public Const EN_PUMP_ECURVE = 20
|
||||
Public Const EN_PUMP_ECOST = 21
|
||||
Public Const EN_PUMP_EPAT = 22
|
||||
|
||||
Global Const EN_ITERATIONS = 0
|
||||
Global Const EN_RELATIVEERROR = 1
|
||||
Public Const EN_DURATION = 0 ' Time parameters
|
||||
Public Const EN_HYDSTEP = 1
|
||||
Public Const EN_QUALSTEP = 2
|
||||
Public Const EN_PATTERNSTEP = 3
|
||||
Public Const EN_PATTERNSTART = 4
|
||||
Public Const EN_REPORTSTEP = 5
|
||||
Public Const EN_REPORTSTART = 6
|
||||
Public Const EN_RULESTEP = 7
|
||||
Public Const EN_STATISTIC = 8
|
||||
Public Const EN_PERIODS = 9
|
||||
Public Const EN_STARTTIME = 10
|
||||
Public Const EN_HTIME = 11
|
||||
Public Const EN_QTIME = 12
|
||||
Public Const EN_HALTFLAG = 13
|
||||
Public Const EN_NEXTEVENT = 14
|
||||
|
||||
Global Const EN_NODECOUNT = 0 'Component counts
|
||||
Global Const EN_TANKCOUNT = 1
|
||||
Global Const EN_LINKCOUNT = 2
|
||||
Global Const EN_PATCOUNT = 3
|
||||
Global Const EN_CURVECOUNT = 4
|
||||
Global Const EN_CONTROLCOUNT = 5
|
||||
Public Const EN_ITERATIONS = 0 ' Run statistics
|
||||
Public Const EN_RELATIVEERROR = 1
|
||||
Public Const EN_MAXHEADERROR = 2
|
||||
Public Const EN_MAXFLOWCHANGE = 3
|
||||
Public Const EN_MASSBALANCE = 4
|
||||
Public Const EN_DEFICIENTNODES = 5
|
||||
Public Const EN_DEMANDREDUCTION = 6
|
||||
|
||||
Global Const EN_JUNCTION = 0 ' Node types
|
||||
Global Const EN_RESERVOIR = 1
|
||||
Global Const EN_TANK = 2
|
||||
Public Const EN_NODE = 0 ' Component types
|
||||
Public Const EN_LINK = 1
|
||||
Public Const EN_TIMEPAT = 2
|
||||
Public Const EN_CURVE = 3
|
||||
Public Const EN_CONTROL = 4
|
||||
Public Const EN_RULE = 5
|
||||
|
||||
Global Const EN_CVPIPE = 0 ' Link types
|
||||
Global Const EN_PIPE = 1
|
||||
Global Const EN_PUMP = 2
|
||||
Global Const EN_PRV = 3
|
||||
Global Const EN_PSV = 4
|
||||
Global Const EN_PBV = 5
|
||||
Global Const EN_FCV = 6
|
||||
Global Const EN_TCV = 7
|
||||
Global Const EN_GPV = 8
|
||||
Public Const EN_NODECOUNT = 0 ' Component counts
|
||||
Public Const EN_TANKCOUNT = 1
|
||||
Public Const EN_LINKCOUNT = 2
|
||||
Public Const EN_PATCOUNT = 3
|
||||
Public Const EN_CURVECOUNT = 4
|
||||
Public Const EN_CONTROLCOUNT = 5
|
||||
Public Const EN_RULECOUNT = 6
|
||||
|
||||
Global Const EN_NONE = 0 ' Quality analysis types
|
||||
Global Const EN_CHEM = 1
|
||||
Global Const EN_AGE = 2
|
||||
Global Const EN_TRACE = 3
|
||||
Public Const EN_JUNCTION = 0 ' Node types
|
||||
Public Const EN_RESERVOIR = 1
|
||||
Public Const EN_TANK = 2
|
||||
|
||||
Global Const EN_CONCEN = 0 ' Source quality types
|
||||
Global Const EN_MASS = 1
|
||||
Global Const EN_SETPOINT = 2
|
||||
Global Const EN_FLOWPACED = 3
|
||||
Public Const EN_CVPIPE = 0 ' Link types
|
||||
Public Const EN_PIPE = 1
|
||||
Public Const EN_PUMP = 2
|
||||
Public Const EN_PRV = 3
|
||||
Public Const EN_PSV = 4
|
||||
Public Const EN_PBV = 5
|
||||
Public Const EN_FCV = 6
|
||||
Public Const EN_TCV = 7
|
||||
Public Const EN_GPV = 8
|
||||
|
||||
Global Const EN_CFS = 0 ' Flow units types
|
||||
Global Const EN_GPM = 1
|
||||
Global Const EN_MGD = 2
|
||||
Global Const EN_IMGD = 3
|
||||
Global Const EN_AFD = 4
|
||||
Global Const EN_LPS = 5
|
||||
Global Const EN_LPM = 6
|
||||
Global Const EN_MLD = 7
|
||||
Global Const EN_CMH = 8
|
||||
Global Const EN_CMD = 9
|
||||
Public Const EN_NONE = 0 ' Quality analysis types
|
||||
Public Const EN_CHEM = 1
|
||||
Public Const EN_AGE = 2
|
||||
Public Const EN_TRACE = 3
|
||||
|
||||
Global Const EN_TRIALS = 0 ' Misc. options
|
||||
Global Const EN_ACCURACY = 1
|
||||
Global Const EN_TOLERANCE = 2
|
||||
Global Const EN_EMITEXPON = 3
|
||||
Global Const EN_DEMANDMULT = 4
|
||||
Public Const EN_CONCEN = 0 ' Source quality types
|
||||
Public Const EN_MASS = 1
|
||||
Public Const EN_SETPOINT = 2
|
||||
Public Const EN_FLOWPACED = 3
|
||||
|
||||
Global Const EN_LOWLEVEL = 0 ' Control types
|
||||
Global Const EN_HILEVEL = 1
|
||||
Global Const EN_TIMER = 2
|
||||
Global Const EN_TIMEOFDAY = 3
|
||||
Public Const EN_HW = 0 ' Head loss formulas
|
||||
Public Const EN_DW = 1
|
||||
Public Const EN_CM = 2
|
||||
|
||||
Global Const EN_AVERAGE = 1 'Time statistic types
|
||||
Global Const EN_MINIMUM = 2
|
||||
Global Const EN_MAXIMUM = 3
|
||||
Global Const EN_RANGE = 4
|
||||
Public Const EN_CFS = 0 ' Flow units types
|
||||
Public Const EN_GPM = 1
|
||||
Public Const EN_MGD = 2
|
||||
Public Const EN_IMGD = 3
|
||||
Public Const EN_AFD = 4
|
||||
Public Const EN_LPS = 5
|
||||
Public Const EN_LPM = 6
|
||||
Public Const EN_MLD = 7
|
||||
Public Const EN_CMH = 8
|
||||
Public Const EN_CMD = 9
|
||||
|
||||
Global Const EN_MIX1 = 0 'Tank mixing models
|
||||
Global Const EN_MIX2 = 1
|
||||
Global Const EN_FIFO = 2
|
||||
Global Const EN_LIFO = 3
|
||||
Public Const EN_DDA = 0 ' Demand driven analysis
|
||||
Public Const EN_PDA = 1 ' Pressure driven analysis
|
||||
|
||||
Global Const EN_NOSAVE = 0 ' Save-results-to-file flag
|
||||
Global Const EN_SAVE = 1
|
||||
Public Const EN_TRIALS = 0 ' Simulation options
|
||||
Public Const EN_ACCURACY = 1
|
||||
Public Const EN_TOLERANCE = 2
|
||||
Public Const EN_EMITEXPON = 3
|
||||
Public Const EN_DEMANDMULT = 4
|
||||
Public Const EN_HEADERROR = 5
|
||||
Public Const EN_FLOWCHANGE = 6
|
||||
Public Const EN_HEADLOSSFORM = 7
|
||||
Public Const EN_GLOBALEFFIC = 8
|
||||
Public Const EN_GLOBALPRICE = 9
|
||||
Public Const EN_GLOBALPATTERN = 10
|
||||
Public Const EN_DEMANDCHARGE = 11
|
||||
Public Const EN_SP_GRAVITY = 12
|
||||
Public Const EN_SP_VISCOS = 13
|
||||
Public Const EN_UNBALANCED = 14
|
||||
Public Const EN_CHECKFREQ = 15
|
||||
Public Const EN_MAXCHECK = 16
|
||||
Public Const EN_DAMPLIMIT = 17
|
||||
Public Const EN_SP_DIFFUS = 18
|
||||
Public Const EN_BULKORDER = 19
|
||||
Public Const EN_WALLORDER = 20
|
||||
Public Const EN_TANKORDER = 21
|
||||
Public Const EN_CONCENLIMIT = 22
|
||||
|
||||
Global Const EN_INITFLOW = 10 ' Re-initialize flow flag
|
||||
Public Const EN_LOWLEVEL = 0 ' Control types
|
||||
Public Const EN_HILEVEL = 1
|
||||
Public Const EN_TIMER = 2
|
||||
Public Const EN_TIMEOFDAY = 3
|
||||
|
||||
Global Const EN_CONST_HP = 0 ' constant horsepower
|
||||
Global Const EN_POWER_FUNC = 1 ' power function
|
||||
Global Const EN_CUSTOM = 2 ' user-defined custom curve
|
||||
Public Const EN_AVERAGE = 1 ' Time statistic types
|
||||
Public Const EN_MINIMUM = 2
|
||||
Public Const EN_MAXIMUM = 3
|
||||
Public Const EN_RANGE = 4
|
||||
|
||||
Public Const EN_MIX1 = 0 ' Tank mixing models
|
||||
Public Const EN_MIX2 = 1
|
||||
Public Const EN_FIFO = 2
|
||||
Public Const EN_LIFO = 3
|
||||
|
||||
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
|
||||
Public Const EN_SAVE = 1
|
||||
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
|
||||
Public Const EN_SAVE_AND_INIT = 11
|
||||
|
||||
Public Const EN_CONST_HP = 0 ' Constant horsepower pump curve
|
||||
Public Const EN_POWER_FUNC = 1 ' Power function pump cuve
|
||||
Public Const EN_CUSTOM = 2 ' User-defined custom pump curve
|
||||
Public Const EN_NOCURVE = 3 ' No pump curve
|
||||
|
||||
Public Const EN_VOLUME_CURVE = 0 ' Volume curve
|
||||
Public Const EN_PUMP_CURVE = 1 ' Pump curve
|
||||
Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
|
||||
Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
|
||||
Public Const EN_GENERIC_CURVE = 4 ' Generic curve
|
||||
|
||||
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
|
||||
Public Const EN_CONDITIONAL = 1 ' Conditional object deletion
|
||||
|
||||
Public Const EN_NO_REPORT = 0 ' No status report
|
||||
Public Const EN_NORMAL_REPORT = 1 ' Normal status report
|
||||
Public Const EN_FULL_REPORT = 2 ' Full status report
|
||||
|
||||
Public Const EN_R_NODE = 6 ' Rule objects
|
||||
Public Const EN_R_LINK = 7
|
||||
Public Const EN_R_SYSTEM = 8
|
||||
|
||||
Public Const EN_R_DEMAND = 0 ' Rule variables
|
||||
Public Const EN_R_HEAD = 1
|
||||
Public Const EN_R_GRADE = 2
|
||||
Public Const EN_R_LEVEL = 3
|
||||
Public Const EN_R_PRESSURE = 4
|
||||
Public Const EN_R_FLOW = 5
|
||||
Public Const EN_R_STATUS = 6
|
||||
Public Const EN_R_SETTING = 7
|
||||
Public Const EN_R_POWER = 8
|
||||
Public Const EN_R_TIME = 9
|
||||
Public Const EN_R_CLOCKTIME = 10
|
||||
Public Const EN_R_FILLTIME = 11
|
||||
Public Const EN_R_DRAINTIME = 12
|
||||
|
||||
Public Const EN_R_EQ = 0 ' Rule operators
|
||||
Public Const EN_R_NE = 1
|
||||
Public Const EN_R_LE = 2
|
||||
Public Const EN_R_GE = 3
|
||||
Public Const EN_R_LT = 4
|
||||
Public Const EN_R_GT = 5
|
||||
Public Const EN_R_IS = 6
|
||||
Public Const EN_R_NOT = 7
|
||||
Public Const EN_R_BELOW = 8
|
||||
Public Const EN_R_ABOVE = 9
|
||||
|
||||
Public Const EN_R_IS_OPEN = 1 ' Rule status types
|
||||
Public Const EN_R_IS_CLOSED = 2
|
||||
Public Const EN_R_IS_ACTIVE = 3
|
||||
|
||||
Public Const EN_MISSING As Double = -1.0E10
|
||||
|
||||
'These are the external functions that comprise the DLL
|
||||
|
||||
Declare Function ENepanet Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String, ByVal F4 As Any) As Long
|
||||
Declare Function ENopen Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String) As Long
|
||||
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal F As String) As Long
|
||||
'Project Functions
|
||||
Declare Function ENgetversion Lib "epanet2.dll" (value As Long) As Long
|
||||
Declare Function ENepanet Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String, ByVal pviewprog As Any) As Long
|
||||
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal outFile As String, ByVal unitsType As Long, ByVal headlossType As Long) As Long
|
||||
Declare Function ENopen Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Long
|
||||
Declare Function ENgettitle Lib "epanet2.dll" (ByVal line1 As String, ByVal line2 As String, ByVal line3 As String) As Long
|
||||
Declare Function ENsettitle Lib "epanet2.dll" (ByVal titleline1 As String, ByVal titleline2 As String, ByVal titleline3 As String) As Long
|
||||
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Long
|
||||
Declare Function ENclose Lib "epanet2.dll" () As Long
|
||||
|
||||
'Hydraulic Analysis Functions
|
||||
Declare Function ENsolveH Lib "epanet2.dll" () As Long
|
||||
Declare Function ENsaveH Lib "epanet2.dll" () As Long
|
||||
Declare Function ENopenH Lib "epanet2.dll" () As Long
|
||||
Declare Function ENinitH Lib "epanet2.dll" (ByVal SaveFlag As Long) As Long
|
||||
Declare Function ENrunH Lib "epanet2.dll" (T As Long) As Long
|
||||
Declare Function ENnextH Lib "epanet2.dll" (Tstep As Long) As Long
|
||||
Declare Function ENinitH Lib "epanet2.dll" (ByVal initFlag As Long) As Long
|
||||
Declare Function ENrunH Lib "epanet2.dll" (currentTime As Long) As Long
|
||||
Declare Function ENnextH Lib "epanet2.dll" (tStep As Long) As Long
|
||||
Declare Function ENcloseH Lib "epanet2.dll" () As Long
|
||||
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal F As String) As Long
|
||||
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal F As String) As Long
|
||||
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal filename As String) As Long
|
||||
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal filename As String) As Long
|
||||
|
||||
'Water Quality Analysis Functions
|
||||
Declare Function ENsolveQ Lib "epanet2.dll" () As Long
|
||||
Declare Function ENopenQ Lib "epanet2.dll" () As Long
|
||||
Declare Function ENinitQ Lib "epanet2.dll" (ByVal SaveFlag As Long) As Long
|
||||
Declare Function ENrunQ Lib "epanet2.dll" (T As Long) As Long
|
||||
Declare Function ENnextQ Lib "epanet2.dll" (Tstep As Long) As Long
|
||||
Declare Function ENstepQ Lib "epanet2.dll" (Tleft As Long) As Long
|
||||
Declare Function ENinitQ Lib "epanet2.dll" (ByVal saveFlag As Long) As Long
|
||||
Declare Function ENrunQ Lib "epanet2.dll" (currentTime As Long) As Long
|
||||
Declare Function ENnextQ Lib "epanet2.dll" (tStep As Long) As Long
|
||||
Declare Function ENstepQ Lib "epanet2.dll" (timeLeft As Long) As Long
|
||||
Declare Function ENcloseQ Lib "epanet2.dll" () As Long
|
||||
|
||||
Declare Function ENwriteline Lib "epanet2.dll" (ByVal S As String) As Long
|
||||
'Reporting Functions
|
||||
Declare Function ENwriteline Lib "epanet2.dll" (ByVal line As String) As Long
|
||||
Declare Function ENreport Lib "epanet2.dll" () As Long
|
||||
Declare Function ENcopyreport Lib "epanet2.dll" (ByVal filename As String) As Long
|
||||
Declare Function ENclearreport Lib "epanet2.dll" () As Long
|
||||
Declare Function ENresetreport Lib "epanet2.dll" () As Long
|
||||
Declare Function ENsetreport Lib "epanet2.dll" (ByVal S As String) As Long
|
||||
Declare Function ENsetreport Lib "epanet2.dll" (ByVal format As String) As Long
|
||||
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal level As Long) As Long
|
||||
Declare Function ENgetcount Lib "epanet2.dll" (ByVal object As Long, count As Long) As Long
|
||||
Declare Function ENgeterror Lib "epanet2.dll" (ByVal errcode As Long, ByVal errmsg As String, ByVal maxLen As Long) As Long
|
||||
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Long, ByRef value As Single) As Long
|
||||
Declare Function ENgetresultindex Lib "epanet2.dll" (ByVal type_ As Long, ByVal index As Long, ByRef value As Long) As Long
|
||||
|
||||
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal Cindex As Long, Ctype As Long, Lindex As Long, Setting As Single, Nindex As Long, Level As Single) As Long
|
||||
Declare Function ENgetcount Lib "epanet2.dll" (ByVal Code As Long, Value As Long) As Long
|
||||
Declare Function ENgetoption Lib "epanet2.dll" (ByVal Code As Long, Value As Single) As Long
|
||||
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal Code As Long, Value As Long) As Long
|
||||
Declare Function ENgetflowunits Lib "epanet2.dll" (Code As Long) As Long
|
||||
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal ID As String, Index As Long) As Long
|
||||
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal Index As Long, ByVal ID As String) As Long
|
||||
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal Index As Long, L As Long) As Long
|
||||
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Period As Long, Value As Single) As Long
|
||||
Declare Function ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal Index As Long, Value As Single) As Long
|
||||
Declare Function ENgetqualtype Lib "epanet2.dll" (QualCode As Long, TraceNode As Long) As Long
|
||||
Declare Function ENgeterror Lib "epanet2.dll" (ByVal ErrCode As Long, ByVal ErrMsg As String, ByVal N As Long) As Long
|
||||
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal Code As Long, Value As Single) As Long
|
||||
'Analysis Options Functions
|
||||
Declare Function ENgetoption Lib "epanet2.dll" (ByVal option_ As Long, value As Single) As Long
|
||||
Declare Function ENsetoption Lib "epanet2.dll" (ByVal option_ As Long, ByVal value As Single) As Long
|
||||
Declare Function ENgetflowunits Lib "epanet2.dll" (units As Long) As Long
|
||||
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal units As Long) As Long
|
||||
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal param As Long, value As Long) As Long
|
||||
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal param As Long, ByVal value As Long) As Long
|
||||
Declare Function ENgetqualinfo Lib "epanet2.dll" (qualType As Long, ByVal chemName As String, ByVal chemUnits As String, traceNode As Long) As Long
|
||||
Declare Function ENgetqualtype Lib "epanet2.dll" (qualType As Long, traceNode As Long) As Long
|
||||
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal qualType As Long, ByVal chemName As String, ByVal chemUnits As String, ByVal traceNode As String) As Long
|
||||
|
||||
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal ID As String, Index As Long) As Long
|
||||
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal Index As Long, ByVal ID As String) As Long
|
||||
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal Index As Long, Code As Long) As Long
|
||||
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Code As Long, Value As Single) As Long
|
||||
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal Index As Long, X As Single, Y As Single) As Long
|
||||
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal Index As Long, ByVal X As Single, ByVal Y As Single) As Long
|
||||
'Node Functions
|
||||
Declare Function ENaddnode Lib "epanet2.dll" (ByVal id As String, ByVal nodeType As Long, index As Long) As Long
|
||||
Declare Function ENdeletenode Lib "epanet2.dll" (ByVal index As Long, ByVal actionCode As Long) As Long
|
||||
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
|
||||
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
|
||||
Declare Function ENsetnodeid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
|
||||
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal index As Long, nodeType As Long) As Long
|
||||
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, value As Single) As Long
|
||||
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, ByVal value As Single) As Long
|
||||
Declare Function ENsetjuncdata Lib "epanet2.dll" (ByVal index As Long, ByVal elev As Single, ByVal dmnd As Single, ByVal dmndpat As String) As Long
|
||||
Declare Function ENsettankdata Lib "epanet2.dll" (ByVal index As Long, ByVal elev As Single, ByVal initlvl As Single, ByVal minlvl As Single, ByVal maxlvl As Single, ByVal diam As Single, ByVal minvol As Single, ByVal volcurve As String) As Long
|
||||
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal index As Long, x As Double, y As Double) As Long
|
||||
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal index As Long, ByVal x As Double, ByVal y As Double) As Long
|
||||
|
||||
'Nodal Demand Functions
|
||||
Declare Function ENgetdemandmodel Lib "epanet2.dll" (type_ As Long, pmin As Single, preq As Single, pexp As Single) As Long
|
||||
Declare Function ENsetdemandmodel Lib "epanet2.dll" (ByVal type_ As Long, ByVal pmin As Single, ByVal preq As Single, ByVal pexp As Single) As Long
|
||||
Declare Function ENadddemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal baseDemand As Single, ByVal patternName As String, ByVal demandName As String) As Long
|
||||
Declare Function ENdeletedemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long) As Long
|
||||
Declare Function ENgetdemandindex Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandName As String, demandIndex As Long) As Long
|
||||
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal nodeIndex As Long, numDemands As Long) As Long
|
||||
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, value As Single) As Long
|
||||
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal BaseDemand As Single) As Long
|
||||
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, patIndex As Long) As Long
|
||||
Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal patIndex As Long) As Long
|
||||
Declare Function ENgetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal demandName As String) As Long
|
||||
Declare Function ENsetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Long, ByVal demandIndex As Long, ByVal demandName As String) As Long
|
||||
|
||||
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal Index As Long, numDemands As Long) As Long
|
||||
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal Index As Long, ByVal DemandIndex As Long, Value As Single) As Long
|
||||
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal Index As Long, ByVal DemandIndex As Long, PatIndex As Long) As Long
|
||||
'Link Functions
|
||||
Declare Function ENaddlink Lib "epanet2.dll" (ByVal id As String, ByVal linkType As Long, ByVal fromNode As String, ByVal toNode As String, index As Long) As Long
|
||||
Declare Function ENdeletelink Lib "epanet2.dll" (ByVal index As Long, ByVal actionCode As Long) As Long
|
||||
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
|
||||
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
|
||||
Declare Function ENsetlinkid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
|
||||
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal index As Long, linkType As Long) As Long
|
||||
Declare Function ENsetlinktype Lib "epanet2.dll" (index As Long, ByVal linkType As Long, ByVal actionCode As Long) As Long
|
||||
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal index As Long, node1 As Long, node2 As Long) As Long
|
||||
Declare Function ENsetlinknodes Lib "epanet2.dll" (ByVal index As Long, ByVal node1 As Long, ByVal node2 As Long) As Long
|
||||
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, value As Single) As Long
|
||||
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal property As Long, ByVal value As Single) As Long
|
||||
Declare Function ENsetpipedata Lib "epanet2.dll" (ByVal index As Long, ByVal length As Single, ByVal diam As Single, ByVal rough As Single, ByVal mloss As Single) As Long
|
||||
Declare Function ENgetvertexcount Lib "epanet2.dll" (ByVal index As Long, count As Long) As Long
|
||||
Declare Function ENgetvertex Lib "epanet2.dll" (ByVal index As Long, ByVal vertex As Long, x As Double, y As Double) As Long
|
||||
Declare Function ENsetvertices Lib "epanet2.dll" (ByVal index As Long, xCoords As Any, yCoords As Any, ByVal count As Long) As Long
|
||||
|
||||
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal ID As String, Index As Long) As Long
|
||||
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal Index As Long, ByVal ID As String) As Long
|
||||
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal Index As Long, Code As Long) As Long
|
||||
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal Index As Long, Node1 As Long, Node2 As Long) As Long
|
||||
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Code As Long, Value As Single) As Long
|
||||
'Pump Functions
|
||||
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Long, curveIndex As Long) As Long
|
||||
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Long, ByVal curveIndex As Long) As Long
|
||||
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal linkIndex As Long, pumpType As Long) As Long
|
||||
|
||||
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal CurveIndex As Long, ByVal CurveID As String, nValues As Long, xValues As Any, yValues As Any) As Long
|
||||
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal PumpIndex As Long, CurveIndex As Long) As Long
|
||||
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal Index As Long, PumpType As Long) As Long
|
||||
'Time Pattern Functions
|
||||
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal id As String) As Long
|
||||
Declare Function ENdeletepattern Lib "epanet2.dll" (ByVal index As Long) As Long
|
||||
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
|
||||
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
|
||||
Declare Function ENsetpatternid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
|
||||
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal index As Long, len_ As Long) As Long
|
||||
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal index As Long, ByVal period As Long, value As Single) As Long
|
||||
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal index As Long, ByVal period As Long, ByVal value As Single) As Long
|
||||
Declare Function ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal index As Long, value As Single) As Long
|
||||
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal index As Long, values As Any, ByVal len_ As Long) As Long
|
||||
|
||||
Declare Function ENgetversion Lib "epanet2.dll" (Value As Long) As Long
|
||||
'Data Curve Functions
|
||||
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal id As String) As Long
|
||||
Declare Function ENdeletecurve Lib "epanet2.dll" (ByVal index As Long) As Long
|
||||
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal id As String, index As Long) As Long
|
||||
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
|
||||
Declare Function ENsetcurveid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
|
||||
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Long, len_ As Long) As Long
|
||||
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal index As Long, type_ As Long) As Long
|
||||
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal pointIndex As Long, x As Single, y As Single) As Long
|
||||
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Long, ByVal pointIndex As Long, ByVal x As Single, ByVal y As Single) As Long
|
||||
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal index As Long, ByVal id As String, nPoints As Long, xValues As Any, yValues As Any) As Long
|
||||
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal index As Long, xValues As Any, yValues As Any, ByVal nPoints As Long) As Long
|
||||
|
||||
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal Cindex As Long, ByVal Ctype As Long, ByVal Lindex As Long, ByVal Setting As Single, ByVal Nindex As Long, ByVal Level As Single) As Long
|
||||
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Code As Long, ByVal Value As Single) As Long
|
||||
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Code As Long, ByVal Value As Single) As Long
|
||||
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal ID As String) As Long
|
||||
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal Index As Long, F As Any, ByVal N As Long) As Long
|
||||
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Period As Long, ByVal Value As Single) As Long
|
||||
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal Code As Long, ByVal Value As Long) As Long
|
||||
Declare Function ENsetoption Lib "epanet2.dll" (ByVal Code As Long, ByVal Value As Single) As Long
|
||||
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal Code As Long) As Long
|
||||
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal QualCode As Long, ByVal ChemName As String, ByVal ChemUnits As String, ByVal TraceNode As String) As Long
|
||||
Declare Function ENgetqualinfo Lib "epanet2.dll" (QualCode As Long, ByVal ChemName As String, ByVal ChemUnits As String, TraceNode As Long) As Long
|
||||
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal NodeIndex As Long, ByVal DemandIndex As Long, ByVal BaseDemand As Single) As Long
|
||||
'Simple Control Functions
|
||||
Declare Function ENaddcontrol Lib "epanet2.dll" (ByVal type_ As Long, ByVal linkIndex As Long, ByVal setting As Single, ByVal nodeIndex As Long, ByVal level As Single, index As Long) As Long
|
||||
Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal index As Long) As Long
|
||||
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal index As Long, type_ As Long, linkIndex As Long, setting As Single, nodeIndex As Long, level As Single) As Long
|
||||
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal index As Long, ByVal type_ As Long, ByVal linkIndex As Long, ByVal setting As Single, ByVal nodeIndex As Long, ByVal level As Single) As Long
|
||||
|
||||
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal ID As String, Index As Long) As Long
|
||||
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal Index As Long, ByVal ID As String) As Long
|
||||
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal Index As Long, L As Long) As Long
|
||||
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Ptn As Long, X As Single, Y As Single) As Long
|
||||
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Ptn As Long, ByVal X As Single, ByVal Y As Single) As Long
|
||||
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal Index As Long, X As Any, Y As Any, ByVal N As Long) As Long
|
||||
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal ID As String) As Long
|
||||
'Rule-Based Control Functions
|
||||
Declare Function ENaddrule Lib "epanet2.dll" (ByVal rule As String) As Long
|
||||
Declare Function ENdeleterule Lib "epanet2.dll" (ByVal index As Long) As Long
|
||||
Declare Function ENgetrule Lib "epanet2.dll" (ByVal index As Long, nPremises As Long, nThenActions As Long, nElseActions As Long, priority As Single) As Long
|
||||
Declare Function ENgetruleID Lib "epanet2.dll" (ByVal index As Long, ByVal id As String) As Long
|
||||
Declare Function ENsetrulepriority Lib "epanet2.dll" (ByVal index As Long, ByVal priority As Single) As Long
|
||||
Declare Function ENgetpremise Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, logop As Long, object As Long, objIndex As Long, variable As Long, relop As Long, status As Long, value As Single) As Long
|
||||
Declare Function ENsetpremise Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal logop As Long, ByVal object As Long, ByVal objIndex As Long, ByVal variable As Long, ByVal relop As Long, ByVal status As Long, ByVal value As Single) As Long
|
||||
Declare Function ENsetpremiseindex Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal objIndex As Long) As Long
|
||||
Declare Function ENsetpremisestatus Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal status As Long) As Long
|
||||
Declare Function ENsetpremisevalue Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal premiseIndex As Long, ByVal value As Single) As Long
|
||||
Declare Function ENgetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, linkIndex As Long, status As Long, setting As Single) As Long
|
||||
Declare Function ENsetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, ByVal linkIndex As Long, ByVal status As Long, ByVal setting As Single) As Long
|
||||
Declare Function ENgetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, linkIndex As Long, status As Long, setting As Single) As Long
|
||||
Declare Function ENsetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Long, ByVal actionIndex As Long, ByVal linkIndex As Long, ByVal status As Long, ByVal setting As Single) As Long
|
||||
|
||||
131
include/epanet2.def
Normal file
131
include/epanet2.def
Normal file
@@ -0,0 +1,131 @@
|
||||
LIBRARY EPANET2.DLL
|
||||
|
||||
EXPORTS
|
||||
ENaddcontrol = _ENaddcontrol@24
|
||||
ENaddcurve = _ENaddcurve@4
|
||||
ENaddlink = _ENaddlink@20
|
||||
ENaddnode = _ENaddnode@12
|
||||
ENadddemand = _ENadddemand@16
|
||||
ENaddpattern = _ENaddpattern@4
|
||||
ENaddrule = _ENaddrule@4
|
||||
ENclearreport = _ENclearreport@0
|
||||
ENclose = _ENclose@0
|
||||
ENcloseH = _ENcloseH@0
|
||||
ENcloseQ = _ENcloseQ@0
|
||||
ENcopyreport = _ENcopyreport@4
|
||||
ENdeletecontrol = _ENdeletecontrol@4
|
||||
ENdeletecurve = _ENdeletecurve@4
|
||||
ENdeletedemand = _ENdeletedemand@8
|
||||
ENdeletelink = _ENdeletelink@8
|
||||
ENdeletenode = _ENdeletenode@8
|
||||
ENdeletepattern = _ENdeletepattern@4
|
||||
ENdeleterule = _ENdeleterule@4
|
||||
ENepanet = _ENepanet@16
|
||||
ENgetaveragepatternvalue = _ENgetaveragepatternvalue@8
|
||||
ENgetbasedemand = _ENgetbasedemand@12
|
||||
ENgetcomment = _ENgetcomment@12
|
||||
ENgetcontrol = _ENgetcontrol@24
|
||||
ENgetcoord = _ENgetcoord@12
|
||||
ENgetcount = _ENgetcount@8
|
||||
ENgetcurve = _ENgetcurve@20
|
||||
ENgetcurveid = _ENgetcurveid@8
|
||||
ENgetcurveindex = _ENgetcurveindex@8
|
||||
ENgetcurvelen = _ENgetcurvelen@8
|
||||
ENgetcurvetype = _ENgetcurvetype@8
|
||||
ENgetcurvevalue = _ENgetcurvevalue@16
|
||||
ENgetdemandindex = _ENgetdemandindex@12
|
||||
ENgetdemandmodel = _ENgetdemandmodel@16
|
||||
ENgetdemandname = _ENgetdemandname@12
|
||||
ENgetdemandpattern = _ENgetdemandpattern@12
|
||||
ENgetelseaction = _ENgetelseaction@20
|
||||
ENgeterror = _ENgeterror@12
|
||||
ENgetflowunits = _ENgetflowunits@4
|
||||
ENgetheadcurveindex = _ENgetheadcurveindex@8
|
||||
ENgetlinkid = _ENgetlinkid@8
|
||||
ENgetlinkindex = _ENgetlinkindex@8
|
||||
ENgetlinknodes = _ENgetlinknodes@12
|
||||
ENsetlinknodes = _ENsetlinknodes@12
|
||||
ENgetlinktype = _ENgetlinktype@8
|
||||
ENgetlinkvalue = _ENgetlinkvalue@12
|
||||
ENgetnodeid = _ENgetnodeid@8
|
||||
ENgetnodeindex = _ENgetnodeindex@8
|
||||
ENgetnodetype = _ENgetnodetype@8
|
||||
ENgetnodevalue = _ENgetnodevalue@12
|
||||
ENgetnumdemands = _ENgetnumdemands@8
|
||||
ENgetoption = _ENgetoption@8
|
||||
ENgetpatternid = _ENgetpatternid@8
|
||||
ENgetpatternindex = _ENgetpatternindex@8
|
||||
ENgetpatternlen = _ENgetpatternlen@8
|
||||
ENgetpatternvalue = _ENgetpatternvalue@12
|
||||
ENgetpremise = _ENgetpremise@36
|
||||
ENgetpumptype = _ENgetpumptype@8
|
||||
ENgetqualinfo = _ENgetqualinfo@16
|
||||
ENgetqualtype = _ENgetqualtype@8
|
||||
ENgetresultindex = _ENgetresultindex@12
|
||||
ENgetrule = _ENgetrule@20
|
||||
ENgetruleID = _ENgetruleID@8
|
||||
ENgetstatistic = _ENgetstatistic@8
|
||||
ENgetthenaction = _ENgetthenaction@20
|
||||
ENgettimeparam = _ENgettimeparam@8
|
||||
ENgettitle = _ENgettitle@12
|
||||
ENgetversion = _ENgetversion@4
|
||||
ENgetvertex = _ENgetvertex@16
|
||||
ENgetvertexcount = _ENgetvertexcount@8
|
||||
ENinit = _ENinit@16
|
||||
ENinitH = _ENinitH@4
|
||||
ENinitQ = _ENinitQ@4
|
||||
ENnextH = _ENnextH@4
|
||||
ENnextQ = _ENnextQ@4
|
||||
ENopen = _ENopen@12
|
||||
ENopenH = _ENopenH@0
|
||||
ENopenQ = _ENopenQ@0
|
||||
ENreport = _ENreport@0
|
||||
ENresetreport = _ENresetreport@0
|
||||
ENrunH = _ENrunH@4
|
||||
ENrunQ = _ENrunQ@4
|
||||
ENsaveH = _ENsaveH@0
|
||||
ENsavehydfile = _ENsavehydfile@4
|
||||
ENsaveinpfile = _ENsaveinpfile@4
|
||||
ENsetbasedemand = _ENsetbasedemand@12
|
||||
ENsetcomment = _ENsetcomment@12
|
||||
ENsetcontrol = _ENsetcontrol@24
|
||||
ENsetcoord = _ENsetcoord@20
|
||||
ENsetcurve = _ENsetcurve@16
|
||||
ENsetcurveid = _ENsetcurveid@8
|
||||
ENsetcurvevalue = _ENsetcurvevalue@16
|
||||
ENsetdemandmodel = _ENsetdemandmodel@16
|
||||
ENsetdemandname = _ENsetdemandname@12
|
||||
ENsetdemandpattern = _ENsetdemandpattern@12
|
||||
ENsetelseaction = _ENsetelseaction@20
|
||||
ENsetflowunits = _ENsetflowunits@4
|
||||
ENsetheadcurveindex = _ENsetheadcurveindex@8
|
||||
ENsetjuncdata = _ENsetjuncdata@16
|
||||
ENsetlinkid = _ENsetlinkid@8
|
||||
ENsetlinknodes = _ENsetlinknodes@12
|
||||
ENsetlinktype = _ENsetlinktype@12
|
||||
ENsetlinkvalue = _ENsetlinkvalue@12
|
||||
ENsetnodeid = _ENsetnodeid@8
|
||||
ENsetnodevalue = _ENsetnodevalue@12
|
||||
ENsetoption = _ENsetoption@8
|
||||
ENsetpattern = _ENsetpattern@12
|
||||
ENsetpatternid = _ENsetpatternid@8
|
||||
ENsetpatternvalue = _ENsetpatternvalue@12
|
||||
ENsetpipedata = _ENsetpipedata@20
|
||||
ENsetpremise = _ENsetpremise@36
|
||||
ENsetpremiseindex = _ENsetpremiseindex@12
|
||||
ENsetpremisestatus = _ENsetpremisestatus@12
|
||||
ENsetpremisevalue = _ENsetpremisevalue@12
|
||||
ENsetqualtype = _ENsetqualtype@16
|
||||
ENsetreport = _ENsetreport@4
|
||||
ENsetrulepriority = _ENsetrulepriority@8
|
||||
ENsetstatusreport = _ENsetstatusreport@4
|
||||
ENsettankdata = _ENsettankdata@32
|
||||
ENsetthenaction = _ENsetthenaction@20
|
||||
ENsettimeparam = _ENsettimeparam@8
|
||||
ENsettitle = _ENsettitle@12
|
||||
ENsetvertices = _ENsetvertices@16
|
||||
ENsolveH = _ENsolveH@0
|
||||
ENsolveQ = _ENsolveQ@0
|
||||
ENstepQ = _ENstepQ@4
|
||||
ENusehydfile = _ENusehydfile@4
|
||||
ENwriteline = _ENwriteline@4
|
||||
1341
include/epanet2.h
Executable file → Normal file
1341
include/epanet2.h
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
423
include/epanet2.pas
Normal file
423
include/epanet2.pas
Normal file
@@ -0,0 +1,423 @@
|
||||
unit epanet2;
|
||||
|
||||
{ Declarations of imported procedures from the EPANET PROGRAMMERs TOOLKIT }
|
||||
{ (EPANET2.DLL) }
|
||||
|
||||
{Last updated on 11/12/19}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
|
||||
{ These are codes used by the DLL functions }
|
||||
EN_MAXID = 31; { Max. # characters in ID name }
|
||||
EN_MAXMSG = 255; { Max. # characters in strings }
|
||||
EN_MISSING = -1.E10;
|
||||
|
||||
EN_ELEVATION = 0; { Node parameters }
|
||||
EN_BASEDEMAND = 1;
|
||||
EN_PATTERN = 2;
|
||||
EN_EMITTER = 3;
|
||||
EN_INITQUAL = 4;
|
||||
EN_SOURCEQUAL = 5;
|
||||
EN_SOURCEPAT = 6;
|
||||
EN_SOURCETYPE = 7;
|
||||
EN_TANKLEVEL = 8;
|
||||
EN_DEMAND = 9;
|
||||
EN_HEAD = 10;
|
||||
EN_PRESSURE = 11;
|
||||
EN_QUALITY = 12;
|
||||
EN_SOURCEMASS = 13;
|
||||
EN_INITVOLUME = 14;
|
||||
EN_MIXMODEL = 15;
|
||||
EN_MIXZONEVOL = 16;
|
||||
|
||||
EN_TANKDIAM = 17;
|
||||
EN_MINVOLUME = 18;
|
||||
EN_VOLCURVE = 19;
|
||||
EN_MINLEVEL = 20;
|
||||
EN_MAXLEVEL = 21;
|
||||
EN_MIXFRACTION = 22;
|
||||
EN_TANK_KBULK = 23;
|
||||
EN_TANKVOLUME = 24;
|
||||
EN_MAXVOLUME = 25;
|
||||
EN_CANOVERFLOW = 26;
|
||||
EN_DEMANDDEFICIT = 27;
|
||||
|
||||
EN_DIAMETER = 0; { Link parameters }
|
||||
EN_LENGTH = 1;
|
||||
EN_ROUGHNESS = 2;
|
||||
EN_MINORLOSS = 3;
|
||||
EN_INITSTATUS = 4;
|
||||
EN_INITSETTING = 5;
|
||||
EN_KBULK = 6;
|
||||
EN_KWALL = 7;
|
||||
EN_FLOW = 8;
|
||||
EN_VELOCITY = 9;
|
||||
EN_HEADLOSS = 10;
|
||||
EN_STATUS = 11;
|
||||
EN_SETTING = 12;
|
||||
EN_ENERGY = 13;
|
||||
EN_LINKQUAL = 14;
|
||||
EN_LINKPATTERN = 15;
|
||||
EN_PUMP_STATE = 16;
|
||||
EN_PUMP_EFFIC = 17;
|
||||
EN_PUMP_POWER = 18;
|
||||
EN_PUMP_HCURVE = 19;
|
||||
EN_PUMP_ECURVE = 20;
|
||||
EN_PUMP_ECOST = 21;
|
||||
EN_PUMP_EPAT = 22;
|
||||
|
||||
EN_DURATION = 0; { Time parameters }
|
||||
EN_HYDSTEP = 1;
|
||||
EN_QUALSTEP = 2;
|
||||
EN_PATTERNSTEP = 3;
|
||||
EN_PATTERNSTART = 4;
|
||||
EN_REPORTSTEP = 5;
|
||||
EN_REPORTSTART = 6;
|
||||
EN_RULESTEP = 7;
|
||||
EN_STATISTIC = 8;
|
||||
EN_PERIODS = 9;
|
||||
EN_STARTTIME = 10;
|
||||
EN_HTIME = 11;
|
||||
EN_QTIME = 12;
|
||||
EN_HALTFLAG = 13;
|
||||
EN_NEXTEVENT = 14;
|
||||
EN_NEXTEVENTTANK = 15;
|
||||
|
||||
EN_ITERATIONS = 0; { Analysis statistics }
|
||||
EN_RELATIVEERROR = 1;
|
||||
EN_MAXHEADERROR = 2;
|
||||
EN_MAXFLOWCHANGE = 3;
|
||||
EN_MASSBALANCE = 4;
|
||||
EN_DEFICIENTNODES = 5;
|
||||
EN_DEMANDREDUCTION = 6;
|
||||
|
||||
EN_NODE = 0; { Component Types }
|
||||
EN_LINK = 1;
|
||||
EN_TIMEPAT = 2;
|
||||
EN_CURVE = 3;
|
||||
EN_CONTROL = 4;
|
||||
EN_RULE = 5;
|
||||
|
||||
EN_NODECOUNT = 0; { Component counts }
|
||||
EN_TANKCOUNT = 1;
|
||||
EN_LINKCOUNT = 2;
|
||||
EN_PATCOUNT = 3;
|
||||
EN_CURVECOUNT = 4;
|
||||
EN_CONTROLCOUNT = 5;
|
||||
EN_RULECOUNT = 6;
|
||||
|
||||
EN_JUNCTION = 0; { Node types }
|
||||
EN_RESERVOIR = 1;
|
||||
EN_TANK = 2;
|
||||
|
||||
EN_CVPIPE = 0; { Link types }
|
||||
EN_PIPE = 1;
|
||||
EN_PUMP = 2;
|
||||
EN_PRV = 3;
|
||||
EN_PSV = 4;
|
||||
EN_PBV = 5;
|
||||
EN_FCV = 6;
|
||||
EN_TCV = 7;
|
||||
EN_GPV = 8;
|
||||
|
||||
EN_CLOSED = 0; { Link status types }
|
||||
EN_OPEN = 1;
|
||||
|
||||
EN_PUMP_XHEAD = 0; { Pump state types }
|
||||
EN_PUMP_CLOSED = 2;
|
||||
EN_PUMP_OPEN = 3;
|
||||
EN_PUMP_XFLOW = 5;
|
||||
|
||||
EN_NONE = 0; { Quality analysis types }
|
||||
EN_CHEM = 1;
|
||||
EN_AGE = 2;
|
||||
EN_TRACE = 3;
|
||||
|
||||
EN_CONCEN = 0; { Source quality types }
|
||||
EN_MASS = 1;
|
||||
EN_SETPOINT = 2;
|
||||
EN_FLOWPACED = 3;
|
||||
|
||||
EN_HW = 0; { Head loss formulas }
|
||||
EN_DW = 1;
|
||||
EN_CM = 2;
|
||||
|
||||
EN_CFS = 0; { Flow units types }
|
||||
EN_GPM = 1;
|
||||
EN_MGD = 2;
|
||||
EN_IMGD = 3;
|
||||
EN_AFD = 4;
|
||||
EN_LPS = 5;
|
||||
EN_LPM = 6;
|
||||
EN_MLD = 7;
|
||||
EN_CMH = 8;
|
||||
EN_CMD = 9;
|
||||
|
||||
EN_DDA = 0; { Demand model types }
|
||||
EN_PDA = 1;
|
||||
|
||||
EN_TRIALS = 0; { Option types }
|
||||
EN_ACCURACY = 1;
|
||||
EN_TOLERANCE = 2;
|
||||
EN_EMITEXPON = 3;
|
||||
EN_DEMANDMULT = 4;
|
||||
EN_HEADERROR = 5;
|
||||
EN_FLOWCHANGE = 6;
|
||||
EN_HEADLOSSFORM = 7;
|
||||
EN_GLOBALEFFIC = 8;
|
||||
EN_GLOBALPRICE = 9;
|
||||
EN_GLOBALPATTERN = 10;
|
||||
EN_DEMANDCHARGE = 11;
|
||||
EN_SP_GRAVITY = 12;
|
||||
EN_SP_VISCOS = 13;
|
||||
EN_EXTRA_ITER = 14;
|
||||
EN_CHECKFREQ = 15;
|
||||
EN_MAXCHECK = 16;
|
||||
EN_DAMPLIMIT = 17;
|
||||
EN_SP_DIFFUS = 18;
|
||||
EN_BULKORDER = 19;
|
||||
EN_WALLORDER = 20;
|
||||
EN_TANKORDER = 21;
|
||||
EN_CONCENLIMIT = 22;
|
||||
|
||||
EN_LOWLEVEL = 0; { Control types }
|
||||
EN_HILEVEL = 1;
|
||||
EN_TIMER = 2;
|
||||
EN_TIMEOFDAY = 3;
|
||||
|
||||
EN_SERIES = 0; { Report statistic types }
|
||||
EN_AVERAGE = 1;
|
||||
EN_MINIMUM = 2;
|
||||
EN_MAXIMUM = 3;
|
||||
EN_RANGE = 4;
|
||||
|
||||
EN_MIX1 = 0; { Tank mixing models }
|
||||
EN_MIX2 = 1;
|
||||
EN_FIFO = 2;
|
||||
EN_LIFO = 3;
|
||||
|
||||
EN_NOSAVE = 0; { Hydraulics flags }
|
||||
EN_SAVE = 1;
|
||||
EN_INITFLOW = 10;
|
||||
EN_SAVE_AND_INIT = 11;
|
||||
|
||||
EN_CONST_HP = 0; { Pump curve types }
|
||||
EN_POWER_FUNC = 1;
|
||||
EN_CUSTOM = 2;
|
||||
EN_NOCURVE = 3;
|
||||
|
||||
EN_VOLUME_CURVE = 0; { Curve types }
|
||||
EN_PUMP_CURVE = 1;
|
||||
EN_EFFIC_CURVE = 2;
|
||||
EN_HLOSS_CURVE = 3;
|
||||
EN_GENERIC_CURVE = 4;
|
||||
|
||||
EN_UNCONDITIONAL = 0; { Deletion action codes }
|
||||
EN_CONDITIONAL = 1;
|
||||
|
||||
EN_NO_REPORT = 0; { Status reporting levels }
|
||||
EN_NORMAL_REPORT = 1;
|
||||
EN_FULL_REPORT = 2;
|
||||
|
||||
EN_R_NODE = 6; { Rule-based control objects }
|
||||
EN_R_LINK = 7;
|
||||
EN_R_SYSTEM = 8;
|
||||
|
||||
EN_R_DEMAND = 0; { Rule-based control variables }
|
||||
EN_R_HEAD = 1;
|
||||
EN_R_GRADE = 2;
|
||||
EN_R_LEVEL = 3;
|
||||
EN_R_PRESSURE = 4;
|
||||
EN_R_FLOW = 5;
|
||||
EN_R_STATUS = 6;
|
||||
EN_R_SETTING = 7;
|
||||
EN_R_POWER = 8;
|
||||
EN_R_TIME = 9;
|
||||
EN_R_CLOCKTIME = 10;
|
||||
EN_R_FILLTIME = 11;
|
||||
EN_R_DRAINTIME = 12;
|
||||
|
||||
EN_R_EQ = 0; { Rule-based control operators }
|
||||
EN_R_NE = 1;
|
||||
EN_R_LE = 2;
|
||||
EN_R_GE = 3;
|
||||
EN_R_LT = 4;
|
||||
EN_R_GT = 5;
|
||||
EN_R_IS = 6;
|
||||
EN_R_NOT = 7;
|
||||
EN_R_BELOW = 8;
|
||||
EN_R_ABOVE = 9;
|
||||
|
||||
EN_R_IS_OPEN = 1; { Rule-based control link status }
|
||||
EN_R_IS_CLOSED = 2;
|
||||
EN_R_IS_ACTIVE = 3;
|
||||
|
||||
EpanetLib = 'epanet2.dll';
|
||||
|
||||
{Project Functions}
|
||||
function ENepanet(F1: PAnsiChar; F2: PAnsiChar; F3: PAnsiChar; F4: Pointer): Integer; stdcall; external EpanetLib;
|
||||
function ENinit(F2: PAnsiChar; F3: PAnsiChar; UnitsType: Integer; HeadlossType: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENopen(F1: PAnsiChar; F2: PAnsiChar; F3: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcount(Code: Integer; var Count: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgettitle(Line1: PAnsiChar; Line2: PAnsiChar; Line3: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsettitle(Line1: PAnsiChar; Line2: PAnsiChar; Line3: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcomment(ObjType: Integer; Index: Integer; Comment: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetcomment(ObjType: Integer; Index: Integer; Comment: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsaveinpfile(F: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENclose: Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Hydraulic Functions}
|
||||
function ENsolveH: Integer; stdcall; external EpanetLib;
|
||||
function ENsaveH: Integer; stdcall; external EpanetLib;
|
||||
function ENopenH: Integer; stdcall; external EpanetLib;
|
||||
function ENinitH(SaveFlag: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENrunH(var T: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENnextH(var Tstep: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENcloseH: Integer; stdcall; external EpanetLib;
|
||||
function ENsavehydfile(F: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENusehydfile(F: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Quality Functions}
|
||||
function ENsolveQ: Integer; stdcall; external EpanetLib;
|
||||
function ENopenQ: Integer; stdcall; external EpanetLib;
|
||||
function ENinitQ(SaveFlag: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENrunQ(var T: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENnextQ(var Tstep: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENstepQ(var Tleft: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENcloseQ: Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Reporting Functions}
|
||||
function ENwriteline(S: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENreport: Integer; stdcall; external EpanetLib;
|
||||
function ENcopyreport(F: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENclearreport: Integer; stdcall; external EpanetLib;
|
||||
function ENresetreport: Integer; stdcall; external EpanetLib;
|
||||
function ENsetreport(S: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetstatusreport(Code: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetversion(var Version: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgeterror(Errcode: Integer; Errmsg: PAnsiChar; MaxLen: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetstatistic(StatType: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetresultindex(Code: Integer; Index: Integer; var Value: Integer): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Analysis Options Functions}
|
||||
function ENgetoption(Code: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetoption(Code: Integer; Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetflowunits(var Code: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetflowunits(Code: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgettimeparam(Code: Integer; var Value: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENsettimeparam(Code: Integer; Value: LongInt): Integer; stdcall; external EpanetLib;
|
||||
function ENgetqualinfo(var QualType: Integer; ChemName: PAnsiChar; ChemUnits: PAnsiChar; var TraceNode: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetqualtype(var QualCode: Integer; var TraceNode: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetqualtype(QualCode: Integer; ChemName: PAnsiChar; ChemUnits: PAnsiChar; TraceNodeID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Node Functions}
|
||||
function ENaddnode(ID: PAnsiChar; NodeType: Integer; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENdeletenode(Index: Integer; ActionCode: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetnodeindex(ID: PAnsiChar; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetnodeid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetnodeid(Index: Integer; NewID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetnodetype(Index: Integer; var Code: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetnodevalue(Index: Integer; Code: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetnodevalue(Index: Integer; Code: Integer; Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetjuncdata(Index: Integer; Elev: Single; Dmnd: Single; DmndPat: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsettankdata(Index: Integer; Elev, InitLvl, MinLvl, MaxLvl, Diam, MinVol: Single; VolCurve: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcoord(Index: Integer; var X: Double; var Y: Double): Integer; stdcall; external EpanetLib;
|
||||
function ENsetcoord(Index: Integer; X: Double; Y: Double): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Demand Functions}
|
||||
function ENgetdemandmodel(var Model: Integer; var Pmin: Single; var Preq: Single; var Pexp: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetdemandmodel(Model: Integer; Pmin: Single; Preq: Single; Pexp: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetnumdemands(NodeIndex: Integer; var NumDemands: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENadddemand(NodeIndex: Integer; BaseDemand: Single; PatName: PAnsiChar; DemandName: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENdeletedemand(NodeIndex: Integer; DemandIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetdemandindex(NodeIndex: Integer; DemandName: PAnsiChar; var DemandIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetbasedemand(NodeIndex: Integer; DemandIndex: Integer; var BaseDemand: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetbasedemand(NodeIndex: Integer; DemandIndex: Integer; BaseDemand: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetdemandpattern(NodeIndex: Integer; DemandIndex: Integer; var PatIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetdemandpattern(NodeIndex: Integer; DemandIndex: Integer; PatIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetdemandname(NodeIndex: Integer; DemandIndex: Integer; DemandName: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetdemandname(NodeIndex: Integer; DemandIndex: Integer; DemandName: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Link Functions}
|
||||
function ENaddlink(ID: PAnsiChar; LinkType: Integer; FromNode: PAnsiChar; ToNode: PAnsiChar; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENdeletelink(Index: Integer; ActionCode: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetlinkindex(ID: PAnsiChar; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetlinkid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetlinkid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetlinktype(Index: Integer; var Code: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetlinktype(var Index: Integer; LinkType: Integer; ActionCode: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetlinknodes(Index: Integer; var Node1: Integer; var Node2: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetlinknodes(Index: Integer; Node1: Integer; Node2: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetlinkvalue(Index: Integer; Code: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetlinkvalue(Index: Integer; Code: Integer; Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpipedata(Index: Integer; Length: Single; Diam: Single; Rough: Single; Mloss:Single): Integer; stdcall; external EpanetLib;
|
||||
|
||||
function ENgetvertexcount(Index: Integer; var Count: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetvertex(Index: Integer; Vertex: Integer; var X: Double; var Y: Double): Integer; stdcall; external EpanetLib;
|
||||
function ENsetvertices(Index: Integer; var X: Double; var Y: Double; Count: Integer): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Pump Functions}
|
||||
function ENgetpumptype(LinkIndex: Integer; var PumpType: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetheadcurveindex(LinkIndex: Integer; var CurveIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetheadcurveindex(LinkIndex: Integer; CurveIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Pattern Functions}
|
||||
function ENaddpattern(ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENdeletepattern(Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetpatternindex(ID: PAnsiChar; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetpatternid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpatternid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetpatternlen(Index: Integer; var Len: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetpatternvalue(Index: Integer; Period: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpatternvalue(Index: Integer; Period: Integer; Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetaveragepatternvalue(Index: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpattern(Index: Integer; var F: Single; N: Integer): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Curve Functions}
|
||||
function ENaddcurve(ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENdeletecurve(Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcurveindex(ID: PAnsiChar; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcurveid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetcurveid(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcurvelen(Index: Integer; var Len: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcurvetype(Index: Integer; var CurveType: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcurvevalue(CurveIndex: Integer; PointIndex: Integer; var X: Single; var Y: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetcurvevalue(CurveIndex: Integer; PointIndex: Integer; X: Single; Y: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcurve(Index: Integer; ID: PAnsiChar; var N: Integer; var X: Single; var Y: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetcurve(Index: Integer; var X: Single; var Y: Single; N: Integer): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Control Functions}
|
||||
function ENaddcontrol(Ctype: Integer; Link: Integer; Setting: Single; Node: Integer; Level: Single; var Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENdeletecontrol(Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetcontrol(Index: Integer; var Ctype: Integer; var Link: Integer; var Setting: Single; var Node: Integer; var Level: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetcontrol(Index: Integer; Ctype: Integer; Link: Integer; Setting: Single; Node: Integer; Level: Single): Integer; stdcall; external EpanetLib;
|
||||
|
||||
{Rule-Based Control Functions}
|
||||
function ENaddrule(Rule: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENdeleterule(Index: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENgetrule(Index: Integer; var Npremises: Integer; var NthenActions: Integer;
|
||||
var NelseActions: Integer; var Priority: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetruleID(Index: Integer; ID: PAnsiChar): Integer; stdcall; external EpanetLib;
|
||||
function ENsetrulepriority(Index: Integer; Priority: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetpremise(RuleIndex: Integer; PremiseIndex: Integer; var LogOp: Integer;
|
||||
var ObjType: Integer; var ObjIndex: Integer; var Param: Integer; var RelOp: Integer;
|
||||
var Status: Integer; var Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpremise(RuleIndex: Integer; PremiseIndex: Integer; LogOp: Integer; ObjType: Integer;
|
||||
ObjIndex: Integer; Param: Integer; RelOp: Integer; Status: Integer; Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpremiseindex(RuleIndex: Integer; PremiseIndex: Integer; ObjIndex: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpremisestatus(RuleIndex: Integer; PremiseIndex: Integer; Status: Integer): Integer; stdcall; external EpanetLib;
|
||||
function ENsetpremisevalue(RuleIndex: Integer; PremiseIndex: Integer; Value: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetthenaction(RuleIndex: Integer; ActionIndex: Integer; var LinkIndex: Integer;
|
||||
var Status: Integer; var Setting: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetthenaction(RuleIndex: Integer; ActionIndex: Integer; LinkIndex: Integer;
|
||||
Status: Integer; Setting: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENgetelseaction(RuleIndex: Integer; ActionIndex: Integer; var LinkIndex: Integer;
|
||||
var Status: Integer; var Setting: Single): Integer; stdcall; external EpanetLib;
|
||||
function ENsetelseaction(RuleIndex: Integer; ActionIndex: Integer; LinkIndex: Integer;
|
||||
Status: Integer; Setting: Single): Integer; stdcall; external EpanetLib;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
@@ -4,7 +4,7 @@
|
||||
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
|
||||
'(EPANET2.DLL) for use with VB.Net.
|
||||
|
||||
'Last updated on 7/19/15 - LR
|
||||
'Last updated on 11/04/2019
|
||||
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Text
|
||||
@@ -38,7 +38,10 @@ Public Const EN_MAXLEVEL = 21
|
||||
Public Const EN_MIXFRACTION = 22
|
||||
Public Const EN_TANK_KBULK = 23
|
||||
|
||||
Public Const EN_TANKVOLUME = 24 'ES
|
||||
Public Const EN_TANKVOLUME = 24
|
||||
Public Const EN_MAXVOLUME = 25
|
||||
Public Const EN_CANOVERFLOW = 26
|
||||
Public Const EN_DEMANDDEFICIT = 27
|
||||
|
||||
Public Const EN_DIAMETER = 0 ' Link parameters
|
||||
Public Const EN_LENGTH = 1
|
||||
@@ -54,9 +57,17 @@ Public Const EN_HEADLOSS = 10
|
||||
Public Const EN_STATUS = 11
|
||||
Public Const EN_SETTING = 12
|
||||
Public Const EN_ENERGY = 13
|
||||
Public Const EN_LINKQUAL = 14 'ES
|
||||
Public Const EN_LINKQUAL = 14
|
||||
Public Const EN_LINKPATTERN = 15
|
||||
|
||||
Public Const EN_PUMP_STATE = 16
|
||||
Public Const EN_PUMP_EFFIC = 17
|
||||
Public Const EN_PUMP_POWER = 18
|
||||
Public Const EN_PUMP_HCURVE = 19
|
||||
Public Const EN_PUMP_ECURVE = 20
|
||||
Public Const EN_PUMP_ECOST = 21
|
||||
Public Const EN_PUMP_EPAT = 22
|
||||
|
||||
Public Const EN_DURATION = 0 ' Time parameters
|
||||
Public Const EN_HYDSTEP = 1
|
||||
Public Const EN_QUALSTEP = 2
|
||||
@@ -67,7 +78,26 @@ Public Const EN_REPORTSTART = 6
|
||||
Public Const EN_RULESTEP = 7
|
||||
Public Const EN_STATISTIC = 8
|
||||
Public Const EN_PERIODS = 9
|
||||
Public Const EN_STARTTIME = 10 'ES
|
||||
Public Const EN_STARTTIME = 10
|
||||
Public Const EN_HTIME = 11
|
||||
Public Const EN_QTIME = 12
|
||||
Public Const EN_HALTFLAG = 13
|
||||
Public Const EN_NEXTEVENT = 14
|
||||
|
||||
Public Const EN_ITERATIONS = 0
|
||||
Public Const EN_RELATIVEERROR = 1
|
||||
Public Const EN_MAXHEADERROR = 2
|
||||
Public Const EN_MAXFLOWCHANGE = 3
|
||||
Public Const EN_MASSBALANCE = 4
|
||||
Public Const EN_DEFICIENTNODES = 5
|
||||
Public Const EN_DEMANDREDUCTION = 6
|
||||
|
||||
Public Const EN_NODE = 0 ' Component types
|
||||
Public Const EN_LINK = 1
|
||||
Public Const EN_TIMEPAT = 2
|
||||
Public Const EN_CURVE = 3
|
||||
Public Const EN_CONTROL = 4
|
||||
Public Const EN_RULE = 5
|
||||
|
||||
Public Const EN_NODECOUNT = 0 'Component counts
|
||||
Public Const EN_TANKCOUNT = 1
|
||||
@@ -75,6 +105,7 @@ Public Const EN_LINKCOUNT = 2
|
||||
Public Const EN_PATCOUNT = 3
|
||||
Public Const EN_CURVECOUNT = 4
|
||||
Public Const EN_CONTROLCOUNT = 5
|
||||
Public Const EN_RULECOUNT = 6
|
||||
|
||||
Public Const EN_JUNCTION = 0 ' Node types
|
||||
Public Const EN_RESERVOIR = 1
|
||||
@@ -100,6 +131,10 @@ Public Const EN_MASS = 1
|
||||
Public Const EN_SETPOINT = 2
|
||||
Public Const EN_FLOWPACED = 3
|
||||
|
||||
Public Const EN_HW = 0 ' Head loss formulas
|
||||
Public Const EN_DW = 1
|
||||
Public Const EN_CM = 2
|
||||
|
||||
Public Const EN_CFS = 0 ' Flow units types
|
||||
Public Const EN_GPM = 1
|
||||
Public Const EN_MGD = 2
|
||||
@@ -111,118 +146,257 @@ Public Const EN_MLD = 7
|
||||
Public Const EN_CMH = 8
|
||||
Public Const EN_CMD = 9
|
||||
|
||||
Public Const EN_TRIALS = 0 ' Misc. options
|
||||
Public Const EN_DDA = 0 ' Demand driven analysis
|
||||
Public Const EN_PDA = 1 ' Pressure driven analysis
|
||||
|
||||
Public Const EN_TRIALS = 0 ' Simulation options
|
||||
Public Const EN_ACCURACY = 1
|
||||
Public Const EN_TOLERANCE = 2
|
||||
Public Const EN_EMITEXPON = 3
|
||||
Public Const EN_DEMANDMULT = 4
|
||||
Public Const EN_HEADERROR = 5
|
||||
Public Const EN_FLOWCHANGE = 6
|
||||
Public Const EN_HEADLOSSFORM = 7
|
||||
Public Const EN_GLOBALEFFIC = 8
|
||||
Public Const EN_GLOBALPRICE = 9
|
||||
Public Const EN_GLOBALPATTERN = 10
|
||||
Public Const EN_DEMANDCHARGE = 11
|
||||
Public Const EN_SP_GRAVITY = 12
|
||||
Public Const EN_SP_VISCOS = 13
|
||||
Public Const EN_UNBALANCED = 14
|
||||
Public Const EN_CHECKFREQ = 15
|
||||
Public Const EN_MAXCHECK = 16
|
||||
Public Const EN_DAMPLIMIT = 17
|
||||
Public Const EN_SP_DIFFUS = 18
|
||||
Public Const EN_BULKORDER = 19
|
||||
Public Const EN_WALLORDER = 20
|
||||
Public Const EN_TANKORDER = 21
|
||||
Public Const EN_CONCENLIMIT = 22
|
||||
|
||||
Public Const EN_LOWLEVEL = 0 ' Control types
|
||||
Public Const EN_LOWLEVEL = 0 ' Control types
|
||||
Public Const EN_HILEVEL = 1
|
||||
Public Const EN_TIMER = 2
|
||||
Public Const EN_TIMEOFDAY = 3
|
||||
|
||||
Public Const EN_AVERAGE = 1 'Time statistic types
|
||||
Public Const EN_AVERAGE = 1 ' Time statistic types
|
||||
Public Const EN_MINIMUM = 2
|
||||
Public Const EN_MAXIMUM = 3
|
||||
Public Const EN_RANGE = 4
|
||||
|
||||
Public Const EN_MIX1 = 0 'Tank mixing models
|
||||
Public Const EN_MIX1 = 0 ' Tank mixing models
|
||||
Public Const EN_MIX2 = 1
|
||||
Public Const EN_FIFO = 2
|
||||
Public Const EN_LIFO = 3
|
||||
|
||||
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
|
||||
Public Const EN_NOSAVE = 0 ' Save-results-to-file flag
|
||||
Public Const EN_SAVE = 1
|
||||
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
|
||||
Public Const EN_INITFLOW = 10 ' Re-initialize flow flag
|
||||
Public Const EN_SAVE_AND_INIT = 11
|
||||
|
||||
Public Const EN_CONST_HP = 0 ' constant horsepower
|
||||
Public Const EN_POWER_FUNC = 1 ' power function
|
||||
Public Const EN_CUSTOM = 2 ' user-defined custom curve
|
||||
Public Const EN_CONST_HP = 0 ' Constant horsepower pump curve
|
||||
Public Const EN_POWER_FUNC = 1 ' Power function pump curve
|
||||
Public Const EN_CUSTOM = 2 ' User-defined custom pump curve
|
||||
Public Const EN_NOCURVE = 3 ' No pump curve
|
||||
|
||||
Public Const EN_VOLUME_CURVE = 0 ' Volume curve
|
||||
Public Const EN_PUMP_CURVE = 1 ' Pump curve
|
||||
Public Const EN_EFFIC_CURVE = 2 ' Efficiency curve
|
||||
Public Const EN_HLOSS_CURVE = 3 ' Head loss curve
|
||||
Public Const EN_GENERIC_CURVE = 4 ' Generic curve
|
||||
|
||||
Public Const EN_UNCONDITIONAL = 0 ' Unconditional object deletion
|
||||
Public Const EN_CONDITIONAL = 1 ' Conditional object deletion
|
||||
|
||||
Public Const EN_NO_REPORT = 0 ' No status report
|
||||
Public Const EN_NORMAL_REPORT = 1 ' Normal status report
|
||||
Public Const EN_FULL_REPORT = 2 ' Full status report
|
||||
|
||||
Public Const EN_R_NODE = 6 ' Rule objects
|
||||
Public Const EN_R_LINK = 7
|
||||
Public Const EN_R_SYSTEM = 8
|
||||
|
||||
Public Const EN_R_DEMAND = 0 ' Rule variables
|
||||
Public Const EN_R_HEAD = 1
|
||||
Public Const EN_R_GRADE = 2
|
||||
Public Const EN_R_LEVEL = 3
|
||||
Public Const EN_R_PRESSURE = 4
|
||||
Public Const EN_R_FLOW = 5
|
||||
Public Const EN_R_STATUS = 6
|
||||
Public Const EN_R_SETTING = 7
|
||||
Public Const EN_R_POWER = 8
|
||||
Public Const EN_R_TIME = 9
|
||||
Public Const EN_R_CLOCKTIME = 10
|
||||
Public Const EN_R_FILLTIME = 11
|
||||
Public Const EN_R_DRAINTIME = 12
|
||||
|
||||
Public Const EN_R_EQ = 0 ' Rule operators
|
||||
Public Const EN_R_NE = 1
|
||||
Public Const EN_R_LE = 2
|
||||
Public Const EN_R_GE = 3
|
||||
Public Const EN_R_LT = 4
|
||||
Public Const EN_R_GT = 5
|
||||
Public Const EN_R_IS = 6
|
||||
Public Const EN_R_NOT = 7
|
||||
Public Const EN_R_BELOW = 8
|
||||
Public Const EN_R_ABOVE = 9
|
||||
|
||||
Public Const EN_R_IS_OPEN = 1 ' Rule status types
|
||||
Public Const EN_R_IS_CLOSED = 2
|
||||
Public Const EN_R_IS_ACTIVE = 3
|
||||
|
||||
Public Const EN_MISSING As Double = -1.0E10
|
||||
|
||||
'These are the external functions that comprise the DLL
|
||||
|
||||
Declare Function ENepanet Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String, ByVal F4 As String) As Int32
|
||||
Declare Function ENopen Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String) As Int32
|
||||
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal F As String) As Int32
|
||||
'Project Functions
|
||||
Declare Function ENgetversion Lib "epanet2.dll" (value As Int32) As Int32
|
||||
Declare Function ENepanet Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String, ByVal pviewprog As Any) As Int32
|
||||
Declare Function ENinit Lib "epanet2.dll" (ByVal rptFile As String, ByVal outFile As String, ByVal unitsType As Int32, ByVal headlossType As Int32) As Int32
|
||||
Declare Function ENopen Lib "epanet2.dll" (ByVal inpFile As String, ByVal rptFile As String, ByVal outFile As String) As Int32
|
||||
Declare Function ENgettitle Lib "epanet2.dll" (ByVal titleline1 As String, ByVal titleline2 As String, ByVal titleline3 As String) As Int32
|
||||
Declare Function ENsettitle Lib "epanet2.dll" (ByVal titleline1 As String, ByVal titleline2 As String, ByVal titleline3 As String) As Int32
|
||||
Declare Function ENsaveinpfile Lib "epanet2.dll" (ByVal filename As String) As Int32
|
||||
Declare Function ENclose Lib "epanet2.dll" () As Int32
|
||||
|
||||
'Hydraulic Analysis Functions
|
||||
Declare Function ENsolveH Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENsaveH Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENopenH Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENinitH Lib "epanet2.dll" (ByVal SaveFlag As Int32) As Int32
|
||||
Declare Function ENrunH Lib "epanet2.dll" (ByRef T As Int32) As Int32
|
||||
Declare Function ENnextH Lib "epanet2.dll" (ByRef Tstep As Int32) As Int32
|
||||
Declare Function ENinitH Lib "epanet2.dll" (ByVal initFlag As Int32) As Int32
|
||||
Declare Function ENrunH Lib "epanet2.dll" (currentTime As Int32) As Int32
|
||||
Declare Function ENnextH Lib "epanet2.dll" (tStep As Int32) As Int32
|
||||
Declare Function ENcloseH Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal F As String) As Int32
|
||||
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal F As String) As Int32
|
||||
Declare Function ENsavehydfile Lib "epanet2.dll" (ByVal filename As String) As Int32
|
||||
Declare Function ENusehydfile Lib "epanet2.dll" (ByVal filename As String) As Int32
|
||||
|
||||
'Water Quality Analysis Functions
|
||||
Declare Function ENsolveQ Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENopenQ Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENinitQ Lib "epanet2.dll" (ByVal SaveFlag As Int32) As Int32
|
||||
Declare Function ENrunQ Lib "epanet2.dll" (ByRef T As Int32) As Int32
|
||||
Declare Function ENnextQ Lib "epanet2.dll" (ByRef Tstep As Int32) As Int32
|
||||
Declare Function ENstepQ Lib "epanet2.dll" (ByRef Tleft As Int32) As Int32
|
||||
Declare Function ENinitQ Lib "epanet2.dll" (ByVal saveFlag As Int32) As Int32
|
||||
Declare Function ENrunQ Lib "epanet2.dll" (currentTime As Int32) As Int32
|
||||
Declare Function ENnextQ Lib "epanet2.dll" (tStep As Int32) As Int32
|
||||
Declare Function ENstepQ Lib "epanet2.dll" (timeLeft As Int32) As Int32
|
||||
Declare Function ENcloseQ Lib "epanet2.dll" () As Int32
|
||||
|
||||
Declare Function ENwriteline Lib "epanet2.dll" (ByVal S As String) As Int32
|
||||
'Reporting Functions
|
||||
Declare Function ENwriteline Lib "epanet2.dll" (ByVal line As String) As Int32
|
||||
Declare Function ENreport Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENcopyreport Lib "epanet2.dll" (ByVal filename As String) As Int32
|
||||
Declare Function ENclearreport Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENresetreport Lib "epanet2.dll" () As Int32
|
||||
Declare Function ENsetreport Lib "epanet2.dll" (ByVal S As String) As Int32
|
||||
Declare Function ENsetreport Lib "epanet2.dll" (ByVal format As String) As Int32
|
||||
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal level As Int32) As Int32
|
||||
Declare Function ENgetcount Lib "epanet2.dll" (ByVal object As Int32, count As Int32) As Int32
|
||||
Declare Function ENgeterror Lib "epanet2.dll" (ByVal errcode As Int32, ByVal errmsg As String, ByVal maxLen As Int32) As Int32
|
||||
Declare Function ENgetstatistic Lib "epanet2.dll" (ByVal type_ As Int32, ByRef value As Single) As Int32
|
||||
Declare Function ENgetresultindex Lib "epanet2.dll" (ByVal type_ As Int32, ByVal index As Int32, ByRef value As Int32) As Int32
|
||||
|
||||
'Analysis Options Functions
|
||||
Declare Function ENgetoption Lib "epanet2.dll" (ByVal option As Int32, value As Single) As Int32
|
||||
Declare Function ENsetoption Lib "epanet2.dll" (ByVal option As Int32, ByVal value As Single) As Int32
|
||||
Declare Function ENgetflowunits Lib "epanet2.dll" (units As Int32) As Int32
|
||||
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal units As Int32) As Int32
|
||||
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal param As Int32, value As Int32) As Int32
|
||||
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal param As Int32, ByVal value As Int32) As Int32
|
||||
Declare Function ENgetqualinfo Lib "epanet2.dll" (qualType As Int32, ByVal chemName As String, ByVal chemUnits As String, traceNode As Int32) As Int32
|
||||
Declare Function ENgetqualtype Lib "epanet2.dll" (qualType As Int32, traceNode As Int32) As Int32
|
||||
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal qualType As Int32, ByVal chemName As String, ByVal chemUnits As String, ByVal traceNode As String) As Int32
|
||||
|
||||
'Node Functions
|
||||
Declare Function ENaddnode Lib "epanet2.dll" (ByVal id As String, ByVal nodeType As Int32, Index As Int32) As Int32
|
||||
Declare Function ENdeletenode Lib "epanet2.dll" (ByVal index As Int32, ByVal actionCode As Int32) As Int32
|
||||
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
|
||||
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
|
||||
Declare Function ENsetnodeid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
|
||||
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal index As Int32, nodeType As Int32) As Int32
|
||||
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, value As Single) As Int32
|
||||
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, ByVal value As Single) As Int32
|
||||
Declare Function ENsetjuncdata Lib "epanet2.dll" (ByVal index As Int32, ByVal elev As Single, ByVal dmnd As Single, ByVal dmndpat As String) As Int32
|
||||
Declare Function ENsettankdata Lib "epanet2.dll" (ByVal index As Int32, ByVal elev As Single, ByVal initlvl As Single, ByVal minlvl As Single, ByVal maxlvl As Single, ByVal diam As Single, ByVal minvol As Single, ByVal volcurve As String) As Int32
|
||||
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal index As Int32, x As Double, y As Double) As Int32
|
||||
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal index As Int32, ByVal x As Double, ByVal y As Double) As Int32
|
||||
|
||||
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal Cindex As Int32, ByRef CtlType As Int32, ByRef Lindex As Int32, ByRef Setting As Single, ByRef Nindex As Int32, ByRef Level As Single) As Int32
|
||||
Declare Function ENgetcount Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Int32) As Int32
|
||||
Declare Function ENgetoption Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Single) As Int32
|
||||
Declare Function ENgettimeparam Lib "epanet2.dll" (ByVal Code As Int32, ByRef Value As Int32) As Int32
|
||||
Declare Function ENgetflowunits Lib "epanet2.dll" (ByRef Code As Int32) As Int32
|
||||
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
|
||||
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
|
||||
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal Index As Int32, ByRef L As Int32) As Int32
|
||||
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Period As Int32, ByRef Value As Single) As Int32
|
||||
Declare Function ENgetqualtype Lib "epanet2.dll" (ByRef QualCode As Int32, ByRef TraceNode As Int32) As Int32
|
||||
Declare Function ENgeterror Lib "epanet2.dll" (ByVal ErrCode As Int32, ByVal ErrMsg As StringBuilder, ByVal N As Int32)
|
||||
'Nodal Demand Functions
|
||||
Declare Function ENgetdemandmodel Lib "epanet2.dll" (type_ As Int32, pmin As Single, preq As Single, pexp As Single) As Int32
|
||||
Declare Function ENsetdemandmodel Lib "epanet2.dll" (ByVal type_ As Int32, ByVal pmin As Single, ByVal preq As Single, ByVal pexp As Single) As Int32
|
||||
Declare Function ENadddemand Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal baseDemand As Single, ByVal patternName As String, ByVal demandName As String) As Int32
|
||||
Declare Function ENdeletedemand Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32) As Int32
|
||||
Declare Function ENgetdemandindex Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandName As String, demandIndex As Int32) As Int32
|
||||
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal nodeIndex As Int32, numDemands As Int32) As Int32
|
||||
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, value As Single) As Int32
|
||||
Declare Function ENsetbasedemand Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal BaseDemand As Single) As Int32
|
||||
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, patIndex As Int32) As Int32
|
||||
Declare Function ENsetdemandpattern Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal patIndex As Int32) As Int32
|
||||
Declare Function ENgetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal demandName As String) As Int32
|
||||
Declare Function ENsetdemandname Lib "epanet2.dll" (ByVal nodeIndex As Int32, ByVal demandIndex As Int32, ByVal demandName As String) As Int32
|
||||
|
||||
Declare Function ENgetnodeindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
|
||||
Declare Function ENgetnodeid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
|
||||
Declare Function ENgetnodetype Lib "epanet2.dll" (ByVal Index As Int32, ByRef Code As Int32) As Int32
|
||||
Declare Function ENgetnodevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByRef Value As Single) As Int32
|
||||
Declare Function ENgetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByRef X As Single, ByRef Y As Single) As Int32
|
||||
Declare Function ENsetcoord Lib "epanet2.dll" (ByVal Index As Int32, ByVal X As Single, ByVal Y As Single) As Int32
|
||||
'Link Functions
|
||||
Declare Function ENaddlink Lib "epanet2.dll" (ByVal id As String, ByVal linkType As Int32, ByVal fromNode As String, ByVal toNode As String, Index As Int32) As Int32
|
||||
Declare Function ENdeletelink Lib "epanet2.dll" (ByVal index As Int32, ByVal actionCode As Int32) As Int32
|
||||
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
|
||||
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
|
||||
Declare Function ENsetlinkid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
|
||||
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal index As Int32, linkType As Int32) As Int32
|
||||
Declare Function ENsetlinktype Lib "epanet2.dll" (index As Int32, ByVal linkType As Int32, ByVal actionCode As Int32) As Int32
|
||||
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal index As Int32, node1 As Int32, node2 As Int32) As Int32
|
||||
Declare Function ENsetlinknodes Lib "epanet2.dll" (ByVal index As Int32, ByVal node1 As Int32, ByVal node2 As Int32) As Int32
|
||||
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, value As Single) As Int32
|
||||
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal property As Int32, ByVal value As Single) As Int32
|
||||
Declare Function ENsetpipedata Lib "epanet2.dll" (ByVal index As Int32, ByVal length As Single, ByVal diam As Single, ByVal rough As Single, ByVal mloss As Single) As Int32
|
||||
Declare Function ENgetvertexcount Lib "epanet2.dll" (ByVal index As Int32, count As Int32) As Int32
|
||||
Declare Function ENgetvertex Lib "epanet2.dll" (ByVal index As Int32, ByVal vertex As Int32, x As Double, y As Double) As Int32
|
||||
Declare Function ENsetvertices Lib "epanet2.dll" (ByVal index As Int32, xCoords As Any, yCoords As Any, ByVal count As Int32) As Int32
|
||||
|
||||
Declare Function ENgetnumdemands Lib "epanet2.dll" (ByVal Index As Int32, ByRef numDemands As Int32) As Int32 'ES
|
||||
Declare Function ENgetbasedemand Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef Value As Single) As Int32 'ES
|
||||
Declare Function ENgetdemandpattern Lib "epanet2.dll" (ByVal Index As Int32, ByVal DemandIndex As Int32, ByRef PatIndex As Int32) As Int32 'ES
|
||||
'Pump Functions
|
||||
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Int32, curveIndex As Int32) As Int32
|
||||
Declare Function ENsetheadcurveindex Lib "epanet2.dll" (ByVal linkIndex As Int32, ByVal curveIndex As Int32) As Int32
|
||||
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal linkIndex As Int32, pumpType As Int32) As Int32
|
||||
|
||||
Declare Function ENgetlinkindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
|
||||
Declare Function ENgetlinkid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
|
||||
Declare Function ENgetlinktype Lib "epanet2.dll" (ByVal Index As Int32, ByRef Code As Int32) As Int32
|
||||
Declare Function ENgetlinknodes Lib "epanet2.dll" (ByVal Index As Int32, ByRef Node1 As Int32, ByRef Node2 As Int32) As Int32
|
||||
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByRef Value As Single) As Int32
|
||||
'Time Pattern Functions
|
||||
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal id As String) As Int32
|
||||
Declare Function ENdeletepattern Lib "epanet2.dll" (ByVal index As Int32) As Int32
|
||||
Declare Function ENgetpatternindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
|
||||
Declare Function ENgetpatternid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
|
||||
Declare Function ENsetpatternid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
|
||||
Declare Function ENgetpatternlen Lib "epanet2.dll" (ByVal index As Int32, len_ As Int32) As Int32
|
||||
Declare Function ENgetpatternvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal period As Int32, value As Single) As Int32
|
||||
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal index As Int32, ByVal period As Int32, ByVal value As Single) As Int32
|
||||
Declare Function ENgetaveragepatternvalue Lib "epanet2.dll" (ByVal index As Int32, value As Single) As Int32
|
||||
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal index As Int32, values As Any, ByVal len_ As Int32) As Int32
|
||||
|
||||
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal CurveIndex As Int32, ByRef nValues As Int32, ByRef xValues As Single, ByRef yValues As Single) As Int32 'ES
|
||||
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal Index As Int32, ByVal CurveIndex As int32) As Int32 'ES
|
||||
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal Index As Int32, ByRef PumpType As Int32) As Int32 'ES
|
||||
'Data Curve Functions
|
||||
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal id As String) As Int32
|
||||
Declare Function ENdeletecurve Lib "epanet2.dll" (ByVal index As Int32) As Int32
|
||||
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal id As String, index As Int32) As Int32
|
||||
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
|
||||
Declare Function ENsetcurveid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
|
||||
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal index As Int32, len_ As Int32) As Int32
|
||||
Declare Function ENgetcurvetype Lib "epanet2.dll" (ByVal index As Int32, type_ As Int32) As Int32
|
||||
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Int32, ByVal pointIndex As Int32, x As Single, y As Single) As Int32
|
||||
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal curveIndex As Int32, ByVal pointIndex As Int32, ByVal x As Single, ByVal y As Single) As Int32
|
||||
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String, nPoints As Int32, xValues As Any, yValues As Any) As Int32
|
||||
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal index As Int32, xValues As Any, yValues As Any, ByVal nPoints As Int32) As Int32
|
||||
|
||||
Declare Function ENgetversion Lib "epanet2.dll" (ByRef Value As Int32) As Int32
|
||||
'Simple Control Functions
|
||||
Declare Function ENaddcontrol Lib "epanet2.dll" (ByVal type_ As Int32, ByVal linkIndex As Int32, ByVal setting As Single, ByVal nodeIndex As Int32, ByVal level As Single, index As Int32) As Int32
|
||||
Declare Function ENdeletecontrol Lib "epanet2.dll" (ByVal index As Int32) As Int32
|
||||
Declare Function ENgetcontrol Lib "epanet2.dll" (ByVal index As Int32, type_ As Int32, linkIndex As Int32, setting As Single, nodeIndex As Int32, level As Single) As Int32
|
||||
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal index As Int32, ByVal type_ As Int32, ByVal linkIndex As Int32, ByVal setting As Single, ByVal nodeIndex As Int32, ByVal level As Single) As Int32
|
||||
|
||||
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal Cindex As Int32, ByVal CtlType As Int32, ByVal Lindex As Int32, ByVal Setting As Single, ByVal Nindex As Int32, ByVal Level As Single) As Int32
|
||||
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByVal Value As Single) As Int32
|
||||
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByVal Value As Single) As Int32
|
||||
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal Index as Int32, ByRef F as Single, ByVal N as Int32) as Int32
|
||||
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Period As Int32, ByVal Value As Single) As Int32
|
||||
Declare Function ENsettimeparam Lib "epanet2.dll" (ByVal Code As Int32, ByVal Value As Int32) As Int32
|
||||
Declare Function ENsetoption Lib "epanet2.dll" (ByVal Code As Int32, ByVal Value As Single) As Int32
|
||||
Declare Function ENsetstatusreport Lib "epanet2.dll" (ByVal Code As Int32) As Int32
|
||||
Declare Function ENsetqualtype Lib "epanet2.dll" (ByVal QualCode As Int32, ByVal ChemName As String, ByVal ChemUnits As String, ByVal TraceNode As String) As Int32
|
||||
|
||||
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal ID As String) As Int32
|
||||
'Rule-Based Control Functions
|
||||
Declare Function ENaddrule Lib "epanet2.dll" (ByVal rule As String) As Int32
|
||||
Declare Function ENdeleterule Lib "epanet2.dll" (ByVal index As Int32) As Int32
|
||||
Declare Function ENgetrule Lib "epanet2.dll" (ByVal index As Int32, nPremises As Int32, nThenActions As Int32, nElseActions As Int32, priority As Single) As Int32
|
||||
Declare Function ENgetruleID Lib "epanet2.dll" (ByVal index As Int32, ByVal id As String) As Int32
|
||||
Declare Function ENsetrulepriority Lib "epanet2.dll" (ByVal index As Int32, ByVal priority As Single) As Int32
|
||||
Declare Function ENgetpremise Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, logop As Int32, object As Int32, objIndex As Int32, variable As Int32, relop As Int32, status As Int32, value As Single) As Int32
|
||||
Declare Function ENsetpremise Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal logop As Int32, ByVal object As Int32, ByVal objIndex As Int32, ByVal variable As Int32, ByVal relop As Int32, ByVal status As Int32, ByVal value As Single) As Int32
|
||||
Declare Function ENsetpremiseindex Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal objIndex As Int32) As Int32
|
||||
Declare Function ENsetpremisestatus Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal status As Int32) As Int32
|
||||
Declare Function ENsetpremisevalue Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal premiseIndex As Int32, ByVal value As Single) As Int32
|
||||
Declare Function ENgetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, linkIndex As Int32, status As Int32, setting As Single) As Int32
|
||||
Declare Function ENsetthenaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, ByVal linkIndex As Int32, ByVal status As Int32, ByVal setting As Single) As Int32
|
||||
Declare Function ENgetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, linkIndex As Int32, status As Int32, setting As Single) As Int32
|
||||
Declare Function ENsetelseaction Lib "epanet2.dll" (ByVal ruleIndex As Int32, ByVal actionIndex As Int32, ByVal linkIndex As Int32, ByVal status As Int32, ByVal setting As Single) As Int32
|
||||
|
||||
Declare Function ENgetcurveindex Lib "epanet2.dll" (ByVal ID As String, ByRef Index As Int32) As Int32
|
||||
Declare Function ENgetcurveid Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32
|
||||
Declare Function ENgetcurvelen Lib "epanet2.dll" (ByVal Index As Int32, ByRef L As Int32) As Int32
|
||||
Declare Function ENgetcurvevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Pnt As Int32, ByRef X As Single, ByRef Y As Single) As Int32
|
||||
Declare Function ENsetcurvevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Pnt As Int32, ByVal X As Single, ByVal Y As Single) As Int32
|
||||
Declare Function ENsetcurve Lib "epanet2.dll" (ByVal Index as Int32, ByRef X as Single, ByRef Y as Single, ByVal N as Int32) as Int32
|
||||
Declare Function ENaddcurve Lib "epanet2.dll" (ByVal ID As String) As Int32
|
||||
|
||||
End Module
|
||||
|
||||
1786
include/epanet2_2.h
Normal file
1786
include/epanet2_2.h
Normal file
File diff suppressed because it is too large
Load Diff
468
include/epanet2_enums.h
Normal file
468
include/epanet2_enums.h
Normal file
@@ -0,0 +1,468 @@
|
||||
/** @file epanet2_enums.h
|
||||
*/
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: epanet2_enums.h
|
||||
Description: enumerations of symbolic constants used by the API functions
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 11/06/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EPANET2_ENUMS_H
|
||||
#define EPANET2_ENUMS_H
|
||||
|
||||
|
||||
// --- Define the EPANET toolkit constants
|
||||
|
||||
/// Size Limts
|
||||
/**
|
||||
Limits on the size of character arrays used to store ID names
|
||||
and text messages.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_MAXID = 31, //!< Max. # characters in ID name
|
||||
EN_MAXMSG = 255 //!< Max. # characters in message text
|
||||
} EN_SizeLimits;
|
||||
|
||||
/// Node properties
|
||||
/**
|
||||
These node properties are used with @ref EN_getnodevalue and @ref EN_setnodevalue.
|
||||
Those marked as read only are computed values that can only be retrieved.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_ELEVATION = 0, //!< Elevation
|
||||
EN_BASEDEMAND = 1, //!< Primary demand baseline value
|
||||
EN_PATTERN = 2, //!< Primary demand time pattern index
|
||||
EN_EMITTER = 3, //!< Emitter flow coefficient
|
||||
EN_INITQUAL = 4, //!< Initial quality
|
||||
EN_SOURCEQUAL = 5, //!< Quality source strength
|
||||
EN_SOURCEPAT = 6, //!< Quality source pattern index
|
||||
EN_SOURCETYPE = 7, //!< Quality source type (see @ref EN_SourceType)
|
||||
EN_TANKLEVEL = 8, //!< Current computed tank water level (read only)
|
||||
EN_DEMAND = 9, //!< Current computed demand (read only)
|
||||
EN_HEAD = 10, //!< Current computed hydraulic head (read only)
|
||||
EN_PRESSURE = 11, //!< Current computed pressure (read only)
|
||||
EN_QUALITY = 12, //!< Current computed quality (read only)
|
||||
EN_SOURCEMASS = 13, //!< Current computed quality source mass inflow (read only)
|
||||
EN_INITVOLUME = 14, //!< Tank initial volume (read only)
|
||||
EN_MIXMODEL = 15, //!< Tank mixing model (see @ref EN_MixingModel)
|
||||
EN_MIXZONEVOL = 16, //!< Tank mixing zone volume (read only)
|
||||
EN_TANKDIAM = 17, //!< Tank diameter
|
||||
EN_MINVOLUME = 18, //!< Tank minimum volume
|
||||
EN_VOLCURVE = 19, //!< Tank volume curve index
|
||||
EN_MINLEVEL = 20, //!< Tank minimum level
|
||||
EN_MAXLEVEL = 21, //!< Tank maximum level
|
||||
EN_MIXFRACTION = 22, //!< Tank mixing fraction
|
||||
EN_TANK_KBULK = 23, //!< Tank bulk decay coefficient
|
||||
EN_TANKVOLUME = 24, //!< Current computed tank volume (read only)
|
||||
EN_MAXVOLUME = 25, //!< Tank maximum volume (read only)
|
||||
EN_CANOVERFLOW = 26, //!< Tank can overflow (= 1) or not (= 0)
|
||||
EN_DEMANDDEFICIT = 27 //!< Amount that full demand is reduced under PDA (read only)
|
||||
} EN_NodeProperty;
|
||||
|
||||
/// Link properties
|
||||
/**
|
||||
These link properties are used with @ref EN_getlinkvalue and @ref EN_setlinkvalue.
|
||||
Those marked as read only are computed values that can only be retrieved.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_DIAMETER = 0, //!< Pipe/valve diameter
|
||||
EN_LENGTH = 1, //!< Pipe length
|
||||
EN_ROUGHNESS = 2, //!< Pipe roughness coefficient
|
||||
EN_MINORLOSS = 3, //!< Pipe/valve minor loss coefficient
|
||||
EN_INITSTATUS = 4, //!< Initial status (see @ref EN_LinkStatusType)
|
||||
EN_INITSETTING = 5, //!< Initial pump speed or valve setting
|
||||
EN_KBULK = 6, //!< Bulk chemical reaction coefficient
|
||||
EN_KWALL = 7, //!< Pipe wall chemical reaction coefficient
|
||||
EN_FLOW = 8, //!< Current computed flow rate (read only)
|
||||
EN_VELOCITY = 9, //!< Current computed flow velocity (read only)
|
||||
EN_HEADLOSS = 10, //!< Current computed head loss (read only)
|
||||
EN_STATUS = 11, //!< Current link status (see @ref EN_LinkStatusType)
|
||||
EN_SETTING = 12, //!< Current link setting
|
||||
EN_ENERGY = 13, //!< Current computed pump energy usage (read only)
|
||||
EN_LINKQUAL = 14, //!< Current computed link quality (read only)
|
||||
EN_LINKPATTERN = 15, //!< Pump speed time pattern index
|
||||
EN_PUMP_STATE = 16, //!< Current computed pump state (read only) (see @ref EN_PumpStateType)
|
||||
EN_PUMP_EFFIC = 17, //!< Current computed pump efficiency (read only)
|
||||
EN_PUMP_POWER = 18, //!< Pump constant power rating
|
||||
EN_PUMP_HCURVE = 19, //!< Pump head v. flow curve index
|
||||
EN_PUMP_ECURVE = 20, //!< Pump efficiency v. flow curve index
|
||||
EN_PUMP_ECOST = 21, //!< Pump average energy price
|
||||
EN_PUMP_EPAT = 22 //!< Pump energy price time pattern index
|
||||
} EN_LinkProperty;
|
||||
|
||||
/// Time parameters
|
||||
/**
|
||||
These time-related options are used with @ref EN_gettimeparam and@ref EN_settimeparam.
|
||||
All times are expressed in seconds The parameters marked as read only are
|
||||
computed values that can only be retrieved.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_DURATION = 0, //!< Total simulation duration
|
||||
EN_HYDSTEP = 1, //!< Hydraulic time step
|
||||
EN_QUALSTEP = 2, //!< Water quality time step
|
||||
EN_PATTERNSTEP = 3, //!< Time pattern period
|
||||
EN_PATTERNSTART = 4, //!< Time when time patterns begin
|
||||
EN_REPORTSTEP = 5, //!< Reporting time step
|
||||
EN_REPORTSTART = 6, //!< Time when reporting starts
|
||||
EN_RULESTEP = 7, //!< Rule-based control evaluation time step
|
||||
EN_STATISTIC = 8, //!< Reporting statistic code (see @ref EN_StatisticType)
|
||||
EN_PERIODS = 9, //!< Number of reporting time periods (read only)
|
||||
EN_STARTTIME = 10, //!< Simulation starting time of day
|
||||
EN_HTIME = 11, //!< Elapsed time of current hydraulic solution (read only)
|
||||
EN_QTIME = 12, //!< Elapsed time of current quality solution (read only)
|
||||
EN_HALTFLAG = 13, //!< Flag indicating if the simulation was halted (read only)
|
||||
EN_NEXTEVENT = 14, //!< Shortest time until a tank becomes empty or full (read only)
|
||||
EN_NEXTEVENTTANK = 15 //!< Index of tank with shortest time to become empty or full (read only)
|
||||
} EN_TimeParameter;
|
||||
|
||||
/// Analysis convergence statistics
|
||||
/**
|
||||
These statistics report the convergence criteria for the most current hydraulic analysis
|
||||
and the cumulative water quality mass balance error at the current simulation time. They
|
||||
can be retrieved with @ref EN_getstatistic.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_ITERATIONS = 0, //!< Number of hydraulic iterations taken
|
||||
EN_RELATIVEERROR = 1, //!< Sum of link flow changes / sum of link flows
|
||||
EN_MAXHEADERROR = 2, //!< Largest head loss error for links
|
||||
EN_MAXFLOWCHANGE = 3, //!< Largest flow change in links
|
||||
EN_MASSBALANCE = 4, //!< Cumulative water quality mass balance ratio
|
||||
EN_DEFICIENTNODES = 5, //!< Number of pressure deficient nodes
|
||||
EN_DEMANDREDUCTION = 6 //!< % demand reduction at pressure deficient nodes
|
||||
} EN_AnalysisStatistic;
|
||||
|
||||
/// Types of network objects
|
||||
/**
|
||||
The types of objects that comprise a network model.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_NODE = 0, //!< Nodes
|
||||
EN_LINK = 1, //!< Links
|
||||
EN_TIMEPAT = 2, //!< Time patterns
|
||||
EN_CURVE = 3, //!< Data curves
|
||||
EN_CONTROL = 4, //!< Simple controls
|
||||
EN_RULE = 5 //!< Control rules
|
||||
} EN_ObjectType;
|
||||
|
||||
/// Types of objects to count
|
||||
/**
|
||||
These options tell @ref EN_getcount which type of object to count.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_NODECOUNT = 0, //!< Number of nodes (junctions + tanks + reservoirs)
|
||||
EN_TANKCOUNT = 1, //!< Number of tanks and reservoirs
|
||||
EN_LINKCOUNT = 2, //!< Number of links (pipes + pumps + valves)
|
||||
EN_PATCOUNT = 3, //!< Number of time patterns
|
||||
EN_CURVECOUNT = 4, //!< Number of data curves
|
||||
EN_CONTROLCOUNT = 5, //!< Number of simple controls
|
||||
EN_RULECOUNT = 6 //!< Number of rule-based controls
|
||||
} EN_CountType;
|
||||
|
||||
/// Node Types
|
||||
/**
|
||||
These are the different types of nodes that can be returned by calling @ref EN_getnodetype.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_JUNCTION = 0, //!< Junction node
|
||||
EN_RESERVOIR = 1, //!< Reservoir node
|
||||
EN_TANK = 2 //!< Storage tank node
|
||||
} EN_NodeType;
|
||||
|
||||
/// Link types
|
||||
/**
|
||||
These are the different types of links that can be returned by calling @ref EN_getlinktype.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_CVPIPE = 0, //!< Pipe with check valve
|
||||
EN_PIPE = 1, //!< Pipe
|
||||
EN_PUMP = 2, //!< Pump
|
||||
EN_PRV = 3, //!< Pressure reducing valve
|
||||
EN_PSV = 4, //!< Pressure sustaining valve
|
||||
EN_PBV = 5, //!< Pressure breaker valve
|
||||
EN_FCV = 6, //!< Flow control valve
|
||||
EN_TCV = 7, //!< Throttle control valve
|
||||
EN_GPV = 8 //!< General purpose valve
|
||||
} EN_LinkType;
|
||||
|
||||
/// Link status
|
||||
/**
|
||||
One of these values is returned when @ref EN_getlinkvalue is used to retrieve a link's
|
||||
initial status ( \b EN_INITSTATUS ) or its current status ( \b EN_STATUS ). These options are
|
||||
also used with @ref EN_setlinkvalue to set values for these same properties.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_CLOSED = 0,
|
||||
EN_OPEN = 1
|
||||
} EN_LinkStatusType;
|
||||
|
||||
/// Pump states
|
||||
/**
|
||||
One of these codes is returned when @ref EN_getlinkvalue is used to retrieve a pump's
|
||||
current operating state ( \b EN_PUMP_STATE ). \b EN_PUMP_XHEAD indicates that the pump has been
|
||||
shut down because it is being asked to deliver more than its shutoff head. \b EN_PUMP_XFLOW
|
||||
indicates that the pump is being asked to deliver more than its maximum flow.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_PUMP_XHEAD = 0, //!< Pump closed - cannot supply head
|
||||
EN_PUMP_CLOSED = 2, //!< Pump closed
|
||||
EN_PUMP_OPEN = 3, //!< Pump open
|
||||
EN_PUMP_XFLOW = 5 //!< Pump open - cannot supply flow
|
||||
} EN_PumpStateType;
|
||||
|
||||
/// Types of water quality analyses
|
||||
/**
|
||||
These are the different types of water quality analyses that EPANET can run. They
|
||||
are used with @ref EN_getqualinfo, @ref EN_getqualtype, and @ref EN_setqualtype.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_NONE = 0, //!< No quality analysis
|
||||
EN_CHEM = 1, //!< Chemical fate and transport
|
||||
EN_AGE = 2, //!< Water age analysis
|
||||
EN_TRACE = 3 //!< Source tracing analysis
|
||||
} EN_QualityType;
|
||||
|
||||
/// Water quality source types
|
||||
/**
|
||||
These are the different types of external water quality sources that can be assigned
|
||||
to a node's \b EN_SOURCETYPE property as used by @ref EN_getnodevalue and @ref EN_setnodevalue.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_CONCEN = 0, //!< Sets the concentration of external inflow entering a node
|
||||
EN_MASS = 1, //!< Injects a given mass/minute into a node
|
||||
EN_SETPOINT = 2, //!< Sets the concentration leaving a node to a given value
|
||||
EN_FLOWPACED = 3 //!< Adds a given value to the concentration leaving a node
|
||||
} EN_SourceType;
|
||||
|
||||
/// Head loss formulas
|
||||
/**
|
||||
The available choices for the \b EN_HEADLOSSFORM option in @ref EN_getoption and
|
||||
@ref EN_setoption. They are also used for the head loss type argument in @ref EN_init.
|
||||
Each head loss formula uses a different type of roughness coefficient ( \b EN_ROUGHNESS )
|
||||
that can be set with @ref EN_setlinkvalue.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_HW = 0, //!< Hazen-Williams
|
||||
EN_DW = 1, //!< Darcy-Weisbach
|
||||
EN_CM = 2 //!< Chezy-Manning
|
||||
} EN_HeadLossType;
|
||||
|
||||
/// Flow units
|
||||
/**
|
||||
These choices for flow units are used with @ref EN_getflowunits and @ref EN_setflowunits.
|
||||
They are also used for the flow units type argument in @ref EN_init. If flow units are
|
||||
expressed in US Customary units ( \b EN_CFS through \b EN_AFD ) then all other quantities are
|
||||
in US Customary units. Otherwise they are in metric units.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_CFS = 0, //!< Cubic feet per second
|
||||
EN_GPM = 1, //!< Gallons per minute
|
||||
EN_MGD = 2, //!< Million gallons per day
|
||||
EN_IMGD = 3, //!< Imperial million gallons per day
|
||||
EN_AFD = 4, //!< Acre-feet per day
|
||||
EN_LPS = 5, //!< Liters per second
|
||||
EN_LPM = 6, //!< Liters per minute
|
||||
EN_MLD = 7, //!< Million liters per day
|
||||
EN_CMH = 8, //!< Cubic meters per hour
|
||||
EN_CMD = 9 //!< Cubic meters per day
|
||||
} EN_FlowUnits;
|
||||
|
||||
/// Demand models
|
||||
/**
|
||||
These choices for modeling consumer demands are used with @ref EN_getdemandmodel
|
||||
and @ref EN_setdemandmodel.
|
||||
|
||||
A demand driven analysis requires that a junction's full demand be supplied
|
||||
in each time period independent of how much pressure is available. A pressure
|
||||
driven analysis makes demand be a power function of pressure, up to the point
|
||||
where the full demand is met.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_DDA = 0, //!< Demand driven analysis
|
||||
EN_PDA = 1 //!< Pressure driven analysis
|
||||
} EN_DemandModel;
|
||||
|
||||
/// Simulation options
|
||||
/**
|
||||
These constants identify the hydraulic and water quality simulation options
|
||||
that are applied on a network-wide basis. They are accessed using the
|
||||
@ref EN_getoption and @ref EN_setoption functions.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_TRIALS = 0, //!< Maximum trials allowed for hydraulic convergence
|
||||
EN_ACCURACY = 1, //!< Total normalized flow change for hydraulic convergence
|
||||
EN_TOLERANCE = 2, //!< Water quality tolerance
|
||||
EN_EMITEXPON = 3, //!< Exponent in emitter discharge formula
|
||||
EN_DEMANDMULT = 4, //!< Global demand multiplier
|
||||
EN_HEADERROR = 5, //!< Maximum head loss error for hydraulic convergence
|
||||
EN_FLOWCHANGE = 6, //!< Maximum flow change for hydraulic convergence
|
||||
EN_HEADLOSSFORM = 7, //!< Head loss formula (see @ref EN_HeadLossType)
|
||||
EN_GLOBALEFFIC = 8, //!< Global pump efficiency (percent)
|
||||
EN_GLOBALPRICE = 9, //!< Global energy price per KWH
|
||||
EN_GLOBALPATTERN = 10, //!< Index of a global energy price pattern
|
||||
EN_DEMANDCHARGE = 11, //!< Energy charge per max. KW usage
|
||||
EN_SP_GRAVITY = 12, //!< Specific gravity
|
||||
EN_SP_VISCOS = 13, //!< Specific viscosity (relative to water at 20 deg C)
|
||||
EN_UNBALANCED = 14, //!< Extra trials allowed if hydraulics don't converge
|
||||
EN_CHECKFREQ = 15, //!< Frequency of hydraulic status checks
|
||||
EN_MAXCHECK = 16, //!< Maximum trials for status checking
|
||||
EN_DAMPLIMIT = 17, //!< Accuracy level where solution damping begins
|
||||
EN_SP_DIFFUS = 18, //!< Specific diffusivity (relative to chlorine at 20 deg C)
|
||||
EN_BULKORDER = 19, //!< Bulk water reaction order for pipes
|
||||
EN_WALLORDER = 20, //!< Wall reaction order for pipes (either 0 or 1)
|
||||
EN_TANKORDER = 21, //!< Bulk water reaction order for tanks
|
||||
EN_CONCENLIMIT = 22 //!< Limiting concentration for growth reactions
|
||||
} EN_Option;
|
||||
|
||||
/// Simple control types
|
||||
/**
|
||||
These are the different types of simple (single statement) controls that can be applied
|
||||
to network links. They are used as an argument to @ref EN_addcontrol,@ref EN_getcontrol,
|
||||
and @ref EN_setcontrol.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_LOWLEVEL = 0, //!< Act when pressure or tank level drops below a setpoint
|
||||
EN_HILEVEL = 1, //!< Act when pressure or tank level rises above a setpoint
|
||||
EN_TIMER = 2, //!< Act at a prescribed elapsed amount of time
|
||||
EN_TIMEOFDAY = 3 //!< Act at a particular time of day
|
||||
} EN_ControlType;
|
||||
|
||||
/// Reporting statistic choices
|
||||
/**
|
||||
These options determine what kind of statistical post-processing should be done on
|
||||
the time series of simulation results generated before they are reported using
|
||||
@ref EN_report. An option can be chosen by using \b STATISTIC _option_ as the argument
|
||||
to @ref EN_setreport.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_SERIES = 0, //!< Report all time series points
|
||||
EN_AVERAGE = 1, //!< Report average value over simulation period
|
||||
EN_MINIMUM = 2, //!< Report minimum value over simulation period
|
||||
EN_MAXIMUM = 3, //!< Report maximum value over simulation period
|
||||
EN_RANGE = 4 //!< Report maximum - minimum over simulation period
|
||||
} EN_StatisticType;
|
||||
|
||||
/// Tank mixing models
|
||||
/**
|
||||
These are the different types of models that describe water quality mixing in storage tanks.
|
||||
The choice of model is accessed with the \b EN_MIXMODEL property of a Tank node using
|
||||
@ref EN_getnodevalue and @ref EN_setnodevalue.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_MIX1 = 0, //!< Complete mix model
|
||||
EN_MIX2 = 1, //!< 2-compartment model
|
||||
EN_FIFO = 2, //!< First in, first out model
|
||||
EN_LIFO = 3 //!< Last in, first out model
|
||||
} EN_MixingModel;
|
||||
|
||||
/// Hydraulic initialization options
|
||||
/**
|
||||
These options are used to initialize a new hydraulic analysis when @ref EN_initH is called.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_NOSAVE = 0, //!< Don't save hydraulics; don't re-initialize flows
|
||||
EN_SAVE = 1, //!< Save hydraulics to file, don't re-initialize flows
|
||||
EN_INITFLOW = 10, //!< Don't save hydraulics; re-initialize flows
|
||||
EN_SAVE_AND_INIT = 11 //!< Save hydraulics; re-initialize flows
|
||||
} EN_InitHydOption;
|
||||
|
||||
/// Types of pump curves
|
||||
/**
|
||||
@ref EN_getpumptype returns one of these values when it is called.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_CONST_HP = 0, //!< Constant horsepower
|
||||
EN_POWER_FUNC = 1, //!< Power function
|
||||
EN_CUSTOM = 2, //!< User-defined custom curve
|
||||
EN_NOCURVE = 3 //!< No curve
|
||||
} EN_PumpType;
|
||||
|
||||
/// Types of data curves
|
||||
/**
|
||||
These are the different types of physical relationships that a data curve can
|
||||
represent as returned by calling @ref EN_getcurvetype.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_VOLUME_CURVE = 0, //!< Tank volume v. depth curve
|
||||
EN_PUMP_CURVE = 1, //!< Pump head v. flow curve
|
||||
EN_EFFIC_CURVE = 2, //!< Pump efficiency v. flow curve
|
||||
EN_HLOSS_CURVE = 3, //!< Valve head loss v. flow curve
|
||||
EN_GENERIC_CURVE = 4 //!< Generic curve
|
||||
} EN_CurveType;
|
||||
|
||||
/// Deletion action codes
|
||||
/**
|
||||
These codes are used in @ref EN_deletenode and @ref EN_deletelink to indicate what action
|
||||
should be taken if the node or link being deleted appears in any simple or rule-based
|
||||
controls or if a deleted node has any links connected to it.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_UNCONDITIONAL = 0, //!< Delete all controls and connecing links
|
||||
EN_CONDITIONAL = 1 //!< Cancel object deletion if it appears in controls or has connecting links
|
||||
} EN_ActionCodeType;
|
||||
|
||||
/// Status reporting levels
|
||||
/**
|
||||
These choices specify the level of status reporting written to a project's report
|
||||
file during a hydraulic analysis. The level is set using the @ref EN_setstatusreport function.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_NO_REPORT = 0, //!< No status reporting
|
||||
EN_NORMAL_REPORT = 1, //!< Normal level of status reporting
|
||||
EN_FULL_REPORT = 2 //!< Full level of status reporting
|
||||
} EN_StatusReport;
|
||||
|
||||
/// Network objects used in rule-based controls
|
||||
typedef enum {
|
||||
EN_R_NODE = 6, //!< Clause refers to a node
|
||||
EN_R_LINK = 7, //!< Clause refers to a link
|
||||
EN_R_SYSTEM = 8 //!< Clause refers to a system parameter (e.g., time)
|
||||
} EN_RuleObject;
|
||||
|
||||
/// Object variables used in rule-based controls
|
||||
typedef enum {
|
||||
EN_R_DEMAND = 0, //!< Nodal demand
|
||||
EN_R_HEAD = 1, //!< Nodal hydraulic head
|
||||
EN_R_GRADE = 2, //!< Nodal hydraulic grade
|
||||
EN_R_LEVEL = 3, //!< Tank water level
|
||||
EN_R_PRESSURE = 4, //!< Nodal pressure
|
||||
EN_R_FLOW = 5, //!< Link flow rate
|
||||
EN_R_STATUS = 6, //!< Link status
|
||||
EN_R_SETTING = 7, //!< Link setting
|
||||
EN_R_POWER = 8, //!< Pump power output
|
||||
EN_R_TIME = 9, //!< Elapsed simulation time
|
||||
EN_R_CLOCKTIME = 10, //!< Time of day
|
||||
EN_R_FILLTIME = 11, //!< Time to fill a tank
|
||||
EN_R_DRAINTIME = 12 //!< Time to drain a tank
|
||||
} EN_RuleVariable;
|
||||
|
||||
/// Comparison operators used in rule-based controls
|
||||
typedef enum {
|
||||
EN_R_EQ = 0, //!< Equal to
|
||||
EN_R_NE = 1, //!< Not equal
|
||||
EN_R_LE = 2, //!< Less than or equal to
|
||||
EN_R_GE = 3, //!< Greater than or equal to
|
||||
EN_R_LT = 4, //!< Less than
|
||||
EN_R_GT = 5, //!< Greater than
|
||||
EN_R_IS = 6, //!< Is equal to
|
||||
EN_R_NOT = 7, //!< Is not equal to
|
||||
EN_R_BELOW = 8, //!< Is below
|
||||
EN_R_ABOVE = 9 //!< Is above
|
||||
} EN_RuleOperator;
|
||||
|
||||
/// Link status codes used in rule-based controls
|
||||
typedef enum {
|
||||
EN_R_IS_OPEN = 1, //!< Link is open
|
||||
EN_R_IS_CLOSED = 2, //!< Link is closed
|
||||
EN_R_IS_ACTIVE = 3 //!< Control valve is active
|
||||
} EN_RuleStatus;
|
||||
|
||||
#define EN_MISSING -1.E10 //!< Missing value indicator
|
||||
|
||||
#endif //EPANET2_ENUMS_H
|
||||
33
run/CMakeLists.txt
Normal file
33
run/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
# EPANET COMMAND LINE EXECUTABLE
|
||||
cmake_minimum_required (VERSION 2.8.8)
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
# Link to multi-threaded static runtime library
|
||||
IF (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -MT)
|
||||
ENDIF (MSVC)
|
||||
|
||||
|
||||
# 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 epanet2 m)
|
||||
else(NOT WIN32)
|
||||
target_link_libraries(runepanet LINK_PUBLIC epanet2)
|
||||
endif(NOT WIN32)
|
||||
180
run/main.c
180
run/main.c
@@ -1,133 +1,93 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "epanet2.h"
|
||||
|
||||
#define MAXMSG 79 /* Max. # characters in message text */
|
||||
#define MAXWARNCODE 99
|
||||
/* text copied here, no more need of include "text.h" */
|
||||
#define FMT01 "\nEPANET Version %d.%d.%d\n"
|
||||
#define FMT03 "\n Correct syntax is:\n epanet <input file> <output file>\n"
|
||||
#define FMT09 "\nEPANET completed.\n"
|
||||
#define FMT10 "\nEPANET completed. There are warnings."
|
||||
#define FMT11 "\nEPANET completed. There are errors."
|
||||
|
||||
|
||||
void writeConsole(char *s);
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------
|
||||
Entry point used to compile a stand-alone executable.
|
||||
----------------------------------------------------------------
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: main.c
|
||||
Description: main stub for a command line executable version of EPANET
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 12/07/2018
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "epanet2.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
void writeConsole(char *s)
|
||||
{
|
||||
fprintf(stdout, "\r%s", s);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
/*--------------------------------------------------------------
|
||||
** Input: argc = number of command line arguments
|
||||
** *argv[] = array of command line arguments
|
||||
** Output: none
|
||||
** Purpose: main program segment
|
||||
** Purpose: main program stub for command line EPANET
|
||||
**
|
||||
** Command line for stand-alone operation is:
|
||||
** progname f1 f2 f3
|
||||
** where progname = name of executable this code was compiled to,
|
||||
** f1 = name of input file,
|
||||
** f2 = name of report file (optional, stdout if left blank)
|
||||
** f3 = name of binary output file (optional, nullfile if left blank).
|
||||
** f2 = name of report file
|
||||
** f3 = name of binary output file (optional).
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
char *f1,*f2,*f3;
|
||||
char blank[] = "";
|
||||
char errmsg[MAXMSG+1]="";
|
||||
int errcode;
|
||||
int version;
|
||||
char s[25];
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
|
||||
/* get version from DLL and trasform in Major.Minor.Patch format
|
||||
instead of hardcoded version */
|
||||
ENgetversion(&version);
|
||||
major= version/10000;
|
||||
minor= (version%10000)/100;
|
||||
patch= version%100;
|
||||
sprintf(s,FMT01, major , minor, patch);
|
||||
writeConsole(s);
|
||||
char *f1,*f2,*f3;
|
||||
char blank[] = "";
|
||||
char errmsg[256] = "";
|
||||
int errcode;
|
||||
int version;
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
|
||||
// Check for proper number of command line arguments
|
||||
if (argc < 3)
|
||||
{
|
||||
printf(
|
||||
"\nUsage:\n %s <input_filename> <report_filename> [<binary_filename>]\n",
|
||||
argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get version number and display in Major.Minor.Patch format
|
||||
ENgetversion(&version);
|
||||
major = version/10000;
|
||||
minor = (version%10000)/100;
|
||||
patch = version%100;
|
||||
printf("\n... Running EPANET Version %d.%d.%d\n", major, minor, patch);
|
||||
|
||||
/* Check for proper number of command line arguments */
|
||||
if (argc < 2) {
|
||||
writeConsole(FMT03);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* set inputfile name */
|
||||
f1 = argv[1];
|
||||
if (argc > 2) {
|
||||
/* set rptfile name */
|
||||
// Assign pointers to file names
|
||||
f1 = argv[1];
|
||||
f2 = argv[2];
|
||||
}
|
||||
else {
|
||||
/* use stdout for rptfile */
|
||||
f2 = blank;
|
||||
}
|
||||
if (argc > 3) {
|
||||
/* set binary output file name */
|
||||
f3 = argv[3];
|
||||
}
|
||||
else {
|
||||
/* NO binary output*/
|
||||
f3 = blank;
|
||||
}
|
||||
if (argc > 3) f3 = argv[3];
|
||||
else f3 = blank;
|
||||
|
||||
/* Call the main control function */
|
||||
if (strlen(f2)> 0) {
|
||||
/* use stdout for progress messages */
|
||||
errcode = ENepanet(f1,f2,f3,writeConsole);
|
||||
}
|
||||
else {
|
||||
/* use stdout for reporting, no progress messages */
|
||||
errcode = ENepanet(f1,f2,f3,NULL);
|
||||
}
|
||||
// Run EPANET
|
||||
errcode = ENepanet(f1, f2, f3, &writeConsole);
|
||||
|
||||
/* Error/Warning check */
|
||||
if (errcode == 0) {
|
||||
/* no errors */
|
||||
writeConsole(FMT09);
|
||||
return(0);
|
||||
}
|
||||
else {
|
||||
ENgeterror(errcode, errmsg, MAXMSG);
|
||||
writeConsole(errmsg);
|
||||
if (errcode > MAXWARNCODE) {
|
||||
/* error */
|
||||
writeConsole(FMT11);
|
||||
return(errcode);
|
||||
}
|
||||
else {
|
||||
/* warning */
|
||||
writeConsole(FMT10);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
// Blank out the last progress message
|
||||
printf("\r ");
|
||||
|
||||
|
||||
} /* End of main */
|
||||
|
||||
|
||||
void writeConsole(char *s)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: text string
|
||||
** Output: none
|
||||
** Purpose: writes string of characters to console
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
fprintf(stdout,"%s\n",s);
|
||||
fflush(stdout);
|
||||
// Check for errors/warnings and report accordingly
|
||||
if (errcode == 0)
|
||||
{
|
||||
printf("\n... EPANET ran successfully.\n");
|
||||
return 0;
|
||||
}
|
||||
else if (errcode < 100)
|
||||
{
|
||||
printf("\n... EPANET ran with warnings - check the Status Report.\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ENgeterror(errcode, errmsg, 255);
|
||||
printf("\n... EPANET failed with %s.\n", errmsg);
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
271
src/enumstxt.h
271
src/enumstxt.h
@@ -1,137 +1,134 @@
|
||||
/*
|
||||
***********************************************************************
|
||||
|
||||
ENUMSTXT.H -- Text strings for enumerated data types in EPANET
|
||||
|
||||
VERSION: 2.00
|
||||
DATE: 5/8/00
|
||||
AUTHOR: L. Rossman
|
||||
US EPA - NRMRL
|
||||
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ENUMSTXT_H
|
||||
#define ENUMSTXT_H
|
||||
|
||||
char *NodeTxt[] = {t_JUNCTION,
|
||||
t_RESERVOIR,
|
||||
t_TANK};
|
||||
|
||||
char *LinkTxt[] = {w_CV,
|
||||
w_PIPE,
|
||||
w_PUMP,
|
||||
w_PRV,
|
||||
w_PSV,
|
||||
w_PBV,
|
||||
w_FCV,
|
||||
w_TCV,
|
||||
w_GPV};
|
||||
|
||||
char *StatTxt[] = {t_XHEAD,
|
||||
t_TEMPCLOSED,
|
||||
t_CLOSED,
|
||||
t_OPEN,
|
||||
t_ACTIVE,
|
||||
t_XFLOW,
|
||||
t_XFCV,
|
||||
t_XPRESSURE,
|
||||
t_FILLING,
|
||||
t_EMPTYING};
|
||||
|
||||
char *FormTxt[] = {w_HW,
|
||||
w_DW,
|
||||
w_CM};
|
||||
|
||||
char *RptFormTxt[] = {t_HW,
|
||||
t_DW,
|
||||
t_CM};
|
||||
|
||||
char *RptFlowUnitsTxt[] = {u_CFS,
|
||||
u_GPM,
|
||||
u_MGD,
|
||||
u_IMGD,
|
||||
u_AFD,
|
||||
u_LPS,
|
||||
u_LPM,
|
||||
u_MLD,
|
||||
u_CMH,
|
||||
u_CMD};
|
||||
|
||||
char *FlowUnitsTxt[] = {w_CFS,
|
||||
w_GPM,
|
||||
w_MGD,
|
||||
w_IMGD,
|
||||
w_AFD,
|
||||
w_LPS,
|
||||
w_LPM,
|
||||
w_MLD,
|
||||
w_CMH,
|
||||
w_CMD};
|
||||
|
||||
char *PressUnitsTxt[] = {w_PSI,
|
||||
w_KPA,
|
||||
w_METERS};
|
||||
|
||||
char *QualTxt[] = {w_NONE,
|
||||
w_CHEM,
|
||||
w_AGE,
|
||||
w_TRACE};
|
||||
|
||||
|
||||
char *SourceTxt[] = {w_CONCEN,
|
||||
w_MASS,
|
||||
w_SETPOINT,
|
||||
w_FLOWPACED};
|
||||
|
||||
char *ControlTxt[] = {w_BELOW,
|
||||
w_ABOVE,
|
||||
w_TIME,
|
||||
w_CLOCKTIME};
|
||||
|
||||
char *TstatTxt[] = {w_NONE,
|
||||
w_AVG,
|
||||
w_MIN,
|
||||
w_MAX,
|
||||
w_RANGE};
|
||||
|
||||
char *MixTxt[] = {w_MIXED,
|
||||
w_2COMP,
|
||||
w_FIFO,
|
||||
w_LIFO,
|
||||
NULL};
|
||||
|
||||
char *RptFlagTxt[] = {w_NO,
|
||||
w_YES,
|
||||
w_FULL};
|
||||
|
||||
char *SectTxt[] = {s_TITLE, s_JUNCTIONS, s_RESERVOIRS,
|
||||
s_TANKS, s_PIPES, s_PUMPS,
|
||||
s_VALVES, s_CONTROLS, s_RULES,
|
||||
s_DEMANDS, s_SOURCES, s_EMITTERS,
|
||||
s_PATTERNS, s_CURVES, s_QUALITY,
|
||||
s_STATUS, s_ROUGHNESS, s_ENERGY,
|
||||
s_REACTIONS, s_MIXING, s_REPORT,
|
||||
s_TIMES, s_OPTIONS, s_COORDS,
|
||||
s_VERTICES, s_LABELS, s_BACKDROP,
|
||||
s_TAGS, s_END,
|
||||
NULL};
|
||||
|
||||
char *RptSectTxt[] = {NULL, t_JUNCTION, t_RESERVOIR,
|
||||
t_TANK, t_PIPE, t_PUMP,
|
||||
t_VALVE, t_CONTROL, t_RULE,
|
||||
t_DEMANDFOR,t_SOURCE, t_EMITTER,
|
||||
t_PATTERN, t_CURVE, t_QUALITY,
|
||||
t_STATUS, t_ROUGHNESS,t_ENERGY,
|
||||
t_REACTION, t_MIXING, t_REPORT,
|
||||
t_TIME, t_OPTION};
|
||||
|
||||
char *Fldname[] = {t_ELEV, t_DEMAND, t_HEAD,
|
||||
t_PRESSURE, t_QUALITY, t_LENGTH,
|
||||
t_DIAM, t_FLOW, t_VELOCITY,
|
||||
t_HEADLOSS, t_LINKQUAL, t_LINKSTATUS,
|
||||
t_SETTING, t_REACTRATE, t_FRICTION,
|
||||
"", "", "", "", "", "", NULL};
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
*****************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: enumstxt.h
|
||||
Description: text strings for enumerated data types
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 06/20/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ENUMSTXT_H
|
||||
#define ENUMSTXT_H
|
||||
#include "text.h"
|
||||
|
||||
char *NodeTxt[] = {t_JUNCTION,
|
||||
t_RESERVOIR,
|
||||
t_TANK};
|
||||
|
||||
char *LinkTxt[] = {w_CV,
|
||||
w_PIPE,
|
||||
w_PUMP,
|
||||
w_PRV,
|
||||
w_PSV,
|
||||
w_PBV,
|
||||
w_FCV,
|
||||
w_TCV,
|
||||
w_GPV};
|
||||
|
||||
char *StatTxt[] = {t_XHEAD,
|
||||
t_TEMPCLOSED,
|
||||
t_CLOSED,
|
||||
t_OPEN,
|
||||
t_ACTIVE,
|
||||
t_XFLOW,
|
||||
t_XFCV,
|
||||
t_XPRESSURE,
|
||||
t_FILLING,
|
||||
t_EMPTYING,
|
||||
t_OVERFLOWING};
|
||||
|
||||
char *FormTxt[] = {w_HW,
|
||||
w_DW,
|
||||
w_CM};
|
||||
|
||||
char *RptFormTxt[] = {t_HW,
|
||||
t_DW,
|
||||
t_CM};
|
||||
|
||||
char *RptFlowUnitsTxt[] = {u_CFS,
|
||||
u_GPM,
|
||||
u_MGD,
|
||||
u_IMGD,
|
||||
u_AFD,
|
||||
u_LPS,
|
||||
u_LPM,
|
||||
u_MLD,
|
||||
u_CMH,
|
||||
u_CMD};
|
||||
|
||||
char *FlowUnitsTxt[] = {w_CFS,
|
||||
w_GPM,
|
||||
w_MGD,
|
||||
w_IMGD,
|
||||
w_AFD,
|
||||
w_LPS,
|
||||
w_LPM,
|
||||
w_MLD,
|
||||
w_CMH,
|
||||
w_CMD};
|
||||
|
||||
char *PressUnitsTxt[] = {w_PSI,
|
||||
w_KPA,
|
||||
w_METERS};
|
||||
|
||||
char *DemandModelTxt[] = { w_DDA,
|
||||
w_PDA,
|
||||
NULL };
|
||||
|
||||
char *QualTxt[] = {w_NONE,
|
||||
w_CHEM,
|
||||
w_AGE,
|
||||
w_TRACE};
|
||||
|
||||
|
||||
char *SourceTxt[] = {w_CONCEN,
|
||||
w_MASS,
|
||||
w_SETPOINT,
|
||||
w_FLOWPACED};
|
||||
|
||||
char *ControlTxt[] = {w_BELOW,
|
||||
w_ABOVE,
|
||||
w_TIME,
|
||||
w_CLOCKTIME};
|
||||
|
||||
char *TstatTxt[] = {w_NONE,
|
||||
w_AVG,
|
||||
w_MIN,
|
||||
w_MAX,
|
||||
w_RANGE};
|
||||
|
||||
char *MixTxt[] = {w_MIXED,
|
||||
w_2COMP,
|
||||
w_FIFO,
|
||||
w_LIFO,
|
||||
NULL};
|
||||
|
||||
char *RptFlagTxt[] = {w_NO,
|
||||
w_YES,
|
||||
w_FULL};
|
||||
|
||||
char *SectTxt[] = {s_TITLE, s_JUNCTIONS, s_RESERVOIRS,
|
||||
s_TANKS, s_PIPES, s_PUMPS,
|
||||
s_VALVES, s_CONTROLS, s_RULES,
|
||||
s_DEMANDS, s_SOURCES, s_EMITTERS,
|
||||
s_PATTERNS, s_CURVES, s_QUALITY,
|
||||
s_STATUS, s_ROUGHNESS, s_ENERGY,
|
||||
s_REACTIONS, s_MIXING, s_REPORT,
|
||||
s_TIMES, s_OPTIONS, s_COORDS,
|
||||
s_VERTICES, s_LABELS, s_BACKDROP,
|
||||
s_TAGS, s_END,
|
||||
NULL};
|
||||
|
||||
char *Fldname[] = {t_ELEV, t_DEMAND, t_HEAD,
|
||||
t_PRESSURE, t_QUALITY, t_LENGTH,
|
||||
t_DIAM, t_FLOW, t_VELOCITY,
|
||||
t_HEADLOSS, t_LINKQUAL, t_LINKSTATUS,
|
||||
t_SETTING, t_REACTRATE, t_FRICTION,
|
||||
"", "", "", "", "", "", NULL};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
8745
src/epanet.c
Executable file → Normal file
8745
src/epanet.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
865
src/epanet2.c
Normal file
865
src/epanet2.c
Normal file
@@ -0,0 +1,865 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: epanet2.c
|
||||
Description: implementation of the legacy EPANET API functions
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 11/02/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "funcs.h"
|
||||
|
||||
#include "epanet2.h"
|
||||
#include "epanet2_2.h"
|
||||
|
||||
|
||||
// This single global variable is used only when the library is called
|
||||
// in "legacy mode" with the 2.1-style API.
|
||||
Project __defaultProject;
|
||||
Project *_defaultProject = &__defaultProject;
|
||||
|
||||
// Functions for creating and removing default temporary files
|
||||
void createtmpfiles()
|
||||
{
|
||||
getTmpName(_defaultProject->TmpHydFname);
|
||||
getTmpName(_defaultProject->TmpOutFname);
|
||||
getTmpName(_defaultProject->TmpStatFname);
|
||||
}
|
||||
|
||||
void removetmpfiles()
|
||||
{
|
||||
remove(_defaultProject->TmpHydFname);
|
||||
remove(_defaultProject->TmpOutFname);
|
||||
remove(_defaultProject->TmpStatFname);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Project Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile,
|
||||
const char *outFile, void (*pviewprog)(char *))
|
||||
{
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: inpFile = name of EPANET formatted input file
|
||||
** rptFile = name of report file
|
||||
** outFile = name of binary output file
|
||||
** pviewprog = see note below
|
||||
** Output: none
|
||||
** Returns: error code
|
||||
** Purpose: runs a complete EPANET simulation
|
||||
**
|
||||
** The pviewprog() argument is a pointer to a callback function
|
||||
** that takes a character string (char *) as its only parameter.
|
||||
** The function would reside in and be used by the calling
|
||||
** program to display the progress messages that EPANET generates
|
||||
** as it carries out its computations. If this feature is not
|
||||
** needed then the argument should be NULL.
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
int errcode = 0;
|
||||
int warncode = 0;
|
||||
|
||||
// Run the project and record any warning
|
||||
createtmpfiles();
|
||||
errcode = EN_runproject(_defaultProject, inpFile, rptFile, outFile, pviewprog);
|
||||
if (errcode < 100) warncode = errcode;
|
||||
removetmpfiles();
|
||||
|
||||
// Return the warning code if the run had no errors
|
||||
if (warncode) errcode = MAX(errcode, warncode);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENinit(const char *rptFile, const char *outFile, int unitsType,
|
||||
int headlossType)
|
||||
{
|
||||
int errcode = 0;
|
||||
createtmpfiles();
|
||||
errcode = EN_init(_defaultProject, rptFile, outFile, unitsType, headlossType);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENopen(const char *inpFile, const char *rptFile, const char *outFile)
|
||||
{
|
||||
int errcode = 0;
|
||||
createtmpfiles();
|
||||
errcode = EN_open(_defaultProject, inpFile, rptFile, outFile);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgettitle(char *line1, char *line2, char *line3)
|
||||
{
|
||||
return EN_gettitle(_defaultProject, line1, line2, line3) ;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsettitle(char *line1, char *line2, char *line3)
|
||||
{
|
||||
return EN_settitle(_defaultProject, line1, line2, line3) ;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcomment(int object, int index, char *comment)
|
||||
{
|
||||
return EN_getcomment(_defaultProject, object, index, comment);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcomment(int object, int index, char *comment)
|
||||
{
|
||||
return EN_setcomment(_defaultProject, object, index, comment);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcount(int object, int *count)
|
||||
{
|
||||
return EN_getcount(_defaultProject, object, count);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsaveinpfile(const char *filename)
|
||||
{
|
||||
return EN_saveinpfile(_defaultProject, filename);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENclose()
|
||||
{
|
||||
EN_close(_defaultProject);
|
||||
removetmpfiles();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Hydraulic Analysis Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENsolveH() { return EN_solveH(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENsaveH() { return EN_saveH(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENopenH() { return EN_openH(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENinitH(int initFlag) { return EN_initH(_defaultProject, initFlag); }
|
||||
|
||||
int DLLEXPORT ENrunH(long *currentTime) { return EN_runH(_defaultProject, currentTime); }
|
||||
|
||||
int DLLEXPORT ENnextH(long *tStep) { return EN_nextH(_defaultProject, tStep); }
|
||||
|
||||
int DLLEXPORT ENcloseH() { return EN_closeH(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENsavehydfile(char *filename)
|
||||
{
|
||||
return EN_savehydfile(_defaultProject, filename);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENusehydfile(char *filename)
|
||||
{
|
||||
return EN_usehydfile(_defaultProject, filename);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Water Quality Analysis Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENsolveQ() { return EN_solveQ(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENopenQ() { return EN_openQ(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENinitQ(int saveFlag) { return EN_initQ(_defaultProject, saveFlag); }
|
||||
|
||||
int DLLEXPORT ENrunQ(long *currentTime) { return EN_runQ(_defaultProject, currentTime); }
|
||||
|
||||
int DLLEXPORT ENnextQ(long *tStep) { return EN_nextQ(_defaultProject, tStep); }
|
||||
|
||||
int DLLEXPORT ENstepQ(long *timeLeft) { return EN_stepQ(_defaultProject, timeLeft); }
|
||||
|
||||
int DLLEXPORT ENcloseQ() { return EN_closeQ(_defaultProject); }
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Reporting Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENwriteline(char *line) { return EN_writeline(_defaultProject, line); }
|
||||
|
||||
int DLLEXPORT ENreport() { return EN_report(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENcopyreport(char *filename)
|
||||
{
|
||||
return EN_copyreport(_defaultProject, filename);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENclearreport() { return EN_clearreport(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENresetreport() { return EN_resetreport(_defaultProject); }
|
||||
|
||||
int DLLEXPORT ENsetreport(char *format) { return EN_setreport(_defaultProject, format); }
|
||||
|
||||
int DLLEXPORT ENsetstatusreport(int level)
|
||||
{
|
||||
return EN_setstatusreport(_defaultProject, level);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetversion(int *version) { return EN_getversion(version); }
|
||||
|
||||
int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen)
|
||||
{
|
||||
return EN_geterror(errcode, errmsg, maxLen);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetstatistic(int type, EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v = 0.0;
|
||||
int errcode = EN_getstatistic(_defaultProject, type, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetresultindex(int type, int index, int *value)
|
||||
{
|
||||
return EN_getresultindex(_defaultProject, type, index, value);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Analysis Options Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENgetoption(int option, EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v = 0.0;
|
||||
int errcode = EN_getoption(_defaultProject, option, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetoption(int option, EN_API_FLOAT_TYPE value)
|
||||
{
|
||||
return EN_setoption(_defaultProject, option, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetflowunits(int *units)
|
||||
{
|
||||
return EN_getflowunits(_defaultProject, units);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetflowunits(int units)
|
||||
{
|
||||
return EN_setflowunits(_defaultProject, units);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgettimeparam(int param, long *value)
|
||||
{
|
||||
return EN_gettimeparam(_defaultProject, param, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsettimeparam(int param, long value)
|
||||
{
|
||||
return EN_settimeparam(_defaultProject, param, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetqualinfo(int *qualType, char *chemName, char *chemUnits,
|
||||
int *traceNode)
|
||||
{
|
||||
return EN_getqualinfo(_defaultProject, qualType, chemName, chemUnits, traceNode);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetqualtype(int *qualType, int *traceNode)
|
||||
{
|
||||
return EN_getqualtype(_defaultProject, qualType, traceNode);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetqualtype(int qualType, char *chemName, char *chemUnits,
|
||||
char *traceNode)
|
||||
{
|
||||
return EN_setqualtype(_defaultProject, qualType, chemName, chemUnits, traceNode);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Node Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddnode(char *id, int nodeType, int *index)
|
||||
{
|
||||
return EN_addnode(_defaultProject, id, nodeType, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletenode(int index, int actionCode)
|
||||
{
|
||||
return EN_deletenode(_defaultProject, index, actionCode);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetnodeindex(char *id, int *index)
|
||||
{
|
||||
return EN_getnodeindex(_defaultProject, id, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetnodeid(int index, char *id)
|
||||
{
|
||||
return EN_getnodeid(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetnodeid(int index, char *newid)
|
||||
{
|
||||
return EN_setnodeid(_defaultProject, index, newid);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetnodetype(int index, int *nodeType)
|
||||
{
|
||||
return EN_getnodetype(_defaultProject, index, nodeType);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetnodevalue(int index, int property, EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v = 0.0;
|
||||
int errcode = EN_getnodevalue(_defaultProject, index, property, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetnodevalue(int index, int property, EN_API_FLOAT_TYPE value)
|
||||
{
|
||||
return EN_setnodevalue(_defaultProject, index, property, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetjuncdata(int index, EN_API_FLOAT_TYPE elev, EN_API_FLOAT_TYPE dmnd,
|
||||
char *dmndpat)
|
||||
{
|
||||
return EN_setjuncdata(_defaultProject, index, elev, dmnd, dmndpat);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsettankdata(int index, EN_API_FLOAT_TYPE elev,
|
||||
EN_API_FLOAT_TYPE initlvl, EN_API_FLOAT_TYPE minlvl,
|
||||
EN_API_FLOAT_TYPE maxlvl, EN_API_FLOAT_TYPE diam,
|
||||
EN_API_FLOAT_TYPE minvol, char *volcurve)
|
||||
{
|
||||
return EN_settankdata(_defaultProject, index, elev, initlvl, minlvl, maxlvl,
|
||||
diam, minvol, volcurve);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcoord(int index, double *x, double *y)
|
||||
{
|
||||
return EN_getcoord(_defaultProject, index, x, y);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcoord(int index, double x, double y)
|
||||
{
|
||||
return EN_setcoord(_defaultProject, index, x, y);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Nodal Demand Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENgetdemandmodel(int *model, EN_API_FLOAT_TYPE *pmin,
|
||||
EN_API_FLOAT_TYPE *preq, EN_API_FLOAT_TYPE *pexp)
|
||||
{
|
||||
double pmin2 = 0.0, preq2 = 0.0, pexp2 = 0.0;
|
||||
int errcode = EN_getdemandmodel(_defaultProject, model, &pmin2, &preq2, &pexp2);
|
||||
*pmin = (EN_API_FLOAT_TYPE)pmin2;
|
||||
*preq = (EN_API_FLOAT_TYPE)preq2;
|
||||
*pexp = (EN_API_FLOAT_TYPE)pexp2;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetdemandmodel(int model, EN_API_FLOAT_TYPE pmin,
|
||||
EN_API_FLOAT_TYPE preq, EN_API_FLOAT_TYPE pexp)
|
||||
{
|
||||
return EN_setdemandmodel(_defaultProject, model, pmin, preq, pexp);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENadddemand(int nodeIndex, EN_API_FLOAT_TYPE baseDemand,
|
||||
char *demandPattern, char *demandName)
|
||||
{
|
||||
return EN_adddemand(_defaultProject, nodeIndex, baseDemand, demandPattern, demandName);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletedemand(int nodeIndex, int demandIndex)
|
||||
{
|
||||
return EN_deletedemand(_defaultProject, nodeIndex, demandIndex);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetdemandindex(int nodeIndex, char *demandName, int *demandIndex)
|
||||
{
|
||||
return EN_getdemandindex(_defaultProject, nodeIndex, demandName, demandIndex);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands)
|
||||
{
|
||||
return EN_getnumdemands(_defaultProject, nodeIndex, numDemands);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIndex,
|
||||
EN_API_FLOAT_TYPE *baseDemand)
|
||||
{
|
||||
double bd2 = 0.0;
|
||||
int errcode = EN_getbasedemand(_defaultProject, nodeIndex, demandIndex, &bd2);
|
||||
*baseDemand = (EN_API_FLOAT_TYPE)bd2;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIndex,
|
||||
EN_API_FLOAT_TYPE baseDemand)
|
||||
{
|
||||
return EN_setbasedemand(_defaultProject, nodeIndex, demandIndex, baseDemand);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetdemandpattern(int nodeIndex, int demandIndex, int patIndex)
|
||||
{
|
||||
return EN_setdemandpattern(_defaultProject, nodeIndex, demandIndex, patIndex);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIdx)
|
||||
{
|
||||
return EN_getdemandpattern(_defaultProject, nodeIndex, demandIndex, pattIdx);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetdemandname(int nodeIndex, int demandIndex, char *demandName)
|
||||
{
|
||||
return EN_getdemandname(_defaultProject, nodeIndex, demandIndex, demandName);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIndex, char *demandName)
|
||||
{
|
||||
return EN_setdemandname(_defaultProject, nodeIndex, demandIndex, demandName);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Link Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddlink(char *id, int linkType, char *fromNode, char *toNode, int *index)
|
||||
{
|
||||
return EN_addlink(_defaultProject, id, linkType, fromNode, toNode, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletelink(int index, int actionCode)
|
||||
{
|
||||
return EN_deletelink(_defaultProject, index, actionCode);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetlinkindex(char *id, int *index)
|
||||
{
|
||||
return EN_getlinkindex(_defaultProject, id, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetlinkid(int index, char *id)
|
||||
{
|
||||
return EN_getlinkid(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetlinkid(int index, char *newid)
|
||||
{
|
||||
return EN_setlinkid(_defaultProject, index, newid);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetlinktype(int index, int *linkType)
|
||||
{
|
||||
return EN_getlinktype(_defaultProject, index, linkType);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetlinktype(int *index, int linkType, int actionCode)
|
||||
{
|
||||
return EN_setlinktype(_defaultProject, index, linkType, actionCode);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2)
|
||||
{
|
||||
return EN_getlinknodes(_defaultProject, index, node1, node2);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetlinknodes(int index, int node1, int node2)
|
||||
{
|
||||
return EN_setlinknodes(_defaultProject, index, node1, node2);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetlinkvalue(int index, int property, EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v = 0.0;
|
||||
int errcode = EN_getlinkvalue(_defaultProject, index, property, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetlinkvalue(int index, int property, EN_API_FLOAT_TYPE value)
|
||||
{
|
||||
return EN_setlinkvalue(_defaultProject, index, property, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpipedata(int index, EN_API_FLOAT_TYPE length,
|
||||
EN_API_FLOAT_TYPE diam, EN_API_FLOAT_TYPE rough, EN_API_FLOAT_TYPE mloss)
|
||||
{
|
||||
return EN_setpipedata(_defaultProject, index, length, diam, rough, mloss);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetvertexcount(int index, int *count)
|
||||
{
|
||||
return EN_getvertexcount(_defaultProject, index, count);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetvertex(int index, int vertex, double *x, double *y)
|
||||
{
|
||||
return EN_getvertex(_defaultProject, index, vertex, x, y);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetvertices(int index, double *x, double *y, int count)
|
||||
{
|
||||
return EN_setvertices(_defaultProject, index, x, y, count);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Pump Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENgetpumptype(int linkIndex, int *pumpType)
|
||||
{
|
||||
return EN_getpumptype(_defaultProject, linkIndex, pumpType);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetheadcurveindex(int linkIndex, int *curveIndex)
|
||||
{
|
||||
return EN_getheadcurveindex(_defaultProject, linkIndex, curveIndex);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetheadcurveindex(int linkIndex, int curveIndex)
|
||||
{
|
||||
return EN_setheadcurveindex(_defaultProject, linkIndex, curveIndex);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Time Pattern Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddpattern(char *id)
|
||||
{
|
||||
return EN_addpattern(_defaultProject, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletepattern(int index)
|
||||
{
|
||||
return EN_deletepattern(_defaultProject, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetpatternindex(char *id, int *index)
|
||||
{
|
||||
return EN_getpatternindex(_defaultProject, id, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetpatternid(int index, char *id)
|
||||
{
|
||||
return EN_getpatternid(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpatternid(int index, char *id)
|
||||
{
|
||||
return EN_setpatternid(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetpatternlen(int index, int *len)
|
||||
{
|
||||
return EN_getpatternlen(_defaultProject, index, len);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v = 0.0;
|
||||
int errcode = EN_getpatternvalue(_defaultProject, index, period, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
|
||||
{
|
||||
return EN_setpatternvalue(_defaultProject, index, period, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v;
|
||||
int errcode = EN_getaveragepatternvalue(_defaultProject, index, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *values, int len)
|
||||
{
|
||||
double *v = NULL;
|
||||
int i, errcode;
|
||||
if (values == NULL) return 206;
|
||||
v = (double *)calloc(len, sizeof(double));
|
||||
if (v)
|
||||
{
|
||||
for (i = 0; i < len; i++) v[i] = values[i];
|
||||
errcode = EN_setpattern(_defaultProject, index, v, len);
|
||||
}
|
||||
else errcode = 101;
|
||||
free(v);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Data Curve Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddcurve(char *id)
|
||||
{
|
||||
return EN_addcurve(_defaultProject, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletecurve(int index)
|
||||
{
|
||||
return EN_deletecurve(_defaultProject, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcurveindex(char *id, int *index)
|
||||
{
|
||||
return EN_getcurveindex(_defaultProject, id, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcurveid(int index, char *id)
|
||||
{
|
||||
return EN_getcurveid(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcurveid(int index, char *id)
|
||||
{
|
||||
return EN_setcurveid(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcurvelen(int index, int *len)
|
||||
{
|
||||
return EN_getcurvelen(_defaultProject, index, len);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcurvetype(int index, int *type)
|
||||
{
|
||||
return EN_getcurvetype(_defaultProject, index, type);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE *x,
|
||||
EN_API_FLOAT_TYPE *y)
|
||||
{
|
||||
double xx = 0.0, yy = 0.0;
|
||||
int errcode = EN_getcurvevalue(_defaultProject, curveIndex, pointIndex, &xx, &yy);
|
||||
*x = (EN_API_FLOAT_TYPE)xx;
|
||||
*y = (EN_API_FLOAT_TYPE)yy;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcurvevalue(int curveIndex, int pointIndex, EN_API_FLOAT_TYPE x,
|
||||
EN_API_FLOAT_TYPE y)
|
||||
{
|
||||
return EN_setcurvevalue(_defaultProject, curveIndex, pointIndex, x, y);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcurve(int index, char *id, int *nPoints,
|
||||
EN_API_FLOAT_TYPE *xValues, EN_API_FLOAT_TYPE *yValues)
|
||||
{
|
||||
int i;
|
||||
Network *net = &_defaultProject->network;
|
||||
Scurve *curve;
|
||||
|
||||
if (index <= 0 || index > net->Ncurves) return 206;
|
||||
if (xValues == NULL || yValues == NULL) return 206;
|
||||
curve = &net->Curve[index];
|
||||
strncpy(id, curve->ID, MAXID);
|
||||
*nPoints = curve->Npts;
|
||||
for (i = 0; i < curve->Npts; i++)
|
||||
{
|
||||
xValues[i] = (EN_API_FLOAT_TYPE)curve->X[i];
|
||||
yValues[i] = (EN_API_FLOAT_TYPE)curve->Y[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcurve(int index, EN_API_FLOAT_TYPE *xValues,
|
||||
EN_API_FLOAT_TYPE *yValues, int nPoints)
|
||||
{
|
||||
double *xx = NULL;
|
||||
double *yy = NULL;
|
||||
int i, errcode = 0;
|
||||
|
||||
if (xValues == NULL || yValues == NULL) return 206;
|
||||
if (nPoints < 1) return 202;
|
||||
|
||||
xx = (double *)calloc(nPoints, sizeof(double));
|
||||
yy = (double *)calloc(nPoints, sizeof(double));
|
||||
if (xx && yy)
|
||||
{
|
||||
for (i = 0; i < nPoints; i++)
|
||||
{
|
||||
xx[i] = xValues[i];
|
||||
yy[i] = yValues[i];
|
||||
}
|
||||
errcode = EN_setcurve(_defaultProject, index, xx, yy, nPoints);
|
||||
}
|
||||
else errcode = 101;
|
||||
free(xx);
|
||||
free(yy);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Simple Controls Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddcontrol(int type, int linkIndex, EN_API_FLOAT_TYPE setting,
|
||||
int nodeIndex, EN_API_FLOAT_TYPE level, int *index)
|
||||
{
|
||||
return EN_addcontrol(_defaultProject, type, linkIndex, setting, nodeIndex,
|
||||
level, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletecontrol(int index)
|
||||
{
|
||||
return EN_deletecontrol(_defaultProject, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcontrol(int index, int *type, int *linkIndex,
|
||||
EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level)
|
||||
{
|
||||
double setting2 = 0.0, level2 = 0.0;
|
||||
int errcode = EN_getcontrol(_defaultProject, index, type, linkIndex, &setting2,
|
||||
nodeIndex, &level2);
|
||||
*setting = (EN_API_FLOAT_TYPE)setting2;
|
||||
*level = (EN_API_FLOAT_TYPE)level2;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcontrol(int index, int type, int linkIndex,
|
||||
EN_API_FLOAT_TYPE setting, int nodeIndex, EN_API_FLOAT_TYPE level)
|
||||
{
|
||||
return EN_setcontrol(_defaultProject, index, type, linkIndex, setting,
|
||||
nodeIndex, level);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Rule-Based Controls Functions
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddrule(char *rule)
|
||||
{
|
||||
return EN_addrule(_defaultProject, rule);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeleterule(int index)
|
||||
{
|
||||
return EN_deleterule(_defaultProject, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetrule(int index, int *nPremises, int *nThenActions,
|
||||
int *nElseActions, EN_API_FLOAT_TYPE *priority)
|
||||
{
|
||||
double priority2 = 0.0;
|
||||
int errcode = EN_getrule(_defaultProject, index, nPremises, nThenActions,
|
||||
nElseActions, &priority2);
|
||||
*priority = (EN_API_FLOAT_TYPE)priority2;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetruleID(int index, char* id)
|
||||
{
|
||||
return EN_getruleID(_defaultProject, index, id);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetpremise(int ruleIndex, int premiseIndex, int *logop, int *object,
|
||||
int *objIndex, int *variable, int *relop, int *status,
|
||||
EN_API_FLOAT_TYPE *value)
|
||||
{
|
||||
double v = 0.0;
|
||||
int errcode = EN_getpremise(_defaultProject, ruleIndex, premiseIndex, logop,
|
||||
object, objIndex, variable, relop, status, &v);
|
||||
*value = (EN_API_FLOAT_TYPE)v;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpremise(int ruleIndex, int premiseIndex, int logop, int object,
|
||||
int objIndex, int variable, int relop, int status, EN_API_FLOAT_TYPE value)
|
||||
{
|
||||
return EN_setpremise(_defaultProject, ruleIndex, premiseIndex, logop, object,
|
||||
objIndex, variable, relop, status, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpremiseindex(int ruleIndex, int premiseIndex, int objIndex)
|
||||
{
|
||||
return EN_setpremiseindex(_defaultProject, ruleIndex, premiseIndex, objIndex);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpremisestatus(int ruleIndex, int premiseIndex, int status)
|
||||
{
|
||||
return EN_setpremisestatus(_defaultProject, ruleIndex, premiseIndex, status);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetpremisevalue(int ruleIndex, int premiseIndex, EN_API_FLOAT_TYPE value)
|
||||
{
|
||||
return EN_setpremisevalue(_defaultProject, ruleIndex, premiseIndex, value);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetthenaction(int ruleIndex, int actionIndex, int *linkIndex,
|
||||
int *status, EN_API_FLOAT_TYPE *setting)
|
||||
{
|
||||
double setting2 = 0.0;
|
||||
int errcode = EN_getthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
|
||||
status, &setting2);
|
||||
*setting = (EN_API_FLOAT_TYPE)setting2;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetthenaction(int ruleIndex, int actionIndex, int linkIndex,
|
||||
int status, EN_API_FLOAT_TYPE setting)
|
||||
{
|
||||
return EN_setthenaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
|
||||
status, setting);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetelseaction(int ruleIndex, int actionIndex, int *linkIndex,
|
||||
int *status, EN_API_FLOAT_TYPE *setting)
|
||||
{
|
||||
double setting2 = 0.0;
|
||||
int errcode = EN_getelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
|
||||
status, &setting2);
|
||||
*setting = (EN_API_FLOAT_TYPE)setting2;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetelseaction(int ruleIndex, int actionIndex, int linkIndex,
|
||||
int status, EN_API_FLOAT_TYPE setting)
|
||||
{
|
||||
return EN_setelseaction(_defaultProject, ruleIndex, actionIndex, linkIndex,
|
||||
status, setting);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetrulepriority(int index, EN_API_FLOAT_TYPE priority)
|
||||
{
|
||||
return EN_setrulepriority(_defaultProject, index, priority);
|
||||
}
|
||||
73
src/errors.dat
Normal file
73
src/errors.dat
Normal file
@@ -0,0 +1,73 @@
|
||||
//EPANET 2 Error Messages
|
||||
DAT(0,"ok")
|
||||
DAT(101,"insufficient memory available")
|
||||
DAT(102,"no network data available")
|
||||
DAT(103,"hydraulic solver not opened")
|
||||
DAT(104,"no hydraulics for water quality analysis")
|
||||
DAT(105,"water quality solver not opened")
|
||||
DAT(106,"no results saved to report on")
|
||||
DAT(107,"hydraulics supplied from external file")
|
||||
DAT(108,"cannot use external file while hydraulics solver is active")
|
||||
DAT(110,"cannot solve network hydraulic equations")
|
||||
DAT(120,"cannot solve water quality transport equations")
|
||||
|
||||
// These errors apply only to an input file
|
||||
DAT(200,"one or more errors in input file")
|
||||
DAT(201,"syntax error")
|
||||
|
||||
// These errors apply to both an input file and to API functions
|
||||
DAT(202,"illegal numeric value")
|
||||
DAT(203,"undefined node")
|
||||
DAT(204,"undefined link")
|
||||
DAT(205,"undefined time pattern")
|
||||
DAT(206,"undefined curve")
|
||||
DAT(207,"attempt to control CV/GPV link")
|
||||
DAT(208,"illegal PDA pressure limits")
|
||||
DAT(209,"illegal node property value")
|
||||
DAT(211,"illegal link property value")
|
||||
DAT(212,"undefined trace node")
|
||||
DAT(213,"invalid option value")
|
||||
DAT(214,"too many characters in input line")
|
||||
DAT(215,"duplicate ID label")
|
||||
DAT(216,"reference to undefined pump")
|
||||
DAT(217,"invalid pump energy data")
|
||||
DAT(219,"illegal valve connection to tank node")
|
||||
DAT(220,"illegal valve connection to another valve")
|
||||
DAT(221,"mis-placed rule clause in rule-based control")
|
||||
DAT(222,"same start and end nodes for link")
|
||||
|
||||
// These errors apply to network consistency check
|
||||
DAT(223,"not enough nodes in network")
|
||||
DAT(224,"no tanks or reservoirs in network")
|
||||
DAT(225,"invalid lower/upper levels for tank")
|
||||
DAT(226,"no head curve or power rating for pump")
|
||||
DAT(227,"invalid head curve for pump")
|
||||
DAT(230,"nonincreasing x-values for curve")
|
||||
DAT(233,"network has unconnected node")
|
||||
|
||||
// These errors apply only to API functions
|
||||
DAT(240,"nonexistent source")
|
||||
DAT(241,"nonexistent control")
|
||||
DAT(250,"invalid format")
|
||||
DAT(251,"invalid parameter code")
|
||||
DAT(252,"invalid ID name")
|
||||
DAT(253,"nonexistent demand category")
|
||||
DAT(254,"node with no coordinates")
|
||||
DAT(255,"invalid link vertex")
|
||||
DAT(257,"nonexistent rule")
|
||||
DAT(258,"nonexistent rule clause")
|
||||
DAT(259,"attempt to delete a node that still has links connected to it")
|
||||
DAT(260,"attempt to delete node assigned as a Trace Node")
|
||||
DAT(261,"attempt to delete a node or link contained in a control")
|
||||
DAT(262,"attempt to modify network structure while solver is active")
|
||||
|
||||
// File errors
|
||||
DAT(301,"identical file names")
|
||||
DAT(302,"cannot open input file")
|
||||
DAT(303,"cannot open report file")
|
||||
DAT(304,"cannot open binary output file")
|
||||
DAT(305,"cannot open hydraulics file")
|
||||
DAT(306,"hydraulics file does not match network data")
|
||||
DAT(307,"cannot read hydraulics file")
|
||||
DAT(308,"cannot save results to file")
|
||||
DAT(309,"cannot save results to report file")
|
||||
481
src/funcs.h
481
src/funcs.h
@@ -1,288 +1,193 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
|
||||
FUNCS.H -- Function Prototypes for EPANET Program
|
||||
|
||||
VERSION: 2.00
|
||||
DATE: 5/8/00
|
||||
9/25/00
|
||||
10/25/00
|
||||
12/29/00
|
||||
3/1/01
|
||||
2/14/08 (2.00.12)
|
||||
AUTHOR: L. Rossman
|
||||
US EPA - NRMRL
|
||||
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
/*****************************************************************/
|
||||
/* Most float arguments have been changed to double - 7/3/07 */
|
||||
/*****************************************************************/
|
||||
|
||||
/* ------- EPANET.C --------------------*/
|
||||
/*
|
||||
** NOTE: The exportable functions that can be called
|
||||
** via the DLL are prototyped in TOOLKIT.H.
|
||||
*/
|
||||
|
||||
#ifndef FUNCS_H
|
||||
#define FUNCS_H
|
||||
|
||||
void initpointers(void); /* Initializes pointers */
|
||||
int allocdata(void); /* Allocates memory */
|
||||
void freeTmplist(STmplist *); /* Frees items in linked list */
|
||||
void freeFloatlist(SFloatlist *); /* Frees list of floats */
|
||||
void freedata(void); /* Frees allocated memory */
|
||||
int openfiles(char *,char *,char *); /* Opens input & report files */
|
||||
int openhydfile(void); /* Opens hydraulics file */
|
||||
int openoutfile(void); /* Opens binary output file */
|
||||
int strcomp(char *, char *); /* Compares two strings */
|
||||
char* getTmpName(char* fname); /* Gets temporary file name */ //(2.00.12 - LR)
|
||||
double interp(int, double *, /* Interpolates a data curve */
|
||||
double *, double);
|
||||
int findnode(char *); /* Finds node's index from ID */
|
||||
int findlink(char *); /* Finds link's index from ID */
|
||||
char* geterrmsg(int); /* Gets text of error message */
|
||||
void errmsg(int); /* Reports program error */
|
||||
void writecon(char *); /* Writes text to console */
|
||||
void writewin(char *); /* Passes text to calling app */
|
||||
|
||||
/* ------- INPUT1.C --------------------*/
|
||||
int getdata(void); /* Gets network data */
|
||||
void setdefaults(void); /* Sets default values */
|
||||
void initreport(void); /* Initializes report options */
|
||||
void adjustdata(void); /* Adjusts input data */
|
||||
int inittanks(void); /* Initializes tank levels */
|
||||
void initunits(void); /* Determines reporting units */
|
||||
void convertunits(void); /* Converts data to std. units*/
|
||||
|
||||
/* -------- INPUT2.C -------------------*/
|
||||
int netsize(void); /* Determines network size */
|
||||
int readdata(void); /* Reads in network data */
|
||||
int newline(int, char *); /* Processes new line of data */
|
||||
int addnodeID(int, char *); /* Adds node ID to data base */
|
||||
int addlinkID(int, char *); /* Adds link ID to data base */
|
||||
int addpattern(char *); /* Adds pattern to data base */
|
||||
int addcurve(char *); /* Adds curve to data base */
|
||||
STmplist *findID(char *, STmplist *); /* Locates ID on linked list */
|
||||
int unlinked(void); /* Checks for unlinked nodes */
|
||||
int getpumpparams(void); /* Computes pump curve coeffs.*/
|
||||
int getpatterns(void); /* Gets pattern data from list*/
|
||||
int getcurves(void); /* Gets curve data from list */
|
||||
int findmatch(char *,char *[]); /* Finds keyword in line */
|
||||
int match(char *, char *); /* Checks for word match */
|
||||
int gettokens(char *); /* Tokenizes input line */
|
||||
int getfloat(char *, double *); /* Converts string to double */
|
||||
double hour(char *, char *); /* Converts time to hours */
|
||||
int setreport(char *); /* Processes reporting command*/
|
||||
void inperrmsg(int,int,char *); /* Input error message */
|
||||
|
||||
/* ---------- INPUT3.C -----------------*/
|
||||
int juncdata(void); /* Processes junction data */
|
||||
int tankdata(void); /* Processes tank data */
|
||||
int pipedata(void); /* Processes pipe data */
|
||||
int pumpdata(void); /* Processes pump data */
|
||||
int valvedata(void); /* Processes valve data */
|
||||
int patterndata(void); /* Processes pattern data */
|
||||
int curvedata(void); /* Processes curve data */
|
||||
int coordata(void); /* Processes coordinate data */
|
||||
int demanddata(void); /* Processes demand data */
|
||||
int controldata(void); /* Processes simple controls */
|
||||
int energydata(void); /* Processes energy data */
|
||||
int sourcedata(void); /* Processes source data */
|
||||
int emitterdata(void); /* Processes emitter data */
|
||||
int qualdata(void); /* Processes quality data */
|
||||
int reactdata(void); /* Processes reaction data */
|
||||
int mixingdata(void); /* Processes tank mixing data */
|
||||
int statusdata(void); /* Processes link status data */
|
||||
int reportdata(void); /* Processes report options */
|
||||
int timedata(void); /* Processes time options */
|
||||
int optiondata(void); /* Processes analysis options */
|
||||
int optionchoice(int); /* Processes option choices */
|
||||
int optionvalue(int); /* Processes option values */
|
||||
int getpumpcurve(int); /* Constructs a pump curve */
|
||||
int powercurve(double, double, double,/* Coeffs. of power pump curve*/
|
||||
double, double, double *,
|
||||
double *, double *);
|
||||
int valvecheck(int, int, int); /* Checks valve placement */
|
||||
void changestatus(int, char, double); /* Changes status of a link */
|
||||
|
||||
/* -------------- RULES.C --------------*/
|
||||
void initrules(void); /* Initializes rule base */
|
||||
void addrule(char *); /* Adds rule to rule base */
|
||||
int allocrules(void); /* Allocates memory for rule */
|
||||
int ruledata(void); /* Processes rule input data */
|
||||
int checkrules(long); /* Checks all rules */
|
||||
void freerules(void); /* Frees rule base memory */
|
||||
|
||||
/* ------------- REPORT.C --------------*/
|
||||
int writereport(void); /* Writes formatted report */
|
||||
void writelogo(void); /* Writes program logo */
|
||||
void writesummary(void); /* Writes network summary */
|
||||
void writehydstat(int,double); /* Writes hydraulic status */
|
||||
void writeenergy(void); /* Writes energy usage */
|
||||
int writeresults(void); /* Writes node/link results */
|
||||
void writeheader(int,int); /* Writes heading on report */
|
||||
void writeline(char *); /* Writes line to report file */
|
||||
void writerelerr(int, double); /* Writes convergence error */
|
||||
void writestatchange(int,char,char); /* Writes link status change */
|
||||
void writecontrolaction(int, int); /* Writes control action taken*/
|
||||
void writeruleaction(int, char *); /* Writes rule action taken */
|
||||
int writehydwarn(int,double); /* Writes hydraulic warnings */
|
||||
void writehyderr(int); /* Writes hydraulic error msg.*/
|
||||
int disconnected(void); /* Checks for disconnections */
|
||||
void marknodes(int, int *, char *); /* Identifies connected nodes */
|
||||
void getclosedlink(int, char *); /* Finds a disconnecting link */
|
||||
void writelimits(int,int); /* Writes reporting limits */
|
||||
int checklimits(double *,int,int); /* Checks variable limits */
|
||||
void writetime(char *); /* Writes current clock time */
|
||||
char *clocktime(char *, long); /* Converts time to hrs:min */
|
||||
char *fillstr(char *, char, int); /* Fills string with character*/
|
||||
int getnodetype(int); /* Determines node type */
|
||||
|
||||
/* --------- HYDRAUL.C -----------------*/
|
||||
int openhyd(void); /* Opens hydraulics solver */
|
||||
|
||||
/*** Updated 3/1/01 ***/
|
||||
void inithyd(int); /* Re-sets initial conditions */
|
||||
|
||||
int runhyd(long *); /* Solves 1-period hydraulics */
|
||||
int nexthyd(long *); /* Moves to next time period */
|
||||
void closehyd(void); /* Closes hydraulics solver */
|
||||
int allocmatrix(void); /* Allocates matrix coeffs. */
|
||||
void freematrix(void); /* Frees matrix coeffs. */
|
||||
void initlinkflow(int, char, double); /* Initializes link flow */
|
||||
void setlinkflow(int, double); /* Sets link flow via headloss*/
|
||||
void setlinkstatus(int, char, char *, /* Sets link status */
|
||||
double *);
|
||||
void setlinksetting(int, double, /* Sets pump/valve setting */
|
||||
char *, double *);
|
||||
void resistance(int); /* Computes resistance coeff. */
|
||||
void demands(void); /* Computes current demands */
|
||||
int controls(void); /* Controls link settings */
|
||||
long timestep(void); /* Computes new time step */
|
||||
void tanktimestep(long *); /* Time till tanks fill/drain */
|
||||
void controltimestep(long *); /* Time till control action */
|
||||
void ruletimestep(long *); /* Time till rule action */
|
||||
void addenergy(long); /* Accumulates energy usage */
|
||||
void getenergy(int, double *, double *); /* Computes link energy use */
|
||||
void tanklevels(long); /* Computes new tank levels */
|
||||
double tankvolume(int,double); /* Finds tank vol. from grade */
|
||||
double tankgrade(int,double); /* Finds tank grade from vol. */
|
||||
int netsolve(int *,double *); /* Solves network equations */
|
||||
int badvalve(int); /* Checks for bad valve */
|
||||
int valvestatus(void); /* Updates valve status */
|
||||
int linkstatus(void); /* Updates link status */
|
||||
char cvstatus(char,double,double); /* Updates CV status */
|
||||
char pumpstatus(int,double); /* Updates pump status */
|
||||
char prvstatus(int,char,double, /* Updates PRV status */
|
||||
double,double);
|
||||
char psvstatus(int,char,double, /* Updates PSV status */
|
||||
double,double);
|
||||
char fcvstatus(int,char,double, /* Updates FCV status */
|
||||
double);
|
||||
void tankstatus(int,int,int); /* Checks if tank full/empty */
|
||||
int pswitch(void); /* Pressure switch controls */
|
||||
double newflows(void); /* Updates link flows */
|
||||
void newcoeffs(void); /* Computes matrix coeffs. */
|
||||
void linkcoeffs(void); /* Computes link coeffs. */
|
||||
void nodecoeffs(void); /* Computes node coeffs. */
|
||||
void valvecoeffs(void); /* Computes valve coeffs. */
|
||||
void pipecoeff(int); /* Computes pipe coeff. */
|
||||
double DWcoeff(int, double *); /* Computes D-W coeff. */
|
||||
void pumpcoeff(int); /* Computes pump coeff. */
|
||||
|
||||
/*** Updated 10/25/00 ***/
|
||||
/*** Updated 12/29/00 ***/
|
||||
void curvecoeff(int,double,double *, /* Computes curve coeffs. */
|
||||
double *);
|
||||
|
||||
void gpvcoeff(int); /* Computes GPV coeff. */
|
||||
void pbvcoeff(int); /* Computes PBV coeff. */
|
||||
void tcvcoeff(int); /* Computes TCV coeff. */
|
||||
void prvcoeff(int,int,int); /* Computes PRV coeff. */
|
||||
void psvcoeff(int,int,int); /* Computes PSV coeff. */
|
||||
void fcvcoeff(int,int,int); /* Computes FCV coeff. */
|
||||
void emittercoeffs(void); /* Computes emitter coeffs. */
|
||||
double emitflowchange(int); /* Computes new emitter flow */
|
||||
|
||||
/* ----------- SMATRIX.C ---------------*/
|
||||
int createsparse(void); /* Creates sparse matrix */
|
||||
int allocsparse(void); /* Allocates matrix memory */
|
||||
void freesparse(void); /* Frees matrix memory */
|
||||
int buildlists(int); /* Builds adjacency lists */
|
||||
int paralink(int, int, int); /* Checks for parallel links */
|
||||
void xparalinks(void); /* Removes parallel links */
|
||||
void freelists(void); /* Frees adjacency lists */
|
||||
void countdegree(void); /* Counts links at each node */
|
||||
int reordernodes(void); /* Finds a node re-ordering */
|
||||
int mindegree(int, int); /* Finds min. degree node */
|
||||
int growlist(int); /* Augments adjacency list */
|
||||
int newlink(Padjlist); /* Adds fill-ins for a node */
|
||||
int linked(int, int); /* Checks if 2 nodes linked */
|
||||
int addlink(int, int, int); /* Creates new fill-in */
|
||||
int storesparse(int); /* Stores sparse matrix */
|
||||
int ordersparse(int); /* Orders matrix storage */
|
||||
void transpose(int,int *,int *, /* Transposes sparse matrix */
|
||||
int *,int *,int *,int *,int *);
|
||||
int linsolve(int, double *, double *, /* Solution of linear eqns. */
|
||||
double *); /* via Cholesky factorization */
|
||||
|
||||
/* ----------- QUALITY.C ---------------*/
|
||||
int openqual(void); /* Opens WQ solver system */
|
||||
void initqual(void); /* Initializes WQ solver */
|
||||
int runqual(long *); /* Gets current WQ results */
|
||||
int nextqual(long *); /* Updates WQ by hyd.timestep */
|
||||
int stepqual(long *); /* Updates WQ by WQ time step */
|
||||
int closequal(void); /* Closes WQ solver system */
|
||||
int gethyd(long *, long *); /* Gets next hyd. results */
|
||||
char setReactflag(void); /* Checks for reactive chem. */
|
||||
void transport(long); /* Transports mass in network */
|
||||
void initsegs(void); /* Initializes WQ segments */
|
||||
void reorientsegs(void); /* Re-orients WQ segments */
|
||||
void updatesegs(long); /* Updates quality in segments*/
|
||||
void removesegs(int); /* Removes a WQ segment */
|
||||
void addseg(int,double,double); /* Adds a WQ segment to pipe */
|
||||
void accumulate(long); /* Sums mass flow into node */
|
||||
void updatenodes(long); /* Updates WQ at nodes */
|
||||
void sourceinput(long); /* Computes source inputs */
|
||||
void release(long); /* Releases mass from nodes */
|
||||
void updatetanks(long); /* Updates WQ in tanks */
|
||||
void updatesourcenodes(long); /* Updates WQ at source nodes */
|
||||
void tankmix1(int, long); /* Complete mix tank model */
|
||||
void tankmix2(int, long); /* 2-compartment tank model */
|
||||
void tankmix3(int, long); /* FIFO tank model */
|
||||
void tankmix4(int, long); /* LIFO tank model */
|
||||
double sourcequal(Psource); /* Finds WQ input from source */
|
||||
double avgqual(int); /* Finds avg. quality in pipe */
|
||||
void ratecoeffs(void); /* Finds wall react. coeffs. */
|
||||
double piperate(int); /* Finds wall react. coeff. */
|
||||
double pipereact(int,double,double,long);/* Reacts water in a pipe */
|
||||
double tankreact(double,double,double,
|
||||
long); /* Reacts water in a tank */
|
||||
double bulkrate(double,double,double); /* Finds bulk reaction rate */
|
||||
double wallrate(double,double,double,double);/* Finds wall reaction rate */
|
||||
|
||||
|
||||
/* ------------ OUTPUT.C ---------------*/
|
||||
int savenetdata(void); /* Saves basic data to file */
|
||||
int savehyd(long *); /* Saves hydraulic solution */
|
||||
int savehydstep(long *); /* Saves hydraulic timestep */
|
||||
int saveenergy(void); /* Saves energy usage */
|
||||
int readhyd(long *); /* Reads hydraulics from file */
|
||||
int readhydstep(long *); /* Reads time step from file */
|
||||
int saveoutput(void); /* Saves results to file */
|
||||
int nodeoutput(int, REAL4 *, double); /* Saves node results to file */
|
||||
int linkoutput(int, REAL4 *, double); /* Saves link results to file */
|
||||
int savefinaloutput(void); /* Finishes saving output */
|
||||
int savetimestat(REAL4 *, char); /* Saves time stats to file */
|
||||
int savenetreacts(double, double,
|
||||
double, double); /* Saves react. rates to file */
|
||||
int saveepilog(void); /* Saves output file epilog */
|
||||
|
||||
|
||||
/* ------------ INPFILE.C --------------*/
|
||||
int saveinpfile(char *); /* Saves network to text file */
|
||||
|
||||
#endif
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: funcs.h
|
||||
Description: prototypes of external functions called by various modules
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 11/15/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef FUNCS_H
|
||||
#define FUNCS_H
|
||||
|
||||
// ------- PROJECT.C ------------
|
||||
|
||||
void initpointers(Project *);
|
||||
int allocdata(Project *);
|
||||
void freedata(Project *);
|
||||
|
||||
int openfiles(Project *, const char *, const char *,const char *);
|
||||
int openhydfile(Project *);
|
||||
int openoutfile(Project *);
|
||||
void closeoutfile(Project *);
|
||||
|
||||
int buildadjlists(Network *);
|
||||
void freeadjlists(Network *);
|
||||
|
||||
int incontrols(Project *, int, int);
|
||||
int valvecheck(Project *, int, int, int, int);
|
||||
int findnode(Network *, char *);
|
||||
int findlink(Network *, char *);
|
||||
int findtank(Network *, int);
|
||||
int findvalve(Network *, int);
|
||||
int findpump(Network *, int);
|
||||
int findpattern(Network *, char *);
|
||||
int findcurve(Network *, char *);
|
||||
|
||||
Pdemand finddemand(Pdemand, int);
|
||||
int adddemand(Snode *, double, int, char *);
|
||||
void freedemands(Snode *);
|
||||
|
||||
int addlinkvertex(Slink *, double, double);
|
||||
void freelinkvertices(Slink *);
|
||||
|
||||
void adjustpatterns(Network *, int);
|
||||
void adjustcurves(Network *, int);
|
||||
int adjustpumpparams(Project *, int);
|
||||
int resizecurve(Scurve *, int);
|
||||
|
||||
int getcomment(Network *, int, int, char *);
|
||||
int setcomment(Network *, int, int, const char *);
|
||||
|
||||
int namevalid(const char *);
|
||||
void getTmpName(char *);
|
||||
char *xstrcpy(char **, const char *, const size_t n);
|
||||
int strcomp(const char *, const char *);
|
||||
double interp(int, double [], double [], double);
|
||||
char *geterrmsg(int, char *);
|
||||
void errmsg(Project *, int);
|
||||
void writewin(void (*vp)(char *), char *);
|
||||
|
||||
// ------- INPUT1.C ----------------
|
||||
|
||||
int getdata(Project *);
|
||||
void setdefaults(Project *);
|
||||
void initreport(Report *);
|
||||
void adjustdata(Project *);
|
||||
int inittanks(Project *);
|
||||
void initunits(Project *);
|
||||
void convertunits(Project *);
|
||||
|
||||
//-------- INPUT2.C -----------------
|
||||
|
||||
int netsize(Project *);
|
||||
int readdata(Project *);
|
||||
int updatepumpparams(Project *, int);
|
||||
int findmatch(char *, char *[]);
|
||||
int match(const char *, const char *);
|
||||
int gettokens(char *, char **, int, char *);
|
||||
int getfloat(char *, double *);
|
||||
double hour(char *, char *);
|
||||
int setreport(Project *, char *);
|
||||
|
||||
// ------- INPUT3.C -----------------
|
||||
|
||||
int juncdata(Project *);
|
||||
int tankdata(Project *);
|
||||
int pipedata(Project *);
|
||||
int pumpdata(Project *);
|
||||
int valvedata(Project *);
|
||||
int patterndata(Project *);
|
||||
int curvedata(Project *);
|
||||
int coordata(Project *);
|
||||
int demanddata(Project *);
|
||||
int controldata(Project *);
|
||||
int energydata(Project *);
|
||||
int sourcedata(Project *);
|
||||
int emitterdata(Project *);
|
||||
int qualdata(Project *);
|
||||
int reactdata(Project *);
|
||||
int mixingdata(Project *);
|
||||
int statusdata(Project *);
|
||||
int reportdata(Project *);
|
||||
int timedata(Project *);
|
||||
int optiondata(Project *);
|
||||
int vertexdata(Project *);
|
||||
|
||||
// ------- RULES.C ------------------
|
||||
|
||||
void initrules(Project *);
|
||||
void addrule(Parser *, char *);
|
||||
void deleterule(Project *, int);
|
||||
int allocrules(Project *);
|
||||
void freerules(Project *);
|
||||
int ruledata(Project *);
|
||||
void ruleerrmsg(Project *);
|
||||
void adjustrules(Project *, int, int);
|
||||
void adjusttankrules(Project *);
|
||||
Spremise *getpremise(Spremise *, int);
|
||||
Saction *getaction(Saction *, int);
|
||||
int writerule(Project *, FILE *, int);
|
||||
int checkrules(Project *, long);
|
||||
|
||||
// ------- REPORT.C -----------------
|
||||
|
||||
int clearreport(Project *);
|
||||
int copyreport(Project *, char *);
|
||||
int writereport(Project *);
|
||||
void writelogo(Project *);
|
||||
void writesummary(Project *);
|
||||
void writehydstat(Project *, int, double);
|
||||
void writeheader(Project *, int,int);
|
||||
void writeline(Project *, char *);
|
||||
void writerelerr(Project *, int, double);
|
||||
void writestatchange(Project *, int,char,char);
|
||||
void writecontrolaction(Project *, int, int);
|
||||
void writeruleaction(Project *, int, char *);
|
||||
int writehydwarn(Project *, int,double);
|
||||
void writehyderr(Project *, int);
|
||||
void writemassbalance(Project *);
|
||||
void writetime(Project *, char *);
|
||||
char *clocktime(char *, long);
|
||||
|
||||
// ------- HYDRAUL.C -----------------
|
||||
|
||||
int openhyd(Project *);
|
||||
void inithyd(Project *, int initFlags);
|
||||
int runhyd(Project *, long *);
|
||||
int nexthyd(Project *, long *);
|
||||
void closehyd(Project *);
|
||||
void setlinkstatus(Project *, int, char, StatusType *, double *);
|
||||
void setlinksetting(Project *, int, double, StatusType *, double *);
|
||||
int tanktimestep(Project *, long *);
|
||||
void getenergy(Project *, int, double *, double *);
|
||||
double tankvolume(Project *, int, double);
|
||||
double tankgrade(Project *, int, double);
|
||||
|
||||
// ------- HYDCOEFFS.C -----------------
|
||||
|
||||
void resistcoeff(Project *, int);
|
||||
void headlosscoeffs(Project *);
|
||||
void matrixcoeffs(Project *);
|
||||
void emitterheadloss(Project *, int, double *, double *);
|
||||
void demandheadloss(Project *, int, double, double, double *, double *);
|
||||
|
||||
// ------- QUALITY.C --------------------
|
||||
|
||||
int openqual(Project *);
|
||||
int initqual(Project *);
|
||||
int runqual(Project *, long *);
|
||||
int nextqual(Project *, long *);
|
||||
int stepqual(Project *, long *);
|
||||
int closequal(Project *);
|
||||
double avgqual(Project *, int);
|
||||
|
||||
// ------- OUTPUT.C ---------------------
|
||||
|
||||
int savenetdata(Project *);
|
||||
int savehyd(Project *, long *);
|
||||
int savehydstep(Project *, long *);
|
||||
int saveenergy(Project *);
|
||||
int readhyd(Project *, long *);
|
||||
int readhydstep(Project *, long *);
|
||||
int saveoutput(Project *);
|
||||
int savefinaloutput(Project *);
|
||||
|
||||
// ------- INPFILE.C --------------------
|
||||
|
||||
int saveinpfile(Project *, const char *);
|
||||
|
||||
#endif
|
||||
|
||||
1000
src/genmmd.c
Normal file
1000
src/genmmd.c
Normal file
File diff suppressed because it is too large
Load Diff
250
src/hash.c
250
src/hash.c
@@ -1,127 +1,177 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
** hash.c
|
||||
**
|
||||
** Implementation of a simple Hash Table for string storage & retrieval
|
||||
**
|
||||
** Written by L. Rossman
|
||||
** Last Updated on 6/19/03
|
||||
**
|
||||
** The hash table data structure (HTable) is defined in "hash.h".
|
||||
** Interface Functions:
|
||||
** HTcreate() - creates a hash table
|
||||
** HTinsert() - inserts a string & its index value into a hash table
|
||||
** HTfind() - retrieves the index value of a string from a table
|
||||
** HTfree() - frees a hash table
|
||||
**
|
||||
*********************************************************************
|
||||
** NOTE: This is a modified version of the original HASH.C module.
|
||||
*********************************************************************
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: hash.c
|
||||
Description: implementation of a simple hash table
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/15/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "hash.h"
|
||||
|
||||
unsigned int _enHash(char *str);
|
||||
unsigned int _enHash(char *str)
|
||||
{
|
||||
unsigned int hash = 5381;
|
||||
unsigned int retHash;
|
||||
int c;
|
||||
while ((c = *str++)) {
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
}
|
||||
retHash = hash % ENHASHTABLEMAXSIZE;
|
||||
return retHash;
|
||||
}
|
||||
#define HASHTABLEMAXSIZE 128000
|
||||
|
||||
ENHashTable *ENHashTableCreate()
|
||||
// An entry in the hash table
|
||||
typedef struct DataEntryStruct
|
||||
{
|
||||
int i;
|
||||
ENHashTable *ht = (ENHashTable *) calloc(ENHASHTABLEMAXSIZE, sizeof(ENHashTable));
|
||||
if (ht != NULL) {
|
||||
for (i=0; i<ENHASHTABLEMAXSIZE; i++) {
|
||||
ht[i] = NULL;
|
||||
char *key;
|
||||
int data;
|
||||
struct DataEntryStruct *next;
|
||||
} DataEntry;
|
||||
|
||||
// Hash a string to an integer
|
||||
unsigned int gethash(char *str)
|
||||
{
|
||||
unsigned int hash = 5381;
|
||||
unsigned int retHash;
|
||||
int c;
|
||||
while ((c = *str++))
|
||||
{
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
}
|
||||
}
|
||||
return(ht);
|
||||
retHash = hash % HASHTABLEMAXSIZE;
|
||||
return retHash;
|
||||
}
|
||||
|
||||
int ENHashTableInsert(ENHashTable *ht, char *key, int data)
|
||||
// Produce a duplicate string
|
||||
char *dupstr(const char *s)
|
||||
{
|
||||
size_t len;
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(0);
|
||||
}
|
||||
entry = (ENHashEntry *) malloc(sizeof(ENHashEntry));
|
||||
if (entry == NULL) {
|
||||
return(0);
|
||||
}
|
||||
len = strlen(key) + 1;
|
||||
entry->key = calloc(len, sizeof(char));
|
||||
strncpy(entry->key, key, len);
|
||||
entry->data = data;
|
||||
entry->next = ht[i];
|
||||
ht[i] = entry;
|
||||
return(1);
|
||||
size_t size = strlen(s) + 1;
|
||||
char *p = malloc(size);
|
||||
if (p) memcpy(p, s, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
int ENHashTableFind(ENHashTable *ht, char *key)
|
||||
// Create a hash table
|
||||
HashTable *hashtable_create()
|
||||
{
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(NOTFOUND);
|
||||
}
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key,key) == 0 ) {
|
||||
return(entry->data);
|
||||
int i;
|
||||
HashTable *ht = (HashTable *) calloc(HASHTABLEMAXSIZE, sizeof(HashTable));
|
||||
if (ht != NULL)
|
||||
{
|
||||
for (i = 0; i < HASHTABLEMAXSIZE; i++) ht[i] = NULL;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return(NOTFOUND);
|
||||
return ht;
|
||||
}
|
||||
|
||||
char *ENHashTableFindKey(ENHashTable *ht, char *key)
|
||||
// Insert an entry into the hash table
|
||||
int hashtable_insert(HashTable *ht, char *key, int data)
|
||||
{
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(NULL);
|
||||
}
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key,key) == 0 ) {
|
||||
return(entry->key);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return(NULL);
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
if ( i >= HASHTABLEMAXSIZE ) return 0;
|
||||
entry = (DataEntry *) malloc(sizeof(DataEntry));
|
||||
if (entry == NULL) return(0);
|
||||
entry->key = dupstr(key);
|
||||
entry->data = data;
|
||||
entry->next = ht[i];
|
||||
ht[i] = entry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ENHashTableFree(ENHashTable *ht)
|
||||
// Change the hash table's data entry for a particular key
|
||||
int hashtable_update(HashTable *ht, char *key, int new_data)
|
||||
{
|
||||
ENHashEntry *entry, *nextentry;
|
||||
int i;
|
||||
for (i=0; i<ENHASHTABLEMAXSIZE; i++)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NOTFOUND;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
nextentry = entry->next;
|
||||
free(entry->key);
|
||||
free(entry);
|
||||
entry = nextentry;
|
||||
if ( strcmp(entry->key, key) == 0 )
|
||||
{
|
||||
entry->data = new_data;
|
||||
return 1;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
free(ht);
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
// Delete an entry in the hash table
|
||||
int hashtable_delete(HashTable *ht, char *key)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry, *preventry;
|
||||
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NOTFOUND;
|
||||
|
||||
preventry = NULL;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if (strcmp(entry->key, key) == 0)
|
||||
{
|
||||
if (preventry == NULL) ht[i] = entry->next;
|
||||
else preventry->next = entry->next;
|
||||
free(entry->key);
|
||||
free(entry);
|
||||
return 1;
|
||||
}
|
||||
preventry = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
// Find the data for a particular key
|
||||
int hashtable_find(HashTable *ht, char *key)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NOTFOUND;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key, key) == 0 )
|
||||
{
|
||||
return entry->data;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
// Find a particular key in the hash table
|
||||
char *hashtable_findkey(HashTable *ht, char *key)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NULL;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key, key) == 0 ) return entry->key;
|
||||
entry = entry->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Delete a hash table and free all of its memory
|
||||
void hashtable_free(HashTable *ht)
|
||||
{
|
||||
DataEntry *entry, *nextentry;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HASHTABLEMAXSIZE; i++)
|
||||
{
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
nextentry = entry->next;
|
||||
free(entry->key);
|
||||
free(entry);
|
||||
entry = nextentry;
|
||||
}
|
||||
ht[i] = NULL;
|
||||
}
|
||||
free(ht);
|
||||
}
|
||||
|
||||
40
src/hash.h
40
src/hash.h
@@ -1,28 +1,28 @@
|
||||
/* HASH.H
|
||||
**
|
||||
** Header file for Hash Table module HASH.C
|
||||
**
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: hash.h
|
||||
Description: header for a simple hash table
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 11/27/2018
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
#define ENHASHTABLEMAXSIZE 128000
|
||||
#define NOTFOUND 0
|
||||
|
||||
typedef struct HTentryStruct
|
||||
{
|
||||
char *key;
|
||||
int data;
|
||||
struct HTentryStruct *next;
|
||||
} ENHashEntry;
|
||||
typedef struct DataEntryStruct *HashTable;
|
||||
|
||||
typedef ENHashEntry *ENHashTable;
|
||||
HashTable *hashtable_create(void);
|
||||
int hashtable_insert(HashTable *, char *, int);
|
||||
int hashtable_find(HashTable *, char *);
|
||||
char *hashtable_findkey(HashTable *, char *);
|
||||
void hashtable_free(HashTable *);
|
||||
int hashtable_update(HashTable *ht, char *key, int new_data);
|
||||
int hashtable_delete(HashTable *ht, char *key);
|
||||
|
||||
ENHashTable *ENHashTableCreate(void);
|
||||
int ENHashTableInsert(ENHashTable *, char *, int);
|
||||
int ENHashTableFind(ENHashTable *, char *);
|
||||
char *ENHashTableFindKey(ENHashTable *, char *);
|
||||
void ENHashTableFree(ENHashTable *);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
1151
src/hydcoeffs.c
Normal file
1151
src/hydcoeffs.c
Normal file
File diff suppressed because it is too large
Load Diff
3625
src/hydraul.c
3625
src/hydraul.c
File diff suppressed because it is too large
Load Diff
720
src/hydsolver.c
Normal file
720
src/hydsolver.c
Normal file
@@ -0,0 +1,720 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: hydsolver.c
|
||||
Description: computes flows and pressures throughout a pipe network using
|
||||
Todini's Global Gradient Algorithm
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 07/15/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "funcs.h"
|
||||
#include "text.h"
|
||||
|
||||
// Hydraulic balance error for network being analyzed
|
||||
typedef struct {
|
||||
double maxheaderror;
|
||||
double maxflowerror;
|
||||
double maxflowchange;
|
||||
int maxheadlink;
|
||||
int maxflownode;
|
||||
int maxflowlink;
|
||||
} Hydbalance;
|
||||
|
||||
// Exported functions
|
||||
int hydsolve(Project *, int *, double *);
|
||||
|
||||
// Imported functions
|
||||
extern int linsolve(Smatrix *, int); //(see SMATRIX.C)
|
||||
extern int valvestatus(Project *); //(see HYDSTATUS.C)
|
||||
extern int linkstatus(Project *); //(see HYDSTATUS.C)
|
||||
|
||||
// Local functions
|
||||
static int badvalve(Project *, int);
|
||||
static int pswitch(Project *);
|
||||
|
||||
static double newflows(Project *, Hydbalance *);
|
||||
static void newlinkflows(Project *, Hydbalance *, double *, double *);
|
||||
static void newemitterflows(Project *, Hydbalance *, double *, double *);
|
||||
static void newdemandflows(Project *, Hydbalance *, double *, double *);
|
||||
|
||||
static void checkhydbalance(Project *, Hydbalance *);
|
||||
static int hasconverged(Project *, double *, Hydbalance *);
|
||||
static int pdaconverged(Project *);
|
||||
static void reporthydbal(Project *, Hydbalance *);
|
||||
|
||||
|
||||
int hydsolve(Project *pr, int *iter, double *relerr)
|
||||
/*
|
||||
**-------------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: *iter = # of iterations to reach solution
|
||||
** *relerr = convergence error in solution
|
||||
** returns error code
|
||||
** Purpose: solves network nodal equations for heads and flows
|
||||
** using Todini's Gradient algorithm
|
||||
**
|
||||
** Notes: Status checks on CVs, pumps and pipes to tanks are made
|
||||
** every CheckFreq iteration, up until MaxCheck iterations
|
||||
** are reached. Status checks on control valves are made
|
||||
** every iteration if DampLimit = 0 or only when the
|
||||
** convergence error is at or below DampLimit. If DampLimit
|
||||
** is > 0 then future computed flow changes are only 60% of
|
||||
** their full value. A complete status check on all links
|
||||
** is made when convergence is achieved. If convergence is
|
||||
** not achieved in MaxIter trials and ExtraIter > 0 then
|
||||
** another ExtraIter trials are made with no status changes
|
||||
** made to any links and a warning message is generated.
|
||||
**
|
||||
** This procedure calls linsolve() which appears in SMATRIX.C.
|
||||
**-------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Smatrix *sm = &hyd->smatrix;
|
||||
Report *rpt = &pr->report;
|
||||
|
||||
int i; // Node index
|
||||
int errcode = 0; // Node causing solution error
|
||||
int nextcheck; // Next status check trial
|
||||
int maxtrials; // Max. trials for convergence
|
||||
double newerr; // New convergence error
|
||||
int valveChange; // Valve status change flag
|
||||
int statChange; // Non-valve status change flag
|
||||
Hydbalance hydbal; // Hydraulic balance errors
|
||||
double fullDemand; // Full demand for a node (cfs)
|
||||
|
||||
// Initialize status checking & relaxation factor
|
||||
nextcheck = hyd->CheckFreq;
|
||||
hyd->RelaxFactor = 1.0;
|
||||
|
||||
// Initialize convergence criteria and PDA results
|
||||
hydbal.maxheaderror = 0.0;
|
||||
hydbal.maxflowchange = 0.0;
|
||||
hyd->DeficientNodes = 0;
|
||||
hyd->DemandReduction = 0.0;
|
||||
|
||||
// Repeat iterations until convergence or trial limit is exceeded.
|
||||
// (ExtraIter used to increase trials in case of status cycling.)
|
||||
if (rpt->Statflag == FULL) writerelerr(pr, 0, 0);
|
||||
maxtrials = hyd->MaxIter;
|
||||
if (hyd->ExtraIter > 0) maxtrials += hyd->ExtraIter;
|
||||
*iter = 1;
|
||||
while (*iter <= maxtrials)
|
||||
{
|
||||
// Compute coefficient matrices A & F and solve A*H = F
|
||||
// where H = heads, A = Jacobian coeffs. derived from
|
||||
// head loss gradients, & F = flow correction terms.
|
||||
// Solution for H is returned in F from call to linsolve().
|
||||
|
||||
headlosscoeffs(pr);
|
||||
matrixcoeffs(pr);
|
||||
errcode = linsolve(sm, net->Njuncs);
|
||||
|
||||
// Matrix ill-conditioning problem - if control valve causing problem,
|
||||
// fix its status & continue, otherwise quit with no solution.
|
||||
if (errcode > 0)
|
||||
{
|
||||
if (badvalve(pr, sm->Order[errcode])) continue;
|
||||
else break;
|
||||
}
|
||||
|
||||
// Update current solution.
|
||||
// (Row[i] = row of solution matrix corresponding to node i)
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
hyd->NodeHead[i] = sm->F[sm->Row[i]]; // Update heads
|
||||
}
|
||||
newerr = newflows(pr, &hydbal); // Update flows
|
||||
*relerr = newerr;
|
||||
|
||||
// Write convergence error to status report if called for
|
||||
if (rpt->Statflag == FULL)
|
||||
{
|
||||
writerelerr(pr, *iter, *relerr);
|
||||
}
|
||||
|
||||
// Apply solution damping & check for change in valve status
|
||||
hyd->RelaxFactor = 1.0;
|
||||
valveChange = FALSE;
|
||||
if (hyd->DampLimit > 0.0)
|
||||
{
|
||||
if (*relerr <= hyd->DampLimit)
|
||||
{
|
||||
hyd->RelaxFactor = 0.6;
|
||||
valveChange = valvestatus(pr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
valveChange = valvestatus(pr);
|
||||
}
|
||||
|
||||
// Check for convergence
|
||||
if (hasconverged(pr, relerr, &hydbal))
|
||||
{
|
||||
// We have convergence - quit if we are into extra iterations
|
||||
if (*iter > hyd->MaxIter) break;
|
||||
|
||||
// Quit if no status changes occur
|
||||
statChange = FALSE;
|
||||
if (valveChange) statChange = TRUE;
|
||||
if (linkstatus(pr)) statChange = TRUE;
|
||||
if (pswitch(pr)) statChange = TRUE;
|
||||
if (!statChange) break;
|
||||
|
||||
// We have a status change so continue the iterations
|
||||
nextcheck = *iter + hyd->CheckFreq;
|
||||
}
|
||||
|
||||
// No convergence yet - see if its time for a periodic status
|
||||
// check on pumps, CV's, and pipes connected to tank
|
||||
else if (*iter <= hyd->MaxCheck && *iter == nextcheck)
|
||||
{
|
||||
linkstatus(pr);
|
||||
nextcheck += hyd->CheckFreq;
|
||||
}
|
||||
(*iter)++;
|
||||
}
|
||||
|
||||
// Iterations ended - report any errors.
|
||||
if (errcode > 0)
|
||||
{
|
||||
writehyderr(pr, sm->Order[errcode]); // Ill-conditioned matrix error
|
||||
errcode = 110;
|
||||
}
|
||||
|
||||
// Store actual junction outflow in NodeDemand & full demand in DemandFlow
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
fullDemand = hyd->NodeDemand[i];
|
||||
hyd->NodeDemand[i] = hyd->DemandFlow[i] + hyd->EmitterFlow[i];
|
||||
hyd->DemandFlow[i] = fullDemand;
|
||||
}
|
||||
|
||||
// Save convergence info
|
||||
hyd->RelativeError = *relerr;
|
||||
hyd->MaxHeadError = hydbal.maxheaderror;
|
||||
hyd->MaxFlowChange = hydbal.maxflowchange;
|
||||
hyd->Iterations = *iter;
|
||||
return errcode;
|
||||
}
|
||||
|
||||
|
||||
int badvalve(Project *pr, int n)
|
||||
/*
|
||||
**-----------------------------------------------------------------
|
||||
** Input: n = node index
|
||||
** Output: returns 1 if node n belongs to an active control valve,
|
||||
** 0 otherwise
|
||||
** Purpose: determines if a node belongs to an active control valve
|
||||
** whose setting causes an inconsistent set of eqns. If so,
|
||||
** the valve status is fixed open and a warning condition
|
||||
** is generated.
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Report *rpt = &pr->report;
|
||||
Times *time = &pr->times;
|
||||
|
||||
int i, k, n1, n2;
|
||||
Slink *link;
|
||||
LinkType t;
|
||||
|
||||
for (i = 1; i <= net->Nvalves; i++)
|
||||
{
|
||||
k = net->Valve[i].Link;
|
||||
link = &net->Link[k];
|
||||
n1 = link->N1;
|
||||
n2 = link->N2;
|
||||
if (n == n1 || n == n2)
|
||||
{
|
||||
t = link->Type;
|
||||
if (t == PRV || t == PSV || t == FCV)
|
||||
{
|
||||
if (hyd->LinkStatus[k] == ACTIVE)
|
||||
{
|
||||
if (rpt->Statflag == FULL)
|
||||
{
|
||||
sprintf(pr->Msg, FMT61,
|
||||
clocktime(rpt->Atime, time->Htime), link->ID);
|
||||
writeline(pr, pr->Msg);
|
||||
}
|
||||
if (link->Type == FCV) hyd->LinkStatus[k] = XFCV;
|
||||
else hyd->LinkStatus[k] = XPRESSURE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pswitch(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns 1 if status of any link changes, 0 if not
|
||||
** Purpose: adjusts settings of links controlled by junction
|
||||
** pressures after a hydraulic solution is found
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Report *rpt = &pr->report;
|
||||
|
||||
int i, // Control statement index
|
||||
k, // Index of link being controlled
|
||||
n, // Node controlling link k
|
||||
reset, // Flag on control conditions
|
||||
change, // Flag for status or setting change
|
||||
anychange = 0; // Flag for 1 or more control actions
|
||||
char s; // Current link status
|
||||
Slink *link;
|
||||
|
||||
// Check each control statement
|
||||
for (i = 1; i <= net->Ncontrols; i++)
|
||||
{
|
||||
reset = 0;
|
||||
k = net->Control[i].Link;
|
||||
if (k <= 0) continue;
|
||||
|
||||
// Determine if control based on a junction, not a tank
|
||||
n = net->Control[i].Node;
|
||||
if (n > 0 && n <= net->Njuncs)
|
||||
{
|
||||
// Determine if control conditions are satisfied
|
||||
if (net->Control[i].Type == LOWLEVEL &&
|
||||
hyd->NodeHead[n] <= net->Control[i].Grade + hyd->Htol)
|
||||
{
|
||||
reset = 1;
|
||||
}
|
||||
if (net->Control[i].Type == HILEVEL &&
|
||||
hyd->NodeHead[n] >= net->Control[i].Grade - hyd->Htol)
|
||||
{
|
||||
reset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if control forces a status or setting change
|
||||
if (reset == 1)
|
||||
{
|
||||
link = &net->Link[k];
|
||||
change = 0;
|
||||
s = hyd->LinkStatus[k];
|
||||
if (link->Type == PIPE)
|
||||
{
|
||||
if (s != net->Control[i].Status) change = 1;
|
||||
}
|
||||
if (link->Type == PUMP)
|
||||
{
|
||||
if (hyd->LinkSetting[k] != net->Control[i].Setting) change = 1;
|
||||
}
|
||||
if (link->Type >= PRV)
|
||||
{
|
||||
if (hyd->LinkSetting[k] != net->Control[i].Setting) change = 1;
|
||||
else if (hyd->LinkSetting[k] == MISSING && s != net->Control[i].Status)
|
||||
{
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If a change occurs, update status & setting
|
||||
if (change)
|
||||
{
|
||||
hyd->LinkStatus[k] = net->Control[i].Status;
|
||||
if (link->Type > PIPE)
|
||||
{
|
||||
hyd->LinkSetting[k] = net->Control[i].Setting;
|
||||
}
|
||||
if (rpt->Statflag == FULL)
|
||||
{
|
||||
writestatchange(pr, k, s, hyd->LinkStatus[k]);
|
||||
}
|
||||
anychange = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return anychange;
|
||||
}
|
||||
|
||||
|
||||
double newflows(Project *pr, Hydbalance *hbal)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: hbal = ptr. to hydraulic balance information
|
||||
** Output: returns solution convergence error
|
||||
** Purpose: updates link, emitter & demand flows after new
|
||||
** nodal heads are computed.
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
double dqsum, // Network flow change
|
||||
qsum; // Network total flow
|
||||
|
||||
// Initialize sum of flows & corrections
|
||||
qsum = 0.0;
|
||||
dqsum = 0.0;
|
||||
hbal->maxflowchange = 0.0;
|
||||
hbal->maxflowlink = 1;
|
||||
hbal->maxflownode = -1;
|
||||
|
||||
// Update flows in all real and virtual links
|
||||
newlinkflows(pr, hbal, &qsum, &dqsum);
|
||||
newemitterflows(pr, hbal, &qsum, &dqsum);
|
||||
newdemandflows(pr, hbal, &qsum, &dqsum);
|
||||
|
||||
// Return ratio of total flow corrections to total flow
|
||||
if (qsum > hyd->Hacc) return (dqsum / qsum);
|
||||
else return dqsum;
|
||||
}
|
||||
|
||||
|
||||
void newlinkflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: hbal = ptr. to hydraulic balance information
|
||||
** qsum = sum of current system flows
|
||||
** dqsum = sum of system flow changes
|
||||
** Output: updates hbal, qsum and dqsum
|
||||
** Purpose: updates link flows after new nodal heads computed
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
double dh, /* Link head loss */
|
||||
dq; /* Link flow change */
|
||||
int k, n, n1, n2;
|
||||
Slink *link;
|
||||
|
||||
// Initialize net inflows (i.e., demands) at fixed grade nodes
|
||||
for (n = net->Njuncs + 1; n <= net->Nnodes; n++)
|
||||
{
|
||||
hyd->NodeDemand[n] = 0.0;
|
||||
}
|
||||
|
||||
// Examine each link
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
// Get link and its end nodes
|
||||
link = &net->Link[k];
|
||||
n1 = link->N1;
|
||||
n2 = link->N2;
|
||||
|
||||
// Apply flow update formula:
|
||||
// dq = Y - P * (new head loss)
|
||||
// P = 1 / (previous head loss gradient)
|
||||
// Y = P * (previous head loss)
|
||||
// where P & Y were computed in hlosscoeff() in hydcoeffs.c
|
||||
|
||||
dh = hyd->NodeHead[n1] - hyd->NodeHead[n2];
|
||||
dq = hyd->Y[k] - hyd->P[k] * dh;
|
||||
|
||||
// Adjust flow change by the relaxation factor
|
||||
dq *= hyd->RelaxFactor;
|
||||
|
||||
// Prevent flow in constant HP pumps from going negative
|
||||
if (link->Type == PUMP)
|
||||
{
|
||||
n = findpump(net, k);
|
||||
if (net->Pump[n].Ptype == CONST_HP && dq > hyd->LinkFlow[k])
|
||||
{
|
||||
dq = hyd->LinkFlow[k] / 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Update link flow and system flow summation
|
||||
hyd->LinkFlow[k] -= dq;
|
||||
*qsum += ABS(hyd->LinkFlow[k]);
|
||||
*dqsum += ABS(dq);
|
||||
|
||||
// Update identity of element with max. flow change
|
||||
if (ABS(dq) > hbal->maxflowchange)
|
||||
{
|
||||
hbal->maxflowchange = ABS(dq);
|
||||
hbal->maxflowlink = k;
|
||||
hbal->maxflownode = -1;
|
||||
}
|
||||
|
||||
// Update net flows to fixed grade nodes
|
||||
if (hyd->LinkStatus[k] > CLOSED)
|
||||
{
|
||||
if (n1 > net->Njuncs) hyd->NodeDemand[n1] -= hyd->LinkFlow[k];
|
||||
if (n2 > net->Njuncs) hyd->NodeDemand[n2] += hyd->LinkFlow[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void newemitterflows(Project *pr, Hydbalance *hbal, double *qsum,
|
||||
double *dqsum)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: hbal = ptr. to hydraulic balance information
|
||||
** qsum = sum of current system flows
|
||||
** dqsum = sum of system flow changes
|
||||
** Output: updates hbal, qsum and dqsum
|
||||
** Purpose: updates nodal emitter flows after new nodal heads computed
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
int i;
|
||||
double hloss, hgrad, dh, dq;
|
||||
|
||||
// Examine each network junction
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
// Skip junction if it does not have an emitter
|
||||
if (net->Node[i].Ke == 0.0) continue;
|
||||
|
||||
// Find emitter head loss and gradient
|
||||
emitterheadloss(pr, i, &hloss, &hgrad);
|
||||
|
||||
// Find emitter flow change
|
||||
dh = hyd->NodeHead[i] - net->Node[i].El;
|
||||
dq = (hloss - dh) / hgrad;
|
||||
dq *= hyd->RelaxFactor;
|
||||
hyd->EmitterFlow[i] -= dq;
|
||||
|
||||
// Update system flow summation
|
||||
*qsum += ABS(hyd->EmitterFlow[i]);
|
||||
*dqsum += ABS(dq);
|
||||
|
||||
// Update identity of element with max. flow change
|
||||
if (ABS(dq) > hbal->maxflowchange)
|
||||
{
|
||||
hbal->maxflowchange = ABS(dq);
|
||||
hbal->maxflownode = i;
|
||||
hbal->maxflowlink = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void newdemandflows(Project *pr, Hydbalance *hbal, double *qsum, double *dqsum)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: hbal = ptr. to hydraulic balance information
|
||||
** qsum = sum of current system flows
|
||||
** dqsum = sum of system flow changes
|
||||
** Output: updates hbal, qsum and dqsum
|
||||
** Purpose: updates nodal pressure dependent demand flows after
|
||||
** new nodal heads computed
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
double dp, // pressure range over which demand can vary (ft)
|
||||
dq, // change in demand flow (cfs)
|
||||
n, // exponent in head loss v. demand function
|
||||
hloss, // current head loss through outflow junction (ft)
|
||||
hgrad, // head loss gradient with respect to flow (ft/cfs)
|
||||
dh; // new head loss through outflow junction (ft)
|
||||
int i;
|
||||
|
||||
// Get demand function parameters
|
||||
if (hyd->DemandModel == DDA) return;
|
||||
dp = MAX((hyd->Preq - hyd->Pmin), MINPDIFF);
|
||||
n = 1.0 / hyd->Pexp;
|
||||
|
||||
// Examine each junction
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
// Skip junctions with no positive demand
|
||||
if (hyd->NodeDemand[i] <= 0.0) continue;
|
||||
|
||||
// Find change in demand flow (see hydcoeffs.c)
|
||||
demandheadloss(pr, i, dp, n, &hloss, &hgrad);
|
||||
dh = hyd->NodeHead[i] - net->Node[i].El - hyd->Pmin;
|
||||
dq = (hloss - dh) / hgrad;
|
||||
dq *= hyd->RelaxFactor;
|
||||
hyd->DemandFlow[i] -= dq;
|
||||
|
||||
// Update system flow summation
|
||||
*qsum += ABS(hyd->DemandFlow[i]);
|
||||
*dqsum += ABS(dq);
|
||||
|
||||
// Update identity of element with max. flow change
|
||||
if (ABS(dq) > hbal->maxflowchange)
|
||||
{
|
||||
hbal->maxflowchange = ABS(dq);
|
||||
hbal->maxflownode = i;
|
||||
hbal->maxflowlink = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checkhydbalance(Project *pr, Hydbalance *hbal)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: hbal = hydraulic balance errors
|
||||
** Output: none
|
||||
** Purpose: finds the link with the largest head imbalance
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
int k, n1, n2;
|
||||
double dh, headerror, headloss;
|
||||
Slink *link;
|
||||
|
||||
hbal->maxheaderror = 0.0;
|
||||
hbal->maxheadlink = 1;
|
||||
headlosscoeffs(pr);
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
if (hyd->LinkStatus[k] <= CLOSED) continue;
|
||||
if (hyd->P[k] == 0.0) continue;
|
||||
link = &net->Link[k];
|
||||
n1 = link->N1;
|
||||
n2 = link->N2;
|
||||
dh = hyd->NodeHead[n1] - hyd->NodeHead[n2];
|
||||
headloss = hyd->Y[k] / hyd->P[k];
|
||||
headerror = ABS(dh - headloss);
|
||||
if (headerror > hbal->maxheaderror)
|
||||
{
|
||||
hbal->maxheaderror = headerror;
|
||||
hbal->maxheadlink = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int hasconverged(Project *pr, double *relerr, Hydbalance *hbal)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: relerr = current total relative flow change
|
||||
** hbal = current hydraulic balance errors
|
||||
** Output: returns 1 if system has converged or 0 if not
|
||||
** Purpose: checks various criteria to see if system has
|
||||
** become hydraulically balanced
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
// Check that total relative flow change is small enough
|
||||
if (*relerr > hyd->Hacc) return 0;
|
||||
|
||||
// Find largest head loss error and absolute flow change
|
||||
checkhydbalance(pr, hbal);
|
||||
if (pr->report.Statflag == FULL)
|
||||
{
|
||||
reporthydbal(pr, hbal);
|
||||
}
|
||||
|
||||
// Check that head loss error and flow change criteria are met
|
||||
if (hyd->HeadErrorLimit > 0.0 &&
|
||||
hbal->maxheaderror > hyd->HeadErrorLimit) return 0;
|
||||
if (hyd->FlowChangeLimit > 0.0 &&
|
||||
hbal->maxflowchange > hyd->FlowChangeLimit) return 0;
|
||||
|
||||
// Check for pressure driven analysis convergence
|
||||
if (hyd->DemandModel == PDA) return pdaconverged(pr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pdaconverged(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns 1 if PDA converged, 0 if not
|
||||
** Purpose: checks if pressure driven analysis has converged
|
||||
** and updates total demand deficit
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
const double TOL = 0.001;
|
||||
int i, converged = 1;
|
||||
double totalDemand = 0.0, totalReduction = 0.0;
|
||||
|
||||
hyd->DeficientNodes = 0;
|
||||
hyd->DemandReduction = 0.0;
|
||||
|
||||
// Add up number of junctions with demand deficits
|
||||
for (i = 1; i <= pr->network.Njuncs; i++)
|
||||
{
|
||||
// Skip nodes whose required demand is non-positive
|
||||
if (hyd->NodeDemand[i] <= 0.0) continue;
|
||||
|
||||
// Check for negative demand flow or positive demand flow at negative pressure
|
||||
if (hyd->DemandFlow[i] < -TOL) converged = 0;
|
||||
if (hyd->DemandFlow[i] > TOL &&
|
||||
hyd->NodeHead[i] - pr->network.Node[i].El - hyd->Pmin < -TOL)
|
||||
converged = 0;
|
||||
|
||||
// Accumulate total required demand and demand deficit
|
||||
if (hyd->DemandFlow[i] + 0.0001 < hyd->NodeDemand[i])
|
||||
{
|
||||
hyd->DeficientNodes++;
|
||||
totalDemand += hyd->NodeDemand[i];
|
||||
totalReduction += hyd->NodeDemand[i] - hyd->DemandFlow[i];
|
||||
}
|
||||
}
|
||||
if (totalDemand > 0.0)
|
||||
hyd->DemandReduction = totalReduction / totalDemand * 100.0;
|
||||
return converged;
|
||||
}
|
||||
|
||||
|
||||
void reporthydbal(Project *pr, Hydbalance *hbal)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: hbal = current hydraulic balance errors
|
||||
** Output: none
|
||||
** Purpose: identifies links with largest flow change and
|
||||
** largest head loss error.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
double qchange = hbal->maxflowchange * pr->Ucf[FLOW];
|
||||
double herror = hbal->maxheaderror * pr->Ucf[HEAD];
|
||||
int qlink = hbal->maxflowlink;
|
||||
int qnode = hbal->maxflownode;
|
||||
int hlink = hbal->maxheadlink;
|
||||
if (qlink >= 1)
|
||||
{
|
||||
sprintf(pr->Msg, FMT66, qchange, pr->network.Link[qlink].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
}
|
||||
else if (qnode >= 1)
|
||||
{
|
||||
sprintf(pr->Msg, FMT67, qchange, pr->network.Node[qnode].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
}
|
||||
if (hlink >= 1)
|
||||
{
|
||||
sprintf(pr->Msg, FMT68, herror, pr->network.Link[hlink].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
}
|
||||
}
|
||||
476
src/hydstatus.c
Normal file
476
src/hydstatus.c
Normal file
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: hydstatus.c
|
||||
Description: updates hydraulic status of network elements
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/15/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "funcs.h"
|
||||
|
||||
// Exported functions
|
||||
int valvestatus(Project *);
|
||||
int linkstatus(Project *);
|
||||
|
||||
// Local functions
|
||||
static StatusType cvstatus(Project *, StatusType, double, double);
|
||||
static StatusType pumpstatus(Project *, int, double);
|
||||
static StatusType prvstatus(Project *, int, StatusType, double, double, double);
|
||||
static StatusType psvstatus(Project *, int, StatusType, double, double, double);
|
||||
static StatusType fcvstatus(Project *, int, StatusType, double, double);
|
||||
static void tankstatus(Project *, int, int, int);
|
||||
|
||||
|
||||
int valvestatus(Project *pr)
|
||||
/*
|
||||
**-----------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns 1 if any pressure or flow control valve
|
||||
** changes status, 0 otherwise
|
||||
** Purpose: updates status for PRVs & PSVs whose status
|
||||
** is not fixed to OPEN/CLOSED
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Report *rpt = &pr->report;
|
||||
|
||||
int change = FALSE, // Status change flag
|
||||
i, k, // Valve & link indexes
|
||||
n1, n2; // Start & end nodes
|
||||
double hset; // Valve head setting
|
||||
StatusType status; // Valve status settings
|
||||
Slink *link;
|
||||
|
||||
// Examine each valve
|
||||
for (i = 1; i <= net->Nvalves; i++)
|
||||
{
|
||||
// Get valve's link and its index
|
||||
k = net->Valve[i].Link;
|
||||
link = &net->Link[k];
|
||||
|
||||
// Ignore valve if its status is fixed to OPEN/CLOSED
|
||||
if (hyd->LinkSetting[k] == MISSING) continue;
|
||||
|
||||
// Get start/end node indexes & save current status
|
||||
n1 = link->N1;
|
||||
n2 = link->N2;
|
||||
status = hyd->LinkStatus[k];
|
||||
|
||||
// Evaluate valve's new status
|
||||
switch (link->Type)
|
||||
{
|
||||
case PRV:
|
||||
hset = net->Node[n2].El + hyd->LinkSetting[k];
|
||||
hyd->LinkStatus[k] = prvstatus(pr, k, status, hset,
|
||||
hyd->NodeHead[n1], hyd->NodeHead[n2]);
|
||||
break;
|
||||
case PSV:
|
||||
hset = net->Node[n1].El + hyd->LinkSetting[k];
|
||||
hyd->LinkStatus[k] = psvstatus(pr, k, status, hset,
|
||||
hyd->NodeHead[n1], hyd->NodeHead[n2]);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for a status change
|
||||
if (status != hyd->LinkStatus[k])
|
||||
{
|
||||
if (rpt->Statflag == FULL)
|
||||
{
|
||||
writestatchange(pr, k, status, hyd->LinkStatus[k]);
|
||||
}
|
||||
change = TRUE;
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
int linkstatus(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns 1 if any link changes status, 0 otherwise
|
||||
** Purpose: determines new status for pumps, CVs, FCVs & pipes
|
||||
** to tanks.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Report *rpt = &pr->report;
|
||||
|
||||
int change = FALSE, // Status change flag
|
||||
k, // Link index
|
||||
n1, // Start node index
|
||||
n2; // End node index
|
||||
double dh; // Head difference across link
|
||||
StatusType status; // Current status
|
||||
Slink *link;
|
||||
|
||||
// Examine each link
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
link = &net->Link[k];
|
||||
n1 = link->N1;
|
||||
n2 = link->N2;
|
||||
dh = hyd->NodeHead[n1] - hyd->NodeHead[n2];
|
||||
|
||||
// Re-open temporarily closed links (status = XHEAD or TEMPCLOSED)
|
||||
status = hyd->LinkStatus[k];
|
||||
if (status == XHEAD || status == TEMPCLOSED)
|
||||
{
|
||||
hyd->LinkStatus[k] = OPEN;
|
||||
}
|
||||
|
||||
// Check for status changes in CVs and pumps
|
||||
if (link->Type == CVPIPE)
|
||||
{
|
||||
hyd->LinkStatus[k] = cvstatus(pr, hyd->LinkStatus[k], dh,
|
||||
hyd->LinkFlow[k]);
|
||||
}
|
||||
if (link->Type == PUMP && hyd->LinkStatus[k] >= OPEN &&
|
||||
hyd->LinkSetting[k] > 0.0)
|
||||
{
|
||||
hyd->LinkStatus[k] = pumpstatus(pr, k, -dh);
|
||||
}
|
||||
|
||||
// Check for status changes in non-fixed FCVs
|
||||
if (link->Type == FCV && hyd->LinkSetting[k] != MISSING)
|
||||
{
|
||||
hyd->LinkStatus[k] = fcvstatus(pr, k, status, hyd->NodeHead[n1],
|
||||
hyd->NodeHead[n2]);
|
||||
}
|
||||
|
||||
// Check for flow into (out of) full (empty) tanks
|
||||
if (n1 > net->Njuncs || n2 > net->Njuncs)
|
||||
{
|
||||
tankstatus(pr, k, n1, n2);
|
||||
}
|
||||
|
||||
// Note any change in link status; do not revise link flow
|
||||
if (status != hyd->LinkStatus[k])
|
||||
{
|
||||
change = TRUE;
|
||||
if (rpt->Statflag == FULL)
|
||||
{
|
||||
writestatchange(pr, k, status, hyd->LinkStatus[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
StatusType cvstatus(Project *pr, StatusType s, double dh, double q)
|
||||
/*
|
||||
**--------------------------------------------------
|
||||
** Input: s = current link status
|
||||
** dh = head loss across link
|
||||
** q = link flow
|
||||
** Output: returns new link status
|
||||
** Purpose: updates status of a check valve link.
|
||||
**--------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
// Prevent reverse flow through CVs
|
||||
if (ABS(dh) > hyd->Htol)
|
||||
{
|
||||
if (dh < -hyd->Htol) return CLOSED;
|
||||
else if (q < -hyd->Qtol) return CLOSED;
|
||||
else return OPEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (q < -hyd->Qtol) return CLOSED;
|
||||
else return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatusType pumpstatus(Project *pr, int k, double dh)
|
||||
/*
|
||||
**--------------------------------------------------
|
||||
** Input: k = link index
|
||||
** dh = head gain across link
|
||||
** Output: returns new pump status
|
||||
** Purpose: updates status of an open pump.
|
||||
**--------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Network *net = &pr->network;
|
||||
|
||||
int p;
|
||||
double hmax;
|
||||
|
||||
// Find maximum head (hmax) pump can deliver
|
||||
p = findpump(net, k);
|
||||
if (net->Pump[p].Ptype == CONST_HP)
|
||||
{
|
||||
// Use huge value for constant HP pump
|
||||
hmax = BIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use speed-adjusted shut-off head for other pumps
|
||||
hmax = SQR(hyd->LinkSetting[k]) * net->Pump[p].Hmax;
|
||||
}
|
||||
|
||||
// Check if currrent head gain exceeds pump's max. head
|
||||
if (dh > hmax + hyd->Htol) return XHEAD;
|
||||
|
||||
// No check is made to see if flow exceeds pump's max. flow
|
||||
return OPEN;
|
||||
}
|
||||
|
||||
|
||||
StatusType prvstatus(Project *pr, int k, StatusType s, double hset,
|
||||
double h1, double h2)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** s = current status
|
||||
** hset = valve head setting
|
||||
** h1 = head at upstream node
|
||||
** h2 = head at downstream node
|
||||
** Output: returns new valve status
|
||||
** Purpose: updates status of a pressure reducing valve.
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
StatusType status; // Valve's new status
|
||||
double hml; // Head loss when fully opened
|
||||
double htol;
|
||||
Slink *link;
|
||||
|
||||
htol = hyd->Htol;
|
||||
link = &pr->network.Link[k];
|
||||
|
||||
// Head loss when fully open
|
||||
hml = link->Km * SQR(hyd->LinkFlow[k]);
|
||||
|
||||
// Rules for updating valve's status from current value s
|
||||
status = s;
|
||||
switch (s)
|
||||
{
|
||||
case ACTIVE:
|
||||
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
||||
else if (h1 - hml < hset - htol) status = OPEN;
|
||||
else status = ACTIVE;
|
||||
break;
|
||||
|
||||
case OPEN:
|
||||
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
||||
else if (h2 >= hset + htol) status = ACTIVE;
|
||||
else status = OPEN;
|
||||
break;
|
||||
|
||||
case CLOSED:
|
||||
if (h1 >= hset + htol && h2 < hset - htol) status = ACTIVE;
|
||||
else if (h1 < hset - htol && h1 > h2 + htol) status = OPEN;
|
||||
else status = CLOSED;
|
||||
break;
|
||||
|
||||
case XPRESSURE:
|
||||
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
StatusType psvstatus(Project *pr, int k, StatusType s, double hset,
|
||||
double h1, double h2)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** s = current status
|
||||
** hset = valve head setting
|
||||
** h1 = head at upstream node
|
||||
** h2 = head at downstream node
|
||||
** Output: returns new valve status
|
||||
** Purpose: updates status of a pressure sustaining valve.
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
StatusType status; // Valve's new status
|
||||
double hml; // Head loss when fully opened
|
||||
double htol;
|
||||
Slink *link;
|
||||
|
||||
htol = hyd->Htol;
|
||||
link = &pr->network.Link[k];
|
||||
|
||||
// Head loss when fully open
|
||||
hml = link->Km * SQR(hyd->LinkFlow[k]);
|
||||
|
||||
// Rules for updating valve's status from current value s
|
||||
status = s;
|
||||
switch (s)
|
||||
{
|
||||
case ACTIVE:
|
||||
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
||||
else if (h2 + hml > hset + htol) status = OPEN;
|
||||
else status = ACTIVE;
|
||||
break;
|
||||
|
||||
case OPEN:
|
||||
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
||||
else if (h1 < hset - htol) status = ACTIVE;
|
||||
else status = OPEN;
|
||||
break;
|
||||
|
||||
case CLOSED:
|
||||
if (h2 > hset + htol && h1 > h2 + htol) status = OPEN;
|
||||
else if (h1 >= hset + htol && h1 > h2 + htol) status = ACTIVE;
|
||||
else status = CLOSED;
|
||||
break;
|
||||
|
||||
case XPRESSURE:
|
||||
if (hyd->LinkFlow[k] < -hyd->Qtol) status = CLOSED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
StatusType fcvstatus(Project *pr, int k, StatusType s, double h1, double h2)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** s = current status
|
||||
** h1 = head at upstream node
|
||||
** h2 = head at downstream node
|
||||
** Output: returns new valve status
|
||||
** Purpose: updates status of a flow control valve.
|
||||
**
|
||||
** Valve status changes to XFCV if flow reversal.
|
||||
** If current status is XFCV and current flow is
|
||||
** above setting, then valve becomes active.
|
||||
** If current status is XFCV, and current flow
|
||||
** positive but still below valve setting, then
|
||||
** status remains same.
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
StatusType status; // New valve status
|
||||
|
||||
status = s;
|
||||
if (h1 - h2 < -hyd->Htol)
|
||||
{
|
||||
status = XFCV;
|
||||
}
|
||||
else if (hyd->LinkFlow[k] < -hyd->Qtol)
|
||||
{
|
||||
status = XFCV;
|
||||
}
|
||||
else if (s == XFCV && hyd->LinkFlow[k] >= hyd->LinkSetting[k])
|
||||
{
|
||||
status = ACTIVE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void tankstatus(Project *pr, int k, int n1, int n2)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** n1 = start node of link
|
||||
** n2 = end node of link
|
||||
** Output: none
|
||||
** Purpose: closes link flowing into full or out of empty tank
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
|
||||
int i, n;
|
||||
double h, q;
|
||||
Stank *tank;
|
||||
Slink *link = &net->Link[k];
|
||||
|
||||
// Return if link is closed
|
||||
if (hyd->LinkStatus[k] <= CLOSED) return;
|
||||
|
||||
// Make node n1 be the tank, reversing flow (q) if need be
|
||||
q = hyd->LinkFlow[k];
|
||||
i = n1 - net->Njuncs;
|
||||
if (i <= 0)
|
||||
{
|
||||
i = n2 - net->Njuncs;
|
||||
if (i <= 0) return;
|
||||
n = n1;
|
||||
n1 = n2;
|
||||
n2 = n;
|
||||
q = -q;
|
||||
}
|
||||
|
||||
// Ignore reservoirs
|
||||
tank = &net->Tank[i];
|
||||
if (tank->A == 0.0) return;
|
||||
|
||||
// Find head difference across link
|
||||
h = hyd->NodeHead[n1] - hyd->NodeHead[n2];
|
||||
|
||||
// If tank is full, then prevent flow into it
|
||||
if (hyd->NodeHead[n1] >= tank->Hmax - hyd->Htol && !tank->CanOverflow)
|
||||
{
|
||||
// Case 1: Link is a pump discharging into tank
|
||||
if (link->Type == PUMP)
|
||||
{
|
||||
if (link->N2 == n1) hyd->LinkStatus[k] = TEMPCLOSED;
|
||||
}
|
||||
|
||||
// Case 2: Downstream head > tank head
|
||||
// (e.g., an open outflow check valve would close)
|
||||
else if (cvstatus(pr, OPEN, h, q) == CLOSED)
|
||||
{
|
||||
hyd->LinkStatus[k] = TEMPCLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
// If tank is empty, then prevent flow out of it
|
||||
if (hyd->NodeHead[n1] <= tank->Hmin + hyd->Htol)
|
||||
{
|
||||
// Case 1: Link is a pump discharging from tank
|
||||
if (link->Type == PUMP)
|
||||
{
|
||||
if (link->N1 == n1) hyd->LinkStatus[k] = TEMPCLOSED;
|
||||
}
|
||||
|
||||
// Case 2: Tank head > downstream head
|
||||
// (e.g., a closed outflow check valve would open)
|
||||
else if (cvstatus(pr, CLOSED, h, q) == OPEN)
|
||||
{
|
||||
hyd->LinkStatus[k] = TEMPCLOSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
1461
src/inpfile.c
Executable file → Normal file
1461
src/inpfile.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1348
src/input1.c
Executable file → Normal file
1348
src/input1.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1845
src/input2.c
Executable file → Normal file
1845
src/input2.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
4065
src/input3.c
Executable file → Normal file
4065
src/input3.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
347
src/mempool.c
347
src/mempool.c
@@ -1,205 +1,142 @@
|
||||
/* mempool.c
|
||||
**
|
||||
** A simple fast memory allocation package.
|
||||
**
|
||||
** By Steve Hill in Graphics Gems III, David Kirk (ed.),
|
||||
** Academic Press, Boston, MA, 1992
|
||||
**
|
||||
** Modified by Lew Rossman, 8/13/94.
|
||||
**
|
||||
** AllocInit() - create an alloc pool, returns the old pool handle
|
||||
** Alloc() - allocate memory
|
||||
** AllocReset() - reset the current pool
|
||||
** AllocSetPool() - set the current pool
|
||||
** AllocFree() - free the memory used by the current pool.
|
||||
**
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifndef __APPLE__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "mempool.h"
|
||||
|
||||
/*
|
||||
** ALLOC_BLOCK_SIZE - adjust this size to suit your installation - it
|
||||
** should be reasonably large otherwise you will be mallocing a lot.
|
||||
*/
|
||||
|
||||
#define ALLOC_BLOCK_SIZE 64000 /*(62*1024)*/
|
||||
|
||||
/*
|
||||
** alloc_hdr_t - Header for each block of memory.
|
||||
*/
|
||||
|
||||
typedef struct alloc_hdr_s
|
||||
{
|
||||
struct alloc_hdr_s *next; /* Next Block */
|
||||
char *block, /* Start of block */
|
||||
*free, /* Next free in block */
|
||||
*end; /* block + block size */
|
||||
} alloc_hdr_t;
|
||||
|
||||
/*
|
||||
** alloc_root_t - Header for the whole pool.
|
||||
*/
|
||||
|
||||
typedef struct alloc_root_s
|
||||
{
|
||||
alloc_hdr_t *first, /* First header in pool */
|
||||
*current; /* Current header */
|
||||
} alloc_root_t;
|
||||
|
||||
/*
|
||||
** root - Pointer to the current pool.
|
||||
*/
|
||||
|
||||
static alloc_root_t *root;
|
||||
|
||||
|
||||
/*
|
||||
** AllocHdr()
|
||||
**
|
||||
** Private routine to allocate a header and memory block.
|
||||
*/
|
||||
|
||||
static alloc_hdr_t *AllocHdr(void);
|
||||
|
||||
static alloc_hdr_t * AllocHdr()
|
||||
{
|
||||
alloc_hdr_t *hdr;
|
||||
char *block;
|
||||
|
||||
block = (char *) malloc(ALLOC_BLOCK_SIZE);
|
||||
hdr = (alloc_hdr_t *) malloc(sizeof(alloc_hdr_t));
|
||||
|
||||
if (hdr == NULL || block == NULL) return(NULL);
|
||||
hdr->block = block;
|
||||
hdr->free = block;
|
||||
hdr->next = NULL;
|
||||
hdr->end = block + ALLOC_BLOCK_SIZE;
|
||||
|
||||
return(hdr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** AllocInit()
|
||||
**
|
||||
** Create a new memory pool with one block.
|
||||
** Returns pointer to the new pool.
|
||||
*/
|
||||
|
||||
DLLEXPORT alloc_handle_t * AllocInit()
|
||||
{
|
||||
alloc_handle_t *newpool;
|
||||
root = (alloc_root_t *) malloc(sizeof(alloc_root_t));
|
||||
if (root == NULL) return(NULL);
|
||||
if ( (root->first = AllocHdr()) == NULL) return(NULL);
|
||||
root->current = root->first;
|
||||
newpool = (alloc_handle_t *) root;
|
||||
return(newpool);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Alloc()
|
||||
**
|
||||
** Use as a direct replacement for malloc(). Allocates
|
||||
** memory from the current pool.
|
||||
*/
|
||||
|
||||
DLLEXPORT char *Alloc(long size)
|
||||
{
|
||||
alloc_hdr_t *hdr = root->current;
|
||||
char *ptr;
|
||||
|
||||
/*
|
||||
** Align to 4 byte boundary - should be ok for most machines.
|
||||
** Change this if your machine has weird alignment requirements.
|
||||
*/
|
||||
size = (size + 3) & 0xfffffffc;
|
||||
|
||||
ptr = hdr->free;
|
||||
hdr->free += size;
|
||||
|
||||
/* Check if the current block is exhausted. */
|
||||
|
||||
if (hdr->free >= hdr->end)
|
||||
{
|
||||
/* Is the next block already allocated? */
|
||||
|
||||
if (hdr->next != NULL)
|
||||
{
|
||||
/* re-use block */
|
||||
hdr->next->free = hdr->next->block;
|
||||
root->current = hdr->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* extend the pool with a new block */
|
||||
if ( (hdr->next = AllocHdr()) == NULL) return(NULL);
|
||||
root->current = hdr->next;
|
||||
}
|
||||
|
||||
/* set ptr to the first location in the next block */
|
||||
ptr = root->current->free;
|
||||
root->current->free += size;
|
||||
}
|
||||
|
||||
/* Return pointer to allocated memory. */
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** AllocSetPool()
|
||||
**
|
||||
** Change the current pool. Return the old pool.
|
||||
*/
|
||||
|
||||
DLLEXPORT alloc_handle_t * AllocSetPool(alloc_handle_t *newpool)
|
||||
{
|
||||
alloc_handle_t *old = (alloc_handle_t *) root;
|
||||
root = (alloc_root_t *) newpool;
|
||||
return(old);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** AllocReset()
|
||||
**
|
||||
** Reset the current pool for re-use. No memory is freed,
|
||||
** so this is very fast.
|
||||
*/
|
||||
|
||||
DLLEXPORT void AllocReset()
|
||||
{
|
||||
root->current = root->first;
|
||||
root->current->free = root->current->block;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** AllocFreePool()
|
||||
**
|
||||
** Free the memory used by the current pool.
|
||||
** Don't use where AllocReset() could be used.
|
||||
*/
|
||||
|
||||
DLLEXPORT void AllocFreePool()
|
||||
{
|
||||
alloc_hdr_t *tmp,
|
||||
*hdr = root->first;
|
||||
|
||||
while (hdr != NULL)
|
||||
{
|
||||
tmp = hdr->next;
|
||||
free((char *) hdr->block);
|
||||
free((char *) hdr);
|
||||
hdr = tmp;
|
||||
}
|
||||
free((char *) root);
|
||||
root = NULL;
|
||||
}
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: mempool.c
|
||||
Description: a simple fast poooled memory allocation package
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/15/2019
|
||||
|
||||
This module is based code by Steve Hill in Graphics Gems III,
|
||||
David Kirk (ed.), Academic Press, Boston, MA, 1992
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mempool.h"
|
||||
|
||||
/*
|
||||
** ALLOC_BLOCK_SIZE - adjust this size to suit your installation - it
|
||||
** should be reasonably large otherwise you will be mallocing a lot.
|
||||
*/
|
||||
|
||||
#define ALLOC_BLOCK_SIZE 64000 /*(62*1024)*/
|
||||
|
||||
struct MemBlock
|
||||
{
|
||||
struct MemBlock *next; // Next block
|
||||
char *block, // Start of block
|
||||
*free, // Next free position in block
|
||||
*end; // block + block size
|
||||
};
|
||||
|
||||
struct Mempool
|
||||
{
|
||||
struct MemBlock *first;
|
||||
struct MemBlock *current;
|
||||
};
|
||||
|
||||
static struct MemBlock* createMemBlock()
|
||||
{
|
||||
struct MemBlock* memBlock = malloc(sizeof(struct MemBlock));
|
||||
if (memBlock)
|
||||
{
|
||||
memBlock->block = malloc(ALLOC_BLOCK_SIZE * sizeof(char));
|
||||
if (memBlock->block == NULL)
|
||||
{
|
||||
free(memBlock);
|
||||
return NULL;
|
||||
}
|
||||
memBlock->free = memBlock->block;
|
||||
memBlock->next = NULL;
|
||||
memBlock->end = memBlock->block + ALLOC_BLOCK_SIZE;
|
||||
}
|
||||
return memBlock;
|
||||
}
|
||||
|
||||
|
||||
static void deleteMemBlock(struct MemBlock* memBlock)
|
||||
{
|
||||
free(memBlock->block);
|
||||
free(memBlock);
|
||||
}
|
||||
|
||||
|
||||
struct Mempool * mempool_create()
|
||||
{
|
||||
struct Mempool *mempool;
|
||||
mempool = (struct Mempool *)malloc(sizeof(struct Mempool));
|
||||
if (mempool == NULL) return NULL;
|
||||
mempool->first = createMemBlock();
|
||||
mempool->current = mempool->first;
|
||||
if (mempool->first == NULL) return NULL;
|
||||
return mempool;
|
||||
}
|
||||
|
||||
void mempool_delete(struct Mempool *mempool)
|
||||
{
|
||||
if (mempool == NULL) return;
|
||||
while (mempool->first)
|
||||
{
|
||||
mempool->current = mempool->first->next;
|
||||
deleteMemBlock(mempool->first);
|
||||
mempool->first = mempool->current;
|
||||
}
|
||||
free(mempool);
|
||||
mempool = NULL;
|
||||
}
|
||||
|
||||
void mempool_reset(struct Mempool *mempool)
|
||||
{
|
||||
mempool->current = mempool->first;
|
||||
mempool->current->free = mempool->current->block;
|
||||
}
|
||||
|
||||
|
||||
char * mempool_alloc(struct Mempool *mempool, size_t size)
|
||||
{
|
||||
char* ptr;
|
||||
|
||||
/*
|
||||
** Align to 4 byte boundary - should be ok for most machines.
|
||||
** Change this if your machine has weird alignment requirements.
|
||||
*/
|
||||
size = (size + 3) & 0xfffffffc;
|
||||
|
||||
if (!mempool->current) return NULL;
|
||||
ptr = mempool->current->free;
|
||||
mempool->current->free += size;
|
||||
|
||||
// Check if the current block is exhausted
|
||||
|
||||
if (mempool->current->free >= mempool->current->end)
|
||||
{
|
||||
// Is the next block already allocated?
|
||||
|
||||
if (mempool->current->next)
|
||||
{
|
||||
// re-use block
|
||||
mempool->current->next->free = mempool->current->next->block;
|
||||
mempool->current = mempool->current->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// extend the pool with a new block
|
||||
mempool->current->next = createMemBlock();
|
||||
if (!mempool->current->next) return NULL;
|
||||
mempool->current = mempool->current->next;
|
||||
}
|
||||
|
||||
// set ptr to the first location in the next block
|
||||
|
||||
ptr = mempool->current->free;
|
||||
mempool->current->free += size;
|
||||
}
|
||||
|
||||
// Return pointer to allocated memory
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -1,43 +1,24 @@
|
||||
/*
|
||||
** mempool.h
|
||||
**
|
||||
** Header for mempool.c
|
||||
**
|
||||
** The type alloc_handle_t provides an opaque reference to the
|
||||
** alloc pool - only the alloc routines know its structure.
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: mempool.h
|
||||
Description: header for a simple pooled memory allocator
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 11/27/2018
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef MEMPOOL_H
|
||||
#define MEMPOOL_H
|
||||
|
||||
#ifndef DLLEXPORT
|
||||
#ifdef DLL
|
||||
#ifdef __cplusplus
|
||||
#define DLLEXPORT extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT __declspec(dllexport) __stdcall
|
||||
#endif
|
||||
#elif defined(CYGWIN)
|
||||
#define DLLEXPORT __stdcall
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#define DLLEXPORT
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
struct Mempool;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long dummy;
|
||||
} alloc_handle_t;
|
||||
|
||||
DLLEXPORT alloc_handle_t *AllocInit(void);
|
||||
DLLEXPORT char *Alloc(long);
|
||||
DLLEXPORT alloc_handle_t *AllocSetPool(alloc_handle_t *);
|
||||
DLLEXPORT void AllocReset(void);
|
||||
DLLEXPORT void AllocFreePool(void);
|
||||
struct Mempool * mempool_create();
|
||||
void mempool_delete(struct Mempool *mempool);
|
||||
void mempool_reset(struct Mempool *mempool);
|
||||
char * mempool_alloc(struct Mempool *mempool, size_t size);
|
||||
|
||||
#endif
|
||||
48
src/outfile/CMakeLists.txt
Normal file
48
src/outfile/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# CMakeLists.txt - CMake configuration file for epanet-output library
|
||||
#
|
||||
# Created: March 9, 2018
|
||||
# Author: Michael E. Tryby
|
||||
# US EPA ORD/NRMRL
|
||||
#
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
# Disable deprecation & link to multi-threaded static runtime library
|
||||
IF (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -MT)
|
||||
ENDIF (MSVC)
|
||||
|
||||
|
||||
# configure file groups
|
||||
set(EPANET_OUT_SOURCES src/epanet_output.c
|
||||
../util/errormanager.c
|
||||
../util/filemanager.c
|
||||
../util/cstr_helper.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
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(epanet-output
|
||||
BASE_NAME epanet_output
|
||||
EXPORT_MACRO_NAME EXPORT_OUT_API
|
||||
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)
|
||||
82
src/outfile/include/epanet_output.h
Normal file
82
src/outfile/include/epanet_output.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* epanet_output.h - EPANET Output API
|
||||
*
|
||||
* Created on: Jun 4, 2014
|
||||
*
|
||||
* Author: Michael E. Tryby
|
||||
* US EPA - ORD/NRMRL
|
||||
*/
|
||||
|
||||
#ifndef EPANET_OUTPUT_H_
|
||||
#define EPANET_OUTPUT_H_
|
||||
/* Epanet Results binary file API */
|
||||
|
||||
|
||||
#define MAXFNAME 259 // Max characters in file name
|
||||
#define MAXID 31 // Max characters in ID name
|
||||
|
||||
|
||||
// This is an opaque pointer to struct. Do not access variables.
|
||||
typedef void* ENR_Handle;
|
||||
|
||||
|
||||
#include "epanet_output_enums.h"
|
||||
#include "epanet_output_export.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int EXPORT_OUT_API ENR_init(ENR_Handle* p_handle_out);
|
||||
|
||||
int EXPORT_OUT_API ENR_open(ENR_Handle p_handle_in, const char* path);
|
||||
|
||||
int EXPORT_OUT_API ENR_getVersion(ENR_Handle p_handle_in, int* int_out);
|
||||
|
||||
int EXPORT_OUT_API ENR_getNetSize(ENR_Handle p_handle_in, int** int_out, int* int_dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getUnits(ENR_Handle p_handle_in, ENR_Units t_enum, int* int_out);
|
||||
|
||||
int EXPORT_OUT_API ENR_getTimes(ENR_Handle p_handle_in, ENR_Time t_enum, int* int_out);
|
||||
|
||||
int EXPORT_OUT_API ENR_getElementName(ENR_Handle p_handle_in, ENR_ElementType t_enum,
|
||||
int elementIndex, char** string_out, int* slen);
|
||||
|
||||
int EXPORT_OUT_API ENR_getEnergyUsage(ENR_Handle p_handle_in, int pumpIndex,
|
||||
int* int_out, float** float_out, int* int_dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getNetReacts(ENR_Handle p_handle_in, float** float_out, int* int_dim);
|
||||
|
||||
|
||||
int EXPORT_OUT_API ENR_getNodeSeries(ENR_Handle p_handle_in, int nodeIndex, ENR_NodeAttribute t_enum,
|
||||
int startPeriod, int endPeriod, float** outValueSeries, int* dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getLinkSeries(ENR_Handle p_handle_in, int linkIndex, ENR_LinkAttribute t_enum,
|
||||
int startPeriod, int endPeriod, float** outValueSeries, int* dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getNodeAttribute(ENR_Handle p_handle_in, int periodIndex,
|
||||
ENR_NodeAttribute t_enum, float** outValueArray, int* dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getLinkAttribute(ENR_Handle p_handle_in, int periodIndex,
|
||||
ENR_LinkAttribute t_enum, float** outValueArray, int* dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getNodeResult(ENR_Handle p_handle_in, int periodIndex, int nodeIndex,
|
||||
float** float_out, int* int_dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_getLinkResult(ENR_Handle p_handle_in, int periodIndex, int linkIndex,
|
||||
float** float_out, int* int_dim);
|
||||
|
||||
int EXPORT_OUT_API ENR_close(ENR_Handle* p_handle_out);
|
||||
|
||||
void EXPORT_OUT_API ENR_free(void** array);
|
||||
|
||||
void EXPORT_OUT_API ENR_clearError(ENR_Handle p_handle_in);
|
||||
|
||||
int EXPORT_OUT_API ENR_checkError(ENR_Handle p_handle_in, char** msg_buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EPANET_OUTPUT_H_ */
|
||||
79
src/outfile/include/epanet_output_enums.h
Normal file
79
src/outfile/include/epanet_output_enums.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* epanet_output_enums.h - EPANET Output API enums
|
||||
*
|
||||
* Created on: March 11, 2019
|
||||
*
|
||||
* Author: Michael E. Tryby
|
||||
* US EPA - ORD/NRMRL
|
||||
*/
|
||||
|
||||
|
||||
#ifndef EPANET_OUTPUT_ENUMS_H_
|
||||
#define EPANET_OUTPUT_ENUMS_H_
|
||||
|
||||
|
||||
typedef enum {
|
||||
ENR_node = 1,
|
||||
ENR_link = 2
|
||||
} ENR_ElementType;
|
||||
|
||||
typedef enum {
|
||||
ENR_flowUnits = 1,
|
||||
ENR_pressUnits = 2,
|
||||
ENR_qualUnits = 3
|
||||
} ENR_Units;
|
||||
|
||||
typedef enum {
|
||||
ENR_CFS = 0,
|
||||
ENR_GPM = 1,
|
||||
ENR_MGD = 2,
|
||||
ENR_IMGD = 3,
|
||||
ENR_AFD = 4,
|
||||
ENR_LPS = 5,
|
||||
ENR_LPM = 6,
|
||||
ENR_MLD = 7,
|
||||
ENR_CMH = 8,
|
||||
ENR_CMD = 9
|
||||
} ENR_FlowUnits;
|
||||
|
||||
typedef enum {
|
||||
ENR_PSI = 0,
|
||||
ENR_MTR = 1,
|
||||
ENR_KPA = 2
|
||||
} ENR_PressUnits;
|
||||
|
||||
typedef enum {
|
||||
ENR_NONE = 0,
|
||||
ENR_MGL = 1,
|
||||
ENR_UGL = 2,
|
||||
ENR_HOURS = 3,
|
||||
ENR_PRCNT = 4
|
||||
} ENR_QualUnits;
|
||||
|
||||
typedef enum {
|
||||
ENR_reportStart = 1,
|
||||
ENR_reportStep = 2,
|
||||
ENR_simDuration = 3,
|
||||
ENR_numPeriods = 4
|
||||
}ENR_Time;
|
||||
|
||||
typedef enum {
|
||||
ENR_demand = 1,
|
||||
ENR_head = 2,
|
||||
ENR_pressure = 3,
|
||||
ENR_quality = 4
|
||||
} ENR_NodeAttribute;
|
||||
|
||||
typedef enum {
|
||||
ENR_flow = 1,
|
||||
ENR_velocity = 2,
|
||||
ENR_headloss = 3,
|
||||
ENR_avgQuality = 4,
|
||||
ENR_status = 5,
|
||||
ENR_setting = 6,
|
||||
ENR_rxRate = 7,
|
||||
ENR_frctnFctr = 8
|
||||
} ENR_LinkAttribute;
|
||||
|
||||
|
||||
#endif /* EPANET_OUTPUT_ENUMS_H_ */
|
||||
939
src/outfile/src/epanet_output.c
Normal file
939
src/outfile/src/epanet_output.c
Normal file
@@ -0,0 +1,939 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// epanet_output.c -- API for reading results from EPANET binary output file
|
||||
//
|
||||
// Version: 0.40
|
||||
// Date 04/02/2019
|
||||
// 09/06/2017
|
||||
// 06/17/2016
|
||||
// 08/05/2014
|
||||
// 05/21/2014
|
||||
//
|
||||
// Author: Michael E. Tryby
|
||||
// US EPA - ORD/NRMRL
|
||||
//
|
||||
// Modified: Maurizio Cingi
|
||||
// University of Modena
|
||||
//
|
||||
// Purpose: Output API provides an interface for retrieving results from an
|
||||
// EPANET binary output file.
|
||||
//
|
||||
// Output data in the binary file are aligned on a 4 byte word size.
|
||||
// Therefore all values both integers and reals are 32 bits in length.
|
||||
//
|
||||
// All values returned by the output API are indexed from 0 to n-1. This
|
||||
// differs from how node and link elements are indexed by the binary file
|
||||
// writer found in EPANET. Times correspond to reporting periods are indexed
|
||||
// from 0 to number of reporting periods minus one. Node and link elements
|
||||
// are indexed from 0 to nodeCount minus one and 0 to linkCount minus one
|
||||
// respectively.
|
||||
//
|
||||
// The Output API functions provide a convenient way to select "slices" of
|
||||
// data from the output file. As such they return arrays of data. The API
|
||||
// functions automatically allocate memory for the array to be returned. The
|
||||
// caller is responsible for deallocating memory. The function ENR_free() is
|
||||
// provided for that purpose.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/errormanager.h"
|
||||
#include "util/filemanager.h"
|
||||
|
||||
#include "epanet_output.h"
|
||||
#include "messages.h"
|
||||
|
||||
|
||||
// NOTE: These depend on machine data model and may change when porting
|
||||
#define INT4 int // Must be a 4 byte / 32 bit integer type
|
||||
#define REAL4 float // Must be a 4 byte / 32 bit real type
|
||||
#define WORDSIZE 4 // Memory alignment 4 byte word size for both int and real
|
||||
|
||||
#define MINNREC 14 // Minimum allowable number of records
|
||||
#define PROLOGUE 884 // Preliminary fixed length section of header
|
||||
#define MAXID_P1 32 // EPANET max characters in ID name PLUS 1
|
||||
#define MAXMSG_P1 80 // EPANET max characters in message text PLUS 1
|
||||
|
||||
#define NELEMENTTYPES 5 // Number of element types
|
||||
#define NENERGYRESULTS 6 // Number of energy results
|
||||
#define NNODERESULTS 4 // number of result fields for nodes
|
||||
#define NLINKRESULTS 8 // number of result fields for links
|
||||
#define NREACTRESULTS 4 // number of net reaction results
|
||||
|
||||
#define MEMCHECK(x) (((x) == NULL) ? 411 : 0 )
|
||||
|
||||
// Typedefs for opaque pointer
|
||||
typedef struct data_s {
|
||||
INT4 nodeCount, tankCount, linkCount, pumpCount, valveCount, nPeriods;
|
||||
F_OFF outputStartPos; // starting file position of output data
|
||||
F_OFF bytesPerPeriod; // bytes saved per simulation time period
|
||||
|
||||
error_handle_t *error_handle;
|
||||
file_handle_t *file_handle;
|
||||
} data_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
//-----------------------------------------------------------------------------
|
||||
void errorLookup(int errcode, char* errmsg, int length);
|
||||
int validateFile(ENR_Handle);
|
||||
float getNodeValue(ENR_Handle, int, int, int);
|
||||
float getLinkValue(ENR_Handle, int, int, int);
|
||||
|
||||
float *newFloatArray(int n);
|
||||
int *newIntArray(int n);
|
||||
char *newCharArray(int n);
|
||||
|
||||
|
||||
int EXPORT_OUT_API ENR_init(ENR_Handle *dp_handle)
|
||||
// Purpose: Initialized pointer for the opaque ENR_Handle.
|
||||
//
|
||||
// Returns: Error code 0 on success, -1 on failure
|
||||
//
|
||||
// Note: The existence of this function has been carefully considered.
|
||||
// Don't change it.
|
||||
//
|
||||
{
|
||||
int errorcode = 0;
|
||||
data_t* p_data;
|
||||
|
||||
// Allocate memory for private data
|
||||
p_data = (data_t*)calloc(1, sizeof(data_t));
|
||||
|
||||
if (p_data != NULL){
|
||||
p_data->error_handle = create_error_manager(&errorLookup);
|
||||
p_data->file_handle = create_file_manager();
|
||||
*dp_handle = p_data;
|
||||
}
|
||||
else
|
||||
errorcode = -1;
|
||||
|
||||
// TODO: Need to handle errors during initialization better.
|
||||
return errorcode;
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_close(ENR_Handle *p_handle)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: *p_handle = pointer to ENR_Handle struct
|
||||
**
|
||||
** Returns: Error code 0 on success, -1 on failure
|
||||
**
|
||||
** Purpose: Close the output binary file, dellocate ENR_Handle struc
|
||||
** and nullify pointer to ENR_Handle struct
|
||||
**
|
||||
** NOTE: ENR_close must be called before program end
|
||||
** after calling ENR_close data in ENR_Handle struct are no more
|
||||
** accessible
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
data_t* p_data;
|
||||
int errorcode = 0;
|
||||
|
||||
p_data = (data_t*)(*p_handle);
|
||||
|
||||
if (p_data == NULL || p_data->file_handle == NULL)
|
||||
errorcode = -1;
|
||||
|
||||
else
|
||||
{
|
||||
close_file(p_data->file_handle);
|
||||
|
||||
delete_error_manager(p_data->error_handle);
|
||||
delete_file_manager(p_data->file_handle);
|
||||
|
||||
free(p_data);
|
||||
|
||||
*p_handle = NULL;
|
||||
}
|
||||
|
||||
return errorcode;
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_open(ENR_Handle p_handle, const char* path)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: path
|
||||
** Output: p_handle = pointer to ENR_Handle struct
|
||||
** Returns: warning / error code
|
||||
** Purpose: Opens the output binary file and reads prologue and epilogue
|
||||
**
|
||||
** NOTE: ENR_init must be called before anyother ENR_* functions
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int err, errorcode = 0;
|
||||
F_OFF bytecount;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else
|
||||
{
|
||||
// Attempt to open binary output file for reading only
|
||||
if ((open_file(p_data->file_handle, path, "rb")) != 0)
|
||||
errorcode = 434;
|
||||
|
||||
// Perform checks to insure the file is valid
|
||||
else if ((err = validateFile(p_data)) != 0) errorcode = err;
|
||||
|
||||
// If a warning is encountered read file header
|
||||
if (errorcode < 400 ) {
|
||||
// read network size
|
||||
seek_file(p_data->file_handle, 2*WORDSIZE, SEEK_SET);
|
||||
read_file(&(p_data->nodeCount), WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(&(p_data->tankCount), WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(&(p_data->linkCount), WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(&(p_data->pumpCount), WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(&(p_data->valveCount), WORDSIZE, 1, p_data->file_handle);
|
||||
|
||||
// Compute positions and offsets for retrieving data
|
||||
// fixed portion of header + title section + filenames + chem names
|
||||
bytecount = PROLOGUE;
|
||||
// node names + link names
|
||||
bytecount += MAXID_P1*p_data->nodeCount + MAXID_P1*p_data->linkCount;
|
||||
// network connectivity + tank nodes + tank areas
|
||||
bytecount += 3*WORDSIZE*p_data->linkCount + 2*WORDSIZE*p_data->tankCount;
|
||||
// node elevations + link lengths and link diameters
|
||||
bytecount += WORDSIZE*p_data->nodeCount + 2*WORDSIZE*p_data->linkCount;
|
||||
// pump energy summary
|
||||
bytecount += 7*WORDSIZE*p_data->pumpCount + WORDSIZE;
|
||||
p_data->outputStartPos= bytecount;
|
||||
|
||||
p_data->bytesPerPeriod = NNODERESULTS*WORDSIZE*p_data->nodeCount +
|
||||
NLINKRESULTS*WORDSIZE*p_data->linkCount;
|
||||
}
|
||||
}
|
||||
// If error close the binary file
|
||||
if (errorcode > 400) {
|
||||
set_error(p_data->error_handle, errorcode);
|
||||
ENR_close(&p_handle);
|
||||
}
|
||||
|
||||
return errorcode;
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getVersion(ENR_Handle p_handle, int* version)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: p_handle = pointer to ENR_Handle struct
|
||||
** Output: version Epanet version
|
||||
** Returns: error code
|
||||
**
|
||||
** Purpose: Returns Epanet version that wrote EBOFile
|
||||
**--------------element codes-------------------------------------------
|
||||
*/
|
||||
{
|
||||
int errorcode = 0;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else
|
||||
{
|
||||
seek_file(p_data->file_handle, 1*WORDSIZE, SEEK_SET);
|
||||
if (read_file(version, WORDSIZE, 1, p_data->file_handle) != 1)
|
||||
errorcode = 436;
|
||||
}
|
||||
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getNetSize(ENR_Handle p_handle, int** elementCount, int* length)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: p_handle = pointer to ENR_Handle struct
|
||||
** Output: array of element counts (nodes, tanks, links, pumps, valves)
|
||||
** Returns: error code
|
||||
** Purpose: Returns an array of count values
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int errorcode = 0;
|
||||
int* temp = newIntArray(NELEMENTTYPES);
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else
|
||||
{
|
||||
temp[0] = p_data->nodeCount;
|
||||
temp[1] = p_data->tankCount;
|
||||
temp[2] = p_data->linkCount;
|
||||
temp[3] = p_data->pumpCount;
|
||||
temp[4] = p_data->valveCount;
|
||||
|
||||
*elementCount = temp;
|
||||
*length = NELEMENTTYPES;
|
||||
}
|
||||
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFlag)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: p_handle = pointer to ENR_Handle struct
|
||||
** code
|
||||
** Output: count
|
||||
** Returns: unitFlag
|
||||
** Purpose: Returns pressure or flow unit flag
|
||||
**--------------pressure unit flags----------------------------------------
|
||||
** 0 = psi
|
||||
** 1 = meters
|
||||
** 2 = kPa
|
||||
**------------------flow unit flags----------------------------------------
|
||||
** 0 = cubic feet/second
|
||||
** 1 = gallons/minute
|
||||
** 2 = million gallons/day
|
||||
** 3 = Imperial million gallons/day
|
||||
** 4 = acre-ft/day
|
||||
** 5 = liters/second
|
||||
** 6 = liters/minute
|
||||
** 7 = megaliters/day
|
||||
** 8 = cubic meters/hour
|
||||
** 9 = cubic meters/day
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int errorcode = 0;
|
||||
F_OFF offset;
|
||||
char temp[MAXID_P1];
|
||||
data_t* p_data;
|
||||
|
||||
*unitFlag = -1;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case ENR_flowUnits:
|
||||
seek_file(p_data->file_handle, 9*WORDSIZE, SEEK_SET);
|
||||
read_file(unitFlag, WORDSIZE, 1, p_data->file_handle);
|
||||
break;
|
||||
|
||||
case ENR_pressUnits:
|
||||
seek_file(p_data->file_handle, 10*WORDSIZE, SEEK_SET);
|
||||
read_file(unitFlag, WORDSIZE, 1, p_data->file_handle);
|
||||
break;
|
||||
|
||||
case ENR_qualUnits:
|
||||
offset = 7*WORDSIZE;
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(unitFlag, WORDSIZE, 1, p_data->file_handle);
|
||||
|
||||
if (*unitFlag == 0) *unitFlag = ENR_NONE;
|
||||
|
||||
else if (*unitFlag == 1) {
|
||||
offset = 15*WORDSIZE + 3*MAXMSG_P1 + 2*(MAXFNAME+1) + MAXID_P1;
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(temp, MAXID_P1, 1, p_data->file_handle);
|
||||
|
||||
if (!strcmp(temp, "mg/L")) *unitFlag = ENR_MGL;
|
||||
else *unitFlag = ENR_UGL;
|
||||
}
|
||||
|
||||
else if (*unitFlag == 2) *unitFlag = ENR_HOURS;
|
||||
|
||||
else *unitFlag = ENR_PRCNT;
|
||||
|
||||
break;
|
||||
|
||||
default: errorcode = 421;
|
||||
}
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getTimes(ENR_Handle p_handle, ENR_Time code, int* time)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: p_handle = pointer to ENR_Handle struct
|
||||
** code = element code
|
||||
** Output: time
|
||||
** Returns: error code
|
||||
** Purpose: Returns report and simulation time related parameters.
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
int errorcode = 0;
|
||||
data_t* p_data;
|
||||
|
||||
*time = -1;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case ENR_reportStart:
|
||||
seek_file(p_data->file_handle, 12*WORDSIZE, SEEK_SET);
|
||||
read_file(time, WORDSIZE, 1, p_data->file_handle);
|
||||
break;
|
||||
|
||||
case ENR_reportStep:
|
||||
seek_file(p_data->file_handle, 13*WORDSIZE, SEEK_SET);
|
||||
read_file(time, WORDSIZE, 1, p_data->file_handle);
|
||||
break;
|
||||
|
||||
case ENR_simDuration:
|
||||
seek_file(p_data->file_handle, 14*WORDSIZE, SEEK_SET);
|
||||
read_file(time, WORDSIZE, 1, p_data->file_handle);
|
||||
break;
|
||||
|
||||
case ENR_numPeriods:
|
||||
*time = p_data->nPeriods;
|
||||
break;
|
||||
|
||||
default:
|
||||
errorcode = 421;
|
||||
}
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getChemData(ENR_Handle p_handle, char** name, int* length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getElementName(ENR_Handle p_handle, ENR_ElementType type,
|
||||
int elementIndex, char** name, int* length)
|
||||
/*------------------------------------------------------------------------
|
||||
** Input: p_handle = pointer to ENR_Handle struct
|
||||
** type = ENR_node or ENR_link
|
||||
** elementIndex from 1 to nodeCount or 1 to linkCount
|
||||
** Output: name = elementName
|
||||
** Returns: error code
|
||||
** Purpose: Retrieves Name of a specified node or link element
|
||||
** NOTE: 'name' must be able to hold MAXID characters
|
||||
** TODO: Takes EPANET indexing from 1 to n not 0 to n-1
|
||||
**-------------------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
F_OFF offset;
|
||||
int errorcode = 0;
|
||||
char* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
/* Allocate memory for name */
|
||||
else if MEMCHECK(temp = newCharArray(MAXID_P1)) errorcode = 411;
|
||||
|
||||
else
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ENR_node:
|
||||
if (elementIndex < 1 || elementIndex > p_data->nodeCount)
|
||||
errorcode = 423;
|
||||
else offset = PROLOGUE + (elementIndex - 1)*MAXID_P1;
|
||||
break;
|
||||
|
||||
case ENR_link:
|
||||
if (elementIndex < 1 || elementIndex > p_data->linkCount)
|
||||
errorcode = 423;
|
||||
else
|
||||
offset = PROLOGUE + p_data->nodeCount*MAXID_P1 +
|
||||
(elementIndex - 1)*MAXID_P1;
|
||||
break;
|
||||
|
||||
default:
|
||||
errorcode = 421;
|
||||
}
|
||||
|
||||
if (!errorcode)
|
||||
{
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(temp, 1, MAXID_P1, p_data->file_handle);
|
||||
|
||||
*name = temp;
|
||||
*length = MAXID_P1;
|
||||
}
|
||||
}
|
||||
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getEnergyUsage(ENR_Handle p_handle, int pumpIndex,
|
||||
int* linkIndex, float** outValues, int* length)
|
||||
/*
|
||||
* Purpose: Returns pump energy usage statistics.
|
||||
*
|
||||
* Energy usage statistics:
|
||||
* 0 = pump utilization
|
||||
* 1 = avg. efficiency
|
||||
* 2 = avg. kW/flow
|
||||
* 3 = avg. kwatts
|
||||
* 4 = peak kwatts
|
||||
* 5 = cost/day
|
||||
*/
|
||||
{
|
||||
F_OFF offset;
|
||||
int errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
// Check for valid pump index
|
||||
else if (pumpIndex < 1 || pumpIndex > p_data->pumpCount) errorcode = 423;
|
||||
// Check memory for outValues
|
||||
else if MEMCHECK(temp = newFloatArray(NENERGYRESULTS)) errorcode = 411;
|
||||
|
||||
else
|
||||
{
|
||||
// Position offset to start of pump energy summary
|
||||
offset = p_data->outputStartPos - (p_data->pumpCount*(WORDSIZE + 6*WORDSIZE) + WORDSIZE);
|
||||
// Adjust offset by pump index
|
||||
offset += (pumpIndex - 1)*(WORDSIZE + 6*WORDSIZE);
|
||||
|
||||
// Power summary is 1 int and 6 floats for each pump
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(linkIndex, WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(temp, WORDSIZE, 6, p_data->file_handle);
|
||||
|
||||
*outValues = temp;
|
||||
*length = NENERGYRESULTS;
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getNetReacts(ENR_Handle p_handle, float** outValues, int* length)
|
||||
/*
|
||||
* Purpose: Returns network wide average reaction rates and average
|
||||
* source mass inflow:
|
||||
* 0 = bulk
|
||||
* 1 = wall
|
||||
* 2 = tank
|
||||
* 3 = source
|
||||
*/
|
||||
{
|
||||
F_OFF offset;
|
||||
int errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
// Check memory for outValues
|
||||
else if MEMCHECK(temp = newFloatArray(NREACTRESULTS)) errorcode = 411;
|
||||
|
||||
else
|
||||
{
|
||||
// Reaction summary is 4 floats located right before epilogue.
|
||||
// This offset is relative to the end of the file.
|
||||
offset = - 3*WORDSIZE - 4*WORDSIZE;
|
||||
seek_file(p_data->file_handle, offset, SEEK_END);
|
||||
read_file(temp, WORDSIZE, 4, p_data->file_handle);
|
||||
|
||||
*outValues = temp;
|
||||
*length = NREACTRESULTS;
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
void EXPORT_OUT_API ENR_free(void** array)
|
||||
//
|
||||
// Purpose: Frees memory allocated by API calls
|
||||
//
|
||||
{
|
||||
if (array != NULL) {
|
||||
free(*array);
|
||||
*array = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getNodeSeries(ENR_Handle p_handle, int nodeIndex, ENR_NodeAttribute attr,
|
||||
int startPeriod, int endPeriod, float** outValueSeries, int* dim)
|
||||
//
|
||||
// Purpose: Get time series results for particular attribute. Specify series
|
||||
// start and length using seriesStart and seriesLength respectively.
|
||||
//
|
||||
// NOTE: The node index argument corresponds to the EPANET node index from 1 to
|
||||
// nnodes. The series returned is indexed from 0 to nperiods - 1.
|
||||
//
|
||||
{
|
||||
int k, length, errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else if (nodeIndex < 1 || nodeIndex > p_data->nodeCount) errorcode = 423;
|
||||
else if (startPeriod < 0 || endPeriod >= p_data->nPeriods ||
|
||||
endPeriod <= startPeriod) errorcode = 422;
|
||||
// Check memory for outValues
|
||||
else if MEMCHECK(temp = newFloatArray(length = endPeriod - startPeriod)) errorcode = 411;
|
||||
else
|
||||
{
|
||||
// loop over and build time series
|
||||
for (k = 0; k < length; k++)
|
||||
temp[k] = getNodeValue(p_handle, startPeriod + k,
|
||||
nodeIndex, attr);
|
||||
|
||||
*outValueSeries = temp;
|
||||
*dim = length;
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getLinkSeries(ENR_Handle p_handle, int linkIndex, ENR_LinkAttribute attr,
|
||||
int startPeriod, int endPeriod, float** outValueSeries, int* dim)
|
||||
//
|
||||
// Purpose: Get time series results for particular attribute. Specify series
|
||||
// start and length using seriesStart and seriesLength respectively.
|
||||
//
|
||||
// NOTE:
|
||||
// The link index argument corresponds to the EPANET link index from 1 to
|
||||
// nlinks. The series returned is indexed from 0 to nperiods - 1.
|
||||
//
|
||||
{
|
||||
int k, length, errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else if (linkIndex < 1 || linkIndex > p_data->linkCount) errorcode = 423;
|
||||
else if (startPeriod < 0 || endPeriod >= p_data->nPeriods ||
|
||||
endPeriod <= startPeriod) errorcode = 422;
|
||||
// Check memory for outValues
|
||||
else if MEMCHECK(temp = newFloatArray(length = endPeriod - startPeriod)) errorcode = 411;
|
||||
else
|
||||
{
|
||||
// loop over and build time series
|
||||
for (k = 0; k < length; k++)
|
||||
temp[k] = getLinkValue(p_handle, startPeriod + k, linkIndex, attr);
|
||||
|
||||
*outValueSeries = temp;
|
||||
*dim = length;
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getNodeAttribute(ENR_Handle p_handle, int periodIndex,
|
||||
ENR_NodeAttribute attr, float** outValueArray, int* length)
|
||||
//
|
||||
// Purpose:
|
||||
// For all nodes at given time, get a particular attribute
|
||||
//
|
||||
// Returns:
|
||||
// Error code
|
||||
// OutValueArray of results is indexed from 0 to nodeCount
|
||||
//
|
||||
// Warning:
|
||||
// Caller must free memory allocated for outValueArray
|
||||
//
|
||||
// NOTE:
|
||||
// The array returned is indexed from 0 to nnodes - 1. So to access
|
||||
// node values by their EPANET index, the index value must be
|
||||
// decremented by one.
|
||||
//
|
||||
{
|
||||
F_OFF offset;
|
||||
int errorcode = 0;
|
||||
float * temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
// if the time index is out of range return an error
|
||||
else if (periodIndex < 0 || periodIndex >= p_data->nPeriods) errorcode = 422;
|
||||
// Check memory for outValues
|
||||
else if MEMCHECK(temp = newFloatArray(p_data->nodeCount)) errorcode = 411;
|
||||
|
||||
else
|
||||
{
|
||||
// calculate byte offset to start time for series
|
||||
offset = p_data->outputStartPos + (periodIndex)*p_data->bytesPerPeriod;
|
||||
// add offset for node and attribute
|
||||
offset += ((attr - 1)*p_data->nodeCount)*WORDSIZE;
|
||||
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(temp, WORDSIZE, p_data->nodeCount, p_data->file_handle);
|
||||
|
||||
*outValueArray = temp;
|
||||
*length = p_data->nodeCount;
|
||||
}
|
||||
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getLinkAttribute(ENR_Handle p_handle, int periodIndex,
|
||||
ENR_LinkAttribute attr, float** outValueArray, int* length)
|
||||
//
|
||||
// Purpose:
|
||||
// For all links at given time, get a particular attribute
|
||||
//
|
||||
// Returns:
|
||||
// Error code
|
||||
// OutValueArray of results is indexed from 0 to linkCount
|
||||
//
|
||||
// Warning:
|
||||
// Caller must free memory allocated for outValueArray
|
||||
//
|
||||
// NOTE:
|
||||
// The array returned is indexed from 0 to nlinks - 1. So to access
|
||||
// link values by their EPANET index, the index value must be
|
||||
// decremented by one.
|
||||
//
|
||||
{
|
||||
F_OFF offset;
|
||||
int errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
// if the time index is out of range return an error
|
||||
else if (periodIndex < 0 || periodIndex >= p_data->nPeriods) errorcode = 422;
|
||||
// Check memory for outValues
|
||||
else if MEMCHECK(temp = newFloatArray(p_data->linkCount)) errorcode = 411;
|
||||
|
||||
else
|
||||
{
|
||||
// calculate byte offset to start time for series
|
||||
offset = p_data->outputStartPos + (periodIndex)*p_data->bytesPerPeriod
|
||||
+ (NNODERESULTS*p_data->nodeCount)*WORDSIZE;
|
||||
// add offset for link and attribute
|
||||
offset += ((attr - 1)*p_data->linkCount)*WORDSIZE;
|
||||
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(temp, WORDSIZE, p_data->linkCount, p_data->file_handle);
|
||||
|
||||
*outValueArray = temp;
|
||||
*length = p_data->linkCount;
|
||||
}
|
||||
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getNodeResult(ENR_Handle p_handle, int periodIndex,
|
||||
int nodeIndex, float** outValueArray, int* length)
|
||||
//
|
||||
// Purpose: For a node at given time, get all attributes.
|
||||
//
|
||||
// NOTE:
|
||||
//
|
||||
{
|
||||
int j, errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else if (periodIndex < 0 || periodIndex >= p_data->nPeriods) errorcode = 422;
|
||||
else if (nodeIndex < 1 || nodeIndex > p_data->nodeCount) errorcode = 423;
|
||||
else if MEMCHECK(temp = newFloatArray(NNODERESULTS)) errorcode = 411;
|
||||
else
|
||||
{
|
||||
for (j = 0; j < NNODERESULTS; j++)
|
||||
temp[j] = getNodeValue(p_handle, periodIndex, nodeIndex, j);
|
||||
|
||||
*outValueArray = temp;
|
||||
*length = NNODERESULTS;
|
||||
}
|
||||
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_getLinkResult(ENR_Handle p_handle, int periodIndex,
|
||||
int linkIndex, float** outValueArray, int* length)
|
||||
//
|
||||
// Purpose: For a link at given time, get all attributes
|
||||
//
|
||||
{
|
||||
int j, errorcode = 0;
|
||||
float* temp;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
else if (periodIndex < 0 || periodIndex >= p_data->nPeriods) errorcode = 422;
|
||||
else if (linkIndex < 1 || linkIndex > p_data->linkCount) errorcode = 423;
|
||||
else if MEMCHECK(temp = newFloatArray(NLINKRESULTS)) errorcode = 411;
|
||||
else
|
||||
{
|
||||
for (j = 0; j < NLINKRESULTS; j++)
|
||||
temp[j] = getLinkValue(p_handle, periodIndex, linkIndex, j);
|
||||
|
||||
*outValueArray = temp;
|
||||
*length = NLINKRESULTS;
|
||||
}
|
||||
return set_error(p_data->error_handle, errorcode);
|
||||
}
|
||||
|
||||
void EXPORT_OUT_API ENR_clearError(ENR_Handle p_handle)
|
||||
{
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
clear_error(p_data->error_handle);
|
||||
}
|
||||
|
||||
int EXPORT_OUT_API ENR_checkError(ENR_Handle p_handle, char** msg_buffer)
|
||||
{
|
||||
data_t* p_data;
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
if (p_data == NULL) return -1;
|
||||
|
||||
return check_error(p_data->error_handle, msg_buffer);
|
||||
}
|
||||
|
||||
|
||||
void errorLookup(int errcode, char* dest_msg, int dest_len)
|
||||
//
|
||||
// Purpose: takes error code returns error message
|
||||
//
|
||||
{
|
||||
const char* msg;
|
||||
|
||||
switch (errcode)
|
||||
{
|
||||
case 10: msg = WARN10;
|
||||
break;
|
||||
case 411: msg = ERR411;
|
||||
break;
|
||||
case 412: msg = ERR412;
|
||||
break;
|
||||
case 421: msg = ERR421;
|
||||
break;
|
||||
case 422: msg = ERR422;
|
||||
break;
|
||||
case 423: msg = ERR423;
|
||||
break;
|
||||
case 434: msg = ERR434;
|
||||
break;
|
||||
case 435: msg = ERR435;
|
||||
break;
|
||||
case 436: msg = ERR436;
|
||||
break;
|
||||
default: msg = ERRERR;
|
||||
}
|
||||
|
||||
strncpy(dest_msg, msg, MSG_MAXLEN);
|
||||
}
|
||||
|
||||
int validateFile(ENR_Handle p_handle)
|
||||
// Returns:
|
||||
// Error code: 435, 436
|
||||
// Warning code: 10
|
||||
{
|
||||
INT4 magic1, magic2, hydcode;
|
||||
int errorcode = 0;
|
||||
F_OFF filepos;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
// Read magic number from beginning of file
|
||||
seek_file(p_data->file_handle, 0L, SEEK_SET);
|
||||
read_file(&magic1, WORDSIZE, 1, p_data->file_handle);
|
||||
|
||||
// Fast forward to end and read file epilogue
|
||||
seek_file(p_data->file_handle, -3*WORDSIZE, SEEK_END);
|
||||
read_file(&(p_data->nPeriods), WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(&hydcode, WORDSIZE, 1, p_data->file_handle);
|
||||
read_file(&magic2, WORDSIZE, 1, p_data->file_handle);
|
||||
|
||||
filepos = tell_file(p_data->file_handle);
|
||||
|
||||
// Is the file an EPANET binary file?
|
||||
if (magic1 != magic2) errorcode = 435;
|
||||
// Does the binary file contain results?
|
||||
else if (filepos < MINNREC*WORDSIZE || p_data->nPeriods == 0)
|
||||
errorcode = 436;
|
||||
// Issue warning if there were problems with the model run.
|
||||
else if (hydcode != 0) errorcode = 10;
|
||||
|
||||
return errorcode;
|
||||
}
|
||||
|
||||
float getNodeValue(ENR_Handle p_handle, int periodIndex, int nodeIndex,
|
||||
int attr)
|
||||
//
|
||||
// Purpose: Retrieves an attribute value at a specified node and time
|
||||
//
|
||||
{
|
||||
F_OFF offset;
|
||||
REAL4 y;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
// calculate byte offset to start time for series
|
||||
offset = p_data->outputStartPos + periodIndex*p_data->bytesPerPeriod;
|
||||
// add byte position for attribute and node
|
||||
offset += ((attr - 1)*p_data->nodeCount + (nodeIndex - 1))*WORDSIZE;
|
||||
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(&y, WORDSIZE, 1, p_data->file_handle);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
float getLinkValue(ENR_Handle p_handle, int periodIndex, int linkIndex,
|
||||
int attr)
|
||||
//
|
||||
// Purpose: Retrieves an attribute value at a specified link and time
|
||||
//
|
||||
{
|
||||
F_OFF offset;
|
||||
REAL4 y;
|
||||
data_t* p_data;
|
||||
|
||||
p_data = (data_t*)p_handle;
|
||||
|
||||
// Calculate byte offset to start time for series
|
||||
offset = p_data->outputStartPos + periodIndex*p_data->bytesPerPeriod
|
||||
+ (NNODERESULTS*p_data->nodeCount)*WORDSIZE;
|
||||
// add byte position for attribute and link
|
||||
offset += ((attr - 1)*p_data->linkCount + (linkIndex - 1))*WORDSIZE;
|
||||
|
||||
seek_file(p_data->file_handle, offset, SEEK_SET);
|
||||
read_file(&y, WORDSIZE, 1, p_data->file_handle);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
float* newFloatArray(int n)
|
||||
//
|
||||
// Warning: Caller must free memory allocated by this function.
|
||||
//
|
||||
{
|
||||
return (float*) malloc((n)*sizeof(float));
|
||||
}
|
||||
|
||||
int* newIntArray(int n)
|
||||
//
|
||||
// Warning: Caller must free memory allocated by this function.
|
||||
//
|
||||
{
|
||||
return (int*) malloc((n)*sizeof(int));
|
||||
}
|
||||
|
||||
char* newCharArray(int n)
|
||||
//
|
||||
// Warning: Caller must free memory allocated by this function.
|
||||
//
|
||||
{
|
||||
return (char*) malloc((n)*sizeof(char));
|
||||
}
|
||||
29
src/outfile/src/messages.h
Normal file
29
src/outfile/src/messages.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* messages.h - EPANET
|
||||
*
|
||||
* Created on: June 1, 2017
|
||||
*
|
||||
* Author: Michael E. Tryby
|
||||
* US EPA - ORD/NRMRL
|
||||
*/
|
||||
|
||||
#ifndef MESSAGES_H_
|
||||
#define MESSAGES_H_
|
||||
/*------------------- Error Messages --------------------*/
|
||||
#define MSG_MAXLEN 53
|
||||
|
||||
#define WARN10 "Warning: model run issued warnings"
|
||||
|
||||
#define ERR411 "Input Error 411: no memory allocated for results"
|
||||
#define ERR412 "Input Error 412: binary file hasn't been opened"
|
||||
#define ERR421 "Input Error 421: invalid parameter code"
|
||||
#define ERR422 "Input Error 422: reporting period index out of range"
|
||||
#define ERR423 "Input Error 423: element index out of range"
|
||||
|
||||
#define ERR434 "File Error 434: unable to open binary file"
|
||||
#define ERR435 "File Error 435: invalid binary file type"
|
||||
#define ERR436 "File Error 436: no results in binary file"
|
||||
|
||||
#define ERRERR "Error: An unknown error has occurred"
|
||||
|
||||
#endif /* MESSAGES_H_ */
|
||||
1559
src/output.c
Executable file → Normal file
1559
src/output.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1359
src/project.c
Normal file
1359
src/project.c
Normal file
File diff suppressed because it is too large
Load Diff
2472
src/quality.c
Executable file → Normal file
2472
src/quality.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
743
src/qualreact.c
Normal file
743
src/qualreact.c
Normal file
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: qualreact.c
|
||||
Description: computes water quality reactions within pipes and tanks
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/15/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "types.h"
|
||||
|
||||
// Exported functions
|
||||
char setreactflag(Project *);
|
||||
double getucf(double);
|
||||
void ratecoeffs(Project *);
|
||||
void reactpipes(Project *, long);
|
||||
void reacttanks(Project *, long);
|
||||
double mixtank(Project *, int, double, double ,double);
|
||||
|
||||
// Imported functions
|
||||
extern void addseg(Project *, int, double, double);
|
||||
extern void reversesegs(Project *, int);
|
||||
|
||||
// Local functions
|
||||
static double piperate(Project *, int);
|
||||
static double pipereact(Project *, int, double, double, long);
|
||||
static double tankreact(Project *, double, double, double, long);
|
||||
static double bulkrate(Project *, double, double, double);
|
||||
static double wallrate(Project *, double, double, double, double);
|
||||
|
||||
static void tankmix1(Project *, int, double, double, double);
|
||||
static void tankmix2(Project *, int, double, double, double);
|
||||
static void tankmix3(Project *, int, double, double, double);
|
||||
static void tankmix4(Project *, int, double, double, double);
|
||||
|
||||
|
||||
char setreactflag(Project *pr)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns 1 for reactive WQ constituent, 0 otherwise
|
||||
** Purpose: checks if reactive chemical being simulated
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
int i;
|
||||
|
||||
if (pr->quality.Qualflag == TRACE) return 0;
|
||||
else if (pr->quality.Qualflag == AGE) return 1;
|
||||
else
|
||||
{
|
||||
for (i = 1; i <= net->Nlinks; i++)
|
||||
{
|
||||
if (net->Link[i].Type <= PIPE)
|
||||
{
|
||||
if (net->Link[i].Kb != 0.0 || net->Link[i].Kw != 0.0) return 1;
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= net->Ntanks; i++)
|
||||
{
|
||||
if (net->Tank[i].Kb != 0.0) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
double getucf(double order)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: order = bulk reaction order
|
||||
** Output: returns a unit conversion factor
|
||||
** Purpose: converts bulk reaction rates from per Liter to
|
||||
** per FT3 basis
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
if (order < 0.0) order = 0.0;
|
||||
if (order == 1.0) return (1.0);
|
||||
else return (1. / pow(LperFT3, (order - 1.0)));
|
||||
}
|
||||
|
||||
|
||||
void ratecoeffs(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: none
|
||||
** Purpose: determines wall reaction coeff. for each pipe
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k;
|
||||
double kw;
|
||||
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
kw = net->Link[k].Kw;
|
||||
if (kw != 0.0) kw = piperate(pr, k);
|
||||
net->Link[k].Rc = kw;
|
||||
qual->PipeRateCoeff[k] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reactpipes(Project *pr, long dt)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: dt = time step
|
||||
** Output: none
|
||||
** Purpose: reacts water within each pipe over a time step.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k;
|
||||
Pseg seg;
|
||||
double cseg, rsum, vsum;
|
||||
|
||||
// Examine each link in network
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
// Skip non-pipe links (pumps & valves)
|
||||
if (net->Link[k].Type != PIPE) continue;
|
||||
rsum = 0.0;
|
||||
vsum = 0.0;
|
||||
|
||||
// Examine each segment of the pipe
|
||||
seg = qual->FirstSeg[k];
|
||||
while (seg != NULL)
|
||||
{
|
||||
// React segment over time dt
|
||||
cseg = seg->c;
|
||||
seg->c = pipereact(pr, k, seg->c, seg->v, dt);
|
||||
|
||||
// Update reaction component of mass balance
|
||||
qual->MassBalance.reacted += (cseg - seg->c) * seg->v;
|
||||
|
||||
// Accumulate volume-weighted reaction rate
|
||||
if (qual->Qualflag == CHEM)
|
||||
{
|
||||
rsum += fabs(seg->c - cseg) * seg->v;
|
||||
vsum += seg->v;
|
||||
}
|
||||
seg = seg->prev;
|
||||
}
|
||||
|
||||
// Normalize volume-weighted reaction rate
|
||||
if (vsum > 0.0) qual->PipeRateCoeff[k] = rsum / vsum / dt * SECperDAY;
|
||||
else qual->PipeRateCoeff[k] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reacttanks(Project *pr, long dt)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: dt = time step
|
||||
** Output: none
|
||||
** Purpose: reacts water within each tank over a time step.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int i, k;
|
||||
double c;
|
||||
Pseg seg;
|
||||
Stank *tank;
|
||||
|
||||
// Examine each tank in network
|
||||
for (i = 1; i <= net->Ntanks; i++)
|
||||
{
|
||||
// Skip reservoirs
|
||||
tank = &net->Tank[i];
|
||||
if (tank->A == 0.0) continue;
|
||||
|
||||
// k is segment chain belonging to tank i
|
||||
k = net->Nlinks + i;
|
||||
|
||||
// React each volume segment in the chain
|
||||
seg = qual->FirstSeg[k];
|
||||
while (seg != NULL)
|
||||
{
|
||||
c = seg->c;
|
||||
seg->c = tankreact(pr, seg->c, seg->v, tank->Kb, dt);
|
||||
qual->MassBalance.reacted += (c - seg->c) * seg->v;
|
||||
seg = seg->prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double piperate(Project *pr, int k)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** Output: returns reaction rate coeff. for 1st-order wall
|
||||
** reactions or mass transfer rate coeff. for 0-order
|
||||
** reactions
|
||||
** Purpose: finds wall reaction rate coeffs.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double a, d, u, q, kf, kw, y, Re, Sh;
|
||||
|
||||
d = net->Link[k].Diam; // Pipe diameter, ft
|
||||
|
||||
// Ignore mass transfer if Schmidt No. is 0
|
||||
if (qual->Sc == 0.0)
|
||||
{
|
||||
if (qual->WallOrder == 0.0) return BIG;
|
||||
else return (net->Link[k].Kw * (4.0 / d) / pr->Ucf[ELEV]);
|
||||
}
|
||||
|
||||
// Compute Reynolds No.
|
||||
// Flow rate made consistent with how its saved to hydraulics file
|
||||
q = (hyd->LinkStatus[k] <= CLOSED) ? 0.0 : hyd->LinkFlow[k];
|
||||
a = PI * d * d / 4.0; // pipe area
|
||||
u = fabs(q) / a; // flow velocity
|
||||
Re = u * d / hyd->Viscos; // Reynolds number
|
||||
|
||||
// Compute Sherwood No. for stagnant flow
|
||||
// (mass transfer coeff. = Diffus./radius)
|
||||
if (Re < 1.0) Sh = 2.0;
|
||||
|
||||
// Compute Sherwood No. for turbulent flow using the Notter-Sleicher formula.
|
||||
else if (Re >= 2300.0) Sh = 0.0149 * pow(Re, 0.88) * pow(qual->Sc, 0.333);
|
||||
|
||||
// Compute Sherwood No. for laminar flow using Graetz solution formula.
|
||||
else
|
||||
{
|
||||
y = d / net->Link[k].Len * Re * qual->Sc;
|
||||
Sh = 3.65 + 0.0668 * y / (1.0 + 0.04 * pow(y, 0.667));
|
||||
}
|
||||
|
||||
// Compute mass transfer coeff. (in ft/sec)
|
||||
kf = Sh * qual->Diffus / d;
|
||||
|
||||
// For zero-order reaction, return mass transfer coeff.
|
||||
if (qual->WallOrder == 0.0) return kf;
|
||||
|
||||
// For first-order reaction, return apparent wall coeff.
|
||||
kw = net->Link[k].Kw / pr->Ucf[ELEV]; // Wall coeff, ft/sec
|
||||
kw = (4.0 / d) * kw * kf / (kf + fabs(kw)); // Wall coeff, 1/sec
|
||||
return kw;
|
||||
}
|
||||
|
||||
|
||||
double pipereact(Project *pr, int k, double c, double v, long dt)
|
||||
/*
|
||||
**------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** c = current quality in segment
|
||||
** v = segment volume
|
||||
** dt = time step
|
||||
** Output: returns new WQ value
|
||||
** Purpose: computes new quality in a pipe segment after
|
||||
** reaction occurs
|
||||
**------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double cnew, dc, dcbulk, dcwall, rbulk, rwall;
|
||||
|
||||
// For water age (hrs), update concentration by timestep
|
||||
if (qual->Qualflag == AGE)
|
||||
{
|
||||
dc = (double)dt / 3600.0;
|
||||
cnew = c + dc;
|
||||
cnew = MAX(0.0, cnew);
|
||||
return cnew;
|
||||
}
|
||||
|
||||
// Otherwise find bulk & wall reaction rates
|
||||
rbulk = bulkrate(pr, c, net->Link[k].Kb, qual->BulkOrder) * qual->Bucf;
|
||||
rwall = wallrate(pr, c, net->Link[k].Diam, net->Link[k].Kw, net->Link[k].Rc);
|
||||
|
||||
// Find change in concentration over timestep
|
||||
dcbulk = rbulk * (double)dt;
|
||||
dcwall = rwall * (double)dt;
|
||||
|
||||
// Update cumulative mass reacted
|
||||
if (pr->times.Htime >= pr->times.Rstart)
|
||||
{
|
||||
qual->Wbulk += fabs(dcbulk) * v;
|
||||
qual->Wwall += fabs(dcwall) * v;
|
||||
}
|
||||
|
||||
// Update concentration
|
||||
dc = dcbulk + dcwall;
|
||||
cnew = c + dc;
|
||||
cnew = MAX(0.0, cnew);
|
||||
return cnew;
|
||||
}
|
||||
|
||||
|
||||
double tankreact(Project *pr, double c, double v, double kb, long dt)
|
||||
/*
|
||||
**-------------------------------------------------------
|
||||
** Input: c = current quality in tank
|
||||
** v = tank volume
|
||||
** kb = reaction coeff.
|
||||
** dt = time step
|
||||
** Output: returns new WQ value
|
||||
** Purpose: computes new quality in a tank after
|
||||
** reaction occurs
|
||||
**-------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double cnew, dc, rbulk;
|
||||
|
||||
// For water age, update concentration by timestep
|
||||
if (qual->Qualflag == AGE)
|
||||
{
|
||||
dc = (double)dt / 3600.0;
|
||||
}
|
||||
|
||||
// For chemical analysis apply bulk reaction rate
|
||||
else
|
||||
{
|
||||
// Find bulk reaction rate
|
||||
rbulk = bulkrate(pr, c, kb, qual->TankOrder) * qual->Tucf;
|
||||
|
||||
// Find concentration change & update quality
|
||||
dc = rbulk * (double)dt;
|
||||
if (pr->times.Htime >= pr->times.Rstart)
|
||||
{
|
||||
qual->Wtank += fabs(dc) * v;
|
||||
}
|
||||
}
|
||||
cnew = c + dc;
|
||||
cnew = MAX(0.0, cnew);
|
||||
return cnew;
|
||||
}
|
||||
|
||||
|
||||
double bulkrate(Project *pr, double c, double kb, double order)
|
||||
/*
|
||||
**-----------------------------------------------------------
|
||||
** Input: c = current WQ concentration
|
||||
** kb = bulk reaction coeff.
|
||||
** order = bulk reaction order
|
||||
** Output: returns bulk reaction rate
|
||||
** Purpose: computes bulk reaction rate (mass/volume/time)
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double c1;
|
||||
|
||||
// Find bulk reaction potential taking into account
|
||||
// limiting potential & reaction order.
|
||||
|
||||
// Zero-order kinetics:
|
||||
if (order == 0.0) c = 1.0;
|
||||
|
||||
// Michaelis-Menton kinetics:
|
||||
else if (order < 0.0)
|
||||
{
|
||||
c1 = qual->Climit + SGN(kb) * c;
|
||||
if (fabs(c1) < TINY) c1 = SGN(c1) * TINY;
|
||||
c = c / c1;
|
||||
}
|
||||
|
||||
// N-th order kinetics:
|
||||
else
|
||||
{
|
||||
// Account for limiting potential
|
||||
if (qual->Climit == 0.0) c1 = c;
|
||||
else c1 = MAX(0.0, SGN(kb) * (qual->Climit - c));
|
||||
|
||||
// Compute concentration potential
|
||||
if (order == 1.0) c = c1;
|
||||
else if (order == 2.0) c = c1 * c;
|
||||
else c = c1 * pow(MAX(0.0, c), order - 1.0);
|
||||
}
|
||||
|
||||
// Reaction rate = bulk coeff. * potential
|
||||
if (c < 0) c = 0;
|
||||
return kb * c;
|
||||
}
|
||||
|
||||
|
||||
double wallrate(Project *pr, double c, double d, double kw, double kf)
|
||||
/*
|
||||
**------------------------------------------------------------
|
||||
** Input: c = current WQ concentration
|
||||
** d = pipe diameter
|
||||
** kw = intrinsic wall reaction coeff.
|
||||
** kf = mass transfer coeff. for 0-order reaction
|
||||
** (ft/sec) or apparent wall reaction coeff.
|
||||
** for 1-st order reaction (1/sec)
|
||||
** Output: returns wall reaction rate in mass/ft3/sec
|
||||
** Purpose: computes wall reaction rate
|
||||
**------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
if (kw == 0.0 || d == 0.0) return (0.0);
|
||||
|
||||
if (qual->WallOrder == 0.0) // 0-order reaction */
|
||||
{
|
||||
kf = SGN(kw) * c * kf; //* Mass transfer rate (mass/ft2/sec)
|
||||
kw = kw * SQR(pr->Ucf[ELEV]); // Reaction rate (mass/ft2/sec)
|
||||
if (fabs(kf) < fabs(kw)) kw = kf; // Reaction mass transfer limited
|
||||
return (kw * 4.0 / d); // Reaction rate (mass/ft3/sec)
|
||||
}
|
||||
else return (c * kf); // 1st-order reaction
|
||||
}
|
||||
|
||||
|
||||
double mixtank(Project *pr, int n, double volin, double massin, double volout)
|
||||
/*
|
||||
**------------------------------------------------------------
|
||||
** Input: n = node index
|
||||
** volin = inflow volume to tank over time step
|
||||
** massin = mass inflow to tank over time step
|
||||
** volout = outflow volume from tank over time step
|
||||
** Output: returns new quality for tank
|
||||
** Purpose: mixes inflow with tank's contents to update its quality.
|
||||
**------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
|
||||
int i;
|
||||
double vnet;
|
||||
i = n - net->Njuncs;
|
||||
vnet = volin - volout;
|
||||
switch (net->Tank[i].MixModel)
|
||||
{
|
||||
case MIX1: tankmix1(pr, i, volin, massin, vnet); break;
|
||||
case MIX2: tankmix2(pr, i, volin, massin, vnet); break;
|
||||
case FIFO: tankmix3(pr, i, volin, massin, vnet); break;
|
||||
case LIFO: tankmix4(pr, i, volin, massin, vnet); break;
|
||||
}
|
||||
return net->Tank[i].C;
|
||||
}
|
||||
|
||||
|
||||
void tankmix1(Project *pr, int i, double vin, double win, double vnet)
|
||||
/*
|
||||
**---------------------------------------------
|
||||
** Input: i = tank index
|
||||
** vin = inflow volume
|
||||
** win = mass inflow
|
||||
** vnet = inflow - outflow
|
||||
** Output: none
|
||||
** Purpose: updates quality in a complete mix tank model
|
||||
**---------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k;
|
||||
double vnew;
|
||||
Pseg seg;
|
||||
Stank *tank = &net->Tank[i];
|
||||
|
||||
k = net->Nlinks + i;
|
||||
seg = qual->FirstSeg[k];
|
||||
if (seg)
|
||||
{
|
||||
vnew = seg->v + vin;
|
||||
if (vnew > 0.0) seg->c = (seg->c * seg->v + win) / vnew;
|
||||
seg->v += vnet;
|
||||
seg->v = MAX(0.0, seg->v);
|
||||
tank->C = seg->c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tankmix2(Project *pr, int i, double vin, double win, double vnet)
|
||||
/*
|
||||
**------------------------------------------------
|
||||
** Input: i = tank index
|
||||
** vin = inflow volume
|
||||
** win = mass inflow
|
||||
** vnet = inflow - outflow
|
||||
** Output: none
|
||||
** Purpose: updates quality in a 2-compartment tank model
|
||||
**------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k;
|
||||
double vt, // Transferred volume
|
||||
vmz; // Full mixing zone volume
|
||||
Pseg mixzone, // Mixing zone segment
|
||||
stagzone; // Stagnant zone segment
|
||||
Stank *tank = &pr->network.Tank[i];
|
||||
|
||||
// Identify segments for each compartment
|
||||
k = net->Nlinks + i;
|
||||
mixzone = qual->LastSeg[k];
|
||||
stagzone = qual->FirstSeg[k];
|
||||
if (mixzone == NULL || stagzone == NULL) return;
|
||||
|
||||
// Full mixing zone volume
|
||||
vmz = tank->V1max;
|
||||
|
||||
// Tank is filling
|
||||
vt = 0.0;
|
||||
if (vnet > 0.0)
|
||||
{
|
||||
vt = MAX(0.0, (mixzone->v + vnet - vmz));
|
||||
if (vin > 0.0)
|
||||
{
|
||||
mixzone->c = ((mixzone->c) * (mixzone->v) + win) /
|
||||
(mixzone->v + vin);
|
||||
}
|
||||
if (vt > 0.0)
|
||||
{
|
||||
stagzone->c = ((stagzone->c) * (stagzone->v) +
|
||||
(mixzone->c) * vt) / (stagzone->v + vt);
|
||||
}
|
||||
}
|
||||
|
||||
// Tank is emptying
|
||||
else if (vnet < 0.0)
|
||||
{
|
||||
if (stagzone->v > 0.0) vt = MIN(stagzone->v, (-vnet));
|
||||
if (vin + vt > 0.0)
|
||||
{
|
||||
mixzone->c = ((mixzone->c) * (mixzone->v) + win +
|
||||
(stagzone->c) * vt) / (mixzone->v + vin + vt);
|
||||
}
|
||||
}
|
||||
|
||||
// Update segment volumes
|
||||
if (vt > 0.0)
|
||||
{
|
||||
mixzone->v = vmz;
|
||||
if (vnet > 0.0) stagzone->v += vt;
|
||||
else stagzone->v = MAX(0.0, ((stagzone->v) - vt));
|
||||
}
|
||||
else
|
||||
{
|
||||
mixzone->v += vnet;
|
||||
mixzone->v = MIN(mixzone->v, vmz);
|
||||
mixzone->v = MAX(0.0, mixzone->v);
|
||||
stagzone->v = 0.0;
|
||||
}
|
||||
|
||||
// Use quality of mixing zone to represent quality of
|
||||
// tank since this is where outflow begins to flow from
|
||||
tank->C = mixzone->c;
|
||||
}
|
||||
|
||||
|
||||
void tankmix3(Project *pr, int i, double vin, double win, double vnet)
|
||||
/*
|
||||
**----------------------------------------------------------
|
||||
** Input: i = tank index
|
||||
** vin = inflow volume
|
||||
** win = mass inflow
|
||||
** vnet = inflow - outflow
|
||||
** Output: none
|
||||
** Purpose: Updates quality in a First-In-First-Out (FIFO) tank model.
|
||||
**----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k;
|
||||
double vout, vseg;
|
||||
double cin, vsum, wsum;
|
||||
Pseg seg;
|
||||
Stank *tank = &pr->network.Tank[i];
|
||||
|
||||
k = net->Nlinks + i;
|
||||
if (qual->LastSeg[k] == NULL || qual->FirstSeg[k] == NULL) return;
|
||||
|
||||
// Add new last segment for flow entering the tank
|
||||
if (vin > 0.0)
|
||||
{
|
||||
// ... increase segment volume if inflow has same quality as segment
|
||||
cin = win / vin;
|
||||
seg = qual->LastSeg[k];
|
||||
if (fabs(seg->c - cin) < qual->Ctol) seg->v += vin;
|
||||
|
||||
// ... otherwise add a new last segment to the tank
|
||||
else addseg(pr, k, vin, cin);
|
||||
}
|
||||
|
||||
// Withdraw flow from first segment
|
||||
vsum = 0.0;
|
||||
wsum = 0.0;
|
||||
vout = vin - vnet;
|
||||
while (vout > 0.0)
|
||||
{
|
||||
seg = qual->FirstSeg[k];
|
||||
if (seg == NULL) break;
|
||||
vseg = seg->v; // Flow volume from leading seg
|
||||
vseg = MIN(vseg, vout);
|
||||
if (seg == qual->LastSeg[k]) vseg = vout;
|
||||
vsum += vseg;
|
||||
wsum += (seg->c) * vseg;
|
||||
vout -= vseg; // Remaining flow volume
|
||||
if (vout >= 0.0 && vseg >= seg->v) // Seg used up
|
||||
{
|
||||
if (seg->prev)
|
||||
{
|
||||
qual->FirstSeg[k] = seg->prev;
|
||||
seg->prev = qual->FreeSeg;
|
||||
qual->FreeSeg = seg;
|
||||
}
|
||||
}
|
||||
else seg->v -= vseg; // Remaining volume in segment
|
||||
}
|
||||
|
||||
// Use quality withdrawn from 1st segment
|
||||
// to represent overall quality of tank
|
||||
if (vsum > 0.0) tank->C = wsum / vsum;
|
||||
else if (qual->FirstSeg[k] == NULL) tank->C = 0.0;
|
||||
else tank->C = qual->FirstSeg[k]->c;
|
||||
}
|
||||
|
||||
|
||||
void tankmix4(Project *pr, int i, double vin, double win, double vnet)
|
||||
/*
|
||||
**----------------------------------------------------------
|
||||
** Input: i = tank index
|
||||
** vin = inflow volume
|
||||
** win = mass inflow
|
||||
** vnet = inflow - outflow
|
||||
** Output: none
|
||||
** Purpose: Updates quality in a Last In-First Out (LIFO) tank model.
|
||||
**----------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k;
|
||||
double cin, vsum, wsum, vseg;
|
||||
Pseg seg;
|
||||
Stank *tank = &pr->network.Tank[i];
|
||||
|
||||
k = net->Nlinks + i;
|
||||
if (qual->LastSeg[k] == NULL || qual->FirstSeg[k] == NULL) return;
|
||||
|
||||
// Find inflows & outflows
|
||||
if (vin > 0.0) cin = win / vin;
|
||||
else cin = 0.0;
|
||||
|
||||
// If tank filling, then create new last seg
|
||||
tank->C = qual->LastSeg[k]->c;
|
||||
seg = qual->LastSeg[k];
|
||||
if (vnet > 0.0)
|
||||
{
|
||||
// ... inflow quality is same as last segment's quality,
|
||||
// so just add inflow volume to last segment
|
||||
if (fabs(seg->c - cin) < qual->Ctol) seg->v += vnet;
|
||||
|
||||
// ... otherwise add a new last segment with inflow quality
|
||||
else addseg(pr, k, vnet, cin);
|
||||
|
||||
// Update reported tank quality
|
||||
tank->C = qual->LastSeg[k]->c;
|
||||
}
|
||||
|
||||
// If tank emptying then remove last segments until vnet consumed
|
||||
else if (vnet < 0.0)
|
||||
{
|
||||
vsum = 0.0;
|
||||
wsum = 0.0;
|
||||
vnet = -vnet;
|
||||
|
||||
// Reverse segment chain so segments are processed from last to first
|
||||
reversesegs(pr, k);
|
||||
|
||||
// While there is still volume to remove
|
||||
while (vnet > 0.0)
|
||||
{
|
||||
// ... start with reversed first segment
|
||||
seg = qual->FirstSeg[k];
|
||||
if (seg == NULL) break;
|
||||
|
||||
// ... find volume to remove from it
|
||||
vseg = seg->v;
|
||||
vseg = MIN(vseg, vnet);
|
||||
if (seg == qual->LastSeg[k]) vseg = vnet;
|
||||
|
||||
// ... update total volume & mass removed
|
||||
vsum += vseg;
|
||||
wsum += (seg->c) * vseg;
|
||||
|
||||
// ... update remiaing volume to remove
|
||||
vnet -= vseg;
|
||||
|
||||
// ... if no more volume left in current segment
|
||||
if (vnet >= 0.0 && vseg >= seg->v)
|
||||
{
|
||||
// ... replace current segment with previous one
|
||||
if (seg->prev)
|
||||
{
|
||||
qual->FirstSeg[k] = seg->prev;
|
||||
seg->prev = qual->FreeSeg;
|
||||
qual->FreeSeg = seg;
|
||||
}
|
||||
}
|
||||
|
||||
// ... otherwise reduce volume of current segment
|
||||
else seg->v -= vseg;
|
||||
}
|
||||
|
||||
// Restore original orientation of segment chain
|
||||
reversesegs(pr, k);
|
||||
|
||||
// Reported tank quality is mixture of flow released and any inflow
|
||||
tank->C = (wsum + win) / (vsum + vin);
|
||||
}
|
||||
}
|
||||
694
src/qualroute.c
Normal file
694
src/qualroute.c
Normal file
@@ -0,0 +1,694 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: qualroute.c
|
||||
Description: computes water quality transport over a single time step
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 05/15/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "mempool.h"
|
||||
#include "types.h"
|
||||
|
||||
// Macro to compute the volume of a link
|
||||
#define LINKVOL(k) (0.785398 * net->Link[(k)].Len * SQR(net->Link[(k)].Diam))
|
||||
|
||||
// Macro to get link flow compatible with flow saved to hydraulics file
|
||||
#define LINKFLOW(k) ((hyd->LinkStatus[k] <= CLOSED) ? 0.0 : hyd->LinkFlow[k])
|
||||
|
||||
// Exported functions
|
||||
int sortnodes(Project *);
|
||||
void transport(Project *, long);
|
||||
void initsegs(Project *);
|
||||
void reversesegs(Project *, int);
|
||||
void addseg(Project *, int, double, double);
|
||||
|
||||
// Imported functions
|
||||
extern double findsourcequal(Project *, int, double, long);
|
||||
extern void reactpipes(Project *, long);
|
||||
extern void reacttanks(Project *, long);
|
||||
extern double mixtank(Project *, int, double, double, double);
|
||||
|
||||
// Local functions
|
||||
static void evalnodeinflow(Project *, int, long, double *, double *);
|
||||
static void evalnodeoutflow(Project *, int, double, long);
|
||||
static double findnodequal(Project *, int, double, double, double, long);
|
||||
static double noflowqual(Project *, int);
|
||||
static void updatemassbalance(Project *, int, double, double, long);
|
||||
static int selectnonstacknode(Project *, int, int *);
|
||||
|
||||
|
||||
void transport(Project *pr, long tstep)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: tstep = length of current time step
|
||||
** Output: none
|
||||
** Purpose: transports constituent mass through the pipe network
|
||||
** under a period of constant hydraulic conditions.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int j, k, m, n;
|
||||
double volin, massin, volout, nodequal;
|
||||
Padjlist alink;
|
||||
|
||||
// React contents of each pipe and tank
|
||||
if (qual->Reactflag)
|
||||
{
|
||||
reactpipes(pr, tstep);
|
||||
reacttanks(pr, tstep);
|
||||
}
|
||||
|
||||
// Analyze each node in topological order
|
||||
for (j = 1; j <= net->Nnodes; j++)
|
||||
{
|
||||
// ... index of node to be processed
|
||||
n = qual->SortedNodes[j];
|
||||
|
||||
// ... zero out mass & flow volumes for this node
|
||||
volin = 0.0;
|
||||
massin = 0.0;
|
||||
volout = 0.0;
|
||||
|
||||
// ... examine each link with flow into the node
|
||||
for (alink = net->Adjlist[n]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
// ... k is index of next link incident on node n
|
||||
k = alink->link;
|
||||
|
||||
// ... link has flow into node - add it to node's inflow
|
||||
// (m is index of link's downstream node)
|
||||
m = net->Link[k].N2;
|
||||
if (qual->FlowDir[k] < 0) m = net->Link[k].N1;
|
||||
if (m == n)
|
||||
{
|
||||
evalnodeinflow(pr, k, tstep, &volin, &massin);
|
||||
}
|
||||
|
||||
// ... link has flow out of node - add it to node's outflow
|
||||
else volout += fabs(LINKFLOW(k));
|
||||
}
|
||||
|
||||
// ... if node is a junction, add on any external outflow (e.g., demands)
|
||||
if (net->Node[n].Type == JUNCTION)
|
||||
{
|
||||
volout += MAX(0.0, hyd->NodeDemand[n]);
|
||||
}
|
||||
|
||||
// ... convert from outflow rate to volume
|
||||
volout *= tstep;
|
||||
|
||||
// ... find the concentration of flow leaving the node
|
||||
nodequal = findnodequal(pr, n, volin, massin, volout, tstep);
|
||||
|
||||
// ... examine each link with flow out of the node
|
||||
for (alink = net->Adjlist[n]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
// ... link k incident on node n has upstream node m equal to n
|
||||
k = alink->link;
|
||||
m = net->Link[k].N1;
|
||||
if (qual->FlowDir[k] < 0) m = net->Link[k].N2;
|
||||
if (m == n)
|
||||
{
|
||||
// ... send flow at new node concen. into link
|
||||
evalnodeoutflow(pr, k, nodequal, tstep);
|
||||
}
|
||||
}
|
||||
updatemassbalance(pr, n, massin, volout, tstep);
|
||||
}
|
||||
}
|
||||
|
||||
void evalnodeinflow(Project *pr, int k, long tstep, double *volin,
|
||||
double *massin)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** tstep = quality routing time step
|
||||
** Output: volin = flow volume entering a node
|
||||
** massin = constituent mass entering a node
|
||||
** Purpose: adds the contribution of a link's outflow volume
|
||||
** and constituent mass to the total inflow into its
|
||||
** downstream node over a time step.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double q, v, vseg;
|
||||
Pseg seg;
|
||||
|
||||
// Get flow rate (q) and flow volume (v) through link
|
||||
q = LINKFLOW(k);
|
||||
v = fabs(q) * tstep;
|
||||
|
||||
// Transport flow volume v from link's leading segments into downstream
|
||||
// node, removing segments once their full volume is consumed
|
||||
while (v > 0.0)
|
||||
{
|
||||
seg = qual->FirstSeg[k];
|
||||
if (!seg) break;
|
||||
|
||||
// ... volume transported from first segment is smaller of
|
||||
// remaining flow volume & segment volume
|
||||
vseg = seg->v;
|
||||
vseg = MIN(vseg, v);
|
||||
|
||||
// ... update total volume & mass entering downstream node
|
||||
*volin += vseg;
|
||||
*massin += vseg * seg->c;
|
||||
|
||||
// ... reduce remaining flow volume by amount transported
|
||||
v -= vseg;
|
||||
|
||||
// ... if all of segment's volume was transferred
|
||||
if (v >= 0.0 && vseg >= seg->v)
|
||||
{
|
||||
// ... replace this leading segment with the one behind it
|
||||
qual->FirstSeg[k] = seg->prev;
|
||||
if (qual->FirstSeg[k] == NULL) qual->LastSeg[k] = NULL;
|
||||
|
||||
// ... recycle the used up segment
|
||||
seg->prev = qual->FreeSeg;
|
||||
qual->FreeSeg = seg;
|
||||
}
|
||||
|
||||
// ... otherwise just reduce this segment's volume
|
||||
else seg->v -= vseg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double findnodequal(Project *pr, int n, double volin,
|
||||
double massin, double volout, long tstep)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: n = node index
|
||||
** volin = flow volume entering node
|
||||
** massin = mass entering node
|
||||
** volout = flow volume leaving node
|
||||
** tstep = length of current time step
|
||||
** Output: returns water quality in a node's outflow
|
||||
** Purpose: computes a node's new quality from its inflow
|
||||
** volume and mass, including any source contribution.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
// Node is a junction - update its water quality
|
||||
if (net->Node[n].Type == JUNCTION)
|
||||
{
|
||||
// ... dilute inflow with any external negative demand
|
||||
volin -= MIN(0.0, hyd->NodeDemand[n]) * tstep;
|
||||
|
||||
// ... new concen. is mass inflow / volume inflow
|
||||
if (volin > 0.0) qual->NodeQual[n] = massin / volin;
|
||||
|
||||
// ... if no inflow adjust quality for reaction in connecting pipes
|
||||
else if (qual->Reactflag) qual->NodeQual[n] = noflowqual(pr, n);
|
||||
}
|
||||
|
||||
// Node is a tank - use its mixing model to update its quality
|
||||
else if (net->Node[n].Type == TANK)
|
||||
{
|
||||
qual->NodeQual[n] = mixtank(pr, n, volin, massin, volout);
|
||||
}
|
||||
|
||||
// Add any external quality source onto node's concen.
|
||||
qual->SourceQual = 0.0;
|
||||
|
||||
// For source tracing analysis find tracer added at source node
|
||||
if (qual->Qualflag == TRACE)
|
||||
{
|
||||
if (n == qual->TraceNode)
|
||||
{
|
||||
// ... quality added to network is difference between tracer
|
||||
// concentration (100 mg/L) and current node quality
|
||||
if (net->Node[n].Type == RESERVOIR) qual->SourceQual = 100.0;
|
||||
else qual->SourceQual = MAX(100.0 - qual->NodeQual[n], 0.0);
|
||||
qual->NodeQual[n] = 100.0;
|
||||
}
|
||||
return qual->NodeQual[n];
|
||||
}
|
||||
|
||||
// Find quality contribued by any external chemical source
|
||||
else qual->SourceQual = findsourcequal(pr, n, volout, tstep);
|
||||
if (qual->SourceQual == 0.0) return qual->NodeQual[n];
|
||||
|
||||
// Combine source quality with node quality
|
||||
switch (net->Node[n].Type)
|
||||
{
|
||||
case JUNCTION:
|
||||
qual->NodeQual[n] += qual->SourceQual;
|
||||
return qual->NodeQual[n];
|
||||
|
||||
case TANK:
|
||||
return qual->NodeQual[n] + qual->SourceQual;
|
||||
|
||||
case RESERVOIR:
|
||||
qual->NodeQual[n] = qual->SourceQual;
|
||||
return qual->SourceQual;
|
||||
}
|
||||
return qual->NodeQual[n];
|
||||
}
|
||||
|
||||
|
||||
double noflowqual(Project *pr, int n)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: n = node index
|
||||
** Output: quality for node n
|
||||
** Purpose: sets the quality for a junction node that has no
|
||||
** inflow to the average of the quality in its
|
||||
** adjoining link segments.
|
||||
** Note: this function is only used for reactive substances.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int k, inflow, kount = 0;
|
||||
double c = 0.0;
|
||||
FlowDirection dir;
|
||||
Padjlist alink;
|
||||
|
||||
// Examine each link incident on the node
|
||||
for (alink = net->Adjlist[n]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
// ... index of an incident link
|
||||
k = alink->link;
|
||||
dir = qual->FlowDir[k];
|
||||
|
||||
// Node n is link's downstream node - add quality
|
||||
// of link's first segment to average
|
||||
if (net->Link[k].N2 == n && dir >= 0) inflow = TRUE;
|
||||
else if (net->Link[k].N1 == n && dir < 0) inflow = TRUE;
|
||||
else inflow = FALSE;
|
||||
if (inflow == TRUE && qual->FirstSeg[k] != NULL)
|
||||
{
|
||||
c += qual->FirstSeg[k]->c;
|
||||
kount++;
|
||||
}
|
||||
|
||||
// Node n is link's upstream node - add quality
|
||||
// of link's last segment to average
|
||||
else if (inflow == FALSE && qual->LastSeg[k] != NULL)
|
||||
{
|
||||
c += qual->LastSeg[k]->c;
|
||||
kount++;
|
||||
}
|
||||
}
|
||||
if (kount > 0) c = c / (double)kount;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void evalnodeoutflow(Project *pr, int k, double c, long tstep)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** c = quality from upstream node
|
||||
** tstep = time step
|
||||
** Output: none
|
||||
** Purpose: releases flow volume and mass from the upstream
|
||||
** node of a link over a time step.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double v;
|
||||
Pseg seg;
|
||||
|
||||
// Find flow volume (v) released over time step
|
||||
v = fabs(LINKFLOW(k)) * tstep;
|
||||
if (v == 0.0) return;
|
||||
|
||||
// Release flow and mass into upstream end of the link
|
||||
|
||||
// ... case where link has a last (most upstream) segment
|
||||
seg = qual->LastSeg[k];
|
||||
if (seg)
|
||||
{
|
||||
// ... if node quality close to segment quality then mix
|
||||
// the nodal outflow volume with the segment's volume
|
||||
if (fabs(seg->c - c) < qual->Ctol)
|
||||
{
|
||||
seg->c = (seg->c*seg->v + c*v) / (seg->v + v);
|
||||
seg->v += v;
|
||||
}
|
||||
|
||||
// ... otherwise add a new segment at upstream end of link
|
||||
else addseg(pr, k, v, c);
|
||||
}
|
||||
|
||||
// ... link has no segments so add one
|
||||
else addseg(pr, k, v, c);
|
||||
}
|
||||
|
||||
|
||||
void updatemassbalance(Project *pr, int n, double massin,
|
||||
double volout, long tstep)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: n = node index
|
||||
** massin = mass inflow to node
|
||||
** volout = outflow volume from node
|
||||
** Output: none
|
||||
** Purpose: Adds a node's external mass inflow and outflow
|
||||
** over the current time step to the network's
|
||||
** overall mass balance.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Hydraul *hyd = &pr->hydraul;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
double masslost = 0.0,
|
||||
massadded = 0.0;
|
||||
|
||||
switch (net->Node[n].Type)
|
||||
{
|
||||
// Junctions lose mass from outflow demand & gain it from source inflow
|
||||
case JUNCTION:
|
||||
masslost = MAX(0.0, hyd->NodeDemand[n]) * tstep * qual->NodeQual[n];
|
||||
massadded = qual->SourceQual * volout;
|
||||
break;
|
||||
|
||||
// Reservoirs add mass from quality source if specified or from a fixed
|
||||
// initial quality
|
||||
case RESERVOIR:
|
||||
masslost = massin;
|
||||
if (qual->SourceQual > 0.0) massadded = qual->SourceQual * volout;
|
||||
else massadded = qual->NodeQual[n] * volout;
|
||||
break;
|
||||
|
||||
// Tanks add mass only from external source inflow
|
||||
case TANK:
|
||||
massadded = qual->SourceQual * volout;
|
||||
break;
|
||||
}
|
||||
qual->MassBalance.outflow += masslost;
|
||||
qual->MassBalance.inflow += massadded;
|
||||
}
|
||||
|
||||
|
||||
int sortnodes(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: returns an error code
|
||||
** Purpose: topologically sorts nodes from upstream to downstream.
|
||||
** Note: links with negligible flow are ignored since they can
|
||||
** create spurious cycles that cause the sort to fail.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int i, j, k, n;
|
||||
int *indegree = NULL;
|
||||
int *stack = NULL;
|
||||
int stacksize = 0;
|
||||
int numsorted = 0;
|
||||
int errcode = 0;
|
||||
FlowDirection dir;
|
||||
Padjlist alink;
|
||||
|
||||
// Allocate an array to count # links with inflow to each node
|
||||
// and for a stack to hold nodes waiting to be processed
|
||||
indegree = (int *)calloc(net->Nnodes + 1, sizeof(int));
|
||||
stack = (int *)calloc(net->Nnodes + 1, sizeof(int));
|
||||
if (indegree && stack)
|
||||
{
|
||||
// Count links with "non-negligible" inflow to each node
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
dir = qual->FlowDir[k];
|
||||
if (dir == POSITIVE) n = net->Link[k].N2;
|
||||
else if (dir == NEGATIVE) n = net->Link[k].N1;
|
||||
else continue;
|
||||
indegree[n]++;
|
||||
}
|
||||
|
||||
// Place nodes with no inflow onto a stack
|
||||
for (i = 1; i <= net->Nnodes; i++)
|
||||
{
|
||||
if (indegree[i] == 0)
|
||||
{
|
||||
stacksize++;
|
||||
stack[stacksize] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Examine each node on the stack until none are left
|
||||
while (numsorted < net->Nnodes)
|
||||
{
|
||||
// ... if stack is empty then a cycle exists
|
||||
if (stacksize == 0)
|
||||
{
|
||||
// ... add a non-sorted node connected to a sorted one to stack
|
||||
j = selectnonstacknode(pr, numsorted, indegree);
|
||||
if (j == 0) break; // This shouldn't happen.
|
||||
indegree[j] = 0;
|
||||
stacksize++;
|
||||
stack[stacksize] = j;
|
||||
}
|
||||
|
||||
// ... make the last node added to the stack the next
|
||||
// in sorted order & remove it from the stack
|
||||
i = stack[stacksize];
|
||||
stacksize--;
|
||||
numsorted++;
|
||||
qual->SortedNodes[numsorted] = i;
|
||||
|
||||
// ... for each outflow link from this node reduce the in-degree
|
||||
// of its downstream node
|
||||
for (alink = net->Adjlist[i]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
// ... k is the index of the next link incident on node i
|
||||
k = alink->link;
|
||||
|
||||
// ... skip link if flow is negligible
|
||||
if (qual->FlowDir[k] == 0) continue;
|
||||
|
||||
// ... link has flow out of node (downstream node n not equal to i)
|
||||
n = net->Link[k].N2;
|
||||
if (qual->FlowDir[k] < 0) n = net->Link[k].N1;
|
||||
|
||||
// ... reduce degree of node n
|
||||
if (n != i && indegree[n] > 0)
|
||||
{
|
||||
indegree[n]--;
|
||||
|
||||
// ... no more degree left so add node n to stack
|
||||
if (indegree[n] == 0)
|
||||
{
|
||||
stacksize++;
|
||||
stack[stacksize] = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else errcode = 101;
|
||||
if (numsorted < net->Nnodes) errcode = 120;
|
||||
FREE(indegree);
|
||||
FREE(stack);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
|
||||
int selectnonstacknode(Project *pr, int numsorted, int *indegree)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: numsorted = number of nodes that have been sorted
|
||||
** indegree = number of inflow links to each node
|
||||
** Output: returns a node index
|
||||
** Purpose: selects a next node for sorting when a cycle exists.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int i, m, n;
|
||||
Padjlist alink;
|
||||
|
||||
// Examine each sorted node in last in - first out order
|
||||
for (i = numsorted; i > 0; i--)
|
||||
{
|
||||
// For each link connected to the sorted node
|
||||
m = qual->SortedNodes[i];
|
||||
for (alink = net->Adjlist[m]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
// ... n is the node of link k opposite to node m
|
||||
n = alink->node;
|
||||
|
||||
// ... select node n if it still has inflow links
|
||||
if (indegree[n] > 0) return n;
|
||||
}
|
||||
}
|
||||
|
||||
// If no node was selected by the above process then return the
|
||||
// first node that still has inflow links remaining
|
||||
for (i = 1; i <= net->Nnodes; i++)
|
||||
{
|
||||
if (indegree[i] > 0) return i;
|
||||
}
|
||||
|
||||
// If all else fails return 0 indicating that no node was selected
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void initsegs(Project *pr)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: none
|
||||
** Output: none
|
||||
** Purpose: initializes water quality volume segments in each
|
||||
** pipe and tank.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Network *net = &pr->network;
|
||||
Quality *qual = &pr->quality;
|
||||
|
||||
int j, k;
|
||||
double c, v, v1;
|
||||
|
||||
// Add one segment with assigned downstream node quality to each pipe
|
||||
for (k = 1; k <= net->Nlinks; k++)
|
||||
{
|
||||
qual->FirstSeg[k] = NULL;
|
||||
qual->LastSeg[k] = NULL;
|
||||
if (net->Link[k].Type == PIPE)
|
||||
{
|
||||
v = LINKVOL(k);
|
||||
j = net->Link[k].N2;
|
||||
c = qual->NodeQual[j];
|
||||
addseg(pr, k, v, c);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize segments in tanks
|
||||
for (j = 1; j <= net->Ntanks; j++)
|
||||
{
|
||||
// Skip reservoirs
|
||||
if (net->Tank[j].A == 0.0) continue;
|
||||
|
||||
// Establish initial tank quality & volume
|
||||
k = net->Tank[j].Node;
|
||||
c = net->Node[k].C0;
|
||||
v = net->Tank[j].V0;
|
||||
|
||||
// Create one volume segment for entire tank
|
||||
k = net->Nlinks + j;
|
||||
qual->FirstSeg[k] = NULL;
|
||||
qual->LastSeg[k] = NULL;
|
||||
addseg(pr, k, v, c);
|
||||
|
||||
// Create a 2nd segment for the 2-compartment tank model
|
||||
if (net->Tank[j].MixModel == MIX2)
|
||||
{
|
||||
// ... mixing zone segment
|
||||
v1 = MAX(0, v - net->Tank[j].V1max);
|
||||
qual->FirstSeg[k]->v = v1;
|
||||
|
||||
// ... stagnant zone segment
|
||||
v = v - v1;
|
||||
addseg(pr, k, v, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void reversesegs(Project *pr, int k)
|
||||
/*
|
||||
**--------------------------------------------------------------
|
||||
** Input: k = link index
|
||||
** Output: none
|
||||
** Purpose: re-orients a link's segments when flow reverses.
|
||||
**--------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Quality *qual = &pr->quality;
|
||||
Pseg seg, nseg, pseg;
|
||||
|
||||
seg = qual->FirstSeg[k];
|
||||
qual->FirstSeg[k] = qual->LastSeg[k];
|
||||
qual->LastSeg[k] = seg;
|
||||
pseg = NULL;
|
||||
while (seg != NULL)
|
||||
{
|
||||
nseg = seg->prev;
|
||||
seg->prev = pseg;
|
||||
pseg = seg;
|
||||
seg = nseg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addseg(Project *pr, int k, double v, double c)
|
||||
/*
|
||||
**-------------------------------------------------------------
|
||||
** Input: k = segment chain index
|
||||
** v = segment volume
|
||||
** c = segment quality
|
||||
** Output: none
|
||||
** Purpose: adds a segment to the start of a link
|
||||
** upstream of its current last segment.
|
||||
**-------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Quality *qual = &pr->quality;
|
||||
Pseg seg;
|
||||
|
||||
// Grab the next free segment from the segment pool if available
|
||||
if (qual->FreeSeg != NULL)
|
||||
{
|
||||
seg = qual->FreeSeg;
|
||||
qual->FreeSeg = seg->prev;
|
||||
}
|
||||
|
||||
// Otherwise allocate a new segment
|
||||
else
|
||||
{
|
||||
seg = (struct Sseg *) mempool_alloc(qual->SegPool, sizeof(struct Sseg));
|
||||
if (seg == NULL)
|
||||
{
|
||||
qual->OutOfMemory = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign volume and quality to the segment
|
||||
seg->v = v;
|
||||
seg->c = c;
|
||||
|
||||
// Add the new segment to the end of the segment chain
|
||||
seg->prev = NULL;
|
||||
if (qual->FirstSeg[k] == NULL) qual->FirstSeg[k] = seg;
|
||||
if (qual->LastSeg[k] != NULL) qual->LastSeg[k]->prev = seg;
|
||||
qual->LastSeg[k] = seg;
|
||||
}
|
||||
2729
src/report.c
Executable file → Normal file
2729
src/report.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
2333
src/rules.c
Executable file → Normal file
2333
src/rules.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1625
src/smatrix.c
1625
src/smatrix.c
File diff suppressed because it is too large
Load Diff
1036
src/text.h
1036
src/text.h
File diff suppressed because it is too large
Load Diff
1339
src/types.h
1339
src/types.h
File diff suppressed because it is too large
Load Diff
59
src/util/cstr_helper.c
Normal file
59
src/util/cstr_helper.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: util/cstr_helper.c
|
||||
Description: Provides C string helper functions
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/02/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cstr_helper.h"
|
||||
|
||||
|
||||
int cstr_duplicate(char **dest, const char *source)
|
||||
// Duplicates source string
|
||||
{
|
||||
size_t size = 1 + strlen(source);
|
||||
*dest = (char *) calloc(size, sizeof(char));
|
||||
|
||||
if (*dest == NULL)
|
||||
return -1;
|
||||
else {
|
||||
#ifdef _MSC_VER
|
||||
strncpy_s(*dest, size, source, size);
|
||||
#else
|
||||
strncpy(*dest, source, size);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool cstr_isvalid(const char *element_id)
|
||||
// Determines if invalid characters are present in an element id string
|
||||
{
|
||||
const char *invalid_chars = " \";";
|
||||
|
||||
// if invalid char is present a pointer to it is returned else NULL
|
||||
if (strpbrk(element_id, invalid_chars))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool cstr_isnullterm(const char *source)
|
||||
// Determines if the string passed is null terminated or not
|
||||
{
|
||||
if (strchr(source, '\0'))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
38
src/util/cstr_helper.h
Normal file
38
src/util/cstr_helper.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: util/cstr_helper.h
|
||||
Description: Provides C string helper functions
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/02/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CSTR_HELPER_H_
|
||||
#define CSTR_HELPER_H_
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int cstr_duplicate(char **dest, const char *source);
|
||||
|
||||
bool cstr_isvalid(const char *element_id);
|
||||
|
||||
bool cstr_isnullterm(const char *source);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* CSTR_HELPER_H_ */
|
||||
91
src/util/errormanager.c
Normal file
91
src/util/errormanager.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: util/errormanager.c
|
||||
Description: Provides a simple interface for managing errors
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/02/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
//#ifdef _WIN32
|
||||
//#define _CRTDBG_MAP_ALLOC
|
||||
//#include <stdlib.h>
|
||||
//#include <crtdbg.h>
|
||||
//#else
|
||||
#include <stdlib.h>
|
||||
//#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "errormanager.h"
|
||||
|
||||
|
||||
typedef struct error_s {
|
||||
int error_status;
|
||||
void (*p_msg_lookup)(int, char*, int);
|
||||
} error_handle_t;
|
||||
|
||||
|
||||
error_handle_t *create_error_manager(void (*p_error_message)(int, char*, int))
|
||||
//
|
||||
// Purpose: Constructs a new error handle.
|
||||
//
|
||||
{
|
||||
error_handle_t *error_handle;
|
||||
error_handle = (error_handle_t*)calloc(1, sizeof(error_handle_t));
|
||||
|
||||
error_handle->p_msg_lookup = p_error_message;
|
||||
|
||||
return error_handle;
|
||||
}
|
||||
|
||||
void delete_error_manager(error_handle_t *error_handle)
|
||||
//
|
||||
// Purpose: Destroys the error handle.
|
||||
//
|
||||
{
|
||||
free(error_handle);
|
||||
}
|
||||
|
||||
int set_error(error_handle_t *error_handle, int error_code)
|
||||
//
|
||||
// Purpose: Sets an error code in the handle.
|
||||
//
|
||||
{
|
||||
// If the error code is 0 no action is taken and 0 is returned.
|
||||
// This is a feature not a bug.
|
||||
if (error_code)
|
||||
error_handle->error_status = error_code;
|
||||
|
||||
return error_code;
|
||||
}
|
||||
|
||||
int check_error(error_handle_t *error_handle, char **error_message)
|
||||
//
|
||||
// Purpose: Returns the error message or NULL.
|
||||
//
|
||||
// Note: Caller must free memory allocated by check_error
|
||||
//
|
||||
{ int error_code = error_handle->error_status;
|
||||
char *temp = NULL;
|
||||
|
||||
if (error_code != 0) {
|
||||
temp = (char*) calloc(ERR_MAXMSG + 1, sizeof(char));
|
||||
|
||||
if (temp)
|
||||
error_handle->p_msg_lookup(error_code, temp, ERR_MAXMSG);
|
||||
}
|
||||
*error_message = temp;
|
||||
return error_code;
|
||||
}
|
||||
|
||||
void clear_error(error_handle_t *error_handle)
|
||||
//
|
||||
// Purpose: Clears the error from the handle.
|
||||
//
|
||||
{
|
||||
error_handle->error_status = 0;
|
||||
}
|
||||
39
src/util/errormanager.h
Normal file
39
src/util/errormanager.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: util/errormanager.h
|
||||
Description: Provides a simple interface for managing errors
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/02/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ERRORMANAGER_H_
|
||||
#define ERRORMANAGER_H_
|
||||
|
||||
#define ERR_MAXMSG 256
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Forward declaration
|
||||
typedef struct error_s error_handle_t;
|
||||
|
||||
error_handle_t* create_error_manager(void (*p_error_message)(int, char*, int));
|
||||
void delete_error_manager(error_handle_t* error_handle);
|
||||
|
||||
int set_error(error_handle_t* error_handle, int error_code);
|
||||
int check_error(error_handle_t* error_handle, char **error_message);
|
||||
void clear_error(error_handle_t* error_handle);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ERRORMANAGER_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user