oemof.solph.Flow

Flow

solph version of oemof.network.Edge including base constraints

class oemof.solph.flows._flow.Flow(**kwargs)[source]

Bases: oemof.network.network.Edge

Defines a flow between two nodes.

Keyword arguments are used to set the attributes of this flow. Parameters which are handled specially are noted below. For the case where a parameter can be either a scalar or an iterable, a scalar value will be converted to a sequence containing the scalar value at every index. This sequence is then stored under the paramter’s key.

Parameters:
  • nominal_value (numeric, \(P_{nom}\)) – The nominal value of the flow. If this value is set the corresponding optimization variable of the flow object will be bounded by this value multiplied with min(lower bound)/max(upper bound).

  • max (numeric (iterable or scalar), \(f_{max}\)) – Normed maximum value of the flow. The flow absolute maximum will be calculated by multiplying nominal_value with max

  • min (numeric (iterable or scalar), \(f_{min}\)) – Normed minimum value of the flow (see max).

  • fix (numeric (iterable or scalar), \(f_{fix}\)) – Normed fixed value for the flow variable. Will be multiplied with the nominal_value to get the absolute value.

  • positive_gradient (dict, default: {‘ub’: None}) –

    A dictionary containing the following key:

    • ‘ub’: numeric (iterable, scalar or None), the normed upper bound on the positive difference (flow[t-1] < flow[t]) of two consecutive flow values.
  • negative_gradient (dict, default: {‘ub’: None}) –

    A dictionary containing the following key:

    • ‘ub’: numeric (iterable, scalar or None), the normed upper bound on the negative difference (flow[t-1] > flow[t]) of two consecutive flow values.
  • full_load_time_max (numeric, \(t_{full\_load,max}\)) – Upper bound on the summed flow expressed as the equivalent time that the flow would have to run at full capacity to yield the same sum. The value will be multiplied with the nominal_value to get the absolute limit.

  • full_load_time_min (numeric, \(t_{full\_load,min}\)) – Lower bound on the summed flow expressed as the equivalent time that the flow would have to run at full capacity to yield the same sum. The value will be multiplied with the nominal_value to get the absolute limit.

  • variable_costs (numeric (iterable or scalar)) – The costs associated with one unit of the flow. If this is set the costs will be added to the objective expression of the optimization problem.

  • fixed (boolean) – Boolean value indicating if a flow is fixed during the optimization problem to its ex-ante set value. Used in combination with the fix.

  • integer (boolean) – Set True to bound the flow values to integers.

  • investment (Investment) – Object indicating if a nominal_value of the flow is determined by the optimization problem. Note: This will refer all attributes to an investment variable rather than to the nominal_value. The nominal_value should not be set (or set to None) if an investment object is used.

  • nonconvex (NonConvex) – If a nonconvex flow object is added here, the flow constraints will be altered significantly as the mathematical model for the flow will be different, i.e. constraint etc. from NonConvexFlowBlock will be used instead of SimpleFlowBlock.

Notes

See SimpleFlowBlock for the variables, constraints and objective parts, that are created for a Flow object.

Examples

Creating a fixed flow object:

>>> f = Flow(nominal_value=2, fix=[10, 4, 4], variable_costs=5)
>>> f.variable_costs[2]
5
>>> f.fix[2]
4

Creating a flow object with time-depended lower and upper bounds:

>>> f1 = Flow(min=[0.2, 0.3], max=0.99, nominal_value=100)
>>> f1.max[1]
0.99

SimpleFlow

solph version of oemof.network.Edge including base constraints

class oemof.solph.flows._simple_flow_block.SimpleFlowBlock(*args, **kwargs)[source]

Bases: pyomo.core.base.block.ScalarBlock

Flow block with definitions for standard flows.

See Flow class for all parameters of the Flow.

Variables

