├── tests ├── __init__.py ├── gdb.bash ├── test_epanettools_2.py ├── test_low_level_functions_via_epanettools_access.py ├── tools_for_testing.py ├── test_low_level_functions_direct_access.py ├── test_ADF.py ├── test_EPANetSimulation2.py ├── test_epanettools.py ├── test_EPANetPatterns.py └── test_EPANetPDD.py ├── requirements.txt ├── src └── epanettools │ ├── examples │ ├── __init__.py │ └── simple │ │ ├── __init__.py │ │ ├── epanet2_test.py │ │ └── Net1.inp │ ├── __init__.py │ ├── adf │ ├── adfandenergycalc.h │ ├── main.cc │ ├── callepanet.h │ └── callepanet.cc │ ├── pdd │ ├── README.txt │ ├── include.h │ ├── mods.cpp │ ├── wrapper.h │ └── wrap.cpp │ ├── patch.c │ ├── __main__.py │ ├── epanet │ ├── hash.h │ ├── mempool.h │ ├── hash.c │ ├── mempool.c │ ├── enumstxt.h │ ├── epanet2.h │ ├── toolkit.h │ └── vars.h │ ├── patch.h │ ├── cli.py │ ├── tools.py │ ├── adf.i │ ├── epanet2.i │ ├── pdd.i │ ├── pdd_class_wrapper.py │ ├── adf.py │ └── epanet2.py ├── docs ├── authors.rst ├── readme.rst ├── changelog.rst ├── contributing.rst ├── requirements.txt ├── reference │ ├── index.rst │ └── epanettools.rst ├── usage.rst ├── installation.rst ├── spelling_wordlist.txt ├── index.rst ├── README.building ├── HISTORY.txt ├── conf.py └── Readme.epanet2.txt ├── swig_wrap.bat ├── AUTHORS.rst ├── set.bash ├── .bumpversion.cfg ├── .coveragerc ├── .editorconfig ├── cov.bash ├── cc ├── src │ ├── main.c │ └── main2.cxx └── epanet │ └── epanet.cbp ├── MANIFEST.in ├── .gitattributes ├── RELEASE.txt ├── ci ├── templates │ ├── .travis.yml │ └── appveyor.yml ├── appveyor-with-compiler.cmd ├── bootstrap.py ├── appveyor-download.py └── appveyor-bootstrap.py ├── CHANGELOG.rst ├── setup.cfg ├── junk ├── epanetpatches │ └── epanet.c.patch ├── prj.wpr └── t.cbp ├── .gitignore ├── LICENSE ├── BUILDING.txt ├── appveyor.yml ├── .cookiecutterrc ├── .travis.yml ├── appveyor_download.py ├── CONTRIBUTING.rst ├── tox.ini └── setup.py /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | coverage>=4.5.1 2 | -------------------------------------------------------------------------------- /src/epanettools/examples/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/epanettools/examples/simple/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/authors.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../AUTHORS.rst 2 | -------------------------------------------------------------------------------- /docs/readme.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CHANGELOG.rst 2 | -------------------------------------------------------------------------------- /src/epanettools/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "1.0.0" 2 | -------------------------------------------------------------------------------- /docs/contributing.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CONTRIBUTING.rst 2 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=1.3 2 | sphinx-rtd-theme 3 | -e . 4 | 5 | -------------------------------------------------------------------------------- /tests/gdb.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | env PYTHONPATH=/home/user/epanettools:/home/user/epanettools/src: gdb python3 3 | -------------------------------------------------------------------------------- /docs/reference/index.rst: -------------------------------------------------------------------------------- 1 | Reference 2 | ========= 3 | 4 | .. toctree:: 5 | :glob: 6 | 7 | epanettools* 8 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | Usage 3 | ===== 4 | 5 | To use epanettools in a project:: 6 | 7 | import epanettools 8 | -------------------------------------------------------------------------------- /swig_wrap.bat: -------------------------------------------------------------------------------- 1 | cd src/epanettools 2 | swig -python epanet2.i 3 | swig -c++ -python pdd.i 4 | swig -c++ -python adf.i 5 | -------------------------------------------------------------------------------- /tests/test_epanettools_2.py: -------------------------------------------------------------------------------- 1 | 2 | from epanettools.cli import main 3 | 4 | 5 | def test_main(): 6 | assert main([]) == 0 7 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Installation 3 | ============ 4 | 5 | At the command line:: 6 | 7 | pip install epanettools 8 | -------------------------------------------------------------------------------- /AUTHORS.rst: -------------------------------------------------------------------------------- 1 | 2 | Authors 3 | ======= 4 | 5 | * Assela Pathirana - http://assela.pathirana.net 6 | * ak2ls2py - https://github.com/ak2ls2py 7 | -------------------------------------------------------------------------------- /src/epanettools/adf/adfandenergycalc.h: -------------------------------------------------------------------------------- 1 | #ifndef ADFCALC_H 2 | #define ADFCALC_H 3 | 4 | void ADF_calculation(char* inpfile, char* outfile, float diafact); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /docs/reference/epanettools.rst: -------------------------------------------------------------------------------- 1 | epanettools 2 | =========== 3 | 4 | .. testsetup:: 5 | 6 | from epanettools import * 7 | 8 | .. automodule:: epanettools 9 | :members: 10 | -------------------------------------------------------------------------------- /docs/spelling_wordlist.txt: -------------------------------------------------------------------------------- 1 | builtin 2 | builtins 3 | classmethod 4 | staticmethod 5 | classmethods 6 | staticmethods 7 | args 8 | kwargs 9 | callstack 10 | Changelog 11 | Indices 12 | -------------------------------------------------------------------------------- /set.bash: -------------------------------------------------------------------------------- 1 | deactivate 2 | VIRTUALENVWRAPPER_PYTHON=python3 3 | rmvirtualenv epanettools 4 | mkvirtualenv epanettools --no-site-packages 5 | workon epanettools 6 | pip install -r requirements.txt 7 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 1.0.0 3 | commit = True 4 | tag = True 5 | 6 | [bumpversion:file:setup.py] 7 | 8 | [bumpversion:file:docs/conf.py] 9 | 10 | [bumpversion:file:src/epanettools/__init__.py] 11 | 12 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [paths] 2 | source = 3 | src/epanettools 4 | */site-packages/epanettools 5 | 6 | [run] 7 | branch = true 8 | source = 9 | epanettools 10 | #tests 11 | parallel = true 12 | 13 | [report] 14 | show_missing = true 15 | precision = 2 16 | omit = *migrations* 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | indent_style = space 9 | indent_size = 4 10 | charset = utf-8 11 | 12 | [*.{bat,cmd,ps1}] 13 | end_of_line = crlf 14 | -------------------------------------------------------------------------------- /cov.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | coverage run --source epanettools setup.py test 3 | coverage html --omit=epanettools/examples/simple/epanet2_test.py 4 | 5 | URL='./htmlcov/index.html' 6 | [[ -x $BROWSER ]] && exec "$BROWSER" "$URL" 7 | path=$(which xdg-open || which gnome-open) && exec "$path" "$URL" 8 | echo "Can't find browser" 9 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Contents 3 | ======== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | readme 9 | installation 10 | usage 11 | reference/index 12 | contributing 13 | authors 14 | changelog 15 | 16 | Indices and tables 17 | ================== 18 | 19 | * :ref:`genindex` 20 | * :ref:`modindex` 21 | * :ref:`search` 22 | 23 | -------------------------------------------------------------------------------- /src/epanettools/pdd/README.txt: -------------------------------------------------------------------------------- 1 | Now set_pdd will make all calls after that to be translated ENxxxx > ENxxxx_wrap! 2 | 3 | To do: wrapper.h - all output variables have to be named and declared as output in pdd.i 4 | 5 | Going back to check original (non-pdd) epanettools package to see if it properly does ENsetxxxx calls. 6 | (in this branch, they silently fail, as evidenced by ENsaveinpfile calls before and after!) -------------------------------------------------------------------------------- /cc/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(){ 4 | printf("Hello\n"); 5 | int k=ENopen("../../epanettools/examples/simple/Net3.inp","tmp.rpt",""); 6 | printf("Returned %i\n", k); 7 | k=ENsaveinpfile("a.inp"); 8 | printf("Returned %i\n", k); 9 | k=ENsetlinkvalue(81,0,9999); 10 | printf("Returned %i\n", k); 11 | k=ENsaveinpfile("b.inp"); 12 | printf("Returned %i\n", k); 13 | } 14 | -------------------------------------------------------------------------------- /src/epanettools/patch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | char TmpDir[200]; 6 | 7 | extern int ENsetpatterndim(int index, int dim){ 8 | int i; 9 | float * pat=malloc(sizeof(float)*dim); 10 | for (i=0;i 2 | #include 3 | using namespace std; 4 | 5 | struct node{ 6 | string id; 7 | int index; 8 | float demand; 9 | float orig_demand; 10 | float orig_basedemand; 11 | float pressure; 12 | float saved_pressure; 13 | float saved_demand; 14 | float ec; 15 | bool offender; 16 | }; 17 | 18 | 19 | int emitter_analysis(); 20 | int post_analysis_cleanup(); 21 | int emitter_analysis_prepare(); 22 | void getEmitterData(float *eexp, float *ecup); 23 | int getniter(); 24 | -------------------------------------------------------------------------------- /src/epanettools/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCH_H 2 | #define PATCH_H 3 | 4 | #define WRAPPER_ERROR_FILE_OPEN 900000 5 | #define WRAPPER_ERROR_NOT_IMPLEMENTED 910000 6 | 7 | #undef WINDOWS 8 | #undef __WIN32__ 9 | 10 | // --- define DLLEXPORT 11 | #ifndef DLLEXPORT 12 | #ifdef __cplusplus 13 | #define DLLEXPORT extern "C" int 14 | #else 15 | #define DLLEXPORT extern int 16 | #endif 17 | #endif 18 | 19 | 20 | DLLEXPORT ENsetpatterndim(int index, int dim); 21 | DLLEXPORT ENsetpatterndim_wrap(int index, int dim); 22 | 23 | 24 | 25 | #endif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Basic .gitattributes for a python repo with c code 2 | 3 | # Source files 4 | # ============ 5 | *.pxd text 6 | *.py text 7 | *.py3 text 8 | *.pyw text 9 | *.pyx text 10 | *.C text 11 | *.c text 12 | 13 | # Binary files 14 | # ============ 15 | *.db binary 16 | *.p binary 17 | *.pkl binary 18 | *.pyc binary 19 | *.pyd binary 20 | *.pyo binary 21 | 22 | # Note: .db, .p, and .pkl files are associated 23 | # with the python modules ``pickle``, ``dbm.*``, 24 | # ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` 25 | # (among others). -------------------------------------------------------------------------------- /RELEASE.txt: -------------------------------------------------------------------------------- 1 | 1. Update git hub 2 | 2. change version : bumpversion 3 | bumpversion --current-version x.y.z minor 4 | (where x.y.z is the current version. minor/major/patch) 5 | 3. Github release (web interface) 6 | 4. Upload new release to pypi using twine 7 | > python setup.py check 8 | (If there are warnings, check README.rst, CHANGELOG.rst etc - which will be used in long_description on setup.py) 9 | > python setup.py register 10 | then download the artifacts (wheels) using the python script: 11 | python appveyor_download.py master 12 | twine upload dist/ 13 | Note: linux wheels and sdist are uploaded by travis automatically (for each release version) 14 | -------------------------------------------------------------------------------- /docs/README.building: -------------------------------------------------------------------------------- 1 | EPANET2 Python calling interface 2 | Assela Pathirana 3 | 4 | #delete any build files 5 | swig.exe -python EPANET2.i (in epanettools directory to create epanet2.py and epanet2_wrap.c) 6 | python setup.py test 7 | python -m doctest README.txt -v 8 | 9 | #make sure there is a %HOME%\.pypirc file, zest.releaser python package is installed 10 | #make sure '* text=auto' is set in .gitattributes file at the root of the repo. 11 | fullrelease 12 | 13 | 14 | # developing with wing ide 15 | 1. Make sure proper python env is set in project properties 16 | 2. Make sure to add repo top to pythonpath 17 | 3. Better to remove epanettools from the python being used. -------------------------------------------------------------------------------- /docs/HISTORY.txt: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | 4 | 5 | New API introduced. 6 | 7 | 8 | 0.5.0.6 (2015-10-09) 9 | 10 | 11 | Minor fixes in documentation. Release made easy. 12 | 13 | 14 | 0.5.0.4 (2015-10-09) 15 | 16 | 17 | - Nothing changed yet. 18 | 19 | 20 | 0.5.0.3 (2015-10-09) 21 | 22 | 23 | No binaries will be provided anymore. 24 | 25 | 26 | 0.5.0.1 (2015-10-09) 27 | 28 | ## [Unreleased] 29 | 30 | Verifed support for a number of extra toolkit functions. These examples are given in the README.txt 31 | 32 | Toolkit functions requiring input arrays are using numpy arrays (float32 type) as input. See README.txt for examples. 33 | 34 | -------------------------------------------------------------------------------- /ci/templates/.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: '3.5' 3 | sudo: false 4 | env: 5 | global: 6 | - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so 7 | - SEGFAULT_SIGNALS=all 8 | matrix: 9 | - TOXENV=check 10 | - TOXENV=docs 11 | {% for env in tox_environments %}{{ '' }} 12 | - TOXENV={{ env }},extension-coveralls,coveralls 13 | {% endfor %} 14 | 15 | before_install: 16 | - python --version 17 | - uname -a 18 | - lsb_release -a 19 | install: 20 | - pip install tox 21 | - virtualenv --version 22 | - easy_install --version 23 | - pip --version 24 | - tox --version 25 | script: 26 | - tox -v 27 | after_failure: 28 | - more .tox/log/* | cat 29 | - more .tox/*/log/* | cat 30 | before_cache: 31 | - rm -rf $HOME/.cache/pip/log 32 | cache: 33 | directories: 34 | - $HOME/.cache/pip 35 | notifications: 36 | email: 37 | on_success: never 38 | on_failure: always 39 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | 2 | Changelog 3 | ========= 4 | 1.0.0 (2018-09-28) 5 | ----------------------------------------- 6 | * Now works with python > 3.4. 7 | * Uses visual c/c++ compilers for windows 8 | 9 | .9.0 (2016-11-13) 10 | ----------------------------------------- 11 | * Available demand fraction with pipes closed added. This was done with c library for efficiency. 12 | 13 | 14 | 0.8.0 (2016-10-06) 15 | ----------------------------------------- 16 | * completely removed dependency on numpy. 17 | 18 | 0.7.2 (2016-09-28) 19 | ----------------------------------------- 20 | * bug fixes 21 | 22 | 0.7.1 (2016-09-21) 23 | ----------------------------------------- 24 | * minor changes 25 | 26 | 0.7.0 (2016-09-21) 27 | ----------------------------------------- 28 | 29 | * A substantial upgrade from version 6.x 30 | * Added pressure-driven demand 31 | * Restuructured repo-structure completely 32 | * much better testing with CI 33 | -------------------------------------------------------------------------------- /src/epanettools/cli.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module that contains the command line app. 3 | 4 | Why does this file exist, and why not put this in __main__? 5 | 6 | You might be tempted to import things from __main__ later, but that will cause 7 | problems: the code will get executed twice: 8 | 9 | - When you run `python -mepanettools` python will execute 10 | ``__main__.py`` as a script. That means there won't be any 11 | ``epanettools.__main__`` in ``sys.modules``. 12 | - When you import __main__ it will get executed again (as a module) because 13 | there's no ``epanettools.__main__`` in ``sys.modules``. 14 | 15 | Also see (1) from http://click.pocoo.org/5/setuptools/#setuptools-integration 16 | """ 17 | import sys 18 | 19 | 20 | def main(argv=sys.argv): 21 | """ 22 | Args: 23 | argv (list): List of arguments 24 | 25 | Returns: 26 | int: A return code 27 | 28 | Does stuff. 29 | """ 30 | 31 | print(argv) 32 | return 0 33 | -------------------------------------------------------------------------------- /src/epanettools/tools.py: -------------------------------------------------------------------------------- 1 | import collections 2 | 3 | 4 | class TransformedDict(collections.MutableMapping): 5 | 6 | """A dictionary that applies an arbitrary key-altering 7 | function before accessing the keys. 8 | 9 | from: http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict 10 | """ 11 | 12 | def __init__(self, *args, **kwargs): 13 | self.store = dict() 14 | self.update(dict(*args, **kwargs)) # use the free update to set keys 15 | 16 | def __getitem__(self, key): 17 | return self.store[self.__keytransform__(key)] 18 | 19 | def __setitem__(self, key, value): 20 | self.store[self.__keytransform__(key)] = value 21 | 22 | def __delitem__(self, key): 23 | del self.store[self.__keytransform__(key)] 24 | 25 | def __iter__(self): 26 | return iter(self.store) 27 | 28 | def __len__(self): 29 | return len(self.store) 30 | 31 | def __keytransform__(self, key): 32 | return key 33 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 140 3 | exclude = tests/*,*/migrations/*,*/south_migrations/*,src/epanettools/epanet2.py,src/epanettools/pdd.py, src/epanettools/adf.py 4 | 5 | [tool:pytest] 6 | norecursedirs = 7 | .git 8 | .tox 9 | .env 10 | dist 11 | build 12 | south_migrations 13 | migrations 14 | python_files = 15 | test_*.py 16 | *_test.py 17 | tests.py 18 | addopts = 19 | -rxEfsw 20 | --strict 21 | --doctest-modules 22 | --doctest-glob=\*.rst 23 | --tb=short 24 | 25 | [isort] 26 | force_single_line=True 27 | line_length=120 28 | known_first_party=epanettools 29 | default_section=THIRDPARTY 30 | forced_separate=test_epanettools 31 | not_skip = __init__.py 32 | skip = migrations, south_migrations, src/epanettools/epanet2.py, src/epanettools/pdd.py 33 | 34 | [check-manifest] 35 | ignore = 36 | tests/*.inp 37 | cc/* 38 | junk/* 39 | cc 40 | junk 41 | *.bash 42 | requirements.txt 43 | RELEASE.txt 44 | BUILDING.txt 45 | *.rpt 46 | log.txt 47 | -------------------------------------------------------------------------------- /junk/epanetpatches/epanet.c.patch: -------------------------------------------------------------------------------- 1 | diff --git a/epanettools/epanet/epanet.c b/epanettools/epanet/epanet.c 2 | index 69213e9..1cb6c27 100644 3 | --- a/epanettools/epanet/epanet.c 4 | +++ b/epanettools/epanet/epanet.c 5 | @@ -2917,8 +2917,24 @@ char* getTmpName(char* fname) 6 | 7 | // --- for non-Windows systems: 8 | #else 9 | + strcpy(name,"enXXXXXX"); 10 | + n = strlen(TmpDir); 11 | + if ( n > 0 ) 12 | + { 13 | + strcpy(fname, TmpDir); 14 | + if ( fname[n-1] != '/' ) strcat(fname, "/"); 15 | + } 16 | + 17 | + // --- otherwise, use the relative path notation as the file name 18 | + // prefix so that the file will be placed in the current directory 19 | + else 20 | + { 21 | + strcpy(fname, "./"); 22 | + } 23 | + 24 | // --- use system function mkstemp() to create a temporary file name 25 | - strcpy(fname, "enXXXXXX"); 26 | + strcat(fname,name ); 27 | + //printf("Writing temp file %s %s\n", TmpDir,fname); 28 | mkstemp(fname); 29 | #endif 30 | return fname; 31 | -------------------------------------------------------------------------------- /src/epanettools/adf.i: -------------------------------------------------------------------------------- 1 | %{ 2 | #define SWIG_FILE_WITH_INIT 3 | /* Includes the header in the wrapper code */ 4 | #include "./adf/adfandenergycalc.h" 5 | extern "C" char TmpDir[200]; /* this makes it possible to overrride the TmpDir */ 6 | %} 7 | 8 | 9 | /* modify epanet2.h file as: 10 | 1. Undefine __win32__ and WINDOWS 11 | 2. for all output parameters, give the name value */ 12 | %module adf 13 | %include "typemaps.i" 14 | %include "cstring.i" 15 | /* %include "numpy.i" 16 | 17 | %init %{ 18 | import_array(); 19 | %} 20 | 21 | %apply (float* IN_ARRAY1, int DIM1) {(float* floatarray, int nfloats)}; */ 22 | 23 | /* read http://www.swig.org/Doc1.3/Arguments.html */ 24 | /* 26-Aug-2016 : IMPORTANT: all output parameters in wrapper.h has to be named and then declared below. See epanet2.h and epanet2.i files for examples. 25 | At the moment only a few were done to test. 26 | */ 27 | 28 | 29 | /* Parse the header file to generate wrappers */ 30 | %include "./adf/adfandenergycalc.h" 31 | 32 | extern char TmpDir[200]; /* this makes it possible to overrride the TmpDir */ 33 | ; 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .coverage 2 | htmlcov/ 3 | en?????? 4 | *.so 5 | ?.inp 6 | *.pyd 7 | *.pyc 8 | build/ 9 | __pycache__ 10 | .cache/ 11 | .eggs/ 12 | *.egg-info/ 13 | *.rpt 14 | dist/ 15 | *.bak 16 | 17 | env/ 18 | tests/s??? 19 | *.wpu 20 | /py*.egg/ 21 | junk/*.layout 22 | *.o 23 | *.depend 24 | *.exe 25 | *deleteme* 26 | *.py[cod] 27 | 28 | # C extensions 29 | *.so 30 | 31 | # Packages 32 | *.egg 33 | *.egg-info 34 | dist 35 | build 36 | eggs 37 | .eggs 38 | parts 39 | bin 40 | var 41 | sdist 42 | wheelhouse 43 | develop-eggs 44 | .installed.cfg 45 | lib 46 | lib64 47 | venv*/ 48 | pyvenv*/ 49 | 50 | # Installer logs 51 | pip-log.txt 52 | 53 | # Unit test / coverage reports 54 | .coverage 55 | .tox 56 | .coverage.* 57 | nosetests.xml 58 | coverage.xml 59 | htmlcov 60 | 61 | # Translations 62 | *.mo 63 | 64 | # Mr Developer 65 | .mr.developer.cfg 66 | .project 67 | .pydevproject 68 | .idea 69 | *.iml 70 | *.komodoproject 71 | 72 | # Complexity 73 | output/*.html 74 | output/*/index.html 75 | 76 | # Sphinx 77 | docs/_build 78 | 79 | .DS_Store 80 | *~ 81 | .*.sw[po] 82 | .build 83 | .ve 84 | .env 85 | .cache 86 | .pytest 87 | .bootstrap 88 | .appveyor.token 89 | *.bak 90 | tests/log.txt 91 | log.txt 92 | -------------------------------------------------------------------------------- /cc/epanet/epanet.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 41 | 42 | -------------------------------------------------------------------------------- /src/epanettools/epanet2.i: -------------------------------------------------------------------------------- 1 | %{ 2 | #define SWIG_FILE_WITH_INIT 3 | /* Includes the header in the wrapper code */ 4 | #include "./epanet/epanet2.h" 5 | #include "./patch.h" 6 | extern char TmpDir[200]; /* this makes it possible to overrride the TmpDir */ 7 | %} 8 | 9 | 10 | /* modify epanet2.h file as: 11 | 1. Undefine __win32__ and WINDOWS 12 | 2. for all output parameters, give the name value */ 13 | %module epanet2 14 | %include "typemaps.i" 15 | %include "cstring.i" 16 | /* %include "numpy.i" 17 | 18 | %init %{ 19 | import_array(); 20 | %} 21 | 22 | %apply (float* IN_ARRAY1, int DIM1) {(float* floatarray, int nfloats)}; */ 23 | 24 | /* read http://www.swig.org/Doc1.3/Arguments.html */ 25 | 26 | %apply int *OUTPUT { int *result }; 27 | %apply int *OUTPUT { int *result1 }; 28 | %apply int *OUTPUT { int *result2 }; 29 | %apply long *OUTPUT { long *result }; 30 | %apply float *OUTPUT { float *result }; 31 | %apply float *OUTPUT {float *c1} 32 | %apply float *OUTPUT {float *c2} 33 | %apply int *OUTPUT {int *ci1} 34 | %apply int *OUTPUT {int *ci2} 35 | %apply int *OUTPUT {int *ci3} 36 | %apply double *OUTPUT { double *result }; 37 | %cstring_bounded_output(char *result, 1024); 38 | 39 | 40 | 41 | /* Parse the header file to generate wrappers */ 42 | %include "./epanet/epanet2.h" 43 | %include "./patch.h" 44 | 45 | extern char TmpDir[200]; /* this makes it possible to overrride the TmpDir */ 46 | ; 47 | -------------------------------------------------------------------------------- /cc/src/main2.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | int main(){ 5 | printf("Enter the network file (xxxx.inp):\n"); 6 | int k=ENopen_wrap("E:/Projects/2016_Bdesh_training_with_dutch_waterboards/Assela Pathirana/risk_based/Adjumani_network_simplified2.inp", 7 | "E:/Projects/2016_Bdesh_training_with_dutch_waterboards/Assela Pathirana/risk_based/Adjumani_network_simplified2.rpt",""); 8 | if(k!=0){printf("Error %i\n", k);} 9 | int NumNodes; 10 | k=ENgetcount_wrap(EN_NODECOUNT, &NumNodes); 11 | if(k!=0){printf("Error %i\n", k);} 12 | printf("Number of nodes %i\n", NumNodes); 13 | float eexp, ecup; 14 | k=ENgetemitter_wrap(&eexp,&ecup); 15 | printf("Emitter %f %f\n", eexp, ecup); 16 | if(eexp==0.0 || ecup ==0.0){ 17 | ENsetemitter_wrap(.5,10.0); 18 | } 19 | k=ENgetemitter_wrap(&eexp,&ecup); 20 | printf("Emitter %f %f\n", eexp, ecup); 21 | getchar(); 22 | ENopenH_wrap(); ENinitH_wrap(0); 23 | long t,tstep; 24 | int i; 25 | float p; 26 | char id[50]; 27 | do{ 28 | ENrunH_wrap(&t); 29 | for (i = 1; i <= NumNodes; i++) 30 | { 31 | ENgetnodevalue_wrap(i, EN_PRESSURE, &p); 32 | ENgetnodeid_wrap(i, id); 33 | printf("pressure: %lu %s %f \n",t, id, p); 34 | } 35 | ENnextH_wrap(&tstep); 36 | } while (tstep > 0); 37 | ENcloseH_wrap(); 38 | ENclose_wrap(); 39 | 40 | 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /junk/prj.wpr: -------------------------------------------------------------------------------- 1 | #!wing 2 | #!version=5.0 3 | ################################################################## 4 | # Wing IDE project file # 5 | ################################################################## 6 | [project attributes] 7 | proj.directory-list = [{'dirloc': loc('../src/epanettools'), 8 | 'excludes': (), 9 | 'filter': u'*', 10 | 'include_hidden': False, 11 | 'recursive': True, 12 | 'watch_for_changes': True}] 13 | proj.file-list = [loc('../setup.py'), 14 | loc('../tests/test_ADF.py'), 15 | loc('../tests/test_EPANetPatterns.py'), 16 | loc('../tests/test_EPANetPDD.py'), 17 | loc('../tests/test_EPANetSimulation2.py'), 18 | loc('../tests/test_EPANetSimulation.py'), 19 | loc('../tests/test_epanettools.py'), 20 | loc('../tests/test_epanettools_2.py'), 21 | loc('../tests/test_low_level_functions_direct_access.py'), 22 | loc('../tests/test_low_level_functions_via_epanettools_access.py'), 23 | loc('../tests/tools_for_testing.py'), 24 | loc('../tests/__init__.py')] 25 | proj.file-type = 'shared' 26 | proj.launch-config = {loc('../setup.py'): ('project', 27 | (u'test ', 28 | ''))} 29 | proj.main-file = loc('../tests/test_EPANetPDD.py') 30 | testing.auto-test-file-specs = (('glob', 31 | 'tests/test*.py'),) 32 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | import os 5 | 6 | 7 | extensions = [ 8 | 'sphinx.ext.autodoc', 9 | 'sphinx.ext.autosummary', 10 | 'sphinx.ext.coverage', 11 | 'sphinx.ext.doctest', 12 | 'sphinx.ext.extlinks', 13 | 'sphinx.ext.ifconfig', 14 | 'sphinx.ext.napoleon', 15 | 'sphinx.ext.todo', 16 | 'sphinx.ext.viewcode', 17 | ] 18 | if os.getenv('SPELLCHECK'): 19 | extensions += 'sphinxcontrib.spelling', 20 | spelling_show_suggestions = True 21 | spelling_lang = 'en_US' 22 | 23 | source_suffix = '.rst' 24 | master_doc = 'index' 25 | project = 'epanettools' 26 | year = '2016' 27 | author = 'Assela Pathirana' 28 | copyright = '{0}, {1}'.format(year, author) 29 | version = release = '1.0.0' 30 | 31 | pygments_style = 'trac' 32 | templates_path = ['.'] 33 | extlinks = { 34 | 'issue': ('https://github.com/asselapathirana/epanettools/issues/%s', '#'), 35 | 'pr': ('https://github.com/asselapathirana/epanettools/pull/%s', 'PR #'), 36 | } 37 | # on_rtd is whether we are on readthedocs.org 38 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True' 39 | 40 | if not on_rtd: # only set the theme if we're building docs locally 41 | html_theme = 'sphinx_rtd_theme' 42 | 43 | html_use_smartypants = True 44 | html_last_updated_fmt = '%b %d, %Y' 45 | html_split_index = False 46 | html_sidebars = { 47 | '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], 48 | } 49 | html_short_title = '%s-%s' % (project, version) 50 | 51 | napoleon_use_ivar = True 52 | napoleon_use_rtype = False 53 | napoleon_use_param = False 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | GNU GENERAL PUBLIC LICENSE 3 | Version 3, 29 June 2007 4 | 5 | Epanet 2.0 Python calling interface 6 | Copyright (C) 2016 Assela Pathirana 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | Also add information on how to contact you by electronic and paper mail. 22 | 23 | You should also get your employer (if you work as a programmer) or school, 24 | if any, to sign a "copyright disclaimer" for the program, if necessary. 25 | For more information on this, and how to apply and follow the GNU GPL, see 26 | . 27 | 28 | The GNU General Public License does not permit incorporating your program 29 | into proprietary programs. If your program is a subroutine library, you 30 | may consider it more useful to permit linking proprietary applications with 31 | the library. If this is what you want to do, use the GNU Lesser General 32 | Public License instead of this License. But first, please read 33 | . 34 | -------------------------------------------------------------------------------- /tests/test_low_level_functions_via_epanettools_access.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import unittest 4 | 5 | from tests import tools_for_testing as tt 6 | 7 | from epanettools.epanettools import EPANetSimulation 8 | from epanettools.examples import simple 9 | 10 | 11 | class Test1(unittest.TestCase): 12 | 13 | def Error(self, e): 14 | if(e): 15 | s = "Epanet Error: %d : %s" % (e, self.es.ENgeterror(e, 500)[1]) 16 | raise Exception(s) 17 | 18 | def setUp(self): 19 | print("SETUP!") 20 | self.file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 21 | self.es = EPANetSimulation(self.file) 22 | 23 | def tearDown(self): 24 | # Bug! the ENclose cause core dumps on posix -- No, on windows as well! 25 | if(False): # os.name!="posix"): 26 | self.Error(self.es.ENclose()) 27 | print("TEAR DOWN!") 28 | 29 | def test_alter_with_ENset_and_check_with_a_file(self): 30 | self.Error(self.es.ENsaveinpfile("1.inp")) 31 | self.Error(self.es.ENsetlinkvalue(81, 0, 9999)) 32 | self.Error(self.es.ENsaveinpfile("2.inp")) 33 | self.assertEqual(tt.compareFiles("1.inp", "2.inp"), '16>1e+04; ') 34 | 35 | 36 | tc = None 37 | 38 | 39 | def clt(fn): 40 | tc.setUp() 41 | fn() 42 | tc.tearDown() 43 | 44 | 45 | def main(): 46 | tc = Test1() 47 | for a in dir(tc): 48 | if (a.startswith('test_pattern')): # test_sync 49 | b = getattr(tc, a) 50 | if(hasattr(b, '__call__')): 51 | print ("calling %s **********************************" % a) 52 | clt(b) 53 | 54 | 55 | if __name__ == "__main__": 56 | main() 57 | -------------------------------------------------------------------------------- /src/epanettools/adf/main.cc: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | *** EPANET-Emitter reference application 3 | *** Author: Assela Pathirana 2016Nov 4 | *** Calling function main.cc 5 | *** ************************************************************************* 6 | *** Modification history: 7 | *** Name Date Description 8 | *****************************************************************************/ 9 | 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | void pause(); 16 | void help(char *); 17 | void readargs(char** argv, char* &inpfile, char* &outfile, float &diafactor ); 18 | 19 | int main(int argc, char **argv){ 20 | if(argc<4){ 21 | help(argv[0]); 22 | exit(1); 23 | } 24 | char* inpfile; 25 | char* outfile; 26 | float diafactor; 27 | readargs(argv,inpfile, outfile, diafactor ); 28 | ADF_calculation(inpfile, outfile, diafactor); 29 | pause(); 30 | 31 | } 32 | 33 | void help(char *myname){ 34 | cerr<< "\nUsage: "< \n\n"; 35 | cerr<< "inf - input EPANET file (in *.inp format).\n"; 36 | cerr << "outf - file to write results."; 37 | cerr << "Press ENTER..\n"; 38 | cin.get(); 39 | } 40 | 41 | void pause() 42 | { 43 | cerr << "Press ENTER..\n"; 44 | cin.get(); 45 | } 46 | 47 | void readargs( char ** argv, char* &inpfile, char * &outfile,float& diafactor) 48 | { 49 | inpfile=(argv[1]); 50 | outfile = (argv[2]); 51 | diafactor = (float)atof(argv[3]); 52 | 53 | cerr << "\nRunning the case with following parameters\n"; 54 | cerr << "(input file,ECUP, EEXP)="; 55 | //cerr << "("< Njuncs ) 18 | { 19 | - v = 4.0/PI*sqrt(Tank[index-Njuncs].A)*Ucf[ELEV]; 20 | + v = sqrt(4.0/PI*Tank[index-Njuncs].A)*Ucf[ELEV]; 21 | } 22 | break; 23 | 24 | ########################## 25 | C/C++ part 26 | edit epanet2.i and pdd.i adf.i 27 | then run 28 | swig -python epanet2.i 29 | swig -c++ -python pdd.i 30 | swig -c++ -python adf.i 31 | 32 | then run 33 | tox # this will do all the testing and doctest. 34 | To run only doctest (scenario: editing README.rst) 35 | - Windows 36 | .\.tox\py34\Scripts\python.exe -m doctest -v README.rst 37 | - POSIX 38 | ./.tox/py27/bin/python -m doctest -v README.rst 39 | (Works only after running tox successfully) 40 | 41 | ########################## 42 | flake8 failures: 43 | try 44 | autopep8 --in-place --recursive --verbose --pep8-passes 5000 45 | 46 | ########################### 47 | Working with wingide 48 | (when c parts are changed) 49 | run python3 setup.py test first 50 | then test with wingide (with python3) 51 | 52 | ######################### 53 | Run a single test on command prompt 54 | env PYTHONPATH=src/ python3 -m unittest -q tests.test_ADF 55 | 56 | 57 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | password: 3 | secure: FTXC0Lbagq+isgXzs7VsYFIBJ1axTt2wgwCiwfhouSU= 4 | matrix: 5 | - PYTHON_VERSION: "2.7" 6 | #- PYTHON_VERSION: "3.3" 7 | - PYTHON_VERSION: "3.4" 8 | #- PYTHON_VERSION: "3.5" 9 | - PYTHON_VERSION: "3.6" 10 | - PYTHON_VERSION: "3.7" 11 | 12 | platform: 13 | - x86 14 | - x64 15 | 16 | matrix: 17 | fast_finish: false 18 | 19 | install: 20 | - set PATH=C:\Miniconda\Scripts 21 | - ps: If ($env:Platform -Match "x64") {$env:PATH="C:\Miniconda-x64\Scripts"} 22 | - set PATH=%PATH%;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem 23 | - conda config --set always_yes yes --set changeps1 no 24 | - conda update -q conda 25 | - conda create -q --name python%PYTHON_VERSION% python=%PYTHON_VERSION% 26 | - activate python%PYTHON_VERSION% 27 | - conda install -q --name python%PYTHON_VERSION% setuptools wheel nose 28 | #- pip install -q mando tstoolbox baker 29 | #- python.exe setup.py config_fc 30 | - python.exe setup.py config 31 | - python.exe setup.py build 32 | - python.exe setup.py install 33 | 34 | build: off 35 | 36 | test_script: 37 | - nosetests 38 | 39 | after_test: 40 | # This step builds your wheels. 41 | - python.exe setup.py bdist_wheel 42 | 43 | artifacts: 44 | # bdist_wheel puts your built wheel in the dist directory 45 | - path: dist\*.whl 46 | 47 | #on_success: 48 | deploy_script: 49 | - "echo [pypi] > %USERPROFILE%\\.pypirc" 50 | - "echo username: assela >> %USERPROFILE%\\.pypirc" 51 | - "echo password: %password% >> %USERPROFILE%\\.pypirc" 52 | # - python setup.py bdist_wheel upload - this hangs!! 53 | 54 | # You can use this step to upload your artifacts to a public website. 55 | # See Appveyor's documentation for more details. Or you can simply 56 | # access your wheels from the Appveyor "artifacts" tab for your build. 57 | -------------------------------------------------------------------------------- /src/epanettools/examples/simple/epanet2_test.py: -------------------------------------------------------------------------------- 1 | 2 | import time 3 | 4 | # To change this template, choose Tools | Templates 5 | # and open the template in the editor. 6 | 7 | __author__ = "assela" 8 | __date__ = "$Sep 30, 2011 12:59:16 PM$" 9 | 10 | 11 | def err(e): 12 | if(e > 0): 13 | print((e, et.ENgeterror(e, 25))) 14 | exit(5) 15 | 16 | 17 | if __name__ == "__main__": 18 | 19 | from epanettools import epanet2 as et 20 | ret = et.ENopen("Net3.inp", "Net3.rpt", "") 21 | err(ret) 22 | ret, result = et.ENgetcount(et.EN_LINKCOUNT) 23 | err(ret) 24 | print(("Network has ", result, " links.")) 25 | ret, result = et.ENgetcount(et.EN_NODECOUNT) 26 | err(ret) 27 | print(("Network has ", result, " nodes.")) 28 | node = '105' 29 | ret, index = et.ENgetnodeindex(node) 30 | print(("Node ", node, " has index : ", index)) 31 | 32 | ret, nnodes = et.ENgetcount(et.EN_NODECOUNT) 33 | nodes = [] 34 | pres = [] 35 | for index in range(1, nnodes): 36 | ret, t = et.ENgetnodeid(index) 37 | nodes.append(t) 38 | t = [] 39 | pres.append(t) 40 | 41 | print(nodes) 42 | err(et.ENopenH()) 43 | err(et.ENinitH(0)) 44 | while True: 45 | ret, t = et.ENrunH() 46 | time.append(t) 47 | err(ret) 48 | # Retrieve hydraulic results for time t 49 | for i in range(0, len(nodes)): 50 | ret, p = et.ENgetnodevalue(i + 1, et.EN_PRESSURE) 51 | pres[i].append(p) 52 | ret, tstep = et.ENnextH() 53 | err(ret) 54 | if (tstep <= 0): 55 | break 56 | ret = et.ENcloseH() 57 | print("") 58 | import matplotlib 59 | matplotlib.use("QT4Agg") 60 | import matplotlib.pyplot as plt 61 | 62 | for i in range(40, 50): 63 | plt.plot(time, pres[i], label=nodes[i]) 64 | 65 | plt.legend(loc=1, bbox_to_anchor=(1, 1)) 66 | 67 | plt.show() 68 | -------------------------------------------------------------------------------- /tests/tools_for_testing.py: -------------------------------------------------------------------------------- 1 | import difflib 2 | import os 3 | import sys 4 | 5 | 6 | def redirect_stdout(): 7 | print ("Redirecting stdout") 8 | sys.stdout.flush() # <--- important when redirecting to files 9 | 10 | # Duplicate stdout (file descriptor 1) 11 | # to a different file descriptor number 12 | newstdout = os.dup(1) 13 | 14 | # /dev/null is used just to discard what is being printed 15 | devnull = os.open('/dev/null', os.O_WRONLY) 16 | 17 | # Duplicate the file descriptor for /dev/null 18 | # and overwrite the value for stdout (file descriptor 1) 19 | os.dup2(devnull, 1) 20 | 21 | # Close devnull after duplication (no longer needed) 22 | os.close(devnull) 23 | 24 | # Use the original stdout to still be able 25 | # to print to stdout within python 26 | sys.stdout = os.fdopen(newstdout, 'w') 27 | 28 | 29 | def is_number(s): 30 | try: 31 | float(s) 32 | return True 33 | except ValueError: 34 | return False 35 | 36 | 37 | def compareFiles(first, second): 38 | with open(first, 'r') as myfile: 39 | f = myfile.readlines() 40 | with open(second, 'r') as myfile: 41 | s = myfile.readlines() 42 | 43 | diff = difflib.ndiff(f, s) 44 | d1 = "" 45 | d2 = "" 46 | for line in diff: 47 | if(len(d1) > 5000): 48 | break 49 | if line.startswith('-'): 50 | d1 = d1 + " " + (line[1:]) 51 | elif line.startswith('+'): 52 | d2 = d2 + " " + (line[1:]) 53 | d1 = d1.split() 54 | d2 = d2.split() 55 | dif = "" 56 | for i in range(min(len(d1), len(d2))): 57 | 58 | s = d1[i].strip("\n\t ") 59 | if(is_number(s)): 60 | s = format(float(s), '.3g') 61 | r = d2[i].strip("\n\t ") 62 | if(is_number(r)): 63 | r = format(float(r), '.3g') 64 | if(s != r): 65 | dif = dif + s + ">" + r + "; " 66 | 67 | return dif 68 | -------------------------------------------------------------------------------- /tests/test_low_level_functions_direct_access.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import unittest 4 | 5 | from tests import tools_for_testing as tt 6 | 7 | from epanettools import epanet2 as et 8 | from epanettools import pdd as pd 9 | from epanettools.examples import simple 10 | 11 | 12 | class Test1(unittest.TestCase): 13 | 14 | def Error(self, e): 15 | if(e): 16 | s = "Epanet Error: %d : %s" % (e, et.ENgeterror(e, 500)[1]) 17 | raise Exception(s) 18 | 19 | def setUp(self): 20 | print("SETUP!") 21 | self.file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 22 | self.Error(et.ENopen(self.file, "t.rpt", "")) 23 | 24 | def tearDown(self): 25 | self.Error(et.ENclose()) 26 | print("TEAR DOWN!") 27 | 28 | def test_alter_with_ENset_and_check_with_a_file(self): 29 | self.Error(et.ENsaveinpfile("1.inp")) 30 | self.Error(et.ENsetlinkvalue(81, 0, 9999)) 31 | self.Error(et.ENsaveinpfile("2.inp")) 32 | self.assertEqual(tt.compareFiles("1.inp", "2.inp"), '16>1e+04; ') 33 | 34 | def test_alter_with_ENset_via_PDD_and_check_with_a_file(self): 35 | self.Error(pd.ENopen(self.file, "t.rpt", "")) 36 | self.Error(pd.ENsaveinpfile_wrap("1.inp")) 37 | self.Error(pd.ENsetlinkvalue_wrap(81, 0, 788288)) 38 | self.Error(pd.ENsaveinpfile_wrap("2.inp")) 39 | self.assertEqual(tt.compareFiles("1.inp", "2.inp"), '16>7.88e+05; ') 40 | self.Error(pd.ENclose()) 41 | 42 | 43 | tc = None 44 | 45 | 46 | def clt(fn): 47 | tc.setUp() 48 | fn() 49 | tc.tearDown() 50 | 51 | 52 | def main(): 53 | tc = Test1() 54 | for a in dir(tc): 55 | if (a.startswith('test_pattern')): # test_sync 56 | b = getattr(tc, a) 57 | if(hasattr(b, '__call__')): 58 | print ("calling %s **********************************" % a) 59 | clt(b) 60 | 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /ci/templates/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{branch}-{build}' 2 | build: off 3 | cache: 4 | - '%LOCALAPPDATA%\pip\Cache' 5 | environment: 6 | global: 7 | WITH_COMPILER: 'cmd /E:ON /V:ON /C .\ci\appveyor-with-compiler.cmd' 8 | matrix: 9 | - TOXENV: check 10 | PYTHON_HOME: C:\Python27 11 | PYTHON_VERSION: '2.7' 12 | PYTHON_ARCH: '32' 13 | 14 | {% for env in tox_environments %}{% if env.startswith(('py27', 'py34', 'py35')) %} 15 | - TOXENV: '{{ env }}' 16 | TOXPYTHON: C:\Python{{ env[2:4] }}\python.exe 17 | PYTHON_HOME: C:\Python{{ env[2:4] }} 18 | PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' 19 | PYTHON_ARCH: '32' 20 | 21 | - TOXENV: '{{ env }}' 22 | TOXPYTHON: C:\Python{{ env[2:4] }}-x64\python.exe 23 | {%- if env.startswith(('py2', 'py33', 'py34')) %} 24 | 25 | WINDOWS_SDK_VERSION: v7.{{ '1' if env.startswith('py3') else '0' }} 26 | {%- endif %} 27 | 28 | PYTHON_HOME: C:\Python{{ env[2:4] }}-x64 29 | PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' 30 | PYTHON_ARCH: '64' 31 | 32 | {% endif %}{% endfor %} 33 | init: 34 | - ps: echo $env:TOXENV 35 | - ps: ls C:\Python* 36 | install: 37 | - python -u ci\appveyor-bootstrap.py 38 | - '%PYTHON_HOME%\Scripts\virtualenv --version' 39 | - '%PYTHON_HOME%\Scripts\easy_install --version' 40 | - '%PYTHON_HOME%\Scripts\pip --version' 41 | - '%PYTHON_HOME%\Scripts\tox --version' 42 | test_script: 43 | - '%WITH_COMPILER% %PYTHON_HOME%\Scripts\tox' 44 | 45 | after_test: 46 | - IF "%TOXENV:~-6,6%" == "-nocov" %WITH_COMPILER% %TOXPYTHON% setup.py bdist_wheel 47 | 48 | on_failure: 49 | - ps: dir "env:" 50 | - ps: get-content .tox\*\log\* 51 | artifacts: 52 | - path: dist\* 53 | 54 | ### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): 55 | # on_finish: 56 | # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) 57 | -------------------------------------------------------------------------------- /.cookiecutterrc: -------------------------------------------------------------------------------- 1 | # This file exists so you can easily regenerate your project. 2 | # 3 | # `cookiepatcher` is a convenient shim around `cookiecutter` 4 | # for regenerating projects (it will generate a .cookiecutterrc 5 | # automatically for any template). To use it: 6 | # 7 | # pip install cookiepatcher 8 | # cookiepatcher gh:ionelmc/cookiecutter-pylibrary project-path 9 | # 10 | # See: 11 | # https://pypi.python.org/pypi/cookiecutter 12 | # 13 | # Alternatively, you can run: 14 | # 15 | # cookiecutter --overwrite-if-exists --config-file=project-path/.cookiecutterrc gh:ionelmc/cookiecutter-pylibrary 16 | 17 | default_context: 18 | 19 | appveyor: 'yes' 20 | c_extension_cython: 'no' 21 | c_extension_optional: 'no' 22 | c_extension_support: 'yes' 23 | codacy: 'no' 24 | codeclimate: 'no' 25 | codecov: 'no' 26 | command_line_interface: 'plain' 27 | command_line_interface_bin_name: 'epanettools' 28 | coveralls: 'yes' 29 | distribution_name: 'epanettools' 30 | email: 'assela@pathirana.net' 31 | full_name: 'Assela Pathirana' 32 | github_username: 'asselapathirana' 33 | landscape: 'no' 34 | package_name: 'epanettools' 35 | project_name: 'epanettools' 36 | project_short_description: 'Epanet 2.0 Python calling interface' 37 | release_date: 'today' 38 | repo_name: 'epanettools' 39 | requiresio: 'yes' 40 | scrutinizer: 'no' 41 | sphinx_doctest: 'yes' 42 | sphinx_theme: 'sphinx-rtd-theme' 43 | test_matrix_configurator: 'no' 44 | test_matrix_separate_coverage: 'no' 45 | test_runner: 'pytest' 46 | travis: 'yes' 47 | version: '0.7.0' 48 | website: 'http://assela.pathirana.net' 49 | year: 'now' 50 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | after_failure: 2 | - more .tox/log/* | cat 3 | - more .tox/*/log/* | cat 4 | before_cache: 5 | - rm -rf $HOME/.cache/pip/log 6 | before_install: 7 | - python --version 8 | - uname -a 9 | - lsb_release -a 10 | cache: 11 | directories: 12 | - $HOME/.cache/pip 13 | deploy: 14 | password: 15 | secure: !!binary | 16 | cjFGVmV6TUJncll1emRic0dZRGtzMFduRDRaZmNKZEFGeXZTcCswdVMxOHRoZm5TdC9aWG1qQlYw 17 | aHJNdTBxODE0NUlFT0tBOVR6KzVqeFVVeVNOYURLV1o3a1JtcWlvK2FGS3lWc1FpTEFHWE1uZW1s 18 | cnJTelFuTXJjTWRjTHdRNnNLZEdadkFqYkJRM0NXS2VLKzRXUWlaaDlVQkU4ZXFLZWdVN0pkcTR2 19 | d1dOazlXeGgvVFhwMUp5MTFkalE3UG45bW5vVi9KYzB4RUlidGFnOE5nTFpGUWtaaDA4aVR4c3VJ 20 | Qm1yemJBVVBNekZVWDY1Ris2MWZtZ2psU3JOcUZ3UGttS0hwREQvNEhSUHdrSk5ya0R4QVJUZUtu 21 | YjJXSlFra1cvQk81ZkxhTFhzV0pBcS93YlR5bzE5T0FYZFU3NjE2eGNoMDRiUTQzYm5RaWhSUlNr 22 | QXorRDk0Y2ZCUmhJUGJuQzBKelMyeUp0RzJIckVud1Bma0d4MjFhMTh0eGRLRnZiMm5pM2tjbit3 23 | RzBNVEE5eEdqZTI3aFFUUzVueS9zUnB2M0luM2FkZUFBazlRZXowaTZZUFFQK0NtYjBkaUp2R3RU 24 | SVE0eTdhZHNQN0FvL0FNUDFsQ29TQXJselFFeEkwODVJQVlJUE9zNEFNVFRmazZDY0pUeXllaWFT 25 | V2UwZ0FwS2U1MVZ1UXVYSm5tVktJeEpXZS92QkR5b1cvbWdyUGUyOTVOdHlSWm1kT3hzSVZiWW5Z 26 | NjY5M0c5aGE4blJRdlVFanFFN3dJRWorR3JaTXFESVdNZ3dFbDRSb3F0aDl4QjB1eTQ4YVZwSTBq 27 | TlRJUVgvVTBGSzV4TWVUL3NZSzdrdlU3N0tTOXpqUjZlTllNYXZCNVQxZ015NDg0WXVOSlZhNjA9 28 | true: 29 | branch: master 30 | tags: true 31 | provider: pypi 32 | user: assela 33 | env: 34 | global: 35 | - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so 36 | - SEGFAULT_SIGNALS=all 37 | matrix: 38 | - TOXENV=py27,extension-coveralls,coveralls 39 | - TOXENV=py33,extension-coveralls,coveralls 40 | - TOXENV=py34,extension-coveralls,coveralls 41 | - TOXENV=py35,extension-coveralls,coveralls 42 | install: 43 | - pip install tox 44 | - virtualenv --version 45 | - easy_install --version 46 | - pip --version 47 | - tox --version 48 | language: python 49 | notifications: 50 | email: 51 | on_failure: always 52 | on_success: never 53 | python: '3.5' 54 | script: 55 | - tox -v 56 | sudo: false 57 | -------------------------------------------------------------------------------- /ci/bootstrap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import absolute_import, print_function, unicode_literals 4 | 5 | import os 6 | import sys 7 | from os.path import abspath 8 | from os.path import dirname 9 | from os.path import exists 10 | from os.path import join 11 | 12 | 13 | if __name__ == "__main__": 14 | base_path = dirname(dirname(abspath(__file__))) 15 | print("Project path: {0}".format(base_path)) 16 | env_path = join(base_path, ".tox", "bootstrap") 17 | if sys.platform == "win32": 18 | bin_path = join(env_path, "Scripts") 19 | else: 20 | bin_path = join(env_path, "bin") 21 | if not exists(env_path): 22 | import subprocess 23 | 24 | print("Making bootstrap env in: {0} ...".format(env_path)) 25 | try: 26 | subprocess.check_call(["virtualenv", env_path]) 27 | except subprocess.CalledProcessError: 28 | subprocess.check_call([sys.executable, "-m", "virtualenv", env_path]) 29 | print("Installing `jinja2` into bootstrap environment...") 30 | subprocess.check_call([join(bin_path, "pip"), "install", "jinja2"]) 31 | activate = join(bin_path, "activate_this.py") 32 | # noinspection PyCompatibility 33 | exec(compile(open(activate, "rb").read(), activate, "exec"), dict(__file__=activate)) 34 | 35 | import jinja2 36 | 37 | import subprocess 38 | 39 | jinja = jinja2.Environment( 40 | loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), 41 | trim_blocks=True, 42 | lstrip_blocks=True, 43 | keep_trailing_newline=True 44 | ) 45 | 46 | tox_environments = [ 47 | line.strip() 48 | # WARNING: 'tox' must be installed globally or in the project's virtualenv 49 | for line in subprocess.check_output(['tox', '--listenvs'], universal_newlines=True).splitlines() 50 | ] 51 | tox_environments = [line for line in tox_environments if line not in ['clean', 'report', 'docs', 'check']] 52 | 53 | for name in os.listdir(join("ci", "templates")): 54 | with open(join(base_path, name), "w") as fh: 55 | fh.write(jinja.get_template(name).render(tox_environments=tox_environments)) 56 | print("Wrote {}".format(name)) 57 | print("DONE.") 58 | -------------------------------------------------------------------------------- /tests/test_ADF.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import math 3 | import os 4 | import sys 5 | import unittest 6 | from unittest import expectedFailure 7 | from unittest import skip 8 | 9 | from tests import tools_for_testing as tt 10 | 11 | import epanettools 12 | from epanettools.epanettools import EPANetSimulation 13 | from epanettools.epanettools import Link 14 | from epanettools.epanettools import Links 15 | from epanettools.examples import simple 16 | 17 | 18 | class Test1(unittest.TestCase): 19 | 20 | def setUp(self): 21 | print("SETUP!") 22 | file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 23 | self.es = EPANetSimulation(file) 24 | 25 | def tearDown(self): 26 | self.es.clean() 27 | print("TEAR DOWN!") 28 | 29 | @skip 30 | def test_false(self): 31 | assert False 32 | 33 | def test_EPANetSimulation_by_default_has_no_ADF_values(self): 34 | d= Link.value_type['EN_DIAMETER'] 35 | self.assertAlmostEqual(self.es.network.links[1].results[d][0],99.,delta=1) 36 | self.assertRaises(AttributeError, getattr, self.es.network.links[1], "ADF") 37 | 38 | def test_EPANetSimulation_after_calling_adfcalc_has_ADF_values(self): 39 | d= Link.value_type['EN_DIAMETER'] 40 | self.assertAlmostEqual(self.es.network.links[1].results[d][0],99.,delta=1) 41 | raised=False 42 | try: 43 | self.assertAlmostEqual(self.es.network.links[1].ADF,.05) 44 | except AttributeError: 45 | raised=True 46 | self.assertTrue(raised,"Did not raise exception.") 47 | self.es.adfcalc() 48 | self.assertAlmostEqual(self.es.network.links[1].ADF,0.99996,delta=.001) 49 | self.assertAlmostEqual(self.es.network.links['151'].ADF,0.974816, delta=0.001) 50 | 51 | 52 | 53 | tc = None 54 | 55 | 56 | 57 | def clt(tc,fn): 58 | tc.setUp() 59 | fn() 60 | tc.tearDown() 61 | 62 | 63 | def main(): 64 | tc = Test1() 65 | for a in dir(tc): 66 | if (a.startswith('test_')): # test_sync 67 | b = getattr(tc, a) 68 | if(hasattr(b, '__call__')): 69 | print ("calling %s **********************************" % a) 70 | clt(tc,b) 71 | 72 | 73 | if __name__ == "__main__": 74 | main() 75 | -------------------------------------------------------------------------------- /tests/test_EPANetSimulation2.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import math 3 | import os 4 | import unittest 5 | from unittest import expectedFailure 6 | from unittest import skip 7 | 8 | from tests import tools_for_testing as tt 9 | 10 | import epanettools 11 | from epanettools.epanettools import Control 12 | from epanettools.epanettools import Controls 13 | from epanettools.epanettools import EPANetSimulation 14 | from epanettools.epanettools import Link 15 | from epanettools.epanettools import Links 16 | from epanettools.epanettools import Network 17 | from epanettools.epanettools import Node 18 | from epanettools.epanettools import Nodes 19 | from epanettools.epanettools import Pattern 20 | from epanettools.epanettools import Patterns 21 | from epanettools.examples import simple 22 | 23 | 24 | class Test1(unittest.TestCase): 25 | 26 | def setUp(self): 27 | print("SETUP!") 28 | file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 29 | self.es = EPANetSimulation(file) 30 | 31 | def tearDown(self): 32 | self.es.clean() 33 | print("TEAR DOWN!") 34 | 35 | @skip 36 | def test_false(self): 37 | assert False 38 | 39 | def test_patterns_are_retrieved_properly(self): 40 | p = self.es.network.patterns 41 | self.assertEqual(len(p), 5) # there are five patterns 42 | [self.assertEqual(p[x].id, str(x)) 43 | for x in range(1, len(p) + 1)] # the ids of patterns are '1','2',..,'5' - how convienient! 44 | l = [len(p[x]) for x in range(1, len(p) + 1)] 45 | [self.assertEqual(x, 24) for x in l] # all thoese patterns are 24 length 46 | # check a few values of pattern 1 47 | self.assertAlmostEqual(p[1][1], 1.34, delta=2) 48 | self.assertAlmostEqual(p[1][24], 1.67, delta=2) 49 | self.assertAlmostEqual(p[1][22], .96, delta=2) 50 | 51 | 52 | def clt(fn, tc): 53 | tc.setUp() 54 | fn() 55 | tc.tearDown() 56 | 57 | 58 | def main(): 59 | tc = Test1() 60 | for a in dir(tc): 61 | if (a.startswith('test_pattern')): # test_sync 62 | b = getattr(tc, a) 63 | if(hasattr(b, '__call__')): 64 | print ("calling %s **********************************" % a) 65 | clt(b, tc) 66 | 67 | 68 | if __name__ == "__main__": 69 | main() 70 | -------------------------------------------------------------------------------- /appveyor_download.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from __future__ import absolute_import, division, print_function 3 | 4 | import os 5 | import sys 6 | from textwrap import dedent 7 | 8 | import requests 9 | 10 | URL = 'https://ci.appveyor.com/api' 11 | TOKEN = os.getenv('APPVEYOR_TOKEN') 12 | ACCOUNT = 'asselapathirana' # AppVeyor username, assuming zzzeek 13 | PROJECT = os.getenv('APPVEYOR_PROJECT') 14 | 15 | if len(sys.argv) != 2: 16 | sys.exit('%s ' %(sys.argv[0])) 17 | 18 | if TOKEN is None: 19 | sys.exit('APPVEYOR_TOKEN env var not set.') 20 | 21 | branch = sys.argv[1] 22 | 23 | session = requests.Session() 24 | session.headers.update({'Authorization': 'Bearer ' + TOKEN}) 25 | 26 | BRANCH_BUILD_URL = '{}/projects/{}/{}/branch/{}'.format( 27 | URL, ACCOUNT, PROJECT, branch) 28 | 29 | print ("URL : %s" % (BRANCH_BUILD_URL)) 30 | 31 | response = session.get(BRANCH_BUILD_URL) 32 | response.raise_for_status() 33 | 34 | build_data = response.json()['build'] 35 | 36 | message = dedent(''' 37 | Downloading wheels for latest build on branch {bd[branch]!r}. 38 | Branch: {bd[branch]} 39 | AppVeyor build: {bd[buildNumber]} 40 | Commit ID: {bd[commitId]} 41 | Commit message: {bd[message]} 42 | Build status: {bd[status]} 43 | '''.format(bd=build_data)) 44 | 45 | print(message) 46 | 47 | if build_data['status'] == 'failed': 48 | sys.exit('Build failed, aborting download.') 49 | elif build_data['status'] == 'running': 50 | sys.exit('Build still running, aborting download.') 51 | 52 | job_ids = [job['jobId'] for job in build_data['jobs']] 53 | 54 | 55 | def download_artifact(artifact): 56 | FILE_URL = '{}/buildjobs/{}/artifacts/{}'.format( 57 | URL, job_id, artifact['fileName']) 58 | 59 | print('Downloading', artifact['fileName']) 60 | 61 | response = session.get(FILE_URL, stream=True) 62 | response.raise_for_status() 63 | 64 | with open(artifact['fileName'], 'wb') as fp: 65 | for chunk in response.iter_content(chunk_size=100 * 1024): 66 | if(chunk): 67 | fp.write(chunk) 68 | 69 | try: 70 | os.mkdir('dist') 71 | except OSError: 72 | pass 73 | 74 | for job_id in job_ids: 75 | ARTIFACTS_URL = '{}/buildjobs/{}/artifacts'.format(URL, job_id) 76 | response = session.get(ARTIFACTS_URL) 77 | for artifact in response.json(): 78 | if artifact['fileName'].endswith('.whl'): 79 | download_artifact(artifact) 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/Readme.epanet2.txt: -------------------------------------------------------------------------------- 1 | Contents of EPANET2.ZIP 2 | ======================= 3 | This archive contains the source code for the EPANET 2 4 | network hydraulic and water quality solver. The solver 5 | provides functions for simulating the extended period 6 | hydraulic and water quality behavior of water distribution 7 | system pipe networks. It is written in ANSI-compatible C 8 | and can be compiled into either a Windows Dynamic Link 9 | Library of functions or into a command-line executable. 10 | 11 | The archived code is set up for compilation as a DLL. 12 | To compile it as a command line (or console) application 13 | simply comment out the "#define DLL" macro statement at 14 | the top of EPANET.C and un-comment the "#define CLE" macro. 15 | 16 | The DLL version of the solver (epanet2.dll) is used with 17 | the EPANET 2 user interface executable (epanet2w.exe) to 18 | form a complete Windows modeling package. It also serves 19 | as the function library for the EPANET Programmer's Toolkit, 20 | allowing developers to construct their own customized pipe 21 | network analysis applications. 22 | 23 | The following C-code files are included in this archive: 24 | EPANET.C -- main module providing supervisory control 25 | INPUT1.C -- controls processing of input data 26 | INPUT2.C -- reads data from input file 27 | INPUT3.C -- parses individual lines of input data 28 | INPFILE.C -- saves modified input data to a text file 29 | RULES.C -- implements rule-based control of piping system 30 | HYDRAUL.C -- computes extended period hydraulic behavior 31 | QUALITY.C -- tracks transport & fate of water quality 32 | OUTPUT.C -- handles transfer of data to and from binary files 33 | REPORT.C -- handles reporting of results to text file 34 | SMATRIX.C -- sparse matrix linear equation solver routines 35 | MEMPOOL.C -- memory pool management routines 36 | HASH.C -- hash table routines 37 | 38 | Also included are the following header files: 39 | TOOLKIT.H -- function prototypes of exported DLL functions 40 | FUNCS.H -- prototypes of all other functions 41 | TYPES.H -- declaration of global constants and data structures 42 | VARS.H -- declaration of global variables 43 | HASH.H -- header file for hash table routines 44 | MEMPOOL.H -- header file for memory pool routines 45 | ENUMSTXT.H -- string constants for enumerated types 46 | TEXT.H -- declaration of all other string constants 47 | 48 | The comments at the top of each file lists the date when the latest 49 | update was made, and these updates can be located in the code by 50 | searching for comments with the phrase "/*** Updated" or with the 51 | release number (e.g., 2.00.12) in them. 52 | 53 | Other useful documentation that can be consulted includes the EPANET 54 | Programmers Toolkit Help file and the EPANET Version 2 Users Manual. 55 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Contributing 3 | ============ 4 | 5 | Contributions are welcome, and they are greatly appreciated! Every 6 | little bit helps, and credit will always be given. 7 | 8 | Bug reports 9 | =========== 10 | 11 | When `reporting a bug `_ please include: 12 | 13 | * Your operating system name and version. 14 | * Any details about your local setup that might be helpful in troubleshooting. 15 | * Detailed steps to reproduce the bug. 16 | 17 | Documentation improvements 18 | ========================== 19 | 20 | epanettools could always use more documentation, whether as part of the 21 | official epanettools docs, in docstrings, or even on the web in blog posts, 22 | articles, and such. 23 | 24 | Feature requests and feedback 25 | ============================= 26 | 27 | The best way to send feedback is to file an issue at https://github.com/asselapathirana/epanettools/issues. 28 | 29 | If you are proposing a feature: 30 | 31 | * Explain in detail how it would work. 32 | * Keep the scope as narrow as possible, to make it easier to implement. 33 | * Remember that this is a volunteer-driven project, and that code contributions are welcome :) 34 | 35 | Development 36 | =========== 37 | 38 | To set up `epanettools` for local development: 39 | 40 | 1. Fork `epanettools `_ 41 | (look for the "Fork" button). 42 | 2. Clone your fork locally:: 43 | 44 | git clone git@github.com:your_name_here/epanettools.git 45 | 46 | 3. Create a branch for local development:: 47 | 48 | git checkout -b name-of-your-bugfix-or-feature 49 | 50 | Now you can make your changes locally. 51 | 52 | 4. When you're done making changes, run all the checks, doc builder and spell checker with `tox `_ one command:: 53 | 54 | tox 55 | 56 | 5. Commit your changes and push your branch to GitHub:: 57 | 58 | git add . 59 | git commit -m "Your detailed description of your changes." 60 | git push origin name-of-your-bugfix-or-feature 61 | 62 | 6. Submit a pull request through the GitHub website. 63 | 64 | Pull Request Guidelines 65 | ----------------------- 66 | 67 | If you need some code review or feedback while you're developing the code just make the pull request. 68 | 69 | For merging, you should: 70 | 71 | 1. Include passing tests (run ``tox``) [1]_. 72 | 2. Update documentation when there's new API, functionality etc. 73 | 3. Add a note to ``CHANGELOG.rst`` about the changes. 74 | 4. Add yourself to ``AUTHORS.rst``. 75 | 76 | .. [1] If you don't have all the necessary python versions available locally you can rely on Travis - it will 77 | `run the tests `_ for each change you add in the pull request. 78 | 79 | It will be slower though ... 80 | 81 | Tips 82 | ---- 83 | 84 | To run a subset of tests:: 85 | 86 | tox -e envname -- py.test -k test_myfeature 87 | 88 | To run all the test environments in *parallel* (you need to ``pip install detox``):: 89 | 90 | detox 91 | -------------------------------------------------------------------------------- /junk/t.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 97 | 98 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | ; a generative tox configuration, see: https://testrun.org/tox/latest/config.html#generative-envlist 2 | 3 | [tox] 4 | envlist = 5 | clean, 6 | check, 7 | {py27,py33,py34,py35,py36,py37,pypy}, 8 | report, 9 | docs 10 | skip_missing_interpreters = 11 | true 12 | skipdist=True 13 | 14 | [testenv] 15 | basepython = 16 | pypy: {env:TOXPYTHON:pypy} 17 | {py27,docs,spell}: {env:TOXPYTHON:python2.7} 18 | py33: {env:TOXPYTHON:python3.3} 19 | py34: {env:TOXPYTHON:python3.4} 20 | py35: {env:TOXPYTHON:python3.5} 21 | py36: {env:TOXPYTHON:python3.6} 22 | py37: {env:TOXPYTHON:python3.7} 23 | {clean,check,report,extension-coveralls,coveralls,codecov}: python3.7 24 | bootstrap: python 25 | setenv = 26 | PYTHONPATH={toxinidir}/tests 27 | PYTHONUNBUFFERED=yes 28 | passenv = 29 | * 30 | usedevelop = false 31 | deps = 32 | pytest 33 | pytest-travis-fold 34 | pytest-cov 35 | nose 36 | 37 | commands = 38 | python setup.py build {posargs} 39 | python setup.py install 40 | py.test --cov --cov-report=term-missing -vv tests 41 | python -m doctest README.rst 42 | 43 | ;;;[testenv:bootstrap] 44 | ;;;deps = 45 | ;;;jinja2 46 | ;;;matrix 47 | ;;;nose 48 | ;;;skip_install = true 49 | ;;;commands = 50 | ;;;python ci/bootstrap.py 51 | ;;;passenv = 52 | ;;;* 53 | 54 | ;;;[testenv:spell] 55 | ;;;setenv = 56 | ;;;SPELLCHECK=1 57 | ;;;commands = 58 | ;;;sphinx-build -b spelling docs dist/docs 59 | ;;;skip_install = true 60 | ;;;deps = 61 | ;;;-r{toxinidir}/docs/requirements.txt 62 | ;;;sphinxcontrib-spelling 63 | ;;;pyenchant 64 | ;;;nose 65 | 66 | ;;;[testenv:docs] 67 | ;;;deps = 68 | ;;;-r{toxinidir}/docs/requirements.txt 69 | ;;;nose 70 | ;;;commands = 71 | ;;;sphinx-build -E -b doctest docs dist/docs 72 | ;;;sphinx-build -E -b html docs dist/docs 73 | ;;;sphinx-build -b linkcheck docs dist/docs 74 | 75 | [testenv:check] 76 | deps = 77 | docutils 78 | check-manifest 79 | flake8 80 | readme-renderer 81 | pygments 82 | isort 83 | nose 84 | skip_install = true 85 | commands = 86 | python setup.py check --strict --metadata --restructuredtext 87 | check-manifest {toxinidir} 88 | flake8 src tests setup.py 89 | isort --verbose --check-only --diff --recursive src tests setup.py 90 | 91 | [testenv:coveralls] 92 | deps = 93 | coveralls 94 | nose 95 | skip_install = true 96 | commands = 97 | coverage combine --append 98 | coverage report --omit="*test*" 99 | coveralls --merge=extension-coveralls.json [] 100 | 101 | [testenv:codecov] 102 | deps = 103 | codecov 104 | nose 105 | skip_install = true 106 | commands = 107 | coverage combine --append 108 | coverage report --omit="*test*" 109 | coverage xml --ignore-errors 110 | codecov [] 111 | 112 | 113 | [testenv:extension-coveralls] 114 | deps = 115 | cpp-coveralls 116 | nose 117 | skip_install = true 118 | commands = 119 | coveralls --build-root=. --include=src --dump=extension-coveralls.json [] 120 | 121 | 122 | 123 | [testenv:report] 124 | deps = coverage 125 | nose 126 | skip_install = true 127 | commands = 128 | coverage combine --append 129 | coverage report --omit="*test*" 130 | coverage html 131 | 132 | [testenv:clean] 133 | commands = coverage erase 134 | skip_install = true 135 | deps = coverage 136 | 137 | -------------------------------------------------------------------------------- /src/epanettools/adf/callepanet.h: -------------------------------------------------------------------------------- 1 | #ifndef CALLADF_H 2 | #define CALLADF_H 3 | 4 | 5 | #define _CRT_SECURE_NO_DEPRECATE // to avoid visual studio screaming 'bloody murder'. 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | /* macros and variables used by ReDirectStdout function */ 19 | // 20 | #ifdef _WIN32 21 | #define _CRT_SECURE_NO_WARNINGS 1 22 | #include 23 | #define _DUP_ _dup 24 | #define _DUP2_ _dup2 25 | #define _CLOSE_ _close 26 | #define _FILENO_ _fileno 27 | #else 28 | #include 29 | #define _DUP_ dup 30 | #define _DUP2_ dup2 31 | #define fopen_s fopen 32 | #define _CLOSE_ close 33 | #define _FILENO_ fileno 34 | #endif 35 | #include 36 | #include 37 | #include 38 | int stdout_dupfd; 39 | FILE *temp_out; 40 | /* end macros and variables used by ReDirectStdout function */ 41 | 42 | 43 | /* Structures */ 44 | struct pr { 45 | float p; 46 | float d; 47 | float bd; 48 | float head; 49 | int type; 50 | }; 51 | 52 | struct res { 53 | float adf1; 54 | float adf2; 55 | float energy_in; 56 | float energy_out; 57 | }; 58 | /* end structures */ 59 | 60 | /* function prototypes */ 61 | void eoutcheck(int); 62 | void HydrantRating(char *, int, float[], float[]); 63 | void GetNodeP(int, vector&, int); 64 | float penalty_score(int); 65 | float penalty(float, float); 66 | res without_link(int); 67 | void init(char*); 68 | void costCalc(); 69 | void BaselineCalc(); 70 | vector > getResults(bool); 71 | void help(char *); 72 | string linkid(int); 73 | float diam(int); 74 | float length(int); 75 | float pen_s(float, float); 76 | float pen(float, float); 77 | float pen_l(float, float); 78 | void no_objects(); 79 | res compute_results(vector >, vector >, vector >); 80 | void open(bool); 81 | void close(bool); 82 | void writeoutputforpipe(int, res &); 83 | void fillinemptyresultsobject(vector > &); 84 | void getValuesForNode(int, int, vector > &, bool); 85 | void ReDirectStdout(bool); 86 | void initLinkArray(); 87 | /* end fuction prototypes */ 88 | 89 | /* Global variables used in callepanet.cc */ 90 | float ecupValue; 91 | float eexpValue; 92 | ofstream ResultsFile; //output file. 93 | vector > emitterbaseline; 94 | vector > regularbaseline; 95 | bool epanet_error = false; 96 | vector linksOfNetwork; // a vector containing the ids of links ordered by index 97 | char* inpfile; 98 | float DIAFACTOR = 5; 99 | /* end of global variables */ 100 | 101 | /* Constants used in callepanet.cc */ 102 | #define LOGFILENAME "log.txt" /* the file we used to redirect stdout when it becomes to much for comfort! */ 103 | #define SMALLDIA 0.01f /* negligibly small diameter (in mm or inches) */ 104 | #define EN_REPORTFILEEXTENSION ".rpt" /* Extension for the report file of epanet */ 105 | #define EN_BINARYOUTFILENAME "" /* Name of the binary result file. Empty - no binary results */ 106 | #define RESULTFILEEXTENSION ".results.txt" /* Extension for the results file*/ 107 | #define DUMBSTRING "-1" /* A string that indicates dumb value */ 108 | /* end constants */ 109 | #endif 110 | -------------------------------------------------------------------------------- /src/epanettools/epanet/hash.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | ** hash.c 3 | ** 4 | ** Implementation of a simple Hash Table for string storage & retrieval 5 | ** 6 | ** Written by L. Rossman 7 | ** Last Updated on 6/19/03 8 | ** 9 | ** The hash table data structure (HTable) is defined in "hash.h". 10 | ** Interface Functions: 11 | ** HTcreate() - creates a hash table 12 | ** HTinsert() - inserts a string & its index value into a hash table 13 | ** HTfind() - retrieves the index value of a string from a table 14 | ** HTfree() - frees a hash table 15 | ** 16 | ********************************************************************* 17 | ** NOTE: This is a modified version of the original HASH.C module. 18 | ********************************************************************* 19 | */ 20 | 21 | #include 22 | #include 23 | #include "hash.h" 24 | 25 | /* Use Fletcher's checksum to compute 2-byte hash of string */ 26 | unsigned int hash(char *str) 27 | { 28 | unsigned int sum1= 0, check1; 29 | unsigned long sum2= 0L; 30 | while( '\0' != *str ) 31 | { 32 | sum1 += (*str); 33 | str++; 34 | if ( 255 <= sum1 ) sum1 -= 255; 35 | sum2 += sum1; 36 | } 37 | check1= sum2; 38 | check1 %= 255; 39 | check1= 255 - (sum1+check1) % 255; 40 | sum1= 255 - (sum1+check1) % 255; 41 | return( ( ( check1 << 8 ) | sum1 ) % HTMAXSIZE); 42 | } 43 | 44 | HTtable *HTcreate() 45 | { 46 | int i; 47 | HTtable *ht = (HTtable *) calloc(HTMAXSIZE, sizeof(HTtable)); 48 | if (ht != NULL) for (i=0; i= HTMAXSIZE ) return(0); 57 | entry = (struct HTentry *) malloc(sizeof(struct HTentry)); 58 | if (entry == NULL) return(0); 59 | entry->key = key; 60 | entry->data = data; 61 | entry->next = ht[i]; 62 | ht[i] = entry; 63 | return(1); 64 | } 65 | 66 | int HTfind(HTtable *ht, char *key) 67 | { 68 | unsigned int i = hash(key); 69 | struct HTentry *entry; 70 | if ( i >= HTMAXSIZE ) return(NOTFOUND); 71 | entry = ht[i]; 72 | while (entry != NULL) 73 | { 74 | if ( strcmp(entry->key,key) == 0 ) return(entry->data); 75 | entry = entry->next; 76 | } 77 | return(NOTFOUND); 78 | } 79 | 80 | char *HTfindKey(HTtable *ht, char *key) 81 | { 82 | unsigned int i = hash(key); 83 | struct HTentry *entry; 84 | if ( i >= HTMAXSIZE ) return(NULL); 85 | entry = ht[i]; 86 | while (entry != NULL) 87 | { 88 | if ( strcmp(entry->key,key) == 0 ) return(entry->key); 89 | entry = entry->next; 90 | } 91 | return(NULL); 92 | } 93 | 94 | void HTfree(HTtable *ht) 95 | { 96 | struct HTentry *entry, 97 | *nextentry; 98 | int i; 99 | for (i=0; inext; 105 | free(entry); 106 | entry = nextentry; 107 | } 108 | } 109 | free(ht); 110 | } 111 | -------------------------------------------------------------------------------- /src/epanettools/adf.py: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by SWIG (http://www.swig.org). 2 | # Version 3.0.12 3 | # 4 | # Do not make changes to this file unless you know what you are doing--modify 5 | # the SWIG interface file instead. 6 | 7 | from sys import version_info as _swig_python_version_info 8 | if _swig_python_version_info >= (2, 7, 0): 9 | def swig_import_helper(): 10 | import importlib 11 | pkg = __name__.rpartition('.')[0] 12 | mname = '.'.join((pkg, '_adf')).lstrip('.') 13 | try: 14 | return importlib.import_module(mname) 15 | except ImportError: 16 | return importlib.import_module('_adf') 17 | _adf = swig_import_helper() 18 | del swig_import_helper 19 | elif _swig_python_version_info >= (2, 6, 0): 20 | def swig_import_helper(): 21 | from os.path import dirname 22 | import imp 23 | fp = None 24 | try: 25 | fp, pathname, description = imp.find_module('_adf', [dirname(__file__)]) 26 | except ImportError: 27 | import _adf 28 | return _adf 29 | try: 30 | _mod = imp.load_module('_adf', fp, pathname, description) 31 | finally: 32 | if fp is not None: 33 | fp.close() 34 | return _mod 35 | _adf = swig_import_helper() 36 | del swig_import_helper 37 | else: 38 | import _adf 39 | del _swig_python_version_info 40 | 41 | try: 42 | _swig_property = property 43 | except NameError: 44 | pass # Python < 2.2 doesn't have 'property'. 45 | 46 | try: 47 | import builtins as __builtin__ 48 | except ImportError: 49 | import __builtin__ 50 | 51 | def _swig_setattr_nondynamic(self, class_type, name, value, static=1): 52 | if (name == "thisown"): 53 | return self.this.own(value) 54 | if (name == "this"): 55 | if type(value).__name__ == 'SwigPyObject': 56 | self.__dict__[name] = value 57 | return 58 | method = class_type.__swig_setmethods__.get(name, None) 59 | if method: 60 | return method(self, value) 61 | if (not static): 62 | if _newclass: 63 | object.__setattr__(self, name, value) 64 | else: 65 | self.__dict__[name] = value 66 | else: 67 | raise AttributeError("You cannot add attributes to %s" % self) 68 | 69 | 70 | def _swig_setattr(self, class_type, name, value): 71 | return _swig_setattr_nondynamic(self, class_type, name, value, 0) 72 | 73 | 74 | def _swig_getattr(self, class_type, name): 75 | if (name == "thisown"): 76 | return self.this.own() 77 | method = class_type.__swig_getmethods__.get(name, None) 78 | if method: 79 | return method(self) 80 | raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name)) 81 | 82 | 83 | def _swig_repr(self): 84 | try: 85 | strthis = "proxy of " + self.this.__repr__() 86 | except __builtin__.Exception: 87 | strthis = "" 88 | return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) 89 | 90 | try: 91 | _object = object 92 | _newclass = 1 93 | except __builtin__.Exception: 94 | class _object: 95 | pass 96 | _newclass = 0 97 | 98 | 99 | def ADF_calculation(inpfile, outfile, diafact): 100 | return _adf.ADF_calculation(inpfile, outfile, diafact) 101 | ADF_calculation = _adf.ADF_calculation 102 | # This file is compatible with both classic and new-style classes. 103 | 104 | cvar = _adf.cvar 105 | 106 | -------------------------------------------------------------------------------- /ci/appveyor-download.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Use the AppVeyor API to download Windows artifacts. 4 | 5 | Taken from: https://bitbucket.org/ned/coveragepy/src/tip/ci/download_appveyor.py 6 | # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 7 | # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt 8 | """ 9 | from __future__ import unicode_literals 10 | 11 | import argparse 12 | import os 13 | import zipfile 14 | 15 | import requests 16 | 17 | 18 | def make_auth_headers(): 19 | """Make the authentication headers needed to use the Appveyor API.""" 20 | path = os.path.expanduser("~/.appveyor.token") 21 | if not os.path.exists(path): 22 | raise RuntimeError( 23 | "Please create a file named `.appveyor.token` in your home directory. " 24 | "You can get the token from https://ci.appveyor.com/api-token" 25 | ) 26 | with open(path) as f: 27 | token = f.read().strip() 28 | 29 | headers = { 30 | 'Authorization': 'Bearer {}'.format(token), 31 | } 32 | return headers 33 | 34 | 35 | def download_latest_artifacts(account_project, build_id): 36 | """Download all the artifacts from the latest build.""" 37 | if build_id is None: 38 | url = "https://ci.appveyor.com/api/projects/{}".format(account_project) 39 | else: 40 | url = "https://ci.appveyor.com/api/projects/{}/build/{}".format(account_project, build_id) 41 | build = requests.get(url, headers=make_auth_headers()).json() 42 | jobs = build['build']['jobs'] 43 | print(u"Build {0[build][version]}, {1} jobs: {0[build][message]}".format(build, len(jobs))) 44 | 45 | for job in jobs: 46 | name = job['name'] 47 | print(u" {0}: {1[status]}, {1[artifactsCount]} artifacts".format(name, job)) 48 | 49 | url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts".format(job['jobId']) 50 | response = requests.get(url, headers=make_auth_headers()) 51 | artifacts = response.json() 52 | 53 | for artifact in artifacts: 54 | is_zip = artifact['type'] == "Zip" 55 | filename = artifact['fileName'] 56 | print(u" {0}, {1} bytes".format(filename, artifact['size'])) 57 | 58 | url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts/{}".format(job['jobId'], filename) 59 | download_url(url, filename, make_auth_headers()) 60 | 61 | if is_zip: 62 | unpack_zipfile(filename) 63 | os.remove(filename) 64 | 65 | 66 | def ensure_dirs(filename): 67 | """Make sure the directories exist for `filename`.""" 68 | dirname = os.path.dirname(filename) 69 | if dirname and not os.path.exists(dirname): 70 | os.makedirs(dirname) 71 | 72 | 73 | def download_url(url, filename, headers): 74 | """Download a file from `url` to `filename`.""" 75 | ensure_dirs(filename) 76 | response = requests.get(url, headers=headers, stream=True) 77 | if response.status_code == 200: 78 | with open(filename, 'wb') as f: 79 | for chunk in response.iter_content(16 * 1024): 80 | f.write(chunk) 81 | else: 82 | print(u" Error downloading {}: {}".format(url, response)) 83 | 84 | 85 | def unpack_zipfile(filename): 86 | """Unpack a zipfile, using the names in the zip.""" 87 | with open(filename, 'rb') as fzip: 88 | z = zipfile.ZipFile(fzip) 89 | for name in z.namelist(): 90 | print(u" extracting {}".format(name)) 91 | ensure_dirs(name) 92 | z.extract(name) 93 | 94 | 95 | parser = argparse.ArgumentParser(description='Download artifacts from AppVeyor.') 96 | parser.add_argument('--id', 97 | metavar='PROJECT_ID', 98 | default='asselapathirana/epanettools', 99 | help='Project ID in AppVeyor.') 100 | parser.add_argument('build', 101 | nargs='?', 102 | metavar='BUILD_ID', 103 | help='Build ID in AppVeyor. Eg: master-123') 104 | 105 | if __name__ == "__main__": 106 | # import logging 107 | # logging.basicConfig(level="DEBUG") 108 | args = parser.parse_args() 109 | download_latest_artifacts(args.id, args.build) 110 | -------------------------------------------------------------------------------- /ci/appveyor-bootstrap.py: -------------------------------------------------------------------------------- 1 | """ 2 | AppVeyor will at least have few Pythons around so there's no point of implementing a bootstrapper in PowerShell. 3 | 4 | This is a port of https://github.com/pypa/python-packaging-user-guide/blob/master/source/code/install.ps1 5 | with various fixes and improvements that just weren't feasible to implement in PowerShell. 6 | """ 7 | from __future__ import print_function 8 | 9 | from os import environ 10 | from os.path import exists 11 | from subprocess import CalledProcessError 12 | from subprocess import check_call 13 | 14 | try: 15 | from urllib.request import urlretrieve 16 | except ImportError: 17 | from urllib import urlretrieve 18 | 19 | BASE_URL = "https://www.python.org/ftp/python/" 20 | GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" 21 | GET_PIP_PATH = "C:\get-pip.py" 22 | URLS = { 23 | ("2.7", "64"): BASE_URL + "2.7.10/python-2.7.10.amd64.msi", 24 | ("2.7", "32"): BASE_URL + "2.7.10/python-2.7.10.msi", 25 | # NOTE: no .msi installer for 3.3.6 26 | ("3.3", "64"): BASE_URL + "3.3.3/python-3.3.3.amd64.msi", 27 | ("3.3", "32"): BASE_URL + "3.3.3/python-3.3.3.msi", 28 | ("3.4", "64"): BASE_URL + "3.4.3/python-3.4.3.amd64.msi", 29 | ("3.4", "32"): BASE_URL + "3.4.3/python-3.4.3.msi", 30 | ("3.5", "64"): BASE_URL + "3.5.0/python-3.5.0-amd64.exe", 31 | ("3.5", "32"): BASE_URL + "3.5.0/python-3.5.0.exe", 32 | } 33 | INSTALL_CMD = { 34 | # Commands are allowed to fail only if they are not the last command. Eg: uninstall (/x) allowed to fail. 35 | "2.7": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"], 36 | ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]], 37 | "3.3": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"], 38 | ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]], 39 | "3.4": [["msiexec.exe", "/L*+!", "install.log", "/qn", "/x", "{path}"], 40 | ["msiexec.exe", "/L*+!", "install.log", "/qn", "/i", "{path}", "TARGETDIR={home}"]], 41 | "3.5": [["{path}", "/quiet", "TargetDir={home}"]], 42 | } 43 | 44 | 45 | def download_file(url, path): 46 | print("Downloading: {} (into {})".format(url, path)) 47 | progress = [0, 0] 48 | 49 | def report(count, size, total): 50 | progress[0] = count * size 51 | if progress[0] - progress[1] > 1000000: 52 | progress[1] = progress[0] 53 | print("Downloaded {:,}/{:,} ...".format(progress[1], total)) 54 | 55 | dest, _ = urlretrieve(url, path, reporthook=report) 56 | return dest 57 | 58 | 59 | def install_python(version, arch, home): 60 | print("Installing Python", version, "for", arch, "bit architecture to", home) 61 | if exists(home): 62 | return 63 | 64 | path = download_python(version, arch) 65 | print("Installing", path, "to", home) 66 | success = False 67 | for cmd in INSTALL_CMD[version]: 68 | cmd = [part.format(home=home, path=path) for part in cmd] 69 | print("Running:", " ".join(cmd)) 70 | try: 71 | check_call(cmd) 72 | except CalledProcessError as exc: 73 | print("Failed command", cmd, "with:", exc) 74 | if exists("install.log"): 75 | with open("install.log") as fh: 76 | print(fh.read()) 77 | else: 78 | success = True 79 | if success: 80 | print("Installation complete!") 81 | else: 82 | print("Installation failed") 83 | 84 | 85 | def download_python(version, arch): 86 | for _ in range(3): 87 | try: 88 | return download_file(URLS[version, arch], "installer.exe") 89 | except Exception as exc: 90 | print("Failed to download:", exc) 91 | print("Retrying ...") 92 | 93 | 94 | def install_pip(home): 95 | pip_path = home + "/Scripts/pip.exe" 96 | python_path = home + "/python.exe" 97 | if exists(pip_path): 98 | print("pip already installed.") 99 | else: 100 | print("Installing pip...") 101 | download_file(GET_PIP_URL, GET_PIP_PATH) 102 | print("Executing:", python_path, GET_PIP_PATH) 103 | check_call([python_path, GET_PIP_PATH]) 104 | 105 | 106 | def install_packages(home, *packages): 107 | cmd = [home + "/Scripts/pip.exe", "install"] 108 | cmd.extend(packages) 109 | check_call(cmd) 110 | 111 | 112 | if __name__ == "__main__": 113 | install_python(environ['PYTHON_VERSION'], environ['PYTHON_ARCH'], environ['PYTHON_HOME']) 114 | install_pip(environ['PYTHON_HOME']) 115 | install_packages(environ['PYTHON_HOME'], "setuptools>=18.0.1", "wheel", "tox", "virtualenv>=13.1.0") 116 | -------------------------------------------------------------------------------- /tests/test_epanettools.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import epanettools 4 | 5 | 6 | class Test1(unittest.TestCase): 7 | 8 | def setup(self): 9 | print("SETUP!") 10 | 11 | def teardown(self): 12 | print("TEAR DOWN!") 13 | 14 | def err(self, et, e): 15 | if(e > 0): 16 | print((e, et.ENgeterror(e, 25))) 17 | exit(5) 18 | 19 | def test_error_func(self): 20 | from epanettools.epanettools import Error 21 | with self.assertRaises(Exception) as e: 22 | Error(202) 23 | self.assertEqual(e.exception.args[0], "Epanet Error: 202 : Input Error 202: function call contains illegal numeric value.") 24 | 25 | def test_basic(self): 26 | import os 27 | from epanettools import epanet2 as et 28 | from epanettools.examples import simple 29 | 30 | file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 31 | ret = et.ENopen(file, "Net3.rpt", "Net3.dat") 32 | self.err(et, ret) 33 | 34 | ret, result = et.ENgetcount(et.EN_LINKCOUNT) 35 | 36 | # links 37 | assert (result == 119) 38 | 39 | ret, result = et.ENgetcount(et.EN_NODECOUNT) 40 | # nodes 41 | assert(result == 97) 42 | 43 | node = '105' 44 | ret, index = et.ENgetnodeindex(node) 45 | # index of node '105' 46 | assert(index == 12) 47 | 48 | # 49 | print(et.ENgetlinknodes(55)) 50 | assert all([i == j for i, j in zip(et.ENgetlinknodes(55), [0, 5, 46])]) 51 | 52 | ret, nnodes = et.ENgetcount(et.EN_NODECOUNT) 53 | nodes = [] 54 | pres = [] 55 | time = [] 56 | for index in range(1, nnodes): 57 | ret, t = et.ENgetnodeid(index) 58 | nodes.append(t) 59 | t = [] 60 | pres.append(t) 61 | print(nodes) 62 | assert(nodes == ['10', '15', '20', '35', '40', '50', 63 | '60', '601', '61', '101', '103', '105', 64 | '107', '109', '111', '113', '115', '117', 65 | '119', '120', '121', '123', '125', '127', 66 | '129', '131', '139', '141', '143', '145', 67 | '147', '149', '151', '153', '157', '159', 68 | '161', '163', '164', '166', '167', '169', 69 | '171', '173', '177', '179', '181', '183', 70 | '184', '185', '187', '189', '191', '193', 71 | '195', '197', '199', '201', '203', '204', 72 | '205', '206', '207', '208', '209', '211', 73 | '213', '215', '217', '219', '225', '229', 74 | '231', '237', '239', '241', '243', '247', 75 | '249', '251', '253', '255', '257', '259', 76 | '261', '263', '265', '267', '269', '271', 77 | '273', '275', 'River', 'Lake', '1', '2']) 78 | 79 | self.err(et, et.ENopenH()) 80 | self.err(et, et.ENinitH(0)) 81 | while True: 82 | ret, t = et.ENrunH() 83 | time.append(t) 84 | self.err(et, ret) 85 | # Retrieve hydraulic results for time t 86 | for i in range(0, len(nodes)): 87 | ret, p = et.ENgetnodevalue(i + 1, et.EN_PRESSURE) 88 | pres[i].append(p) 89 | ret, tstep = et.ENnextH() 90 | self.err(et, ret) 91 | if (tstep <= 0): 92 | break 93 | ret = et.ENcloseH() 94 | print(pres[12]) 95 | diffs = [abs(i - j) for i, j in zip(pres[12], 96 | [54.085777282714844, 60.99293518066406, 97 | 63.03010940551758, 63.56983947753906, 98 | 66.80770874023438, 63.989463806152344, 99 | 63.49333190917969, 63.895835876464844, 100 | 63.440582275390625, 63.90030288696289, 101 | 63.43799591064453, 63.438758850097656, 102 | 63.03285598754883, 63.005157470703125, 103 | 63.1264533996582, 63.40403366088867, 104 | 56.72084045410156, 56.622596740722656, 105 | 56.47193908691406, 56.478843688964844, 106 | 56.27402114868164, 55.576839447021484, 107 | 55.0153923034668, 55.81755065917969, 108 | 55.200626373291016, 53.8864860534668, 109 | 55.024227142333984])] 110 | print([i for i in diffs]) 111 | assert all([i < 1.e-5 for i in diffs]) 112 | -------------------------------------------------------------------------------- /src/epanettools/pdd/mods.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | float value, EEXP, ECUP; 7 | 8 | string itoa_(long num) 9 | { 10 | stringstream converter; 11 | converter << num; 12 | return converter.str(); 13 | } 14 | 15 | 16 | string ftoa_(float num) 17 | { 18 | stringstream converter; 19 | converter << num; 20 | return converter.str(); 21 | } 22 | 23 | /* Following is a function to access the analysis system before each toolkit function. 24 | For the sake of completeness, all toolkit functions are addressed. But many could be useless 25 | e.g. run_before_ENget -- what is there to set before getting a network property!) 26 | */ 27 | 28 | int run_before_ENopen(){ 29 | return 0; 30 | } 31 | int run_before_ENsaveinpfile(){ 32 | return 0; 33 | } 34 | int run_before_ENclose(){ 35 | return 0; 36 | } 37 | int run_before_ENsaveH(){ 38 | return 0; 39 | } 40 | int run_before_ENinitH(){ 41 | emitter_analysis_prepare(); // this is extremely important 42 | getEmitterData(&EEXP, &ECUP); 43 | write_sign("Using P="+ftoa_(ECUP)+ " as cutoff pressure for emitters."); 44 | write_sign("Using n="+ftoa_(EEXP)+ " as emitter exponent."); 45 | float val; 46 | ENgetoption(EN_ACCURACY,&val); 47 | write_sign("Using n="+ftoa_(val)+ " as accuracy for pressure convergence."); 48 | return 0; 49 | } 50 | 51 | int run_before_ENnextH(){ 52 | //write_sign("... Ended cleanup for hour: "+itoa_(getcurrenttime()/3600)+" xxxxx "); 53 | post_analysis_cleanup(); 54 | return 0; 55 | } 56 | int run_before_ENcloseH(){ 57 | write_sign("... Ended the custom hydraulic analysis."); 58 | return 0; 59 | } 60 | int run_before_ENsavehydfile(){ 61 | return 0; 62 | } 63 | int run_before_ENusehydfile(){ 64 | return 0; 65 | } 66 | int run_before_ENsolveQ(){ 67 | return 0; 68 | } 69 | int run_before_ENopenQ(){ 70 | return 0; 71 | } 72 | int run_before_ENinitQ(){ 73 | return 0; 74 | } 75 | int run_before_ENrunQ(){ 76 | return 0; 77 | } 78 | int run_before_ENnextQ(){ 79 | return 0; 80 | } 81 | int run_before_ENstepQ(){ 82 | return 0; 83 | } 84 | int run_before_ENcloseQ(){ 85 | return 0; 86 | } 87 | int run_before_ENwriteline(){ 88 | return 0; 89 | } 90 | int run_before_ENreport(){ 91 | return 0; 92 | } 93 | int run_before_ENresetreport(){ 94 | return 0; 95 | } 96 | int run_before_ENsetreport(){ 97 | return 0; 98 | } 99 | int run_before_ENgetcontrol(){ 100 | return 0; 101 | } 102 | int run_before_ENgetcount(){ 103 | return 0; 104 | } 105 | int run_before_ENgetoption(){ 106 | return 0; 107 | } 108 | int run_before_ENgettimeparam(){ 109 | return 0; 110 | } 111 | int run_before_ENgetflowunits(){ 112 | return 0; 113 | } 114 | int run_before_ENgetpatternindex(){ 115 | return 0; 116 | } 117 | int run_before_ENgetpatternid(){ 118 | return 0; 119 | } 120 | int run_before_ENgetpatternlen(){ 121 | return 0; 122 | } 123 | int run_before_ENgetpatternvalue(){ 124 | return 0; 125 | } 126 | int run_before_ENgetqualtype(){ 127 | return 0; 128 | } 129 | int run_before_ENgeterror(){ 130 | return 0; 131 | } 132 | int run_before_ENgetnodeindex(){ 133 | return 0; 134 | } 135 | int run_before_ENgetnodeid(){ 136 | return 0; 137 | } 138 | int run_before_ENgetnodetype(){ 139 | return 0; 140 | } 141 | int run_before_ENgetnodevalue(){ 142 | return 0; 143 | } 144 | int run_before_ENgetlinkindex(){ 145 | return 0; 146 | } 147 | int run_before_ENgetlinkid(){ 148 | return 0; 149 | } 150 | int run_before_ENgetlinktype(){ 151 | return 0; 152 | } 153 | int run_before_ENgetlinknodes(){ 154 | return 0; 155 | } 156 | int run_before_ENgetlinkvalue(){ 157 | return 0; 158 | } 159 | int run_before_ENgetversion(){ 160 | return 0; 161 | } 162 | int run_before_ENsetcontrol(){ 163 | return 0; 164 | } 165 | int run_before_ENsetnodevalue(){ 166 | return 0; 167 | } 168 | int run_before_ENsetlinkvalue(){ 169 | return 0; 170 | } 171 | int run_before_ENaddpattern(){ 172 | return 0; 173 | } 174 | int run_before_ENsetpattern(){ 175 | return 0; 176 | } 177 | int run_before_ENsetpatternvalue(){ 178 | return 0; 179 | } 180 | int run_before_ENsettimeparam(){ 181 | return 0; 182 | } 183 | int run_before_ENsetoption(){ 184 | return 0; 185 | } 186 | int run_before_ENsetstatusreport(){ 187 | return 0; 188 | } 189 | int run_before_ENsetqualtype(){ 190 | return 0; 191 | } 192 | int run_before_ENopenH(){ 193 | write_sign("Starting the custom hydraulic analysis..."); 194 | return 0; 195 | } 196 | int run_before_ENrunH (){ 197 | int ret=emitter_analysis(); 198 | if(ret!=0){ 199 | write_sign("ERROR: Non-converging emitter analysis!!!"); 200 | } 201 | write_sign("PDD analysis ended for hour: "+ftoa_((getcurrenttime()/3600.+1.))+" with " 202 | + itoa_(getniter())+ " iterations."); 203 | /* string name="file-"+itoa_(getcurrenttime())+".inp"; 204 | char * name2; 205 | strcpy(name2,name.c_str()); 206 | int ret=ENsaveinpfile(name2); 207 | write_sign("Writing a temp file "+name+" 00000 " + itoa_(ret)); 208 | */ 209 | 210 | return ret; 211 | } 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /tests/test_EPANetPatterns.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import math 3 | import os 4 | import sys 5 | import unittest 6 | from unittest import expectedFailure 7 | from unittest import skip 8 | 9 | from tests import tools_for_testing as tt 10 | 11 | import epanettools 12 | from epanettools.epanettools import Control 13 | from epanettools.epanettools import Controls 14 | from epanettools.epanettools import EPANetSimulation 15 | from epanettools.epanettools import Link 16 | from epanettools.epanettools import Links 17 | from epanettools.epanettools import Network 18 | from epanettools.epanettools import Node 19 | from epanettools.epanettools import Nodes 20 | from epanettools.epanettools import Pattern 21 | from epanettools.epanettools import Patterns 22 | from epanettools.examples import simple 23 | 24 | patId = "NewPattern"; 25 | 26 | class Test1(unittest.TestCase): 27 | 28 | def setUp(self): 29 | print("SETUP!") 30 | file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 31 | self.es = EPANetSimulation(file) 32 | 33 | def tearDown(self): 34 | self.es.clean() 35 | print("TEAR DOWN!") 36 | 37 | @skip 38 | def test_false(self): 39 | assert False 40 | 41 | def test_can_retrieve_patterns_with_correct_length_and_values(self): 42 | self.assertAlmostEqual(self.es.network.patterns[1][1],1.34,delta=.01 ) 43 | self.assertAlmostEqual(self.es.network.patterns[1][2],1.94,delta=.01 ) 44 | self.assertAlmostEqual(self.es.network.patterns[1][3],1.46,delta=.01 ) 45 | self.assertEqual(len(self.es.network.patterns[1]),24) 46 | self.assertAlmostEqual(self.es.network.patterns[1][24],1.67,delta=.01) 47 | self.assertEqual(len(self.es.network.patterns),5) 48 | with self.assertRaises(KeyError): 49 | self.es.network.patterns[6] 50 | with self.assertRaises(KeyError): 51 | self.es.network.patterns[1][25] 52 | 53 | 54 | def test_set_patternvalue_changes_pattern_values(self): 55 | self.assertAlmostEqual(self.es.ENgetpatternvalue(1,3)[1],1.46,delta=.01 ) 56 | self.assertEqual(self.es.ENsetpatternvalue(1,3,1.8),0) 57 | self.assertAlmostEqual(self.es.ENgetpatternvalue(1,3)[1],1.8,delta=.01 ) 58 | 59 | def test_set_patternvalue_can_append_pattern_value(self): 60 | self.assertEqual(len(self.es.network.patterns[1]),24) 61 | with self.assertRaises(TypeError): 62 | self.assertEqual(self.es.ENsetpattern(6,1.,3),0) 63 | 64 | def test_ENsetpatterndim_will_allocate_a_pattern(self): 65 | index = self.create_pattern() 66 | self.assertEqual(self.es.ENsetpatterndim(index,24),0) 67 | self.assertEqual(self.es.ENgetpatternlen(index),[0,24]) 68 | for i in range(25): 69 | p=self.es.ENgetpatternvalue(index,i+1) 70 | if(i<24): 71 | self.assertEqual(p[0],0) 72 | self.assertAlmostEqual(p[1],0.0, delta=.01) 73 | else: 74 | self.assertEqual(p[0],251) 75 | 76 | def create_pattern(self): 77 | self.assertEqual(self.es.ENaddpattern(patId),0) 78 | ret,index=self.es.ENgetpatternindex(patId) 79 | return index 80 | 81 | def test_ENsetpattern_will_successfully_allocate_and_fill_an_exiting_pattern(self): 82 | index=self.create_pattern() 83 | pat=[1.0,2.0,3.0,4.0,8.0,9.0,10.0,11.0, 84 | 1.5,2.5,3.5,4.5,8.5,9.5,10.5,11.5, 85 | 1.6,2.6,3.6,4.6,8.6,9.6,10.6,11.6,] 86 | self.assertEqual(self.es.ENsetpattern(index,pat),0) 87 | self.assertEqual(self.es.ENgetpatternlen(index),[0,24]) 88 | for i in range(len(pat)): 89 | p=self.es.ENgetpatternvalue(index,i+1) 90 | self.assertEqual(p[0],0) 91 | self.assertAlmostEqual(p[1],pat[i],delta=0.001) 92 | 93 | def test_ENsetpattern_with_pat_id_not_index_will_successfully_allocate_and_fill_an_exiting_pattern(self): 94 | index=self.create_pattern() 95 | pat=[1.0,2.0,3.0,4.0,8.0,9.0,10.0,11.0, 96 | 1.5,2.5,3.5,4.5,8.5,9.5,10.5,11.5, 97 | 1.6,2.6,3.6,4.6,8.6,9.6,10.6,11.6,] 98 | with self.assertRaises(Exception): 99 | self.es.ENsetpattern("boo",pat) 100 | self.assertEqual(self.es.ENsetpattern(patId,pat),0) 101 | self.assertEqual(self.es.ENgetpatternlen(index),[0,24]) 102 | for i in range(len(pat)): 103 | p=self.es.ENgetpatternvalue(index,i+1) 104 | self.assertEqual(p[0],0) 105 | self.assertAlmostEqual(p[1],pat[i],delta=0.001) 106 | 107 | 108 | 109 | 110 | tc = None 111 | 112 | 113 | 114 | def clt(tc,fn): 115 | tc.setUp() 116 | fn() 117 | tc.tearDown() 118 | 119 | 120 | def main(): 121 | tc = Test1() 122 | for a in dir(tc): 123 | if (a.startswith('test_')): # test_sync 124 | b = getattr(tc, a) 125 | if(hasattr(b, '__call__')): 126 | print ("calling %s **********************************" % a) 127 | clt(tc,b) 128 | 129 | 130 | if __name__ == "__main__": 131 | main() 132 | -------------------------------------------------------------------------------- /src/epanettools/epanet/mempool.c: -------------------------------------------------------------------------------- 1 | /* mempool.c 2 | ** 3 | ** A simple fast memory allocation package. 4 | ** 5 | ** By Steve Hill in Graphics Gems III, David Kirk (ed.), 6 | ** Academic Press, Boston, MA, 1992 7 | ** 8 | ** Modified by Lew Rossman, 8/13/94. 9 | ** 10 | ** AllocInit() - create an alloc pool, returns the old pool handle 11 | ** Alloc() - allocate memory 12 | ** AllocReset() - reset the current pool 13 | ** AllocSetPool() - set the current pool 14 | ** AllocFree() - free the memory used by the current pool. 15 | ** 16 | */ 17 | 18 | #include 19 | #include 20 | #include "mempool.h" 21 | 22 | /* 23 | ** ALLOC_BLOCK_SIZE - adjust this size to suit your installation - it 24 | ** should be reasonably large otherwise you will be mallocing a lot. 25 | */ 26 | 27 | #define ALLOC_BLOCK_SIZE 64000 /*(62*1024)*/ 28 | 29 | /* 30 | ** alloc_hdr_t - Header for each block of memory. 31 | */ 32 | 33 | typedef struct alloc_hdr_s 34 | { 35 | struct alloc_hdr_s *next; /* Next Block */ 36 | char *block, /* Start of block */ 37 | *free, /* Next free in block */ 38 | *end; /* block + block size */ 39 | } alloc_hdr_t; 40 | 41 | /* 42 | ** alloc_root_t - Header for the whole pool. 43 | */ 44 | 45 | typedef struct alloc_root_s 46 | { 47 | alloc_hdr_t *first, /* First header in pool */ 48 | *current; /* Current header */ 49 | } alloc_root_t; 50 | 51 | /* 52 | ** root - Pointer to the current pool. 53 | */ 54 | 55 | static alloc_root_t *root; 56 | 57 | 58 | /* 59 | ** AllocHdr() 60 | ** 61 | ** Private routine to allocate a header and memory block. 62 | */ 63 | 64 | static alloc_hdr_t *AllocHdr(void); 65 | 66 | static alloc_hdr_t * AllocHdr() 67 | { 68 | alloc_hdr_t *hdr; 69 | char *block; 70 | 71 | block = (char *) malloc(ALLOC_BLOCK_SIZE); 72 | hdr = (alloc_hdr_t *) malloc(sizeof(alloc_hdr_t)); 73 | 74 | if (hdr == NULL || block == NULL) return(NULL); 75 | hdr->block = block; 76 | hdr->free = block; 77 | hdr->next = NULL; 78 | hdr->end = block + ALLOC_BLOCK_SIZE; 79 | 80 | return(hdr); 81 | } 82 | 83 | 84 | /* 85 | ** AllocInit() 86 | ** 87 | ** Create a new memory pool with one block. 88 | ** Returns pointer to the new pool. 89 | */ 90 | 91 | alloc_handle_t * AllocInit() 92 | { 93 | alloc_handle_t *newpool; 94 | 95 | root = (alloc_root_t *) malloc(sizeof(alloc_root_t)); 96 | if (root == NULL) return(NULL); 97 | if ( (root->first = AllocHdr()) == NULL) return(NULL); 98 | root->current = root->first; 99 | newpool = (alloc_handle_t *) root; 100 | return(newpool); 101 | } 102 | 103 | 104 | /* 105 | ** Alloc() 106 | ** 107 | ** Use as a direct replacement for malloc(). Allocates 108 | ** memory from the current pool. 109 | */ 110 | 111 | char * Alloc(long size) 112 | { 113 | alloc_hdr_t *hdr = root->current; 114 | char *ptr; 115 | 116 | /* 117 | ** Align to 4 byte boundary - should be ok for most machines. 118 | ** Change this if your machine has weird alignment requirements. 119 | */ 120 | size = (size + 3) & 0xfffffffc; 121 | 122 | ptr = hdr->free; 123 | hdr->free += size; 124 | 125 | /* Check if the current block is exhausted. */ 126 | 127 | if (hdr->free >= hdr->end) 128 | { 129 | /* Is the next block already allocated? */ 130 | 131 | if (hdr->next != NULL) 132 | { 133 | /* re-use block */ 134 | hdr->next->free = hdr->next->block; 135 | root->current = hdr->next; 136 | } 137 | else 138 | { 139 | /* extend the pool with a new block */ 140 | if ( (hdr->next = AllocHdr()) == NULL) return(NULL); 141 | root->current = hdr->next; 142 | } 143 | 144 | /* set ptr to the first location in the next block */ 145 | ptr = root->current->free; 146 | root->current->free += size; 147 | } 148 | 149 | /* Return pointer to allocated memory. */ 150 | 151 | return(ptr); 152 | } 153 | 154 | 155 | /* 156 | ** AllocSetPool() 157 | ** 158 | ** Change the current pool. Return the old pool. 159 | */ 160 | 161 | alloc_handle_t * AllocSetPool(alloc_handle_t *newpool) 162 | { 163 | alloc_handle_t *old = (alloc_handle_t *) root; 164 | root = (alloc_root_t *) newpool; 165 | return(old); 166 | } 167 | 168 | 169 | /* 170 | ** AllocReset() 171 | ** 172 | ** Reset the current pool for re-use. No memory is freed, 173 | ** so this is very fast. 174 | */ 175 | 176 | void AllocReset() 177 | { 178 | root->current = root->first; 179 | root->current->free = root->current->block; 180 | } 181 | 182 | 183 | /* 184 | ** AllocFreePool() 185 | ** 186 | ** Free the memory used by the current pool. 187 | ** Don't use where AllocReset() could be used. 188 | */ 189 | 190 | void AllocFreePool() 191 | { 192 | alloc_hdr_t *tmp, 193 | *hdr = root->first; 194 | 195 | while (hdr != NULL) 196 | { 197 | tmp = hdr->next; 198 | free((char *) hdr->block); 199 | free((char *) hdr); 200 | hdr = tmp; 201 | } 202 | free((char *) root); 203 | root = NULL; 204 | } 205 | -------------------------------------------------------------------------------- /src/epanettools/epanet/enumstxt.h: -------------------------------------------------------------------------------- 1 | /* 2 | *********************************************************************** 3 | 4 | ENUMSTXT.H -- Text strings for enumerated data types in EPANET 5 | 6 | VERSION: 2.00 7 | DATE: 5/8/00 8 | AUTHOR: L. Rossman 9 | US EPA - NRMRL 10 | 11 | ********************************************************************** 12 | */ 13 | 14 | char *NodeTxt[] = {t_JUNCTION, 15 | t_RESERVOIR, 16 | t_TANK}; 17 | 18 | char *LinkTxt[] = {w_CV, 19 | w_PIPE, 20 | w_PUMP, 21 | w_PRV, 22 | w_PSV, 23 | w_PBV, 24 | w_FCV, 25 | w_TCV, 26 | w_GPV}; 27 | 28 | char *StatTxt[] = {t_XHEAD, 29 | t_TEMPCLOSED, 30 | t_CLOSED, 31 | t_OPEN, 32 | t_ACTIVE, 33 | t_XFLOW, 34 | t_XFCV, 35 | t_XPRESSURE, 36 | t_FILLING, 37 | t_EMPTYING}; 38 | 39 | char *FormTxt[] = {w_HW, 40 | w_DW, 41 | w_CM}; 42 | 43 | char *RptFormTxt[] = {t_HW, 44 | t_DW, 45 | t_CM}; 46 | 47 | char *RptFlowUnitsTxt[] = {u_CFS, 48 | u_GPM, 49 | u_MGD, 50 | u_IMGD, 51 | u_AFD, 52 | u_LPS, 53 | u_LPM, 54 | u_MLD, 55 | u_CMH, 56 | u_CMD}; 57 | 58 | char *FlowUnitsTxt[] = {w_CFS, 59 | w_GPM, 60 | w_MGD, 61 | w_IMGD, 62 | w_AFD, 63 | w_LPS, 64 | w_LPM, 65 | w_MLD, 66 | w_CMH, 67 | w_CMD}; 68 | 69 | char *PressUnitsTxt[] = {w_PSI, 70 | w_KPA, 71 | w_METERS}; 72 | 73 | char *QualTxt[] = {w_NONE, 74 | w_CHEM, 75 | w_AGE, 76 | w_TRACE}; 77 | 78 | 79 | char *SourceTxt[] = {w_CONCEN, 80 | w_MASS, 81 | w_SETPOINT, 82 | w_FLOWPACED}; 83 | 84 | char *ControlTxt[] = {w_BELOW, 85 | w_ABOVE, 86 | w_TIME, 87 | w_CLOCKTIME}; 88 | 89 | char *TstatTxt[] = {w_NONE, 90 | w_AVG, 91 | w_MIN, 92 | w_MAX, 93 | w_RANGE}; 94 | 95 | char *MixTxt[] = {w_MIXED, 96 | w_2COMP, 97 | w_FIFO, 98 | w_LIFO, 99 | NULL}; 100 | 101 | char *RptFlagTxt[] = {w_NO, 102 | w_YES, 103 | w_FULL}; 104 | 105 | char *SectTxt[] = {s_TITLE, s_JUNCTIONS, s_RESERVOIRS, 106 | s_TANKS, s_PIPES, s_PUMPS, 107 | s_VALVES, s_CONTROLS, s_RULES, 108 | s_DEMANDS, s_SOURCES, s_EMITTERS, 109 | s_PATTERNS, s_CURVES, s_QUALITY, 110 | s_STATUS, s_ROUGHNESS, s_ENERGY, 111 | s_REACTIONS, s_MIXING, s_REPORT, 112 | s_TIMES, s_OPTIONS, s_COORDS, 113 | s_VERTICES, s_LABELS, s_BACKDROP, 114 | s_TAGS, s_END, 115 | NULL}; 116 | 117 | char *RptSectTxt[] = {NULL, t_JUNCTION, t_RESERVOIR, 118 | t_TANK, t_PIPE, t_PUMP, 119 | t_VALVE, t_CONTROL, t_RULE, 120 | t_DEMANDFOR,t_SOURCE, t_EMITTER, 121 | t_PATTERN, t_CURVE, t_QUALITY, 122 | t_STATUS, t_ROUGHNESS,t_ENERGY, 123 | t_REACTION, t_MIXING, t_REPORT, 124 | t_TIME, t_OPTION}; 125 | 126 | char *Fldname[] = {t_ELEV, t_DEMAND, t_HEAD, 127 | t_PRESSURE, t_QUALITY, t_LENGTH, 128 | t_DIAM, t_FLOW, t_VELOCITY, 129 | t_HEADLOSS, t_LINKQUAL, t_LINKSTATUS, 130 | t_SETTING, t_REACTRATE, t_FRICTION, 131 | "", "", "", "", "", "", NULL}; 132 | 133 | char *LogoTxt[] = {LOGO1,LOGO2,LOGO3,LOGO4,LOGO5,LOGO6,NULL}; 134 | 135 | 136 | -------------------------------------------------------------------------------- /src/epanettools/pdd/wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef WRAP_H 2 | #define WRAP_H 3 | 4 | #define WRAPPER_ERROR_FILE_OPEN 900000 5 | #define WRAPPER_ERROR_NOT_IMPLEMENTED 910000 6 | 7 | #undef WINDOWS 8 | #undef __WIN32__ 9 | 10 | // --- define DLLEXPORT 11 | #ifndef DLLEXPORT 12 | #ifdef __cplusplus 13 | #define DLLEXPORT extern "C" int 14 | #else 15 | #define DLLEXPORT extern int 16 | #endif 17 | #endif 18 | 19 | 20 | 21 | #include 22 | using namespace std; 23 | 24 | /* 26-Aug-2016 : IMPORTANT: all output parameters in wrapper.h has to be named and then declared below. See epanet2.h and epanet2.i files for examples. 25 | At the moment only a few were done to test. 26 | */ 27 | 28 | 29 | DLLEXPORT ENepanet_wrap(char * f1, char * f2, char * f3, void (*pviewprog) (char *)); 30 | DLLEXPORT ENopen_wrap(char * a1, char * a2, char * a3); 31 | DLLEXPORT ENsaveinpfile_wrap(char *a1); 32 | DLLEXPORT ENclose_wrap(void); 33 | DLLEXPORT ENsolveH_wrap(void); 34 | DLLEXPORT ENsaveH_wrap(void); 35 | DLLEXPORT ENopenH_wrap(void); 36 | DLLEXPORT ENinitH_wrap(int a1); 37 | DLLEXPORT ENrunH_wrap(long *result); 38 | DLLEXPORT ENnextH_wrap(long *result); 39 | DLLEXPORT ENcloseH_wrap(void); 40 | DLLEXPORT ENsavehydfile_wrap(char *a1); 41 | DLLEXPORT ENusehydfile_wrap(char *a1); 42 | DLLEXPORT ENsolveQ_wrap(void); 43 | DLLEXPORT ENopenQ_wrap(void); 44 | DLLEXPORT ENinitQ_wrap(int a1); 45 | DLLEXPORT ENrunQ_wrap(long *result); 46 | DLLEXPORT ENnextQ_wrap(long *result) ; 47 | DLLEXPORT ENstepQ_wrap(long *result) ; 48 | DLLEXPORT ENcloseQ_wrap(void); 49 | DLLEXPORT ENwriteline_wrap(char *a1) ; 50 | DLLEXPORT ENreport_wrap(void); 51 | DLLEXPORT ENresetreport_wrap(void); 52 | DLLEXPORT ENsetreport_wrap(char *a1) ; 53 | DLLEXPORT ENgetcontrol_wrap(int , int * ci1, int * ci2, float * c1, 54 | int* ci3, float * c2) ; 55 | DLLEXPORT ENgetcount_wrap(int a1, int * result) ; 56 | DLLEXPORT ENgetoption_wrap(int a1, float * result) ; 57 | DLLEXPORT ENgettimeparam_wrap(int a1, long * result) ; 58 | DLLEXPORT ENgetflowunits_wrap(int *result) ; 59 | DLLEXPORT ENgetpatternindex_wrap(char * a1, int * result) ; 60 | DLLEXPORT ENgetpatternid_wrap(int a1, char * result) ; 61 | DLLEXPORT ENgetpatternlen_wrap(int a1, int * result) ; 62 | DLLEXPORT ENgetpatternvalue_wrap(int a1, int a2, float *result) ; 63 | DLLEXPORT ENgetqualtype_wrap(int * result1, int * result) ; 64 | DLLEXPORT ENgeterror_wrap(int a1, char * a2, int a3); 65 | DLLEXPORT ENgetnodeindex_wrap(char * result, int *a2) ; 66 | DLLEXPORT ENgetnodeid_wrap(int a1, char * result); 67 | DLLEXPORT ENgetnodetype_wrap(int a1, int * result) ; 68 | DLLEXPORT ENgetnodevalue_wrap(int a1, int a2, float *result) ; 69 | DLLEXPORT ENgetlinkindex_wrap(char * a1, int *result) ; 70 | DLLEXPORT ENgetlinkid_wrap(int a1, char *result) ; 71 | DLLEXPORT ENgetlinktype_wrap(int a1, int *result) ; 72 | DLLEXPORT ENgetlinknodes_wrap(int a1, int * result1, int *result2) ; 73 | DLLEXPORT ENgetlinkvalue_wrap(int a1, int a2, float *result) ; 74 | DLLEXPORT ENgetversion_wrap(int *a1) ; 75 | DLLEXPORT ENsetcontrol_wrap(int a1, int a2, int a3, float a4, int a5, float a6); 76 | DLLEXPORT ENsetnodevalue_wrap(int a1, int a2, float a3); 77 | DLLEXPORT ENsetlinkvalue_wrap(int a1, int a2, float a3); 78 | DLLEXPORT ENaddpattern_wrap(char *a1) ; 79 | DLLEXPORT ENsetpattern_wrap(int a1, float * a2, int a3); 80 | DLLEXPORT ENsetpatternvalue_wrap(int a1, int a2, float a3); 81 | DLLEXPORT ENsettimeparam_wrap(int a1, long a2); 82 | DLLEXPORT ENsetoption_wrap(int a1, float a2); 83 | DLLEXPORT ENsetstatusreport_wrap(int a1); 84 | DLLEXPORT ENsetqualtype_wrap(int a1, char * a2, char * a3, char *a4) ; 85 | DLLEXPORT ENsetemitter_wrap(float a1, float a2); 86 | DLLEXPORT ENgetemitter_wrap(float *a1, float *a2); 87 | 88 | /* Call this function to write a note to the epanet2 report file */ 89 | extern int write_sign(string str); 90 | extern long getcurrenttime(); 91 | 92 | 93 | extern int run_before_ENopen(); 94 | extern int run_before_ENsaveinpfile(); 95 | extern int run_before_ENclose(); 96 | extern int run_before_ENsaveH(); 97 | extern int run_before_ENinitH(); 98 | extern int run_before_ENrunH (); 99 | extern int run_before_ENnextH (); 100 | extern int run_before_ENnextH(); 101 | extern int run_before_ENcloseH(); 102 | extern int run_before_ENsavehydfile(); 103 | extern int run_before_ENusehydfile(); 104 | extern int run_before_ENsolveQ(); 105 | extern int run_before_ENopenQ(); 106 | extern int run_before_ENinitQ(); 107 | extern int run_before_ENrunQ(); 108 | extern int run_before_ENnextQ(); 109 | extern int run_before_ENstepQ(); 110 | extern int run_before_ENcloseQ(); 111 | extern int run_before_ENwriteline(); 112 | extern int run_before_ENreport(); 113 | extern int run_before_ENresetreport(); 114 | extern int run_before_ENsetreport(); 115 | extern int run_before_ENgetcontrol(); 116 | extern int run_before_ENgetcount(); 117 | extern int run_before_ENgetoption(); 118 | extern int run_before_ENgettimeparam(); 119 | extern int run_before_ENgetflowunits(); 120 | extern int run_before_ENgetpatternindex(); 121 | extern int run_before_ENgetpatternid(); 122 | extern int run_before_ENgetpatternlen(); 123 | extern int run_before_ENgetpatternvalue(); 124 | extern int run_before_ENgetqualtype(); 125 | extern int run_before_ENgeterror(); 126 | extern int run_before_ENgetnodeindex(); 127 | extern int run_before_ENgetnodeid(); 128 | extern int run_before_ENgetnodetype(); 129 | extern int run_before_ENgetnodevalue(); 130 | extern int run_before_ENgetlinkindex(); 131 | extern int run_before_ENgetlinkid(); 132 | extern int run_before_ENgetlinktype(); 133 | extern int run_before_ENgetlinknodes(); 134 | extern int run_before_ENgetlinkvalue(); 135 | extern int run_before_ENgetversion(); 136 | extern int run_before_ENsetcontrol(); 137 | extern int run_before_ENsetnodevalue(); 138 | extern int run_before_ENsetlinkvalue(); 139 | extern int run_before_ENaddpattern(); 140 | extern int run_before_ENsetpattern(); 141 | extern int run_before_ENsetpatternvalue(); 142 | extern int run_before_ENsettimeparam(); 143 | extern int run_before_ENsetoption(); 144 | extern int run_before_ENsetstatusreport(); 145 | extern int run_before_ENsetqualtype(); 146 | int run_before_ENopenH(); 147 | int run_before_ENrunH (); 148 | 149 | void getEmitterData(float *eexp_, float *ecup_); 150 | void setEmitterData(float eexp_, float ecup_); 151 | 152 | 153 | #endif -------------------------------------------------------------------------------- /tests/test_EPANetPDD.py: -------------------------------------------------------------------------------- 1 | import math 2 | import os 3 | import unittest 4 | from unittest import expectedFailure 5 | from unittest import skip 6 | 7 | import epanettools 8 | from epanettools.epanettools import Control 9 | from epanettools.epanettools import Controls 10 | from epanettools.epanettools import EPANetSimulation 11 | from epanettools.epanettools import Link 12 | from epanettools.epanettools import Links 13 | from epanettools.epanettools import Network 14 | from epanettools.epanettools import Node 15 | from epanettools.epanettools import Nodes 16 | from epanettools.epanettools import Pattern 17 | from epanettools.epanettools import Patterns 18 | from epanettools.examples import simple 19 | 20 | 21 | class Test1(unittest.TestCase): 22 | 23 | def Error(self, e): 24 | if(e): 25 | s = "Epanet Error: %d : %s" % (e, self.es.ENgeterror(e, 500)[1]) 26 | raise Exception(s) 27 | 28 | def setUp(self): 29 | print("SETUP!") 30 | file = os.path.join(os.path.dirname(simple.__file__), 'Net3.inp') 31 | self.es = EPANetSimulation(file) 32 | 33 | def tearDown(self): 34 | self.es.clean() 35 | print("TEAR DOWN!") 36 | 37 | 38 | @skip 39 | def test_runs_a_simulation_with_pipe_closed_and_get_results_pdd_give_reasonable_results(self): 40 | # now do the same with pipe '247' closed. 41 | ind = self.es.network.links['247'].index 42 | dia = Link.value_type["EN_DIAMETER"] # get the code for EN_STATUS 43 | # use old interface to set diameter to zero 44 | self.Error(self.es.ENsetlinkvalue(ind, dia, 0.1)) # now link diameter is small 45 | file = "1.inp" 46 | ret=self.es.ENsaveinpfile(file) 47 | self.assertEqual(ret,0) 48 | # now create a new object with the new file. 49 | es = EPANetSimulation(file, pdd=True) 50 | es.run() 51 | p = Node.value_type['EN_PRESSURE'] 52 | d = Node.value_type['EN_DEMAND'] 53 | self.assertAlmostEquals(es.network.nodes['215'].results[p][5], -1.3, places=1) 54 | self.assertAlmostEqual(es.network.nodes['215'].results[d][5], 0.0, places=1) 55 | 56 | 57 | def test_runs_a_normal_pressure_simulation_and_get_results_pdd_does_not_change_results(self): 58 | # self.fail("Not yet calling epanet emitter properly") 59 | def mod1(): 60 | p = Node.value_type['EN_PRESSURE'] 61 | self.assertAlmostEqual(self.es.network.nodes['103'].results[p][5], 59.301, places=3) 62 | self.assertAlmostEqual(self.es.network.nodes['125'].results[p][5], 66.051, places=3) 63 | self.assertEqual(self.es.network.time[5], 15213) 64 | self.assertEqual(self.es.network.tsteps[5], 2787) 65 | self.assertEqual(self.es.network.tsteps[6], 3600) 66 | self.assertEqual(len(self.es.network.time), len(self.es.network.nodes[1].results[p])) 67 | 68 | d = Node.value_type['EN_DEMAND'] 69 | h = Node.value_type['EN_HEAD'] 70 | self.assertAlmostEqual(self.es.network.nodes['103'].results[d][5], 101.232, places=3) 71 | self.assertAlmostEqual(self.es.network.nodes['103'].results[h][5], 179.858, places=3) 72 | 73 | def mod2(): 74 | p = Link.value_type['EN_DIAMETER'] 75 | self.assertAlmostEquals( 76 | self.es.network.links[1].results[p][0], 77 | 99.0, 78 | places=1) # index is not important. Diameter is fixed. ! 79 | self.assertAlmostEquals(self.es.network.links['105'].results[p][0], 12.0, places=1) 80 | v = Link.value_type['EN_VELOCITY'] 81 | self.assertAlmostEquals(self.es.network.links[2].results[v][22], 0.025, places=2) 82 | self.assertAlmostEquals(self.es.network.links['111'].results[v][1], 3.23, places=2) 83 | 84 | def mod3(): 85 | p = Node.value_type['EN_PRESSURE'] 86 | self.assertAlmostEqual(self.es.network.nodes['215'].results[p][5], 58.7571, places=3) 87 | self.assertAlmostEqual(self.es.network.nodes['225'].results[p][5], 58.320, places=3) 88 | 89 | d = Node.value_type['EN_DEMAND'] 90 | self.assertAlmostEqual(self.es.network.nodes['215'].results[d][5], 70.064, places=3) 91 | self.assertAlmostEqual(self.es.network.nodes['225'].results[d][5], 17.328, places=3) 92 | 93 | def mod4(): 94 | p = Node.value_type['EN_PRESSURE'] 95 | self.assertAlmostEqual(self.es.network.nodes['215'].results[p][5], 58.7571, places=3) 96 | self.assertAlmostEqual(self.es.network.nodes['225'].results[p][5], 58.320, places=3) 97 | 98 | d = Node.value_type['EN_DEMAND'] 99 | self.assertAlmostEqual(self.es.network.nodes['215'].results[d][5], 70.064, places=3) 100 | self.assertAlmostEqual(self.es.network.nodes['225'].results[d][5], 17.328, places=3) 101 | 102 | self.es.run() 103 | mod1() 104 | mod2() 105 | self.es.runq() 106 | q = Node.value_type['EN_QUALITY'] 107 | self.assertAlmostEqual(self.es.network.nodes['117'].results[q][4], 85.317, places=3) 108 | self.assertAlmostEqual(self.es.network.nodes['117'].results[q][5], 100.0) 109 | e = Link.value_type['EN_ENERGY'] 110 | self.assertAlmostEquals(self.es.network.links['111'].results[e][23], .00685, places=2) 111 | mod1() 112 | mod2() 113 | mod3() 114 | 115 | file = "1.inp" 116 | self.Error(self.es.ENsaveinpfile(file)) 117 | # now create a new object with the new file. 118 | es = EPANetSimulation(file, pdd=True) 119 | es.run() 120 | mod1() 121 | mod2() 122 | mod3() 123 | 124 | def test_ppd_wrapper_error_func(self): 125 | from epanettools.pdd_class_wrapper import Error 126 | with self.assertRaises(Exception) as e: 127 | Error(202) 128 | self.assertEqual(e.exception.args[0], 129 | 'Epanet Error: 202 : Input Error 202: function call contains illegal numeric value.') 130 | 131 | 132 | def clt(fn, tc): 133 | tc.setUp() 134 | fn() 135 | tc.tearDown() 136 | 137 | 138 | def main(): 139 | tc = Test1() 140 | for a in dir(tc): 141 | if (a.startswith('test_')): 142 | # if 143 | # (a.startswith('test_runs_a_simulation_with_pipe_closed_and_get_results_pdd_give_reasonable_results')):#test_')): 144 | b = getattr(tc, a) 145 | if(hasattr(b, '__call__')): 146 | print ("calling %s **********************************" % a) 147 | clt(b, tc) 148 | 149 | 150 | if __name__ == "__main__": 151 | main() 152 | -------------------------------------------------------------------------------- /src/epanettools/examples/simple/Net1.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 1 3 | A simple example of modeling chlorine decay. Both bulk and 4 | wall reactions are included. 5 | 6 | [JUNCTIONS] 7 | ;ID Elev Demand Pattern 8 | 10 710 0 ; 9 | 11 710 150 ; 10 | 12 700 150 ; 11 | 13 695 100 ; 12 | 21 700 150 ; 13 | 22 695 200 ; 14 | 23 690 150 ; 15 | 31 700 100 ; 16 | 32 710 100 ; 17 | 18 | [RESERVOIRS] 19 | ;ID Head Pattern 20 | 9 800 ; 21 | 22 | [TANKS] 23 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 24 | 2 850 120 100 150 50.5 0 ; 25 | 26 | [PIPES] 27 | ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status 28 | 10 10 11 10530 18 100 0 Open ; 29 | 11 11 12 5280 14 100 0 Open ; 30 | 12 12 13 5280 10 100 0 Open ; 31 | 21 21 22 5280 10 100 0 Open ; 32 | 22 22 23 5280 12 100 0 Open ; 33 | 31 31 32 5280 6 100 0 Open ; 34 | 110 2 12 200 18 100 0 Open ; 35 | 111 11 21 5280 10 100 0 Open ; 36 | 112 12 22 5280 12 100 0 Open ; 37 | 113 13 23 5280 8 100 0 Open ; 38 | 121 21 31 5280 8 100 0 Open ; 39 | 122 22 32 5280 6 100 0 Open ; 40 | 41 | [PUMPS] 42 | ;ID Node1 Node2 Parameters 43 | 9 9 10 HEAD 1 ; 44 | 45 | [VALVES] 46 | ;ID Node1 Node2 Diameter Type Setting MinorLoss 47 | 48 | [TAGS] 49 | 50 | [DEMANDS] 51 | ;Junction Demand Pattern Category 52 | 53 | [STATUS] 54 | ;ID Status/Setting 55 | 56 | [PATTERNS] 57 | ;ID Multipliers 58 | ;Demand Pattern 59 | 1 1.0 1.2 1.4 1.6 1.4 1.2 60 | 1 1.0 0.8 0.6 0.4 0.6 0.8 61 | 62 | [CURVES] 63 | ;ID X-Value Y-Value 64 | ;PUMP: Pump Curve for Pump 9 65 | 1 1500 250 66 | 67 | [CONTROLS] 68 | LINK 9 OPEN IF NODE 2 BELOW 110 69 | LINK 9 CLOSED IF NODE 2 ABOVE 140 70 | 71 | 72 | [RULES] 73 | 74 | [ENERGY] 75 | Global Efficiency 75 76 | Global Price 0.0 77 | Demand Charge 0.0 78 | 79 | [EMITTERS] 80 | ;Junction Coefficient 81 | 82 | [QUALITY] 83 | ;Node InitQual 84 | 10 0.5 85 | 11 0.5 86 | 12 0.5 87 | 13 0.5 88 | 21 0.5 89 | 22 0.5 90 | 23 0.5 91 | 31 0.5 92 | 32 0.5 93 | 9 1.0 94 | 2 1.0 95 | 96 | [SOURCES] 97 | ;Node Type Quality Pattern 98 | 99 | [REACTIONS] 100 | ;Type Pipe/Tank Coefficient 101 | 102 | 103 | [REACTIONS] 104 | Order Bulk 1 105 | Order Tank 1 106 | Order Wall 1 107 | Global Bulk -.5 108 | Global Wall -1 109 | Limiting Potential 0.0 110 | Roughness Correlation 0.0 111 | 112 | [MIXING] 113 | ;Tank Model 114 | 115 | [TIMES] 116 | Duration 24:00 117 | Hydraulic Timestep 1:00 118 | Quality Timestep 0:05 119 | Pattern Timestep 2:00 120 | Pattern Start 0:00 121 | Report Timestep 1:00 122 | Report Start 0:00 123 | Start ClockTime 12 am 124 | Statistic None 125 | 126 | [REPORT] 127 | Status Yes 128 | Summary No 129 | Page 0 130 | 131 | [OPTIONS] 132 | Units GPM 133 | Headloss H-W 134 | Specific Gravity 1.0 135 | Viscosity 1.0 136 | Trials 40 137 | Accuracy 0.001 138 | CHECKFREQ 2 139 | MAXCHECK 10 140 | DAMPLIMIT 0 141 | Unbalanced Continue 10 142 | Pattern 1 143 | Demand Multiplier 1.0 144 | Emitter Exponent 0.5 145 | Quality Chlorine mg/L 146 | Diffusivity 1.0 147 | Tolerance 0.01 148 | 149 | [COORDINATES] 150 | ;Node X-Coord Y-Coord 151 | 10 20.00 70.00 152 | 11 30.00 70.00 153 | 12 50.00 70.00 154 | 13 70.00 70.00 155 | 21 30.00 40.00 156 | 22 50.00 40.00 157 | 23 70.00 40.00 158 | 31 30.00 10.00 159 | 32 50.00 10.00 160 | 9 10.00 70.00 161 | 2 50.00 90.00 162 | 163 | [VERTICES] 164 | ;Link X-Coord Y-Coord 165 | 166 | [LABELS] 167 | ;X-Coord Y-Coord Label & Anchor Node 168 | 6.99 73.63 "Source" 169 | 13.48 68.13 "Pump" 170 | 43.85 91.21 "Tank" 171 | 172 | [BACKDROP] 173 | DIMENSIONS 7.00 6.00 73.00 94.00 174 | UNITS None 175 | FILE 176 | OFFSET 0.00 0.00 177 | 178 | [END] 179 | -------------------------------------------------------------------------------- /src/epanettools/epanet/epanet2.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** EPANET2.H 3 | ** 4 | ** C/C++ header file for EPANET Programmers Toolkit 5 | ** 6 | ** Last updated on 2/14/08 (2.00.12) 7 | */ 8 | 9 | #ifndef EPANET2_H 10 | #define EPANET2_H 11 | 12 | // --- Define the EPANET toolkit constants 13 | 14 | #define EN_ELEVATION 0 /* Node parameters */ 15 | #define EN_BASEDEMAND 1 16 | #define EN_PATTERN 2 17 | #define EN_EMITTER 3 18 | #define EN_INITQUAL 4 19 | #define EN_SOURCEQUAL 5 20 | #define EN_SOURCEPAT 6 21 | #define EN_SOURCETYPE 7 22 | #define EN_TANKLEVEL 8 23 | #define EN_DEMAND 9 24 | #define EN_HEAD 10 25 | #define EN_PRESSURE 11 26 | #define EN_QUALITY 12 27 | #define EN_SOURCEMASS 13 28 | #define EN_INITVOLUME 14 29 | #define EN_MIXMODEL 15 30 | #define EN_MIXZONEVOL 16 31 | 32 | #define EN_TANKDIAM 17 33 | #define EN_MINVOLUME 18 34 | #define EN_VOLCURVE 19 35 | #define EN_MINLEVEL 20 36 | #define EN_MAXLEVEL 21 37 | #define EN_MIXFRACTION 22 38 | #define EN_TANK_KBULK 23 39 | 40 | #define EN_DIAMETER 0 /* Link parameters */ 41 | #define EN_LENGTH 1 42 | #define EN_ROUGHNESS 2 43 | #define EN_MINORLOSS 3 44 | #define EN_INITSTATUS 4 45 | #define EN_INITSETTING 5 46 | #define EN_KBULK 6 47 | #define EN_KWALL 7 48 | #define EN_FLOW 8 49 | #define EN_VELOCITY 9 50 | #define EN_HEADLOSS 10 51 | #define EN_STATUS 11 52 | #define EN_SETTING 12 53 | #define EN_ENERGY 13 54 | 55 | #define EN_DURATION 0 /* Time parameters */ 56 | #define EN_HYDSTEP 1 57 | #define EN_QUALSTEP 2 58 | #define EN_PATTERNSTEP 3 59 | #define EN_PATTERNSTART 4 60 | #define EN_REPORTSTEP 5 61 | #define EN_REPORTSTART 6 62 | #define EN_RULESTEP 7 63 | #define EN_STATISTIC 8 64 | #define EN_PERIODS 9 65 | 66 | #define EN_NODECOUNT 0 /* Component counts */ 67 | #define EN_TANKCOUNT 1 68 | #define EN_LINKCOUNT 2 69 | #define EN_PATCOUNT 3 70 | #define EN_CURVECOUNT 4 71 | #define EN_CONTROLCOUNT 5 72 | 73 | #define EN_JUNCTION 0 /* Node types */ 74 | #define EN_RESERVOIR 1 75 | #define EN_TANK 2 76 | 77 | #define EN_CVPIPE 0 /* Link types */ 78 | #define EN_PIPE 1 79 | #define EN_PUMP 2 80 | #define EN_PRV 3 81 | #define EN_PSV 4 82 | #define EN_PBV 5 83 | #define EN_FCV 6 84 | #define EN_TCV 7 85 | #define EN_GPV 8 86 | 87 | #define EN_NONE 0 /* Quality analysis types */ 88 | #define EN_CHEM 1 89 | #define EN_AGE 2 90 | #define EN_TRACE 3 91 | 92 | #define EN_CONCEN 0 /* Source quality types */ 93 | #define EN_MASS 1 94 | #define EN_SETPOINT 2 95 | #define EN_FLOWPACED 3 96 | 97 | #define EN_CFS 0 /* Flow units types */ 98 | #define EN_GPM 1 99 | #define EN_MGD 2 100 | #define EN_IMGD 3 101 | #define EN_AFD 4 102 | #define EN_LPS 5 103 | #define EN_LPM 6 104 | #define EN_MLD 7 105 | #define EN_CMH 8 106 | #define EN_CMD 9 107 | 108 | #define EN_TRIALS 0 /* Misc. options */ 109 | #define EN_ACCURACY 1 110 | #define EN_TOLERANCE 2 111 | #define EN_EMITEXPON 3 112 | #define EN_DEMANDMULT 4 113 | 114 | #define EN_LOWLEVEL 0 /* Control types */ 115 | #define EN_HILEVEL 1 116 | #define EN_TIMER 2 117 | #define EN_TIMEOFDAY 3 118 | 119 | #define EN_AVERAGE 1 /* Time statistic types. */ 120 | #define EN_MINIMUM 2 121 | #define EN_MAXIMUM 3 122 | #define EN_RANGE 4 123 | 124 | #define EN_MIX1 0 /* Tank mixing models */ 125 | #define EN_MIX2 1 126 | #define EN_FIFO 2 127 | #define EN_LIFO 3 128 | 129 | #define EN_NOSAVE 0 /* Save-results-to-file flag */ 130 | #define EN_SAVE 1 131 | #define EN_INITFLOW 10 /* Re-initialize flow flag */ 132 | 133 | 134 | 135 | // --- define WINDOWS 136 | 137 | #undef WINDOWS 138 | #ifdef _WIN32 139 | #define WINDOWS 140 | #endif 141 | #ifdef __WIN32__ 142 | #define WINDOWS 143 | #endif 144 | 145 | //#undef WINDOWS 146 | //#undef __WIN32__ 147 | 148 | // --- define DLLEXPORT 149 | 150 | #ifdef WINDOWS 151 | #ifdef __cplusplus 152 | #define DLLEXPORT extern "C" int __declspec(dllexport) 153 | //__stdcall 154 | #else 155 | #define DLLEXPORT int __declspec(dllexport) 156 | //__stdcall 157 | #endif 158 | #else 159 | #ifdef __cplusplus 160 | #define DLLEXPORT extern "C" int 161 | #else 162 | #define DLLEXPORT extern int 163 | #endif 164 | #endif 165 | 166 | 167 | // --- declare the EPANET toolkit functions 168 | DLLEXPORT ENepanet(char *, char *, char *, void (*) (char *)); 169 | DLLEXPORT ENopen(char *, char *, char *); 170 | DLLEXPORT ENsaveinpfile(char *); 171 | DLLEXPORT ENclose(void); 172 | 173 | DLLEXPORT ENsolveH(void); 174 | DLLEXPORT ENsaveH(void); 175 | DLLEXPORT ENopenH(void); 176 | DLLEXPORT ENinitH(int); 177 | DLLEXPORT ENrunH(long * result ); 178 | DLLEXPORT ENnextH(long * result ); 179 | DLLEXPORT ENcloseH(void); 180 | DLLEXPORT ENsavehydfile(char * ); 181 | DLLEXPORT ENusehydfile(char * ); 182 | 183 | DLLEXPORT ENsolveQ(void); 184 | DLLEXPORT ENopenQ(void); 185 | DLLEXPORT ENinitQ(int); 186 | DLLEXPORT ENrunQ(long * result ); 187 | DLLEXPORT ENnextQ(long * result ); 188 | DLLEXPORT ENstepQ(long * result ); 189 | DLLEXPORT ENcloseQ(void); 190 | 191 | DLLEXPORT ENwriteline(char * ); 192 | DLLEXPORT ENreport(void); 193 | DLLEXPORT ENresetreport(void); 194 | DLLEXPORT ENsetreport(char * ); 195 | 196 | DLLEXPORT ENgetcontrol(int, int * ci1, int * ci2, float * c1, 197 | int * ci3, float * c2 ); 198 | DLLEXPORT ENgetcount(int, int * result); 199 | DLLEXPORT ENgetoption(int, float * result ); 200 | DLLEXPORT ENgettimeparam(int, long * result ); 201 | DLLEXPORT ENgetflowunits(int * result ); 202 | DLLEXPORT ENgetpatternindex(char *, int * result ); 203 | DLLEXPORT ENgetpatternid(int, char * result ); 204 | DLLEXPORT ENgetpatternlen(int, int * result ); 205 | DLLEXPORT ENgetpatternvalue(int, int, float * result ); 206 | DLLEXPORT ENgetqualtype(int * result1, int * result ); 207 | DLLEXPORT ENgeterror(int, char * result, int); 208 | 209 | DLLEXPORT ENgetnodeindex(char *, int * result ); 210 | DLLEXPORT ENgetnodeid(int, char * result ); 211 | DLLEXPORT ENgetnodetype(int, int * result ); 212 | DLLEXPORT ENgetnodevalue(int, int, float * result ); 213 | 214 | DLLEXPORT ENgetlinkindex(char *, int * result ); 215 | DLLEXPORT ENgetlinkid(int, char * result ); 216 | DLLEXPORT ENgetlinktype(int, int * result ); 217 | DLLEXPORT ENgetlinknodes(int, int * result1, int * result2 ); 218 | DLLEXPORT ENgetlinkvalue(int, int, float * result ); 219 | 220 | DLLEXPORT ENgetversion(int * result ); 221 | 222 | DLLEXPORT ENsetcontrol(int, int, int, float, int, float); 223 | DLLEXPORT ENsetnodevalue(int, int, float); 224 | DLLEXPORT ENsetlinkvalue(int, int, float); 225 | DLLEXPORT ENaddpattern(char * ); 226 | DLLEXPORT ENsetpattern(int, float * floatarray, int nfloats); 227 | DLLEXPORT ENsetpatternvalue(int, int, float); 228 | DLLEXPORT ENsettimeparam(int, long); 229 | DLLEXPORT ENsetoption(int, float); 230 | DLLEXPORT ENsetstatusreport(int); 231 | DLLEXPORT ENsetqualtype(int, char *, char *, char * ); 232 | 233 | 234 | #endif 235 | -------------------------------------------------------------------------------- /src/epanettools/epanet/toolkit.h: -------------------------------------------------------------------------------- 1 | /* 2 | ******************************************************************* 3 | 4 | TOOLKIT.H - Prototypes for EPANET Functions Exported to DLL Toolkit 5 | 6 | VERSION: 2.00 7 | DATE: 5/8/00 8 | 10/25/00 9 | 3/1/01 10 | 8/15/07 (2.00.11) 11 | 2/14/08 (2.00.12) 12 | AUTHOR: L. Rossman 13 | US EPA - NRMRL 14 | 15 | ******************************************************************* 16 | */ 17 | 18 | // --- Define DLLEXPORT 19 | 20 | #ifdef DLL 21 | #ifdef __cplusplus 22 | #define DLLEXPORT extern "C" __declspec(dllexport) __stdcall 23 | #else 24 | #define DLLEXPORT __declspec(dllexport) __stdcall 25 | #endif 26 | #else 27 | #ifdef __cplusplus 28 | #define DLLEXPORT extern "C" 29 | #else 30 | #define DLLEXPORT 31 | #endif 32 | #endif 33 | 34 | // --- Define the EPANET toolkit constants 35 | 36 | #define EN_ELEVATION 0 /* Node parameters */ 37 | #define EN_BASEDEMAND 1 38 | #define EN_PATTERN 2 39 | #define EN_EMITTER 3 40 | #define EN_INITQUAL 4 41 | #define EN_SOURCEQUAL 5 42 | #define EN_SOURCEPAT 6 43 | #define EN_SOURCETYPE 7 44 | #define EN_TANKLEVEL 8 45 | #define EN_DEMAND 9 46 | #define EN_HEAD 10 47 | #define EN_PRESSURE 11 48 | #define EN_QUALITY 12 49 | #define EN_SOURCEMASS 13 50 | #define EN_INITVOLUME 14 51 | #define EN_MIXMODEL 15 52 | #define EN_MIXZONEVOL 16 53 | 54 | #define EN_TANKDIAM 17 55 | #define EN_MINVOLUME 18 56 | #define EN_VOLCURVE 19 57 | #define EN_MINLEVEL 20 58 | #define EN_MAXLEVEL 21 59 | #define EN_MIXFRACTION 22 60 | #define EN_TANK_KBULK 23 61 | 62 | #define EN_DIAMETER 0 /* Link parameters */ 63 | #define EN_LENGTH 1 64 | #define EN_ROUGHNESS 2 65 | #define EN_MINORLOSS 3 66 | #define EN_INITSTATUS 4 67 | #define EN_INITSETTING 5 68 | #define EN_KBULK 6 69 | #define EN_KWALL 7 70 | #define EN_FLOW 8 71 | #define EN_VELOCITY 9 72 | #define EN_HEADLOSS 10 73 | #define EN_STATUS 11 74 | #define EN_SETTING 12 75 | #define EN_ENERGY 13 76 | 77 | #define EN_DURATION 0 /* Time parameters */ 78 | #define EN_HYDSTEP 1 79 | #define EN_QUALSTEP 2 80 | #define EN_PATTERNSTEP 3 81 | #define EN_PATTERNSTART 4 82 | #define EN_REPORTSTEP 5 83 | #define EN_REPORTSTART 6 84 | #define EN_RULESTEP 7 85 | #define EN_STATISTIC 8 86 | #define EN_PERIODS 9 87 | 88 | #define EN_NODECOUNT 0 /* Component counts */ 89 | #define EN_TANKCOUNT 1 90 | #define EN_LINKCOUNT 2 91 | #define EN_PATCOUNT 3 92 | #define EN_CURVECOUNT 4 93 | #define EN_CONTROLCOUNT 5 94 | 95 | #define EN_JUNCTION 0 /* Node types */ 96 | #define EN_RESERVOIR 1 97 | #define EN_TANK 2 98 | 99 | #define EN_CVPIPE 0 /* Link types. */ 100 | #define EN_PIPE 1 /* See LinkType in TYPES.H */ 101 | #define EN_PUMP 2 102 | #define EN_PRV 3 103 | #define EN_PSV 4 104 | #define EN_PBV 5 105 | #define EN_FCV 6 106 | #define EN_TCV 7 107 | #define EN_GPV 8 108 | 109 | #define EN_NONE 0 /* Quality analysis types. */ 110 | #define EN_CHEM 1 /* See QualType in TYPES.H */ 111 | #define EN_AGE 2 112 | #define EN_TRACE 3 113 | 114 | #define EN_CONCEN 0 /* Source quality types. */ 115 | #define EN_MASS 1 /* See SourceType in TYPES.H. */ 116 | #define EN_SETPOINT 2 117 | #define EN_FLOWPACED 3 118 | 119 | #define EN_CFS 0 /* Flow units types. */ 120 | #define EN_GPM 1 /* See FlowUnitsType */ 121 | #define EN_MGD 2 /* in TYPES.H. */ 122 | #define EN_IMGD 3 123 | #define EN_AFD 4 124 | #define EN_LPS 5 125 | #define EN_LPM 6 126 | #define EN_MLD 7 127 | #define EN_CMH 8 128 | #define EN_CMD 9 129 | 130 | #define EN_TRIALS 0 /* Misc. options */ 131 | #define EN_ACCURACY 1 132 | #define EN_TOLERANCE 2 133 | #define EN_EMITEXPON 3 134 | #define EN_DEMANDMULT 4 135 | 136 | #define EN_LOWLEVEL 0 /* Control types. */ 137 | #define EN_HILEVEL 1 /* See ControlType */ 138 | #define EN_TIMER 2 /* in TYPES.H. */ 139 | #define EN_TIMEOFDAY 3 140 | 141 | #define EN_AVERAGE 1 /* Time statistic types. */ 142 | #define EN_MINIMUM 2 /* See TstatType in TYPES.H */ 143 | #define EN_MAXIMUM 3 144 | #define EN_RANGE 4 145 | 146 | #define EN_MIX1 0 /* Tank mixing models */ 147 | #define EN_MIX2 1 148 | #define EN_FIFO 2 149 | #define EN_LIFO 3 150 | 151 | #define EN_NOSAVE 0 /* Save-results-to-file flag */ 152 | #define EN_SAVE 1 153 | 154 | #define EN_INITFLOW 10 /* Re-initialize flows flag */ 155 | 156 | 157 | // --- Declare the EPANET toolkit functions 158 | 159 | extern int ENepanet(char *, char *, char *, void (*) (char *)); 160 | 161 | extern int ENopen(char *, char *, char *); 162 | extern int ENsaveinpfile(char *); 163 | extern int ENclose(void); 164 | 165 | extern int ENsolveH(void); 166 | extern int ENsaveH(void); 167 | extern int ENopenH(void); 168 | extern int ENinitH(int); 169 | extern int ENrunH(long *); 170 | extern int ENnextH(long *); 171 | extern int ENcloseH(void); 172 | extern int ENsavehydfile(char *); 173 | extern int ENusehydfile(char *); 174 | 175 | extern int ENsolveQ(void); 176 | extern int ENopenQ(void); 177 | extern int ENinitQ(int); 178 | extern int ENrunQ(long *); 179 | extern int ENnextQ(long *); 180 | extern int ENstepQ(long *); 181 | extern int ENcloseQ(void); 182 | 183 | extern int ENwriteline(char *); 184 | extern int ENreport(void); 185 | extern int ENresetreport(void); 186 | extern int ENsetreport(char *); 187 | 188 | extern int ENgetcontrol(int, int *, int *, float *, 189 | int *, float *); 190 | extern int ENgetcount(int, int *); 191 | extern int ENgetoption(int, float *); 192 | extern int ENgettimeparam(int, long *); 193 | extern int ENgetflowunits(int *); 194 | extern int ENgetpatternindex(char *, int *); 195 | extern int ENgetpatternid(int, char *); 196 | extern int ENgetpatternlen(int, int *); 197 | extern int ENgetpatternvalue(int, int, float *); 198 | extern int ENgetqualtype(int *, int *); 199 | extern int ENgeterror(int, char *, int); 200 | 201 | extern int ENgetnodeindex(char *, int *); 202 | extern int ENgetnodeid(int, char *); 203 | extern int ENgetnodetype(int, int *); 204 | extern int ENgetnodevalue(int, int, float *); 205 | 206 | extern int ENgetlinkindex(char *, int *); 207 | extern int ENgetlinkid(int, char *); 208 | extern int ENgetlinktype(int, int *); 209 | extern int ENgetlinknodes(int, int *, int *); 210 | extern int ENgetlinkvalue(int, int, float *); 211 | 212 | extern int ENgetversion(int *); 213 | 214 | extern int ENsetcontrol(int, int, int, float, int, float); 215 | extern int ENsetnodevalue(int, int, float); 216 | extern int ENsetlinkvalue(int, int, float); 217 | extern int ENaddpattern(char *); 218 | extern int ENsetpattern(int, float *, int); 219 | extern int ENsetpatternvalue(int, int, float); 220 | extern int ENsettimeparam(int, long); 221 | extern int ENsetoption(int, float); 222 | extern int ENsetstatusreport(int); 223 | extern int ENsetqualtype(int, char *, char *, char *); 224 | 225 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 -*- 3 | from __future__ import absolute_import 4 | from __future__ import print_function 5 | 6 | import io 7 | # import sys 8 | import os 9 | import re 10 | from glob import glob 11 | # from os.path import relpath 12 | from os.path import basename 13 | from os.path import dirname 14 | from os.path import join 15 | from os.path import splitext 16 | 17 | # from setuptools import find_packages 18 | from setuptools import Extension 19 | from setuptools import setup 20 | from setuptools.command.test import test as TestCommand 21 | 22 | # in windows use microsoft compilers 23 | if os.name == 'nt': 24 | 25 | compilerargs = ['/DDLL#1', ] 26 | linkerargs = [] 27 | else: 28 | compilerargs = ['-Wno-format','-O0'] 29 | linkerargs = [] 30 | 31 | 32 | 33 | 34 | 35 | 36 | # from setuptools.command.build_ext import build_ext 37 | # from collections import defaultdict 38 | 39 | class Tox(TestCommand): 40 | user_options = [('tox-args=', 'a', "Arguments to pass to tox")] 41 | 42 | def initialize_options(self): 43 | TestCommand.initialize_options(self) 44 | self.tox_args = None 45 | 46 | def finalize_options(self): 47 | TestCommand.finalize_options(self) 48 | self.test_args = [] 49 | self.test_suite = True 50 | 51 | def run_tests(self): 52 | # import here, cause outside the eggs aren't loaded 53 | import tox 54 | import shlex 55 | args = self.tox_args 56 | if args: 57 | args = shlex.split(self.tox_args) 58 | tox.cmdline(args=args) 59 | 60 | 61 | def read(*names, **kwargs): 62 | return io.open( 63 | join(dirname(__file__), *names), 64 | encoding=kwargs.get('encoding', 'utf8') 65 | ).read() 66 | 67 | 68 | # Enable code coverage for C code: we can't use CFLAGS=-coverage in tox.ini, since that may mess with compiling 69 | # dependencies (e.g. numpy). Therefore we set SETUPPY_CFLAGS=-coverage in tox.ini and copy it to CFLAGS here (after 70 | # deps have been safely installed). 71 | if 'TOXENV' in os.environ and 'SETUPPY_CFLAGS' in os.environ: 72 | os.environ['CFLAGS'] = os.environ['SETUPPY_CFLAGS'] 73 | 74 | sources = [ 75 | "src" + os.sep + "epanettools" + os.sep + "epanet" + os.sep + x for x in ["epanet.c", 76 | "hash.c", 77 | "hydraul.c", 78 | "inpfile.c", 79 | "input1.c", 80 | "input2.c", 81 | "input3.c", 82 | "mempool.c", 83 | "output.c", 84 | "quality.c", 85 | "report.c", 86 | "rules.c", 87 | "smatrix.c" 88 | ]] 89 | sources.append("src" + os.sep + "epanettools" + os.sep + "epanet2_wrap.c") 90 | 91 | # 25-Aug-2016 - append emitter modification files 92 | sources = sources + list( 93 | "src" + os.sep + "epanettools" + os.sep + 94 | "pdd" + os.sep + x for x in ["emitter_analysis.cpp", 95 | "mods.cpp", "wrap.cpp", ]) 96 | sources.append("src" + os.sep + "epanettools" + os.sep + "patch.c") 97 | sources.append("src" + os.sep + "epanettools" + os.sep + "pdd_wrap.cxx") 98 | # ^^^^^ NOTE: keep pdd_wrap.cxx as last element in sources 99 | # - we remove that below using the fact that it is the last element 100 | # 12-Nov-2016 - append adf calculation files 101 | 102 | sources2 = sources[:-1] + list( 103 | "src" + os.sep + "epanettools" + os.sep + "adf" + os.sep + x for x in ["callepanet.cc", 104 | ]) 105 | 106 | sources2.append("src" + os.sep + "epanettools" + os.sep + "adf_wrap.cxx") 107 | 108 | 109 | 110 | 111 | 112 | setup( 113 | name='EPANETTOOLS', 114 | version='1.0.0', 115 | license='GPLv3+', 116 | description='Epanet 2.0 Python calling interface', 117 | long_description='%s\n%s' % ( 118 | re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub( 119 | '', read('README.rst')), 120 | re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')) 121 | ), 122 | author='Assela Pathirana', 123 | author_email='assela@pathirana.net', 124 | url='https://github.com/asselapathirana/epanettools', 125 | packages=["epanettools"], 126 | include_dirs=[], 127 | package_dir={'': 'src'}, 128 | py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')], 129 | include_package_data=True, 130 | zip_safe=False, 131 | classifiers=[ 132 | # complete classifier list: 133 | # http://pypi.python.org/pypi?%3Aaction=list_classifiers 134 | 'Development Status :: 5 - Production/Stable', 135 | 'Intended Audience :: Developers', 136 | 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) ', 137 | 'Operating System :: Unix', 138 | 'Operating System :: POSIX', 139 | 'Operating System :: Microsoft :: Windows', 140 | 'Programming Language :: Python', 141 | 'Programming Language :: Python :: 2.7', 142 | 'Programming Language :: Python :: 3', 143 | 'Programming Language :: Python :: 3.3', 144 | 'Programming Language :: Python :: 3.4', 145 | 'Programming Language :: Python :: 3.5', 146 | 'Programming Language :: Python :: Implementation :: CPython', 147 | 'Programming Language :: Python :: Implementation :: PyPy', 148 | # uncomment if you test on these interpreters: 149 | # 'Programming Language :: Python :: Implementation :: IronPython', 150 | # 'Programming Language :: Python :: Implementation :: Jython', 151 | # 'Programming Language :: Python :: Implementation :: Stackless', 152 | 'Topic :: Utilities', 153 | ], 154 | keywords=[ 155 | # eg: 'keyword1', 'keyword2', 'keyword3', 156 | ], 157 | install_requires=[ 158 | # eg: 'aspectlib==1.1.1', 'six>=1.7', 159 | ], 160 | extras_require={ 161 | # eg: 162 | # 'rst': ['docutils>=0.11'], 163 | # ':python_version=="2.6"': ['argparse'], 164 | }, 165 | entry_points={ 166 | 'console_scripts': [ 167 | 'epanettools = epanettools.cli:main', 168 | ] 169 | }, 170 | ext_modules=[ 171 | Extension('_epanet2', 172 | sources=sources, 173 | extra_compile_args=compilerargs, 174 | extra_link_args=linkerargs, 175 | include_dirs=[ 176 | "src/epanettools/adf", "src/epanettools/epanet", "src/epanettools/pdd"] 177 | ), 178 | Extension('_pdd', 179 | sources=sources, 180 | extra_compile_args=compilerargs, 181 | extra_link_args=linkerargs, 182 | include_dirs=[ 183 | "src/epanettools/adf", "src/epanettools/epanet", "src/epanettools/pdd"] 184 | ), 185 | Extension('_adf', 186 | sources=sources2, 187 | extra_compile_args=compilerargs, 188 | extra_link_args=linkerargs, 189 | include_dirs=[ 190 | "src/epanettools/adf", "src/epanettools/epanet", "src/epanettools/pdd"] 191 | ) 192 | 193 | ], 194 | tests_require=['tox'], 195 | ) 196 | -------------------------------------------------------------------------------- /src/epanettools/pdd/wrap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "wrapper.h" 7 | #include 8 | static bool usehydfile=false; 9 | static long currenttime=-9999; 10 | using namespace std; 11 | 12 | extern long getcurrenttime (){ 13 | return currenttime; 14 | } 15 | 16 | void writecon (char *s) 17 | /*---------------------------------------------------------------- 18 | ** Input: text string 19 | ** Output: none 20 | ** Purpose: writes string of characters to console 21 | **---------------------------------------------------------------- 22 | */ 23 | { 24 | #ifdef CLE // (2.00.11 - LR) 25 | fprintf (stdout,s); 26 | fflush (stdout); 27 | #endif 28 | } 29 | 30 | /* Write a signature to the report file, so that the user knows this is not the original epanet */ 31 | extern int write_sign (string str){ 32 | int ret1=0; 33 | string s= ("** Note: "+str+" **\n").c_str (); 34 | char * m; 35 | m = new char[s.length () + 1]; 36 | strcpy (m, s.c_str ()); 37 | ret1+=ENwriteline (m); 38 | 39 | return ret1; 40 | 41 | } 42 | 43 | DLLEXPORT ENsetemitter_wrap(float a1, float a2){ 44 | setEmitterData(a1,a2); 45 | return 1; 46 | } 47 | DLLEXPORT ENgetemitter_wrap(float* a1, float* a2){ 48 | getEmitterData(a1,a2); 49 | return 1; 50 | 51 | } 52 | 53 | DLLEXPORT ENepanet_wrap (char * f1, char * f2, char * f3, void (*pviewprog) (char *)){ 54 | write_sign ("ENepanet is not implemented in this custom dll"); 55 | writecon ("This function is not implimented!! "); 56 | return (WRAPPER_ERROR_NOT_IMPLEMENTED); 57 | } 58 | 59 | DLLEXPORT ENopen_wrap (char * a1, char * a2, char * a3){ 60 | usehydfile=false; // don't try to use old hydraulics files. 61 | write_sign ("This is a custom epanet2.dll"); 62 | run_before_ENopen(); 63 | return ENopen (a1,a2,a3); 64 | } 65 | 66 | DLLEXPORT ENsaveinpfile_wrap (char *a1){ 67 | run_before_ENsaveinpfile(); 68 | return ENsaveinpfile ( a1); 69 | } 70 | 71 | DLLEXPORT ENclose_wrap (void){ 72 | run_before_ENclose(); 73 | write_sign(" This was a custom epanet2 run!"); 74 | return ENclose (); 75 | } 76 | 77 | 78 | 79 | DLLEXPORT ENsolveH_wrap (void){ 80 | write_sign ("ENsolveH is not implemented in this custom dll"); 81 | writecon ("This function is not implimented!! "); 82 | return (WRAPPER_ERROR_NOT_IMPLEMENTED); 83 | } 84 | 85 | DLLEXPORT ENsaveH_wrap (void){ 86 | run_before_ENsaveH(); 87 | return ENsaveH (); 88 | } 89 | 90 | DLLEXPORT ENopenH_wrap (void){ 91 | int ret1=ENwriteline("================================================================================"); 92 | ret1=ENwriteline ("===== USING A MODIFIED EPANET, Assela Pathirana, a.pathirana@unesco-ihe.org ===="); 93 | ret1=ENwriteline ("===== Pay attention to \"Note:\" statements in the report below, ===="); 94 | ret1=ENwriteline ("===== particularly the parts between and tags. ===="); 95 | ret1=ENwriteline ("================================================================================"); 96 | run_before_ENopenH(); 97 | int ret=ENopenH (); 98 | if (ret==0){ 99 | currenttime=0; 100 | } 101 | return ret; 102 | } 103 | 104 | DLLEXPORT ENinitH_wrap (int a1){ 105 | run_before_ENinitH(); 106 | return ENinitH (a1); 107 | } 108 | 109 | /* this is the function the interface use to run hydraulics */ 110 | DLLEXPORT ENrunH_wrap (long *a1){ 111 | int ret=run_before_ENrunH (); 112 | int ret1=ENrunH (a1); 113 | currenttime= (*a1); 114 | return ret1==0?ret:ret1; 115 | } 116 | 117 | DLLEXPORT ENnextH_wrap (long *a1){ 118 | run_before_ENnextH(); 119 | return ENnextH (a1); 120 | } 121 | 122 | DLLEXPORT ENcloseH_wrap (void){ 123 | run_before_ENcloseH(); 124 | return ENcloseH (); 125 | } 126 | 127 | DLLEXPORT ENsavehydfile_wrap (char *a1){ 128 | run_before_ENsavehydfile(); 129 | return ENsavehydfile (a1); 130 | } 131 | 132 | DLLEXPORT ENusehydfile_wrap (char *a1){ 133 | usehydfile=true; 134 | run_before_ENusehydfile(); 135 | return ENusehydfile (a1); 136 | } 137 | 138 | DLLEXPORT ENsolveQ_wrap (void){ 139 | run_before_ENsolveQ(); 140 | return ENsolveQ (); 141 | } 142 | 143 | DLLEXPORT ENopenQ_wrap (void){ 144 | run_before_ENopenQ(); 145 | return ENopenQ (); 146 | } 147 | 148 | DLLEXPORT ENinitQ_wrap (int a1){ 149 | run_before_ENinitQ(); 150 | return ENinitQ (a1); 151 | } 152 | 153 | DLLEXPORT ENrunQ_wrap (long *a1){ 154 | run_before_ENrunQ(); 155 | return ENrunQ (a1); 156 | } 157 | 158 | DLLEXPORT ENnextQ_wrap (long *a1) { 159 | run_before_ENnextQ(); 160 | return ENnextQ (a1); 161 | } 162 | 163 | DLLEXPORT ENstepQ_wrap (long *a1) { 164 | run_before_ENstepQ(); 165 | return ENstepQ (a1); 166 | } 167 | 168 | DLLEXPORT ENcloseQ_wrap (void){ 169 | run_before_ENcloseQ(); 170 | return ENcloseQ (); 171 | } 172 | 173 | 174 | DLLEXPORT ENwriteline_wrap (char *a1) { 175 | run_before_ENwriteline(); 176 | return ENwriteline (a1); 177 | } 178 | 179 | DLLEXPORT ENreport_wrap (void){ 180 | run_before_ENreport(); 181 | return ENreport (); 182 | } 183 | 184 | DLLEXPORT ENresetreport_wrap (void){ 185 | run_before_ENresetreport(); 186 | return ENresetreport (); 187 | } 188 | 189 | DLLEXPORT ENsetreport_wrap (char *a1) { 190 | run_before_ENsetreport(); 191 | return ENsetreport (a1); 192 | } 193 | 194 | 195 | DLLEXPORT ENgetcontrol_wrap (int a1, int * a2, int * a3, float * a4, int* a5, float * a6) { 196 | run_before_ENgetcontrol(); 197 | return ENgetcontrol (a1, a2, a3, a4, a5, a6); 198 | } 199 | 200 | 201 | DLLEXPORT ENgetcount_wrap (int a1, int *a2) { 202 | run_before_ENgetcount(); 203 | return ENgetcount (a1, a2); 204 | } 205 | 206 | DLLEXPORT ENgetoption_wrap (int a1, float *a2) { 207 | run_before_ENgetoption(); 208 | return ENgetoption (a1, a2); 209 | } 210 | 211 | DLLEXPORT ENgettimeparam_wrap (int a1, long *a2) { 212 | run_before_ENgettimeparam(); 213 | return ENgettimeparam (a1, a2); 214 | } 215 | 216 | DLLEXPORT ENgetflowunits_wrap (int *a1) { 217 | run_before_ENgetflowunits(); 218 | return ENgetflowunits (a1); 219 | } 220 | 221 | DLLEXPORT ENgetpatternindex_wrap (char * a1, int *a2) { 222 | run_before_ENgetpatternindex(); 223 | return ENgetpatternindex (a1, a2); 224 | } 225 | 226 | DLLEXPORT ENgetpatternid_wrap (int a1, char *a2) { 227 | run_before_ENgetpatternid(); 228 | return ENgetpatternid (a1, a2); 229 | } 230 | 231 | DLLEXPORT ENgetpatternlen_wrap (int a1, int *a2) { 232 | run_before_ENgetpatternlen(); 233 | return ENgetpatternlen (a1, a2); 234 | } 235 | 236 | DLLEXPORT ENgetpatternvalue_wrap (int a1, int a2, float *a3) { 237 | run_before_ENgetpatternvalue(); 238 | return ENgetpatternvalue (a1, a2, a3); 239 | } 240 | 241 | DLLEXPORT ENgetqualtype_wrap (int * a1, int *a2) { 242 | run_before_ENgetqualtype(); 243 | return ENgetqualtype (a1,a2); 244 | } 245 | 246 | DLLEXPORT ENgeterror_wrap (int a1, char * a2, int a3){ 247 | run_before_ENgeterror(); 248 | return ENgeterror (a1,a2, a3); 249 | } 250 | 251 | 252 | DLLEXPORT ENgetnodeindex_wrap (char * a1, int *a2) { 253 | run_before_ENgetnodeindex(); 254 | return ENgetnodeindex (a1, a2); 255 | } 256 | 257 | DLLEXPORT ENgetnodeid_wrap (int a1, char *a2) { 258 | run_before_ENgetnodeid(); 259 | return ENgetnodeid (a1, a2); 260 | } 261 | 262 | DLLEXPORT ENgetnodetype_wrap (int a1, int *a2) { 263 | run_before_ENgetnodetype(); 264 | return ENgetnodetype (a1, a2); 265 | } 266 | 267 | DLLEXPORT ENgetnodevalue_wrap (int a1, int a2, float *a3) { 268 | run_before_ENgetnodevalue(); 269 | return ENgetnodevalue (a1,a2,a3); 270 | } 271 | 272 | 273 | DLLEXPORT ENgetlinkindex_wrap (char * a1, int *a2) { 274 | run_before_ENgetlinkindex(); 275 | return ENgetlinkindex (a1,a2); 276 | } 277 | 278 | DLLEXPORT ENgetlinkid_wrap (int a1, char *a2) { 279 | run_before_ENgetlinkid(); 280 | return ENgetlinkid (a1,a2); 281 | } 282 | 283 | DLLEXPORT ENgetlinktype_wrap (int a1, int *a2) { 284 | run_before_ENgetlinktype(); 285 | return ENgetlinktype (a1,a2); 286 | } 287 | 288 | DLLEXPORT ENgetlinknodes_wrap (int a1, int * a2, int *a3) { 289 | run_before_ENgetlinknodes(); 290 | return ENgetlinknodes (a1,a2,a3); 291 | } 292 | 293 | DLLEXPORT ENgetlinkvalue_wrap (int a1, int a2, float *a3) { 294 | run_before_ENgetlinkvalue(); 295 | return ENgetlinkvalue (a1,a2,a3); 296 | } 297 | 298 | 299 | DLLEXPORT ENgetversion_wrap (int *a1) { 300 | run_before_ENgetversion(); 301 | return ENgetversion (a1); 302 | } 303 | 304 | 305 | DLLEXPORT ENsetcontrol_wrap (int a1, int a2, int a3, float a4, int a5, float a6){ 306 | run_before_ENsetcontrol(); 307 | return ENsetcontrol (a1,a2,a3,a4,a5,a6); 308 | } 309 | 310 | DLLEXPORT ENsetnodevalue_wrap (int a1, int a2, float a3){ 311 | run_before_ENsetnodevalue(); 312 | return ENsetnodevalue (a1,a2,a3); 313 | } 314 | 315 | DLLEXPORT ENsetlinkvalue_wrap (int a1, int a2, float a3){ 316 | run_before_ENsetlinkvalue(); 317 | return ENsetlinkvalue (a1,a2,a3); 318 | } 319 | 320 | DLLEXPORT ENaddpattern_wrap (char *a1) { 321 | run_before_ENaddpattern(); 322 | return ENaddpattern (a1); 323 | } 324 | 325 | DLLEXPORT ENsetpattern_wrap (int a1, float * a2, int a3){ 326 | run_before_ENsetpattern(); 327 | return ENsetpattern (a1,a2,a3); 328 | } 329 | 330 | DLLEXPORT ENsetpatternvalue_wrap (int a1, int a2, float a3){ 331 | run_before_ENsetpatternvalue(); 332 | return ENsetpatternvalue (a1,a2,a3); 333 | } 334 | 335 | DLLEXPORT ENsettimeparam_wrap (int a1, long a2){ 336 | run_before_ENsettimeparam(); 337 | return ENsettimeparam (a1,a2); 338 | } 339 | 340 | DLLEXPORT ENsetoption_wrap (int a1, float a2){ 341 | run_before_ENsetoption(); 342 | return ENsetoption (a1,a2); 343 | } 344 | 345 | DLLEXPORT ENsetstatusreport_wrap (int a1){ 346 | run_before_ENsetstatusreport(); 347 | return ENsetstatusreport (a1); 348 | } 349 | 350 | DLLEXPORT ENsetqualtype_wrap (int a1, char * a2, char * a3, char *a4) { 351 | run_before_ENsetqualtype(); 352 | return ENsetqualtype (a1,a2,a3,a4); 353 | } 354 | 355 | 356 | 357 | 358 | /* 359 | |sed 's/(/ (/g'|awk '{if($1=="return"){print "\trun_before_" $2"();\n", $0}else{print $0}}' 360 | */ 361 | -------------------------------------------------------------------------------- /src/epanettools/adf/callepanet.cc: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | *** EPANET-Emitter reference application 3 | *** Author: Assela Pathirana 2016Nov 4 | *** Routines: entry point : ADF_and_energy_calculation 5 | *** ************************************************************************* 6 | *** Modification history: 7 | *** Name Date Description 8 | *****************************************************************************/ 9 | #include 10 | #include 11 | #include 12 | 13 | void getValuesForNode(int ii, int jj, vector > &results, bool emitter) 14 | /** reads the results from epanet system for the current calculation step and stores in the vector results 15 | arguments: 16 | jj, ii - locations of results vector the values should be stored. 17 | results - the results vector 18 | emitter - whether we are in the middle of an emitter based analysis (True) 19 | **/ 20 | { 21 | pr tmp2; 22 | float val; 23 | results.at(jj).push_back(tmp2); 24 | eoutcheck(emitter?ENgetnodevalue_wrap(jj, EN_PRESSURE, &val):ENgetnodevalue(jj, EN_PRESSURE, &val)); 25 | results.at(jj).at(ii).p=val; 26 | eoutcheck(emitter?ENgetnodevalue_wrap(jj, EN_DEMAND, &val):ENgetnodevalue(jj, EN_DEMAND, &val)); 27 | results.at(jj).at(ii).d=val; 28 | eoutcheck(emitter?ENgetnodevalue_wrap(jj, EN_HEAD, &val):ENgetnodevalue(jj, EN_HEAD, &val)); 29 | results.at(jj).at(ii).head=val; 30 | int ty; 31 | eoutcheck(ENgetnodetype(jj,&ty)); 32 | results.at(jj).at(ii).type=ty; 33 | } 34 | 35 | void ADF_calculation(char * _inpfile, char * outfile, float _DIAFACTOR) 36 | /** Computes the ADF calculation of the given network file 37 | arguments: 38 | _inpfile : name of the epanet .inp file 39 | 40 | */ 41 | { 42 | DIAFACTOR = _DIAFACTOR; 43 | inpfile=new char[500]; 44 | char ResultsFileName[500]; 45 | strcpy(inpfile,_inpfile); 46 | strcpy(ResultsFileName,outfile); 47 | //strcat(ResultsFileName,RESULTFILEEXTENSION); 48 | init(ResultsFileName); // , open the output file 49 | initLinkArray(); // store the number of links and nodes in global variables. 50 | BaselineCalc(); 51 | costCalc(); 52 | ResultsFile.close(); 53 | } 54 | 55 | void BaselineCalc() 56 | /** Does the epanet simulation without any pipes closed (normal operation), with and without emitter modification. 57 | emitterbaseline and emitterbaseline are the two vectors holding results for emitter, no-emitter simulations respectively 58 | arguments: 59 | none 60 | **/ 61 | { 62 | open(true); 63 | emitterbaseline=getResults(true); 64 | close(true); 65 | open(false); 66 | regularbaseline=getResults(false); 67 | close(false); 68 | } 69 | 70 | 71 | void writeoutputforpipe( int ii, res &r ) 72 | /** Writes the output to stdout and the file opened at 'ResultsFile' if possible. 73 | arguments: 74 | ii : pipe index 75 | r : struct res containing the results 76 | */ 77 | { 78 | /* cout.precision(3); 79 | cout << setw(3) << ii<< 80 | '\t'< > results=getResults(true); 208 | 209 | // reset the pipe 210 | eoutcheck(ENsetlinkvalue(li,EN_DIAMETER,dia)); 211 | close(true); 212 | 213 | return compute_results(results,emitterbaseline,regularbaseline); 214 | } 215 | 216 | void open(bool emitter) 217 | /** Opens the epanet system, opens hydraulics for emitter/non-emitter analysis 218 | arguments: 219 | emitter : whether doing emitter-based analysis 220 | **/ 221 | { 222 | char outputfile[1024]; 223 | strcpy(outputfile,inpfile); 224 | strcat(outputfile,EN_REPORTFILEEXTENSION); 225 | eoutcheck(emitter? 226 | ENopen_wrap(inpfile, outputfile, EN_BINARYOUTFILENAME) 227 | : 228 | ENopen(inpfile, outputfile, EN_BINARYOUTFILENAME) 229 | ); 230 | eoutcheck(emitter?ENopenH_wrap():ENopenH()); 231 | } 232 | 233 | void close(bool emitter) 234 | /** Closes the epanet system after closing hydraulics of an emitter/non-emitter analysis 235 | arguments: 236 | emitter : whether doing emitter-based analysis 237 | **/ 238 | { 239 | eoutcheck(emitter?ENcloseH_wrap():ENcloseH()); 240 | eoutcheck(emitter?ENclose_wrap():ENclose()); 241 | } 242 | 243 | 244 | void initLinkArray() 245 | /** Reads the number of links in the currently opened network and creates the vector of link ids (linksOfNetwork) 246 | arguments: 247 | none 248 | **/ 249 | { 250 | open(false); 251 | int NLINKS; 252 | ENgetcount(EN_LINKCOUNT,&NLINKS); 253 | linksOfNetwork.clear(); //BUG FIX 2016NOV13 254 | linksOfNetwork.push_back(DUMBSTRING); 255 | for(int i=1;i<=NLINKS;i++){ 256 | char id[50]; 257 | eoutcheck(ENgetlinkid(i,id)); 258 | linksOfNetwork.push_back(id); 259 | } 260 | close(false); 261 | } 262 | 263 | 264 | 265 | res compute_results(vector >r, vector >emt, vector > nem ) 266 | /** Computes the ADF and energy results and returns as a type res 267 | arguments: 268 | r : results vector for which ADF and energy are calculated. 269 | emt : results vector from emitter based baseline calculation (corressponding adf res.adf1) 270 | nem : results vector from non-emitter based baseline calculation (corressponding adf res.adf2) 271 | **/ 272 | { 273 | res result; 274 | float sum1=0, sum2=0; 275 | result.adf1=result.adf2=result.energy_in=result.energy_out=0.f; 276 | for(unsigned int i=1;i > &results ) 298 | /** Reads the number of nodes of the currently opened network and create the results vector to take up nodal values at each time step later 299 | arguments: 300 | results : reference of the result vector to be used 301 | **/ 302 | { 303 | vector tmp; 304 | results.push_back(tmp); //dumb 305 | int NNODES; 306 | ENgetcount(EN_NODECOUNT,&NNODES); 307 | for(int jj=1;jj<=NNODES;jj++){ 308 | pr tmp2; 309 | results.push_back(tmp); 310 | results.at(jj).push_back(tmp2); 311 | } 312 | } 313 | 314 | void setNaN( vector > &results ) 315 | /** Sets all the values of a result object to NaN. 316 | arguments: 317 | results : reference of the result vector to be used 318 | **/ 319 | { 320 | for(unsigned int i=1;i::signaling_NaN(); 323 | results.at(i).at(j).d=std::numeric_limits::signaling_NaN(); 324 | 325 | } 326 | } 327 | } 328 | 329 | 330 | vector > getResults(bool emitter) 331 | /** runs an analysis with the current input file and reads demands, and pressures 332 | Epanet system should be opened (ENopen/_wrap), but initialization would be done inside this function. 333 | arguments: 334 | emitter : whether to do emitter analysis 335 | **/ 336 | { 337 | 338 | ReDirectStdout(true); 339 | 340 | vector > results; 341 | long tt; 342 | epanet_error=false; 343 | eoutcheck(emitter?ENinitH_wrap(0):ENinitH(0)); 344 | fillinemptyresultsobject(results); 345 | int ii=0; 346 | long timestep; 347 | eoutcheck(emitter?ENgettimeparam_wrap(EN_REPORTSTEP,×tep):ENgettimeparam(EN_REPORTSTEP,×tep)); 348 | do{ 349 | eoutcheck(emitter?ENrunH_wrap(&tt):ENrunH(&tt)); 350 | if(tt%timestep==0){ 351 | ii++; 352 | for(unsigned int jj=1;jj 0); 359 | if(epanet_error){ 360 | //setNaN(results); 361 | 362 | } 363 | ReDirectStdout(false); 364 | return results; 365 | 366 | } 367 | 368 | 369 | void eoutcheck(int ret) 370 | /** Check the value of argument against epanet error/warning signalling system. 371 | If there is an error, or some critical warnings, the flag epanet_error (global) 372 | is set to true, signalling the problem. 373 | arguments: 374 | ret : value to be checked 375 | **/ 376 | { 377 | //check ret against standard epanet signals and raise hell if anything is wrong 378 | if(ret>0){ 379 | char enerr[500]; 380 | ENgeterror(ret,enerr,499); 381 | if(epanet_error){ return;} 382 | if(ret>100){ 383 | cerr << "Error in epanet..\n" <= (2, 7, 0): 9 | def swig_import_helper(): 10 | import importlib 11 | pkg = __name__.rpartition('.')[0] 12 | mname = '.'.join((pkg, '_epanet2')).lstrip('.') 13 | try: 14 | return importlib.import_module(mname) 15 | except ImportError: 16 | return importlib.import_module('_epanet2') 17 | _epanet2 = swig_import_helper() 18 | del swig_import_helper 19 | elif _swig_python_version_info >= (2, 6, 0): 20 | def swig_import_helper(): 21 | from os.path import dirname 22 | import imp 23 | fp = None 24 | try: 25 | fp, pathname, description = imp.find_module('_epanet2', [dirname(__file__)]) 26 | except ImportError: 27 | import _epanet2 28 | return _epanet2 29 | try: 30 | _mod = imp.load_module('_epanet2', fp, pathname, description) 31 | finally: 32 | if fp is not None: 33 | fp.close() 34 | return _mod 35 | _epanet2 = swig_import_helper() 36 | del swig_import_helper 37 | else: 38 | import _epanet2 39 | del _swig_python_version_info 40 | 41 | try: 42 | _swig_property = property 43 | except NameError: 44 | pass # Python < 2.2 doesn't have 'property'. 45 | 46 | try: 47 | import builtins as __builtin__ 48 | except ImportError: 49 | import __builtin__ 50 | 51 | def _swig_setattr_nondynamic(self, class_type, name, value, static=1): 52 | if (name == "thisown"): 53 | return self.this.own(value) 54 | if (name == "this"): 55 | if type(value).__name__ == 'SwigPyObject': 56 | self.__dict__[name] = value 57 | return 58 | method = class_type.__swig_setmethods__.get(name, None) 59 | if method: 60 | return method(self, value) 61 | if (not static): 62 | if _newclass: 63 | object.__setattr__(self, name, value) 64 | else: 65 | self.__dict__[name] = value 66 | else: 67 | raise AttributeError("You cannot add attributes to %s" % self) 68 | 69 | 70 | def _swig_setattr(self, class_type, name, value): 71 | return _swig_setattr_nondynamic(self, class_type, name, value, 0) 72 | 73 | 74 | def _swig_getattr(self, class_type, name): 75 | if (name == "thisown"): 76 | return self.this.own() 77 | method = class_type.__swig_getmethods__.get(name, None) 78 | if method: 79 | return method(self) 80 | raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name)) 81 | 82 | 83 | def _swig_repr(self): 84 | try: 85 | strthis = "proxy of " + self.this.__repr__() 86 | except __builtin__.Exception: 87 | strthis = "" 88 | return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) 89 | 90 | try: 91 | _object = object 92 | _newclass = 1 93 | except __builtin__.Exception: 94 | class _object: 95 | pass 96 | _newclass = 0 97 | 98 | EN_ELEVATION = _epanet2.EN_ELEVATION 99 | EN_BASEDEMAND = _epanet2.EN_BASEDEMAND 100 | EN_PATTERN = _epanet2.EN_PATTERN 101 | EN_EMITTER = _epanet2.EN_EMITTER 102 | EN_INITQUAL = _epanet2.EN_INITQUAL 103 | EN_SOURCEQUAL = _epanet2.EN_SOURCEQUAL 104 | EN_SOURCEPAT = _epanet2.EN_SOURCEPAT 105 | EN_SOURCETYPE = _epanet2.EN_SOURCETYPE 106 | EN_TANKLEVEL = _epanet2.EN_TANKLEVEL 107 | EN_DEMAND = _epanet2.EN_DEMAND 108 | EN_HEAD = _epanet2.EN_HEAD 109 | EN_PRESSURE = _epanet2.EN_PRESSURE 110 | EN_QUALITY = _epanet2.EN_QUALITY 111 | EN_SOURCEMASS = _epanet2.EN_SOURCEMASS 112 | EN_INITVOLUME = _epanet2.EN_INITVOLUME 113 | EN_MIXMODEL = _epanet2.EN_MIXMODEL 114 | EN_MIXZONEVOL = _epanet2.EN_MIXZONEVOL 115 | EN_TANKDIAM = _epanet2.EN_TANKDIAM 116 | EN_MINVOLUME = _epanet2.EN_MINVOLUME 117 | EN_VOLCURVE = _epanet2.EN_VOLCURVE 118 | EN_MINLEVEL = _epanet2.EN_MINLEVEL 119 | EN_MAXLEVEL = _epanet2.EN_MAXLEVEL 120 | EN_MIXFRACTION = _epanet2.EN_MIXFRACTION 121 | EN_TANK_KBULK = _epanet2.EN_TANK_KBULK 122 | EN_DIAMETER = _epanet2.EN_DIAMETER 123 | EN_LENGTH = _epanet2.EN_LENGTH 124 | EN_ROUGHNESS = _epanet2.EN_ROUGHNESS 125 | EN_MINORLOSS = _epanet2.EN_MINORLOSS 126 | EN_INITSTATUS = _epanet2.EN_INITSTATUS 127 | EN_INITSETTING = _epanet2.EN_INITSETTING 128 | EN_KBULK = _epanet2.EN_KBULK 129 | EN_KWALL = _epanet2.EN_KWALL 130 | EN_FLOW = _epanet2.EN_FLOW 131 | EN_VELOCITY = _epanet2.EN_VELOCITY 132 | EN_HEADLOSS = _epanet2.EN_HEADLOSS 133 | EN_STATUS = _epanet2.EN_STATUS 134 | EN_SETTING = _epanet2.EN_SETTING 135 | EN_ENERGY = _epanet2.EN_ENERGY 136 | EN_DURATION = _epanet2.EN_DURATION 137 | EN_HYDSTEP = _epanet2.EN_HYDSTEP 138 | EN_QUALSTEP = _epanet2.EN_QUALSTEP 139 | EN_PATTERNSTEP = _epanet2.EN_PATTERNSTEP 140 | EN_PATTERNSTART = _epanet2.EN_PATTERNSTART 141 | EN_REPORTSTEP = _epanet2.EN_REPORTSTEP 142 | EN_REPORTSTART = _epanet2.EN_REPORTSTART 143 | EN_RULESTEP = _epanet2.EN_RULESTEP 144 | EN_STATISTIC = _epanet2.EN_STATISTIC 145 | EN_PERIODS = _epanet2.EN_PERIODS 146 | EN_NODECOUNT = _epanet2.EN_NODECOUNT 147 | EN_TANKCOUNT = _epanet2.EN_TANKCOUNT 148 | EN_LINKCOUNT = _epanet2.EN_LINKCOUNT 149 | EN_PATCOUNT = _epanet2.EN_PATCOUNT 150 | EN_CURVECOUNT = _epanet2.EN_CURVECOUNT 151 | EN_CONTROLCOUNT = _epanet2.EN_CONTROLCOUNT 152 | EN_JUNCTION = _epanet2.EN_JUNCTION 153 | EN_RESERVOIR = _epanet2.EN_RESERVOIR 154 | EN_TANK = _epanet2.EN_TANK 155 | EN_CVPIPE = _epanet2.EN_CVPIPE 156 | EN_PIPE = _epanet2.EN_PIPE 157 | EN_PUMP = _epanet2.EN_PUMP 158 | EN_PRV = _epanet2.EN_PRV 159 | EN_PSV = _epanet2.EN_PSV 160 | EN_PBV = _epanet2.EN_PBV 161 | EN_FCV = _epanet2.EN_FCV 162 | EN_TCV = _epanet2.EN_TCV 163 | EN_GPV = _epanet2.EN_GPV 164 | EN_NONE = _epanet2.EN_NONE 165 | EN_CHEM = _epanet2.EN_CHEM 166 | EN_AGE = _epanet2.EN_AGE 167 | EN_TRACE = _epanet2.EN_TRACE 168 | EN_CONCEN = _epanet2.EN_CONCEN 169 | EN_MASS = _epanet2.EN_MASS 170 | EN_SETPOINT = _epanet2.EN_SETPOINT 171 | EN_FLOWPACED = _epanet2.EN_FLOWPACED 172 | EN_CFS = _epanet2.EN_CFS 173 | EN_GPM = _epanet2.EN_GPM 174 | EN_MGD = _epanet2.EN_MGD 175 | EN_IMGD = _epanet2.EN_IMGD 176 | EN_AFD = _epanet2.EN_AFD 177 | EN_LPS = _epanet2.EN_LPS 178 | EN_LPM = _epanet2.EN_LPM 179 | EN_MLD = _epanet2.EN_MLD 180 | EN_CMH = _epanet2.EN_CMH 181 | EN_CMD = _epanet2.EN_CMD 182 | EN_TRIALS = _epanet2.EN_TRIALS 183 | EN_ACCURACY = _epanet2.EN_ACCURACY 184 | EN_TOLERANCE = _epanet2.EN_TOLERANCE 185 | EN_EMITEXPON = _epanet2.EN_EMITEXPON 186 | EN_DEMANDMULT = _epanet2.EN_DEMANDMULT 187 | EN_LOWLEVEL = _epanet2.EN_LOWLEVEL 188 | EN_HILEVEL = _epanet2.EN_HILEVEL 189 | EN_TIMER = _epanet2.EN_TIMER 190 | EN_TIMEOFDAY = _epanet2.EN_TIMEOFDAY 191 | EN_AVERAGE = _epanet2.EN_AVERAGE 192 | EN_MINIMUM = _epanet2.EN_MINIMUM 193 | EN_MAXIMUM = _epanet2.EN_MAXIMUM 194 | EN_RANGE = _epanet2.EN_RANGE 195 | EN_MIX1 = _epanet2.EN_MIX1 196 | EN_MIX2 = _epanet2.EN_MIX2 197 | EN_FIFO = _epanet2.EN_FIFO 198 | EN_LIFO = _epanet2.EN_LIFO 199 | EN_NOSAVE = _epanet2.EN_NOSAVE 200 | EN_SAVE = _epanet2.EN_SAVE 201 | EN_INITFLOW = _epanet2.EN_INITFLOW 202 | 203 | def ENepanet(arg1, arg2, arg3, arg4): 204 | return _epanet2.ENepanet(arg1, arg2, arg3, arg4) 205 | ENepanet = _epanet2.ENepanet 206 | 207 | def ENopen(arg1, arg2, arg3): 208 | return _epanet2.ENopen(arg1, arg2, arg3) 209 | ENopen = _epanet2.ENopen 210 | 211 | def ENsaveinpfile(arg1): 212 | return _epanet2.ENsaveinpfile(arg1) 213 | ENsaveinpfile = _epanet2.ENsaveinpfile 214 | 215 | def ENclose(): 216 | return _epanet2.ENclose() 217 | ENclose = _epanet2.ENclose 218 | 219 | def ENsolveH(): 220 | return _epanet2.ENsolveH() 221 | ENsolveH = _epanet2.ENsolveH 222 | 223 | def ENsaveH(): 224 | return _epanet2.ENsaveH() 225 | ENsaveH = _epanet2.ENsaveH 226 | 227 | def ENopenH(): 228 | return _epanet2.ENopenH() 229 | ENopenH = _epanet2.ENopenH 230 | 231 | def ENinitH(arg1): 232 | return _epanet2.ENinitH(arg1) 233 | ENinitH = _epanet2.ENinitH 234 | 235 | def ENrunH(): 236 | return _epanet2.ENrunH() 237 | ENrunH = _epanet2.ENrunH 238 | 239 | def ENnextH(): 240 | return _epanet2.ENnextH() 241 | ENnextH = _epanet2.ENnextH 242 | 243 | def ENcloseH(): 244 | return _epanet2.ENcloseH() 245 | ENcloseH = _epanet2.ENcloseH 246 | 247 | def ENsavehydfile(arg1): 248 | return _epanet2.ENsavehydfile(arg1) 249 | ENsavehydfile = _epanet2.ENsavehydfile 250 | 251 | def ENusehydfile(arg1): 252 | return _epanet2.ENusehydfile(arg1) 253 | ENusehydfile = _epanet2.ENusehydfile 254 | 255 | def ENsolveQ(): 256 | return _epanet2.ENsolveQ() 257 | ENsolveQ = _epanet2.ENsolveQ 258 | 259 | def ENopenQ(): 260 | return _epanet2.ENopenQ() 261 | ENopenQ = _epanet2.ENopenQ 262 | 263 | def ENinitQ(arg1): 264 | return _epanet2.ENinitQ(arg1) 265 | ENinitQ = _epanet2.ENinitQ 266 | 267 | def ENrunQ(): 268 | return _epanet2.ENrunQ() 269 | ENrunQ = _epanet2.ENrunQ 270 | 271 | def ENnextQ(): 272 | return _epanet2.ENnextQ() 273 | ENnextQ = _epanet2.ENnextQ 274 | 275 | def ENstepQ(): 276 | return _epanet2.ENstepQ() 277 | ENstepQ = _epanet2.ENstepQ 278 | 279 | def ENcloseQ(): 280 | return _epanet2.ENcloseQ() 281 | ENcloseQ = _epanet2.ENcloseQ 282 | 283 | def ENwriteline(arg1): 284 | return _epanet2.ENwriteline(arg1) 285 | ENwriteline = _epanet2.ENwriteline 286 | 287 | def ENreport(): 288 | return _epanet2.ENreport() 289 | ENreport = _epanet2.ENreport 290 | 291 | def ENresetreport(): 292 | return _epanet2.ENresetreport() 293 | ENresetreport = _epanet2.ENresetreport 294 | 295 | def ENsetreport(arg1): 296 | return _epanet2.ENsetreport(arg1) 297 | ENsetreport = _epanet2.ENsetreport 298 | 299 | def ENgetcontrol(arg1): 300 | return _epanet2.ENgetcontrol(arg1) 301 | ENgetcontrol = _epanet2.ENgetcontrol 302 | 303 | def ENgetcount(arg1): 304 | return _epanet2.ENgetcount(arg1) 305 | ENgetcount = _epanet2.ENgetcount 306 | 307 | def ENgetoption(arg1): 308 | return _epanet2.ENgetoption(arg1) 309 | ENgetoption = _epanet2.ENgetoption 310 | 311 | def ENgettimeparam(arg1): 312 | return _epanet2.ENgettimeparam(arg1) 313 | ENgettimeparam = _epanet2.ENgettimeparam 314 | 315 | def ENgetflowunits(): 316 | return _epanet2.ENgetflowunits() 317 | ENgetflowunits = _epanet2.ENgetflowunits 318 | 319 | def ENgetpatternindex(arg1): 320 | return _epanet2.ENgetpatternindex(arg1) 321 | ENgetpatternindex = _epanet2.ENgetpatternindex 322 | 323 | def ENgetpatternid(arg1): 324 | return _epanet2.ENgetpatternid(arg1) 325 | ENgetpatternid = _epanet2.ENgetpatternid 326 | 327 | def ENgetpatternlen(arg1): 328 | return _epanet2.ENgetpatternlen(arg1) 329 | ENgetpatternlen = _epanet2.ENgetpatternlen 330 | 331 | def ENgetpatternvalue(arg1, arg2): 332 | return _epanet2.ENgetpatternvalue(arg1, arg2) 333 | ENgetpatternvalue = _epanet2.ENgetpatternvalue 334 | 335 | def ENgetqualtype(): 336 | return _epanet2.ENgetqualtype() 337 | ENgetqualtype = _epanet2.ENgetqualtype 338 | 339 | def ENgeterror(arg1, arg3): 340 | return _epanet2.ENgeterror(arg1, arg3) 341 | ENgeterror = _epanet2.ENgeterror 342 | 343 | def ENgetnodeindex(arg1): 344 | return _epanet2.ENgetnodeindex(arg1) 345 | ENgetnodeindex = _epanet2.ENgetnodeindex 346 | 347 | def ENgetnodeid(arg1): 348 | return _epanet2.ENgetnodeid(arg1) 349 | ENgetnodeid = _epanet2.ENgetnodeid 350 | 351 | def ENgetnodetype(arg1): 352 | return _epanet2.ENgetnodetype(arg1) 353 | ENgetnodetype = _epanet2.ENgetnodetype 354 | 355 | def ENgetnodevalue(arg1, arg2): 356 | return _epanet2.ENgetnodevalue(arg1, arg2) 357 | ENgetnodevalue = _epanet2.ENgetnodevalue 358 | 359 | def ENgetlinkindex(arg1): 360 | return _epanet2.ENgetlinkindex(arg1) 361 | ENgetlinkindex = _epanet2.ENgetlinkindex 362 | 363 | def ENgetlinkid(arg1): 364 | return _epanet2.ENgetlinkid(arg1) 365 | ENgetlinkid = _epanet2.ENgetlinkid 366 | 367 | def ENgetlinktype(arg1): 368 | return _epanet2.ENgetlinktype(arg1) 369 | ENgetlinktype = _epanet2.ENgetlinktype 370 | 371 | def ENgetlinknodes(arg1): 372 | return _epanet2.ENgetlinknodes(arg1) 373 | ENgetlinknodes = _epanet2.ENgetlinknodes 374 | 375 | def ENgetlinkvalue(arg1, arg2): 376 | return _epanet2.ENgetlinkvalue(arg1, arg2) 377 | ENgetlinkvalue = _epanet2.ENgetlinkvalue 378 | 379 | def ENgetversion(): 380 | return _epanet2.ENgetversion() 381 | ENgetversion = _epanet2.ENgetversion 382 | 383 | def ENsetcontrol(arg1, arg2, arg3, arg4, arg5, arg6): 384 | return _epanet2.ENsetcontrol(arg1, arg2, arg3, arg4, arg5, arg6) 385 | ENsetcontrol = _epanet2.ENsetcontrol 386 | 387 | def ENsetnodevalue(arg1, arg2, arg3): 388 | return _epanet2.ENsetnodevalue(arg1, arg2, arg3) 389 | ENsetnodevalue = _epanet2.ENsetnodevalue 390 | 391 | def ENsetlinkvalue(arg1, arg2, arg3): 392 | return _epanet2.ENsetlinkvalue(arg1, arg2, arg3) 393 | ENsetlinkvalue = _epanet2.ENsetlinkvalue 394 | 395 | def ENaddpattern(arg1): 396 | return _epanet2.ENaddpattern(arg1) 397 | ENaddpattern = _epanet2.ENaddpattern 398 | 399 | def ENsetpattern(arg1, floatarray, nfloats): 400 | return _epanet2.ENsetpattern(arg1, floatarray, nfloats) 401 | ENsetpattern = _epanet2.ENsetpattern 402 | 403 | def ENsetpatternvalue(arg1, arg2, arg3): 404 | return _epanet2.ENsetpatternvalue(arg1, arg2, arg3) 405 | ENsetpatternvalue = _epanet2.ENsetpatternvalue 406 | 407 | def ENsettimeparam(arg1, arg2): 408 | return _epanet2.ENsettimeparam(arg1, arg2) 409 | ENsettimeparam = _epanet2.ENsettimeparam 410 | 411 | def ENsetoption(arg1, arg2): 412 | return _epanet2.ENsetoption(arg1, arg2) 413 | ENsetoption = _epanet2.ENsetoption 414 | 415 | def ENsetstatusreport(arg1): 416 | return _epanet2.ENsetstatusreport(arg1) 417 | ENsetstatusreport = _epanet2.ENsetstatusreport 418 | 419 | def ENsetqualtype(arg1, arg2, arg3, arg4): 420 | return _epanet2.ENsetqualtype(arg1, arg2, arg3, arg4) 421 | ENsetqualtype = _epanet2.ENsetqualtype 422 | WRAPPER_ERROR_FILE_OPEN = _epanet2.WRAPPER_ERROR_FILE_OPEN 423 | WRAPPER_ERROR_NOT_IMPLEMENTED = _epanet2.WRAPPER_ERROR_NOT_IMPLEMENTED 424 | 425 | def ENsetpatterndim(index, dim): 426 | return _epanet2.ENsetpatterndim(index, dim) 427 | ENsetpatterndim = _epanet2.ENsetpatterndim 428 | 429 | def ENsetpatterndim_wrap(index, dim): 430 | return _epanet2.ENsetpatterndim_wrap(index, dim) 431 | ENsetpatterndim_wrap = _epanet2.ENsetpatterndim_wrap 432 | # This file is compatible with both classic and new-style classes. 433 | 434 | cvar = _epanet2.cvar 435 | 436 | --------------------------------------------------------------------------------