ies-optimiser 2026.9.0__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.
Files changed (36) hide show
  1. ies_optimiser-2026.9.0/CMakeLists.txt +43 -0
  2. ies_optimiser-2026.9.0/LICENSE +21 -0
  3. ies_optimiser-2026.9.0/PKG-INFO +100 -0
  4. ies_optimiser-2026.9.0/README.md +65 -0
  5. ies_optimiser-2026.9.0/pyproject.toml +192 -0
  6. ies_optimiser-2026.9.0/src/ies_optimiser/__init__.py +37 -0
  7. ies_optimiser-2026.9.0/src/ies_optimiser/__main__.py +10 -0
  8. ies_optimiser-2026.9.0/src/ies_optimiser/_install.py +132 -0
  9. ies_optimiser-2026.9.0/src/ies_optimiser/api.py +465 -0
  10. ies_optimiser-2026.9.0/src/ies_optimiser/chk.py +317 -0
  11. ies_optimiser-2026.9.0/src/ies_optimiser/cli.py +197 -0
  12. ies_optimiser-2026.9.0/src/ies_optimiser/data/ies-optimiser-input-1.schema.json +905 -0
  13. ies_optimiser-2026.9.0/src/ies_optimiser/data/ies-optimiser-result-1.schema.json +2806 -0
  14. ies_optimiser-2026.9.0/src/ies_optimiser/eqs_dmd_e.py +117 -0
  15. ies_optimiser-2026.9.0/src/ies_optimiser/eqs_dmd_x.py +55 -0
  16. ies_optimiser-2026.9.0/src/ies_optimiser/eqs_flx.py +154 -0
  17. ies_optimiser-2026.9.0/src/ies_optimiser/eqs_gen.py +136 -0
  18. ies_optimiser-2026.9.0/src/ies_optimiser/eqs_p2x_1.py +118 -0
  19. ies_optimiser-2026.9.0/src/ies_optimiser/eqs_p2x_2.py +33 -0
  20. ies_optimiser-2026.9.0/src/ies_optimiser/errors.py +169 -0
  21. ies_optimiser-2026.9.0/src/ies_optimiser/fcn.py +762 -0
  22. ies_optimiser-2026.9.0/src/ies_optimiser/formats.py +392 -0
  23. ies_optimiser-2026.9.0/src/ies_optimiser/models.py +537 -0
  24. ies_optimiser-2026.9.0/src/ies_optimiser/obj.py +69 -0
  25. ies_optimiser-2026.9.0/src/ies_optimiser/opt.py +42 -0
  26. ies_optimiser-2026.9.0/src/ies_optimiser/pos.py +283 -0
  27. ies_optimiser-2026.9.0/src/ies_optimiser/pos_dmd.py +722 -0
  28. ies_optimiser-2026.9.0/src/ies_optimiser/py.typed +0 -0
  29. ies_optimiser-2026.9.0/src/ies_optimiser/results.py +323 -0
  30. ies_optimiser-2026.9.0/src/ies_optimiser/schemas.py +100 -0
  31. ies_optimiser-2026.9.0/thermo/Cogen.cpp +204 -0
  32. ies_optimiser-2026.9.0/thermo/Cogen.h +96 -0
  33. ies_optimiser-2026.9.0/thermo/README.md +36 -0
  34. ies_optimiser-2026.9.0/thermo/iesOptimiserH2O.cpp +1919 -0
  35. ies_optimiser-2026.9.0/thermo/iesOptimiserH2O.h +247 -0
  36. ies_optimiser-2026.9.0/thermo/sim.cpp +65 -0