All Flow objects are indexed by a starting and ending node \((i, o)\), which is omitted in the following for the sake of convenience. The creation of some variables depend on the values of Flow attributes. The following variables are created:

  • \(P(t)\)

    Actual flow value (created in Model). The variable is bound to: \(f_\mathrm{min}(t) \cdot P_\mathrm{nom} \le P(t) \le f_\mathrm{max}(t) \cdot P_\mathrm{nom}\).

    If Flow.fix is not None the variable is bound to \(P(t) = f_\mathrm{fix}(t) \cdot P_\mathrm{nom}\).

  • \(ve_n\) (Flow.negative_gradient is not None)

    Difference of a flow in consecutive timesteps if flow is reduced. The variable is bound to: \(0 \ge ve_n \ge ve_n^{max}\).

  • \(ve_p\) (Flow.positive_gradient is not None)

    Difference of a flow in consecutive timesteps if flow is increased. The variable is bound to: \(0 \ge ve_p \ge ve_p^{max}\).

The following variable is build for Flows with the attribute integer_flows being not None.

  • \(i\) (Flow.integer is True)
    All flow values are integers. Variable is bound to non-negative integers.

Constraints

The following constraints are created, if the appropriate attribute of the Flow (see Flow) object is set:

  • Flow.full_load_time_max is not None (full_load_time_max_constr):
    \[\sum_t P(t) \cdot \tau \leq F_{max} \cdot P_{nom}\]
  • Flow.full_load_time_min is not None (full_load_time_min_constr):
    \[\sum_t P(t) \cdot \tau \geq F_{min} \cdot P_{nom}\]
  • Flow.negative_gradient is not None (negative_gradient_constr):
    \[P(t-1) - P(t) \geq ve_n(t)\]
  • Flow.positive_gradient is not None (positive_gradient_constr):
    \[P(t) - P(t-1) \geq ve_p(t)\]
  • Flow.integer is True
    \[P(t) = i(t)\]

Objective function

Depending on the attributes of the Flow object the following parts of the objective function are created:

  • Flow.variable_costs is not None:
    \[\sum_{(i,o)} \sum_t P(t) \cdot c_{var}(i, o, t)\]
List of Variables
symbol attribute explanation
\(P(t)\) flow[i, o][t] Actual flow value
\(ve_n\) negative_gradient[n, o, t] Negative gradient of the flow
\(ve_p\) positive_gradient[n, o, t] Positive gradient of the flow
\(i\) integer_flow[i, o, t] Integer flow
List of Parameters
symbol attribute explanation
\(P_{nom}\) flows[i, o].nominal_value Nominal value of the flow
\(F_{max}\) flow[i, o].full_load_time_max Maximal full load time
\(F_{min}\) flow[i, o].full_load_time_min Minimal full load time
\(c_{var}\) variable_costs[t] Variable cost of the flow
\(f_{max}\) flows[i, o].max[t] Normed maximum value of the flow, the absolute maximum is \(f_{max} \cdot P_{nom}\)
\(f_{min}\) flows[i, o].min[t] Normed minimum value of the flow, the absolute minimum is \(f_{min} \cdot P_{nom}\)
\(f_{fix}\) flows[i, o].min[t] Normed fixed value of the flow, the absolute fixed value is \(f_{fix} \cdot P_{nom}\)
\(ve_n^{max}\) flows[i, o].negative_gradient Normed maximal negative gradient of the flow, the absolute maximum gradient is \(ve_n^{max} \cdot P_{nom}\)
\(ve_p^{max}\) flows[i, o].positive_gradient Normed maximal positive gradient of the flow, the absolute maximum gradient is \(ve_n^{max} \cdot P_{nom}\)

Note

See the Flow class for the definition of all parameters from the “List of Parameters above.

InvestmentFlow

Creating sets, variables, constraints and parts of the objective function for SimpleFlowBlock objects with investment option.

class oemof.solph.flows._investment_flow_block.InvestmentFlowBlock(*args, **kwargs)[source]

Bases: pyomo.core.base.block.ScalarBlock

Block for all flows with Investment being not None.

See oemof.solph.options.Investment for all parameters of the Investment class.

See oemof.solph.network.SimpleFlowBlock for all parameters of the SimpleFlowBlock class.

Variables

