Skip to content

Commit ab83844

Browse files
authored
Merge pull request #1190 from oemof/release/v0.5
Release/v0.5
2 parents 193ab62 + 444f1a9 commit ab83844

File tree

17 files changed

+118
-59
lines changed

17 files changed

+118
-59
lines changed

.github/workflows/lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ jobs:
1515

1616
steps:
1717
- name: Check out Git repository
18-
uses: actions/checkout@v2
18+
uses: actions/checkout@v3
1919

2020
- name: Set up Python
2121
uses: actions/setup-python@v5
2222
with:
23-
python-version: 3.9
23+
python-version: "3.10"
2424

2525
- name: Install Python dependencies
2626
run: pip install black flake8

.github/workflows/packaging.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ jobs:
1919
strategy:
2020
max-parallel: 4
2121
matrix:
22-
python-version: [3.9]
22+
python-version: ["3.10"]
2323

2424
steps:
25-
- uses: actions/checkout@v1
25+
- uses: actions/checkout@v3
2626
- name: Set up Python ${{ matrix.python-version }}
2727
uses: actions/setup-python@v5
2828
with:

.github/workflows/tox_checks.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ jobs:
3131
- name: Install LaTeX
3232
run: sudo apt install dvipng rubber texlive-latex-extra
3333
- name: Git clone
34-
uses: actions/checkout@v2
34+
uses: actions/checkout@v3
3535

36-
- name: Set up Python ${{ env.default_python || '3.9' }}
36+
- name: Set up Python ${{ env.default_python || '3.10' }}
3737
uses: actions/setup-python@v5
3838
with:
39-
python-version: "${{ env.default_python || '3.9' }}"
39+
python-version: "${{ env.default_python || '3.10' }}"
4040

4141
- name: Pip cache
42-
uses: actions/cache@v2
42+
uses: actions/cache@v4
4343
with:
4444
path: ~/.cache/pip
4545
key: ${{ runner.os }}-pip-${{ matrix.toxenv }}-${{ hashFiles('tox.ini', 'setup.py') }}

.github/workflows/tox_pytests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ jobs:
1717
runs-on: ubuntu-latest
1818
strategy:
1919
matrix:
20-
python-version: [3.9, "3.10", "3.11"]
20+
python-version: ["3.10", "3.11"]
2121

2222
steps:
23-
- uses: actions/checkout@v1
23+
- uses: actions/checkout@v3
2424
- name: Install cbc
2525
run: sudo apt install coinor-cbc
2626
- name: Set up Python ${{ matrix.python-version }}

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ These are new features and improvements of note in each release
99
:backlinks: top
1010

1111

12+
.. include:: whatsnew/v0-5-7.rst
1213
.. include:: whatsnew/v0-5-6.rst
1314
.. include:: whatsnew/v0-5-5.rst
1415
.. include:: whatsnew/v0-5-4.rst

