openswmm 6.0.0a1__tar.gz → 6.0.0.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/CMakeLists.txt +34 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/PKG-INFO +2 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/concepts.rst +15 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/links.rst +79 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/nodes.rst +51 -2
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/solver.rst +63 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/statistics.rst +66 -6
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/subcatchments.rst +47 -14
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_2d.pxd +8 -7
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_2d.pyi +31 -5
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_2d.pyx +69 -10
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_common.pxd +119 -36
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_enums.py +5 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_gages.pyi +2 -1
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_gages.pyx +7 -2
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_geopackage.pyi +6 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_geopackage.pyx +101 -51
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_hotstart.pyi +9 -4
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_hotstart.pyx +32 -8
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_links.pyi +219 -4
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_links.pyx +457 -8
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_nodes.pyi +95 -6
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_nodes.pyx +196 -13
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_output_reader.pyi +61 -4
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_output_reader.pyx +128 -12
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_solver.pyi +69 -1
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_solver.pyx +126 -2
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_statistics.pyi +111 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_statistics.pyx +206 -6
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_subcatchments.pyi +66 -1
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_subcatchments.pyx +136 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/pyproject.toml +71 -10
- openswmm-6.0.0.dev2/scripts/cibw_repair_windows.py +98 -0
- openswmm-6.0.0.dev2/tests/data/__pycache__/__init__.cpython-312.pyc +0 -0
- openswmm-6.0.0.dev2/tests/data/output/__pycache__/__init__.cpython-312.pyc +0 -0
- openswmm-6.0.0.dev2/tests/data/solver/__pycache__/__init__.cpython-312.pyc +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/non_existent_input_file.rpt +3 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example.rpt +3 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_link.rpt +3 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_node.rpt +3 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_outfall.rpt +4 -4
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_routing.rpt +3 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_runoff.rpt +3 -3
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_subcatch.rpt +4 -4
- openswmm-6.0.0.dev2/tests/engine/test_concurrent_simulation.py +294 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_geopackage.py +65 -4
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_integration.py +5 -3
- openswmm-6.0.0.dev2/tests/engine/test_new_api.py +724 -0
- openswmm-6.0.0.dev2/tests/engine/test_new_api.py.tmp +724 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_output_reader.py +90 -0
- openswmm-6.0.0.dev2/tests/engine/test_runoff_interface.py +170 -0
- openswmm-6.0.0.dev2/tests/engine/verify_geopackage_c_api.cpp +495 -0
- openswmm-6.0.0.dev2/tests/engine/verify_geopackage_c_api.sh +90 -0
- openswmm-6.0.0.dev2/tests/test_api_coverage.py +304 -0
- openswmm-6.0.0a1/scripts/repair_wheel_windows.py +0 -76
- openswmm-6.0.0a1/tests/engine/test_new_api.py +0 -295
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/.claude/settings.local.json +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/CMakePresets.json +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/LICENSE +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/README.md +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/cmake/CythonHelpers.cmake +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/cmake/PatchNumpyPxd.cmake +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/create_schema_review_db.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/LEGACY_API_EXPANSION_PLAN.md +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/Makefile +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.buildinfo +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/__intersphinx_cache__/numpy_objects.inv +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/__intersphinx_cache__/python_objects.inv +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/api.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/environment.pickle +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/concepts.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/controls.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/editing.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/error_handling.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/forcing.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/gages.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/hotstart.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/index.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/inflows.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/infrastructure.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/install.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/links.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/massbalance.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/model_builder.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/nodes.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/output_reader.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/pollutants.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/quality.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/quickstart.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/solver.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/spatial.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/statistics.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/subcatchments.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/guide/tables.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/index.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/legacy/index.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/legacy/output.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/legacy/solver.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/license.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/.doctrees/migration/swmm5_to_swmm6.doctree +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_images/hydrocouple_logo.png +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/index.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/openswmm/legacy/engine/_forcing_log.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/openswmm/legacy/engine/_links.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/openswmm/legacy/engine/_nodes.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/openswmm/legacy/engine/_raingages.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/openswmm/legacy/engine/_subcatchments.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_modules/openswmm/legacy/engine/_system.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/api.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/concepts.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/controls.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/editing.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/error_handling.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/forcing.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/gages.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/hotstart.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/index.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/inflows.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/infrastructure.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/install.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/links.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/massbalance.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/model_builder.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/nodes.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/output_reader.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/pollutants.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/quality.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/quickstart.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/solver.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/spatial.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/statistics.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/subcatchments.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/guide/tables.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/index.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/legacy/index.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/legacy/output.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/legacy/solver.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/license.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sources/migration/swmm5_to_swmm6.rst.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_sphinx_design_static/design-tabs.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/base-stemmer.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/basic.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/design-tabs.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/doctools.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/documentation_options.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/english-stemmer.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/file.png +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/hydrocouple_logo.png +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/language_data.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/minus.png +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/openswmm.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/plus.png +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/pygments.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/scripts/bootstrap.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/scripts/bootstrap.js.map +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/scripts/pydata-sphinx-theme.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/scripts/pydata-sphinx-theme.js.map +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/searchtools.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/sphinx_highlight.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/styles/bootstrap.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/styles/bootstrap.css.map +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/styles/pydata-sphinx-theme.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/styles/pydata-sphinx-theme.css.map +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/styles/theme.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/LICENSE.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/css/all.min.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/js/all.min.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/js/all.min.js.LICENSE.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-brands-400.ttf +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-brands-400.woff2 +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-regular-400.ttf +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-regular-400.woff2 +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-solid-900.ttf +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-solid-900.woff2 +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-v4compatibility.ttf +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/vendor/fontawesome/6.5.1/webfonts/fa-v4compatibility.woff2 +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/_static/webpack-macros.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/api.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/genindex.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/concepts.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/controls.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/editing.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/error_handling.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/forcing.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/gages.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/hotstart.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/index.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/inflows.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/infrastructure.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/install.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/links.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/massbalance.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/model_builder.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/nodes.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/output_reader.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/pollutants.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/quality.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/quickstart.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/solver.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/spatial.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/statistics.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/subcatchments.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/guide/tables.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/index.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/legacy/index.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/legacy/output.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/legacy/solver.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/license.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/migration/swmm5_to_swmm6.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/objects.inv +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/py-modindex.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/search.html +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_build/html/searchindex.js +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/_static/openswmm.css +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/api.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/conf.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/environment.yml +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/controls.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/editing.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/error_handling.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/forcing.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/gages.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/hotstart.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/index.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/inflows.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/infrastructure.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/install.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/massbalance.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/model_builder.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/output_reader.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/pollutants.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/quality.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/quickstart.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/spatial.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/guide/tables.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/images/hydrocouple_logo.png +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/index.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/legacy/index.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/legacy/output.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/legacy/solver.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/license.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/make.bat +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/migration/swmm5_to_swmm6.rst +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/docs/requirements.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/generate_geopackage_erd.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/data/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/__init__.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/__init__.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_controls.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_controls.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_dates.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_dates.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_edit.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_edit.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_enums.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_forcing.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_forcing.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_geometry.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_inflows.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_inflows.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_infrastructure.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_infrastructure.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_massbalance.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_massbalance.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_model.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_model.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_pollutants.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_pollutants.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_quality.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_quality.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_report.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_solver.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_spatial.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_spatial.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_tables.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/engine/_tables.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/__init__.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_forcing_log.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_links.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_nodes.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_raingages.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_solver.c +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_solver.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_solver.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_subcatchments.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/_system.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/engine/solver.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/output/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/output/__init__.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/output/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/output/_output.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/output/_output.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/legacy/output/output.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/output/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/output/__init__.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/output/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/output/_output.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/output/_output.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/output/output.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/solver/CMakeLists.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/solver/__init__.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/solver/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/solver/_solver.pyi +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/solver/_solver.pyx +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/openswmm/solver/solver.pxd +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/requirements.txt +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/scripts/clean.sh +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/smoke_test.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/conftest.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/__pycache__/__init__.cpython-313.pyc +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/output/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/output/__pycache__/__init__.cpython-313.pyc +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/output/example_output_1.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/output/json_time_series.pickle +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/__pycache__/__init__.cpython-313.pyc +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example.inp +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_link.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_node.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_outfall.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_routing.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_runoff.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/data/solver/site_drainage_example_subcatch.out +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/conftest.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_callbacks_and_xsect.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_controls_advancement.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_controls_inflows.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_edit.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_enums.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_gages.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_gages_expanded.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_hotstart.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_infrastructure.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_links.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_links_expanded.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_massbalance.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_massbalance_expanded.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_model_builder.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_new_modules.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_nodes.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_nodes_expanded.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_opened_state_editing.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_quality_pollutants.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_rdii_advancement.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_solver.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_spatial.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_subcatchments.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_subcatchments_expanded.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_tables.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/engine/test_workflow.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/legacy/__init__.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/legacy/test_output.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/legacy/test_phase1_enum_coverage.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/legacy/test_phase2_statistics.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/legacy/test_phase3_oop_wrappers.py +0 -0
- {openswmm-6.0.0a1 → openswmm-6.0.0.dev2}/tests/legacy/test_solver.py +0 -0
|
@@ -11,6 +11,40 @@
|
|
|
11
11
|
|
|
12
12
|
cmake_minimum_required(VERSION 3.24)
|
|
13
13
|
|
|
14
|
+
# ============================================================================
|
|
15
|
+
# Source-distribution guard: the sdist on PyPI is metadata-only and does NOT
|
|
16
|
+
# carry the OpenSWMM C/C++ engine source tree. Detect that we have neither a
|
|
17
|
+
# pre-built engine prefix nor the parent project's CMakeLists.txt reachable
|
|
18
|
+
# via add_subdirectory(..) and fail with a clear, actionable error rather
|
|
19
|
+
# than letting vcpkg or the C compiler emit a confusing one. Without this
|
|
20
|
+
# guard, a stray VCPKG_ROOT in the user's environment causes the auto-load
|
|
21
|
+
# block below to fire and vcpkg then tries to read a vcpkg.json next to the
|
|
22
|
+
# unpacked sdist that does not exist.
|
|
23
|
+
# ============================================================================
|
|
24
|
+
if(NOT DEFINED OPENSWMM_ENGINE_INSTALL_PREFIX
|
|
25
|
+
AND NOT DEFINED ENV{OPENSWMM_ENGINE_INSTALL_PREFIX}
|
|
26
|
+
AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt")
|
|
27
|
+
message(FATAL_ERROR
|
|
28
|
+
"openswmm cannot be built from this source distribution: the sdist "
|
|
29
|
+
"does not bundle the OpenSWMM C/C++ engine sources, and no pre-built "
|
|
30
|
+
"engine was supplied via -DOPENSWMM_ENGINE_INSTALL_PREFIX=<path>.\n"
|
|
31
|
+
"\n"
|
|
32
|
+
"Install a pre-built wheel instead:\n"
|
|
33
|
+
" python -m pip install openswmm\n"
|
|
34
|
+
"\n"
|
|
35
|
+
"Wheels are published for Python 3.9-3.13 on Linux x86_64, macOS "
|
|
36
|
+
"(arm64 and x86_64), and Windows x64. If pip fell back to this "
|
|
37
|
+
"sdist, no wheel matched your platform/interpreter -- check the "
|
|
38
|
+
"available files at https://pypi.org/project/openswmm/#files and, "
|
|
39
|
+
"if needed, switch to a supported Python version.\n"
|
|
40
|
+
"\n"
|
|
41
|
+
"Source builds are supported only from a full git checkout of the "
|
|
42
|
+
"openswmm.engine repository:\n"
|
|
43
|
+
" git clone https://github.com/hydrocouple/openswmm.engine\n"
|
|
44
|
+
" cd openswmm.engine/python\n"
|
|
45
|
+
" pip install . --no-build-isolation")
|
|
46
|
+
endif()
|
|
47
|
+
|
|
14
48
|
# ============================================================================
|
|
15
49
|
# vcpkg manifest directory: the vcpkg.json lives one directory above python/.
|
|
16
50
|
# Set VCPKG_MANIFEST_DIR before project() so vcpkg's toolchain file sees it.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openswmm
|
|
3
|
-
Version: 6.0.
|
|
3
|
+
Version: 6.0.0.dev2
|
|
4
4
|
Summary: Python bindings for the OpenSWMM stormwater modelling engine.
|
|
5
5
|
Keywords: SWMM,stormwater,hydrology,hydraulics,water resources,environmental engineering
|
|
6
6
|
Author-Email: Caleb Buahin <caleb.buahin@gmail.com>
|
|
@@ -23,7 +23,6 @@ Classifier: Operating System :: Unix
|
|
|
23
23
|
Classifier: Operating System :: POSIX :: Linux
|
|
24
24
|
Classifier: Operating System :: MacOS
|
|
25
25
|
Classifier: Programming Language :: Python :: 3
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
27
26
|
Classifier: Programming Language :: Python :: 3.10
|
|
28
27
|
Classifier: Programming Language :: Python :: 3.11
|
|
29
28
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -37,7 +36,7 @@ Project-URL: Homepage, https://github.com/hydrocouple/openswmm.engine/python
|
|
|
37
36
|
Project-URL: Repository, https://github.com/hydrocouple/openswmm.engine
|
|
38
37
|
Project-URL: Bug Tracker, https://github.com/hydrocouple/openswmm.engine/issues
|
|
39
38
|
Project-URL: Changelog, https://github.com/hydrocouple/openswmm.engine/blob/main/CHANGELOG.md
|
|
40
|
-
Requires-Python: >=3.
|
|
39
|
+
Requires-Python: >=3.10
|
|
41
40
|
Requires-Dist: numpy>=1.21.0
|
|
42
41
|
Provides-Extra: dev
|
|
43
42
|
Requires-Dist: pytest>=8.3; extra == "dev"
|
|
@@ -256,6 +256,21 @@ Threading & multiprocessing
|
|
|
256
256
|
* **Multiple threads, one Solver per thread**: supported. The C
|
|
257
257
|
engine is reentrant; two threads each holding their own Solver do
|
|
258
258
|
not interact.
|
|
259
|
+
|
|
260
|
+
As of OpenSWMM 6.0, the following Cython entry points release the
|
|
261
|
+
GIL while inside the C engine, so two such threads execute their
|
|
262
|
+
C work truly in parallel rather than serialising on the interpreter:
|
|
263
|
+
|
|
264
|
+
* :meth:`Solver.step`, :meth:`Solver.stride`
|
|
265
|
+
* Every ``*_bulk`` getter / setter on :class:`Nodes`,
|
|
266
|
+
:class:`Links`, and :class:`Subcatchments`
|
|
267
|
+
(:meth:`get_depths_bulk`, :meth:`get_flows_bulk`,
|
|
268
|
+
:meth:`get_quality_bulk`, etc.)
|
|
269
|
+
|
|
270
|
+
Registered step-begin / step-end callbacks remain safe: their
|
|
271
|
+
Cython trampolines reacquire the GIL via ``noexcept with gil:``
|
|
272
|
+
before invoking the user's Python callable.
|
|
273
|
+
|
|
259
274
|
* **Multiple threads, one shared Solver**: **not** supported. The
|
|
260
275
|
Solver and its domain classes assume a single-threaded caller. If
|
|
261
276
|
you need shared state, drive a single Solver from one thread and
|
|
@@ -138,6 +138,41 @@ Pump-specific
|
|
|
138
138
|
* - :meth:`get_pump_init_state` / :meth:`set_pump_init_state`
|
|
139
139
|
- Initial on/off state.
|
|
140
140
|
|
|
141
|
+
Pump utilization statistics
|
|
142
|
+
---------------------------
|
|
143
|
+
|
|
144
|
+
Accumulated during a running simulation. Read either per-link with the
|
|
145
|
+
scalar accessors, or — for whole-network summaries — in one shot with
|
|
146
|
+
:meth:`get_pump_stats_bulk`, which performs a single C ABI crossing
|
|
147
|
+
instead of ``3 * n_links`` and releases the GIL during the call.
|
|
148
|
+
|
|
149
|
+
.. list-table::
|
|
150
|
+
:header-rows: 1
|
|
151
|
+
:widths: 45 55
|
|
152
|
+
|
|
153
|
+
* - Method
|
|
154
|
+
- Returns
|
|
155
|
+
* - :meth:`get_stat_pump_cycles(idx)`
|
|
156
|
+
- Pump on/off cycle count (``int``).
|
|
157
|
+
* - :meth:`get_stat_pump_on_time(idx)`
|
|
158
|
+
- Total pump on-time in seconds (``float``).
|
|
159
|
+
* - :meth:`get_stat_pump_volume(idx)`
|
|
160
|
+
- Total volume pumped in ft³ (``float``).
|
|
161
|
+
* - :meth:`get_pump_stats_bulk()`
|
|
162
|
+
- ``dict`` of three ``np.ndarray`` columns — ``cycles``
|
|
163
|
+
(``int32``), ``on_time`` (``float64``), ``volume`` (``float64``);
|
|
164
|
+
non-pump links carry ``cycles == -1``.
|
|
165
|
+
|
|
166
|
+
.. code-block:: python
|
|
167
|
+
|
|
168
|
+
# Whole-network pump summary in one call.
|
|
169
|
+
stats = links.get_pump_stats_bulk()
|
|
170
|
+
pumps = stats["cycles"] >= 0 # filter to pump links
|
|
171
|
+
total_pumped_ft3 = stats["volume"][pumps].sum()
|
|
172
|
+
total_run_time_h = stats["on_time"][pumps].sum() / 3600.0
|
|
173
|
+
print(f"{pumps.sum()} pumps, {total_pumped_ft3:.1f} ft³ pumped, "
|
|
174
|
+
f"{total_run_time_h:.1f} pump-hours")
|
|
175
|
+
|
|
141
176
|
Weir / orifice
|
|
142
177
|
--------------
|
|
143
178
|
|
|
@@ -301,10 +336,51 @@ Bulk arrays
|
|
|
301
336
|
- All link mid-point depths.
|
|
302
337
|
* - :meth:`get_quality_bulk(p)`
|
|
303
338
|
- Pollutant ``p`` concentration per link.
|
|
339
|
+
* - :meth:`get_pump_stats_bulk`
|
|
340
|
+
- All pump statistics in a single C call —
|
|
341
|
+
``{"cycles": ndarray[int32], "on_time": ndarray[float64],
|
|
342
|
+
"volume": ndarray[float64]}``. Non-pump links carry
|
|
343
|
+
``cycles == -1`` as a sentinel.
|
|
344
|
+
* - :meth:`get_velocities_bulk`
|
|
345
|
+
- Cross-sectional velocity per link *(added 6.0.0)*.
|
|
346
|
+
* - :meth:`get_capacities_bulk`
|
|
347
|
+
- Capacity ratio ``q / q_full`` per link *(added 6.0.0)*.
|
|
348
|
+
* - :meth:`get_volumes_bulk`
|
|
349
|
+
- Stored volume per link *(added 6.0.0)*.
|
|
350
|
+
* - :meth:`get_control_settings_bulk`
|
|
351
|
+
- Active control setting (0..1) per link *(added 6.0.0)*.
|
|
352
|
+
* - :meth:`get_target_settings_bulk`
|
|
353
|
+
- Target control setting per link *(added 6.0.0)*.
|
|
354
|
+
* - :meth:`get_hyd_powers_bulk`
|
|
355
|
+
- Hydraulic power per link in ft-lb/s
|
|
356
|
+
(``gamma * |Q| * |hL|``) *(added 6.0.0)*.
|
|
357
|
+
* - :meth:`get_ids_bulk`
|
|
358
|
+
- ``list[str]`` of every link's id in one C call
|
|
359
|
+
*(added 6.0.0; stride-packed UTF-8)*.
|
|
360
|
+
|
|
361
|
+
Memory-aliasing note: ``get_flows_bulk`` and ``get_depths_bulk`` return
|
|
362
|
+
arrays that share memory with engine scratch space — ``.copy()`` if you
|
|
363
|
+
keep them past the next call. The other bulk getters (``get_pump_stats_bulk``
|
|
364
|
+
and every Phase 3 addition) return freshly allocated arrays, so the
|
|
365
|
+
result is yours to retain.
|
|
366
|
+
|
|
367
|
+
Whole-network reporting pattern (mirrors the Nodes example):
|
|
368
|
+
|
|
369
|
+
.. code-block:: python
|
|
304
370
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
371
|
+
ids = links.get_ids_bulk() # list[str]
|
|
372
|
+
flows = links.get_flows_bulk() # np.ndarray[float64]
|
|
373
|
+
velocities = links.get_velocities_bulk()
|
|
374
|
+
capacities = links.get_capacities_bulk()
|
|
375
|
+
powers = links.get_hyd_powers_bulk()
|
|
376
|
+
stats = links.get_pump_stats_bulk()
|
|
377
|
+
pumps = stats["cycles"] >= 0 # boolean mask
|
|
378
|
+
|
|
379
|
+
# Pump-energy summary in 3 lines:
|
|
380
|
+
pump_run_hours = float(stats["on_time"][pumps].sum() / 3600.0)
|
|
381
|
+
pump_ft_lb_s = float(powers[pumps].sum())
|
|
382
|
+
pump_hp = pump_ft_lb_s / 550.0
|
|
383
|
+
print(f"{pumps.sum()} pumps ran {pump_run_hours:.1f} h ~{pump_hp:.1f} hp avg")
|
|
308
384
|
|
|
309
385
|
Vectorised peak detection across all links:
|
|
310
386
|
|
|
@@ -316,7 +316,7 @@ want vectorised. Each returns or accepts a contiguous
|
|
|
316
316
|
|
|
317
317
|
.. list-table::
|
|
318
318
|
:header-rows: 1
|
|
319
|
-
:widths:
|
|
319
|
+
:widths: 40 60
|
|
320
320
|
|
|
321
321
|
* - Method
|
|
322
322
|
- Returns / accepts
|
|
@@ -327,13 +327,33 @@ want vectorised. Each returns or accepts a contiguous
|
|
|
327
327
|
* - :meth:`set_depths_bulk(arr)`
|
|
328
328
|
- Force depths for every node from ``arr``.
|
|
329
329
|
* - :meth:`get_inflows_bulk`
|
|
330
|
-
-
|
|
330
|
+
- **Lateral** inflow per node (see naming note below).
|
|
331
331
|
* - :meth:`get_overflows_bulk`
|
|
332
332
|
- Overflow (flooding) per node.
|
|
333
333
|
* - :meth:`set_lat_inflows_bulk(arr)`
|
|
334
334
|
- Lateral inflow per node.
|
|
335
335
|
* - :meth:`get_quality_bulk(p)`
|
|
336
336
|
- Concentration of pollutant ``p`` per node.
|
|
337
|
+
* - :meth:`get_volumes_bulk`
|
|
338
|
+
- Stored volume per node *(added 6.0.0)*.
|
|
339
|
+
* - :meth:`get_outflows_bulk`
|
|
340
|
+
- Total outflow per node *(added 6.0.0)*.
|
|
341
|
+
* - :meth:`get_losses_bulk`
|
|
342
|
+
- Per-node losses (evaporation + seepage) *(added 6.0.0)*.
|
|
343
|
+
* - :meth:`get_lateral_inflows_bulk`
|
|
344
|
+
- Lateral inflow per node — explicitly named successor to
|
|
345
|
+
:meth:`get_inflows_bulk` *(added 6.0.0)*.
|
|
346
|
+
* - :meth:`get_ids_bulk`
|
|
347
|
+
- ``list[str]`` of every node's id in one C call
|
|
348
|
+
*(added 6.0.0; stride-packed UTF-8)*.
|
|
349
|
+
|
|
350
|
+
.. note::
|
|
351
|
+
|
|
352
|
+
Naming caveat: :meth:`get_inflows_bulk` reads the *lateral* inflow
|
|
353
|
+
column on the C side despite its generic name; it is retained for
|
|
354
|
+
backward compatibility, but new code should prefer
|
|
355
|
+
:meth:`get_lateral_inflows_bulk`. Both methods return the same
|
|
356
|
+
values.
|
|
337
357
|
|
|
338
358
|
Memory-aliasing rule: the array returned by a ``get_*_bulk`` method
|
|
339
359
|
shares memory with an internal scratch buffer that the engine reuses
|
|
@@ -351,6 +371,35 @@ keep the array (e.g. across a step), call ``.copy()``:
|
|
|
351
371
|
history.append(nodes.get_depths_bulk().copy()) # detach from scratch
|
|
352
372
|
H = np.stack(history) # shape (T, n_nodes)
|
|
353
373
|
|
|
374
|
+
Whole-network reporting with the Phase 3 bulk accessors:
|
|
375
|
+
|
|
376
|
+
.. code-block:: python
|
|
377
|
+
|
|
378
|
+
# Single C call per quantity — replaces N round-trips through
|
|
379
|
+
# the scalar getters. Useful when building post-run summaries,
|
|
380
|
+
# MCP / GUI dataframes, or input to a downstream tool.
|
|
381
|
+
ids = nodes.get_ids_bulk() # list[str]
|
|
382
|
+
depths = nodes.get_depths_bulk() # np.ndarray[float64]
|
|
383
|
+
volumes = nodes.get_volumes_bulk()
|
|
384
|
+
outflows = nodes.get_outflows_bulk()
|
|
385
|
+
losses = nodes.get_losses_bulk()
|
|
386
|
+
lat = nodes.get_lateral_inflows_bulk()
|
|
387
|
+
|
|
388
|
+
# Build a single DataFrame-shaped dict in one shot:
|
|
389
|
+
summary = {
|
|
390
|
+
"id": ids,
|
|
391
|
+
"depth": depths,
|
|
392
|
+
"volume": volumes,
|
|
393
|
+
"outflow": outflows,
|
|
394
|
+
"losses": losses,
|
|
395
|
+
"lateral_inflow": lat,
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
# Find the most-flooded outfall, e.g.:
|
|
399
|
+
flooded = nodes.get_overflows_bulk()
|
|
400
|
+
worst = int(flooded.argmax())
|
|
401
|
+
print(f"max overflow at {ids[worst]}: {flooded[worst]:.3f}")
|
|
402
|
+
|
|
354
403
|
----
|
|
355
404
|
|
|
356
405
|
EngineState requirements & exceptions
|
|
@@ -409,6 +409,69 @@ For the full list see :class:`~openswmm.engine.ErrorCode`.
|
|
|
409
409
|
|
|
410
410
|
----
|
|
411
411
|
|
|
412
|
+
Runoff interface file (Phase 1b)
|
|
413
|
+
================================
|
|
414
|
+
|
|
415
|
+
Persists per-subcatchment runoff snapshots to a binary file matching
|
|
416
|
+
the legacy SWMM-5 ``Frunoff`` format. Useful when a slow-running
|
|
417
|
+
runoff phase needs to be cached and replayed against a downstream
|
|
418
|
+
routing-only run (e.g. design-storm sensitivity analyses).
|
|
419
|
+
|
|
420
|
+
.. list-table::
|
|
421
|
+
:header-rows: 1
|
|
422
|
+
:widths: 40 60
|
|
423
|
+
|
|
424
|
+
* - Method
|
|
425
|
+
- Description
|
|
426
|
+
* - :meth:`open_runoff_iface_write(path)`
|
|
427
|
+
- Open the file in SAVE mode. The engine then auto-emits one
|
|
428
|
+
record per runoff substep until :meth:`close_runoff_iface`
|
|
429
|
+
is called.
|
|
430
|
+
* - :meth:`open_runoff_iface_read(path)`
|
|
431
|
+
- Open the file in USE mode. Currently exposes the file but
|
|
432
|
+
does **not** yet skip the engine's runoff computation —
|
|
433
|
+
see the note below.
|
|
434
|
+
* - :meth:`save_runoff_step(dt)`
|
|
435
|
+
- Manually force one snapshot. Normally unnecessary because the
|
|
436
|
+
engine auto-saves; provided for plugin authors and tests.
|
|
437
|
+
* - :meth:`read_runoff_step()`
|
|
438
|
+
- Read one record from the open USE file into the current
|
|
439
|
+
subcatchment runoff/quality vectors. Returns ``False`` on EOF.
|
|
440
|
+
* - :meth:`close_runoff_iface()`
|
|
441
|
+
- Close the file (idempotent). Called automatically when the
|
|
442
|
+
solver is closed.
|
|
443
|
+
|
|
444
|
+
.. note::
|
|
445
|
+
|
|
446
|
+
USE-mode auto-skip — making the engine bypass its own runoff
|
|
447
|
+
computation when a USE file is open — is a follow-up to Phase 1b.
|
|
448
|
+
Today's USE mode is an advanced manual feature: callers must invoke
|
|
449
|
+
:meth:`read_runoff_step` between :meth:`Solver.step` calls *and*
|
|
450
|
+
understand that the engine will overwrite the loaded state when it
|
|
451
|
+
runs its own runoff phase.
|
|
452
|
+
|
|
453
|
+
End-to-end SAVE example:
|
|
454
|
+
|
|
455
|
+
.. code-block:: python
|
|
456
|
+
|
|
457
|
+
from openswmm.engine import EngineState, Solver
|
|
458
|
+
|
|
459
|
+
with Solver("design_storm.inp", "design_storm.rpt", "design_storm.out") as s:
|
|
460
|
+
s.open()
|
|
461
|
+
s.initialize()
|
|
462
|
+
s.start()
|
|
463
|
+
s.open_runoff_iface_write("design_storm.rfi")
|
|
464
|
+
while s.state == EngineState.RUNNING:
|
|
465
|
+
if s.step() != 0:
|
|
466
|
+
break
|
|
467
|
+
s.end()
|
|
468
|
+
s.close_runoff_iface()
|
|
469
|
+
# design_storm.rfi now contains one record per runoff substep and
|
|
470
|
+
# can be reopened by a downstream routing-only run via
|
|
471
|
+
# ``s.open_runoff_iface_read(...)``.
|
|
472
|
+
|
|
473
|
+
----
|
|
474
|
+
|
|
412
475
|
See also
|
|
413
476
|
========
|
|
414
477
|
|
|
@@ -99,6 +99,10 @@ Per-subcatchment
|
|
|
99
99
|
Bulk variants
|
|
100
100
|
-------------
|
|
101
101
|
|
|
102
|
+
Each bulk method makes a single C call and returns a contiguous
|
|
103
|
+
``np.ndarray[float64]``. The GIL is released for the duration of the
|
|
104
|
+
C call.
|
|
105
|
+
|
|
102
106
|
.. list-table::
|
|
103
107
|
:header-rows: 1
|
|
104
108
|
:widths: 50 50
|
|
@@ -111,9 +115,46 @@ Bulk variants
|
|
|
111
115
|
- All-link peak flows.
|
|
112
116
|
* - :meth:`subcatch_runoff_vol_bulk()`
|
|
113
117
|
- All-subcatchment runoff volumes.
|
|
118
|
+
* - :meth:`node_max_overflow_bulk()`
|
|
119
|
+
- All-node peak overflow rate *(added 6.0.0)*.
|
|
120
|
+
* - :meth:`node_vol_flooded_bulk()`
|
|
121
|
+
- All-node total flooded volume *(added 6.0.0)*.
|
|
122
|
+
* - :meth:`node_time_flooded_bulk()`
|
|
123
|
+
- All-node cumulative time-flooded *(added 6.0.0)*.
|
|
124
|
+
* - :meth:`subcatch_max_runoff_bulk()`
|
|
125
|
+
- All-subcatchment peak runoff *(added 6.0.0)*.
|
|
126
|
+
* - :meth:`link_max_velocity_bulk()`
|
|
127
|
+
- All-link peak velocity *(added 6.0.0)*.
|
|
128
|
+
* - :meth:`link_max_filling_bulk()`
|
|
129
|
+
- All-link peak depth/full-depth ratio *(added 6.0.0)*.
|
|
130
|
+
* - :meth:`link_vol_flow_bulk()`
|
|
131
|
+
- All-link cumulative flow volume *(added 6.0.0)*.
|
|
132
|
+
* - :meth:`link_surcharge_time_bulk()`
|
|
133
|
+
- All-link cumulative surcharge time *(added 6.0.0)*.
|
|
134
|
+
|
|
135
|
+
Whole-network flooding summary in 4 C calls (replaces a ``4 * n_nodes``
|
|
136
|
+
Python loop):
|
|
137
|
+
|
|
138
|
+
.. code-block:: python
|
|
139
|
+
|
|
140
|
+
from openswmm.engine import Nodes, Statistics
|
|
141
|
+
|
|
142
|
+
stats = Statistics(solver)
|
|
143
|
+
nodes = Nodes(solver)
|
|
144
|
+
|
|
145
|
+
ids = nodes.get_ids_bulk()
|
|
146
|
+
max_over = stats.node_max_overflow_bulk()
|
|
147
|
+
vol_flood = stats.node_vol_flooded_bulk()
|
|
148
|
+
t_flood = stats.node_time_flooded_bulk()
|
|
149
|
+
|
|
150
|
+
# Worst-flooded node by cumulative volume:
|
|
151
|
+
worst = int(vol_flood.argmax())
|
|
152
|
+
print(f"{ids[worst]}: vol={vol_flood[worst]:.1f}, "
|
|
153
|
+
f"peak overflow={max_over[worst]:.3f}, hours={t_flood[worst]:.2f}")
|
|
114
154
|
|
|
115
155
|
The standard memory-aliasing rule applies — ``.copy()`` if you need
|
|
116
|
-
to keep the array.
|
|
156
|
+
to keep the array (the four pre-6.0 bulk getters share scratch
|
|
157
|
+
buffers; the 6.0 additions return freshly allocated arrays).
|
|
117
158
|
|
|
118
159
|
----
|
|
119
160
|
|
|
@@ -214,7 +255,9 @@ Compute surcharge fraction across the network
|
|
|
214
255
|
Bulk arrays
|
|
215
256
|
===========
|
|
216
257
|
|
|
217
|
-
The ``*_bulk`` family is the vectorised path
|
|
258
|
+
The ``*_bulk`` family is the vectorised path. Each call returns a
|
|
259
|
+
contiguous ``np.ndarray[float64]`` of the indicated shape. GIL is
|
|
260
|
+
released during the underlying C call.
|
|
218
261
|
|
|
219
262
|
.. list-table::
|
|
220
263
|
:header-rows: 1
|
|
@@ -228,10 +271,27 @@ The ``*_bulk`` family is the vectorised path:
|
|
|
228
271
|
- ``(n_links,)``
|
|
229
272
|
* - :meth:`subcatch_runoff_vol_bulk`
|
|
230
273
|
- ``(n_subcatch,)``
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
274
|
+
* - :meth:`node_max_overflow_bulk`
|
|
275
|
+
- ``(n_nodes,)`` *(added 6.0.0)*
|
|
276
|
+
* - :meth:`node_vol_flooded_bulk`
|
|
277
|
+
- ``(n_nodes,)`` *(added 6.0.0)*
|
|
278
|
+
* - :meth:`node_time_flooded_bulk`
|
|
279
|
+
- ``(n_nodes,)`` *(added 6.0.0)*
|
|
280
|
+
* - :meth:`subcatch_max_runoff_bulk`
|
|
281
|
+
- ``(n_subcatch,)`` *(added 6.0.0)*
|
|
282
|
+
* - :meth:`link_max_velocity_bulk`
|
|
283
|
+
- ``(n_links,)`` *(added 6.0.0)*
|
|
284
|
+
* - :meth:`link_max_filling_bulk`
|
|
285
|
+
- ``(n_links,)`` *(added 6.0.0)*
|
|
286
|
+
* - :meth:`link_vol_flow_bulk`
|
|
287
|
+
- ``(n_links,)`` *(added 6.0.0)*
|
|
288
|
+
* - :meth:`link_surcharge_time_bulk`
|
|
289
|
+
- ``(n_links,)`` *(added 6.0.0)*
|
|
290
|
+
|
|
291
|
+
Memory-aliasing rule: the three pre-6.0 bulk methods share scratch
|
|
292
|
+
buffers with engine state — ``.copy()`` if you need to retain them
|
|
293
|
+
past the next call. The 6.0 additions return freshly allocated
|
|
294
|
+
arrays.
|
|
235
295
|
|
|
236
296
|
----
|
|
237
297
|
|
|
@@ -297,24 +297,57 @@ Per-subcatchment runoff coefficient (post-run summary)
|
|
|
297
297
|
Bulk arrays
|
|
298
298
|
===========
|
|
299
299
|
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
Each bulk method makes a single C call and returns a contiguous
|
|
301
|
+
``np.ndarray[float64]`` of shape ``(n_subcatchments,)`` (or a
|
|
302
|
+
``list[str]`` for ids). The GIL is released for the duration of the C
|
|
303
|
+
call, so multi-threaded consumers can read from independent solvers
|
|
304
|
+
in parallel.
|
|
302
305
|
|
|
303
|
-
..
|
|
306
|
+
.. list-table::
|
|
307
|
+
:header-rows: 1
|
|
308
|
+
:widths: 40 60
|
|
304
309
|
|
|
305
|
-
|
|
310
|
+
* - Method
|
|
311
|
+
- Returns / accepts
|
|
312
|
+
* - :meth:`get_runoff_bulk`
|
|
313
|
+
- Runoff rate per subcatchment (project flow units).
|
|
314
|
+
* - :meth:`get_quality_bulk(p)`
|
|
315
|
+
- Concentration of pollutant ``p`` per subcatchment.
|
|
316
|
+
* - :meth:`get_rainfall_bulk`
|
|
317
|
+
- Rainfall rate per subcatchment *(added 6.0.0)*.
|
|
318
|
+
* - :meth:`get_evap_bulk`
|
|
319
|
+
- Evaporation loss per subcatchment *(added 6.0.0)*.
|
|
320
|
+
* - :meth:`get_infil_bulk`
|
|
321
|
+
- Infiltration loss per subcatchment *(added 6.0.0)*.
|
|
322
|
+
* - :meth:`get_snow_depth_bulk`
|
|
323
|
+
- Snow depth per subcatchment *(added 6.0.0; placeholder zeros
|
|
324
|
+
pending full snow-state integration)*.
|
|
325
|
+
* - :meth:`get_ids_bulk`
|
|
326
|
+
- ``list[str]`` of every subcatchment's id in one C call
|
|
327
|
+
*(added 6.0.0; stride-packed UTF-8)*.
|
|
328
|
+
|
|
329
|
+
Whole-network water-balance pattern using the Phase 3 accessors:
|
|
306
330
|
|
|
307
|
-
|
|
308
|
-
while s.state == EngineState.RUNNING:
|
|
309
|
-
if s.step() != 0:
|
|
310
|
-
break
|
|
311
|
-
for i in range(sc.count()):
|
|
312
|
-
runoff[i] += sc.get_runoff(i)
|
|
331
|
+
.. code-block:: python
|
|
313
332
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
333
|
+
ids = sc.get_ids_bulk()
|
|
334
|
+
rain = sc.get_rainfall_bulk()
|
|
335
|
+
infil = sc.get_infil_bulk()
|
|
336
|
+
evap = sc.get_evap_bulk()
|
|
337
|
+
runoff = sc.get_runoff_bulk()
|
|
338
|
+
|
|
339
|
+
# Per-subcatch instantaneous residual (storage / snow can make this
|
|
340
|
+
# noisy step-by-step but it should integrate near zero over a long
|
|
341
|
+
# simulation if the model is well-balanced).
|
|
342
|
+
residual = rain - infil - evap - runoff
|
|
343
|
+
for i, name in enumerate(ids):
|
|
344
|
+
print(f" {name:<12} R={rain[i]:.3f} I={infil[i]:.3f} "
|
|
345
|
+
f"E={evap[i]:.3f} Q={runoff[i]:.3f} resid={residual[i]:+.3f}")
|
|
346
|
+
|
|
347
|
+
For *cumulative* (post-run) statistics, prefer the bulk accessors on
|
|
348
|
+
:class:`Statistics` (``subcatch_runoff_vol_bulk`` etc.) or the
|
|
349
|
+
:class:`OutputReader` — those are denser and pull from the report
|
|
350
|
+
file rather than recomputing from the live state.
|
|
318
351
|
|
|
319
352
|
----
|
|
320
353
|
|
|
@@ -13,7 +13,8 @@ cdef extern from "openswmm_2d.h":
|
|
|
13
13
|
int swmm_2d_vertex_get_xyz(void* engine, int idx,
|
|
14
14
|
double* x, double* y, double* z)
|
|
15
15
|
int swmm_2d_vertex_get_xyz_bulk(void* engine,
|
|
16
|
-
double* x, double* y, double* z)
|
|
16
|
+
double* x, double* y, double* z) nogil
|
|
17
|
+
int swmm_2d_set_vertex_z(void* engine, int idx, double z)
|
|
17
18
|
int swmm_2d_triangle_get_vertices(void* engine, int idx,
|
|
18
19
|
int* v0, int* v1, int* v2)
|
|
19
20
|
int swmm_2d_triangle_get_area(void* engine, int idx, double* area)
|
|
@@ -23,7 +24,7 @@ cdef extern from "openswmm_2d.h":
|
|
|
23
24
|
int swmm_2d_triangle_get_neighbours(void* engine, int idx,
|
|
24
25
|
int* n0, int* n1, int* n2)
|
|
25
26
|
int swmm_2d_edge_get_geometry_bulk(void* engine,
|
|
26
|
-
double* length, double* nx, double* ny)
|
|
27
|
+
double* length, double* nx, double* ny) nogil
|
|
27
28
|
|
|
28
29
|
# Coupling
|
|
29
30
|
int swmm_2d_vertex_coupling_count(void* engine, int* count)
|
|
@@ -37,14 +38,14 @@ cdef extern from "openswmm_2d.h":
|
|
|
37
38
|
int swmm_2d_get_coupling_flux(void* engine, int idx, double* flux)
|
|
38
39
|
int swmm_2d_get_rainfall(void* engine, int idx, double* rainfall)
|
|
39
40
|
int swmm_2d_get_net_source(void* engine, int idx, double* net_source)
|
|
40
|
-
int swmm_2d_get_depths_bulk(void* engine, double* depths)
|
|
41
|
-
int swmm_2d_get_heads_bulk(void* engine, double* heads)
|
|
42
|
-
int swmm_2d_get_coupling_fluxes_bulk(void* engine, double* fluxes)
|
|
43
|
-
int swmm_2d_get_edge_flux_bulk(void* engine, double* flux)
|
|
41
|
+
int swmm_2d_get_depths_bulk(void* engine, double* depths) nogil
|
|
42
|
+
int swmm_2d_get_heads_bulk(void* engine, double* heads) nogil
|
|
43
|
+
int swmm_2d_get_coupling_fluxes_bulk(void* engine, double* fluxes) nogil
|
|
44
|
+
int swmm_2d_get_edge_flux_bulk(void* engine, double* flux) nogil
|
|
44
45
|
|
|
45
46
|
# State — per vertex
|
|
46
47
|
int swmm_2d_vertex_get_head(void* engine, int idx, double* head)
|
|
47
|
-
int swmm_2d_vertex_get_heads_bulk(void* engine, double* heads)
|
|
48
|
+
int swmm_2d_vertex_get_heads_bulk(void* engine, double* heads) nogil
|
|
48
49
|
|
|
49
50
|
# Statistics
|
|
50
51
|
int swmm_2d_get_max_depth(void* engine, double* max_depth)
|
|
@@ -92,7 +92,8 @@ class Surface2D:
|
|
|
92
92
|
npt.NDArray[np.float64],
|
|
93
93
|
npt.NDArray[np.float64],
|
|
94
94
|
]:
|
|
95
|
-
"""Return (x, y, z) NumPy arrays for all vertices.
|
|
95
|
+
"""Return (x, y, z) NumPy arrays for all vertices. GIL is released
|
|
96
|
+
during the C call.
|
|
96
97
|
|
|
97
98
|
@return: Tuple C{(x, y, z)}, each of shape C{(n_vertices,)} with
|
|
98
99
|
dtype C{float64}.
|
|
@@ -101,6 +102,23 @@ class Surface2D:
|
|
|
101
102
|
"""
|
|
102
103
|
...
|
|
103
104
|
|
|
105
|
+
def set_vertex_z(self, idx: int, z: float) -> None:
|
|
106
|
+
"""Set the ground elevation of a mesh vertex.
|
|
107
|
+
|
|
108
|
+
Updates derived geometry for every triangle incident to this
|
|
109
|
+
vertex (centroid Z, per-edge midpoint Z). XY-derived fields are
|
|
110
|
+
unaffected. When called during a running simulation, solver
|
|
111
|
+
state (head, depth) is intentionally not rewritten — the implied
|
|
112
|
+
depth = head - bed therefore changes by the same amount as bed.
|
|
113
|
+
|
|
114
|
+
@param idx: Vertex index (0-based).
|
|
115
|
+
@type idx: int
|
|
116
|
+
@param z: New ground elevation (project vertical units).
|
|
117
|
+
@type z: float
|
|
118
|
+
@raise RuntimeError: If the C API call fails.
|
|
119
|
+
"""
|
|
120
|
+
...
|
|
121
|
+
|
|
104
122
|
def get_triangle_vertices(self, idx: int) -> tuple[int, int, int]:
|
|
105
123
|
"""Return the (v0, v1, v2) vertex indices for a triangle.
|
|
106
124
|
|
|
@@ -205,10 +223,13 @@ class Surface2D:
|
|
|
205
223
|
|
|
206
224
|
# ====================================================================
|
|
207
225
|
# State (depth/velocity) - per triangle bulk arrays
|
|
226
|
+
#
|
|
227
|
+
# Every bulk getter in this section releases the GIL for the C call.
|
|
208
228
|
# ====================================================================
|
|
209
229
|
|
|
210
230
|
def get_depths(self) -> npt.NDArray[np.float64]:
|
|
211
|
-
"""Return depths for all triangles as a NumPy array.
|
|
231
|
+
"""Return depths for all triangles as a NumPy array. GIL is
|
|
232
|
+
released during the C call.
|
|
212
233
|
|
|
213
234
|
@return: Array of shape C{(n_triangles,)} with dtype C{float64}.
|
|
214
235
|
@rtype: np.ndarray
|
|
@@ -217,7 +238,8 @@ class Surface2D:
|
|
|
217
238
|
...
|
|
218
239
|
|
|
219
240
|
def get_heads(self) -> npt.NDArray[np.float64]:
|
|
220
|
-
"""Return total heads for all triangles as a NumPy array.
|
|
241
|
+
"""Return total heads for all triangles as a NumPy array. GIL is
|
|
242
|
+
released during the C call.
|
|
221
243
|
|
|
222
244
|
@return: Array of shape C{(n_triangles,)} with dtype C{float64}.
|
|
223
245
|
@rtype: np.ndarray
|
|
@@ -226,7 +248,8 @@ class Surface2D:
|
|
|
226
248
|
...
|
|
227
249
|
|
|
228
250
|
def get_coupling_fluxes(self) -> npt.NDArray[np.float64]:
|
|
229
|
-
"""Return coupling fluxes for all triangles as a NumPy array.
|
|
251
|
+
"""Return coupling fluxes for all triangles as a NumPy array. GIL
|
|
252
|
+
is released during the C call.
|
|
230
253
|
|
|
231
254
|
@return: Array of shape C{(n_triangles,)} with dtype C{float64}.
|
|
232
255
|
Positive values denote flux into the 2D surface.
|
|
@@ -236,7 +259,8 @@ class Surface2D:
|
|
|
236
259
|
...
|
|
237
260
|
|
|
238
261
|
def get_edge_flux_bulk(self) -> npt.NDArray[np.float64]:
|
|
239
|
-
"""Return normal edge fluxes for all triangle edges.
|
|
262
|
+
"""Return normal edge fluxes for all triangle edges. GIL is
|
|
263
|
+
released during the C call.
|
|
240
264
|
|
|
241
265
|
Indexed as C{[tri*3 + localEdge]}.
|
|
242
266
|
@return: Array of shape C{(n_triangles*3,)} with dtype C{float64}.
|
|
@@ -245,6 +269,7 @@ class Surface2D:
|
|
|
245
269
|
|
|
246
270
|
def get_edge_geometry_bulk(self) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64], npt.NDArray[np.float64]]:
|
|
247
271
|
"""Return time-invariant edge lengths and outward unit normal components.
|
|
272
|
+
GIL is released during the C call.
|
|
248
273
|
|
|
249
274
|
Returns C{(length, nx, ny)}, each indexed as C{[tri*3 + localEdge]}.
|
|
250
275
|
|
|
@@ -317,6 +342,7 @@ class Surface2D:
|
|
|
317
342
|
|
|
318
343
|
def get_vertex_heads(self) -> npt.NDArray[np.float64]:
|
|
319
344
|
"""Return reconstructed heads at all vertices as a NumPy array.
|
|
345
|
+
GIL is released during the C call.
|
|
320
346
|
|
|
321
347
|
@return: Array of shape C{(n_vertices,)} with dtype C{float64}.
|
|
322
348
|
@rtype: np.ndarray
|