All InvestmentFlowBlock are indexed by a starting and ending node \((i, o)\), which is omitted in the following for the sake of convenience. The following variables are created:

  • \(P(t)\)

    Actual flow value (created in oemof.solph.models.BaseModel).

  • \(P_{invest}\)

    Value of the investment variable, i.e. equivalent to the nominal value of the flows after optimization.

  • \(b_{invest}\)

    Binary variable for the status of the investment, if nonconvex is True.

Constraints

Depending on the attributes of the InvestmentFlowBlock and SimpleFlowBlock, different constraints are created. The following constraint is created for all InvestmentFlowBlock:

Upper bound for the flow value
\[P(t) \le ( P_{invest} + P_{exist} ) \cdot f_{max}(t)\]

Depeding on the attribute nonconvex, the constraints for the bounds of the decision variable \(P_{invest}\) are different:

  • nonconvex = False
\[P_{invest, min} \le P_{invest} \le P_{invest, max}\]
  • nonconvex = True
\[\begin{split}& P_{invest, min} \cdot b_{invest} \le P_{invest}\\ & P_{invest} \le P_{invest, max} \cdot b_{invest}\\\end{split}\]

For all InvestmentFlowBlock (independent of the attribute nonconvex), the following additional constraints are created, if the appropriate attribute of the SimpleFlowBlock (see oemof.solph.network.SimpleFlowBlock) is set:

  • fix is not None

    Actual value constraint for investments with fixed flow values

\[P(t) = ( P_{invest} + P_{exist} ) \cdot f_{fix}(t)\]
  • min != 0

    Lower bound for the flow values

\[P(t) \geq ( P_{invest} + P_{exist} ) \cdot f_{min}(t)\]
  • full_load_time_max is not None

    Upper bound for the sum of all flow values (e.g. maximum full load hours)

\[\sum_t P(t) \cdot \tau(t) \leq ( P_{invest} + P_{exist} ) \cdot t_{full\_load, min}\]
  • full_load_time_min is not None

    Lower bound for the sum of all flow values (e.g. minimum full load hours)

\[\sum_t P(t) \cdot \tau(t) \geq ( P_{invest} + P_{exist} ) \cdot t_{full\_load, min}\]

Objective function

The part of the objective function added by the InvestmentFlowBlock also depends on whether a convex or nonconvex InvestmentFlowBlock is selected. The following parts of the objective function are created:

  • nonconvex = False

    \[P_{invest} \cdot c_{invest,var}\]
  • nonconvex = True

    \[\begin{split}P_{invest} \cdot c_{invest,var} + c_{invest,fix} \cdot b_{invest}\\\end{split}\]

The total value of all costs of all InvestmentFlowBlock can be retrieved calling om.InvestmentFlowBlock.investment_costs.expr().

List of Variables (in csv table syntax)
symbol attribute explanation
\(P(t)\) flow[n, o, t] Actual flow value
\(P_{invest}\) invest[i, o] Invested flow capacity
\(b_{invest}\) invest_status[i, o] Binary status of investment

List of Variables (in rst table syntax):

symbol attribute explanation
\(P(t)\) flow[n, o, t] Actual flow value
\(P_{invest}\) invest[i, o] Invested flow capacity
\(b_{invest}\) invest_status[i, o] Binary status of investment

Grid table style:

symbol attribute explanation
\(P(t)\) flow[n, o, t] Actual flow value
\(P_{invest}\) invest[i, o] Invested flow capacity
\(b_{invest}\) invest_status[i, o] Binary status of investment
List of Parameters
symbol attribute explanation
\(P_{exist}\) flows[i, o].investment.existing Existing flow capacity
\(P_{invest,min}\) flows[i, o].investment.minimum Minimum investment capacity
\(P_{invest,max}\) flows[i, o].investment.maximum Maximum investment capacity
\(c_{invest,var}\) flows[i, o].investment.ep_costs Variable investment costs
\(c_{invest,fix}\) flows[i, o].investment.offset Fix investment costs
\(f_{actual}\) flows[i, o].fix[t] Normed fixed value for the flow variable
\(f_{max}\) flows[i, o].max[t] Normed maximum value of the flow
\(f_{min}\) flows[i, o].min[t] Normed minimum value of the flow
\(t_{full\_load,max}\) flows[i, o].full_load_time_max Specific maximum of summed flow values (per installed capacity)
\(t_{full\_load,min}\) flows[i, o].full_load_time_min Specific minimum of summed flow values (per installed capacity)
\(\tau(t)\) timeincrement[t] Time step width for each time step

