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.
- ies_optimiser-2026.9.0/CMakeLists.txt +43 -0
- ies_optimiser-2026.9.0/LICENSE +21 -0
- ies_optimiser-2026.9.0/PKG-INFO +100 -0
- ies_optimiser-2026.9.0/README.md +65 -0
- ies_optimiser-2026.9.0/pyproject.toml +192 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/__init__.py +37 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/__main__.py +10 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/_install.py +132 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/api.py +465 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/chk.py +317 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/cli.py +197 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/data/ies-optimiser-input-1.schema.json +905 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/data/ies-optimiser-result-1.schema.json +2806 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/eqs_dmd_e.py +117 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/eqs_dmd_x.py +55 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/eqs_flx.py +154 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/eqs_gen.py +136 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/eqs_p2x_1.py +118 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/eqs_p2x_2.py +33 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/errors.py +169 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/fcn.py +762 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/formats.py +392 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/models.py +537 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/obj.py +69 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/opt.py +42 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/pos.py +283 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/pos_dmd.py +722 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/py.typed +0 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/results.py +323 -0
- ies_optimiser-2026.9.0/src/ies_optimiser/schemas.py +100 -0
- ies_optimiser-2026.9.0/thermo/Cogen.cpp +204 -0
- ies_optimiser-2026.9.0/thermo/Cogen.h +96 -0
- ies_optimiser-2026.9.0/thermo/README.md +36 -0
- ies_optimiser-2026.9.0/thermo/iesOptimiserH2O.cpp +1919 -0
- ies_optimiser-2026.9.0/thermo/iesOptimiserH2O.h +247 -0
- 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'
|