Completed
Push — dev ( 93e34e...2bb17a )
by Patrik
19s queued 11s
created

NonConvexFlowBlock._create_variables()   A

Complexity

Conditions 4

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 34
rs 9.55
c 0
b 0
f 0
cc 4
nop 1
1
# -*- coding: utf-8 -*-
2
3
"""Creating sets, variables, constraints and parts of the objective function
4
for Flow objects with nonconvex but without investment options.
5
6
SPDX-FileCopyrightText: Uwe Krien <[email protected]>
7
SPDX-FileCopyrightText: Simon Hilpert
8
SPDX-FileCopyrightText: Cord Kaldemeyer
9
SPDX-FileCopyrightText: Patrik Schönfeldt
10
SPDX-FileCopyrightText: Birgit Schachler
11
SPDX-FileCopyrightText: jnnr
12
SPDX-FileCopyrightText: jmloenneberga
13
SPDX-FileCopyrightText: Johannes Kochems
14
15
SPDX-License-Identifier: MIT
16
17
"""
18
19
from pyomo.core import Binary
20
from pyomo.core import Constraint
21
from pyomo.core import Expression
22
from pyomo.core import NonNegativeReals
23
from pyomo.core import Set
24
from pyomo.core import Var
25
from pyomo.core.base.block import ScalarBlock
26
27
from . import _shared
28
29
30
class NonConvexFlowBlock(ScalarBlock):
31
    r"""
32
    .. automethod:: _create_constraints
33
    .. automethod:: _create_variables
34
    .. automethod:: _create_sets
35
36
    .. automethod:: _objective_expression
37
38
    Parameters are defined in :class:`Flow`.
39
    """
40
41
    def __init__(self, *args, **kwargs):
42
        super().__init__(*args, **kwargs)
43
44
    def _create(self, group=None):
45
        """Creates set, variables, constraints for all flow object with
46
        an attribute flow of type class:`.NonConvexFlowBlock`.
47
48
        Parameters
49
        ----------
50
        group : list
51
            List of oemof.solph.NonConvexFlowBlock objects for which
52
            the constraints are build.
53
        """
54
        if group is None:
55
            return None
56
57
        self._create_sets(group)
58
        self._create_variables()
59
        self._create_constraints()
60
61
    def _create_sets(self, group):
62
        r"""
63
        **The following sets are created:** (-> see basic sets at
64
        :class:`.Model` )
65
66
        FIXED_CAPACITY_NONCONVEX_FLOWS
67
            A set of flows with the attribute `nonconvex` of type
68
            :class:`.options.NonConvex`.
69
70
        Also creates everything listed in `_sets_for_non_convex_flows`.
71
        """
72
        self.FIXED_CAPACITY_NONCONVEX_FLOWS = Set(
73
            initialize=[(g[0], g[1]) for g in group]
74
        )
75
76
        _shared.sets_for_non_convex_flows(self, group)
77
78
    def _create_variables(self):
79
        r"""
80
        :math:`Y_{status}` (binary) `om.NonConvexFlowBlock.status`:
81
            Variable indicating if flow is >= 0
82
83
        :math:`P_{max,status}` Status_nominal (continuous)
84
            Variable indicating if flow is >= 0
85
86
        Also creates :py:func:`_variables_for_non_convex_flows`.
87
        """
88
        m = self.parent_block()
89
        self.status = Var(
90
            self.FIXED_CAPACITY_NONCONVEX_FLOWS, m.TIMESTEPS, within=Binary
91
        )
92
        for o, i in self.FIXED_CAPACITY_NONCONVEX_FLOWS:
93
            if m.flows[o, i].nonconvex.initial_status is not None:
94
                for t in range(
95
                    0, m.flows[o, i].nonconvex.first_flexible_timestep
96
                ):
97
                    self.status[o, i, t] = m.flows[
98
                        o, i
99
                    ].nonconvex.initial_status
100
                    self.status[o, i, t].fix()
101
102
        # `status_nominal` is a parameter which represents the
103
        # multiplication of a binary variable (`status`)
104
        # and a continuous variable (`invest` or `nominal_capacity`)
105
        self.status_nominal = Var(
106
            self.FIXED_CAPACITY_NONCONVEX_FLOWS,
107
            m.TIMESTEPS,
108
            within=NonNegativeReals,
109
        )
110
111
        _shared.variables_for_non_convex_flows(self)
112
113
    def _create_constraints(self):
114
        """
115
        The following constraints are created:
116
117
        .. automethod:: _status_nominal_constraint
118
119
        Also creates: :py:func:`_minimum_flow_constraint`,
120
        :py:func:`_maximum_flow_constraint`, and
121
        :py:func:`_shared_constraints_for_non_convex_flows`.
122
123
        """
124
125
        self.status_nominal_constraint = self._status_nominal_constraint()
126
        self.min = _shared.minimum_flow_constraint(self)
127
        self.max = _shared.maximum_flow_constraint(self)
128
129
        _shared.shared_constraints_for_non_convex_flows(self)
130
131
    def _objective_expression(self):
132
        r"""
133
        The following terms are to the cost function:
134
135
        * :py:func:`_startup_costs`
136
        * :py:func:`_shutdown_costs`
137
        * :py:func:`_activity_costs`
138
        * :py:func:`_inactivity_costs`
139
        """
140
        if not hasattr(self, "FIXED_CAPACITY_NONCONVEX_FLOWS"):
141
            return 0
142
143
        startup_costs = _shared.startup_costs(self)
144
        shutdown_costs = _shared.shutdown_costs(self)
145
        activity_costs = _shared.activity_costs(self)
146
        inactivity_costs = _shared.inactivity_costs(self)
147
148
        self.activity_costs = Expression(expr=activity_costs)
149
        self.inactivity_costs = Expression(expr=inactivity_costs)
150
        self.startup_costs = Expression(expr=startup_costs)
151
        self.shutdown_costs = Expression(expr=shutdown_costs)
152
153
        self.costs = Expression(
154
            expr=(
155
                startup_costs
156
                + shutdown_costs
157
                + activity_costs
158
                + inactivity_costs
159
            )
160
        )
161
162
        return self.costs
163
164
    def _status_nominal_constraint(self):
165
        r"""
166
        .. math::
167
            P_{max,status}(t) =  Y_{status}(t) \cdot P_{nom}, \\
168
            \forall t \in \textrm{TIMESTEPS}.
169
        """
170
        m = self.parent_block()
171
172
        def _status_nominal_rule(_, i, o, t):
173
            """Rule definition for status_nominal"""
174
            expr = (
175
                self.status_nominal[i, o, t]
176
                == self.status[i, o, t] * m.flows[i, o].nominal_capacity
177
            )
178
            return expr
179
180
        return Constraint(
181
            self.FIXED_CAPACITY_NONCONVEX_FLOWS,
182
            m.TIMESTEPS,
183
            rule=_status_nominal_rule,
184
        )
185