Skip to content

Commit

Permalink
Merge pull request #1077 from oemof/revision/refine_timeindex
Browse files Browse the repository at this point in the history
Refine time index of Flows
  • Loading branch information
p-snft authored Jun 24, 2024
2 parents 155cc70 + 1b26471 commit f2b40f9
Show file tree
Hide file tree
Showing 168 changed files with 12,278 additions and 12,324 deletions.
1 change: 1 addition & 0 deletions docs/whatsnew/v0-5-3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Other changes

* Unified (usage) documentation for `OffsetConverter`
* Remove approach to model cellular systems (was more confusing than it helped)
* Refine indexing of flows (period index was not needed).

Known issues
############
Expand Down
12 changes: 6 additions & 6 deletions examples/flexible_modelling/add_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,26 +123,26 @@ def run_add_constraints_example(solver="cbc", nologg=False):
# add the sub-model to the oemof Model instance
om.add_component("MyBlock", myblock)

def _inflow_share_rule(m, s, e, p, t):
def _inflow_share_rule(m, s, e, t):
"""pyomo rule definition: Here we can use all objects from the block or
the om object, in this case we don't need anything from the block
except the newly defined set MYFLOWS.
"""
expr = om.flow[s, e, p, t] >= om.flows[s, e].outflow_share[t] * sum(
om.flow[i, o, p, t] for (i, o) in om.FLOWS if o == e
expr = om.flow[s, e, t] >= om.flows[s, e].outflow_share[t] * sum(
om.flow[i, o, t] for (i, o) in om.FLOWS if o == e
)
return expr

myblock.inflow_share = po.Constraint(
myblock.MYFLOWS, om.TIMEINDEX, rule=_inflow_share_rule
myblock.MYFLOWS, om.TIMESTEPS, rule=_inflow_share_rule
)
# add emission constraint
myblock.emission_constr = po.Constraint(
expr=(
sum(
om.flow[i, o, p, t]
om.flow[i, o, t]
for (i, o) in myblock.COMMODITYFLOWS
for p, t in om.TIMEINDEX
for t in om.TIMESTEPS
)
<= emission_limit
)
Expand Down
24 changes: 12 additions & 12 deletions src/oemof/solph/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,33 +461,33 @@ def _add_parent_block_sets(self):
def _add_parent_block_variables(self):
"""Add the parent block variables, which is the `flow` variable,
indexed by FLOWS and TIMEINDEX."""
self.flow = po.Var(self.FLOWS, self.TIMEINDEX, within=po.Reals)
self.flow = po.Var(self.FLOWS, self.TIMESTEPS, within=po.Reals)

for o, i in self.FLOWS:
if self.flows[o, i].nominal_value is not None:
if self.flows[o, i].fix[self.TIMESTEPS.at(1)] is not None:
for p, t in self.TIMEINDEX:
self.flow[o, i, p, t].value = (
for t in self.TIMESTEPS:
self.flow[o, i, t].value = (
self.flows[o, i].fix[t]
* self.flows[o, i].nominal_value
)
self.flow[o, i, p, t].fix()
self.flow[o, i, t].fix()
else:
for p, t in self.TIMEINDEX:
self.flow[o, i, p, t].setub(
for t in self.TIMESTEPS:
self.flow[o, i, t].setub(
self.flows[o, i].max[t]
* self.flows[o, i].nominal_value
)
if not self.flows[o, i].nonconvex:
for p, t in self.TIMEINDEX:
self.flow[o, i, p, t].setlb(
for t in self.TIMESTEPS:
self.flow[o, i, t].setlb(
self.flows[o, i].min[t]
* self.flows[o, i].nominal_value
)
elif (o, i) in self.UNIDIRECTIONAL_FLOWS:
for p, t in self.TIMEINDEX:
self.flow[o, i, p, t].setlb(0)
for t in self.TIMESTEPS:
self.flow[o, i, t].setlb(0)
else:
if (o, i) in self.UNIDIRECTIONAL_FLOWS:
for p, t in self.TIMEINDEX:
self.flow[o, i, p, t].setlb(0)
for t in self.TIMESTEPS:
self.flow[o, i, t].setlb(0)
30 changes: 15 additions & 15 deletions src/oemof/solph/buses/_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ class BusBlock(ScalarBlock):
Bus balance: `om.Bus.balance[i, o, t]`
.. math::
\sum_{i \in INPUTS(n)} P_{i}(p, t) =
\sum_{o \in OUTPUTS(n)} P_{o}(p, t), \\
\forall p, t \in \textrm{TIMEINDEX}, \\
\sum_{i \in INPUTS(n)} P_{i}(t) =
\sum_{o \in OUTPUTS(n)} P_{o}(t), \\
\forall t \in \textrm{TIMESTEPS}, \\
\forall i \in \textrm{INPUTS}, \\
\forall o \in \textrm{OUTPUTS}
Expand All @@ -89,17 +89,17 @@ class BusBlock(ScalarBlock):
output of the Bus object.
The index :math:`n` is the index for the Bus node itself. Therefore,
a :math:`flow[i, n, p, t]` is a flow from the Component i to the Bus n at
a :math:`flow[i, n, t]` is a flow from the Component i to the Bus n at
time index p, t.
====================== ============================ ====================
symbol attribute explanation
====================== ============================ ====================
:math:`P_{i}(p, t)` `flow[i, n, p, t]` Bus, inflow
====================== ========================= ====================
symbol attribute explanation
====================== ========================= ====================
:math:`P_{i}(p, t)` `flow[i, n, t]` Bus, inflow
:math:`P_{o}(p, t)` `flow[n, o, p, t]` Bus, outflow
:math:`P_{o}(p, t)` `flow[n, o, t]` Bus, outflow
====================== ============================ ====================
====================== ========================= ====================
"""

def __init__(self, *args, **kwargs):
Expand All @@ -126,14 +126,14 @@ def _create(self, group=None):
outs[n] = [o for o in n.outputs]

def _busbalance_rule(block):
for p, t in m.TIMEINDEX:
for t in m.TIMESTEPS:
for g in group:
lhs = sum(m.flow[i, g, p, t] for i in ins[g])
rhs = sum(m.flow[g, o, p, t] for o in outs[g])
lhs = sum(m.flow[i, g, t] for i in ins[g])
rhs = sum(m.flow[g, o, t] for o in outs[g])
expr = lhs == rhs
# no inflows no outflows yield: 0 == 0 which is True
if expr is not True:
block.balance.add((g, p, t), expr)
block.balance.add((g, t), expr)

self.balance = Constraint(group, m.TIMEINDEX, noruleinit=True)
self.balance = Constraint(group, m.TIMESTEPS, noruleinit=True)
self.balance_build = BuildAction(rule=_busbalance_rule)
24 changes: 12 additions & 12 deletions src/oemof/solph/components/_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ class ConverterBlock(ScalarBlock):
Linear relation :attr:`om.ConverterBlock.relation[i,o,t]`
.. math::
P_{i}(p, t) \cdot \eta_{o}(t) =
P_{o}(p, t) \cdot \eta_{i}(t), \\
\forall p, t \in \textrm{TIMEINDEX}, \\
P_{i}(t) \cdot \eta_{o}(t) =
P_{o}(t) \cdot \eta_{i}(t), \\
\forall t \in \textrm{TIMESTEPS}, \\
\forall n \in \textrm{CONVERTERS}, \\
\forall i \in \textrm{INPUTS}, \\
\forall o \in \textrm{OUTPUTS}
Expand All @@ -196,15 +196,15 @@ class ConverterBlock(ScalarBlock):
constraints.
The index :math: n is the index for the Transformer node itself. Therefore,
a `flow[i, n, p, t]` is a flow from the Bus i to the Transformer n at
a `flow[i, n, t]` is a flow from the Bus i to the Transformer n at
time index p, t.
====================== ============================ ====================
symbol attribute explanation
====================== ============================ ====================
:math:`P_{i,n}(p, t)` `flow[i, n, p, t]` Converter, inflow
:math:`P_{i,n}(p, t)` `flow[i, n, t]` Converter, inflow
:math:`P_{n,o}(p, t)` `flow[n, o, p, t]` Converter, outflow
:math:`P_{n,o}(p, t)` `flow[n, o, t]` Converter, outflow
:math:`\eta_{i}(t)` `conversion_factor[i, n, t]` Inflow, efficiency
Expand Down Expand Up @@ -243,8 +243,8 @@ def _create(self, group=None):

self.relation = Constraint(
[
(n, i, o, p, t)
for p, t in m.TIMEINDEX
(n, i, o, t)
for t in m.TIMESTEPS
for n in group
for o in out_flows[n]
for i in in_flows[n]
Expand All @@ -253,17 +253,17 @@ def _create(self, group=None):
)

def _input_output_relation(block):
for p, t in m.TIMEINDEX:
for t in m.TIMESTEPS:
for n in group:
for o in out_flows[n]:
for i in in_flows[n]:
try:
lhs = (
m.flow[i, n, p, t]
m.flow[i, n, t]
* n.conversion_factors[o][t]
)
rhs = (
m.flow[n, o, p, t]
m.flow[n, o, t]
* n.conversion_factors[i][t]
)
except ValueError:
Expand All @@ -273,6 +273,6 @@ def _input_output_relation(block):
n.label, o.label
),
)
block.relation.add((n, i, o, p, t), (lhs == rhs))
block.relation.add((n, i, o, t), (lhs == rhs))

self.relation_build = BuildAction(rule=_input_output_relation)
28 changes: 14 additions & 14 deletions src/oemof/solph/components/_extraction_turbine_chp.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,17 @@ class ExtractionTurbineCHPBlock(ScalarBlock):
* :math:`\dot H_{Fuel}`
Fuel input flow, represented in code as `flow[i, n, p, t]`
Fuel input flow, represented in code as `flow[i, n, t]`
* :math:`P_{el}`
Electric power outflow, represented in code as
`flow[n, main_output, p, t]`
`flow[n, main_output, t]`
* :math:`\dot Q_{th}`
Thermal output flow, represented in code as
`flow[n, tapped_output, p, t]`
`flow[n, tapped_output, t]`
**Parameters**
Expand Down Expand Up @@ -242,36 +242,36 @@ def _create(self, group=None):

def _input_output_relation_rule(block):
"""Connection between input, main output and tapped output."""
for p, t in m.TIMEINDEX:
for t in m.TIMESTEPS:
for g in group:
lhs = m.flow[g.inflow, g, p, t]
lhs = m.flow[g.inflow, g, t]
rhs = (
m.flow[g, g.main_output, p, t]
+ m.flow[g, g.tapped_output, p, t]
m.flow[g, g.main_output, t]
+ m.flow[g, g.tapped_output, t]
* g.main_flow_loss_index[t]
) / g.conversion_factor_full_condensation_sq[t]
block.input_output_relation.add((g, p, t), (lhs == rhs))
block.input_output_relation.add((g, t), (lhs == rhs))

self.input_output_relation = Constraint(
group, m.TIMEINDEX, noruleinit=True
group, m.TIMESTEPS, noruleinit=True
)
self.input_output_relation_build = BuildAction(
rule=_input_output_relation_rule
)

def _out_flow_relation_rule(block):
"""Relation between main and tapped output in full chp mode."""
for p, t in m.TIMEINDEX:
for t in m.TIMESTEPS:
for g in group:
lhs = m.flow[g, g.main_output, p, t]
lhs = m.flow[g, g.main_output, t]
rhs = (
m.flow[g, g.tapped_output, p, t]
m.flow[g, g.tapped_output, t]
* g.flow_relation_index[t]
)
block.out_flow_relation.add((g, p, t), (lhs >= rhs))
block.out_flow_relation.add((g, t), (lhs >= rhs))

self.out_flow_relation = Constraint(
group, m.TIMEINDEX, noruleinit=True
group, m.TIMESTEPS, noruleinit=True
)
self.out_flow_relation_build = BuildAction(
rule=_out_flow_relation_rule
Expand Down
18 changes: 9 additions & 9 deletions src/oemof/solph/components/_generic_chp.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,37 +338,37 @@ def _create(self, group=None):
self.Y = Var(self.GENERICCHPS, m.TIMESTEPS, within=Binary)

# constraint rules
def _H_flow_rule(block, n, p, t):
def _H_flow_rule(block, n, t):
"""Link fuel consumption to component inflow."""
expr = 0
expr += self.H_F[n, t]
expr += -m.flow[list(n.fuel_input.keys())[0], n, p, t]
expr += -m.flow[list(n.fuel_input.keys())[0], n, t]
return expr == 0

self.H_flow = Constraint(
self.GENERICCHPS, m.TIMEINDEX, rule=_H_flow_rule
self.GENERICCHPS, m.TIMESTEPS, rule=_H_flow_rule
)

def _Q_flow_rule(block, n, p, t):
def _Q_flow_rule(block, n, t):
"""Link heat flow to component outflow."""
expr = 0
expr += self.Q[n, t]
expr += -m.flow[n, list(n.heat_output.keys())[0], p, t]
expr += -m.flow[n, list(n.heat_output.keys())[0], t]
return expr == 0

self.Q_flow = Constraint(
self.GENERICCHPS, m.TIMEINDEX, rule=_Q_flow_rule
self.GENERICCHPS, m.TIMESTEPS, rule=_Q_flow_rule
)

def _P_flow_rule(block, n, p, t):
def _P_flow_rule(block, n, t):
"""Link power flow to component outflow."""
expr = 0
expr += self.P[n, t]
expr += -m.flow[n, list(n.electrical_output.keys())[0], p, t]
expr += -m.flow[n, list(n.electrical_output.keys())[0], t]
return expr == 0

self.P_flow = Constraint(
self.GENERICCHPS, m.TIMEINDEX, rule=_P_flow_rule
self.GENERICCHPS, m.TIMESTEPS, rule=_P_flow_rule
)

def _H_F_1_rule(block, n, t):
Expand Down
Loading

0 comments on commit f2b40f9

Please sign in to comment.