Skip to content

Commit

Permalink
Merge pull request #912 from lensum/features/cellular
Browse files Browse the repository at this point in the history
Enable modelling of cellular grid structures
  • Loading branch information
p-snft committed Jul 6, 2023
2 parents 7a73bad + 3ec1470 commit 1cee273
Show file tree
Hide file tree
Showing 7 changed files with 599 additions and 20 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Authors
* Jonathan Amme
* Julian Endres
* Lluis Millet
* Lennart Schürmann
* Martin Soethe
* Patrik Schönfeldt
* Pierre-François Duc
Expand Down
6 changes: 6 additions & 0 deletions docs/examples/solph.examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Balanced and unbalanced storage
.. automodule:: storage_balanced_unbalanced.storage


Cellular modelling
------------------

.. automodule:: cellular.cellular


Electrical
----------

Expand Down
125 changes: 125 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,131 @@ Besides the `invest` variable, new variables are introduced as well. These are:
monthly periods, but you would need to be very careful in parameterizing your energy system and your model and also,
this would mean monthly discounting (if applicable) as well as specifying your plants lifetimes in months.
Modelling cellular energy systems and modularizing energy system models
-----------------------------------------------------------------------
The cellular approach is a concept proposed by the [VDE-ETG](https://shop.vde.com/en/vde-study-the-cellular-approach). It is
related to smart-grids and multi-microgrid systems but extends both. The idea is to group the components of an energy system
into a hierarchically aggregating structure of cells. For example, the sources, sinks, storages and converters of a household
could be a single cell. Then a group of physically neighboring households could form another cell, consisting of household-cells.
This behaviour can be scaled up. The real game-changer in the cellular approach is the way the cells are operated, which will
not be covered here. Here, we focus on the way such cellular energy systems can be modeled.
So far, the implementation in solph is just a neat way to group different parts of a larger energy system into cells. However,
the implementation can also be regarded as a precursor for further functionality. Decomposition techniques such
as [Benders](https://en.wikipedia.org/wiki/Benders_decomposition) or
[Dantzig-Wolfe](https://en.wikipedia.org/wiki/Dantzig%E2%80%93Wolfe_decomposition) could be implemented in solph. These methods
are dependent on a special constraint matrix structure, which the cellular modelling approach presented here is helping to obtain.
Modelling procedure
^^^^^^^^^^^^^^^^^^^
Similar to the creation of regular energy systems, the creation of energy cells is the first step in model creation. Essentially,
each energy cell is just an energy system, therefore we use the class :py:class:`oemof.solph.EnergySystem` to create energy cells.
.. code-block:: python
from oemof.solph import EnergySystem
es = EnergySystem(
label="es", timeindex=timeindex, infer_last_interval=False
)
ec_1 = EnergySystem(
label="ec_1", timeindex=timeindex, infer_last_interval=False
)
ec_2 = EnergySystem(
label="ec_2", timeindex=timeindex, inver_last_interval=False
)
Now we can go on and add components to the energy cells just like we do with regular energy systems.
.. code-block:: python
from oemof import solph
bus_el_es = solph.buses.Bus(label="bus_el_es")
es.add(bus_el_es)
bus_el_ec_1 = solph.buses.Bus(label="bus_el_ec_1")
sink_el_ec_1 = solph.components.Sink(
label="sink_el_ec_1",
inputs={bus_el_ec_1: flows.Flow(fix=10, nominal_value=1)},
)
source_el_ec_1 = solph.components.Source(
label="source_el_ec_1",
outputs={
bus_el_ec_1: flows.Flow(
max=30, nominal_value=1, variable_costs=10,
),
},
)
ec_1.add(bus_el_ec_1, sink_el_ec_1, source_el_ec_1)
.. note:: This is just an exemplary piece of code. A (little bit more interesting) working
example can be found in the examples.
The next step would be to model the connections between cells. Here, we resort to the class
:py:class:`oemof.solph.components.Link`. Each connection Link has two inputs (from the
"parent cell" and the "child cell") and two outputs (to the "parent cell" and the "child
cell"). A connection between the "parent cell" `es` and the "child cell" `ec_1` could look
like this:
.. code-block:: python
connector_el_ec_1 = solph.buses.Bus(
label="connector_el_ec_1",
inputs={
bus_el_es: flows.Flow(),
bus_el_ec_1: flows.Flow(),
},
outputs={
bus_el_es: flows.Flow(),
bus_el_ec_1: flows.Flow(),
},
conversion_factors={
(bus_el_es, bus_el_ec_1): 0.85,
(bus_el_ec_1, bus_el_es): 0.85
}
)
es.add(connector_el_ec_1)
The `conversion_factors` can be used to model transmission losses. Here, a symmetrical
loss of 15% is assumed.
All connection Links are added to the upmost energy cell.
.. note:: Note that we do not add the energy cells as components to their parent cells!
Instead, the hierarchical structure is flattened and all connections between the cells
are created as depicted above.
The last step is to create (and solve) the model. Again, this is fairly similar to the
regular model creation. However, instead of passing just one instance of
:py:class:`oemof.solph.EnergySystem`, a list of energy systems is passed.
.. warning::
By convention the first element of the list is assumed to be the upmost energy cell.
The ordering afterwards does not play a role.
.. note:: The resulting model is monolithic. This means that all components of all energy
cells are actually grouped into one pyomo model. It would, therefore, also be possible
to model all the components in one :py:class:`oemof.solph.EnergySystem` instance and
the results would be identical.
.. code-block:: python
cmodel = Model(
energysystem=[es, ec_1, ec_2, ...]
)
cmodel.solve()
As pointed out above, the resulting model is monolithic. Nonetheless, this modelling approach
holds some benefits:
* Better overview through segmentation of the energy system
* (Facilitated) opportunity to model cellular energy systems where the energy exchanged between cells
is of interest
* Segmentation of the energy system is a necessary precursor for distributed optimization via Dantzig-Wolfe
Mixed Integer (Linear) Problems
-------------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/whatsnew/v0-5-1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ New features
* Include discounting and calculating annuities in the objective function terms. Introduce attribute `discount_rate`
of :class:`oemof.solph.models.Model` and `interest_rate` for individual investment objects (options.Investment).
* Add `storage_level_constraint` that allows to set flows from/to storage (in)active based on storage content.
* `Model` now accepts a list of `EnergySystem` objects, which allows for modelling of cellular energysystems.

Documentation
#############
Expand Down

0 comments on commit 1cee273

Please sign in to comment.