Completed
Push — dev ( 468d85...f4c061 )
by Patrik
23s queued 17s
created

add_constraints.main()   B

Complexity

Conditions 6

Size

Total Lines 105
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 56
dl 0
loc 105
rs 7.5066
c 0
b 0
f 0
cc 6
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# -*- coding: utf-8 -*-
2
3
"""
4
General description
5
-------------------
6
This script shows how to add an individual constraint to the oemof solph
7
OperationalModel.
8
The constraint we add forces a flow to be greater or equal a certain share
9
of all inflows of its target bus. Moreover we will set an emission constraint.
10
11
Code
12
----
13
Download source code: :download:`add_constraints.py </../examples/flexible_modelling/add_constraints.py>`
14
15
.. dropdown:: Click to display code
16
17
    .. literalinclude:: /../examples/flexible_modelling/add_constraints.py
18
        :language: python
19
        :lines: 41-158
20
21
Installation requirements
22
-------------------------
23
This example requires oemof.solph (v0.5.x), install by:
24
25
.. code:: bash
26
27
    pip install oemof.solph[examples]
28
29
To draw the graph pygraphviz is required, installed by:
30
31
.. code:: bash
32
33
    pip install pygraphviz
34
35
License
36
-------
37
Simon Hilpert - 31.10.2016 - [email protected]
38
39
`MIT license <https://github.com/oemof/oemof-solph/blob/dev/LICENSE>`_
40
"""
41
import logging
42
43
import pandas as pd
44
import pyomo.environ as po
45
46
from oemof.solph import Bus
47
from oemof.solph import EnergySystem
48
from oemof.solph import Flow
49
from oemof.solph import Model
50
from oemof.solph import components as cmp
51
52
53
def main(solver="cbc", nologg=False, optimize=True):
54
    if not nologg:
55
        logging.basicConfig(level=logging.INFO)
56
    # ##### creating an oemof solph optimization model, nothing special here ##
57
    # create an energy system object for the oemof solph nodes
58
    es = EnergySystem(
59
        timeindex=pd.date_range("1/1/2017", periods=5, freq="h"),
60
        infer_last_interval=False,
61
    )
62
    # add some nodes
63
64
    boil = Bus(label="oil", balanced=False)
65
    blig = Bus(label="lignite", balanced=False)
66
    b_el = Bus(label="b_el")
67
68
    es.add(boil, blig, b_el)
69
70
    sink = cmp.Sink(
71
        label="Sink",
72
        inputs={b_el: Flow(nominal_capacity=40, fix=[0.5, 0.4, 0.3, 1])},
73
    )
74
    pp_oil = cmp.Converter(
75
        label="pp_oil",
76
        inputs={boil: Flow()},
77
        outputs={b_el: Flow(nominal_capacity=50, variable_costs=25)},
78
        conversion_factors={b_el: 0.39},
79
    )
80
    pp_lig = cmp.Converter(
81
        label="pp_lig",
82
        inputs={blig: Flow()},
83
        outputs={b_el: Flow(nominal_capacity=50, variable_costs=10)},
84
        conversion_factors={b_el: 0.41},
85
    )
86
87
    es.add(sink, pp_oil, pp_lig)
88
89
    if optimize is False:
90
        return es
91
92
    # create the model
93
    om = Model(energysystem=es)
94
95
    # add specific emission values to flow objects if source is a commodity bus
96
    for s, t in om.flows.keys():
97
        if s is boil:
98
            om.flows[s, t].emission_factor = 0.27  # t/MWh
99
        if s is blig:
100
            om.flows[s, t].emission_factor = 0.39  # t/MWh
101
    emission_limit = 60e3
102
103
    # add the outflow share
104
    om.flows[(boil, pp_oil)].outflow_share = [1, 0.5, 0, 0.3]
105
106
    # Now we are going to add a 'sub-model' and add a user specific constraint
107
    # first we add a pyomo Block() instance that we can use to add our
108
    # constraints. Then, we add this Block to our previous defined
109
    # Model instance and add the constraints.
110
    myblock = po.Block()
111
112
    # create a pyomo set with the flows (i.e. list of tuples),
113
    # there will of course be only one flow inside this set, the one we used to
114
    # add outflow_share
115
    myblock.MYFLOWS = po.Set(
116
        initialize=[
117
            k for (k, v) in om.flows.items() if hasattr(v, "outflow_share")
118
        ]
119
    )
120
121
    # pyomo does not need a po.Set, we can use a simple list as well
122
    myblock.COMMODITYFLOWS = [
123
        k for (k, v) in om.flows.items() if hasattr(v, "emission_factor")
124
    ]
125
126
    # add the sub-model to the oemof Model instance
127
    om.add_component("MyBlock", myblock)
128
129
    def _inflow_share_rule(m, s, e, t):
130
        """pyomo rule definition: Here we can use all objects from the block or
131
        the om object, in this case we don't need anything from the block
132
        except the newly defined set MYFLOWS.
133
        """
134
        expr = om.flow[s, e, t] >= om.flows[s, e].outflow_share[t] * sum(
0 ignored issues
show
introduced by
The variable om does not seem to be defined for all execution paths.
Loading history...
135
            om.flow[i, o, t] for (i, o) in om.FLOWS if o == e
136
        )
137
        return expr
138
139
    myblock.inflow_share = po.Constraint(
140
        myblock.MYFLOWS, om.TIMESTEPS, rule=_inflow_share_rule
141
    )
142
    # add emission constraint
143
    myblock.emission_constr = po.Constraint(
144
        expr=(
145
            sum(
146
                om.flow[i, o, t]
147
                for (i, o) in myblock.COMMODITYFLOWS
148
                for t in om.TIMESTEPS
149
            )
150
            <= emission_limit
151
        )
152
    )
153
154
    # solve and write results to dictionary
155
    # you may print the model with om.pprint()
156
    om.solve(solver=solver)
157
    logging.info("Successfully finished.")
158
159
160
if __name__ == "__main__":
161
    main()
162