├── .github └── workflows │ ├── build_wheel.yml │ └── unit_test.yml ├── .gitignore ├── .gitmodules ├── README.md ├── nrtest-swmm ├── main.py ├── nrtest_swmm │ ├── __init__.py │ └── output_reader.py ├── scripts │ └── report-diff └── setup.py └── swmm-toolkit ├── AUTHORS ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── build-requirements.txt ├── docs ├── Makefile ├── apidoc │ ├── swmm.rst │ ├── swmm.toolkit.output.rst │ ├── swmm.toolkit.rst │ ├── swmm.toolkit.shared_enum.rst │ └── swmm.toolkit.solver.rst ├── conf.py ├── index.rst └── make.bat ├── extern ├── license-llvm-openmp.txt └── openmp.cmake ├── pyproject.toml ├── setup.py ├── src └── swmm │ └── toolkit │ ├── CMakeLists.txt │ ├── __init__.py │ ├── output.i │ ├── output_docs.i │ ├── output_metadata.py │ ├── output_rename.i │ ├── shared_enum.py │ ├── solver.i │ ├── solver_docs.i │ ├── solver_rename.i │ └── stats_typemaps.i ├── test-requirements.txt ├── tests ├── data │ ├── test_Example1.inp │ ├── test_Example1.out │ ├── test_Example2.inp │ ├── test_Example3.inp │ ├── test_Example3.old.inp │ └── test_inlet_drains.inp ├── test_metadata.py ├── test_output.py ├── test_solver.py └── test_stats.py └── tools └── build-wheels.sh /.github/workflows/build_wheel.yml: -------------------------------------------------------------------------------- 1 | name: Build Wheels 2 | 3 | # Cross compile wheels only on main branch and tags 4 | on: 5 | pull_request: 6 | branches: 7 | - master 8 | push: 9 | branches: 10 | - master 11 | tags: 12 | - v* 13 | workflow_dispatch: 14 | 15 | jobs: 16 | build_nrtest_plugin: 17 | name: Build nrtest-swmm plugin 18 | runs-on: ubuntu-latest 19 | defaults: 20 | run: 21 | working-directory: ./nrtest-swmm 22 | 23 | steps: 24 | - name: Checkout repo 25 | uses: actions/checkout@v3 26 | with: 27 | submodules: true 28 | 29 | - name: Install Python 30 | uses: actions/setup-python@v4 31 | with: 32 | python-version: 3.7 33 | 34 | - name: Build wheel 35 | run: | 36 | pip install wheel 37 | python setup.py bdist_wheel 38 | - uses: actions/upload-artifact@v3 39 | with: 40 | path: nrtest-swmm/dist/*.whl 41 | 42 | 43 | 44 | build_wheels: 45 | runs-on: ${{ matrix.os }} 46 | strategy: 47 | fail-fast: false 48 | matrix: 49 | os: [ubuntu-latest, windows-2022, macos-12] 50 | pyver: [cp38, cp39, cp310, cp311, cp312] 51 | 52 | steps: 53 | - name: Checkout repo 54 | uses: actions/checkout@v3 55 | with: 56 | submodules: true 57 | 58 | - name: Build wheels 59 | uses: pypa/cibuildwheel@v2.17.0 60 | with: 61 | package-dir: ./swmm-toolkit 62 | env: 63 | CIBW_TEST_COMMAND: "pytest {package}/tests" 64 | CIBW_BEFORE_TEST: pip install -r {package}/test-requirements.txt 65 | # mac needs ninja to build 66 | CIBW_BEFORE_BUILD_MACOS: brew install ninja 67 | # remove system swig (cmake bug doesn't respect python venv) 68 | # https://github.com/swig/swig/issues/2481#issuecomment-1949573105 69 | CIBW_BEFORE_BUILD_LINUX: rm -f $(which swig) && rm -f $(which swig4.0) 70 | # configure cibuildwheel to build native archs ('auto'), and some emulated ones 71 | CIBW_ARCHS_LINUX: x86_64 72 | CIBW_ARCHS_WINDOWS: AMD64 73 | CIBW_ARCHS_MACOS: x86_64 74 | # only build current supported python: https://devguide.python.org/versions/ 75 | # don't build pypy or musllinux to save build time. TODO: find a good way to support those archs 76 | CIBW_BUILD: ${{matrix.pyver}}-* 77 | CIBW_SKIP: cp36-* cp37-* pp* *-musllinux* 78 | # Will avoid testing on emulated architectures 79 | # Skip trying to test arm64 builds on Intel Macs 80 | CIBW_TEST_SKIP: "*-*linux_{aarch64,ppc64le,s390x} *-macosx_arm64 *-macosx_universal2:arm64" 81 | CIBW_BUILD_VERBOSITY: 1 82 | 83 | - uses: actions/upload-artifact@v3 84 | with: 85 | path: ./wheelhouse/*.whl 86 | 87 | build_cross_wheels: 88 | runs-on: ${{ matrix.os }} 89 | strategy: 90 | fail-fast: false 91 | matrix: 92 | os: [ubuntu-latest,macos-12] 93 | pyver: [cp38, cp39, cp310, cp311, cp312] 94 | 95 | steps: 96 | - name: Checkout repo 97 | uses: actions/checkout@v3 98 | with: 99 | submodules: true 100 | 101 | - name: Set up QEMU 102 | if: runner.os == 'Linux' 103 | uses: docker/setup-qemu-action@v2 104 | with: 105 | platforms: all 106 | 107 | - name: Build wheels 108 | uses: pypa/cibuildwheel@v2.17.0 109 | with: 110 | package-dir: ./swmm-toolkit 111 | env: 112 | # remove system swig (cmake bug doesn't respect python venv) 113 | # https://github.com/swig/swig/issues/2481#issuecomment-1949573105 114 | CIBW_BEFORE_BUILD_LINUX: rm -f $(which swig) && rm -f $(which swig4.0) 115 | # configure cibuildwheel to build native archs ('auto'), and some emulated ones 116 | CIBW_ARCHS_LINUX: aarch64 117 | CIBW_ARCHS_MACOS: arm64 118 | # only build current supported python: https://devguide.python.org/versions/ 119 | # don't build pypy or musllinux to save build time. TODO: find a good way to support those archs 120 | CIBW_BUILD: ${{matrix.pyver}}-* 121 | CIBW_SKIP: cp36-* cp37-* pp* *-musllinux* 122 | CIBW_BUILD_VERBOSITY: 1 123 | 124 | - uses: actions/upload-artifact@v3 125 | with: 126 | path: ./wheelhouse/*.whl 127 | -------------------------------------------------------------------------------- /.github/workflows/unit_test.yml: -------------------------------------------------------------------------------- 1 | name: Unit Test 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - 'master' 7 | tags-ignore: 8 | - v* 9 | pull_request: 10 | branches-ignore: 11 | - 'master' 12 | 13 | jobs: 14 | build_and_test: 15 | name: Build and test on ${{ matrix.os }} 16 | runs-on: ${{ matrix.os }} 17 | defaults: 18 | run: 19 | working-directory: ./swmm-toolkit 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | os: [windows-2022, macos-12, ubuntu-latest] 25 | include: 26 | - os: windows-2022 27 | sys_pkgs: choco install swig 28 | activate: ./build-env/Scripts/activate 29 | 30 | - os: macos-12 31 | sys_pkgs: brew install swig ninja 32 | activate: source ./build-env/bin/activate 33 | 34 | - os: ubuntu-latest 35 | activate: source ./build-env/bin/activate 36 | 37 | steps: 38 | - name: Checkout repo 39 | uses: actions/checkout@v3 40 | with: 41 | submodules: true 42 | 43 | - name: Install Python 44 | uses: actions/setup-python@v4 45 | with: 46 | python-version: "3.11" 47 | 48 | - name: Install required system packages 49 | run: ${{matrix.sys_pkgs}} 50 | 51 | - name: Build wheel in virtual env 52 | run: | 53 | python -m venv --clear ./build-env 54 | ${{matrix.activate}} 55 | python -m pip install -r build-requirements.txt 56 | python setup.py bdist_wheel 57 | deactivate 58 | 59 | - name: Test wheel 60 | run: | 61 | pip install -r test-requirements.txt 62 | pip install --no-index --find-links=./dist swmm_toolkit 63 | pytest -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # .gitignore for swmm-python repo 3 | # 4 | 5 | !.git* 6 | 7 | .vscode 8 | 9 | .DS_Store 10 | 11 | *.pyc 12 | 13 | _skbuild/ 14 | _cmake_test_compile 15 | 16 | dist/ 17 | MANIFEST 18 | .pytest_cache/ 19 | __pycache__/ 20 | *.egg-info/ 21 | 22 | swmm-toolkit/docs/_build 23 | 24 | swmm-toolkit/tests/data/* 25 | !test_*.* 26 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "swmm-toolkit/swmm-solver"] 2 | path = swmm-toolkit/swmm-solver 3 | url = https://github.com/OpenWaterAnalytics/Stormwater-Management-Model.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swmm-python 2 | 3 | 4 | ## Contents 5 | nrtest-swmm - Plugin for performing numerical regression testing on swmm-solver. 6 | 7 | 8 | swmm-toolkit - SWIG based wrappers for the swmm-solver and swmm-output libraries. 9 | 10 | ![Build Wheels](https://github.com/SWMM-Project/swmm-python/workflows/Build%20Wheels/badge.svg) 11 | -------------------------------------------------------------------------------- /nrtest-swmm/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 4 | # main.py 5 | # 6 | # Author: Michael E. Tryby 7 | # US EPA - ORD/NRMRL 8 | # 9 | ''' 10 | Provides entry point main. Useful for development and testing purposes. 11 | ''' 12 | 13 | import cStringIO 14 | 15 | import time 16 | 17 | import header_detail_footer as hdf 18 | import numpy as np 19 | 20 | import nrtest_swmm.output_reader as ordr 21 | 22 | def result_compare(path_test, path_ref, comp_args): 23 | 24 | isclose = True 25 | close = 0 26 | notclose = 0 27 | equal = 0 28 | total = 0 29 | output = cStringIO.StringIO() 30 | eps = np.finfo(float).eps 31 | 32 | start = time.time() 33 | 34 | test_reader = ordr.output_generator(path_test) 35 | ref_reader = ordr.output_generator(path_ref) 36 | 37 | for test, ref in _zip(test_reader, ref_reader): 38 | total += 1 39 | if total%100000 == 0: 40 | print(total) 41 | 42 | if len(test) != len(ref): 43 | raise ValueError('Inconsistent lengths') 44 | 45 | # Skip results if they are zero or equal 46 | if np.array_equal(test, ref): 47 | equal += 1 48 | continue 49 | else: 50 | try: 51 | np.testing.assert_allclose(test, ref, comp_args[0], comp_args[1]) 52 | close += 1 53 | 54 | except AssertionError as ae: 55 | notclose += 1 56 | output.write(str(ae)) 57 | output.write('\n\n') 58 | continue 59 | 60 | stop = time.time() 61 | 62 | print(output.getvalue()) 63 | output.close() 64 | 65 | print('equal: %d close: %d notclose: %d total: %d in %f (sec)\n' % 66 | (equal, close, notclose, total, (stop - start))) 67 | 68 | if notclose > 0: 69 | print('%d differences found\n' % notclose) 70 | isclose = False 71 | 72 | return isclose 73 | 74 | def array_zero(test, ref): 75 | if not test.any() and not ref.any(): 76 | return True 77 | return False 78 | 79 | def report_compare(path_test, path_ref, (comp_args)): 80 | ''' 81 | Compares results in two report files ignoring contents of header and footer. 82 | ''' 83 | with open(path_test ,'r') as ftest, open(path_ref, 'r') as fref: 84 | for (test_line, ref_line) in zip(hdf.parse(ftest, 4, 4)[1], 85 | hdf.parse(fref, 4, 4)[1]): 86 | if test_line != ref_line: 87 | return False 88 | 89 | return True 90 | 91 | 92 | import logging 93 | from os import listdir 94 | from os.path import exists, isfile, isdir, join 95 | 96 | from nrtest.testsuite import TestSuite 97 | from nrtest.compare import compare_testsuite, validate_testsuite 98 | from nrtest.execute import execute_testsuite 99 | 100 | def nrtest_compare(path_test, path_ref, rtol, atol): 101 | 102 | ts_new = TestSuite.read_benchmark(path_test) 103 | ts_old = TestSuite.read_benchmark(path_ref) 104 | 105 | if not validate_testsuite(ts_new) or not validate_testsuite(ts_old): 106 | exit(1) 107 | 108 | try: 109 | logging.info('Found %i tests' % len(ts_new.tests)) 110 | compatible = compare_testsuite(ts_new, ts_old, rtol, atol) 111 | except KeyboardInterrupt: 112 | logging.warning('Process interrupted by user') 113 | compatible = False 114 | else: 115 | logging.info('Finished') 116 | 117 | # Non-zero exit code indicates failure 118 | exit(not compatible) 119 | 120 | def nrtest_execute(app_path, test_path, output_path): 121 | 122 | 123 | for p in test_path + [app_path]: 124 | if not exists(p): 125 | logging.error('Could not find path: "%s"' % p) 126 | 127 | test_dirs = [p for p in test_path if isdir(p)] 128 | test_files = [p for p in test_path if isfile(p)] 129 | test_files += [join(d, p) for d in test_dirs for p in listdir(d) 130 | if p.endswith('.json')] 131 | 132 | test_files = list(set(test_files)) # remove duplicates 133 | 134 | ts = TestSuite.read_config(app_path, test_files, output_path) 135 | 136 | if not validate_testsuite(ts): 137 | exit(1) 138 | 139 | try: 140 | logging.info('Found %i tests' % len(test_files)) 141 | success = execute_testsuite(ts) 142 | ts.write_manifest() 143 | except KeyboardInterrupt: 144 | logging.warning('Process interrupted by user') 145 | success = False 146 | else: 147 | logging.info('Finished') 148 | 149 | # Non-zero exit code indicates failure 150 | exit(not success) 151 | -------------------------------------------------------------------------------- /nrtest-swmm/nrtest_swmm/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 4 | # __init__.py - nrtest_swmm module 5 | # 6 | # Author: Michael E. Tryby 7 | # US EPA - ORD/NRMRL 8 | # 9 | 10 | ''' 11 | Numerical regression testing (nrtest) plugin for comparing SWMM binary results 12 | files and SWMM text based report files. 13 | ''' 14 | 15 | # third party imports 16 | import header_detail_footer as hdf 17 | import numpy as np 18 | 19 | # project imports 20 | import nrtest_swmm.output_reader as ordr 21 | 22 | 23 | __author__ = "Michael E. Tryby" 24 | __copyright__ = "None" 25 | __credits__ = "Colleen Barr, Maurizio Cingi, Mark Gray, David Hall, Bryant McDonnell" 26 | __license__ = "CC0 1.0 Universal" 27 | 28 | __version__ = "0.7.0" 29 | __date__ = "Jul 28, 2021" 30 | 31 | __maintainer__ = "Michael E. Tryby" 32 | __email__ = "tryby.michael@epa.gov" 33 | __status = "Development" 34 | 35 | 36 | def swmm_allclose_compare(path_test, path_ref, rtol, atol): 37 | ''' 38 | Compares results in two SWMM binary files. Using the comparison criteria 39 | described in the numpy assert_allclose documentation. 40 | 41 | (test_value - ref_value) <= atol + rtol * abs(ref_value) 42 | 43 | Returns true if all of the results in the two binary files meet the 44 | comparison criteria; otherwise, an AssertionError is thrown. 45 | 46 | Numpy allclose is quite expensive to evaluate. Test and reference results 47 | are checked to see if they are equal before being compared using the 48 | allclose criteria. This reduces comparison times significantly. 49 | 50 | Arguments: 51 | path_test - path to result file being tested 52 | path_ref - path to reference result file 53 | rtol - relative tolerance 54 | atol - absolute tolerance 55 | 56 | Returns: 57 | True or raises an error 58 | 59 | Raises: 60 | ValueError() 61 | AssertionError() 62 | ... 63 | ''' 64 | 65 | for (test, ref) in zip(ordr.output_generator(path_test), 66 | ordr.output_generator(path_ref)): 67 | 68 | # Compare arrays when lengths are unequal by truncating extra elements 69 | length = min(len(test[0]), len(ref[0])) 70 | 71 | # Skip over results if they are equal to optimize performance 72 | if (np.array_equal(test[0][:length], ref[0][:length])): 73 | continue 74 | 75 | else: 76 | np.testing.assert_allclose(test[0][:length], ref[0][:length], rtol, atol) 77 | 78 | return True 79 | 80 | #def swmm_better_compare(): 81 | # ''' 82 | # If for some reason you don't like numpy.testing.assert_allclose() add a 83 | # better function here. Be sure to add the entry point to the setup file so 84 | # nrtest can find it at runtime. 85 | # ''' 86 | # pass 87 | 88 | def swmm_report_compare(path_test, path_ref, rtol, atol): 89 | ''' 90 | Compares results in two report files ignoring contents of header and footer. 91 | 92 | Arguments: 93 | path_test - path to result file being tested 94 | path_ref - path to reference result file 95 | rtol - ignored 96 | atol - ignored 97 | 98 | Returns: 99 | True or False 100 | 101 | Raises: 102 | HeaderError() 103 | FooterError() 104 | RunTimeError() 105 | ... 106 | ''' 107 | 108 | HEADER = 4 109 | FOOTER = 4 110 | 111 | with open(path_test ,'r') as ftest, open(path_ref, 'r') as fref: 112 | 113 | for (test_line, ref_line) in zip(hdf.parse(ftest, HEADER, FOOTER)[1], 114 | hdf.parse(fref, HEADER, FOOTER)[1]): 115 | 116 | if test_line != ref_line: 117 | return False 118 | 119 | return True 120 | -------------------------------------------------------------------------------- /nrtest-swmm/nrtest_swmm/output_reader.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 4 | # output_reader.py 5 | # 6 | # Date Created: 11/14/2017 7 | # Date Modified: 10/17/2019 8 | # 9 | # Author: Michael E. Tryby 10 | # US EPA - ORD/NRMRL 11 | # 12 | ''' 13 | The module output_reader provides the class used to implement the output 14 | generator. 15 | ''' 16 | 17 | # system import 18 | from itertools import islice 19 | 20 | # project import 21 | from swmm.toolkit import output, shared_enum 22 | 23 | 24 | def output_generator(path_ref): 25 | ''' 26 | The output_generator is designed to iterate over a swmm binary file and 27 | yield element results. It is useful for comparing contents of binary files 28 | for numerical regression testing. 29 | 30 | The generator yields a list containing the SWMM element result. 31 | 32 | Arguments: 33 | path_ref - path to result file 34 | 35 | Raises: 36 | SWMM_OutputReaderError() 37 | ... 38 | ''' 39 | 40 | with OutputReader(path_ref) as reader: 41 | 42 | for period_index in range(0, reader.report_periods()): 43 | for element_type in islice(shared_enum.ElementType, 4): 44 | for element_index in range(0, reader.element_count(element_type)): 45 | 46 | yield (reader.element_result(element_type, period_index, element_index), 47 | (element_type, period_index, element_index)) 48 | 49 | 50 | class OutputReader(): 51 | ''' 52 | Provides minimal interface needed to implement the SWMM output generator. 53 | ''' 54 | 55 | def __init__(self, filename): 56 | self.filepath = filename 57 | self.handle = None 58 | self.count = None 59 | self.get_element_result = { 60 | shared_enum.ElementType.SUBCATCH: output.get_subcatch_result, 61 | shared_enum.ElementType.NODE: output.get_node_result, 62 | shared_enum.ElementType.LINK: output.get_link_result, 63 | shared_enum.ElementType.SYSTEM: output.get_system_result 64 | } 65 | 66 | def __enter__(self): 67 | self.handle = output.init() 68 | output.open(self.handle, self.filepath) 69 | self.count = output.get_proj_size(self.handle) 70 | return self 71 | 72 | def __exit__(self, type, value, traceback): 73 | output.close(self.handle) 74 | 75 | def report_periods(self): 76 | return output.get_times(self.handle, shared_enum.Time.NUM_PERIODS) 77 | 78 | def element_count(self, element_type): 79 | return self.count[element_type] 80 | 81 | def element_result(self, element_type, time_index, element_index): 82 | return self.get_element_result[element_type](self.handle, time_index, element_index) 83 | -------------------------------------------------------------------------------- /nrtest-swmm/scripts/report-diff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # 5 | # binary_diff.py 6 | # 7 | # Date Created: July 11, 2018 8 | # Date Modified: October 17, 2019 9 | # 10 | # Author: Michael E. Tryby 11 | # US EPA - ORD/NRMRL 12 | # 13 | 14 | # system imports 15 | import argparse 16 | 17 | # third party imports 18 | import numpy as np 19 | 20 | # project imports 21 | import nrtest_swmm.output_reader as ordr 22 | 23 | 24 | def _binary_diff(path_test, path_ref, min_cdd): 25 | for (test, ref) in zip(ordr.output_generator(path_test), 26 | ordr.output_generator(path_ref)): 27 | 28 | # Compare arrays when lengths are unequal by truncating extra elements 29 | length = min(len(test[0]), len(ref[0])) 30 | 31 | # Skip over arrays that are equal 32 | if np.array_equal(test[0][:length], ref[0][:length]): 33 | continue 34 | else: 35 | lre = _log_relative_error(test[0][:length], ref[0][:length]) 36 | idx = np.unravel_index(np.argmin(lre), lre.shape) 37 | 38 | if lre[idx] < min_cdd: 39 | _print_diff(idx, lre, test, ref) 40 | 41 | return 42 | 43 | 44 | def _log_relative_error(q, c): 45 | ''' 46 | Computes log relative error, a measure of numerical accuracy. 47 | 48 | Single precision machine epsilon is between 2^-24 and 2^-23. 49 | 50 | Reference: 51 | McCullough, B. D. "Assessing the Reliability of Statistical Software: Part I." 52 | The American Statistician, vol. 52, no. 4, 1998, pp. 358-366. 53 | ''' 54 | diff = np.subtract(q, c) 55 | tmp_c = np.copy(c) 56 | 57 | # If ref value is small compute absolute error 58 | tmp_c[np.fabs(tmp_c) < 1.0e-6] = 1.0 59 | re = np.fabs(diff)/np.fabs(tmp_c) 60 | 61 | # If re is tiny set lre to number of digits 62 | re[re < 1.0e-7] = 1.0e-7 63 | # If re is very large set lre to zero 64 | re[re > 2.0] = 1.0 65 | 66 | lre = np.negative(np.log10(re)) 67 | 68 | # If lre is negative set to zero 69 | lre[lre < 0.0] = 0.0 70 | 71 | return lre 72 | 73 | 74 | def _print_diff(idx, lre, test, ref): 75 | 76 | idx_val = (idx[0], ref[1]) 77 | test_val = (test[0][idx[0]]) 78 | ref_val = (ref[0][idx[0]]) 79 | diff_val = (test_val - ref_val) 80 | lre_val = (lre[idx[0]]) 81 | 82 | print("Idx: %s\nSut: %e Ref: %e Diff: %e LRE: %.2f\n" 83 | % (idx_val, test_val, ref_val, diff_val, lre_val)) 84 | 85 | 86 | def report(args): 87 | _binary_diff(args.test, args.ref, args.mincdd) 88 | 89 | 90 | if __name__ == '__main__': 91 | 92 | parser = argparse.ArgumentParser(description='SWMM binary output difference reporting') 93 | parser.set_defaults(func=report) 94 | 95 | parser.add_argument('-t', '--test', default=None, 96 | help='Path to test benchmark') 97 | parser.add_argument('-r', '--ref', default=None, 98 | help='Path to reference benchmark') 99 | parser.add_argument('-mc', '--mincdd', type=int, default=3, 100 | help='Minimum correct decimal digits') 101 | 102 | args = parser.parse_args() 103 | args.func(args) 104 | -------------------------------------------------------------------------------- /nrtest-swmm/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 4 | # setup.py 5 | # 6 | # Author: Michael E. Tryby 7 | # US EPA - ORD/NRMRL 8 | # 9 | # Modified: Jul 28, 2021 10 | # 11 | # Usage: 12 | # \>python setup.py bdist_wheel 13 | # 14 | ''' Setup up script for nrtest_swmm package. ''' 15 | 16 | 17 | from setuptools import setup 18 | 19 | 20 | entry_points = { 21 | 'nrtest.compare': [ 22 | 'swmm allclose = nrtest_swmm:swmm_allclose_compare', 23 | 'swmm report = nrtest_swmm:swmm_report_compare', 24 | # Add the entry point for new comparison functions here 25 | ] 26 | } 27 | 28 | setup( 29 | name='nrtest-swmm', 30 | version='0.7.0', 31 | description="SWMM extension for nrtest", 32 | 33 | author="Michael E. Tryby", 34 | author_email='tryby.michael@epa.gov', 35 | url='https://github.com/USEPA', 36 | 37 | packages=['nrtest_swmm',], 38 | scripts=['scripts/report-diff',], 39 | entry_points=entry_points, 40 | 41 | install_requires=[ 42 | 'header_detail_footer>=2.3', 43 | 'nrtest>=0.2.0', 44 | 'numpy>=1.7.0', 45 | 'swmm-toolkit', 46 | ], 47 | 48 | keywords='nrtest_swmm', 49 | classifiers=[ 50 | 'Programming Language :: Python :: 3' 51 | ], 52 | ) 53 | -------------------------------------------------------------------------------- /swmm-toolkit/AUTHORS: -------------------------------------------------------------------------------- 1 | # Authors ordered by first contribution 2 | 3 | Michael Tryby (public domain) 4 | 5 | Jennifer Wu 6 | Caleb Buahin 7 | Laurent Courty 8 | Constantine Karos 9 | Abhiram Mullapudi 10 | Brooke Mason 11 | Sara C. Troutman -------------------------------------------------------------------------------- /swmm-toolkit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # CMakeLists.txt - CMake configuration file for swmm-toolkit python package 3 | # 4 | # Created: Feb 6, 2020 5 | # Modified Jun 7, 2021 6 | # 7 | # Author: See AUTHORS 8 | # 9 | 10 | ################################################################################ 11 | ################## CMAKELISTS FOR SWMM-TOOLKIT PROJECT ################### 12 | ################################################################################ 13 | 14 | cmake_minimum_required (VERSION 3.17) 15 | 16 | project(swmm-toolkit 17 | VERSION 18 | 0.15.5 19 | ) 20 | 21 | 22 | # Trick here is to perform build in a python virtual environment 23 | set(Python_FIND_VIRTUALENV FIRST) 24 | #set(CMAKE_FIND_DEBUG_MODE TRUE) 25 | if(NOT MSVC) 26 | find_package (Python3 ${PYTHON_VERSION_STRING} COMPONENTS Interpreter Development.Module REQUIRED) 27 | else() 28 | find_package (Python3 ${PYTHON_VERSION_STRING} COMPONENTS Interpreter Development REQUIRED) 29 | endif() 30 | #set(CMAKE_FIND_DEBUG_MODE FALSE) 31 | 32 | 33 | # SWIG is a build requirement so needs to be installed first 34 | find_package(SWIG REQUIRED) 35 | cmake_policy(SET CMP0078 NEW) 36 | cmake_policy(SET CMP0086 NEW) 37 | include(${SWIG_USE_FILE}) 38 | 39 | # If wheel build on Apple fetch and build OpenMP Library 40 | if (APPLE) 41 | include(./extern/openmp.cmake) 42 | else() 43 | find_package(OpenMP 44 | REQUIRED 45 | OPTIONAL_COMPONENTS 46 | C 47 | ) 48 | endif() 49 | 50 | # Add project subdirectories 51 | add_subdirectory(swmm-solver) 52 | 53 | add_subdirectory(src/swmm/toolkit) 54 | -------------------------------------------------------------------------------- /swmm-toolkit/LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | # Copyright Notice 3 | 4 | This project contains material prepared by the United States Government for 5 | which domestic copyright protection is not available under 17 USC § 105. 6 | 7 | 8 | No Copyright Restrictions 2020 U.S. Federal Government 9 | 10 | 11 | # License Notice 12 | 13 | This project is distributed under the Creative Commons Zero (CC0) Universal 14 | version 1.0 (see below). swmm-toolkit also includes third-party software 15 | libraries which have separate licensing policies. 16 | 17 | 18 | 19 | # CC0 1.0 Universal 20 | 21 | ## Statement of Purpose 22 | 23 | The laws of most jurisdictions throughout the world automatically confer 24 | exclusive Copyright and Related Rights (defined below) upon the creator and 25 | subsequent owner(s) (each and all, an "owner") of an original work of 26 | authorship and/or a database (each, a "Work"). 27 | 28 | 29 | Certain owners wish to permanently relinquish those rights to a Work for the 30 | purpose of contributing to a commons of creative, cultural and scientific 31 | works ("Commons") that the public can reliably and without fear of later 32 | claims of infringement build upon, modify, incorporate in other works, reuse 33 | and redistribute as freely as possible in any form whatsoever and for any 34 | purposes, including without limitation commercial purposes. These owners may 35 | contribute to the Commons to promote the ideal of a free culture and the 36 | further production of creative, cultural and scientific works, or to gain 37 | reputation or greater distribution for their Work in part through the use and 38 | efforts of others. 39 | 40 | 41 | For these and/or other purposes and motivations, and without any expectation 42 | of additional consideration or compensation, the person associating CC0 with a 43 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 44 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 45 | and publicly distribute the Work under its terms, with knowledge of his or her 46 | Copyright and Related Rights in the Work and the meaning and intended legal 47 | effect of CC0 on those rights. 48 | 49 | 50 | 1. Copyright and Related Rights. A Work made available under CC0 may be 51 | protected by copyright and related or neighboring rights ("Copyright and 52 | Related Rights"). Copyright and Related Rights include, but are not limited 53 | to, the following: 54 | 55 | 56 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 57 | and translate a Work; 58 | 59 | 60 | ii. moral rights retained by the original author(s) and/or performer(s); 61 | 62 | 63 | iii. publicity and privacy rights pertaining to a person's image or likeness 64 | depicted in a Work; 65 | 66 | 67 | iv. rights protecting against unfair competition in regards to a Work, 68 | subject to the limitations in paragraph 4(a), below; 69 | 70 | 71 | v. rights protecting the extraction, dissemination, use and reuse of data in 72 | a Work; 73 | 74 | 75 | vi. database rights (such as those arising under Directive 96/9/EC of the 76 | European Parliament and of the Council of 11 March 1996 on the legal 77 | protection of databases, and under any national implementation thereof, 78 | including any amended or successor version of such directive); and 79 | 80 | 81 | vii. other similar, equivalent or corresponding rights throughout the world 82 | based on applicable law or treaty, and any national implementations thereof. 83 | 84 | 85 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 86 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 87 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 88 | and Related Rights and associated claims and causes of action, whether now 89 | known or unknown (including existing as well as future claims and causes of 90 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 91 | duration provided by applicable law or treaty (including future time 92 | extensions), (iii) in any current or future medium and for any number of 93 | copies, and (iv) for any purpose whatsoever, including without limitation 94 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 95 | the Waiver for the benefit of each member of the public at large and to the 96 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 97 | shall not be subject to revocation, rescission, cancellation, termination, or 98 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 99 | by the public as contemplated by Affirmer's express Statement of Purpose. 100 | 101 | 102 | 3. Public License Fallback. Should any part of the Waiver for any reason be 103 | judged legally invalid or ineffective under applicable law, then the Waiver 104 | shall be preserved to the maximum extent permitted taking into account 105 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 106 | is so judged Affirmer hereby grants to each affected person a royalty-free, 107 | non transferable, non sublicensable, non exclusive, irrevocable and 108 | unconditional license to exercise Affirmer's Copyright and Related Rights in 109 | the Work (i) in all territories worldwide, (ii) for the maximum duration 110 | provided by applicable law or treaty (including future time extensions), (iii) 111 | in any current or future medium and for any number of copies, and (iv) for any 112 | purpose whatsoever, including without limitation commercial, advertising or 113 | promotional purposes (the "License"). The License shall be deemed effective as 114 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 115 | License for any reason be judged legally invalid or ineffective under 116 | applicable law, such partial invalidity or ineffectiveness shall not 117 | invalidate the remainder of the License, and in such case Affirmer hereby 118 | affirms that he or she will not (i) exercise any of his or her remaining 119 | Copyright and Related Rights in the Work or (ii) assert any associated claims 120 | and causes of action with respect to the Work, in either case contrary to 121 | Affirmer's express Statement of Purpose. 122 | 123 | 124 | 4. Limitations and Disclaimers. 125 | 126 | 127 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 128 | surrendered, licensed or otherwise affected by this document. 129 | 130 | 131 | b. Affirmer offers the Work as-is and makes no representations or warranties 132 | of any kind concerning the Work, express, implied, statutory or otherwise, 133 | including without limitation warranties of title, merchantability, fitness 134 | for a particular purpose, non infringement, or the absence of latent or 135 | other defects, accuracy, or the present or absence of errors, whether or not 136 | discoverable, all to the greatest extent permissible under applicable law. 137 | 138 | 139 | c. Affirmer disclaims responsibility for clearing rights of other persons 140 | that may apply to the Work or any use thereof, including without limitation 141 | any person's Copyright and Related Rights in the Work. Further, Affirmer 142 | disclaims responsibility for obtaining any necessary consents, permissions 143 | or other rights required for any use of the Work. 144 | 145 | 146 | d. Affirmer understands and acknowledges that Creative Commons is not a 147 | party to this document and has no duty or obligation with respect to this 148 | CC0 or use of the Work. 149 | 150 | 151 | For more information, please see 152 | 153 | 154 | 155 | 156 | # Third-Party Libraries 157 | 158 | ## OWA SWMM 159 | 160 | ## OpenMP 161 | -------------------------------------------------------------------------------- /swmm-toolkit/README.md: -------------------------------------------------------------------------------- 1 | # swmm-toolkit 2 | 3 | `swmm-toolkit` contains SWIG generated Python wrappers for the swmm-solver and swmm-output libraries. 4 | 5 | 6 | ## Build Status 7 | 8 | ![Build Wheels](https://github.com/SWMM-Project/swmm-python/workflows/Build%20Wheels/badge.svg) 9 | 10 | 11 | ## Installation 12 | 13 | [![version](https://img.shields.io/pypi/v/swmm-toolkit.svg?maxAge=3600)](https://pypi.org/project/swmm-toolkit/) [![Downloads](https://pepy.tech/badge/swmm-toolkit)](https://pepy.tech/project/swmm-toolkit) 14 | 15 | ``pip install swmm-toolkit`` 16 | 17 | 18 | ## Features 19 | 20 | `swmm-toolkit` makes SWMM a fully fledged Python extension with: 21 | - Compatibility with USEPA SWMM 22 | - Python integration at the speed of C 23 | - Full access to library APIs 24 | - Pythonic naming, enums, exceptions, and return value handling 25 | 26 | 27 | ## Basic Usage 28 | 29 | Run a SWMM simulation. 30 | ``` 31 | from swmm.toolkit import solver 32 | 33 | solver.run('input_file.inp', 'report_file.rpt', 'output_file.out') 34 | ``` 35 | -------------------------------------------------------------------------------- /swmm-toolkit/build-requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | setuptools == 65.5.1 5 | wheel == 0.38.1 6 | scikit-build == 0.11.1 7 | cmake == 3.21 8 | swig == 4.0.2 -------------------------------------------------------------------------------- /swmm-toolkit/docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/apidoc/swmm.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | .. _api_documentation: 5 | 6 | API documentation 7 | =================== 8 | 9 | .. automodule:: swmm 10 | :members: 11 | :no-undoc-members: 12 | :show-inheritance: 13 | 14 | Subpackages 15 | ----------- 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | 20 | swmm.toolkit 21 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/apidoc/swmm.toolkit.output.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | swmm.toolkit.output module 4 | ========================== 5 | 6 | .. automodule:: swmm.toolkit.output 7 | :members: 8 | :no-undoc-members: 9 | :show-inheritance: 10 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/apidoc/swmm.toolkit.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | swmm.toolkit package 4 | ==================== 5 | 6 | .. automodule:: swmm.toolkit 7 | :members: 8 | :no-undoc-members: 9 | :show-inheritance: 10 | 11 | Submodules 12 | ---------- 13 | 14 | .. toctree:: 15 | 16 | swmm.toolkit.output 17 | swmm.toolkit.shared_enum 18 | swmm.toolkit.solver 19 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/apidoc/swmm.toolkit.shared_enum.rst: -------------------------------------------------------------------------------- 1 | 2 | swmm.toolkit.shared_enum module 3 | =============================== 4 | 5 | .. automodule:: swmm.toolkit.shared_enum 6 | :members: 7 | :no-undoc-members: 8 | :show-inheritance: -------------------------------------------------------------------------------- /swmm-toolkit/docs/apidoc/swmm.toolkit.solver.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | swmm.toolkit.solver module 4 | ========================== 5 | 6 | 7 | .. automodule:: swmm.toolkit.solver 8 | :members: 9 | :no-undoc-members: 10 | :show-inheritance: 11 | 12 | 13 | .. autoclass:: swmm.toolkit.solver.NodeStats 14 | .. autoclass:: swmm.toolkit.solver.StorageStats 15 | .. autoclass:: swmm.toolkit.solver.OutfallStats 16 | .. autoclass:: swmm.toolkit.solver.LinkStats 17 | .. autoclass:: swmm.toolkit.solver.PumpStats 18 | .. autoclass:: swmm.toolkit.solver.SubcatchStats 19 | .. autoclass:: swmm.toolkit.solver.RoutingTotals 20 | .. autoclass:: swmm.toolkit.solver.RunoffTotals 21 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | 13 | import os 14 | import sys 15 | sys.path.insert(0, os.path.abspath('../_skbuild/macosx-10.10-x86_64-3.7/cmake-install/src')) 16 | 17 | # -- Project information ----------------------------------------------------- 18 | 19 | project = 'swmm.toolkit' 20 | copyright = 'See LICENSE' 21 | author = 'See AUTHORS' 22 | 23 | # The full version, including alpha/beta/rc tags 24 | release = '0.5.0' 25 | 26 | 27 | # -- General configuration --------------------------------------------------- 28 | 29 | # Add any Sphinx extension module names here, as strings. They can be 30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 31 | # ones. 32 | extensions = [ 33 | 'sphinx.ext.autodoc', 34 | 'sphinx.ext.viewcode', 35 | 'sphinx.ext.autosummary', 36 | 'numpydoc', 37 | 'sphinx.ext.napoleon', 38 | 'sphinx.ext.intersphinx' 39 | ] 40 | 41 | napoleon_use_rtype = False 42 | viewcode_follow_imported_members = True 43 | numpydoc_show_class_members = True 44 | numpydoc_show_inherited_class_members = False 45 | numpydoc_class_members_toctree = False 46 | autodoc_member_order = 'bysource' 47 | autoclass_content = 'init' 48 | numfig=True 49 | numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'} 50 | 51 | # Add any paths that contain templates here, relative to this directory. 52 | templates_path = ['_templates'] 53 | 54 | # List of patterns, relative to source directory, that match files and 55 | # directories to ignore when looking for source files. 56 | # This pattern also affects html_static_path and html_extra_path. 57 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 58 | 59 | 60 | # -- Options for HTML output ------------------------------------------------- 61 | 62 | # The theme to use for HTML and HTML Help pages. See the documentation for 63 | # a list of builtin themes. 64 | # 65 | html_theme = 'sphinx_rtd_theme' 66 | 67 | # Add any paths that contain custom static files (such as style sheets) here, 68 | # relative to this directory. They are copied after the builtin static files, 69 | # so a file named "default.css" will overwrite the builtin "default.css". 70 | html_static_path = ['_static'] 71 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/index.rst: -------------------------------------------------------------------------------- 1 | .. swmm.toolkit documentation master file, created by 2 | sphinx-quickstart on Mon Jun 15 13:57:22 2020. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | 7 | Welcome to swmm.toolkit's documentation! 8 | ======================================== 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | :caption: Contents: 13 | 14 | API documentation 15 | 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | * :ref:`search` 23 | -------------------------------------------------------------------------------- /swmm-toolkit/docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /swmm-toolkit/extern/license-llvm-openmp.txt: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: 3 | ============================================================================== 4 | 5 | Apache License 6 | Version 2.0, January 2004 7 | http://www.apache.org/licenses/ 8 | 9 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 10 | 11 | 1. Definitions. 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, 14 | and distribution as defined by Sections 1 through 9 of this document. 15 | 16 | "Licensor" shall mean the copyright owner or entity authorized by 17 | the copyright owner that is granting the License. 18 | 19 | "Legal Entity" shall mean the union of the acting entity and all 20 | other entities that control, are controlled by, or are under common 21 | control with that entity. For the purposes of this definition, 22 | "control" means (i) the power, direct or indirect, to cause the 23 | direction or management of such entity, whether by contract or 24 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 25 | outstanding shares, or (iii) beneficial ownership of such entity. 26 | 27 | "You" (or "Your") shall mean an individual or Legal Entity 28 | exercising permissions granted by this License. 29 | 30 | "Source" form shall mean the preferred form for making modifications, 31 | including but not limited to software source code, documentation 32 | source, and configuration files. 33 | 34 | "Object" form shall mean any form resulting from mechanical 35 | transformation or translation of a Source form, including but 36 | not limited to compiled object code, generated documentation, 37 | and conversions to other media types. 38 | 39 | "Work" shall mean the work of authorship, whether in Source or 40 | Object form, made available under the License, as indicated by a 41 | copyright notice that is included in or attached to the work 42 | (an example is provided in the Appendix below). 43 | 44 | "Derivative Works" shall mean any work, whether in Source or Object 45 | form, that is based on (or derived from) the Work and for which the 46 | editorial revisions, annotations, elaborations, or other modifications 47 | represent, as a whole, an original work of authorship. For the purposes 48 | of this License, Derivative Works shall not include works that remain 49 | separable from, or merely link (or bind by name) to the interfaces of, 50 | the Work and Derivative Works thereof. 51 | 52 | "Contribution" shall mean any work of authorship, including 53 | the original version of the Work and any modifications or additions 54 | to that Work or Derivative Works thereof, that is intentionally 55 | submitted to Licensor for inclusion in the Work by the copyright owner 56 | or by an individual or Legal Entity authorized to submit on behalf of 57 | the copyright owner. For the purposes of this definition, "submitted" 58 | means any form of electronic, verbal, or written communication sent 59 | to the Licensor or its representatives, including but not limited to 60 | communication on electronic mailing lists, source code control systems, 61 | and issue tracking systems that are managed by, or on behalf of, the 62 | Licensor for the purpose of discussing and improving the Work, but 63 | excluding communication that is conspicuously marked or otherwise 64 | designated in writing by the copyright owner as "Not a Contribution." 65 | 66 | "Contributor" shall mean Licensor and any individual or Legal Entity 67 | on behalf of whom a Contribution has been received by Licensor and 68 | subsequently incorporated within the Work. 69 | 70 | 2. Grant of Copyright License. Subject to the terms and conditions of 71 | this License, each Contributor hereby grants to You a perpetual, 72 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 73 | copyright license to reproduce, prepare Derivative Works of, 74 | publicly display, publicly perform, sublicense, and distribute the 75 | Work and such Derivative Works in Source or Object form. 76 | 77 | 3. Grant of Patent License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | (except as stated in this section) patent license to make, have made, 81 | use, offer to sell, sell, import, and otherwise transfer the Work, 82 | where such license applies only to those patent claims licensable 83 | by such Contributor that are necessarily infringed by their 84 | Contribution(s) alone or by combination of their Contribution(s) 85 | with the Work to which such Contribution(s) was submitted. If You 86 | institute patent litigation against any entity (including a 87 | cross-claim or counterclaim in a lawsuit) alleging that the Work 88 | or a Contribution incorporated within the Work constitutes direct 89 | or contributory patent infringement, then any patent licenses 90 | granted to You under this License for that Work shall terminate 91 | as of the date such litigation is filed. 92 | 93 | 4. Redistribution. You may reproduce and distribute copies of the 94 | Work or Derivative Works thereof in any medium, with or without 95 | modifications, and in Source or Object form, provided that You 96 | meet the following conditions: 97 | 98 | (a) You must give any other recipients of the Work or 99 | Derivative Works a copy of this License; and 100 | 101 | (b) You must cause any modified files to carry prominent notices 102 | stating that You changed the files; and 103 | 104 | (c) You must retain, in the Source form of any Derivative Works 105 | that You distribute, all copyright, patent, trademark, and 106 | attribution notices from the Source form of the Work, 107 | excluding those notices that do not pertain to any part of 108 | the Derivative Works; and 109 | 110 | (d) If the Work includes a "NOTICE" text file as part of its 111 | distribution, then any Derivative Works that You distribute must 112 | include a readable copy of the attribution notices contained 113 | within such NOTICE file, excluding those notices that do not 114 | pertain to any part of the Derivative Works, in at least one 115 | of the following places: within a NOTICE text file distributed 116 | as part of the Derivative Works; within the Source form or 117 | documentation, if provided along with the Derivative Works; or, 118 | within a display generated by the Derivative Works, if and 119 | wherever such third-party notices normally appear. The contents 120 | of the NOTICE file are for informational purposes only and 121 | do not modify the License. You may add Your own attribution 122 | notices within Derivative Works that You distribute, alongside 123 | or as an addendum to the NOTICE text from the Work, provided 124 | that such additional attribution notices cannot be construed 125 | as modifying the License. 126 | 127 | You may add Your own copyright statement to Your modifications and 128 | may provide additional or different license terms and conditions 129 | for use, reproduction, or distribution of Your modifications, or 130 | for any such Derivative Works as a whole, provided Your use, 131 | reproduction, and distribution of the Work otherwise complies with 132 | the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, 135 | any Contribution intentionally submitted for inclusion in the Work 136 | by You to the Licensor shall be under the terms and conditions of 137 | this License, without any additional terms or conditions. 138 | Notwithstanding the above, nothing herein shall supersede or modify 139 | the terms of any separate license agreement you may have executed 140 | with Licensor regarding such Contributions. 141 | 142 | 6. Trademarks. This License does not grant permission to use the trade 143 | names, trademarks, service marks, or product names of the Licensor, 144 | except as required for reasonable and customary use in describing the 145 | origin of the Work and reproducing the content of the NOTICE file. 146 | 147 | 7. Disclaimer of Warranty. Unless required by applicable law or 148 | agreed to in writing, Licensor provides the Work (and each 149 | Contributor provides its Contributions) on an "AS IS" BASIS, 150 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 151 | implied, including, without limitation, any warranties or conditions 152 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 153 | PARTICULAR PURPOSE. You are solely responsible for determining the 154 | appropriateness of using or redistributing the Work and assume any 155 | risks associated with Your exercise of permissions under this License. 156 | 157 | 8. Limitation of Liability. In no event and under no legal theory, 158 | whether in tort (including negligence), contract, or otherwise, 159 | unless required by applicable law (such as deliberate and grossly 160 | negligent acts) or agreed to in writing, shall any Contributor be 161 | liable to You for damages, including any direct, indirect, special, 162 | incidental, or consequential damages of any character arising as a 163 | result of this License or out of the use or inability to use the 164 | Work (including but not limited to damages for loss of goodwill, 165 | work stoppage, computer failure or malfunction, or any and all 166 | other commercial damages or losses), even if such Contributor 167 | has been advised of the possibility of such damages. 168 | 169 | 9. Accepting Warranty or Additional Liability. While redistributing 170 | the Work or Derivative Works thereof, You may choose to offer, 171 | and charge a fee for, acceptance of support, warranty, indemnity, 172 | or other liability obligations and/or rights consistent with this 173 | License. However, in accepting such obligations, You may act only 174 | on Your own behalf and on Your sole responsibility, not on behalf 175 | of any other Contributor, and only if You agree to indemnify, 176 | defend, and hold each Contributor harmless for any liability 177 | incurred by, or claims asserted against, such Contributor by reason 178 | of your accepting any such warranty or additional liability. 179 | 180 | END OF TERMS AND CONDITIONS 181 | 182 | APPENDIX: How to apply the Apache License to your work. 183 | 184 | To apply the Apache License to your work, attach the following 185 | boilerplate notice, with the fields enclosed by brackets "[]" 186 | replaced with your own identifying information. (Don't include 187 | the brackets!) The text should be enclosed in the appropriate 188 | comment syntax for the file format. We also recommend that a 189 | file or class name and description of purpose be included on the 190 | same "printed page" as the copyright notice for easier 191 | identification within third-party archives. 192 | 193 | Copyright [yyyy] [name of copyright owner] 194 | 195 | Licensed under the Apache License, Version 2.0 (the "License"); 196 | you may not use this file except in compliance with the License. 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | See the License for the specific language governing permissions and 205 | limitations under the License. 206 | 207 | 208 | ---- LLVM Exceptions to the Apache 2.0 License ---- 209 | 210 | As an exception, if, as a result of your compiling your source code, portions 211 | of this Software are embedded into an Object form of such source code, you 212 | may redistribute such embedded portions in such Object form without complying 213 | with the conditions of Sections 4(a), 4(b) and 4(d) of the License. 214 | 215 | In addition, if you combine or link compiled forms of this Software with 216 | software that is licensed under the GPLv2 ("Combined Software") and if a 217 | court of competent jurisdiction determines that the patent provision (Section 218 | 3), the indemnity provision (Section 9) or other Section of the License 219 | conflicts with the conditions of the GPLv2, you may retroactively and 220 | prospectively choose to deem waived or otherwise exclude such Section(s) of 221 | the License, but only in their entirety and only with respect to the Combined 222 | Software. 223 | 224 | ============================================================================== 225 | Software from third parties included in the LLVM Project: 226 | ============================================================================== 227 | The LLVM Project contains third party software which is under different license 228 | terms. All such code will be identified clearly using at least one of two 229 | mechanisms: 230 | 1) It will be in a separate directory tree with its own `LICENSE.txt` or 231 | `LICENSE` file at the top containing the specific license and restrictions 232 | which apply to that software, or 233 | 2) It will contain specific license and restriction terms at the top of every 234 | file. 235 | 236 | ============================================================================== 237 | Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): 238 | ============================================================================== 239 | 240 | The software contained in this directory tree is dual licensed under both the 241 | University of Illinois "BSD-Like" license and the MIT license. As a user of 242 | this code you may choose to use it under either license. As a contributor, 243 | you agree to allow your code to be used under both. The full text of the 244 | relevant licenses is included below. 245 | 246 | In addition, a license agreement from the copyright/patent holders of the 247 | software contained in this directory tree is included below. 248 | 249 | ============================================================================== 250 | 251 | University of Illinois/NCSA 252 | Open Source License 253 | 254 | Copyright (c) 1997-2019 Intel Corporation 255 | 256 | All rights reserved. 257 | 258 | Developed by: 259 | OpenMP Runtime Team 260 | Intel Corporation 261 | http://www.openmprtl.org 262 | 263 | Permission is hereby granted, free of charge, to any person obtaining a copy of 264 | this software and associated documentation files (the "Software"), to deal with 265 | the Software without restriction, including without limitation the rights to 266 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 267 | of the Software, and to permit persons to whom the Software is furnished to do 268 | so, subject to the following conditions: 269 | 270 | * Redistributions of source code must retain the above copyright notice, 271 | this list of conditions and the following disclaimers. 272 | 273 | * Redistributions in binary form must reproduce the above copyright notice, 274 | this list of conditions and the following disclaimers in the 275 | documentation and/or other materials provided with the distribution. 276 | 277 | * Neither the names of Intel Corporation OpenMP Runtime Team nor the 278 | names of its contributors may be used to endorse or promote products 279 | derived from this Software without specific prior written permission. 280 | 281 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 282 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 283 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 284 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 285 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 286 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 287 | SOFTWARE. 288 | 289 | ============================================================================== 290 | 291 | Copyright (c) 1997-2019 Intel Corporation 292 | 293 | Permission is hereby granted, free of charge, to any person obtaining a copy 294 | of this software and associated documentation files (the "Software"), to deal 295 | in the Software without restriction, including without limitation the rights 296 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 297 | copies of the Software, and to permit persons to whom the Software is 298 | furnished to do so, subject to the following conditions: 299 | 300 | The above copyright notice and this permission notice shall be included in 301 | all copies or substantial portions of the Software. 302 | 303 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 304 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 305 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 306 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 307 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 308 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 309 | THE SOFTWARE. 310 | 311 | ============================================================================== 312 | 313 | Intel Corporation 314 | 315 | Software Grant License Agreement ("Agreement") 316 | 317 | Except for the license granted herein to you, Intel Corporation ("Intel") reserves 318 | all right, title, and interest in and to the Software (defined below). 319 | 320 | Definition 321 | 322 | "Software" means the code and documentation as well as any original work of 323 | authorship, including any modifications or additions to an existing work, that 324 | is intentionally submitted by Intel to llvm.org (http://llvm.org) ("LLVM") for 325 | inclusion in, or documentation of, any of the products owned or managed by LLVM 326 | (the "Work"). For the purposes of this definition, "submitted" means any form of 327 | electronic, verbal, or written communication sent to LLVM or its 328 | representatives, including but not limited to communication on electronic 329 | mailing lists, source code control systems, and issue tracking systems that are 330 | managed by, or on behalf of, LLVM for the purpose of discussing and improving 331 | the Work, but excluding communication that is conspicuously marked otherwise. 332 | 333 | 1. Grant of Copyright License. Subject to the terms and conditions of this 334 | Agreement, Intel hereby grants to you and to recipients of the Software 335 | distributed by LLVM a perpetual, worldwide, non-exclusive, no-charge, 336 | royalty-free, irrevocable copyright license to reproduce, prepare derivative 337 | works of, publicly display, publicly perform, sublicense, and distribute the 338 | Software and such derivative works. 339 | 340 | 2. Grant of Patent License. Subject to the terms and conditions of this 341 | Agreement, Intel hereby grants you and to recipients of the Software 342 | distributed by LLVM a perpetual, worldwide, non-exclusive, no-charge, 343 | royalty-free, irrevocable (except as stated in this section) patent license 344 | to make, have made, use, offer to sell, sell, import, and otherwise transfer 345 | the Work, where such license applies only to those patent claims licensable 346 | by Intel that are necessarily infringed by Intel's Software alone or by 347 | combination of the Software with the Work to which such Software was 348 | submitted. If any entity institutes patent litigation against Intel or any 349 | other entity (including a cross-claim or counterclaim in a lawsuit) alleging 350 | that Intel's Software, or the Work to which Intel has contributed constitutes 351 | direct or contributory patent infringement, then any patent licenses granted 352 | to that entity under this Agreement for the Software or Work shall terminate 353 | as of the date such litigation is filed. 354 | 355 | Unless required by applicable law or agreed to in writing, the software is 356 | provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 357 | either express or implied, including, without limitation, any warranties or 358 | conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 359 | PARTICULAR PURPOSE. 360 | 361 | ============================================================================== 362 | -------------------------------------------------------------------------------- /swmm-toolkit/extern/openmp.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # CMakeLists.txt - CMake configuration file for OpenMP Library on Darwin 3 | # 4 | # Created: Mar 17, 2021 5 | # Updated: May 19, 2021 6 | # 7 | # Author: Michael E. Tryby 8 | # US EPA ORD/CESER 9 | # 10 | # Note: 11 | # Need to build libomp for binary compatibility with Python. 12 | # 13 | # OpenMP library build fails for Xcode generator. Use Ninja or Unix Makefiles 14 | # instead. 15 | # 16 | # All sources were obtained directly from the LLVM releases on github 17 | # See license-llvm-openmp.txt for the corresponding license and 18 | # https://openmp.llvm.org/ for details on the OpenMP run-time. 19 | 20 | ################################################################################ 21 | ##################### CMAKELISTS FOR OPENMP LIBRARY ###################### 22 | ################################################################################ 23 | 24 | include(FetchContent) 25 | 26 | 27 | FetchContent_Declare(OpenMP 28 | URL 29 | https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.1/openmp-12.0.1.src.tar.xz 30 | URL_HASH 31 | SHA256=60fe79440eaa9ebf583a6ea7f81501310388c02754dbe7dc210776014d06b091 32 | ) 33 | 34 | set(OPENMP_STANDALONE_BUILD TRUE) 35 | set(LIBOMP_INSTALL_ALIASES OFF) 36 | 37 | FetchContent_MakeAvailable(OpenMP) 38 | set(OpenMP_AVAILABLE TRUE) 39 | 40 | 41 | target_link_directories(omp 42 | PUBLIC 43 | $ 44 | $ 45 | ) 46 | 47 | install(TARGETS omp 48 | LIBRARY 49 | DESTINATION 50 | "${LIBRARY_DIST}" 51 | ) 52 | 53 | if(CMAKE_C_COMPILER_ID MATCHES "Clang\$") 54 | set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I${CMAKE_BINARY_DIR}/_deps/openmp-build/runtime/src") 55 | set(OpenMP_C_LIB_NAMES "omp") 56 | set(OpenMP_omp_LIBRARY "${CMAKE_BINARY_DIR}/_deps/openmp-build/runtime/src/libomp.dylib") 57 | endif() 58 | 59 | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang\$") 60 | set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${CMAKE_BINARY_DIR}/_deps/openmp-build/runtime/src") 61 | set(OpenMP_CXX_LIB_NAMES "omp") 62 | set(OpenMP_omp_LIBRARY "${CMAKE_BINARY_DIR}/_deps/openmp-build/runtime/src/libomp.dylib") 63 | endif() -------------------------------------------------------------------------------- /swmm-toolkit/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "wheel>=0.38.1", 4 | "setuptools>=42", 5 | "scikit-build>=0.13", 6 | "cmake>=3.21", 7 | "swig==4.0.2", 8 | "ninja==1.11.1 ; sys_platform == 'darwin'" 9 | ] 10 | build-backend = "setuptools.build_meta" -------------------------------------------------------------------------------- /swmm-toolkit/setup.py: -------------------------------------------------------------------------------- 1 | # 2 | # setup.py - Setup script for swmm-toolkit python package 3 | # 4 | # Created: Jul 2, 2018 5 | # Updated: Jun 7, 2021 6 | # 7 | # Author: See AUTHORS 8 | # 9 | # Suggested Usage: 10 | # python setup.py build 11 | # python setup.py bdist_wheel 12 | # python setup.py sdist 13 | # python setup.py clean 14 | # 15 | 16 | import platform 17 | import subprocess 18 | import pathlib 19 | import os 20 | from skbuild import setup 21 | from setuptools import Command 22 | import sys 23 | 24 | # Determine platform 25 | platform_system = platform.system() 26 | 27 | 28 | class CleanCommand(Command): 29 | ''' Cleans project tree ''' 30 | user_options = [] 31 | 32 | def initialize_options(self): 33 | pass 34 | 35 | def finalize_options(self): 36 | pass 37 | 38 | def run(self): 39 | if platform_system == "Windows": 40 | cmd = ['del' '/Q', 'tests\\data\\temp_*.*' '&&' \ 41 | 'rd' '/s/q', '_cmake_test_compile', '_skbuild', 'dist', '.pytest_cache', \ 42 | 'src\\swmm\\toolkit\\swmm_toolkit.egg-info', 'tests\\__pycache__'] 43 | exe = "C:\\Windows\\System32\\cmd.exe" 44 | 45 | elif platform_system == "Linux": 46 | cmd = ["rm -vrf _skbuild/ dist/ **/build .pytest_cache/ **/__pycache__ \ 47 | **/*.egg-info **/data/temp_*.* **/data/en* **/.DS_Store MANIFEST"] 48 | exe = "/bin/bash" 49 | 50 | elif platform_system == "Darwin": 51 | cmd = ['setopt extended_glob nullglob; rm -vrf _skbuild dist **/build .pytest_cache \ 52 | **/__pycache__ **/*.egg-info **/data/(^test_*).* **/data/en* **/.DS_Store MANIFEST'] 53 | exe = '/bin/zsh' 54 | 55 | p = subprocess.Popen(cmd, shell=True, executable=exe) 56 | p.wait() 57 | 58 | 59 | # Set up location of wheel libraries depending on build platform and command 60 | # commands that trigger cmake from skbuild.setuptools_wrap._should_run_cmake 61 | commands_that_trigger_cmake = { 62 | "build", 63 | "build_ext", 64 | "develop", 65 | "install", 66 | "install_lib", 67 | "bdist", 68 | "bdist_dumb", 69 | "bdist_egg", 70 | "bdist_rpm", 71 | "bdist_wininst", 72 | "bdist_wheel", 73 | "test", 74 | } 75 | command = sys.argv[1] if len(sys.argv) > 1 else None 76 | if command in commands_that_trigger_cmake: 77 | swmm_toolkit_dir= "bin" if platform_system == "Windows" else "lib" 78 | else: 79 | swmm_toolkit_dir= "swmm-solver" 80 | package_dir = {"swmm_toolkit" : swmm_toolkit_dir, "swmm.toolkit": "src/swmm/toolkit"} 81 | 82 | 83 | if os.environ.get('SWMM_CMAKE_ARGS') is not None: 84 | cmake_args = os.environ.get('SWMM_CMAKE_ARGS').split() 85 | 86 | # Set Platform specific cmake args here 87 | elif platform_system == "Windows": 88 | cmake_args = ["-GVisual Studio 17 2022","-Ax64"] 89 | 90 | elif platform_system == "Darwin": 91 | cmake_args = ["-GNinja","-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9"] 92 | 93 | else: 94 | cmake_args = ["-GUnix Makefiles"] 95 | 96 | 97 | # Filters cmake manifest for wheel build 98 | def exclude_files(cmake_manifest): 99 | print("INFO: processing cmake manifest") 100 | exclude_pats = ('runswmm', '.exe', '.cmake', '.h', '.lib') 101 | return list(filter(lambda name: not (name.endswith(exclude_pats)), cmake_manifest)) 102 | 103 | 104 | # Get the long description from the README file 105 | here = pathlib.Path(__file__).parent.resolve() 106 | long_description = (here / 'README.md').read_text(encoding='utf-8') 107 | 108 | if platform_system == "Darwin": 109 | license_files = ['LICENSE.md', 'extern/license-llvm-openmp.txt'] 110 | else: 111 | license_files = ['LICENSE.md'] 112 | 113 | setup( 114 | name = "swmm-toolkit", 115 | version = "0.15.5", 116 | 117 | packages = ["swmm_toolkit", "swmm.toolkit"], 118 | package_dir = package_dir, 119 | 120 | zip_safe = False, 121 | install_requires = ["aenum==3.1.11"], 122 | 123 | cmdclass = {"clean": CleanCommand}, 124 | cmake_args = cmake_args, 125 | cmake_process_manifest_hook = exclude_files, 126 | 127 | description='PySWMM SWMM Python Toolkit', 128 | long_description=long_description, 129 | long_description_content_type='text/markdown', 130 | url='https://github.com/pyswmm/swmm-python', 131 | 132 | author='See AUTHORS', 133 | maintainer_email='bemcdonnell@gmail.com', 134 | license='CC0', 135 | license_files=license_files, 136 | keywords="swmm5, swmm, stormwater, hydraulics, hydrology", 137 | classifiers=[ 138 | "Topic :: Scientific/Engineering", 139 | "Operating System :: Microsoft :: Windows", 140 | "Operating System :: POSIX :: Linux", 141 | "Operating System :: MacOS", 142 | "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", 143 | "Programming Language :: Python :: 3.7", 144 | "Programming Language :: Python :: 3.8", 145 | "Programming Language :: Python :: 3.9", 146 | "Programming Language :: Python :: 3.10", 147 | "Programming Language :: Python :: 3.11", 148 | "Programming Language :: Python :: 3.12", 149 | "Programming Language :: C", 150 | "Development Status :: 5 - Production/Stable", 151 | ] 152 | ) 153 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # CMakeLists.txt - CMake configuration file for swmm.toolkit python package 3 | # 4 | # Created: Feb 6, 2020 5 | # Updated: May 19, 2021 6 | # 7 | # Author: See AUTHORS 8 | # 9 | 10 | ################################################################################ 11 | ################# CMAKELISTS FOR SWMM-TOOLKIT EXT BUILD ################## 12 | ################################################################################ 13 | 14 | 15 | set(CMAKE_SWIG_FLAGS -py3) 16 | 17 | # Determine filename suffix for python extension 18 | if(WIN32) 19 | set(LIB_EXT "pyd") 20 | else() 21 | set(LIB_EXT "so") 22 | endif() 23 | set(PYTHON_SUFFIX ".${Python3_SOABI}.${LIB_EXT}") 24 | 25 | 26 | # Location of package at runtime on MacOS/Linux 27 | if(APPLE) 28 | set(LIB_ROOT "@loader_path") 29 | else() 30 | set(LIB_ROOT "$ORIGIN") 31 | endif() 32 | 33 | # Set up rpath on MacOS and Linux 34 | set(PACKAGE_RPATH 35 | "${LIB_ROOT}/../../swmm_toolkit/" 36 | ) 37 | 38 | 39 | ############################################################# 40 | #################### OUTPUT TARGET #################### 41 | ############################################################# 42 | 43 | set_property(SOURCE output.i 44 | PROPERTY 45 | USE_TARGET_INCLUDE_DIRECTORIES ON 46 | ) 47 | 48 | swig_add_library(output 49 | TYPE 50 | MODULE 51 | LANGUAGE 52 | python 53 | SOURCES 54 | output.i 55 | ) 56 | 57 | 58 | target_link_options(output 59 | PUBLIC 60 | $<$:-undefineddynamic_lookup> 61 | ) 62 | 63 | target_include_directories(output 64 | PUBLIC 65 | ${Python3_INCLUDE_DIRS} 66 | ) 67 | 68 | target_link_libraries(output 69 | PUBLIC 70 | $<$>:Python3::Module> 71 | swmm-output 72 | ) 73 | 74 | set_target_properties(output 75 | PROPERTIES 76 | SUFFIX ${PYTHON_SUFFIX} 77 | SWIG_COMPILE_DEFINITIONS EXPORT_OUT_API 78 | MACOSX_RPATH TRUE 79 | SKIP_BUILD_RPATH FALSE 80 | BUILD_WITH_INSTALL_RPATH FALSE 81 | INSTALL_RPATH "${PACKAGE_RPATH}" 82 | INSTALL_RPATH_USE_LINK_PATH TRUE 83 | ) 84 | 85 | install( 86 | FILES 87 | "__init__.py" 88 | "shared_enum.py" 89 | "output_metadata.py" 90 | "${CMAKE_CURRENT_BINARY_DIR}/output.py" 91 | DESTINATION 92 | "src/swmm/toolkit" 93 | ) 94 | 95 | install( 96 | TARGETS 97 | output 98 | DESTINATION 99 | "src/swmm/toolkit" 100 | ) 101 | 102 | ############################################################# 103 | #################### SOLVER TARGET #################### 104 | ############################################################# 105 | 106 | 107 | set_property(SOURCE solver.i 108 | PROPERTY 109 | USE_TARGET_INCLUDE_DIRECTORIES ON 110 | ) 111 | 112 | swig_add_library(solver 113 | TYPE 114 | MODULE 115 | LANGUAGE 116 | python 117 | SOURCES 118 | solver.i 119 | ) 120 | 121 | 122 | target_link_options(solver 123 | PUBLIC 124 | $<$:-undefineddynamic_lookup> 125 | ) 126 | 127 | target_include_directories(solver 128 | PUBLIC 129 | ${Python3_INCLUDE_DIRS} 130 | ) 131 | 132 | target_link_libraries(solver 133 | PUBLIC 134 | $<$>:Python3::Module> 135 | swmm5 136 | $<$:OpenMP::OpenMP_C> 137 | ) 138 | 139 | set_target_properties(solver 140 | PROPERTIES 141 | SUFFIX ${PYTHON_SUFFIX} 142 | SWIG_COMPILE_DEFINITIONS EXPORT_TOOLKIT 143 | MACOSX_RPATH TRUE 144 | SKIP_BUILD_RPATH FALSE 145 | BUILD_WITH_INSTALL_RPATH FALSE 146 | INSTALL_RPATH "${PACKAGE_RPATH}" 147 | INSTALL_RPATH_USE_LINK_PATH TRUE 148 | ) 149 | 150 | 151 | # Stages python module for package build 152 | install( 153 | FILES 154 | "${CMAKE_CURRENT_BINARY_DIR}/solver.py" 155 | DESTINATION 156 | "src/swmm/toolkit" 157 | ) 158 | 159 | # Stages extension library for package build 160 | install( 161 | TARGETS 162 | solver 163 | DESTINATION 164 | "src/swmm/toolkit" 165 | ) 166 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # 4 | # __init__.py - SWMM toolkit package 5 | # 6 | # Created: Aug 9, 2018 7 | # Updated: July 2, 2022 8 | # 9 | # Author: See AUTHORS 10 | # 11 | 12 | """ 13 | A low level pythonic API for the swmm-output and swmm-solver dlls using SWIG. 14 | """ 15 | 16 | 17 | __author__ = "See AUTHORS" 18 | __copyright__ = "None" 19 | __credits__ = "Colleen Barr, Sam Hatchett" 20 | __license__ = "CC0 1.0 Universal" 21 | 22 | __version__ = "0.15.5" 23 | __date__ = "June 7, 2021" 24 | 25 | __maintainer__ = "Michael Tryby" 26 | __email__ = "tryby.michael@epa.gov" 27 | __status__ = "Beta" 28 | 29 | 30 | import os 31 | import platform 32 | import sys 33 | 34 | 35 | # Adds directory containing swmm libraries to path 36 | if platform.system() == "Windows": 37 | libdir = os.path.join(os.path.dirname(__file__), "../../swmm_toolkit") 38 | 39 | if hasattr(os, 'add_dll_directory'): 40 | conda_exists = os.path.exists(os.path.join(sys.prefix, 'conda-meta')) 41 | if conda_exists: 42 | os.environ['CONDA_DLL_SEARCH_MODIFICATION_ENABLE'] = "1" 43 | os.add_dll_directory(libdir) 44 | else: 45 | os.environ["PATH"] = libdir + ";" + os.environ["PATH"] 46 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/output.i: -------------------------------------------------------------------------------- 1 | /* 2 | * output.i - SWIG interface description file for swmm-output 3 | * 4 | * Created: November 3, 2017 5 | * Updated: February 21, 2020 6 | * 7 | * Author: See AUTHORS 8 | * 9 | */ 10 | 11 | 12 | %include "typemaps.i" 13 | %include "cstring.i" 14 | 15 | 16 | /* Docstrings for module */ 17 | %include "output_docs.i" 18 | 19 | %module(package="swmm.toolkit", docstring=OUTPUT_MODULE_DOCS) output 20 | %{ 21 | #define SWIG_FILE_WITH_INIT 22 | 23 | #include "swmm_output_enums.h" 24 | #include "swmm_output.h" 25 | %} 26 | 27 | /* RENAME FUNCTIONS PYTHON STYLE */ 28 | //%rename("%(regex:/^\w+_([a-zA-Z]+)/\L\\1/)s") ""; 29 | %include "output_rename.i" 30 | 31 | 32 | /* MARK FUNCTIONS FOR ALLOCATING AND DEALLOCATING HANDLES */ 33 | %newobject SMO_init; 34 | %delobject SMO_close; 35 | 36 | 37 | /* TYPEMAPS FOR HANDLE POINTER */ 38 | /* Used for functions that output a new opaque pointer */ 39 | %typemap(in,numinputs=0) SMO_Handle *p_handle (SMO_Handle temp) { 40 | $1 = &temp; 41 | } 42 | /* used for functions that take in an opaque pointer (or NULL) 43 | and return a (possibly) different pointer */ 44 | %typemap(argout) SMO_Handle *p_handle { 45 | %append_output(SWIG_NewPointerObj(*$1, SWIGTYPE_p_Handle, SWIG_POINTER_NEW)); 46 | } 47 | 48 | 49 | /* TYPEMAP FOR IGNORING INT ERROR CODE RETURN VALUE */ 50 | %typemap(out) int { 51 | $result = Py_None; 52 | Py_INCREF($result); 53 | } 54 | 55 | 56 | /* APPLY MACROS FOR OUTPUT VARIABLES */ 57 | %apply double *OUTPUT { 58 | double *date 59 | } 60 | 61 | %apply int *OUTPUT { 62 | int *version, 63 | int *time 64 | } 65 | 66 | %cstring_output_allocate_size(char **elementName, int *size, SMO_freeMemory(*$1)); 67 | 68 | 69 | /* TYPEMAPS FOR MEMORY MANAGEMNET OF FLOAT ARRAYS */ 70 | %typemap(in, numinputs=0)float **float_out (float *temp), int *int_dim (int temp){ 71 | $1 = &temp; 72 | } 73 | %typemap(argout) (float **float_out, int *int_dim) { 74 | if (*$1) { 75 | PyObject *o = PyList_New(*$2); 76 | float* temp = *$1; 77 | for(int i=0; i<*$2; i++) { 78 | PyList_SetItem(o, i, PyFloat_FromDouble((double)temp[i])); 79 | } 80 | $result = SWIG_Python_AppendOutput($result, o); 81 | SMO_freeMemory(*$1); 82 | } 83 | } 84 | 85 | 86 | /* TYPEMAPS FOR MEMORY MANAGEMENT OF INT ARRAYS */ 87 | %typemap(in, numinputs=0)int **int_out (int *temp), int *int_dim (int temp){ 88 | $1 = &temp; 89 | } 90 | %typemap(argout) (int **int_out, int *int_dim) { 91 | if (*$1) { 92 | int *temp = *$1; 93 | PyObject *o = PyList_New(*$2); 94 | for(int i=0; i<*$2; i++) { 95 | PyList_SetItem(o, i, PyInt_FromLong((long)temp[i])); 96 | } 97 | $result = SWIG_Python_AppendOutput($result, o); 98 | SMO_freeMemory(*$1); 99 | } 100 | } 101 | 102 | 103 | /* TYPEMAP FOR ENUMERATED TYPE INPUT ARGUMENTS */ 104 | %typemap(in) EnumTypeIn { 105 | int value = 0; 106 | if (PyObject_HasAttrString($input, "value")) { 107 | PyObject *o = PyObject_GetAttrString($input, "value"); 108 | SWIG_AsVal_int(o, &value); 109 | } 110 | $1 = ($1_basetype)(value); 111 | } 112 | %apply EnumTypeIn { 113 | SMO_unit, 114 | SMO_elementType, 115 | SMO_time, 116 | SMO_subcatchAttribute, 117 | SMO_nodeAttribute, 118 | SMO_linkAttribute, 119 | SMO_systemAttribute 120 | } 121 | 122 | 123 | /* INSERTS CUSTOM EXCEPTION HANDLING IN WRAPPER */ 124 | %exception SMO_init 125 | { 126 | $function 127 | } 128 | 129 | %exception SMO_close 130 | { 131 | $function 132 | } 133 | 134 | %exception 135 | { 136 | char *err_msg; 137 | SMO_clearError(arg1); 138 | $function 139 | if (SMO_checkError(arg1, &err_msg)) 140 | { 141 | PyErr_SetString(PyExc_Exception, err_msg); 142 | SMO_freeMemory((void *)err_msg); 143 | SWIG_fail; 144 | } 145 | } 146 | 147 | /* INSERT EXCEPTION HANDLING FOR THESE FUNCTIONS */ 148 | 149 | %ignore SMO_freeMemory; 150 | %ignore SMO_clearError; 151 | %ignore SMO_checkError; 152 | 153 | %include "swmm_output.h" 154 | 155 | %exception; 156 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/output_docs.i: -------------------------------------------------------------------------------- 1 | /* 2 | * output_docs.i - Documentation for swmm-output 3 | * 4 | * Created: 12/10/2020 5 | * 6 | * Author: See AUTHORS 7 | * 8 | */ 9 | 10 | 11 | %define OUTPUT_MODULE_DOCS 12 | "Output Module 13 | " 14 | %enddef 15 | 16 | 17 | %feature("autodoc", 18 | "Initialize pointer for output handle. 19 | 20 | Returns 21 | ------- 22 | p_handle: SMO_Handle * 23 | A SWMM output handle 24 | " 25 | ) SMO_init; 26 | 27 | 28 | %feature("autodoc", 29 | "Open binary output file and reads prologue and epilogue. 30 | 31 | Parameters 32 | ---------- 33 | p_handle: SMO_Handle 34 | A SWMM output handle 35 | path: char const * 36 | The name of the binary output file to be opened. 37 | " 38 | ) SMO_open; 39 | 40 | 41 | %feature("autodoc", 42 | "Close binary output file and perform cleanup. 43 | 44 | Parameters 45 | ---------- 46 | p_handle: SMO_Handle 47 | A SWMM output handle 48 | " 49 | ) SMO_close; 50 | 51 | 52 | %feature("autodoc", 53 | "Get the SWMM version that produced the binary output file. 54 | 55 | Parameters 56 | ---------- 57 | p_handle: SMO_Handle 58 | A SWMM output handle 59 | 60 | Returns 61 | ------- 62 | version: int * 63 | The SWMM version number found in the output file prologue. 64 | 65 | " 66 | ) SMO_getVersion; 67 | 68 | 69 | %feature("autodoc", 70 | "Project element counts. 71 | 72 | Parameters 73 | ---------- 74 | p_handle: SMO_Handle 75 | A SWMM output handle 76 | 77 | Returns 78 | ------- 79 | elementCount:int ** 80 | Array of element count values 81 | length:int * 82 | Array size 83 | " 84 | ) SMO_getProjectSize; 85 | 86 | 87 | %feature("autodoc", 88 | "Project unit flags for unit_system, flow, and pollutants. 89 | 90 | Parameters 91 | ---------- 92 | p_handle: SMO_Handle 93 | A SWMM output handle 94 | 95 | Returns 96 | ------- 97 | unitFlag: int ** 98 | Array of unit flag values 99 | length: int * 100 | Array length 101 | " 102 | ) SMO_getUnits; 103 | 104 | 105 | %feature("autodoc", 106 | "Analysis start date. 107 | 108 | Parameters 109 | ---------- 110 | p_handle: SMO_Handle 111 | A SWMM output handle 112 | 113 | Returns 114 | ------- 115 | date: double * 116 | SWMM simulation start date (encoded) 117 | " 118 | ) SMO_getStartDate; 119 | 120 | 121 | %feature("autodoc", 122 | "Analysis step size and number of periods. 123 | 124 | Parameters 125 | ---------- 126 | p_handle: SMO_Handle 127 | A SWMM output handle 128 | code: SMO_time 129 | A time parameter code (see :ref: SMO_Time) 130 | 131 | Returns 132 | ------- 133 | time: int * 134 | Time value 135 | " 136 | ) SMO_getTimes; 137 | 138 | 139 | %feature("autodoc", 140 | "Given an element index returns the element name. 141 | 142 | Parameters 143 | ---------- 144 | p_handle: SMO_Handle 145 | A SWMM output handle 146 | type: SMO_elementType 147 | The type of the element being queried 148 | elementIndex: int 149 | The index of the element being queried 150 | 151 | Returns 152 | ------- 153 | name: char ** 154 | Element name array 155 | length: int * 156 | Length of array 157 | " 158 | ) SMO_getElementName; 159 | 160 | 161 | %feature("autodoc", 162 | "Get time series results for particular attribute. Specify series start and 163 | length using timeIndex and length respectively. 164 | 165 | Parameters 166 | ---------- 167 | p_handle: SMO_Handle 168 | A SWMM output handle 169 | subcatchIndex: int 170 | The subcatchment index for time series 171 | attr: SMO_subcatchAttribute 172 | Code for the subcatch attribute to report (see :ref: SMO_subcatchAttribute) 173 | startPeriod: int 174 | Time period of series start 175 | endPeriod: int 176 | Time period of series end 177 | 178 | Returns 179 | ------- 180 | outValueArray: float ** 181 | Array of time series values 182 | length: int * 183 | Length of array 184 | " 185 | ) SMO_getSubcatchSeries; 186 | 187 | 188 | %feature("autodoc", 189 | "Get time series results for particular attribute. Specify series start and 190 | length using timeIndex and length respectively. 191 | 192 | Parameters 193 | ---------- 194 | p_handle: SMO_Handle 195 | A SWMM output handle 196 | nodeIndex: int 197 | The node index for time series 198 | attr: SMO_nodeAttribute 199 | Code for the node attribute to report (see :ref: SMO_nodeAttribute) 200 | startPeriod: int 201 | Time period of series start 202 | endPeriod: int 203 | Time period of series end 204 | 205 | Returns 206 | ------- 207 | outValueArray: float ** 208 | Array of time series values 209 | length: int * 210 | Length of array 211 | " 212 | ) SMO_getNodeSeries; 213 | 214 | 215 | %feature("autodoc", 216 | "Get time series results for particular attribute. Specify series start and 217 | length using timeIndex and length respectively. 218 | 219 | Parameters 220 | ---------- 221 | p_handle: SMO_Handle 222 | A SWMM output handle 223 | linkIndex: int 224 | The link index for time series 225 | attr: SMO_linkAttribute 226 | Code for the link attribute to report (see :ref: SMO_linkAttribute) 227 | startPeriod: int 228 | Time period of series start 229 | endPeriod: int 230 | Time period of series end 231 | 232 | Returns 233 | ------- 234 | outValueArray: float ** 235 | Array of time series values 236 | length: int * 237 | Length of array 238 | " 239 | ) SMO_getLinkSeries; 240 | 241 | 242 | %feature("autodoc", 243 | "Get time series results for particular attribute. Specify series start and 244 | length using timeIndex and length respectively. 245 | 246 | Parameters 247 | ---------- 248 | p_handle: SMO_Handle 249 | A SWMM output handle 250 | attr: SMO_systemAttribute 251 | Code for the system attribute to report (see :ref: SMO_systemAttribute) 252 | startPeriod: int 253 | Time period of series start 254 | endPeriod: int 255 | Time period of series end 256 | 257 | Returns 258 | ------- 259 | outValueArray: float ** 260 | Array of time series values 261 | length: int * 262 | Length of array 263 | " 264 | ) SMO_getSystemSeries; 265 | 266 | 267 | %feature("autodoc", 268 | "For all subcatchments at given time, get a particular attribute. 269 | 270 | Parameters 271 | ---------- 272 | p_handle: SMO_Handle 273 | A SWMM output handle 274 | timeIndex: int 275 | The time period index for reporting results 276 | attr: SMO_subcatchAttribute 277 | Code for the subcatchment attribute to report (see :ref: SMO_subcatchAttribute) 278 | 279 | Returns 280 | ------- 281 | outValueArray: float ** 282 | The array of subcatchment attribute values 283 | length: int * 284 | Length of array 285 | " 286 | ) SMO_getSubcatchAttribute; 287 | 288 | 289 | %feature("autodoc", 290 | "For all nodes at given time, get a particular attribute. 291 | 292 | Parameters 293 | ---------- 294 | p_handle: SMO_Handle 295 | A SWMM output handle 296 | timeIndex: int 297 | The time period index for reporting results 298 | attr: SMO_nodeAttribute 299 | Code for the node attribute to report (see :ref: SMO_nodeAttribute) 300 | 301 | Returns 302 | ------- 303 | outValueArray: float ** 304 | The array of node attribute values 305 | length: int * 306 | Length of array 307 | " 308 | ) SMO_getNodeAttribute; 309 | 310 | 311 | %feature("autodoc", 312 | "For all links at given time, get a particular attribute. 313 | 314 | Parameters 315 | ---------- 316 | p_handle: SMO_Handle 317 | A SWMM output handle 318 | timeIndex: int 319 | The time period index for reporting results 320 | attr: SMO_linkAttribute 321 | Code for the link attribute to report (see :ref: SMO_linkAttribute) 322 | 323 | Returns 324 | ------- 325 | outValueArray: float ** 326 | The array of link attribute values 327 | length: int * 328 | Length of array 329 | " 330 | ) SMO_getLinkAttribute; 331 | 332 | 333 | %feature("autodoc", 334 | "For the system at given time, get a particular attribute. 335 | 336 | Parameters 337 | ---------- 338 | p_handle: SMO_Handle 339 | A SWMM output handle 340 | timeIndex: int 341 | The time period index for reporting results 342 | attr: SMO_systemAttribute 343 | Code for the system attribute to report (see :ref: SMO_systemAttribute) 344 | 345 | Returns 346 | ------- 347 | outValueArray: float ** 348 | The array of system attribute values 349 | length: int * 350 | Length of array 351 | " 352 | ) SMO_getSystemAttribute; 353 | 354 | 355 | %feature("autodoc", 356 | "For a subcatchment at given time, get all attributes. 357 | 358 | Parameters 359 | ---------- 360 | p_handle: SMO_Handle 361 | A SWMM output handle 362 | timeIndex: int 363 | The time period index for reporting results 364 | subcatchIndex: int 365 | The subcatchment index for reporting results 366 | 367 | Returns 368 | ------- 369 | outValueArray: float ** 370 | The array of subcatchment result values 371 | length: int * 372 | Length of array 373 | " 374 | ) SMO_getSubcatchResult; 375 | 376 | 377 | %feature("autodoc", 378 | "For a node at given time, get all attributes. 379 | 380 | Parameters 381 | ---------- 382 | p_handle: SMO_Handle 383 | A SWMM output handle 384 | timeIndex: int 385 | The time period index for reporting results 386 | nodeIndex: int 387 | The node index for reporting results 388 | 389 | Returns 390 | ------- 391 | outValueArray: float ** 392 | The array of node result values 393 | length: int * 394 | Length of array 395 | " 396 | ) SMO_getNodeResult; 397 | 398 | 399 | %feature("autodoc", 400 | "For a link at given time, get all attributes. 401 | 402 | Parameters 403 | ---------- 404 | p_handle: SMO_Handle 405 | A SWMM output handle 406 | timeIndex: int 407 | The time period index for reporting results 408 | linkIndex: int 409 | The link index for reporting results 410 | 411 | Returns 412 | ------- 413 | outValueArray: float ** 414 | The array of link result values 415 | length: int * 416 | Length of array 417 | " 418 | ) SMO_getLinkResult; 419 | 420 | 421 | %feature("autodoc", 422 | "For the system at given time, get all attributes. 423 | 424 | Parameters 425 | ---------- 426 | p_handle: SMO_Handle 427 | A SWMM output handle 428 | timeIndex: int 429 | The time period index for reporting results 430 | dummyIndex: int 431 | No-op for API consistency 432 | 433 | Returns 434 | ------- 435 | outValueArray: float ** 436 | The array of system result values 437 | length: int * 438 | Length of array 439 | " 440 | ) SMO_getSystemResult; 441 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/output_metadata.py: -------------------------------------------------------------------------------- 1 | # 2 | # output_metadata.py - 3 | # 4 | # Created: February 20, 2020 5 | # Updated: 6 | # 7 | # Author: See AUTHORS 8 | # 9 | 10 | 11 | from itertools import islice 12 | 13 | from aenum import extend_enum 14 | 15 | from swmm.toolkit import output, shared_enum 16 | 17 | 18 | class OutputMetadata: 19 | ''' 20 | Simple attribute name and unit lookup. 21 | ''' 22 | _unit_labels_us_ = { 23 | shared_enum.BaseUnits.RAIN_INT: "in/hr", 24 | shared_enum.BaseUnits.SNOW_DEPTH: "in", 25 | shared_enum.BaseUnits.EVAP_RATE: "in/day", 26 | shared_enum.BaseUnits.INFIL_RATE: "in/hr", 27 | shared_enum.BaseUnits.ELEV: "ft", 28 | shared_enum.BaseUnits.PERCENT: "%", 29 | shared_enum.BaseUnits.HEAD: "ft", 30 | shared_enum.BaseUnits.VOLUME: "cu ft", 31 | shared_enum.BaseUnits.VELOCITY: "ft/sec", 32 | shared_enum.BaseUnits.TEMP: "deg F", 33 | shared_enum.BaseUnits.UNITLESS: "unitless", 34 | shared_enum.BaseUnits.NONE: "", 35 | 36 | shared_enum.FlowUnits.CFS: "cu ft/sec", 37 | shared_enum.FlowUnits.GPM: "gal/min", 38 | shared_enum.FlowUnits.MGD: "M gal/day", 39 | } 40 | 41 | _unit_labels_si_ = { 42 | shared_enum.BaseUnits.RAIN_INT: "mm/hr", 43 | shared_enum.BaseUnits.SNOW_DEPTH: "mm", 44 | shared_enum.BaseUnits.EVAP_RATE: "mm/day", 45 | shared_enum.BaseUnits.INFIL_RATE: "mm/hr", 46 | shared_enum.BaseUnits.ELEV: "m", 47 | shared_enum.BaseUnits.PERCENT: "%", 48 | shared_enum.BaseUnits.HEAD: "m", 49 | shared_enum.BaseUnits.VOLUME: "cu m", 50 | shared_enum.BaseUnits.VELOCITY: "m/sec", 51 | shared_enum.BaseUnits.TEMP: "deg C", 52 | shared_enum.BaseUnits.UNITLESS: "unitless", 53 | shared_enum.BaseUnits.NONE: "", 54 | 55 | shared_enum.FlowUnits.CMS: "cu m/sec", 56 | shared_enum.FlowUnits.LPS: "L/sec", 57 | shared_enum.FlowUnits.MLD: "M L/day", 58 | } 59 | 60 | _unit_labels_quality_ = { 61 | shared_enum.ConcUnits.MG: "mg/L", 62 | shared_enum.ConcUnits.UG: "ug/L", 63 | shared_enum.ConcUnits.COUNT: "Count/L", 64 | shared_enum.ConcUnits.NONE: "" 65 | } 66 | 67 | 68 | def _build_pollut_metadata(self, output_handle): 69 | ''' 70 | Builds metadata for pollutant attributes at runtime. 71 | ''' 72 | # Get number of pollutants 73 | n = output.get_proj_size(output_handle)[shared_enum.ElementType.POLLUT] 74 | 75 | if n > 0: 76 | 77 | pollut_name = [] 78 | pollut_units = [] 79 | 80 | # Get pollutant names 81 | for i in range(0, n): 82 | pollut_name.append(output.get_elem_name( 83 | output_handle, shared_enum.ElementType.POLLUT, i)) 84 | # Get pollutant units 85 | for u in output.get_units(output_handle)[2:]: 86 | pollut_units.append(shared_enum.ConcUnits(u)) 87 | 88 | # Create dictionary keys 89 | for i in range(1, n): 90 | symbolic_name = 'POLLUT_CONC_' + str(i) 91 | if symbolic_name not in shared_enum.SubcatchAttribute._member_names_: 92 | extend_enum(shared_enum.SubcatchAttribute, symbolic_name, 8 + i) 93 | extend_enum(shared_enum.NodeAttribute, symbolic_name, 6 + i) 94 | extend_enum(shared_enum.LinkAttribute, symbolic_name, 5 + i) 95 | 96 | # Update metadata dictionary with pollutant metadata 97 | for i, attr in enumerate(islice(shared_enum.SubcatchAttribute, 8, None)): 98 | self._metadata[attr] = (pollut_name[i], self._unit_labels[pollut_units[i]]) 99 | 100 | for i, attr in enumerate(islice(shared_enum.NodeAttribute, 6, None)): 101 | self._metadata[attr] = (pollut_name[i], self._unit_labels[pollut_units[i]]) 102 | 103 | for i, attr in enumerate(islice(shared_enum.LinkAttribute, 5, None)): 104 | self._metadata[attr] = (pollut_name[i], self._unit_labels[pollut_units[i]]) 105 | 106 | 107 | def __init__(self, output_handle): 108 | # Get units from binary output file 109 | self.units = output.get_units(output_handle) 110 | 111 | # Determine prevailing unit system 112 | self._unit_system = shared_enum.UnitSystem(self.units[0]) 113 | if self._unit_system == shared_enum.UnitSystem.US: 114 | self._unit_labels = type(self)._unit_labels_us_ 115 | else: 116 | self._unit_labels = type(self)._unit_labels_si_ 117 | 118 | self._unit_labels.update(type(self)._unit_labels_quality_) 119 | 120 | # Set user flow units 121 | self._flow = shared_enum.FlowUnits(self.units[1]) 122 | 123 | self._metadata = { 124 | shared_enum.SubcatchAttribute.RAINFALL: 125 | ("Rainfall", self._unit_labels[shared_enum.BaseUnits.RAIN_INT]), 126 | shared_enum.SubcatchAttribute.SNOW_DEPTH: 127 | ("Snow Depth", self._unit_labels[shared_enum.BaseUnits.SNOW_DEPTH]), 128 | shared_enum.SubcatchAttribute.EVAP_LOSS: 129 | ("Evaporation Loss", self._unit_labels[shared_enum.BaseUnits.EVAP_RATE]), 130 | shared_enum.SubcatchAttribute.INFIL_LOSS: 131 | ("Infiltration Loss", self._unit_labels[shared_enum.BaseUnits.INFIL_RATE]), 132 | shared_enum.SubcatchAttribute.RUNOFF_RATE: 133 | ("Runoff Rate", self._unit_labels[self._flow]), 134 | shared_enum.SubcatchAttribute.GW_OUTFLOW_RATE: 135 | ("Groundwater Flow Rate", self._unit_labels[self._flow]), 136 | shared_enum.SubcatchAttribute.GW_TABLE_ELEV: 137 | ("Groundwater Elevation", self._unit_labels[shared_enum.BaseUnits.ELEV]), 138 | shared_enum.SubcatchAttribute.SOIL_MOISTURE: 139 | ("Soil Moisture", self._unit_labels[shared_enum.BaseUnits.PERCENT]), 140 | shared_enum.SubcatchAttribute.POLLUT_CONC_0: 141 | ("Pollutant Concentration", self._unit_labels[shared_enum.BaseUnits.NONE]), 142 | 143 | shared_enum.NodeAttribute.INVERT_DEPTH: 144 | ("Invert Depth", self._unit_labels[shared_enum.BaseUnits.ELEV]), 145 | shared_enum.NodeAttribute.HYDRAULIC_HEAD: 146 | ("Hydraulic Head", self._unit_labels[shared_enum.BaseUnits.HEAD]), 147 | shared_enum.NodeAttribute.PONDED_VOLUME: 148 | ("Ponded Volume", self._unit_labels[shared_enum.BaseUnits.VOLUME]), 149 | shared_enum.NodeAttribute.LATERAL_INFLOW: 150 | ("Lateral Inflow", self._unit_labels[self._flow]), 151 | shared_enum.NodeAttribute.TOTAL_INFLOW: 152 | ("Total Inflow", self._unit_labels[self._flow]), 153 | shared_enum.NodeAttribute.FLOODING_LOSSES: 154 | ("Flooding Loss", self._unit_labels[self._flow]), 155 | shared_enum.NodeAttribute.POLLUT_CONC_0: 156 | ("Pollutant Concentration", self._unit_labels[shared_enum.BaseUnits.NONE]), 157 | 158 | shared_enum.LinkAttribute.FLOW_RATE: 159 | ("Flow Rate", self._unit_labels[self._flow]), 160 | shared_enum.LinkAttribute.FLOW_DEPTH: 161 | ("Flow Depth", self._unit_labels[shared_enum.BaseUnits.ELEV]), 162 | shared_enum.LinkAttribute.FLOW_VELOCITY: 163 | ("Flow Velocity", self._unit_labels[shared_enum.BaseUnits.VELOCITY]), 164 | shared_enum.LinkAttribute.FLOW_VOLUME: 165 | ("Flow Volume", self._unit_labels[shared_enum.BaseUnits.VOLUME]), 166 | shared_enum.LinkAttribute.CAPACITY: 167 | ("Capacity", self._unit_labels[shared_enum.BaseUnits.PERCENT]), 168 | shared_enum.LinkAttribute.POLLUT_CONC_0: 169 | ("Pollutant Concentration", self._unit_labels[shared_enum.BaseUnits.NONE]), 170 | 171 | shared_enum.SystemAttribute.AIR_TEMP: 172 | ("Temperature", self._unit_labels[shared_enum.BaseUnits.TEMP]), 173 | shared_enum.SystemAttribute.RAINFALL: 174 | ("Rainfall", self._unit_labels[shared_enum.BaseUnits.RAIN_INT]), 175 | shared_enum.SystemAttribute.SNOW_DEPTH: 176 | ("Snow Depth", self._unit_labels[shared_enum.BaseUnits.SNOW_DEPTH]), 177 | shared_enum.SystemAttribute.EVAP_INFIL_LOSS: 178 | ("Evap and Infil Losses", self._unit_labels[shared_enum.BaseUnits.INFIL_RATE]), 179 | shared_enum.SystemAttribute.RUNOFF_FLOW: 180 | ("Runoff Flow Rate", self._unit_labels[self._flow]), 181 | shared_enum.SystemAttribute.DRY_WEATHER_INFLOW: 182 | ("Dry Weather Inflow", self._unit_labels[self._flow]), 183 | shared_enum.SystemAttribute.GW_INFLOW: 184 | ("Groundwater Inflow", self._unit_labels[self._flow]), 185 | shared_enum.SystemAttribute.RDII_INFLOW: 186 | ("RDII Inflow", self._unit_labels[self._flow]), 187 | shared_enum.SystemAttribute.DIRECT_INFLOW: 188 | ("Direct Inflow", self._unit_labels[self._flow]), 189 | shared_enum.SystemAttribute.TOTAL_LATERAL_INFLOW: 190 | ("Total Lateral Inflow", self._unit_labels[self._flow]), 191 | shared_enum.SystemAttribute.FLOOD_LOSSES: 192 | ("Flood Losses", self._unit_labels[self._flow]), 193 | shared_enum.SystemAttribute.OUTFALL_FLOWS: 194 | ("Outfall Flow", self._unit_labels[self._flow]), 195 | shared_enum.SystemAttribute.VOLUME_STORED: 196 | ("Volume Stored", self._unit_labels[shared_enum.BaseUnits.VOLUME]), 197 | shared_enum.SystemAttribute.EVAP_RATE: 198 | ("Evaporation Rate", self._unit_labels[shared_enum.BaseUnits.EVAP_RATE]), 199 | shared_enum.SystemAttribute.PTNL_EVAP_RATE: 200 | ("Potential Evaporation Rate", self._unit_labels[shared_enum.BaseUnits.EVAP_RATE]) 201 | } 202 | 203 | self._build_pollut_metadata(output_handle) 204 | 205 | 206 | def get_attribute_metadata(self, attribute): 207 | ''' 208 | Takes an attribute enum and returns the name and units in a tuple. 209 | ''' 210 | return self._metadata[attribute] 211 | 212 | 213 | # Units of Measurement 214 | # 215 | # Units US Customary SI Metric 216 | # AREA_SUBCATCH acres ac hectares ha 217 | # AREA_STOR square feet sq ft square meters sq m 218 | # AREA_POND square feet sq ft square meters sq m 219 | # CAP_SUC inches in millimeters mm 220 | # CONC milligrams/liter mg/L milligrams/liter mg/L 221 | # micrograms/liter ug/L micrograms/liter ug/L 222 | # counts/liter Count/L counts/liter Count/L 223 | # INFIL_DECAY 1/hours 1/hrs 1/hours 1/hrs 224 | # POLLUT_DECAY 1/days 1/days 1/days 1/days 225 | # DEPRES_STOR inches in millimeters mm 226 | # DEPTH feet ft meters m 227 | # DIAM feet ft meters m 228 | # DISC_COEFF_ORIF dimensionless dimless dimensionless dimless 229 | # DISC_COEFF_WEIR CFS/foot^n CFS/ft^n CMS/meter^n CMS/m^n 230 | # ELEV feet ft meters m 231 | # EVAP_RATE inches/day in/day millimeters/day mm/day 232 | # FLOW_RATE cubic feet/sec CFS cubic meter/sec CMS 233 | # gallons/minute GPM liter/sec LPS 234 | # million gallons/day MGD million liter/day MLD 235 | # HEAD feet ft meters m 236 | # HYD_CONDUCT inches/hour in/hr millimeters/hour mm/hr 237 | # INFIL_RATE inches/hour in/hr millimeters/hour mm/hr 238 | # LEN feet ft meters m 239 | # MANN_N seconds/meter^1/3 sec/m^1/3 seconds/meter^1/3 sec/m^1/3 240 | # POLLUT_BUILDUP mass/length mass/len mass/length mass/len 241 | # mass/acre mass/ac mass/hectare mass/ha 242 | # RAIN_INTENSITY inches/hour in/hr millimeters/hour mm/hr 243 | # RAIN_VOLUME inches in millimeters mm 244 | # SLOPE_SUBCATCH percent percent percent percent 245 | # SLOPE_XSEC rise/run rise/run rise/run rise/run 246 | # STREET_CLEAN_INT days days days days 247 | # VOLUME cubic feet cu ft cubic meters cu m 248 | # WIDTH feet ft meters m 249 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/output_rename.i: -------------------------------------------------------------------------------- 1 | /* 2 | * output_rename.i - Rename mapping for swmm-output 3 | * 4 | * Created: 2/12/2020 5 | * 6 | * Author: See AUTHORS 7 | * 8 | */ 9 | 10 | 11 | // RENAME FUNCTIONS ACCORDING TO PEP8 12 | %rename(init) SMO_init; 13 | %rename(open) SMO_open; 14 | %rename(close) SMO_close; 15 | %rename(get_version) SMO_getVersion; 16 | %rename(get_proj_size) SMO_getProjectSize; 17 | 18 | %rename(get_units) SMO_getUnits; 19 | %rename(get_start_date) SMO_getStartDate; 20 | %rename(get_times) SMO_getTimes; 21 | %rename(get_elem_name) SMO_getElementName; 22 | 23 | %rename(get_subcatch_series) SMO_getSubcatchSeries; 24 | %rename(get_node_series) SMO_getNodeSeries; 25 | %rename(get_link_series) SMO_getLinkSeries; 26 | %rename(get_system_series) SMO_getSystemSeries; 27 | 28 | %rename(get_subcatch_attribute) SMO_getSubcatchAttribute; 29 | %rename(get_node_attribute) SMO_getNodeAttribute; 30 | %rename(get_link_attribute) SMO_getLinkAttribute; 31 | %rename(get_system_attribute) SMO_getSystemAttribute; 32 | 33 | %rename(get_subcatch_result) SMO_getSubcatchResult; 34 | %rename(get_node_result) SMO_getNodeResult; 35 | %rename(get_link_result) SMO_getLinkResult; 36 | %rename(get_system_result) SMO_getSystemResult; 37 | -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/shared_enum.py: -------------------------------------------------------------------------------- 1 | # 2 | # shared_enum.py - 3 | # 4 | # Created: February 21, 2020 5 | # Updated: 6 | # 7 | # Author: See AUTHORS 8 | # 9 | 10 | from aenum import Enum, IntEnum 11 | 12 | 13 | class UnitSystem(Enum): 14 | """SWMM Unit System enum class. 15 | 16 | .. rubric:: Enum Members 17 | 18 | ================ ==================== 19 | :attr:`~US` US Traditional units 20 | :attr:`~SI` SI (metric) units 21 | ================ ==================== 22 | """ 23 | US = 0 24 | SI = 1 25 | 26 | 27 | class FlowUnits(Enum): 28 | """SWMM Flow Units enum class. 29 | 30 | .. rubric:: Enum Members 31 | 32 | ================ ======================= 33 | :attr:`~CFS` cubic feet per second 34 | :attr:`~GPM` gallons per minute 35 | :attr:`~MGD` million gallons per day 36 | :attr:`~CMS` cubic meters per second 37 | :attr:`~LPS` liters per second 38 | :attr:`~MLD` million liters per day 39 | ================ ======================= 40 | """ 41 | CFS = 0 42 | GPM = 1 43 | MGD = 2 44 | CMS = 3 45 | LPS = 4 46 | MLD = 5 47 | 48 | 49 | class ConcUnits(Enum): 50 | """SWMM Concentration Units enum class. 51 | 52 | .. rubric:: Enum Members 53 | 54 | ================ ==================== 55 | :attr:`~MG` Milligrams per liter 56 | :attr:`~UG` Micrograms per liter 57 | :attr:`~COUNT` Counts per liter 58 | :attr:`~NONE` None 59 | ================ ==================== 60 | """ 61 | MG = 0 62 | UG = 1 63 | COUNT = 2 64 | NONE = 3 65 | 66 | 67 | class BaseUnits(Enum, start = 1): 68 | """Base Units enum class 69 | 70 | .. rubric:: Enum Members 71 | 72 | =================== ================== 73 | :attr:`~RAIN_INT` rainfall intensity 74 | :attr:`~SNOW_DEPTH` rainfall depth 75 | :attr:`~EVAP_RATE` evaporation rate 76 | :attr:`~INFIL_RATE` infiltration rate 77 | :attr:`~FLOW_RATE` flow rate 78 | :attr:`~ELEV` elevation 79 | :attr:`~PERCENT` percent 80 | :attr:`~CONCEN` concentration 81 | :attr:`~HEAD` head 82 | :attr:`~VOLUME` volume 83 | :attr:`~VELOCITY` velocity 84 | :attr:`~TEMP` temperature 85 | :attr:`~UNITLESS` unitless quantity 86 | :attr:`~NONE` none 87 | =================== ================== 88 | """ 89 | RAIN_INT = 1 90 | SNOW_DEPTH = 2 91 | EVAP_RATE = 3 92 | INFIL_RATE = 4 93 | FLOW_RATE = 5 94 | ELEV = 6 95 | PERCENT = 7 96 | CONCEN = 8 97 | HEAD = 9 98 | VOLUME = 10 99 | VELOCITY = 11 100 | TEMP = 12 101 | UNITLESS = 13 102 | NONE = 14 103 | 104 | 105 | class ObjectType(Enum): 106 | """SWMM Object Types enum class. 107 | 108 | .. rubric:: Enum Members 109 | 110 | ==================== =============================== 111 | :attr:`~GAGE` rain gage 112 | :attr:`~SUBCATCH` subcatchment 113 | :attr:`~NODE` conveyance system node 114 | :attr:`~LINK` conveyance system link 115 | :attr:`~POLLUT` pollutant 116 | :attr:`~LANDUSE` land use category 117 | :attr:`~TIMEPATTERN` dry weather flow time pattern 118 | :attr:`~CURVE` generic table of values 119 | :attr:`~TSERIES` generic time series of values 120 | :attr:`~CONTROL` conveyance system control rules 121 | :attr:`~TRANSECT` irregular channel cross-section 122 | :attr:`~AQUIFER` groundwater aquifer 123 | :attr:`~UNITHYD` RDII unit hydrograph 124 | :attr:`~SNOWMELT` snowmelt parameter set 125 | :attr:`~SHAPE` custom conduit shape 126 | :attr:`~LID` LID treatment unit 127 | ==================== =============================== 128 | """ 129 | GAGE = 0 130 | SUBCATCH = 1 131 | NODE = 2 132 | LINK = 3 133 | POLLUT = 4 134 | LANDUSE = 5 135 | TIMEPATTERN = 6 136 | CURVE = 7 137 | TSERIES = 8 138 | CONTROL = 9 139 | TRANSECT = 10 140 | AQUIFER = 11 141 | UNITHYD = 12 142 | SNOWMELT = 13 143 | SHAPE = 14 144 | LID = 15 145 | 146 | 147 | class NodeType(Enum): 148 | """Node Sub-Types enum class. 149 | 150 | :attr:`~JUNCTION` 151 | :attr:`~OUTFALL` 152 | :attr:`~STORAGE` 153 | :attr:`~DIVIDER` 154 | """ 155 | JUNCTION = 0 156 | OUTFALL = 1 157 | STORAGE = 2 158 | DIVIDER = 3 159 | 160 | 161 | class LinkType(Enum): 162 | """Link Sub-Types enum class. 163 | 164 | :attr:`~CONDUIT` 165 | :attr:`~PUMP` 166 | :attr:`~ORIFICE` 167 | :attr:`~WEIR` 168 | :attr:`~OUTLET` 169 | """ 170 | CONDUIT = 0 171 | PUMP = 1 172 | ORIFICE = 2 173 | WEIR = 3 174 | OUTLET = 4 175 | 176 | 177 | class LinkDirection(Enum): 178 | """Link Direction enum class. 179 | 180 | :attr:`~UPSTREAM_TO_DOWNSTREAM` 181 | :attr:`~DOWNSTREAM_TO_UPSTREAM` 182 | """ 183 | UPSTREAM_TO_DOWNSTREAM = 1 184 | DOWNSTREAM_TO_UPSTREAM = -1 185 | 186 | 187 | class ElementType(IntEnum, start = 0): 188 | """SWMM Element Types enum class. 189 | 190 | :attr:`~SUBCATCH` 191 | :attr:`~NODE` 192 | :attr:`~LINK` 193 | :attr:`~SYSTEM` 194 | :attr:`~POLLUT` 195 | """ 196 | SUBCATCH = 0 197 | NODE = 1 198 | LINK = 2 199 | SYSTEM = 3 200 | POLLUT = 4 201 | 202 | 203 | class Time(Enum, start = 0): 204 | """Time enum class. 205 | 206 | :attr:`~REPORT_STEP` 207 | :attr:`~NUM_PERIODS` 208 | """ 209 | REPORT_STEP = 0 210 | NUM_PERIODS = 1 211 | 212 | 213 | class SubcatchAttribute(Enum, start = 0): 214 | """Subcatchment Attributes enum class. 215 | 216 | .. rubric:: Enum Members 217 | 218 | ========================= =============================== 219 | :attr:`~RAINFALL` rainfall intensity 220 | :attr:`~SNOW_DEPTH` snow depth 221 | :attr:`~EVAP_LOSS` evaporation loss 222 | :attr:`~INFIL_LOSS` infiltration loss 223 | :attr:`~RUNOFF_RATE` runoff flow rate 224 | :attr:`~GW_OUTFLOW_RATE` groundwater flow rate to node 225 | :attr:`~GW_TABLE_ELEV` elevation of saturated gw table 226 | :attr:`~SOIL_MOISTURE` soil moisture 227 | :attr:`~POLLUT_CONC_0` pollutant washoff concentration 228 | ========================= =============================== 229 | """ 230 | RAINFALL = 0 231 | SNOW_DEPTH = 1 232 | EVAP_LOSS = 2 233 | INFIL_LOSS = 3 234 | RUNOFF_RATE = 4 235 | GW_OUTFLOW_RATE = 5 236 | GW_TABLE_ELEV = 6 237 | SOIL_MOISTURE = 7 238 | POLLUT_CONC_0 = 8 239 | 240 | 241 | class NodeAttribute(Enum, start = 0): 242 | """Node Attribute enum class. 243 | 244 | .. rubric:: Enum Members 245 | 246 | ========================= =============================== 247 | :attr:`~INVERT_DEPTH` water depth above invert 248 | :attr:`~HYDRAULIC_HEAD` hydraulic head 249 | :attr:`~PONDED_VOLUME` volume stored and ponded 250 | :attr:`~LATERAL_INFLOW` lateral inflow rate 251 | :attr:`~TOTAL_INFLOW` total inflow rate 252 | :attr:`~FLOODING_LOSSES` overflow rate 253 | :attr:`~POLLUT_CONC_0` concentration of each pollutant 254 | ========================= =============================== 255 | """ 256 | INVERT_DEPTH = 0 257 | HYDRAULIC_HEAD = 1 258 | PONDED_VOLUME = 2 259 | LATERAL_INFLOW = 3 260 | TOTAL_INFLOW = 4 261 | FLOODING_LOSSES = 5 262 | POLLUT_CONC_0 = 6 263 | 264 | 265 | class LinkAttribute(Enum, start = 0): 266 | """Link Attribute enum class. 267 | 268 | .. rubric:: Enum Members 269 | 270 | ====================== =============================== 271 | :attr:`~FLOW_RATE` flow rate 272 | :attr:`~FLOW_DEPTH` flow depth 273 | :attr:`~FLOW_VELOCITY` flow velocity 274 | :attr:`~FLOW_VOLUME` link volume 275 | :attr:`~CAPACITY` ratio of area to full area 276 | :attr:`~POLLUT_CONC_0` concentration of each pollutant 277 | ====================== =============================== 278 | """ 279 | FLOW_RATE = 0 280 | FLOW_DEPTH = 1 281 | FLOW_VELOCITY = 2 282 | FLOW_VOLUME = 3 283 | CAPACITY = 4 284 | POLLUT_CONC_0 = 5 285 | 286 | 287 | class SystemAttribute(Enum, start = 0): 288 | """System Attribute enum class. 289 | 290 | .. rubric:: Enum Members 291 | 292 | ============================= ==================== 293 | :attr:`~AIR_TEMP` air temperature 294 | :attr:`~RAINFALL` rainfall intensity 295 | :attr:`~SNOW_DEPTH` snow depth 296 | :attr:`~EVAP_INFIL_LOSS` infiltration 297 | :attr:`~RUNOFF_FLOW` runoff 298 | :attr:`~DRY_WEATHER_INFLOW` dry weather inflow 299 | :attr:`~GW_INFLOW` ground water inflow 300 | :attr:`~RDII_INFLOW` RDII inflow 301 | :attr:`~DIRECT_INFLOW` external inflow 302 | :attr:`~TOTAL_LATERAL_INFLOW` total lateral inflow 303 | :attr:`~FLOOD_LOSSES` flooding outflow 304 | :attr:`~OUTFALL_FLOWS` outfall outflow 305 | :attr:`~VOLUME_STORED` storage volume 306 | :attr:`~EVAP_RATE` evaporation 307 | :attr:`~PTNL_EVAP_RATE` potential evapotranspiration 308 | ============================= ==================== 309 | """ 310 | AIR_TEMP = 0 311 | RAINFALL = 1 312 | SNOW_DEPTH = 2 313 | EVAP_INFIL_LOSS = 3 314 | RUNOFF_FLOW = 4 315 | DRY_WEATHER_INFLOW = 5 316 | GW_INFLOW = 6 317 | RDII_INFLOW = 7 318 | DIRECT_INFLOW = 8 319 | TOTAL_LATERAL_INFLOW = 9 320 | FLOOD_LOSSES = 10 321 | OUTFALL_FLOWS = 11 322 | VOLUME_STORED = 12 323 | EVAP_RATE = 13 324 | PTNL_EVAP_RATE = 14 325 | 326 | 327 | # 328 | # Solver Toolkit API Enums 329 | # 330 | class TimeProperty(Enum): 331 | """Time Property enum class. 332 | 333 | :attr:`~START_DATE` 334 | :attr:`~END_DATE` 335 | :attr:`~REPORT_DATE` 336 | """ 337 | START_DATE = 0 338 | END_DATE = 1 339 | REPORT_DATE = 2 340 | 341 | 342 | class UnitProperty(Enum): 343 | """Unit Property enum class. 344 | 345 | :attr:`~SYSTEM_UNIT` 346 | :attr:`~FLOW_UNIT` 347 | """ 348 | SYSTEM_UNIT = 0 349 | FLOW_UNIT = 1 350 | 351 | 352 | class SimOption(Enum): 353 | """Simulation Option enum class. 354 | 355 | :attr:`~ALLOW_POND` 356 | :attr:`~SKIP_STEADY` 357 | :attr:`~IGNORE_RAIN` 358 | :attr:`~IGNORE_RDII` 359 | :attr:`~IGNORE_SNOW` 360 | :attr:`~IGNORE_GW` 361 | :attr:`~IGNORE_ROUTE` 362 | :attr:`~IGNORE_ROUTE_QUALITY` 363 | """ 364 | ALLOW_POND = 0 365 | SKIP_STEADY = 1 366 | IGNORE_RAIN = 2 367 | IGNORE_RDII = 3 368 | IGNORE_SNOW = 4 369 | IGNORE_GW = 5 370 | IGNORE_ROUTE = 6 371 | IGNORE_ROUTE_QUALITY = 7 372 | 373 | 374 | class SimSetting(Enum): 375 | """Simulation Settings enum class. 376 | 377 | :attr:`~ROUTE_STEP` 378 | :attr:`~MIN_ROUTE_STEP` 379 | :attr:`~LENGTH_STEP` 380 | :attr:`~START_DRY_DAYS` 381 | :attr:`~COURANT_FACTOR` 382 | :attr:`~MIN_SURFACE_AREA` 383 | :attr:`~MIN_SLOPE` 384 | :attr:`~RUNOFF_ERROR` 385 | :attr:`~GW_ERROR` 386 | :attr:`~FLOW_ERROR` 387 | :attr:`~QUALITY_ERROR` 388 | :attr:`~HEAD_TOLERANCE` 389 | :attr:`~SYSTEM_FLOW_TOLERANCE` 390 | :attr:`~LATERAL_FLOW_TOLERANCE` 391 | """ 392 | ROUTE_STEP = 0 393 | MIN_ROUTE_STEP = 1 394 | LENGTH_STEP = 2 395 | START_DRY_DAYS = 3 396 | COURANT_FACTOR = 4 397 | MIN_SURFACE_AREA = 5 398 | MIN_SLOPE = 6 399 | RUNOFF_ERROR = 7 400 | GW_ERROR = 8 401 | FLOW_ERROR = 9 402 | QUALITY_ERROR = 10 403 | HEAD_TOLERANCE = 11 404 | SYSTEM_FLOW_TOLERANCE = 12 405 | LATERAL_FLOW_TOLERANCE = 13 406 | THREADS = 14 407 | 408 | 409 | class NodeProperty(Enum): 410 | """Node Property enum class. 411 | 412 | :attr:`~INVERT_ELEVATION` 413 | :attr:`~FULL_DEPTH` 414 | :attr:`~SURCHARGE_DEPTH` 415 | :attr:`~POND_AREA` 416 | :attr:`~INITIAL_DEPTH` 417 | """ 418 | INVERT_ELEVATION = 0 419 | FULL_DEPTH = 1 420 | SURCHARGE_DEPTH = 2 421 | POND_AREA = 3 422 | INITIAL_DEPTH = 4 423 | 424 | 425 | class NodeResult(Enum): 426 | """Node Result enum class. 427 | 428 | :attr:`~TOTAL_INFLOW` 429 | :attr:`~TOTAL_OUTFLOW` 430 | :attr:`~LOSSES` 431 | :attr:`~VOLUME` 432 | :attr:`~FLOOD` 433 | :attr:`~DEPTH` 434 | :attr:`~HEAD` 435 | :attr:`~LATERAL_INFLOW` 436 | :attr:`~HYD_RES_TIME` 437 | """ 438 | TOTAL_INFLOW = 0 439 | TOTAL_OUTFLOW = 1 440 | LOSSES = 2 441 | VOLUME = 3 442 | FLOOD = 4 443 | DEPTH = 5 444 | HEAD = 6 445 | LATERAL_INFLOW = 7 446 | HYD_RES_TIME = 8 447 | 448 | 449 | class NodePollutant(Enum): 450 | """Node Pollutant enum class. 451 | 452 | :attr:`~QUALITY` 453 | :attr:`~INFLOW_CONC` 454 | :attr:`~REACTOR_CONC` 455 | """ 456 | QUALITY = 0 457 | INFLOW_CONC = 1 458 | REACTOR_CONC = 2 459 | 460 | 461 | class LinkProperty(Enum): 462 | """Link Property enum class. 463 | 464 | :attr:`~OFFSET_1` 465 | :attr:`~OFFSET_2` 466 | :attr:`~INITIAL_FLOW` 467 | :attr:`~FLOW_LIMIT` 468 | :attr:`~INLET_LOSS` 469 | :attr:`~OUTLET_LOSS` 470 | :attr:`~AVERAGE_LOSS` 471 | """ 472 | OFFSET_1 = 0 473 | OFFSET_2 = 1 474 | INITIAL_FLOW = 2 475 | FLOW_LIMIT = 3 476 | INLET_LOSS = 4 477 | OUTLET_LOSS = 5 478 | AVERAGE_LOSS = 6 479 | 480 | 481 | class LinkResult(Enum): 482 | """Link Result enum class. 483 | 484 | :attr:`~FLOW` 485 | :attr:`~DEPTH` 486 | :attr:`~VOLUME` 487 | :attr:`~US_SURFACE_AREA` 488 | :attr:`~DS_SURFACE_AREA` 489 | :attr:`~SETTING` 490 | :attr:`~TARGET_SETTING` 491 | :attr:`~FROUDE` 492 | """ 493 | FLOW = 0 494 | DEPTH = 1 495 | VOLUME = 2 496 | US_SURFACE_AREA = 3 497 | DS_SURFACE_AREA = 4 498 | SETTING = 5 499 | TARGET_SETTING = 6 500 | FROUDE = 7 501 | 502 | 503 | class LinkPollutant(Enum): 504 | """Link Pollutant enum class. 505 | 506 | :attr:`~QUALITY` 507 | :attr:`~TOTAL_LOAD` 508 | :attr:`~REACTOR_CONC` 509 | """ 510 | QUALITY = 0 511 | TOTAL_LOAD = 1 512 | REACTOR_CONC = 2 513 | 514 | 515 | class SubcatchProperty(Enum): 516 | """Subcatchment Property enum class. 517 | 518 | :attr:`~WIDTH` 519 | :attr:`~AREA` 520 | :attr:`~IMPERVIOUS_FRACTION` 521 | :attr:`~SLOPE` 522 | :attr:`~CURB_LENGTH` 523 | """ 524 | WIDTH = 0 525 | AREA = 1 526 | IMPERVIOUS_FRACTION = 2 527 | SLOPE = 3 528 | CURB_LENGTH = 4 529 | 530 | 531 | class SubcatchResult(Enum): 532 | """Subcatchment Result enum class. 533 | 534 | :attr:`~RAIN` 535 | :attr:`~EVAPORATION` 536 | :attr:`~INFILTRATION` 537 | :attr:`~RUNON` 538 | :attr:`~RUNOFF` 539 | :attr:`~SNOW` 540 | """ 541 | RAIN = 0 542 | EVAPORATION = 1 543 | INFILTRATION = 2 544 | RUNON = 3 545 | RUNOFF = 4 546 | SNOW = 5 547 | 548 | 549 | class SubcatchPollutant(Enum): 550 | """Subcatchment Pollutant enum class. 551 | 552 | :attr:`~BUILD_UP` 553 | :attr:`~CONCENTRATION` 554 | :attr:`~QUALITY` 555 | :attr:`~TOTAL_LOAD` 556 | """ 557 | BUILD_UP = 0 558 | CONCENTRATION = 1 559 | QUALITY = 2 560 | TOTAL_LOAD = 3 561 | 562 | 563 | class LidUsageProperty(Enum): 564 | """LID Usage Property enum class. 565 | 566 | :attr:`~UNIT_AREA` 567 | :attr:`~TOP_WIDTH` 568 | :attr:`~BOTTOM_WIDTH` 569 | :attr:`~INITIAL_SATURATION` 570 | :attr:`~FROM_IMPERVIOUS` 571 | :attr:`~FROM_PERVIOUS` 572 | """ 573 | UNIT_AREA = 0 574 | TOP_WIDTH = 1 575 | BOTTOM_WIDTH = 2 576 | INITIAL_SATURATION = 3 577 | FROM_IMPERVIOUS = 4 578 | FROM_PERVIOUS = 5 579 | 580 | 581 | class LidUsageOption(Enum): 582 | """LID Usage Option enum class. 583 | 584 | :attr:`~INDEX` 585 | :attr:`~NUMBER` 586 | :attr:`~TO_PERV` 587 | :attr:`~DRAIN_SUBCATCH` 588 | :attr:`~DRAIN_NODE` 589 | """ 590 | INDEX = 0 591 | NUMBER = 1 592 | TO_PERV = 2 593 | DRAIN_SUBCATCH = 3 594 | DRAIN_NODE = 4 595 | 596 | 597 | class LidLayer(Enum): 598 | """LID Layer enum class. 599 | 600 | :attr:`~SURFACE` 601 | :attr:`~SOIL` 602 | :attr:`~STORAGE` 603 | :attr:`~PAVEMENT` 604 | :attr:`~DRAIN` 605 | :attr:`~DRAIN_MAT` 606 | """ 607 | SURFACE = 0 608 | SOIL = 1 609 | STORAGE = 2 610 | PAVEMENT = 3 611 | DRAIN = 4 612 | DRAIN_MAT = 5 613 | 614 | 615 | class LidLayerProperty(Enum): 616 | """LID Layer Property enum class. 617 | 618 | :attr:`~THICKNESS` 619 | :attr:`~VOID_FRACTION` 620 | :attr:`~ROUGHNESS` 621 | :attr:`~SURFACE_SLOPE` 622 | :attr:`~SIDE_SLOP` 623 | :attr:`~ALPHA` 624 | :attr:`~POROSITY` 625 | :attr:`~FIELD_CAPACITY` 626 | :attr:`~WILTING_POINT` 627 | :attr:`~SUCTION_HEAD` 628 | :attr:`~K_SATURATION` 629 | :attr:`~K_SLOPE` 630 | :attr:`~CLOG_FACTOR` 631 | :attr:`~IMPERVIOUS_FRACTION` 632 | :attr:`~DRAIN_COEFFICIENT` 633 | :attr:`~DRAIN_EXPONENT` 634 | :attr:`~DRAIN_OFFSET` 635 | :attr:`~DRAIN_DELAY` 636 | :attr:`~DRAIN_HEAD_OPEN` 637 | :attr:`~DRAIN_HEAD_CLOSE` 638 | :attr:`~DRAIN_CURVE` 639 | :attr:`~DRAIN_REGEN_DAYS` 640 | :attr:`~DRAIN_REGEN_DEGREE` 641 | """ 642 | THICKNESS = 0 643 | VOID_FRACTION = 1 644 | ROUGHNESS = 2 645 | SURFACE_SLOPE = 3 646 | SIDE_SLOP = 4 647 | ALPHA = 5 648 | POROSITY = 6 649 | FIELD_CAPACITY = 7 650 | WILTING_POINT = 8 651 | SUCTION_HEAD = 9 652 | K_SATURATION = 10 653 | K_SLOPE = 11 654 | CLOG_FACTOR = 12 655 | IMPERVIOUS_FRACTION = 13 656 | DRAIN_COEFFICIENT = 14 657 | DRAIN_EXPONENT = 15 658 | DRAIN_OFFSET = 16 659 | DRAIN_DELAY = 17 660 | DRAIN_HEAD_OPEN = 18 661 | DRAIN_HEAD_CLOSE = 19 662 | DRAIN_CURVE = 20 663 | DRAIN_REGEN_DAYS = 21 664 | DRAIN_REGEN_DEGREE = 22 665 | 666 | 667 | class LidResult(Enum): 668 | """LID Result enum class. 669 | 670 | :attr:`~INFLOW` 671 | :attr:`~EVAPORATION` 672 | :attr:`~INFILTRATION` 673 | :attr:`~SURFACE_FLOW` 674 | :attr:`~DRAIN_FLOW` 675 | :attr:`~INITIAL_VOLUME` 676 | :attr:`~FINAL_VOLUME` 677 | :attr:`~SURFACE_DEPTH` 678 | :attr:`~PAVEMENT_DEPTH` 679 | :attr:`~SOIL_MOISTURE` 680 | :attr:`~STORAGE_DEPTH` 681 | :attr:`~DRY_TIME` 682 | :attr:`~OLD_DRAIN_FLOW` 683 | :attr:`~NEW_DRAIN_FLOW` 684 | :attr:`~PERVIOUS_AREA` 685 | :attr:`~FLOW_TO_PERVIOUS_AREA` 686 | :attr:`~EVAPORATE_RATE` 687 | :attr:`~NATIVE_INFILTRATION` 688 | :attr:`~SURFACE_INFLOW` 689 | :attr:`~SURFACE_INFILTRATION` 690 | :attr:`~SURFACE_EVAPORATION` 691 | :attr:`~SURFACE_OUTFLOW` 692 | :attr:`~PAVEMENT_EVAPORATION` 693 | :attr:`~PAVEMENT_PERCOLATION` 694 | :attr:`~SOIL_EVAPORATION` 695 | :attr:`~SOIL_PERCOLATION` 696 | :attr:`~STORAGE_INFLOW` 697 | :attr:`~STORAGE_EXFILTRATION` 698 | :attr:`~STORAGE_EVAPORATION` 699 | :attr:`~STORAGE_DRAIN` 700 | """ 701 | INFLOW = 0 702 | EVAPORATION = 1 703 | INFILTRATION = 2 704 | SURFACE_FLOW = 3 705 | DRAIN_FLOW = 4 706 | INITIAL_VOLUME = 5 707 | FINAL_VOLUME = 6 708 | SURFACE_DEPTH = 7 709 | PAVEMENT_DEPTH = 8 710 | SOIL_MOISTURE = 9 711 | STORAGE_DEPTH = 10 712 | DRY_TIME = 11 713 | OLD_DRAIN_FLOW = 12 714 | NEW_DRAIN_FLOW = 13 715 | PERVIOUS_AREA = 14 716 | FLOW_TO_PERVIOUS_AREA = 15 717 | EVAPORATE_RATE = 16 718 | NATIVE_INFILTRATION = 17 719 | SURFACE_INFLOW = 18 720 | SURFACE_INFILTRATION = 19 721 | SURFACE_EVAPORATION = 20 722 | SURFACE_OUTFLOW = 21 723 | PAVEMENT_EVAPORATION = 22 724 | PAVEMENT_PERCOLATION = 23 725 | SOIL_EVAPORATION = 24 726 | SOIL_PERCOLATION = 25 727 | STORAGE_INFLOW = 26 728 | STORAGE_EXFILTRATION = 27 729 | STORAGE_EVAPORATION = 28 730 | STORAGE_DRAIN = 29 731 | 732 | 733 | class RainResult(Enum): 734 | """Rain Result enum class. 735 | 736 | :attr:`~TOTAL` 737 | :attr:`~RAINFALL` 738 | :attr:`~SNOWFALL` 739 | """ 740 | TOTAL = 0 741 | RAINFALL = 1 742 | SNOWFALL = 2 743 | 744 | class InletProperty(Enum): 745 | """Inlet Property enum class. 746 | 747 | :attr:`~NUM_INLETS` 748 | :attr:`~CLOG_FACTOR` 749 | :attr:`~FLOW_LIMIT` 750 | :attr:`~DEPRESSION_HEIGHT` 751 | :attr:`~DEPRESSION_WIDTH`""" 752 | NUM_INLETS = 0 753 | CLOG_FACTOR = 1 754 | FLOW_LIMIT = 2 755 | DEPRESSION_HEIGHT = 3 756 | DEPRESSION_WIDTH = 4 757 | 758 | 759 | class InletResult(Enum): 760 | """Inlet Result enum class. 761 | 762 | :attr:`~FLOW_FACTOR` 763 | :attr:`~FLOW CAPTURE` 764 | :attr:`~BACK_FLOW` 765 | :attr:`~BLACK_FLOW_RATIO` 766 | """ 767 | FLOW_FACTOR = 0 768 | FLOW_CAPTURE = 1 769 | BACK_FLOW = 2 770 | BLACK_FLOW_RATIO = 3 771 | 772 | class HotstartFile(Enum): 773 | """Hotstart File enum class. 774 | 775 | :attr:`~USE` 776 | :attr:`~SAVE` 777 | """ 778 | USE = 0 779 | SAVE = 1 -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/solver.i: -------------------------------------------------------------------------------- 1 | /* 2 | * solver.i - SWIG interface description file for swmm-solver 3 | * 4 | * Created: 7/2/2018 5 | * Updated: 8/17/2020 6 | * 7 | * Author: See AUTHORS 8 | * 9 | */ 10 | 11 | 12 | %include "typemaps.i" 13 | %include "cstring.i" 14 | 15 | 16 | /* Docstrings for module */ 17 | %include "solver_docs.i" 18 | 19 | %module(package="swmm.toolkit", docstring=SOLVER_MODULE_DOCS) solver 20 | %{ 21 | #define SWIG_FILE_WITH_INIT 22 | 23 | #include "swmm5.h" 24 | #include "toolkit.h" 25 | #include "toolkit_enums.h" 26 | #include "toolkit_structs.h" 27 | %} 28 | 29 | /* RENAME FUNCTIONS PYTHON STYLE */ 30 | %include "solver_rename.i" 31 | 32 | %include "stats_typemaps.i"; 33 | 34 | 35 | 36 | /* TYPEMAP FOR IGNORING INT ERROR CODE RETURN VALUE */ 37 | %typemap(out) int { 38 | $result = Py_None; 39 | Py_INCREF($result); 40 | } 41 | 42 | %typemap(out) int swmm_getVersion { 43 | $result = PyInt_FromLong($1); 44 | } 45 | 46 | 47 | %apply int *OUTPUT { 48 | int *index, 49 | int *value, 50 | int *count, 51 | int *node1, 52 | int *node2, 53 | int *out_index, 54 | int *condition, 55 | int *year, 56 | int *month, 57 | int *day, 58 | int *hour, 59 | int *minute, 60 | int *second 61 | } 62 | 63 | 64 | %apply double *OUTPUT { 65 | double *elapsedTime, 66 | double *value, 67 | double *result 68 | } 69 | 70 | 71 | %apply float *OUTPUT { 72 | float *runoffErr, 73 | float *flowErr, 74 | float *qualErr 75 | } 76 | 77 | 78 | %apply signed char *OUTPUT { 79 | signed char *value 80 | } 81 | 82 | 83 | %apply char *OUTPUT { 84 | char *condition 85 | } 86 | 87 | 88 | %cstring_output_allocate(char **OUTCHAR, swmm_freeMemory(*$1)); 89 | 90 | %apply char **OUTCHAR { 91 | char **id, 92 | char **major, 93 | char **minor, 94 | char **patch 95 | } 96 | 97 | 98 | /* TYPEMAPS FOR MEMORY MANAGEMNET OF DOUBLE ARRAYS */ 99 | %typemap(in, numinputs=0) double **double_out (double *temp) { 100 | $1=&temp; 101 | } 102 | %typemap(in, numinputs=0) int *int_dim (int temp) { 103 | $1=&temp; 104 | } 105 | %typemap(argout) (double **double_out, int *int_dim) { 106 | if (*$1) { 107 | PyObject *o = PyList_New(*$2); 108 | for(int i=0; i<*$2; i++) { 109 | PyList_SetItem(o, i, PyFloat_FromDouble(temp$argnum[i])); 110 | } 111 | $result = SWIG_Python_AppendOutput($result, o); 112 | swmm_freeMemory(*$1); 113 | } 114 | } 115 | 116 | %apply double **double_out { 117 | double **pollutArray 118 | } 119 | %apply int *int_dim { 120 | int *length 121 | } 122 | %apply (double **double_out, int *int_dim) { 123 | (double **pollutArray, int *length) 124 | } 125 | 126 | 127 | /* TYPEMAP FOR ENUMERATED TYPE INPUT ARGUMENTS */ 128 | %typemap(in) EnumTypeIn { 129 | int value = 0; 130 | if (PyObject_HasAttrString($input, "value")) { 131 | PyObject *o = PyObject_GetAttrString($input, "value"); 132 | SWIG_AsVal_int(o, &value); 133 | } 134 | else if (PyLong_Check($input)) { 135 | SWIG_AsVal_int($input, &value); 136 | } 137 | $1 = ($1_basetype)(value); 138 | } 139 | %apply EnumTypeIn { 140 | SM_ObjectType, 141 | SM_NodeType, 142 | SM_LinkType, 143 | SM_TimePropety, 144 | SM_Units, 145 | SM_SimOption, 146 | SM_SimSetting, 147 | SM_NodeProperty, 148 | SM_LinkProperty, 149 | SM_SubcProperty, 150 | SM_NodeResult, 151 | SM_NodePollut, 152 | SM_LinkResult, 153 | SM_LinkPollut, 154 | SM_SubcResult, 155 | SM_SubcPollut, 156 | SM_GagePrecip, 157 | SM_LidLayer, 158 | SM_LidLayerProperty, 159 | SM_LidUProperty, 160 | SM_LidUOptions, 161 | SM_LidResult, 162 | SM_InletProperty, 163 | SM_InletResult, 164 | SM_HotStart 165 | } 166 | 167 | 168 | /* TYPEMAPS FOR ENUMERATED TYPE OUTPUT ARGUMENTS */ 169 | %typemap(in, numinputs=0) EnumTypeOut * (int temp) { 170 | $1 = ($1_type)&temp; 171 | } 172 | %typemap(argout) EnumTypeOut * { 173 | char *temp = "$1_basetype"; 174 | PyObject *module = PyImport_ImportModule("swmm.toolkit.shared_enum"); 175 | PyObject *function = PyDict_GetItemString(PyModule_GetDict(module), (temp + 3)); 176 | if (PyCallable_Check(function)) { 177 | PyObject *enum_out = PyObject_CallFunction(function, "i", *$1); 178 | %append_output(enum_out); 179 | } 180 | } 181 | %apply EnumTypeOut * { 182 | SM_ObjectType *, 183 | SM_NodeType *, 184 | SM_LinkType * 185 | } 186 | 187 | 188 | /* INSERTS CUSTOM EXCEPTION HANDLING IN WRAPPER */ 189 | %exception swmm_getSemVersion 190 | { 191 | $function 192 | } 193 | 194 | %exception swmm_getBuildId 195 | { 196 | $function 197 | } 198 | 199 | %exception swmm_getVersion 200 | { 201 | $function 202 | } 203 | 204 | /* INSERTS CUSTOM EXCEPTION HANDLING IN WRAPPER */ 205 | %exception 206 | { 207 | $function 208 | if (result > 0) { 209 | char* errorMsg = NULL; 210 | int errorCode = 0; 211 | errorCode = swmm_getAPIError(result, &errorMsg); 212 | if (errorCode == 0) { 213 | PyErr_SetString(PyExc_Exception, errorMsg); 214 | } 215 | swmm_freeMemory(errorMsg); 216 | SWIG_fail; 217 | } 218 | } 219 | 220 | // CANONICAL API 221 | %ignore swmm_getError; 222 | %ignore swmm_getWarnings; 223 | %ignore swmm_IsOpenFlag; 224 | %ignore swmm_IsStartedFlag; 225 | %ignore swmm_IsStartedFlag; 226 | 227 | %ignore swmm_getCount; 228 | %ignore swmm_getName; 229 | %ignore swmm_getIndex; 230 | %ignore swmm_getValue; 231 | %ignore swmm_setValue; 232 | %ignore swmm_getSavedValue; 233 | %ignore swmm_writeLine; 234 | %ignore swmm_decodeDate; 235 | 236 | %include "swmm5.h" 237 | 238 | 239 | // TOOLKIT API 240 | %ignore swmm_run_cb; 241 | %ignore swmm_getAPIError; 242 | %ignore swmm_getObjectIndex; 243 | %ignore swmm_freeMemory; 244 | 245 | 246 | %include "toolkit.h" 247 | 248 | 249 | %exception; -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/solver_rename.i: -------------------------------------------------------------------------------- 1 | /* 2 | * solver_rename.i - Rename mapping for swmm-solver 3 | * 4 | * Created: 2/26/2020 5 | * 6 | * Author: See AUTHORS 7 | * 8 | * Purpose: Renames functions according to PEP8 9 | */ 10 | 11 | 12 | // RENAME STATS STRUCTS 13 | %rename (NodeStats) SM_NodeStats; 14 | %rename (StorageStats) SM_StorageStats; 15 | %rename (OutfallStats) SM_OutfallStats; 16 | %rename (LinkStats) SM_LinkStats; 17 | %rename (PumpStats) SM_PumpStats; 18 | %rename (SubcatchStats) SM_SubcatchStats; 19 | %rename (RoutingTotals) SM_RoutingTotals; 20 | %rename (RunoffTotals) SM_RunoffTotals; 21 | 22 | 23 | // RENAME CANONICAL API AS NECESSARY 24 | %rename(swmm_get_mass_balance) swmm_getMassBalErr; 25 | %rename(swmm_get_version) swmm_getVersion; 26 | 27 | 28 | // RENAME NEW API 29 | %rename(project_get_index) swmm_project_findObject; 30 | %rename(project_get_id) swmm_getObjectId; 31 | %rename(project_get_count) swmm_countObjects; 32 | 33 | 34 | %rename(simulation_get_datetime) swmm_getSimulationDateTime; 35 | %rename(simulation_get_current_datetime) swmm_getCurrentDateTime; 36 | %rename(simulation_set_datetime) swmm_setSimulationDateTime; 37 | %rename(simulation_get_setting) swmm_getSimulationAnalysisSetting; 38 | %rename(simulation_get_parameter) swmm_getSimulationParam; 39 | %rename(simulation_get_unit) swmm_getSimulationUnit; 40 | 41 | 42 | %rename(node_get_type) swmm_getNodeType; 43 | %rename(node_get_parameter) swmm_getNodeParam; 44 | %rename(node_set_parameter) swmm_setNodeParam; 45 | %rename(node_get_result) swmm_getNodeResult; 46 | %rename(node_get_pollutant) swmm_getNodePollut; 47 | %rename(node_set_pollutant) swmm_setNodePollut; 48 | %rename(node_get_total_inflow) swmm_getNodeTotalInflow; 49 | %rename(node_set_total_inflow) swmm_setNodeInflow; 50 | %rename(node_get_stats) swmm_getNodeStats; 51 | 52 | 53 | %rename(storage_get_stats) swmm_getStorageStats; 54 | 55 | 56 | %rename(outfall_set_stage) swmm_setOutfallStage; 57 | %rename(outfall_get_stats) swmm_getOutfallStats; 58 | 59 | 60 | %rename(link_get_type) swmm_getLinkType; 61 | %rename(link_get_connections) swmm_getLinkConnections; 62 | %rename(link_get_direction) swmm_getLinkDirection; 63 | %rename(link_get_parameter) swmm_getLinkParam; 64 | %rename(link_set_parameter) swmm_setLinkParam; 65 | %rename(link_get_result) swmm_getLinkResult; 66 | %rename(link_get_pollutant) swmm_getLinkPollut; 67 | %rename(link_set_pollutant) swmm_setLinkPollut; 68 | %rename(link_set_target_setting) swmm_setLinkSetting; 69 | %rename(link_get_stats) swmm_getLinkStats; 70 | 71 | %rename(inlet_get_parameter) swmm_getInletParam; 72 | %rename(inlet_set_parameter) swmm_setInletParam; 73 | %rename(inlet_get_result) swmm_getInletResult; 74 | 75 | %rename(pump_get_stats) swmm_getPumpStats; 76 | 77 | 78 | %rename(subcatch_get_connection) swmm_getSubcatchOutConnection; 79 | %rename(subcatch_get_parameter) swmm_getSubcatchParam; 80 | %rename(subcatch_set_parameter) swmm_setSubcatchParam; 81 | %rename(subcatch_get_result) swmm_getSubcatchResult; 82 | %rename(subcatch_get_pollutant) swmm_getSubcatchPollut; 83 | %rename(subcatch_get_stats) swmm_getSubcatchStats; 84 | 85 | 86 | %rename(system_get_routing_totals) swmm_getSystemRoutingTotals; 87 | %rename(system_get_runoff_totals) swmm_getSystemRunoffTotals; 88 | 89 | 90 | %rename(lid_usage_get_count) swmm_getLidUCount; 91 | %rename(lid_usage_get_parameter) swmm_getLidUParam; 92 | %rename(lid_usage_set_parameter) swmm_setLidUParam; 93 | %rename(lid_usage_get_option) swmm_getLidUOption; 94 | %rename(lid_usage_set_option) swmm_setLidUOption; 95 | %rename(lid_usage_get_flux_rate) swmm_getLidUFluxRates; 96 | %rename(lid_usage_get_result) swmm_getLidUResult; 97 | %rename(lid_control_get_overflow) swmm_getLidCOverflow; 98 | %rename(lid_control_get_parameter) swmm_getLidCParam; 99 | %rename(lid_control_set_parameter) swmm_setLidCParam; 100 | %rename(lid_group_get_result) swmm_getLidGResult; 101 | 102 | 103 | %rename(raingage_get_precipitation) swmm_getGagePrecip; 104 | %rename(raingage_set_precipitation) swmm_setGagePrecip; 105 | 106 | 107 | %rename(swmm_version_info) swmm_getSemVersion; 108 | %rename(swmm_build_id) swmm_getBuildId; 109 | %rename(swmm_hotstart) swmm_hotstart; -------------------------------------------------------------------------------- /swmm-toolkit/src/swmm/toolkit/stats_typemaps.i: -------------------------------------------------------------------------------- 1 | /* 2 | * stats_typemaps.i - SWIG interface description file for swmm structs 3 | * 4 | * Created: 11/16/2020 5 | * Updated: 6 | * 7 | * Author: See AUTHORS 8 | * 9 | */ 10 | 11 | 12 | %define %statsmaps(Type) 13 | %typemap(in, numinputs=0) Type *out_stats (Type *temp) { 14 | temp = (Type *)calloc(1, sizeof(Type)); 15 | $1 = temp; 16 | } 17 | %typemap(argout) Type *out_stats { 18 | %append_output(SWIG_NewPointerObj(SWIG_as_voidptr(temp$argnum), $1_descriptor, 0)); 19 | } 20 | %enddef 21 | 22 | %statsmaps(SM_NodeStats); 23 | %apply SM_NodeStats *out_stats { 24 | SM_NodeStats *nodeStats 25 | } 26 | 27 | %statsmaps(SM_StorageStats); 28 | %apply SM_StorageStats *out_stats { 29 | SM_StorageStats *storageStats 30 | } 31 | 32 | 33 | /* PROVIDE CUSTOM CONSTRUCTOR/DECONSTRUCTOR */ 34 | %nodefaultctor SM_OutfallStats; 35 | 36 | %extend SM_OutfallStats { 37 | SM_OutfallStats(int num_pollut) { 38 | SM_OutfallStats *s = (SM_OutfallStats *)calloc(1, sizeof(SM_OutfallStats)); 39 | if (num_pollut > 0) 40 | s->totalLoad = (double *)calloc(num_pollut, sizeof(double)); 41 | return s; 42 | } 43 | ~SM_OutfallStats(SM_OutfallStats *self) { 44 | if (self != NULL) 45 | free(self->totalLoad); 46 | free(self); 47 | } 48 | double get_totalLoad(int index) { 49 | return self->totalLoad[index]; 50 | } 51 | } 52 | 53 | %typemap(in, numinputs=0) SM_OutfallStats *out_outfall_stats (SM_OutfallStats *temp) { 54 | int num_pollut; 55 | swmm_countObjects(SM_POLLUT, &num_pollut); 56 | temp = new_SM_OutfallStats(num_pollut); 57 | $1 = temp; 58 | } 59 | %typemap(argout) SM_OutfallStats *out_outfall_stats { 60 | %append_output(SWIG_NewPointerObj(SWIG_as_voidptr(temp$argnum), $1_descriptor, 0)); 61 | } 62 | 63 | %apply SM_OutfallStats *out_outfall_stats { 64 | SM_OutfallStats *outfallStats 65 | } 66 | 67 | 68 | 69 | %statsmaps(SM_LinkStats); 70 | %apply SM_LinkStats *out_stats { 71 | SM_LinkStats *linkStats 72 | } 73 | 74 | 75 | %statsmaps(SM_PumpStats); 76 | %apply SM_PumpStats *out_stats { 77 | SM_PumpStats *pumpStats 78 | } 79 | 80 | 81 | %statsmaps(SM_SubcatchStats); 82 | %apply SM_SubcatchStats *out_stats { 83 | SM_SubcatchStats *subcatchStats 84 | } 85 | 86 | 87 | %statsmaps(SM_RoutingTotals); 88 | %apply SM_RoutingTotals *out_stats { 89 | SM_RoutingTotals *routingTotals 90 | } 91 | 92 | 93 | %statsmaps(SM_RunoffTotals); 94 | %apply SM_RunoffTotals *out_stats { 95 | SM_RunoffTotals *runoffTotals 96 | } 97 | 98 | 99 | /* WRAP PUBLIC STRUCTURES AND GENERATE GETTERS */ 100 | %immutable; 101 | %include "toolkit_structs.h" 102 | %noimmutable; 103 | -------------------------------------------------------------------------------- /swmm-toolkit/test-requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pytest == 7.1.1 5 | numpy == 1.21.6; python_version == "3.7" 6 | numpy == 1.24.4; python_version < "3.12" 7 | numpy == 1.26.2; python_version >= "3.12" 8 | aenum == 3.1.11 9 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/data/test_Example1.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | ;;Project Title/Notes 3 | Example 1 4 | 5 | [OPTIONS] 6 | ;;Option Value 7 | FLOW_UNITS CFS 8 | INFILTRATION HORTON 9 | FLOW_ROUTING KINWAVE 10 | LINK_OFFSETS DEPTH 11 | MIN_SLOPE 0 12 | ALLOW_PONDING NO 13 | SKIP_STEADY_STATE NO 14 | 15 | START_DATE 01/01/1998 16 | START_TIME 00:00:00 17 | REPORT_START_DATE 01/01/1998 18 | REPORT_START_TIME 00:00:00 19 | END_DATE 01/02/1998 20 | END_TIME 12:00:00 21 | SWEEP_START 1/1 22 | SWEEP_END 12/31 23 | DRY_DAYS 5 24 | REPORT_STEP 01:00:00 25 | WET_STEP 00:15:00 26 | DRY_STEP 01:00:00 27 | ROUTING_STEP 0:01:00 28 | 29 | INERTIAL_DAMPING PARTIAL 30 | NORMAL_FLOW_LIMITED BOTH 31 | FORCE_MAIN_EQUATION H-W 32 | VARIABLE_STEP 0.75 33 | LENGTHENING_STEP 0 34 | MIN_SURFAREA 0 35 | MAX_TRIALS 0 36 | HEAD_TOLERANCE 0 37 | SYS_FLOW_TOL 5 38 | LAT_FLOW_TOL 5 39 | MINIMUM_STEP 0.5 40 | THREADS 1 41 | 42 | [EVAPORATION] 43 | ;;Data Source Parameters 44 | ;;-------------- ---------------- 45 | CONSTANT 0.0 46 | DRY_ONLY NO 47 | 48 | [RAINGAGES] 49 | ;;Name Format Interval SCF Source 50 | ;;-------------- --------- ------ ------ ---------- 51 | RG1 INTENSITY 1:00 1.0 TIMESERIES TS1 52 | 53 | [SUBCATCHMENTS] 54 | ;;Name Rain Gage Outlet Area %Imperv Width %Slope CurbLen SnowPack 55 | ;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ---------------- 56 | 2 RG1 10 10 50 500 0.01 0 57 | 3 RG1 13 5 50 500 0.01 0 58 | 1 RG1 9 10 50 500 0.01 0 59 | 4 RG1 22 5 50 500 0.01 0 60 | 5 RG1 15 15 50 500 0.01 0 61 | 6 RG1 23 12 10 500 0.01 0 62 | 7 RG1 19 4 10 500 0.01 0 63 | 8 RG1 18 10 10 500 0.01 0 64 | 65 | [SUBAREAS] 66 | ;;Subcatchment N-Imperv N-Perv S-Imperv S-Perv PctZero RouteTo PctRouted 67 | ;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- 68 | 2 0.001 0.10 0.05 0.05 25 OUTLET 69 | 3 0.001 0.10 0.05 0.05 25 OUTLET 70 | 1 0.001 0.10 0.05 0.05 25 OUTLET 71 | 4 0.001 0.10 0.05 0.05 25 OUTLET 72 | 5 0.001 0.10 0.05 0.05 25 OUTLET 73 | 6 0.001 0.10 0.05 0.05 25 OUTLET 74 | 7 0.001 0.10 0.05 0.05 25 OUTLET 75 | 8 0.001 0.10 0.05 0.05 25 OUTLET 76 | 77 | [INFILTRATION] 78 | ;;Subcatchment MaxRate MinRate Decay DryTime MaxInfil 79 | ;;-------------- ---------- ---------- ---------- ---------- ---------- 80 | 2 0.7 0.3 4.14 0.50 0 81 | 3 0.7 0.3 4.14 0.50 0 82 | 1 0.35 0.25 4.14 0.50 0 83 | 4 0.7 0.3 4.14 0.50 0 84 | 5 0.7 0.3 4.14 0.50 0 85 | 6 0.7 0.3 4.14 0.50 0 86 | 7 0.7 0.3 4.14 0.50 0 87 | 8 0.7 0.3 4.14 0.50 0 88 | 89 | [JUNCTIONS] 90 | ;;Name Elevation MaxDepth InitDepth SurDepth Aponded 91 | ;;-------------- ---------- ---------- ---------- ---------- ---------- 92 | 9 1000 3 0 0 0 93 | 10 995 3 0 0 0 94 | 13 995 3 0 0 0 95 | 14 990 3 0 0 0 96 | 15 987 3 0 0 0 97 | 16 985 3 0 0 0 98 | 17 980 3 0 0 0 99 | 19 1010 3 0 0 0 100 | 20 1005 3 0 0 0 101 | 21 990 3 0 0 0 102 | 22 987 3 0 0 0 103 | 23 990 3 0 0 0 104 | 24 984 3 0 0 0 105 | 106 | [OUTFALLS] 107 | ;;Name Elevation Type Stage Data Gated Route To 108 | ;;-------------- ---------- ---------- ---------------- -------- ---------------- 109 | 18 975 FREE NO 110 | 111 | [STORAGE] 112 | ;; Invert Max. Init. Storage Curve Evap. 113 | ;;Name Elev. Depth Depth Curve Params Frac. Infiltration parameters 114 | ;;-------------- -------- -------- -------- ---------- -------- -------- -------- -------- -------- ----------------------- 115 | SU1 0 1 0 FUNCTIONAL 1000 0 0 0 0 116 | SU2 0 5 0 FUNCTIONAL 1000 0 0 0 0 117 | 118 | [CONDUITS] 119 | ;;Name From Node To Node Length Roughness InOffset OutOffset InitFlow MaxFlow 120 | ;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- 121 | 1 9 10 400 0.01 0 0 0 0 122 | 4 19 20 200 0.01 0 0 0 0 123 | 5 20 21 200 0.01 0 0 0 0 124 | 6 10 21 400 0.01 0 1 0 0 125 | 7 21 22 300 0.01 1 1 0 0 126 | 8 22 16 300 0.01 0 0 0 0 127 | 10 17 18 400 0.01 0 0 0 0 128 | 11 13 14 400 0.01 0 0 0 0 129 | 12 14 15 400 0.01 0 0 0 0 130 | 13 15 16 400 0.01 0 0 0 0 131 | 14 23 24 400 0.01 0 0 0 0 132 | 15 16 24 100 0.01 0 0 0 0 133 | 16 24 17 400 0.01 0 0 0 0 134 | 135 | [PUMPS] 136 | ;; Inlet Outlet Pump Init. Startup Shutoff 137 | ;;Name Node Node Curve Status Depth Depth 138 | ;;-------------- ---------------- ---------------- ---------------- ------ -------- -------- 139 | P1 SU1 SU2 Curve1 ON 0 0 140 | 141 | [XSECTIONS] 142 | ;;Link Shape Geom1 Geom2 Geom3 Geom4 Barrels Culvert 143 | ;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ---------- 144 | 1 CIRCULAR 1.5 0 0 0 1 145 | 4 CIRCULAR 1 0 0 0 1 146 | 5 CIRCULAR 1 0 0 0 1 147 | 6 CIRCULAR 1 0 0 0 1 148 | 7 CIRCULAR 2 0 0 0 1 149 | 8 CIRCULAR 2 0 0 0 1 150 | 10 CIRCULAR 2 0 0 0 1 151 | 11 CIRCULAR 1.5 0 0 0 1 152 | 12 CIRCULAR 1.5 0 0 0 1 153 | 13 CIRCULAR 1.5 0 0 0 1 154 | 14 CIRCULAR 1 0 0 0 1 155 | 15 CIRCULAR 2 0 0 0 1 156 | 16 CIRCULAR 2 0 0 0 1 157 | 158 | [POLLUTANTS] 159 | ;;Name Units Crain Cgw Crdii Kdecay SnowOnly Co-Pollutant Co-Frac Cdwf Cinit 160 | ;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ---------- 161 | TSS MG/L 0.0 0.0 0 0.0 NO * 0.0 0 0 162 | Lead UG/L 0.0 0.0 0 0.0 NO TSS 0.2 0 0 163 | 164 | [LANDUSES] 165 | ;; Sweeping Fraction Last 166 | ;;Name Interval Available Swept 167 | ;;-------------- ---------- ---------- ---------- 168 | Residential 169 | Undeveloped 170 | 171 | [COVERAGES] 172 | ;;Subcatchment Land Use Percent 173 | ;;-------------- ---------------- ---------- 174 | 2 Residential 50.00 175 | 2 Undeveloped 50.00 176 | 3 Residential 100.00 177 | 1 Residential 100.00 178 | 4 Residential 50.00 179 | 4 Undeveloped 50.00 180 | 5 Residential 100.00 181 | 6 Undeveloped 100.00 182 | 7 Undeveloped 100.00 183 | 8 Undeveloped 100.00 184 | 185 | [LOADINGS] 186 | ;;Subcatchment Pollutant Buildup 187 | ;;-------------- ---------------- ---------- 188 | 189 | [BUILDUP] 190 | ;;Land Use Pollutant Function Coeff1 Coeff2 Coeff3 Per Unit 191 | ;;-------------- ---------------- ---------- ---------- ---------- ---------- ---------- 192 | Residential TSS SAT 50 0 2 AREA 193 | Residential Lead NONE 0 0 0 AREA 194 | Undeveloped TSS SAT 100 0 3 AREA 195 | Undeveloped Lead NONE 0 0 0 AREA 196 | 197 | [WASHOFF] 198 | ;;Land Use Pollutant Function Coeff1 Coeff2 SweepRmvl BmpRmvl 199 | ;;-------------- ---------------- ---------- ---------- ---------- ---------- ---------- 200 | Residential TSS EXP 0.1 1 0 0 201 | Residential Lead EMC 0 0 0 0 202 | Undeveloped TSS EXP 0.1 0.7 0 0 203 | Undeveloped Lead EMC 0 0 0 0 204 | 205 | [CURVES] 206 | ;;Name Type X-Value Y-Value 207 | ;;-------------- ---------- ---------- ---------- 208 | Curve1 Pump3 1 0 209 | Curve1 10 1 210 | 211 | [TIMESERIES] 212 | ;;Name Date Time Value 213 | ;;-------------- ---------- ---------- ---------- 214 | ;RAINFALL 215 | TS1 0:00 0.0 216 | TS1 1:00 0.25 217 | TS1 2:00 0.5 218 | TS1 3:00 0.8 219 | TS1 4:00 0.4 220 | TS1 5:00 0.1 221 | TS1 6:00 0.0 222 | TS1 27:00 0.0 223 | TS1 28:00 0.4 224 | TS1 29:00 0.2 225 | TS1 30:00 0.0 226 | 227 | [REPORT] 228 | ;;Reporting Options 229 | INPUT NO 230 | CONTROLS NO 231 | SUBCATCHMENTS ALL 232 | NODES ALL 233 | LINKS ALL 234 | 235 | [TAGS] 236 | 237 | [MAP] 238 | DIMENSIONS 0.000 0.000 10000.000 10000.000 239 | Units None 240 | 241 | [COORDINATES] 242 | ;;Node X-Coord Y-Coord 243 | ;;-------------- ------------------ ------------------ 244 | 9 4042.110 9600.000 245 | 10 4105.260 6947.370 246 | 13 2336.840 4357.890 247 | 14 3157.890 4294.740 248 | 15 3221.050 3242.110 249 | 16 4821.050 3326.320 250 | 17 6252.630 2147.370 251 | 19 7768.420 6736.840 252 | 20 5957.890 6589.470 253 | 21 4926.320 6105.260 254 | 22 4421.050 4715.790 255 | 23 6484.210 3978.950 256 | 24 5389.470 3031.580 257 | 18 6631.580 505.260 258 | SU1 6876.91 50.471 259 | 260 | [VERTICES] 261 | ;;Link X-Coord Y-Coord 262 | ;;-------------- ------------------ ------------------ 263 | 10 6673.680 1368.420 264 | 265 | [Polygons] 266 | ;;Subcatchment X-Coord Y-Coord 267 | ;;-------------- ------------------ ------------------ 268 | 2 7600.000 9663.160 269 | 2 7705.260 6736.840 270 | 2 5915.790 6694.740 271 | 2 4926.320 6294.740 272 | 2 4189.470 7200.000 273 | 2 4126.320 9621.050 274 | 3 2357.890 6021.050 275 | 3 2400.000 4336.840 276 | 3 3031.580 4252.630 277 | 3 2989.470 3389.470 278 | 3 315.790 3410.530 279 | 3 294.740 6000.000 280 | 1 3936.840 6905.260 281 | 1 3494.740 6252.630 282 | 1 273.680 6336.840 283 | 1 252.630 8526.320 284 | 1 463.160 9200.000 285 | 1 1157.890 9726.320 286 | 1 4000.000 9705.260 287 | 4 3473.680 6105.260 288 | 4 3915.790 6421.050 289 | 4 4168.420 6694.740 290 | 4 4463.160 6463.160 291 | 4 4821.050 6063.160 292 | 4 4400.000 5263.160 293 | 4 4357.890 4442.110 294 | 4 4547.370 3705.260 295 | 4 4000.000 3431.580 296 | 4 3326.320 3368.420 297 | 4 3242.110 3536.840 298 | 4 3136.840 5157.890 299 | 4 2589.470 5178.950 300 | 4 2589.470 6063.160 301 | 4 3284.210 6063.160 302 | 4 3705.260 6231.580 303 | 4 4126.320 6715.790 304 | 5 2568.420 3200.000 305 | 5 4905.260 3136.840 306 | 5 5221.050 2842.110 307 | 5 5747.370 2421.050 308 | 5 6463.160 1578.950 309 | 5 6610.530 968.420 310 | 5 6589.470 505.260 311 | 5 1305.260 484.210 312 | 5 968.420 336.840 313 | 5 315.790 778.950 314 | 5 315.790 3115.790 315 | 6 9052.630 4147.370 316 | 6 7894.740 4189.470 317 | 6 6442.110 4105.260 318 | 6 5915.790 3642.110 319 | 6 5326.320 3221.050 320 | 6 4631.580 4231.580 321 | 6 4568.420 5010.530 322 | 6 4884.210 5768.420 323 | 6 5368.420 6294.740 324 | 6 6042.110 6568.420 325 | 6 8968.420 6526.320 326 | 7 8736.840 9642.110 327 | 7 9010.530 9389.470 328 | 7 9010.530 8631.580 329 | 7 9052.630 6778.950 330 | 7 7789.470 6800.000 331 | 7 7726.320 9642.110 332 | 8 9073.680 2063.160 333 | 8 9052.630 778.950 334 | 8 8505.260 336.840 335 | 8 7431.580 315.790 336 | 8 7410.530 484.210 337 | 8 6842.110 505.260 338 | 8 6842.110 589.470 339 | 8 6821.050 1178.950 340 | 8 6547.370 1831.580 341 | 8 6147.370 2378.950 342 | 8 5600.000 3073.680 343 | 8 6589.470 3894.740 344 | 8 8863.160 3978.950 345 | 346 | [SYMBOLS] 347 | ;;Gage X-Coord Y-Coord 348 | ;;-------------- ------------------ ------------------ 349 | RG1 10084.210 8210.530 350 | 351 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/data/test_Example1.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyswmm/swmm-python/11f60fe560a07ecf1b21397b5967330215478eca/swmm-toolkit/tests/data/test_Example1.out -------------------------------------------------------------------------------- /swmm-toolkit/tests/data/test_Example2.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | ;;Project Title/Notes 3 | Example 5 4 | A simple groundwater example. 5 | 6 | [OPTIONS] 7 | ;;Option Value 8 | FLOW_UNITS CFS 9 | INFILTRATION HORTON 10 | FLOW_ROUTING KINWAVE 11 | LINK_OFFSETS DEPTH 12 | MIN_SLOPE 0 13 | ALLOW_PONDING NO 14 | SKIP_STEADY_STATE NO 15 | 16 | START_DATE 09/13/2014 17 | START_TIME 00:00:00 18 | REPORT_START_DATE 09/13/2014 19 | REPORT_START_TIME 00:00:00 20 | END_DATE 09/15/2014 21 | END_TIME 00:00:00 22 | SWEEP_START 01/01 23 | SWEEP_END 12/31 24 | DRY_DAYS 0 25 | REPORT_STEP 01:00:00 26 | WET_STEP 00:30:00 27 | DRY_STEP 01:00:00 28 | ROUTING_STEP 0:00:30 29 | RULE_STEP 00:00:00 30 | 31 | INERTIAL_DAMPING PARTIAL 32 | NORMAL_FLOW_LIMITED BOTH 33 | FORCE_MAIN_EQUATION H-W 34 | VARIABLE_STEP 0.75 35 | LENGTHENING_STEP 0 36 | MIN_SURFAREA 12.557 37 | MAX_TRIALS 8 38 | HEAD_TOLERANCE 0.005 39 | SYS_FLOW_TOL 5 40 | LAT_FLOW_TOL 5 41 | MINIMUM_STEP 0.5 42 | THREADS 1 43 | 44 | [EVAPORATION] 45 | ;;Data Source Parameters 46 | ;;-------------- ---------------- 47 | CONSTANT 0.0 48 | DRY_ONLY NO 49 | 50 | [RAINGAGES] 51 | ;;Name Format Interval SCF Source 52 | ;;-------------- --------- ------ ------ ---------- 53 | 1 INTENSITY 0:15 1.0 TIMESERIES Rainfall 54 | 55 | [SUBCATCHMENTS] 56 | ;;Name Rain Gage Outlet Area %Imperv Width %Slope CurbLen SnowPack 57 | ;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ---------------- 58 | wBC 1 2 5 50 100 1 0 59 | woBC 1 2 5 50 100 1 0 60 | 61 | [SUBAREAS] 62 | ;;Subcatchment N-Imperv N-Perv S-Imperv S-Perv PctZero RouteTo PctRouted 63 | ;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- 64 | wBC 0.01 0.1 0.05 0.05 25 OUTLET 65 | woBC 0.01 0.1 0.05 0.05 25 OUTLET 66 | 67 | [INFILTRATION] 68 | ;;Subcatchment MaxRate MinRate Decay DryTime MaxInfil 69 | ;;-------------- ---------- ---------- ---------- ---------- ---------- 70 | wBC 1.2 0.1 2 7 0 71 | woBC 1.2 0.1 2 7 0 72 | 73 | [LID_CONTROLS] 74 | ;;Name Type/Layer Parameters 75 | ;;-------------- ---------- ---------- 76 | BC BC 77 | BC SURFACE 6 .25 0.1 1.0 5 78 | BC SOIL 12 0.5 0.2 0.1 0.5 10.0 3.5 79 | BC STORAGE 12 0.75 0.5 0 80 | BC DRAIN 0 0.5 6 6 0 0 81 | 82 | [LID_USAGE] 83 | ;;Subcatchment LID Process Number Area Width InitSat FromImp ToPerv RptFile DrainTo FromPerv 84 | ;;-------------- ---------------- ------- ---------- ---------- ---------- ---------- ---------- ------------------------ ---------------- ---------- 85 | wBC BC 100 50 10 0 25 1 "feng.txt" * 0 86 | 87 | [OUTFALLS] 88 | ;;Name Elevation Type Stage Data Gated Route To 89 | ;;-------------- ---------- ---------- ---------------- -------- ---------------- 90 | 2 0 FREE NO 91 | 92 | [TIMESERIES] 93 | ;;Name Date Time Value 94 | ;;-------------- ---------- ---------- ---------- 95 | Rainfall 0:00 0.037 96 | Rainfall 0:15 0.111 97 | Rainfall 0:30 0.185 98 | Rainfall 0:45 0.259 99 | Rainfall 1:00 0.333 100 | Rainfall 1:15 0.407 101 | Rainfall 1:30 0.481 102 | Rainfall 1:45 0.556 103 | Rainfall 2:00 0.630 104 | Rainfall 2:15 0.644 105 | Rainfall 2:30 0.600 106 | Rainfall 2:45 0.556 107 | Rainfall 3:00 0.511 108 | Rainfall 3:15 0.467 109 | Rainfall 3:30 0.422 110 | Rainfall 3:45 0.378 111 | Rainfall 4:00 0.333 112 | Rainfall 4:15 0.289 113 | Rainfall 4:30 0.244 114 | Rainfall 4:45 0.200 115 | Rainfall 5:00 0.156 116 | Rainfall 5:15 0.111 117 | Rainfall 5:30 0.067 118 | Rainfall 5:45 0.022 119 | Rainfall 6:00 0 120 | 121 | [REPORT] 122 | ;;Reporting Options 123 | INPUT YES 124 | CONTROLS YES 125 | SUBCATCHMENTS ALL 126 | NODES ALL 127 | LINKS ALL 128 | 129 | [TAGS] 130 | 131 | [MAP] 132 | DIMENSIONS 2806.303 3109.860 6292.997 8439.437 133 | Units None 134 | 135 | [COORDINATES] 136 | ;;Node X-Coord Y-Coord 137 | ;;-------------- ------------------ ------------------ 138 | 2 4556.338 3352.113 139 | 140 | [VERTICES] 141 | ;;Link X-Coord Y-Coord 142 | ;;-------------- ------------------ ------------------ 143 | 144 | [Polygons] 145 | ;;Subcatchment X-Coord Y-Coord 146 | ;;-------------- ------------------ ------------------ 147 | wBC 2964.789 4971.831 148 | wBC 6134.511 4986.413 149 | wBC 6134.511 7445.652 150 | wBC 2964.789 7450.704 151 | woBC 2957.539 7437.452 152 | woBC 2957.539 7437.452 153 | woBC 2957.539 7437.452 154 | woBC 3000.569 4960.151 155 | woBC 3000.569 4960.151 156 | woBC 1445.340 5236.773 157 | woBC 480.238 5464.218 158 | woBC 369.590 6558.410 159 | woBC 443.355 7425.158 160 | woBC 2963.686 7437.452 161 | 162 | [SYMBOLS] 163 | ;;Gage X-Coord Y-Coord 164 | ;;-------------- ------------------ ------------------ 165 | 1 4485.915 8197.183 166 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/data/test_Example3.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | ;;Project Title/Notes 3 | 4 | [OPTIONS] 5 | ;;Option Value 6 | FLOW_UNITS CMS 7 | INFILTRATION HORTON 8 | FLOW_ROUTING KINWAVE 9 | LINK_OFFSETS DEPTH 10 | MIN_SLOPE 0 11 | ALLOW_PONDING NO 12 | SKIP_STEADY_STATE NO 13 | 14 | START_DATE 01/27/2020 15 | START_TIME 00:00:00 16 | REPORT_START_DATE 01/27/2020 17 | REPORT_START_TIME 00:00:00 18 | END_DATE 01/27/2020 19 | END_TIME 00:30:00 20 | SWEEP_START 01/01 21 | SWEEP_END 02/28 22 | DRY_DAYS 0 23 | REPORT_STEP 00:00:01 24 | WET_STEP 00:00:01 25 | DRY_STEP 00:00:01 26 | ROUTING_STEP 0:00:01 27 | RULE_STEP 00:00:00 28 | 29 | INERTIAL_DAMPING PARTIAL 30 | NORMAL_FLOW_LIMITED BOTH 31 | FORCE_MAIN_EQUATION H-W 32 | VARIABLE_STEP 0.75 33 | LENGTHENING_STEP 0 34 | MIN_SURFAREA 1.14 35 | MAX_TRIALS 8 36 | HEAD_TOLERANCE 0.0015 37 | SYS_FLOW_TOL 5 38 | LAT_FLOW_TOL 5 39 | MINIMUM_STEP 0.5 40 | THREADS 1 41 | 42 | [EVAPORATION] 43 | ;;Data Source Parameters 44 | ;;-------------- ---------------- 45 | CONSTANT 0.0 46 | DRY_ONLY NO 47 | 48 | [OUTFALLS] 49 | ;;Name Elevation Type Stage Data Gated Route To 50 | ;;-------------- ---------- ---------- ---------------- -------- ---------------- 51 | Outfall 0 FREE NO 52 | 53 | [STORAGE] 54 | ;;Name Elev. MaxDepth InitDepth Shape Curve Name/Params N/A Fevap Psi Ksat IMD 55 | ;;-------------- -------- ---------- ----------- ---------- ---------------------------- -------- -------- -------- -------- 56 | Tank 10 5 0 TABULAR Tank_Curve 0 0 57 | 58 | [CONDUITS] 59 | ;;Name From Node To Node Length Roughness InOffset OutOffset InitFlow MaxFlow 60 | ;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- 61 | Valve Tank Outfall 400 0.01 0 0 0 0 62 | 63 | [XSECTIONS] 64 | ;;Link Shape Geom1 Geom2 Geom3 Geom4 Barrels Culvert 65 | ;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ---------- 66 | Valve CIRCULAR 1 0 0 0 1 67 | 68 | [POLLUTANTS] 69 | ;;Name Units Crain Cgw Crdii Kdecay SnowOnly Co-Pollutant Co-Frac Cdwf Cinit 70 | ;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ---------- 71 | P1 MG/L 0.0 0.0 0 0.0 NO * 0.0 0.0 0 72 | 73 | [TREATMENT] 74 | ;;Node Pollutant Function 75 | ;;-------------- ---------------- ---------- 76 | Tank P1 C = 2.0 77 | 78 | [INFLOWS] 79 | ;;Node Constituent Time Series Type Mfactor Sfactor Baseline Pattern 80 | ;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- 81 | Tank FLOW "" FLOW 1.0 1.0 5 82 | Tank P1 "" CONCENTRATION 1.0 1.0 10 83 | 84 | [CURVES] 85 | ;;Name Type X-Value Y-Value 86 | ;;-------------- ---------- ---------- ---------- 87 | Tank_Curve Storage 0 100 88 | Tank_Curve 1 100 89 | Tank_Curve 2 100 90 | Tank_Curve 3 100 91 | Tank_Curve 4 100 92 | Tank_Curve 5 100 93 | 94 | [TIMESERIES] 95 | ;;Name Date Time Value 96 | ;;-------------- ---------- ---------- ---------- 97 | TestRain 1 0 98 | TestRain 2 0.5 99 | TestRain 3 0.75 100 | TestRain 4 1 101 | TestRain 5 0.75 102 | TestRain 6 0.5 103 | TestRain 7 0 104 | 105 | [PATTERNS] 106 | ;;Name Type Multipliers 107 | ;;-------------- ---------- ----------- 108 | DailyX1 DAILY 1.0 1.0 1.0 1.0 1.0 1.0 1.0 109 | 110 | [REPORT] 111 | ;;Reporting Options 112 | SUBCATCHMENTS ALL 113 | NODES ALL 114 | LINKS ALL 115 | 116 | [TAGS] 117 | 118 | [MAP] 119 | DIMENSIONS 0.000 0.000 10000.000 10000.000 120 | Units None 121 | 122 | [COORDINATES] 123 | ;;Node X-Coord Y-Coord 124 | ;;-------------- ------------------ ------------------ 125 | Outfall -178.777 6435.986 126 | Tank -1101.499 6828.143 127 | 128 | [VERTICES] 129 | ;;Link X-Coord Y-Coord 130 | ;;-------------- ------------------ ------------------ 131 | 132 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/data/test_Example3.old.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | ;;Project Title/Notes 3 | 4 | [OPTIONS] 5 | ;;Option Value 6 | FLOW_UNITS CMS 7 | INFILTRATION HORTON 8 | FLOW_ROUTING KINWAVE 9 | LINK_OFFSETS DEPTH 10 | MIN_SLOPE 0 11 | ALLOW_PONDING NO 12 | SKIP_STEADY_STATE NO 13 | 14 | START_DATE 01/27/2020 15 | START_TIME 00:00:00 16 | REPORT_START_DATE 01/27/2020 17 | REPORT_START_TIME 00:00:00 18 | END_DATE 01/27/2020 19 | END_TIME 00:30:00 20 | SWEEP_START 01/01 21 | SWEEP_END 02/28 22 | DRY_DAYS 0 23 | REPORT_STEP 00:00:01 24 | WET_STEP 00:00:01 25 | DRY_STEP 00:00:01 26 | ROUTING_STEP 0:00:01 27 | 28 | INERTIAL_DAMPING PARTIAL 29 | NORMAL_FLOW_LIMITED BOTH 30 | FORCE_MAIN_EQUATION H-W 31 | VARIABLE_STEP 0.75 32 | LENGTHENING_STEP 0 33 | MIN_SURFAREA 1.14 34 | MAX_TRIALS 8 35 | HEAD_TOLERANCE 0.0015 36 | SYS_FLOW_TOL 5 37 | LAT_FLOW_TOL 5 38 | MINIMUM_STEP 0.5 39 | THREADS 1 40 | 41 | [EVAPORATION] 42 | ;;Data Source Parameters 43 | ;;-------------- ---------------- 44 | CONSTANT 0.0 45 | DRY_ONLY NO 46 | 47 | [OUTFALLS] 48 | ;;Name Elevation Type Stage Data Gated Route To 49 | ;;-------------- ---------- ---------- ---------------- -------- ---------------- 50 | Outfall 0 FREE NO 51 | 52 | [STORAGE] 53 | ;;Name Elev. MaxDepth InitDepth Shape Curve Name/Params N/A Fevap Psi Ksat IMD 54 | ;;-------------- -------- ---------- ----------- ---------- ---------------------------- -------- -------- -------- -------- 55 | Tank 10 5 0 TABULAR Tank_Curve 0 0 56 | 57 | [ORIFICES] 58 | ;;Name From Node To Node Type Offset Qcoeff Gated CloseTime 59 | ;;-------------- ---------------- ---------------- ------------ ---------- ---------- -------- ---------- 60 | Valve Tank Outfall BOTTOM 0 1 NO 0 61 | 62 | [XSECTIONS] 63 | ;;Link Shape Geom1 Geom2 Geom3 Geom4 Barrels Culvert 64 | ;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ---------- 65 | Valve RECT_CLOSED 1 1 0 0 66 | 67 | [POLLUTANTS] 68 | ;;Name Units Crain Cgw Crdii Kdecay SnowOnly Co-Pollutant Co-Frac Cdwf Cinit 69 | ;;-------------- ------ ---------- ---------- ---------- ---------- ---------- ---------------- ---------- ---------- ---------- 70 | P1 MG/L 0.0 0.0 0 0.0 NO * 0.0 0.0 0 71 | 72 | 73 | [INFLOWS] 74 | ;;Node Constituent Time Series Type Mfactor Sfactor Baseline Pattern 75 | ;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- 76 | Tank FLOW "" FLOW 1.0 1.0 5 77 | Tank P1 "" CONCENTRATION 1.0 1.0 10 78 | 79 | [TREATMENT] 80 | ;;Node Pollutant Function 81 | ;;-------------- ---------------- ---------- 82 | Tank P1 C = 2.0 83 | 84 | [CURVES] 85 | ;;Name Type X-Value Y-Value 86 | ;;-------------- ---------- ---------- ---------- 87 | Tank_Curve Storage 0 100 88 | Tank_Curve 1 100 89 | Tank_Curve 2 100 90 | Tank_Curve 3 100 91 | Tank_Curve 4 100 92 | Tank_Curve 5 100 93 | 94 | [TIMESERIES] 95 | ;;Name Date Time Value 96 | ;;-------------- ---------- ---------- ---------- 97 | TestRain 1 0 98 | TestRain 2 0.5 99 | TestRain 3 0.75 100 | TestRain 4 1 101 | TestRain 5 0.75 102 | TestRain 6 0.5 103 | TestRain 7 0 104 | 105 | [PATTERNS] 106 | ;;Name Type Multipliers 107 | ;;-------------- ---------- ----------- 108 | DailyX1 DAILY 1.0 1.0 1.0 1.0 1.0 1.0 1.0 109 | 110 | [REPORT] 111 | ;;Reporting Options 112 | INPUT NO 113 | CONTROLS NO 114 | SUBCATCHMENTS ALL 115 | NODES ALL 116 | LINKS ALL 117 | 118 | [TAGS] 119 | 120 | [MAP] 121 | DIMENSIONS 0.000 0.000 10000.000 10000.000 122 | Units None 123 | 124 | [COORDINATES] 125 | ;;Node X-Coord Y-Coord 126 | ;;-------------- ------------------ ------------------ 127 | Outfall -178.777 6435.986 128 | Tank -1101.499 6828.143 129 | 130 | [VERTICES] 131 | ;;Link X-Coord Y-Coord 132 | ;;-------------- ------------------ ------------------ 133 | 134 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/data/test_inlet_drains.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | ;;Project Title/Notes 3 | A dual drainage model with street inlets. 4 | See Inlet_Drains_Model.txt for more details. 5 | 6 | [OPTIONS] 7 | ;;Option Value 8 | FLOW_UNITS CFS 9 | INFILTRATION HORTON 10 | FLOW_ROUTING DYNWAVE 11 | LINK_OFFSETS DEPTH 12 | MIN_SLOPE 0 13 | ALLOW_PONDING NO 14 | SKIP_STEADY_STATE NO 15 | 16 | START_DATE 01/01/2007 17 | START_TIME 00:00:00 18 | REPORT_START_DATE 01/01/2007 19 | REPORT_START_TIME 00:00:00 20 | END_DATE 01/01/2007 21 | END_TIME 06:00:00 22 | SWEEP_START 01/01 23 | SWEEP_END 12/31 24 | DRY_DAYS 0 25 | REPORT_STEP 00:01:00 26 | WET_STEP 00:01:00 27 | DRY_STEP 01:00:00 28 | ROUTING_STEP 0:00:15 29 | RULE_STEP 00:00:00 30 | 31 | INERTIAL_DAMPING PARTIAL 32 | NORMAL_FLOW_LIMITED SLOPE 33 | FORCE_MAIN_EQUATION H-W 34 | VARIABLE_STEP 0.75 35 | LENGTHENING_STEP 0 36 | MIN_SURFAREA 12.566 37 | MAX_TRIALS 8 38 | HEAD_TOLERANCE 0.005 39 | SYS_FLOW_TOL 5 40 | LAT_FLOW_TOL 5 41 | MINIMUM_STEP 0.5 42 | THREADS 1 43 | 44 | [EVAPORATION] 45 | ;;Data Source Parameters 46 | ;;-------------- ---------------- 47 | CONSTANT 0.0 48 | DRY_ONLY NO 49 | 50 | [RAINGAGES] 51 | ;;Name Format Interval SCF Source 52 | ;;-------------- --------- ------ ------ ---------- 53 | RainGage INTENSITY 0:05 1.0 TIMESERIES 2-yr 54 | 55 | [SUBCATCHMENTS] 56 | ;;Name Rain Gage Outlet Area %Imperv Width %Slope CurbLen SnowPack 57 | ;;-------------- ---------------- ---------------- -------- -------- -------- -------- -------- ---------------- 58 | S1 RainGage Aux1 4.55 56.8 1587 2 0 59 | S2 RainGage Aux4 4.74 63.0 1653 2 0 60 | S3 RainGage Aux3 3.74 39.5 1456 3.1 0 61 | S4 RainGage J7 6.79 49.9 2331 3.1 0 62 | S5 RainGage J10 4.79 87.7 1670 2 0 63 | S6 RainGage J11 1.98 95.0 690 2 0 64 | S7 RainGage J10 2.33 0.0 907 3.1 0 65 | 66 | [SUBAREAS] 67 | ;;Subcatchment N-Imperv N-Perv S-Imperv S-Perv PctZero RouteTo PctRouted 68 | ;;-------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- 69 | S1 0.015 0.24 0.06 0.3 25 OUTLET 70 | S2 0.015 0.24 0.06 0.3 25 OUTLET 71 | S3 0.015 0.24 0.06 0.3 25 OUTLET 72 | S4 0.015 0.24 0.06 0.3 25 OUTLET 73 | S5 0.015 0.24 0.06 0.3 25 OUTLET 74 | S6 0.015 0.24 0.06 0.3 25 OUTLET 75 | S7 0.015 0.24 0.06 0.3 25 OUTLET 76 | 77 | [INFILTRATION] 78 | ;;Subcatchment Param1 Param2 Param3 Param4 Param5 79 | ;;-------------- ---------- ---------- ---------- ---------- ---------- 80 | S1 4.5 0.2 6.5 7 0 81 | S2 4.5 0.2 6.5 7 0 82 | S3 4.5 0.2 6.5 7 0 83 | S4 4.5 0.2 6.5 7 0 84 | S5 4.5 0.2 6.5 7 0 85 | S6 4.5 0.2 6.5 7 0 86 | S7 4.5 0.2 6.5 7 0 87 | 88 | [JUNCTIONS] 89 | ;;Name Elevation MaxDepth InitDepth SurDepth Aponded 90 | ;;-------------- ---------- ---------- ---------- ---------- ---------- 91 | Aux1 4975 0 0 0 0 92 | Aux2 4973 0 0 0 0 93 | Aux3 4968.5 0 0 0 0 94 | Aux4 4971.8 0 0 0 0 95 | Aux5 4970.7 0 0 0 0 96 | Aux6 4969 0 0 0 0 97 | Aux7 4963 0 0 0 0 98 | J1 4969 4 0 0 0 99 | J10 4957.8 0 0 0 0 100 | J11 4957 0 0 0 0 101 | J2 4965 4 0 0 0 102 | J2a 4966.7 4 0 0 0 103 | J3 4973 0 0 0 0 104 | J4 4965 0 0 0 0 105 | J5 4965.8 0 0 0 0 106 | J6 4969 0 0 0 0 107 | J7 4963.5 0 0 0 0 108 | J8 4966.5 0 0 0 0 109 | J9 4964.8 0 0 0 0 110 | 111 | [OUTFALLS] 112 | ;;Name Elevation Type Stage Data Gated Route To 113 | ;;-------------- ---------- ---------- ---------------- -------- ---------------- 114 | O1 4956 FREE NO 115 | 116 | [CONDUITS] 117 | ;;Name From Node To Node Length Roughness InOffset OutOffset InitFlow MaxFlow 118 | ;;-------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- 119 | Street1 Aux1 Aux2 377.31 0.016 0 0 0 0 120 | Street2 Aux2 Aux4 286.06 0.016 0 0 0 0 121 | Street3 Aux4 Aux5 239.41 0.016 0 0 0 0 122 | Street4 Aux5 Aux6 157.48 0.016 0 0 0 0 123 | Street5 Aux6 Aux7 526.0 0.016 0 0 0 0 124 | C3 J3 J4 109.0 0.016 0 6 0 0 125 | C4 J4 J5 133.0 0.05 6 4 0 0 126 | C5 J5 J6 207.0 0.05 4 0 0 0 127 | C6 J7 J6 140.0 0.05 8 0 0 0 128 | C7 J6 J8 95.0 0.016 0 0 0 0 129 | C8 J8 J9 166.0 0.05 0 0 0 0 130 | C9 J9 J10 320.0 0.05 0 6 0 0 131 | C10 J10 J11 145.0 0.05 6 6 0 0 132 | C11 J11 O1 89.0 0.016 0 0 0 0 133 | C_Aux3 Aux3 J3 444.75 0.05 6 0 0 0 134 | P1 J1 J5 185.39 0.016 0 0 0 0 135 | P2 J2a J2 157.48 0.016 0 0 0 0 136 | P3 J2 J11 529.22 0.016 0 0 0 0 137 | P4 Aux3 J4 567.19 0.016 0 0 0 0 138 | P5 J5 J4 125.98 0.016 0 0 0 0 139 | P6 J4 J7 360.39 0.016 0 0 0 0 140 | P7 J7 J10 507.76 0.016 0 0 0 0 141 | P8 J10 J11 144.50 0.016 0 0 0 0 142 | 143 | [XSECTIONS] 144 | ;;Link Shape Geom1 Geom2 Geom3 Geom4 Barrels Culvert 145 | ;;-------------- ------------ ---------------- ---------- ---------- ---------- ---------- ---------- 146 | Street1 STREET FullStreet 147 | Street2 STREET FullStreet 148 | Street3 STREET FullStreet 149 | Street4 STREET HalfStreet 150 | Street5 STREET HalfStreet 151 | C3 CIRCULAR 2.25 0 0 0 1 152 | C4 TRAPEZOIDAL 3 5 5 5 1 153 | C5 TRAPEZOIDAL 3 5 5 5 1 154 | C6 TRAPEZOIDAL 3 5 5 5 1 155 | C7 CIRCULAR 3.5 0 0 0 1 156 | C8 TRAPEZOIDAL 3 5 5 5 1 157 | C9 TRAPEZOIDAL 3 5 5 5 1 158 | C10 TRAPEZOIDAL 3 5 5 5 1 159 | C11 CIRCULAR 4.75 0 0 0 1 160 | C_Aux3 TRAPEZOIDAL 3 5 5 5 1 161 | P1 CIRCULAR 0.5 0 0 0 1 162 | P2 CIRCULAR 1.5 0 0 0 1 163 | P3 CIRCULAR 1.5 0 0 0 1 164 | P4 CIRCULAR 1.67 0 0 0 1 165 | P5 CIRCULAR 1.83 0 0 0 1 166 | P6 CIRCULAR 2 0 0 0 1 167 | P7 CIRCULAR 2 0 0 0 1 168 | P8 CIRCULAR 3.17 0 0 0 1 169 | 170 | [STREETS] 171 | ;;Name Tcrown Hcurb Sx nRoad a W Sides Tback Sback nBack 172 | ;;-------------- -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- 173 | HalfStreet 20 0.5 4 0.016 0 0 1 20 4 0.016 174 | FullStreet 20 0.5 4 0.016 0 0 2 20 4 0.016 175 | 176 | [INLETS] 177 | ;;Name Type Parameters: 178 | ;;-------------- ---------------- ----------- 179 | ComboInlet GRATE 2 2 P_BAR-50 180 | ComboInlet CURB 2 0.5 HORIZONTAL 181 | 182 | [INLET_USAGE] 183 | ;;Conduit Inlet Node Number %Clogged Qmax aLocal wLocal Placement 184 | ;;-------------- ---------------- ---------------- --------- --------- --------- --------- --------- --------- --------- 185 | Street1 ComboInlet J1 1 50 2.2 0.5 2 186 | Street3 ComboInlet J2a 1 0 0 0 0 187 | Street4 ComboInlet J2 1 0 0 0 0 188 | Street5 ComboInlet J11 2 0 0 0 0 189 | 190 | [TIMESERIES] 191 | ;;Name Date Time Value 192 | ;;-------------- ---------- ---------- ---------- 193 | 2-yr 0:00 0.29 194 | 2-yr 0:05 0.33 195 | 2-yr 0:10 0.38 196 | 2-yr 0:15 0.64 197 | 2-yr 0:20 0.81 198 | 2-yr 0:25 1.57 199 | 2-yr 0:30 2.85 200 | 2-yr 0:35 1.18 201 | 2-yr 0:40 0.71 202 | 2-yr 0:45 0.42 203 | 2-yr 0:50 0.35 204 | 2-yr 0:55 0.3 205 | 2-yr 1:00 0.2 206 | 2-yr 1:05 0.19 207 | 2-yr 1:10 0.18 208 | 2-yr 1:15 0.17 209 | 2-yr 1:20 0.17 210 | 2-yr 1:25 0.16 211 | 2-yr 1:30 0.15 212 | 2-yr 1:35 0.15 213 | 2-yr 1:40 0.14 214 | 2-yr 1:45 0.14 215 | 2-yr 1:50 0.13 216 | 2-yr 1:55 0.13 217 | ; 218 | 10-yr 0:00 0.49 219 | 10-yr 0:05 0.56 220 | 10-yr 0:10 0.65 221 | 10-yr 0:15 1.09 222 | 10-yr 0:20 1.39 223 | 10-yr 0:25 2.69 224 | 10-yr 0:30 4.87 225 | 10-yr 0:35 2.02 226 | 10-yr 0:40 1.21 227 | 10-yr 0:45 0.71 228 | 10-yr 0:50 0.6 229 | 10-yr 0:55 0.52 230 | 10-yr 1:00 0.39 231 | 10-yr 1:05 0.37 232 | 10-yr 1:10 0.35 233 | 10-yr 1:15 0.34 234 | 10-yr 1:20 0.32 235 | 10-yr 1:25 0.31 236 | 10-yr 1:30 0.3 237 | 10-yr 1:35 0.29 238 | 10-yr 1:40 0.28 239 | 10-yr 1:45 0.27 240 | 10-yr 1:50 0.26 241 | 10-yr 1:55 0.25 242 | 243 | [REPORT] 244 | ;;Reporting Options 245 | INPUT YES 246 | SUBCATCHMENTS ALL 247 | NODES ALL 248 | LINKS ALL 249 | 250 | [TAGS] 251 | Link Street1 Full_Street 252 | Link Street2 Full_Street 253 | Link Street3 Full_Street 254 | Link Street4 Half_Street 255 | Link Street5 Half_Street 256 | Link C3 Culvert 257 | Link C4 Swale 258 | Link C5 Swale 259 | Link C6 Swale 260 | Link C7 Culvert 261 | Link C8 Swale 262 | Link C9 Swale 263 | Link C10 Swale 264 | Link C11 Culvert 265 | Link C_Aux3 Swale 266 | 267 | [MAP] 268 | DIMENSIONS -255.206 -70.199 1490.833 1514.231 269 | Units Feet 270 | 271 | [COORDINATES] 272 | ;;Node X-Coord Y-Coord 273 | ;;-------------- ------------------ ------------------ 274 | Aux1 293.152 1161.023 275 | Aux2 653.046 1052.180 276 | Aux3 122.363 696.959 277 | Aux4 914.142 1058.025 278 | Aux5 1175.238 1120.376 279 | Aux6 1260.972 956.704 280 | Aux7 1381.777 514.399 281 | J1 647.200 1022.952 282 | J10 1254.058 640.029 283 | J11 1270.714 491.017 284 | J2 1218.105 950.859 285 | J2a 1159.651 1069.716 286 | J3 405.287 905.702 287 | J4 505.345 862.573 288 | J5 631.281 859.123 289 | J6 803.079 869.022 290 | J7 831.398 709.035 291 | J8 915.930 840.146 292 | J9 1072.918 867.749 293 | O1 1411.468 477.401 294 | 295 | [VERTICES] 296 | ;;Link X-Coord Y-Coord 297 | ;;-------------- ------------------ ------------------ 298 | Street1 382.860 1112.719 299 | Street1 514.703 1061.922 300 | Street2 806.976 1042.437 301 | Street3 1062.227 1091.149 302 | Street4 1210.311 1061.922 303 | Street5 1338.911 781.341 304 | Street5 1387.623 662.483 305 | Street5 1393.468 586.493 306 | C4 559.710 846.393 307 | C5 672.684 850.497 308 | C5 712.363 829.795 309 | C5 743.415 805.643 310 | C5 768.006 833.950 311 | C6 791.719 734.912 312 | C6 798.620 784.942 313 | C8 965.959 838.421 314 | C8 995.287 831.520 315 | C8 1038.415 850.497 316 | C9 1102.246 867.749 317 | C9 1131.573 852.222 318 | C9 1147.099 829.795 319 | C9 1162.626 809.094 320 | C9 1198.854 779.766 321 | C9 1219.556 757.339 322 | C9 1233.357 721.111 323 | C9 1238.532 715.936 324 | C9 1235.082 674.532 325 | C9 1247.158 646.930 326 | C_Aux3 163.003 699.992 327 | C_Aux3 208.620 726.287 328 | C_Aux3 239.673 793.567 329 | C_Aux3 251.749 876.374 330 | C_Aux3 291.427 912.602 331 | C_Aux3 355.257 929.854 332 | P3 1331.117 691.711 333 | P3 1329.168 590.390 334 | P4 275.901 572.749 335 | P4 472.567 824.620 336 | P7 886.602 800.468 337 | 338 | [Polygons] 339 | ;;Subcatchment X-Coord Y-Coord 340 | ;;-------------- ------------------ ------------------ 341 | S1 282.657 1334.810 342 | S1 111.700 1101.604 343 | S1 172.525 1062.743 344 | S1 231.660 1027.262 345 | S1 306.002 990.092 346 | S1 370.206 959.679 347 | S1 409.066 946.163 348 | S1 444.547 936.025 349 | S1 493.545 924.198 350 | S1 532.405 915.750 351 | S1 569.576 907.302 352 | S1 610.125 897.165 353 | S1 655.744 897.165 354 | S1 684.338 1318.700 355 | S1 651.043 1321.922 356 | S1 596.269 1332.662 357 | S1 551.160 1346.624 358 | S1 495.312 1367.030 359 | S1 455.573 1384.214 360 | S1 410.465 1409.991 361 | S1 386.836 1427.175 362 | S1 363.208 1442.211 363 | S2 678.967 1238.149 364 | S2 673.584 1152.903 365 | S2 655.744 897.165 366 | S2 758.808 893.786 367 | S2 817.943 895.475 368 | S2 880.458 898.855 369 | S2 921.007 905.613 370 | S2 978.453 920.819 371 | S2 1042.657 937.715 372 | S2 1103.482 959.679 373 | S2 1159.238 985.023 374 | S2 1225.131 1010.367 375 | S2 1109.646 1274.665 376 | S2 1052.723 1400.325 377 | S2 985.061 1370.252 378 | S2 924.916 1348.772 379 | S2 861.549 1331.588 380 | S2 815.367 1325.144 381 | S2 762.740 1319.774 382 | S2 719.780 1316.552 383 | S2 684.338 1317.626 384 | S3 109.199 1103.258 385 | S3 141.754 1081.555 386 | S3 190.586 1051.713 387 | S3 247.557 1019.158 388 | S3 304.528 989.317 389 | S3 354.716 964.900 390 | S3 398.123 949.980 391 | S3 490.166 922.509 392 | S3 477.743 883.275 393 | S3 501.993 816.065 394 | S3 556.059 778.895 395 | S3 488.476 679.210 396 | S3 422.582 729.897 397 | S3 282.348 557.560 398 | S3 179.734 633.927 399 | S3 153.962 651.561 400 | S3 107.843 693.610 401 | S3 71.218 742.443 402 | S3 48.159 785.849 403 | S3 31.881 837.394 404 | S3 29.168 886.226 405 | S3 31.881 933.702 406 | S3 38.664 967.613 407 | S3 50.872 1001.525 408 | S3 65.793 1035.436 409 | S3 87.496 1070.704 410 | S3 109.199 1103.258 411 | S4 282.348 559.250 412 | S4 420.893 729.897 413 | S4 488.476 680.899 414 | S4 556.828 779.067 415 | S4 501.213 814.335 416 | S4 479.468 885.000 417 | S4 491.718 922.851 418 | S4 616.511 898.434 419 | S4 668.056 897.078 420 | S4 783.355 895.722 421 | S4 815.909 898.434 422 | S4 857.959 899.791 423 | S4 890.595 897.165 424 | S4 968.316 915.750 425 | S4 1042.657 937.715 426 | S4 1074.759 849.857 427 | S4 1054.484 773.826 428 | S4 1020.692 702.864 429 | S4 963.247 623.454 430 | S4 689.536 256.816 431 | S5 1301.482 474.258 432 | S5 1271.677 445.380 433 | S5 1232.340 393.835 434 | S5 1241.835 384.340 435 | S5 1222.844 366.706 436 | S5 1233.696 355.854 437 | S5 1026.159 66.931 438 | S5 1008.525 56.079 439 | S5 708.750 275.824 440 | S5 1023.446 704.462 441 | S5 1150.644 618.812 442 | S5 1251.203 640.809 443 | S5 1328.193 519.824 444 | S6 1334.478 519.824 445 | S6 1306.266 488.956 446 | S6 1293.380 474.205 447 | S6 1232.340 393.835 448 | S6 1241.835 381.627 449 | S6 1222.844 365.350 450 | S6 1232.340 353.142 451 | S6 1027.516 65.574 452 | S6 1012.595 56.079 453 | S6 707.393 273.111 454 | S6 688.403 254.121 455 | S6 739.948 218.853 456 | S6 788.780 159.169 457 | S6 806.414 106.268 458 | S6 813.197 1.821 459 | S6 994.961 12.673 460 | S6 1228.270 27.594 461 | S6 1222.844 115.763 462 | S6 1228.270 167.308 463 | S6 1241.835 229.705 464 | S6 1255.399 254.121 465 | S6 1279.815 302.953 466 | S6 1309.657 354.498 467 | S6 1335.430 401.974 468 | S6 1359.846 448.093 469 | S6 1370.616 475.830 470 | S6 1381.615 491.542 471 | S7 1122.467 968.970 472 | S7 1174.012 987.282 473 | S7 1225.557 1005.594 474 | S7 1377.480 675.977 475 | S7 1391.044 642.065 476 | S7 1396.470 598.659 477 | S7 1381.615 491.542 478 | S7 1331.336 519.824 479 | S7 1249.632 640.809 480 | S7 1150.644 617.241 481 | S7 1020.733 704.462 482 | S7 1054.645 772.285 483 | S7 1076.796 848.212 484 | S7 1056.370 900.062 485 | S7 1040.658 937.772 486 | 487 | [SYMBOLS] 488 | ;;Gage X-Coord Y-Coord 489 | ;;-------------- ------------------ ------------------ 490 | RainGage -175.841 1212.778 491 | 492 | [LABELS] 493 | ;;X-Coord Y-Coord Label 494 | 145.274 1129.896 "S1" "" "Arial" 14 0 0 495 | 758.404 969.723 "S2" "" "Arial" 14 0 0 496 | 247.369 666.226 "S3" "" "Arial" 14 0 0 497 | 628.971 458.688 "S4" "" "Arial" 14 0 0 498 | 952.552 257.845 "S5" "" "Arial" 14 0 0 499 | 827.947 56.930 "S6" "" "Arial" 14 0 0 500 | 1073.058 780.037 "S7" "" "Arial" 14 0 0 501 | 1385.481 454.225 "Outfall" "" "Arial" 10 1 0 502 | 503 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/test_metadata.py: -------------------------------------------------------------------------------- 1 | # 2 | # test_metadata.py 3 | # 4 | # Created: Apr 8, 2020 5 | # Modified: Apr 20, 2020 6 | # 7 | # Author: See AUTHORS 8 | # 9 | # Unit testing for SWMM output metadata using pytest. 10 | # 11 | 12 | 13 | import os 14 | 15 | import pytest 16 | 17 | from swmm.toolkit import output, shared_enum, output_metadata 18 | 19 | 20 | DATA_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data') 21 | OUTPUT_FILE_EXAMPLE1 = os.path.join(DATA_PATH, 'test_Example1.out') 22 | 23 | 24 | @pytest.fixture() 25 | def handle(request): 26 | _handle = output.init() 27 | output.open(_handle, OUTPUT_FILE_EXAMPLE1) 28 | 29 | def close(): 30 | output.close(_handle) 31 | 32 | request.addfinalizer(close) 33 | return _handle 34 | 35 | 36 | def test_outputmetadata(handle): 37 | 38 | om = output_metadata.OutputMetadata(handle) 39 | 40 | ref = { 41 | shared_enum.SubcatchAttribute.RAINFALL: ("Rainfall", "in/hr"), 42 | shared_enum.SubcatchAttribute.SNOW_DEPTH: ("Snow Depth", "in"), 43 | shared_enum.SubcatchAttribute.EVAP_LOSS: ("Evaporation Loss", "in/day"), 44 | shared_enum.SubcatchAttribute.INFIL_LOSS: ("Infiltration Loss", "in/hr"), 45 | shared_enum.SubcatchAttribute.RUNOFF_RATE: ("Runoff Rate", "cu ft/sec"), 46 | shared_enum.SubcatchAttribute.GW_OUTFLOW_RATE: ("Groundwater Flow Rate", "cu ft/sec"), 47 | shared_enum.SubcatchAttribute.GW_TABLE_ELEV: ("Groundwater Elevation", "ft"), 48 | shared_enum.SubcatchAttribute.SOIL_MOISTURE: ("Soil Moisture", "%"), 49 | shared_enum.SubcatchAttribute.POLLUT_CONC_0: ("TSS", "mg/L"), 50 | shared_enum.SubcatchAttribute.POLLUT_CONC_1: ("Lead", "ug/L"), 51 | 52 | shared_enum.NodeAttribute.INVERT_DEPTH: ("Invert Depth", "ft"), 53 | shared_enum.NodeAttribute.HYDRAULIC_HEAD: ("Hydraulic Head", "ft"), 54 | shared_enum.NodeAttribute.PONDED_VOLUME: ("Ponded Volume", "cu ft"), 55 | shared_enum.NodeAttribute.LATERAL_INFLOW: ("Lateral Inflow", "cu ft/sec"), 56 | shared_enum.NodeAttribute.TOTAL_INFLOW: ("Total Inflow", "cu ft/sec"), 57 | shared_enum.NodeAttribute.FLOODING_LOSSES: ("Flooding Loss", "cu ft/sec"), 58 | shared_enum.NodeAttribute.POLLUT_CONC_0: ("TSS", "mg/L"), 59 | shared_enum.NodeAttribute.POLLUT_CONC_1: ("Lead", "ug/L"), 60 | 61 | shared_enum.LinkAttribute.FLOW_RATE: ("Flow Rate", "cu ft/sec"), 62 | shared_enum.LinkAttribute.FLOW_DEPTH: ("Flow Depth", "ft"), 63 | shared_enum.LinkAttribute.FLOW_VELOCITY: ("Flow Velocity", "ft/sec"), 64 | shared_enum.LinkAttribute.FLOW_VOLUME: ("Flow Volume", "cu ft"), 65 | shared_enum.LinkAttribute.CAPACITY: ("Capacity", "%"), 66 | shared_enum.LinkAttribute.POLLUT_CONC_0: ("TSS", "mg/L"), 67 | shared_enum.LinkAttribute.POLLUT_CONC_1: ("Lead", "ug/L"), 68 | 69 | shared_enum.SystemAttribute.AIR_TEMP: ("Temperature", "deg F"), 70 | shared_enum.SystemAttribute.RAINFALL: ("Rainfall", "in/hr"), 71 | shared_enum.SystemAttribute.SNOW_DEPTH: ("Snow Depth", "in"), 72 | shared_enum.SystemAttribute.EVAP_INFIL_LOSS: ("Evap and Infil Losses", "in/hr"), 73 | shared_enum.SystemAttribute.RUNOFF_FLOW: ("Runoff Flow Rate", "cu ft/sec"), 74 | shared_enum.SystemAttribute.DRY_WEATHER_INFLOW: ("Dry Weather Inflow", "cu ft/sec"), 75 | shared_enum.SystemAttribute.GW_INFLOW: ("Groundwater Inflow", "cu ft/sec"), 76 | shared_enum.SystemAttribute.RDII_INFLOW: ("RDII Inflow", "cu ft/sec"), 77 | shared_enum.SystemAttribute.DIRECT_INFLOW: ("Direct Inflow", "cu ft/sec"), 78 | shared_enum.SystemAttribute.TOTAL_LATERAL_INFLOW: ("Total Lateral Inflow", "cu ft/sec"), 79 | shared_enum.SystemAttribute.FLOOD_LOSSES: ("Flood Losses", "cu ft/sec"), 80 | shared_enum.SystemAttribute.OUTFALL_FLOWS: ("Outfall Flow", "cu ft/sec"), 81 | shared_enum.SystemAttribute.VOLUME_STORED: ("Volume Stored", "cu ft"), 82 | shared_enum.SystemAttribute.EVAP_RATE: ("Evaporation Rate", "in/day"), 83 | shared_enum.SystemAttribute.PTNL_EVAP_RATE: ("Potential Evaporation Rate", "in/day") 84 | } 85 | 86 | for attr in shared_enum.SubcatchAttribute: 87 | temp = om.get_attribute_metadata(attr) 88 | assert temp == ref[attr] 89 | 90 | for attr in shared_enum.NodeAttribute: 91 | temp = om.get_attribute_metadata(attr) 92 | assert temp == ref[attr] 93 | 94 | for attr in shared_enum.LinkAttribute: 95 | temp = om.get_attribute_metadata(attr) 96 | assert temp == ref[attr] 97 | 98 | for attr in shared_enum.SystemAttribute: 99 | temp = om.get_attribute_metadata(attr) 100 | assert temp == ref[attr] 101 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/test_output.py: -------------------------------------------------------------------------------- 1 | # 2 | # test_output.py 3 | # 4 | # Created: Aug 7, 2018 5 | # Updated: Apr 20, 2020 6 | # 7 | # Author: See AUTHORS 8 | # 9 | # Unit testing for SWMM Output API using pytest. 10 | # 11 | 12 | 13 | import os 14 | 15 | import pytest 16 | import numpy as np 17 | 18 | from swmm.toolkit import output, shared_enum, output_metadata 19 | 20 | 21 | DATA_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data') 22 | OUTPUT_FILE_EXAMPLE1 = os.path.join(DATA_PATH, 'test_Example1.out') 23 | 24 | 25 | def test_openclose(): 26 | _handle = output.init() 27 | output.open(_handle, OUTPUT_FILE_EXAMPLE1) 28 | output.close(_handle) 29 | 30 | 31 | def test_opencloseopenclose(): 32 | _handle = output.init() 33 | output.open(_handle, OUTPUT_FILE_EXAMPLE1) 34 | output.close(_handle) 35 | _handle2 = output.init() 36 | output.open(_handle2, OUTPUT_FILE_EXAMPLE1) 37 | output.close(_handle2) 38 | 39 | 40 | @pytest.fixture() 41 | def handle(request): 42 | _handle = output.init() 43 | output.open(_handle, OUTPUT_FILE_EXAMPLE1) 44 | 45 | def close(): 46 | output.close(_handle) 47 | 48 | request.addfinalizer(close) 49 | return _handle 50 | 51 | 52 | def test_getversion(handle): 53 | 54 | assert output.get_version(handle) == 51000 55 | 56 | 57 | def test_getprojectsize(handle): 58 | 59 | assert output.get_proj_size(handle) == [8, 14, 13, 1, 2] 60 | 61 | 62 | # def test_getflowunits(handle): 63 | # 64 | # assert output.getunits(handle)[0] == output.FlowUnits.CFS.value 65 | # 66 | # 67 | # def test_getpollutantunits(handle): 68 | # 69 | # assert output.getunits(handle)[2:] == [output.ConcUnits.MG.value, output.ConcUnits.UG.value] 70 | 71 | 72 | def test_getstartdate(handle): 73 | 74 | assert output.get_start_date(handle) == 35796 75 | 76 | 77 | def test_gettimes(handle): 78 | 79 | assert output.get_times(handle, shared_enum.Time.REPORT_STEP) == 3600 80 | assert output.get_times(handle, shared_enum.Time.NUM_PERIODS) == 36 81 | 82 | 83 | def test_getelementname(handle): 84 | 85 | assert output.get_elem_name(handle, shared_enum.ElementType.NODE, 1) == "10" 86 | 87 | 88 | def test_getsubcatchseries(handle): 89 | 90 | ref_array = np.array([0.0, 91 | 1.2438242, 92 | 2.5639679, 93 | 4.524055, 94 | 2.5115132, 95 | 0.69808137, 96 | 0.040894926, 97 | 0.011605669, 98 | 0.00509294, 99 | 0.0027438672]) 100 | 101 | test_array = output.get_subcatch_series(handle, 1, shared_enum.SubcatchAttribute.RUNOFF_RATE, 0, 10) 102 | 103 | assert len(test_array) == 10 104 | assert np.allclose(test_array, ref_array) 105 | 106 | 107 | def test_getsubcatchattribute(handle): 108 | 109 | ref_array = np.array([0.125, 110 | 0.125, 111 | 0.125, 112 | 0.125, 113 | 0.125, 114 | 0.225, 115 | 0.225, 116 | 0.225]) 117 | 118 | test_array = output.get_subcatch_attribute(handle, 1, shared_enum.SubcatchAttribute.INFIL_LOSS) 119 | 120 | assert len(test_array) == 8 121 | assert np.allclose(test_array, ref_array) 122 | 123 | 124 | def test_getsubcatchresult(handle): 125 | 126 | ref_array = np.array([0.5, 127 | 0.0, 128 | 0.0, 129 | 0.125, 130 | 1.2438242, 131 | 0.0, 132 | 0.0, 133 | 0.0, 134 | 33.481991, 135 | 6.6963983]) 136 | 137 | test_array = output.get_subcatch_result(handle, 1, 1) 138 | 139 | assert len(test_array) == 10 140 | assert np.allclose(test_array, ref_array) 141 | 142 | 143 | def test_getnoderesult(handle): 144 | 145 | ref_array = np.array([0.296234, 146 | 995.296204, 147 | 0.0, 148 | 1.302650, 149 | 1.302650, 150 | 0.0, 151 | 15.361463, 152 | 3.072293]) 153 | 154 | test_array = output.get_node_result(handle, 2, 2) 155 | 156 | assert len(test_array) == 8 157 | assert np.allclose(test_array, ref_array) 158 | 159 | 160 | def test_getlinkresult(handle): 161 | 162 | ref_array = np.array([4.631762, 163 | 1.0, 164 | 5.8973422, 165 | 314.15927, 166 | 1.0, 167 | 19.070757, 168 | 3.8141515]) 169 | 170 | test_array = output.get_link_result(handle, 3, 3) 171 | 172 | assert len(test_array) == 7 173 | assert np.allclose(test_array, ref_array) 174 | 175 | 176 | def test_getsystemresult(handle): 177 | 178 | ref_array = np.array([70.0, 179 | 0.1, 180 | 0.0, 181 | 0.19042271, 182 | 14.172027, 183 | 0.0, 184 | 0.0, 185 | 0.0, 186 | 0.0, 187 | 14.172027, 188 | 0.55517411, 189 | 13.622702, 190 | 2913.0793, 191 | 0.0]) 192 | 193 | test_array = output.get_system_result(handle, 4, 4) 194 | 195 | assert len(test_array) == 14 196 | assert np.allclose(test_array, ref_array) 197 | 198 | def test_getsystemattribute(handle): 199 | 200 | ref_array = np.array([70.0]) 201 | 202 | test_array = output.get_system_attribute(handle, 0, shared_enum.SystemAttribute.AIR_TEMP) 203 | 204 | assert len(test_array) == 1 205 | assert np.allclose(test_array, ref_array) 206 | -------------------------------------------------------------------------------- /swmm-toolkit/tests/test_stats.py: -------------------------------------------------------------------------------- 1 | # 2 | # test_stats.py 3 | # 4 | # Created: Nov 16, 2020 5 | # Updated: 6 | # 7 | # Author: See AUTHORS 8 | # 9 | 10 | import os 11 | 12 | import pytest 13 | 14 | from swmm.toolkit import solver, shared_enum 15 | 16 | 17 | DATA_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data') 18 | INPUT_FILE_EXAMPLE_1 = os.path.join(DATA_PATH, 'test_Example1.inp') 19 | REPORT_FILE_TEST_1 = os.path.join(DATA_PATH, 'temp_Example.rpt') 20 | OUTPUT_FILE_TEST_1 = os.path.join(DATA_PATH, 'temp_Example.out') 21 | 22 | 23 | @pytest.fixture() 24 | def before_end(request): 25 | solver.swmm_open(INPUT_FILE_EXAMPLE_1, REPORT_FILE_TEST_1, OUTPUT_FILE_TEST_1) 26 | solver.swmm_start(0) 27 | 28 | while True: 29 | time = solver.swmm_step() 30 | if time == 0: 31 | break 32 | 33 | def close(): 34 | solver.swmm_end() 35 | solver.swmm_close() 36 | 37 | request.addfinalizer(close) 38 | 39 | 40 | def test_node_get_stats(before_end): 41 | while True: 42 | time = solver.swmm_step() 43 | if time == 0: 44 | break 45 | 46 | node_stats = solver.node_get_stats(5) 47 | assert node_stats.maxDepth == pytest.approx(1.15, 0.1) 48 | 49 | 50 | def test_storage_get_stats(before_end): 51 | node_index = solver.project_get_index(shared_enum.ObjectType.NODE, 'SU1') 52 | while True: 53 | time = solver.swmm_step() 54 | if time == 0: 55 | break 56 | 57 | stor_stats = solver.storage_get_stats(node_index) 58 | assert stor_stats.avgVol == pytest.approx(0, 0.1) 59 | 60 | 61 | def test_outfall_stats(before_end): 62 | id = '18' 63 | 64 | index = solver.project_get_index(shared_enum.ObjectType.NODE, id) 65 | 66 | stats = solver.outfall_get_stats(index) 67 | assert stats.totalLoad != None 68 | 69 | 70 | def test_get_routing_totals(before_end): 71 | 72 | stats = solver.system_get_routing_totals() 73 | assert stats != None 74 | 75 | 76 | def test_get_runoff_totals(before_end): 77 | 78 | stats = solver.system_get_runoff_totals() 79 | assert stats != None 80 | -------------------------------------------------------------------------------- /swmm-toolkit/tools/build-wheels.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # build-wheels.sh - in a manyLinux docker image using dockcross 5 | # 6 | # Date created: Feb 2, 2021 7 | # Date modified: Jun 7, 2021 8 | # 9 | # Author: See AUTHORS 10 | # 11 | 12 | set -e -x 13 | 14 | 15 | # Install a system package required by our library 16 | # sudo yum install -y swig 17 | 18 | 19 | # Setup and build in swmm-toolkit dir 20 | mkdir -p ./dist 21 | cd swmm-toolkit 22 | 23 | # Build wheels 24 | for PYBIN in /opt/python/cp{37,38,39,310,311}*/bin; do 25 | # Setup python virtual environment for build 26 | ${PYBIN}/python -m venv --clear ./build-env 27 | source ./build-env/bin/activate 28 | 29 | # Install build requirements 30 | python -m pip install -r build-requirements.txt 31 | 32 | # Build wheel 33 | python setup.py bdist_wheel 34 | mv ./dist/*.whl ../dist/ 35 | 36 | # cleanup 37 | python setup.py clean 38 | deactivate 39 | done 40 | 41 | # Cleanup 42 | rm -rf ./build-env 43 | 44 | 45 | # Repairing and testing from swmm-python directory 46 | cd .. 47 | 48 | # Bundle external shared libraries into the wheels 49 | for WHL in ./dist/*-linux_x86_64.whl; do 50 | auditwheel repair -L '' -w ./dist $WHL 51 | done 52 | 53 | 54 | # Install packages and test 55 | for PYBIN in /opt/python/cp{37,38,39,310}*/bin; do 56 | # Setup python virtual environment for test 57 | ${PYBIN}/python -m venv --clear ./test-env 58 | source ./test-env/bin/activate 59 | 60 | python -m pip install -r swmm-toolkit/test-requirements.txt 61 | 62 | python -m pip install --verbose --no-index --find-links=./dist swmm_toolkit 63 | pytest 64 | 65 | deactivate 66 | done 67 | 68 | # Cleanup 69 | rm -rf ./test-env 70 | --------------------------------------------------------------------------------