docs/whatsnew/v0-5-7.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
v0.5.7 (April 25th, 2025)
2+
--------------------------
3+
4+
New features
5+
############
6+
7+
* Introduce option Model.solve(allow_nonoptimal=False) that raises
8+
an error if no optimal solution is found. (Backported from v0.6.)
9+
10+
Bug fixes
11+
#########
12+
13+
* storage_costs are now considered also for GenericStorage with a
14+
capacity that is subject to an Investment.
15+
16+
Known issues
17+
############
18+
19+
* Indexing of storage with capacity investment is off by one.
20+
* Related: Storage limits not applied for last time step.
21+
* Some links in the documentation are no longer valid.
22+
23+
Contributors
24+
############
25+
26+
* Eva Schischke
27+
* Patrik Schönfeldt

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,14 @@ classifiers = [
4747
"Operating System :: OS Independent",
4848
"Programming Language :: Python",
4949
"Programming Language :: Python :: 3",
50-
"Programming Language :: Python :: 3.9",
5150
"Programming Language :: Python :: 3.10",
5251
"Programming Language :: Python :: 3.11",
52+
"Programming Language :: Python :: 3.12",
53+
"Programming Language :: Python :: 3.13",
5354
"Programming Language :: Python :: Implementation :: CPython",
5455
"Topic :: Utilities",
5556
]
56-
requires-python = ">=3.8"
57+
requires-python = ">=3.10"
5758
dependencies = [
5859
"blinker",
5960
"dill",

src/oemof/solph/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.5.6"
1+
__version__ = "0.5.7"
22

33
from . import buses
44
from . import components

src/oemof/solph/_models.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ def results(self):
213213
"""
214214
return processing.results(self)
215215

216-
def solve(self, solver="cbc", solver_io="lp", **kwargs):
216+
def solve(
217+
self, solver="cbc", solver_io="lp", allow_nonoptimal=True, **kwargs
218+
):
217219
r"""Takes care of communication with solver to solve the model.
218220
219221
Parameters
@@ -222,6 +224,9 @@ def solve(self, solver="cbc", solver_io="lp", **kwargs):
222224
solver to be used e.g. "cbc", "glpk", "gurobi", "cplex"
223225
solver_io : string
224226
pyomo solver interface file format: "lp", "python", "nl", etc.
227+
allow_nonoptimal : bool
228+
if set to false, an error will be raised
229+
if no optimal solution is found
225230
\**kwargs : keyword arguments
226231
Possible keys can be set see below:
227232
@@ -248,23 +253,29 @@ def solve(self, solver="cbc", solver_io="lp", **kwargs):
248253

249254
solver_results = opt.solve(self, **solve_kwargs)
250255

251-
status = solver_results["Solver"][0]["Status"]
252-
termination_condition = solver_results["Solver"][0][
253-
"Termination condition"
254-
]
256+
status = solver_results.Solver.Status
257+
termination_condition = solver_results.Solver.Termination_condition
258+
259+
self.es.results = solver_results
260+
self.solver_results = solver_results
255261

256262
if status == "ok" and termination_condition == "optimal":
257263
logging.info("Optimization successful...")
258264
else:
259265
msg = (
260-
"Optimization ended with status {0} and termination "
261-
"condition {1}"
262-
)
263-
warnings.warn(
264-
msg.format(status, termination_condition), UserWarning
266+
f"The solver did not return an optimal solution. "
267+
f"Instead the optimization ended with\n "
268+
f" - status: {status}\n"
269+
f" - termination condition: {termination_condition}"
265270
)
266-
self.es.results = solver_results
267-
self.solver_results = solver_results
271+
272+
if allow_nonoptimal:
273+
msg += "\n In the future, this will be treated as an error."
274+
warnings.warn(
275+
msg.format(status, termination_condition), UserWarning
276+
)
277+
else:
278+
raise RuntimeError(msg)
268279

269280
return solver_results
270281

src/oemof/solph/components/_generic_storage.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ def _create(self, group=None):
12121212

12131213
# ######################### Variables ################################
12141214
self.storage_content = Var(
1215-
self.INVESTSTORAGES, m.TIMESTEPS, within=NonNegativeReals
1215+
self.INVESTSTORAGES, m.TIMEPOINTS, within=NonNegativeReals
12161216
)
12171217

12181218
def _storage_investvar_bound_rule(block, n, p):
@@ -1751,6 +1751,7 @@ def _objective_expression(self):
17511751
return 0
17521752

17531753
investment_costs = 0
1754+
storage_costs = 0
17541755
period_investment_costs = {p: 0 for p in m.PERIODS}
17551756
fixed_costs = 0
17561757

@@ -1889,10 +1890,24 @@ def _objective_expression(self):
18891890
for pp in range(range_limit)
18901891
)
18911892

1893+
for n in self.INVESTSTORAGES:
1894+
if valid_sequence(n.storage_costs, len(m.TIMESTEPS)):
1895+
storage_costs += (
1896+
self.storage_content[n, 0] * n.storage_costs[0]
1897+
)
1898+
for t in m.TIMESTEPS:
1899+
storage_costs += (
1900+
self.storage_content[n, t + 1] * n.storage_costs[t + 1]
1901+
)
1902+
1903+
self.storage_costs = Expression(expr=storage_costs)
1904+
18921905
self.investment_costs = Expression(expr=investment_costs)
18931906
self.period_investment_costs = period_investment_costs
18941907
self.fixed_costs = Expression(expr=fixed_costs)
1895-
self.costs = Expression(expr=investment_costs + fixed_costs)
1908+
self.costs = Expression(
1909+
expr=investment_costs + fixed_costs + storage_costs
1910+
)
18961911

18971912
return self.costs
18981913

0 commit comments

Comments
 (0)