@@ -0,0 +1,43 @@
1
+ # Gréoux Research (2024). IES Optimiser: a linear optimiser-based integrated energy system modelling environment. https://github.com/greoux-research/ies-optimiser
2
+ #
3
+ # Builds the thermodynamics executable (thermo/*.cpp) and installs it inside
4
+ # the Python package, at ies_optimiser/_bin/ies-optimiser-thermo (ies-optimiser-thermo.exe on Windows).
5
+ # Run by scikit-build-core during 'python -m build' or 'pip install'; see
6
+ # pyproject.toml. It is a standalone executable called as a subprocess, not a
7
+ # Python extension.
8
+
9
+ cmake_minimum_required(VERSION 3.15...3.31)
10
+ project(ies_optimiser_thermo LANGUAGES CXX)
11
+
12
+ # Compiled with the flags of thermo/build.sh, the build that produced the
13
+ # reference executable (g++ -fPIC -Wall, no optimisation flag and no -std
14
+ # flag), so the packaged tool performs the same floating-point operations. The
15
+ # build type's own flags (Release adds -O3 -DNDEBUG) are deliberately cleared.
16
+ foreach(config RELEASE RELWITHDEBINFO MINSIZEREL DEBUG)
17
+ set(CMAKE_CXX_FLAGS_${config} "")
18
+ endforeach()
19
+
20
+ # On Windows the C++ runtime is linked statically (/MT): the executable is run
21
+ # as a separate process, outside Python's DLL directories, and msvcp140.dll is
22
+ # not guaranteed on a clean system. tools/inspect_native.py checks the result.
23
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
24
+
25
+ add_executable(ies-optimiser-thermo thermo/sim.cpp thermo/Cogen.cpp thermo/iesOptimiserH2O.cpp)
26
+ set_target_properties(ies-optimiser-thermo PROPERTIES POSITION_INDEPENDENT_CODE ON)
27
+ if(MSVC)
28
+ target_compile_options(ies-optimiser-thermo PRIVATE /W4)
29
+ else()
30
+ target_compile_options(ies-optimiser-thermo PRIVATE -Wall)
31
+ endif()
32
+ if(UNIX)
33
+ target_link_libraries(ies-optimiser-thermo PRIVATE m)
34
+ endif()
35
+
36
+ # SKBUILD_PLATLIB_DIR is the wheel's platform-library root when built by
37
+ # scikit-build-core; a plain 'cmake --install' uses the prefix instead.
38
+ if(DEFINED SKBUILD_PLATLIB_DIR)
39
+ set(IES_OPTIMISER_BIN_DESTINATION "${SKBUILD_PLATLIB_DIR}/ies_optimiser/_bin")
40
+ else()
41
+ set(IES_OPTIMISER_BIN_DESTINATION "ies_optimiser/_bin")
42
+ endif()
43
+ install(TARGETS ies-optimiser-thermo RUNTIME DESTINATION "${IES_OPTIMISER_BIN_DESTINATION}")
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Gréoux Research
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: ies-optimiser
3
+ Version: 2026.9.0
4
+ Summary: IES Optimiser: a linear optimiser-based integrated energy system modelling environment
5
+ Keywords: energy system,optimisation,linear programming,power-to-x,cogeneration
6
+ Author: Gréoux Research
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: C++
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Operating System :: Microsoft :: Windows
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Classifier: Typing :: Typed
20
+ Project-URL: Homepage, https://github.com/greoux-research/ies-optimiser
21
+ Project-URL: Documentation, https://github.com/greoux-research/ies-optimiser/tree/main/docs
22
+ Project-URL: Source, https://github.com/greoux-research/ies-optimiser
23
+ Project-URL: Issues, https://github.com/greoux-research/ies-optimiser/issues
24
+ Project-URL: Changelog, https://github.com/greoux-research/ies-optimiser/blob/main/CHANGELOG.md
25
+ Requires-Python: >=3.11
26
+ Requires-Dist: numpy<3,>=2.0
27
+ Requires-Dist: ortools<10,>=9.15
28
+ Requires-Dist: pydantic<3,>=2.11
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=8; extra == "dev"
31
+ Requires-Dist: jsonschema>=4.18; extra == "dev"
32
+ Requires-Dist: mypy>=1.10; extra == "dev"
33
+ Requires-Dist: build>=1.2; extra == "dev"
34
+ Description-Content-Type: text/markdown
35
+
36
+ # IES Optimiser
37
+
38
+ IES Optimiser (*Integrated Energy Systems Optimiser*) is a linear optimiser-based energy system modelling environment designed to support initial investigations such as options evaluation and trend analysis. It sizes and dispatches generators, storage and Power-to-X processes (electrolysis, desalination, cogeneration heat) over a year of hourly steps, with OR-Tools' GLOP solver.
39
+
40
+ - [Modelling Approach](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-modelling-approach.md)
41
+ - [Setup Guide](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-setup-guide.md)
42
+ - [IO File Structure](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-io-file-structure.md)
43
+ - [Inputs, Validation and the Python API](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-api.md)
44
+ - [Supported Platforms](https://github.com/greoux-research/ies-optimiser/blob/main/docs/support-matrix.md)
45
+ - [Changelog](https://github.com/greoux-research/ies-optimiser/blob/main/CHANGELOG.md)
46
+ - [Baseline Verification](https://github.com/greoux-research/ies-optimiser/blob/main/docs/baseline-verification.md)
47
+
48
+ ## Installation
49
+
50
+ IES Optimiser needs Python 3.11 or later, on Linux x86_64 (glibc 2.28+), macOS (Apple Silicon 11+, Intel 10.15+) or Windows x86_64. Wheels include the compiled thermodynamics executable; no compiler is needed.
51
+
52
+ Install it from PyPI into a fresh virtual environment:
53
+
54
+ ```bash
55
+ python3 -m venv ies-optimiser-env
56
+ source ies-optimiser-env/bin/activate # Windows: ies-optimiser-env\Scripts\activate
57
+ python -m pip install ies-optimiser
58
+ ```
59
+
60
+ To install a wheel file or a development checkout instead, see the [Setup Guide](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-setup-guide.md).
61
+
62
+ ## Use
63
+
64
+ A synthetic demonstration case (a solar, gas and battery system; MIT-licensed, like the code) is in the repository's [`examples/`](https://github.com/greoux-research/ies-optimiser/tree/main/examples) folder, with a thermally coupled Power-to-X case beside it; `python tools/build_examples.py` regenerates both in a checkout. From a directory holding a copy of `examples/`:
65
+
66
+ <!-- tested -->
67
+ ```bash
68
+ ies-optimiser validate examples/electricity-storage/case.json # check without solving
69
+ ies-optimiser examples/electricity-storage/case.json carbon-constraint=150
70
+ # -> examples/electricity-storage/case.ies-optimiser.carbon-constraint_150.0.json
71
+ ```
72
+
73
+ <!-- tested -->
74
+ ```python
75
+ import ies_optimiser
76
+
77
+ result = ies_optimiser.solve('examples/power-to-x-thermal/case.json')
78
+ if result.optimal and result.accounting_ok:
79
+ print(result.document['system']['cost']) # USD per year
80
+ ```
81
+
82
+ `ies-optimiser --help` lists the commands; `ies-optimiser schema input` prints the JSON Schema of an input.
83
+
84
+ ## Licence and data
85
+
86
+ The code, the thermodynamics sources and the synthetic examples are under the MIT licence. The illustrative datasets in [`datasets/`](https://github.com/greoux-research/ies-optimiser/tree/main/datasets) are not part of the installed package: their hourly profiles are derived from Renewables.ninja and licensed CC BY-NC 4.0.
87
+
88
+ Report problems at https://github.com/greoux-research/ies-optimiser/issues.
89
+
90
+ ## Repository
91
+
92
+ - **src/ies_optimiser** — the package: the API, the input and result models, their JSON Schemas, the command line, and the model; **thermo** — the C++ thermodynamics sources, built into the package by CMake; **ies_optimiser.py** — a launcher for `python ies_optimiser.py ...` in a checkout.
93
+ - **examples** — the synthetic cases; **datasets** — four illustrative island cases (`tools/build_datasets.py`); **results** — the current verified results for them, with provenance.
94
+ - **tests** — the development suite; **tests_installed** — the tests CI runs against each built wheel, outside the checkout; **tools** — builders, the result comparator, distribution and native-executable checks, the scenario runner (writing to the ignored **runs** folder) and `product_costs.py` (IES Optimiser's product cost KPI is an allocation, not a production cost).
95
+
96
+ Every result carries a `provenance` block recording the code, the digests of the input and of each profile it references, the options applied, and the solver and environment that produced it, and a `system.checks` block recording whether its balances and accounts reconcile. Results are reproducible only against a recorded environment: a different solver build may settle on a different vertex of the same optimal face, so hourly dispatch and surplus can differ between equally optimal results.
97
+
98
+ ## How to cite IES Optimiser
99
+
100
+ Gréoux Research (2024). IES Optimiser: a linear optimiser-based integrated energy system modelling environment. https://github.com/greoux-research/ies-optimiser
@@ -0,0 +1,65 @@
1
+ # IES Optimiser
2
+
3
+ IES Optimiser (*Integrated Energy Systems Optimiser*) is a linear optimiser-based energy system modelling environment designed to support initial investigations such as options evaluation and trend analysis. It sizes and dispatches generators, storage and Power-to-X processes (electrolysis, desalination, cogeneration heat) over a year of hourly steps, with OR-Tools' GLOP solver.
4
+
5
+ - [Modelling Approach](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-modelling-approach.md)
6
+ - [Setup Guide](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-setup-guide.md)
7
+ - [IO File Structure](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-io-file-structure.md)
8
+ - [Inputs, Validation and the Python API](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-api.md)
9
+ - [Supported Platforms](https://github.com/greoux-research/ies-optimiser/blob/main/docs/support-matrix.md)
10
+ - [Changelog](https://github.com/greoux-research/ies-optimiser/blob/main/CHANGELOG.md)
11
+ - [Baseline Verification](https://github.com/greoux-research/ies-optimiser/blob/main/docs/baseline-verification.md)
12
+
13
+ ## Installation
14
+
15
+ IES Optimiser needs Python 3.11 or later, on Linux x86_64 (glibc 2.28+), macOS (Apple Silicon 11+, Intel 10.15+) or Windows x86_64. Wheels include the compiled thermodynamics executable; no compiler is needed.
16
+
17
+ Install it from PyPI into a fresh virtual environment:
18
+
19
+ ```bash
20
+ python3 -m venv ies-optimiser-env
21
+ source ies-optimiser-env/bin/activate # Windows: ies-optimiser-env\Scripts\activate
22
+ python -m pip install ies-optimiser
23
+ ```
24
+
25
+ To install a wheel file or a development checkout instead, see the [Setup Guide](https://github.com/greoux-research/ies-optimiser/blob/main/docs/ies-optimiser-setup-guide.md).
26
+
27
+ ## Use
28
+
29
+ A synthetic demonstration case (a solar, gas and battery system; MIT-licensed, like the code) is in the repository's [`examples/`](https://github.com/greoux-research/ies-optimiser/tree/main/examples) folder, with a thermally coupled Power-to-X case beside it; `python tools/build_examples.py` regenerates both in a checkout. From a directory holding a copy of `examples/`:
30
+
31
+ <!-- tested -->
32
+ ```bash
33
+ ies-optimiser validate examples/electricity-storage/case.json # check without solving
34
+ ies-optimiser examples/electricity-storage/case.json carbon-constraint=150
35
+ # -> examples/electricity-storage/case.ies-optimiser.carbon-constraint_150.0.json
36
+ ```
37
+
38
+ <!-- tested -->
39
+ ```python
40
+ import ies_optimiser
41
+
42
+ result = ies_optimiser.solve('examples/power-to-x-thermal/case.json')
43
+ if result.optimal and result.accounting_ok:
44
+ print(result.document['system']['cost']) # USD per year
45
+ ```
46
+
47
+ `ies-optimiser --help` lists the commands; `ies-optimiser schema input` prints the JSON Schema of an input.
48
+
49
+ ## Licence and data
50
+
51
+ The code, the thermodynamics sources and the synthetic examples are under the MIT licence. The illustrative datasets in [`datasets/`](https://github.com/greoux-research/ies-optimiser/tree/main/datasets) are not part of the installed package: their hourly profiles are derived from Renewables.ninja and licensed CC BY-NC 4.0.
52
+
53
+ Report problems at https://github.com/greoux-research/ies-optimiser/issues.
54
+
55
+ ## Repository
56
+
57
+ - **src/ies_optimiser** — the package: the API, the input and result models, their JSON Schemas, the command line, and the model; **thermo** — the C++ thermodynamics sources, built into the package by CMake; **ies_optimiser.py** — a launcher for `python ies_optimiser.py ...` in a checkout.
58
+ - **examples** — the synthetic cases; **datasets** — four illustrative island cases (`tools/build_datasets.py`); **results** — the current verified results for them, with provenance.
59
+ - **tests** — the development suite; **tests_installed** — the tests CI runs against each built wheel, outside the checkout; **tools** — builders, the result comparator, distribution and native-executable checks, the scenario runner (writing to the ignored **runs** folder) and `product_costs.py` (IES Optimiser's product cost KPI is an allocation, not a production cost).
60
+
61
+ Every result carries a `provenance` block recording the code, the digests of the input and of each profile it references, the options applied, and the solver and environment that produced it, and a `system.checks` block recording whether its balances and accounts reconcile. Results are reproducible only against a recorded environment: a different solver build may settle on a different vertex of the same optimal face, so hourly dispatch and surplus can differ between equally optimal results.
62
+
63
+ ## How to cite IES Optimiser
64
+
65
+ Gréoux Research (2024). IES Optimiser: a linear optimiser-based integrated energy system modelling environment. https://github.com/greoux-research/ies-optimiser
@@ -0,0 +1,192 @@
1
+ [build-system]
2
+ # scikit-build-core drives CMake, which builds the thermodynamics executable
3
+ # (thermo/*.cpp) into the wheel. 0.11 is the first release with PEP 639
4
+ # licence metadata.
5
+ requires = ["scikit-build-core>=0.11"]
6
+ build-backend = "scikit_build_core.build"
7
+
8
+ [project]
9
+ name = "ies-optimiser"
10
+ # The single authoritative version (calendar versioning: year.month.patch).
11
+ # Installed code reads it from the distribution metadata (ies_optimiser.__version__).
12
+ version = "2026.9.0"
13
+ description = "IES Optimiser: a linear optimiser-based integrated energy system modelling environment"
14
+ readme = "README.md"
15
+ license = "MIT"
16
+ license-files = ["LICENSE"]
17
+ authors = [{ name = "Gréoux Research" }]
18
+ # The minimum. Verified locally on macOS arm64 with 3.11, 3.12, 3.13 and 3.14;
19
+ # the full platform matrix (docs/support-matrix.md) is verified by CI.
20
+ requires-python = ">=3.11"
21
+ # Ranges follow what the code imports and what has been verified:
22
+ # - numpy: array handling and profile I/O; written against the NumPy 2 API,
23
+ # verified with 2.0.2.
24
+ # - ortools: GLOP through ortools.linear_solver.pywraplp and the version query
25
+ # in ortools.init. Verified with 9.15.6755. The solver build decides which
26
+ # optimal vertex is returned, so results are reproducible only against a
27
+ # recorded version; the range is not a claim that every 9.x gives the same
28
+ # dispatch, and releases before 9.15 are not tested.
29
+ # - pydantic: the input and result models; validate_by_name and
30
+ # serialize_by_alias need 2.11.
31
+ dependencies = [
32
+ "numpy>=2.0,<3",
33
+ "ortools>=9.15,<10",
34
+ "pydantic>=2.11,<3",
35
+ ]
36
+ keywords = ["energy system", "optimisation", "linear programming", "power-to-x", "cogeneration"]
37
+ classifiers = [
38
+ "Development Status :: 4 - Beta",
39
+ "Intended Audience :: Science/Research",
40
+ "Programming Language :: Python :: 3",
41
+ "Programming Language :: Python :: 3.11",
42
+ "Programming Language :: Python :: 3.12",
43
+ "Programming Language :: C++",
44
+ "Operating System :: MacOS",
45
+ "Operating System :: POSIX :: Linux",
46
+ "Operating System :: Microsoft :: Windows",
47
+ "Topic :: Scientific/Engineering",
48
+ "Typing :: Typed",
49
+ ]
50
+
51
+ [project.optional-dependencies]
52
+ # pip install -e ".[dev]": the test suite, the schema tests and the type check.
53
+ dev = [
54
+ "pytest>=8",
55
+ "jsonschema>=4.18",
56
+ "mypy>=1.10",
57
+ "build>=1.2",
58
+ ]
59
+
60
+ [project.scripts]
61
+ ies-optimiser = "ies_optimiser.cli:main"
62
+
63
+ [project.urls]
64
+ Homepage = "https://github.com/greoux-research/ies-optimiser"
65
+ Documentation = "https://github.com/greoux-research/ies-optimiser/tree/main/docs"
66
+ Source = "https://github.com/greoux-research/ies-optimiser"
67
+ Issues = "https://github.com/greoux-research/ies-optimiser/issues"
68
+ Changelog = "https://github.com/greoux-research/ies-optimiser/blob/main/CHANGELOG.md"
69
+
70
+ [tool.scikit-build]
71
+ minimum-version = "build-system.requires"
72
+ build-dir = "build/{wheel_tag}"
73
+ cmake.version = ">=3.15"
74
+ # The wheel carries a native executable but no Python extension: it is tagged
75
+ # py3-none-<platform>, installable on any Python 3 of that platform, and never
76
+ # as a pure-Python (any) wheel.
77
+ wheel.py-api = "py3"
78
+ wheel.packages = ["src/ies_optimiser"]
79
+ # ies_optimiser/_bin/ies-optimiser-thermo comes from the CMake install step. src/ies_optimiser/_bin is
80
+ # ignored by Git and excluded from the sdist, and a clean build tree holds none.
81
+ # The source distribution is an allow-list: the package, the native sources
82
+ # and their build files, the metadata. Datasets (whose profiles are licensed
83
+ # CC BY-NC 4.0), results, runs, tests, tools, docs and build products are
84
+ # excluded.
85
+ sdist.exclude = ["/*"]
86
+ sdist.include = [
87
+ "/pyproject.toml",
88
+ "/CMakeLists.txt",
89
+ "/README.md",
90
+ "/LICENSE",
91
+ "/src/ies_optimiser/*.py",
92
+ "/src/ies_optimiser/py.typed",
93
+ "/src/ies_optimiser/data/*.schema.json",
94
+ "/thermo/*.cpp",
95
+ "/thermo/*.h",
96
+ "/thermo/README.md",
97
+ ]
98
+
99
+ # Cross-platform wheels (.github/workflows/wheels.yml runs cibuildwheel with
100
+ # this configuration; docs/support-matrix.md explains the choices).
101
+ #
102
+ # The wheel is py3-none-<platform>: one wheel per platform serves every
103
+ # supported Python, so it is built once, with CPython 3.11 (the minimum), and
104
+ # the CI test jobs install it on each supported Python. The repair step checks
105
+ # the thermodynamics executable itself (tools/inspect_native.py), since the
106
+ # repair tools are written for extension modules.
107
+ [tool.cibuildwheel]
108
+ build = "cp311-*"
109
+ skip = "*-musllinux_*"
110
+ build-frontend = "build"
111
+ build-verbosity = 1
112
+ before-build = "python -m pip install pyelftools pefile auditwheel"
113
+ test-requires = ["pytest", "jsonschema"]
114
+ test-sources = [
115
+ "tests_installed", "tests/fixtures", "examples", "README.md", "docs/ies-optimiser-api.md", "docs/ies-optimiser-setup-guide.md",
116
+ "tools/check_invariants.py",
117
+ ]
118
+ test-command = "python -m pytest tests_installed -p no:cacheprovider -q -rs"
119
+
120
+ [tool.cibuildwheel.linux]
121
+ # glibc 2.28 and later (RHEL 8, Debian 10, Ubuntu 18.10 and newer), the same
122
+ # baseline as the OR-Tools wheels IES Optimiser depends on.
123
+ archs = ["x86_64"]
124
+ manylinux-x86_64-image = "manylinux_2_28"
125
+ repair-wheel-command = [
126
+ "auditwheel repair --plat manylinux_2_28_x86_64 -w {dest_dir} {wheel}",
127
+ "python {project}/tools/inspect_native.py {dest_dir}",
128
+ ]
129
+
130
+ [tool.cibuildwheel.macos]
131
+ archs = ["native"]
132
+ repair-wheel-command = [
133
+ "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
134
+ "python {project}/tools/inspect_native.py {dest_dir}",
135
+ ]
136
+
137
+ [tool.cibuildwheel.windows]
138
+ archs = ["AMD64"]
139
+ # No DLL to bundle (the C++ runtime is linked statically): check, then copy.
140
+ repair-wheel-command = "python {project}/tools/inspect_native.py {wheel} --copy-to {dest_dir}"
141
+
142
+ # Minimum macOS: the floor of the OR-Tools wheels for each architecture.
143
+ [[tool.cibuildwheel.overrides]]
144
+ select = "*-macosx_arm64"
145
+ environment = { MACOSX_DEPLOYMENT_TARGET = "11.0" }
146
+
147
+ [[tool.cibuildwheel.overrides]]
148
+ select = "*-macosx_x86_64"
149
+ environment = { MACOSX_DEPLOYMENT_TARGET = "10.15" }
150
+
151
+ [tool.pytest.ini_options]
152
+ testpaths = ["tests"]
153
+
154
+ # Static type checking of the public boundary: python -m mypy
155
+ # Scope: the modules users and scripts call. The model-building modules are
156
+ # imported and followed silently (their errors are not reported here) and are
157
+ # typed incrementally; chk's functions and the fcn functions the boundary calls
158
+ # are annotated already.
159
+ [tool.mypy]
160
+ # No python_version: mypy checks against the interpreter it runs in, whose
161
+ # installed NumPy stubs may use syntax newer than 3.11 (NumPy 2.5 requires
162
+ # 3.12). Compatibility with 3.11 itself is tested by running on 3.11.
163
+ files = [
164
+ "src/ies_optimiser/__init__.py", "src/ies_optimiser/__main__.py", "src/ies_optimiser/_install.py", "src/ies_optimiser/api.py",
165
+ "src/ies_optimiser/cli.py", "src/ies_optimiser/errors.py", "src/ies_optimiser/formats.py", "src/ies_optimiser/models.py",
166
+ "src/ies_optimiser/results.py", "src/ies_optimiser/schemas.py",
167
+ ]
168
+ mypy_path = "src"
169
+ plugins = ["pydantic.mypy"]
170
+ strict = true
171
+ # Calls from the boundary into the equation-building modules are allowed while
172
+ # those remain unannotated.
173
+ untyped_calls_exclude = [
174
+ "ies_optimiser.eqs_dmd_e", "ies_optimiser.eqs_dmd_x", "ies_optimiser.eqs_flx", "ies_optimiser.eqs_gen", "ies_optimiser.eqs_p2x_1", "ies_optimiser.eqs_p2x_2",
175
+ "ies_optimiser.obj", "ies_optimiser.opt", "ies_optimiser.pos",
176
+ ]
177
+
178
+ [[tool.mypy.overrides]]
179
+ module = [
180
+ "ies_optimiser.chk", "ies_optimiser.fcn", "ies_optimiser.eqs_dmd_e", "ies_optimiser.eqs_dmd_x", "ies_optimiser.eqs_flx", "ies_optimiser.eqs_gen", "ies_optimiser.eqs_p2x_1",
181
+ "ies_optimiser.eqs_p2x_2", "ies_optimiser.obj", "ies_optimiser.opt", "ies_optimiser.pos", "ies_optimiser.pos_dmd",
182
+ ]
183
+ follow_imports = "silent"
184
+
185
+ [[tool.mypy.overrides]]
186
+ module = ["ortools.*"]
187
+ ignore_missing_imports = true
188
+
189
+ [tool.pydantic-mypy]
190
+ init_forbid_extra = true
191
+ init_typed = true
192
+ warn_required_dynamic_aliases = true
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # Gréoux Research (2024). IES Optimiser: a linear optimiser-based integrated energy system modelling environment. https://github.com/greoux-research/ies-optimiser
4
+
5
+ """IES Optimiser: a linear optimiser-based integrated energy system modelling environment.
6
+
7
+ import ies_optimiser
8
+
9
+ report = ies_optimiser.validate('case.json') # nothing solved, nothing written
10
+ result = ies_optimiser.solve('case.json', options={'carbon-constraint': 50.0})
11
+ if result.optimal and result.accounting_ok:
12
+ print(result.document['system']['cost'])
13
+
14
+ The names below are the public API; see docs/ies-optimiser-api.md. The public modules
15
+ are ies_optimiser.api, ies_optimiser.models, ies_optimiser.results, ies_optimiser.errors, ies_optimiser.schemas and
16
+ ies_optimiser.cli. The modelling modules (chk, fcn, eqs_*, obj, opt, pos, pos_dmd,
17
+ formats) are internal, except for fcn.RunConfig, exported here. Importing ies_optimiser
18
+ reads, writes, prints and runs nothing.
19
+ """
20
+
21
+ from ies_optimiser._install import version as _version
22
+ from ies_optimiser.api import (SolveResult, ValidationReport, check_options, load_input, output_path, parse_case, solve,
23
+ to_canonical, validate, write_result)
24
+ from ies_optimiser.errors import Diagnostic, IesOptimiserError, InputError, ThermoError
25
+ from ies_optimiser.fcn import RunConfig
26
+ from ies_optimiser.models import (Case, CommodityDemand, Demand, ElectricityDemand, Generator, Process, SolveOptions,
27
+ Storage)
28
+
29
+ __version__: str = _version()
30
+
31
+ __all__ = [
32
+ '__version__',
33
+ 'solve', 'validate', 'load_input', 'parse_case', 'to_canonical', 'check_options', 'write_result',
34
+ 'output_path', 'SolveResult', 'ValidationReport', 'RunConfig',
35
+ 'IesOptimiserError', 'InputError', 'ThermoError', 'Diagnostic',
36
+ 'Case', 'Demand', 'ElectricityDemand', 'CommodityDemand', 'Generator', 'Storage', 'Process', 'SolveOptions',
37
+ ]
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # Gréoux Research (2024). IES Optimiser: a linear optimiser-based integrated energy system modelling environment. https://github.com/greoux-research/ies-optimiser
4
+
5
+ """python -m ies_optimiser ...: the same command line as the ies-optimiser console command."""
6
+
7
+ from ies_optimiser.cli import main
8
+
9
+ if __name__ == '__main__':
10
+ raise SystemExit(main())
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # Gréoux Research (2024). IES Optimiser: a linear optimiser-based integrated energy system modelling environment. https://github.com/greoux-research/ies-optimiser
4
+
5
+ """Where this copy of IES Optimiser lives: its version, its files, its checkout (if
6
+ any) and its thermodynamics executable.
7
+
8
+ Nothing here reads outside the package's own directory and its distribution
9
+ metadata, and nothing is written, downloaded or compiled. The version comes
10
+ from the installed distribution's metadata, which pyproject.toml sets (the
11
+ single authoritative version); a source tree that is not installed reads
12
+ pyproject.toml itself.
13
+ """
14
+
15
+ import os
16
+ import sys
17
+ from importlib import metadata, resources
18
+ from typing import Any, Dict, Optional
19
+
20
+ DISTRIBUTION = 'ies-optimiser'
21
+
22
+ PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__))
23
+ """The directory of the ies_optimiser package that is running (site-packages/ies_optimiser, or src/ies_optimiser)."""
24
+
25
+ THERMO_NAME = 'ies-optimiser-thermo.exe' if sys.platform == 'win32' else 'ies-optimiser-thermo'
26
+ """The thermodynamics executable's file name on this platform."""
27
+
28
+
29
+ def packaged_thermo() -> str:
30
+ """The absolute path of the thermodynamics executable installed with the
31
+ package, whether or not it exists; never looked up in the working
32
+ directory or a repository.
33
+
34
+ A wheel installs it beside the modules, at ies_optimiser/_bin/, found through the
35
+ package's resources. An editable install keeps the modules in the source
36
+ tree and the built executable in site-packages; there it is the file the
37
+ distribution records as ies_optimiser/_bin/<name> (its RECORD), and only when the
38
+ distribution is an editable install of the running checkout.
39
+ """
40
+ beside = os.path.abspath(str(resources.files('ies_optimiser').joinpath('_bin', THERMO_NAME)))
41
+ if os.path.isfile(beside):
42
+ return beside
43
+ root = checkout_root()
44
+ dist = _distribution()
45
+ if root is not None and dist is not None and _editable_of(dist, root):
46
+ wanted = '/'.join(('ies_optimiser', '_bin', THERMO_NAME))
47
+ for entry in dist.files or ():
48
+ if str(entry).replace(os.sep, '/') == wanted:
49
+ return os.path.abspath(str(dist.locate_file(entry)))
50
+ return beside
51
+
52
+
53
+ def checkout_root() -> Optional[str]:
54
+ """The source checkout this package is running from -- the directory
55
+ holding pyproject.toml above src/ies_optimiser -- or None for an installed wheel."""
56
+ src = os.path.dirname(PACKAGE_DIR)
57
+ root = os.path.dirname(src)
58
+ if os.path.basename(PACKAGE_DIR) == 'ies_optimiser' and os.path.basename(src) == 'src' \
59
+ and os.path.isfile(os.path.join(root, 'pyproject.toml')):
60
+ return root
61
+ return None
62
+
63
+
64
+ def _distribution() -> Optional[metadata.Distribution]:
65
+ try:
66
+ return metadata.distribution(DISTRIBUTION)
67
+ except metadata.PackageNotFoundError:
68
+ return None
69
+
70
+
71
+ def _same(a: str, b: str) -> bool:
72
+ try:
73
+ return os.path.samefile(a, b)
74
+ except OSError:
75
+ return False
76
+
77
+
78
+ def installation() -> Dict[str, Any]:
79
+ """How the running package was installed.
80
+
81
+ Returns
82
+ -------
83
+ dict
84
+ ``kind``: 'wheel' (an installed distribution whose files are the
85
+ running ones), 'editable' (an editable install of the running
86
+ checkout), 'source' (a checkout on the path but not installed) or
87
+ 'unknown'; ``version``; ``package_dir``; ``checkout`` (the source
88
+ checkout's root, or None).
89
+ """
90
+ root = checkout_root()
91
+ dist = _distribution()
92
+ kind = 'unknown'
93
+ version = None
94
+ if dist is not None:
95
+ installed = dist.locate_file(os.path.join('ies_optimiser', '__init__.py'))
96
+ if _same(str(installed), os.path.join(PACKAGE_DIR, '__init__.py')):
97
+ kind, version = 'wheel', dist.version
98
+ elif root is not None and _editable_of(dist, root):
99
+ kind, version = 'editable', dist.version
100
+ if kind == 'unknown' and root is not None:
101
+ kind, version = 'source', _pyproject_version(root)
102
+ return {'kind': kind, 'version': version, 'package_dir': PACKAGE_DIR, 'checkout': root}
103
+
104
+
105
+ def _editable_of(dist: metadata.Distribution, root: str) -> bool:
106
+ # PEP 610: an editable install records the project directory it points to.
107
+ import json
108
+ from urllib.parse import urlparse
109
+ from urllib.request import url2pathname
110
+ text = dist.read_text('direct_url.json')
111
+ if not text:
112
+ return False
113
+ info = json.loads(text)
114
+ if not info.get('dir_info', {}).get('editable'):
115
+ return False
116
+ url = urlparse(info.get('url', ''))
117
+ # url2pathname turns '/C:/dir' into 'C:\\dir' on Windows and unquotes.
118
+ return url.scheme == 'file' and _same(url2pathname(url.path), root)
119
+
120
+
121
+ def _pyproject_version(root: str) -> Optional[str]:
122
+ try:
123
+ import tomllib
124
+ with open(os.path.join(root, 'pyproject.toml'), 'rb') as f:
125
+ return str(tomllib.load(f)['project']['version'])
126
+ except (ImportError, OSError, KeyError, ValueError):
127
+ return None
128
+
129
+
130
+ def version() -> str:
131
+ """The version of the running package ('unknown' if it cannot be told)."""
132
+ return installation()['version'] or 'unknown'