Note

In case of a nonconvex investment flow (nonconvex=True), the existing flow capacity \(P_{exist}\) needs to be zero. At least, it is not tested yet, whether this works out, or makes any sense at all.

Note

See also Flow, SimpleFlowBlock and Investment

NonConvexFlow

Creating sets, variables, constraints and parts of the objective function for nonconvex SimpleFlowBlock objects.

class oemof.solph.flows._non_convex_flow_block.NonConvexFlowBlock(*args, **kwargs)[source]

Bases: pyomo.core.base.block.ScalarBlock

_create_constraints()[source]

The following constraints are created:

_status_nominal_constraint()[source]
\[\begin{split}status\_nominal(i, o, t) = status(i, o, t) \cdot nominal\_value, \\ \forall (i, o) \in \textrm{NONCONVEX\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_minimum_flow_constraint()[source]
\[\begin{split}flow(i, o, t) \geq min(i, o, t) \cdot nominal\_value \ \cdot status(i, o, t), \\ \forall (i, o) \in \textrm{NONCONVEX\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_maximum_flow_constraint()[source]
\[\begin{split}flow(i, o, t) \leq max(i, o, t) \cdot nominal\_value \ \cdot status(i, o, t), \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall (i, o) \in \textrm{NONCONVEX\_FLOWS}.\end{split}\]
_shared_constraints_for_non_convex_flows()[source]
_startup_constraint()[source]
\[\begin{split}startup(i, o, t) \geq \ status(i,o,t) - status(i, o, t-1) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall (i,o) \in \textrm{STARTUPFLOWS}.\end{split}\]
_max_startup_constraint()[source]
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} startup(i, o, t) \leq \ N_{start}(i,o)\\ \forall (i,o) \in \textrm{MAXSTARTUPFLOWS}.\end{split}\]
_shutdown_constraint()[source]
\[\begin{split}shutdown(i, o, t) \geq \ status(i, o, t-1) - status(i, o, t) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall (i, o) \in \textrm{SHUTDOWNFLOWS}.\end{split}\]
_max_shutdown_constraint()[source]
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} startup(i, o, t) \leq \ N_{shutdown}(i,o)\\ \forall (i,o) \in \textrm{MAXSHUTDOWNFLOWS}.\end{split}\]
_min_uptime_constraint()[source]
\[\begin{split}(status(i, o, t)-status(i, o, t-1)) \cdot minimum\_uptime(i, o) \\ \leq \sum_{n=0}^{minimum\_uptime-1} status(i,o,t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..minimum\_uptime\} \cup \ \{t\_max-minimum\_uptime..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}. \\ \\ status(i, o, t) = initial\_status(i, o) \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..minimum\_uptime\} \cup \ \{t\_max-minimum\_uptime..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}.\end{split}\]
_min_downtime_constraint()[source]
\[\begin{split}(status(i, o, t-1)-status(i, o, t)) \ \cdot minimum\_downtime(i, o) \\ \leq minimum\_downtime(i, o) \ - \sum_{n=0}^{minimum\_downtime-1} status(i,o,t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..minimum\_downtime\} \cup \ \{t\_max-minimum\_downtime..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}. \\ \\ status(i, o, t) = initial\_status(i, o) \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..minimum\_downtime\} \cup \ \{t\_max-minimum\_downtime..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}.\end{split}\]
positive_gradient_constraint
\[\begin{split}flow(i, o, t) \cdot status(i, o, t) - flow(i, o, t-1) \cdot status(i, o, t-1) \geq \ positive\_gradient(i, o, t), \\ \forall (i, o) \in \textrm{POSITIVE\_GRADIENT\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
negative_gradient_constraint
\[\begin{split}flow(i, o, t-1) \cdot status(i, o, t-1) - flow(i, o, t) \cdot status(i, o, t) \geq \ negative\_gradient(i, o, t), \\ \forall (i, o) \in \textrm{NEGATIVE\_GRADIENT\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_create_variables()[source]
Status (binary) om.NonConvexFlowBlock.status:
Variable indicating if flow is >= 0
Status_nominal (continuous)
Variable indicating if flow is >= 0
_variables_for_non_convex_flows()[source]
Startup variable (binary) NonConvexFlowBlock.startup:
Variable indicating startup of flow (component) indexed by STARTUPFLOWS
Shutdown variable (binary) NonConvexFlowBlock.shutdown:
Variable indicating shutdown of flow (component) indexed by SHUTDOWNFLOWS
Positive gradient (continuous) NonConvexFlowBlock.positive_gradient:
Variable indicating the positive gradient, i.e. the load increase between two consecutive timesteps, indexed by POSITIVE_GRADIENT_FLOWS
Negative gradient (continuous) NonConvexFlowBlock.negative_gradient:
Variable indicating the negative gradient, i.e. the load decrease between two consecutive timesteps, indexed by NEGATIVE_GRADIENT_FLOWS
_create_sets(group)[source]

The following sets are created: (-> see basic sets at Model )

NONCONVEX_FLOWS
A set of flows with the attribute nonconvex of type options.NonConvex.
_sets_for_non_convex_flows(group)[source]
MIN_FLOWS
A subset of set NONCONVEX_FLOWS with the attribute min being not None in the first timestep.
ACTIVITYCOSTFLOWS
A subset of set NONCONVEX_FLOWS with the attribute activity_costs being not None.
INACTIVITYCOSTFLOWS
A subset of set NONCONVEX_FLOWS with the attribute inactivity_costs being not None.
STARTUPFLOWS
A subset of set NONCONVEX_FLOWS with the attribute maximum_startups or startup_costs being not None.
MAXSTARTUPFLOWS
A subset of set STARTUPFLOWS with the attribute maximum_startups being not None.
SHUTDOWNFLOWS
A subset of set NONCONVEX_FLOWS with the attribute maximum_shutdowns or shutdown_costs being not None.
MAXSHUTDOWNFLOWS
A subset of set SHUTDOWNFLOWS with the attribute maximum_shutdowns being not None.
MINUPTIMEFLOWS
A subset of set NONCONVEX_FLOWS with the attribute minimum_uptime being not None.
MINDOWNTIMEFLOWS
A subset of set NONCONVEX_FLOWS with the attribute minimum_downtime being not None.
POSITIVE_GRADIENT_FLOWS
A subset of set NONCONVEX_FLOWS with the attribute positive_gradient being not None.
NEGATIVE_GRADIENT_FLOWS
A subset of set NONCONVEX_FLOWS with the attribute negative_gradient being not None.
_objective_expression()[source]

The following terms are to the cost function:

_startup_costs()[source]
\[\sum_{i, o \in STARTUPFLOWS} \sum_t startup(i, o, t) \ \cdot startup\_costs(i, o)\]
_shutdown_costs()[source]
\[\sum_{i, o \in SHUTDOWNFLOWS} \sum_t shutdown(i, o, t) \ \cdot shutdown\_costs(i, o)\]
_activity_costs()[source]
\[\sum_{i, o \in ACTIVITYCOSTFLOWS} \sum_t status(i, o, t) \ \cdot activity\_costs(i, o)\]
_inactivity_costs()[source]
\[\sum_{i, o \in INACTIVITYCOSTFLOWS} \sum_t (1 - status(i, o, t)) \ \cdot inactivity\_costs(i, o)\]

InvestNonConvexFlow

Creating sets, variables, constraints and parts of the objective function for InvestNonConvexFlowBlock objects with both Nonconvex and Investment options.

class oemof.solph.flows._invest_non_convex_flow_block.InvestNonConvexFlowBlock(*args, **kwargs)[source]

Bases: oemof.solph.flows._non_convex_flow_block.NonConvexFlowBlock

_create_constraints()[source]
_shared_constraints_for_non_convex_flows()
_startup_constraint()
\[\begin{split}startup(i, o, t) \geq \ status(i,o,t) - status(i, o, t-1) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall (i,o) \in \textrm{STARTUPFLOWS}.\end{split}\]
_max_startup_constraint()
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} startup(i, o, t) \leq \ N_{start}(i,o)\\ \forall (i,o) \in \textrm{MAXSTARTUPFLOWS}.\end{split}\]
_shutdown_constraint()
\[\begin{split}shutdown(i, o, t) \geq \ status(i, o, t-1) - status(i, o, t) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall (i, o) \in \textrm{SHUTDOWNFLOWS}.\end{split}\]
_max_shutdown_constraint()
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} startup(i, o, t) \leq \ N_{shutdown}(i,o)\\ \forall (i,o) \in \textrm{MAXSHUTDOWNFLOWS}.\end{split}\]
_min_uptime_constraint()
\[\begin{split}(status(i, o, t)-status(i, o, t-1)) \cdot minimum\_uptime(i, o) \\ \leq \sum_{n=0}^{minimum\_uptime-1} status(i,o,t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..minimum\_uptime\} \cup \ \{t\_max-minimum\_uptime..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}. \\ \\ status(i, o, t) = initial\_status(i, o) \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..minimum\_uptime\} \cup \ \{t\_max-minimum\_uptime..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}.\end{split}\]
_min_downtime_constraint()
\[\begin{split}(status(i, o, t-1)-status(i, o, t)) \ \cdot minimum\_downtime(i, o) \\ \leq minimum\_downtime(i, o) \ - \sum_{n=0}^{minimum\_downtime-1} status(i,o,t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..minimum\_downtime\} \cup \ \{t\_max-minimum\_downtime..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}. \\ \\ status(i, o, t) = initial\_status(i, o) \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..minimum\_downtime\} \cup \ \{t\_max-minimum\_downtime..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}.\end{split}\]
positive_gradient_constraint
\[\begin{split}flow(i, o, t) \cdot status(i, o, t) - flow(i, o, t-1) \cdot status(i, o, t-1) \geq \ positive\_gradient(i, o, t), \\ \forall (i, o) \in \textrm{POSITIVE\_GRADIENT\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
negative_gradient_constraint
\[\begin{split}flow(i, o, t-1) \cdot status(i, o, t-1) - flow(i, o, t) \cdot status(i, o, t) \geq \ negative\_gradient(i, o, t), \\ \forall (i, o) \in \textrm{NEGATIVE\_GRADIENT\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_minimum_invest_constraint()[source]
\[P_{invest, min} \le P_{invest}\]
_maximum_invest_constraint()[source]
\[P_{invest} \le P_{invest, max}\]
_minimum_flow_constraint()
\[\begin{split}flow(i, o, t) \geq min(i, o, t) \cdot nominal\_value \ \cdot status(i, o, t), \\ \forall (i, o) \in \textrm{NONCONVEX\_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_maximum_flow_constraint()
\[\begin{split}flow(i, o, t) \leq max(i, o, t) \cdot nominal\_value \ \cdot status(i, o, t), \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall (i, o) \in \textrm{NONCONVEX\_FLOWS}.\end{split}\]
_linearised_investment_constraints()[source]

The resulting constraint is equivalent to

\[status\_nominal(i,o,t) = status(i,o,t) \cdot P_{invest}.\]

However, \(status\) and \(invest\) are variables (binary and continuous, respectively). Thus, three constraints are created which combination is equivalent.

_linearised_investment_constraint_1()[source]
\[status\_nominal(i,o,t) \leq status(i,o,t) \cdot P_{invest, max}\quad (1)\]
_linearised_investment_constraint_2()[source]
\[status\_nominal(i,o,t) \leq P_{invest}\quad (2)\]
_linearised_investment_constraint_3()[source]
\[status\_nominal(i,o,t) \geq P_{invest} - (1 - status(i,o,t)) \cdot P_{invest, max}\quad (3)\]

The following cases may occur:

  • Case \(status = 0\)
    \[\begin{split}(1) \Rightarrow status\_nominal = 0,\\ (2) \Rightarrow \text{ trivially fulfilled},\\ (3) \Rightarrow \text{ trivially fulfilled}.\end{split}\]
  • Case \(status = 1\)
    \[\begin{split}(1) \Rightarrow \text{ trivially fulfilled},\\ (2) \Rightarrow status\_nominal \leq P_{invest},\\ (3) \Rightarrow status\_nominal \geq P_{invest}.\end{split}\]

    So, in total \(status\_nominal = P_{invest}\), which is the desired result.

_create_variables()[source]
Status variable (binary) om.InvestNonConvexFlowBlock.status:
Variable indicating if flow is >= 0 indexed by FLOWS
\(P_{invest}\) InvestNonConvexFlowBlock.invest
Value of the investment variable, i.e. equivalent to the nominal value of the flows after optimization.
\(status\_nominal(i,o,t)\) (non-negative real number)
New paramater representing the multiplication of P_{invest} (from the <class ‘oemof.solph.flows.InvestmentFlow’>) and status(i,o,t) (from the <class ‘oemof.solph.flows.NonConvexFlow’>) used for the constraints on the minimum and maximum flow constraints.
_variables_for_non_convex_flows()
Startup variable (binary) NonConvexFlowBlock.startup:
Variable indicating startup of flow (component) indexed by STARTUPFLOWS
Shutdown variable (binary) NonConvexFlowBlock.shutdown:
Variable indicating shutdown of flow (component) indexed by SHUTDOWNFLOWS
Positive gradient (continuous) NonConvexFlowBlock.positive_gradient:
Variable indicating the positive gradient, i.e. the load increase between two consecutive timesteps, indexed by POSITIVE_GRADIENT_FLOWS
Negative gradient (continuous) NonConvexFlowBlock.negative_gradient:
Variable indicating the negative gradient, i.e. the load decrease between two consecutive timesteps, indexed by NEGATIVE_GRADIENT_FLOWS
_create_sets(group)[source]

Creates all sets for investment non-convex flows.

INVEST_NON_CONVEX_FLOWS
A set of flows with the attribute nonconvex of type options.NonConvex and the attribute invest of type options.Invest.
MIN_FLOWS
A subset of set NONCONVEX_FLOWS with the attribute min being not None in the first timestep.
STARTUPFLOWS
A subset of set NONCONVEX_FLOWS with the attribute maximum_startups or startup_costs being not None.
MAXSTARTUPFLOWS
A subset of set STARTUPFLOWS with the attribute maximum_startups being not None.
SHUTDOWNFLOWS
A subset of set NONCONVEX_FLOWS with the attribute maximum_shutdowns or shutdown_costs being not None.
MAXSHUTDOWNFLOWS
A subset of set SHUTDOWNFLOWS with the attribute maximum_shutdowns being not None.
MINUPTIMEFLOWS
A subset of set NONCONVEX_FLOWS with the attribute minimum_uptime being not None.
MINDOWNTIMEFLOWS
A subset of set NONCONVEX_FLOWS with the attribute minimum_downtime being not None.
POSITIVE_GRADIENT_FLOWS
A subset of set NONCONVEX_FLOWS with the attribute positive_gradient being not None.
NEGATIVE_GRADIENT_FLOWS
A subset of set NONCONVEX_FLOWS with the attribute negative_gradient being not None.
_objective_expression()[source]

Objective expression for nonconvex investment flows.

The following parts of the objective function are created similar to the <class ‘oemof.solph.flows.NonConvexFlow’> class:

If nonconvex.startup_costs is set by the user:
\[\sum_{i, o \in STARTUPFLOWS} \sum_t startup(i, o, t) \ \cdot startup\_costs(i, o)\]
If nonconvex.shutdown_costs is set by the user:
\[\sum_{i, o \in SHUTDOWNFLOWS} \sum_t shutdown(i, o, t) \ \cdot shutdown\_costs(i, o)\]

The following parts of the objective function are created similar to the <class ‘oemof.solph.flows.InvestmentFlow’> class:

\[P_{invest} \cdot c_{invest,var}\]