oemof.solph.Flow

Flow

solph version of oemof.network.Edge

class oemof.solph.flows._flow.Flow(nominal_value=None, variable_costs=0, min=None, max=None, fix=None, positive_gradient_limit=None, negative_gradient_limit=None, full_load_time_max=None, full_load_time_min=None, integer=False, bidirectional=False, nonconvex=None, lifetime=None, age=None, fixed_costs=None, investment=None, summed_max=None, summed_min=None, custom_attributes=None)[source]

Bases: 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 parameter’s key.

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

  • variable_costs (numeric (iterable or scalar), default: 0, \(c\)) – The costs associated with one unit of the flow per hour. The costs for each timestep (\(P_t \cdot c \cdot \delta(t)\)) will be added to the objective expression of the optimization problem.

  • 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_limit (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_limit (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.

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

  • 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.

  • fixed_costs (numeric (iterable or scalar), \(c_{fixed}\)) – The fixed costs associated with a flow. Note: These are only applicable for a multi-period model and given on a yearly basis.

  • lifetime (int, \(l\)) – The lifetime of a flow (usually given in years); once it reaches its lifetime (considering also an initial age), the flow is forced to 0. Note: Only applicable for a multi-period model.

  • age (int, \(a\)) – The initial age of a flow (usually given in years); once it reaches its lifetime (considering also an initial age), the flow is forced to 0. Note: Only applicable for a multi-period model.

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

Creating sets, variables, constraints and parts of the objective function for Flow objects with neither nonconvex nor investment options.

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

Bases: ScalarBlock

Flow block with definitions for standard flows.

See Flow class for all parameters of the Flow.

_create_constraints()[source]

Creates all constraints for standard flows.

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)\]
_create_variables(group)[source]

Creates all variables for standard flows.

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(p, t)\)

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

    If Flow.fix is not None the variable is bound to \(P(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.

_create_sets(group)[source]

Creates all sets for standard flows.

_objective_expression()[source]

Objective expression for all standard flows with fixed costs and variable costs.

Depending on the attributes of the Flow object the following parts of the objective function are created for a standard model:

  • Flow.variable_costs is not None:
    \[\sum_{(i,o)} \sum_t P(t) \cdot w(t) \cdot c_{var}(i, o, t)\]

where \(w(t)\) is the objective weighting.

In a multi-period model, in contrast, the following parts of the objective function are created:

  • Flow.variable_costs is not None:
    \[\sum_{(i,o)} \sum_{p, t} P(p, t) \cdot w(t) \cdot c_{var}(i, o, t)\]
  • Flow.fixed_costs is not None and flow has no lifetime limit
    \[\sum_{(i,o)} \displaystyle \sum_{pp=0}^{year_{max}} P_{nominal} \cdot c_{fixed}(i, o, pp) \cdot DF^{-pp}\]
  • Flow.fixed_costs is not None and flow has a lifetime limit,
    but not an initial age
    \[\sum_{(i,o)} \displaystyle \sum_{pp=0}^{limit_{exo}} P_{nominal} \cdot c_{fixed}(i, o, pp) \cdot DF^{-pp}\]
  • Flow.fixed_costs is not None and flow has a lifetime limit,
    and an initial age
    \[\sum_{(i,o)} \displaystyle \sum_{pp=0}^{limit_{exo}} P_{nominal} \cdot c_{fixed}(i, o, pp) \cdot DF^{-pp}\]

Hereby

  • \(DF(p) = (1 + dr)\) is the discount factor for period \(p\) and \(dr\) is the discount rate.

  • \(n\) is the unit lifetime and \(a\) is the initial age.

  • \(year_{max}\) denotes the last year of the optimization horizon, i.e. at the end of the last period.

  • \(limit_{exo}=min\{year_{max}, n - a\}\) is used as an upper bound to ensure fixed costs for existing capacities to occur within the optimization horizon. \(a\) is the initial age of an asset (or 0 if not specified).

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 Flow objects with investment but without nonconvex option.

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

Bases: ScalarBlock

Block for all flows with Investment being not None.

_create_constraints()[source]

Creates all constraints for standard flows.

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

Total capacity / energy

\[\begin{split}& if \quad p=0:\\ & P_{total}(p) = P_{invest}(p) + P_{exist}(p) \\ &\\ & else:\\ & P_{total}(p) = P_{total}(p-1) + P_{invest}(p) - P_{old}(p) \\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]

Upper bound for the flow value

\[\begin{split}& P(p, t) \le ( P_{total}(p) ) \cdot f_{max}(t) \\ & \forall p, t \in \textrm{TIMEINDEX}\end{split}\]

For a multi-period model, the old capacity is defined as follows:

\[\begin{split}& P_{old}(p) = P_{old,exo}(p) + P_{old,end}(p)\\ &\\ & if \quad p=0:\\ & P_{old,end}(p) = 0\\ &\\ & else \quad if \quad l \leq year(p):\\ & P_{old,end}(p) = P_{invest}(p_{comm})\\ &\\ & else:\\ & P_{old,end}(p) = 0\\ &\\ & if \quad p=0:\\ & P_{old,exo}(p) = 0\\ &\\ & else \quad if \quad l - a \leq year(p):\\ & P_{old,exo}(p) = P_{exist} (*)\\ &\\ & else:\\ & P_{old,exo}(p) = 0\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]

where:

  • (*) is only performed for the first period the condition is True. A decommissioning flag is then set to True to prevent having falsely added old capacity in future periods.

  • \(year(p)\) is the year corresponding to period p

  • \(p_{comm}\) is the commissioning period of the flow (which is determined by the model itself)

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

  • nonconvex = False

\[\begin{split}& P_{invest, min}(p) \le P_{invest}(p) \le P_{invest, max}(p) \\ & \forall p \in \textrm{PERIODS}\end{split}\]
  • nonconvex = True

\[\begin{split}& P_{invest, min}(p) \cdot Y_{invest}(p) \le P_{invest}(p)\\ & P_{invest}(p) \le P_{invest, max}(p) \cdot Y_{invest}(p)\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]

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

  • fix is not None

    Actual value constraint for investments with fixed flow values

\[\begin{split}& P(p, t) = P_{total}(p) \cdot f_{fix}(t) \\ &\\ & \forall p, t \in \textrm{TIMEINDEX}\end{split}\]
  • min != 0

    Lower bound for the flow values

\[\begin{split}& P(p, t) \geq P_{total}(p) \cdot f_{min}(t) \\ &\\ & \forall p, t \in \textrm{TIMEINDEX}\end{split}\]
  • full_load_time_max is not None

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

\[\sum_{p, t} P(p, t) \cdot \tau(t) \leq P_{total}(p) \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_{p, t} P(t) \cdot \tau(t) \geq P_{total} \cdot t_{full\_load, min}\]
  • overall_maximum is not None (for multi-period model only)

    Overall maximum of total installed capacity / energy for flow

\[\begin{split}& P_{total}(p) \leq P_{overall,max} \\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]
  • overall_minimum is not None (for multi-period model only)

    Overall minimum of total installed capacity / energy for flow; applicable only in last period

\[P_{total}(p_{last}) \geq P_{overall,min}\]
_create_variables(_)[source]

Creates all variables for investment flows.

All InvestmentFlowBlock objects 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(p, t)\)

    Actual flow value (created in oemof.solph.models.BaseModel), indexed by tuple of periods p and timestep t

  • \(P_{invest}(p)\)

    Value of the investment variable in period p, equal to what is being invested and equivalent resp. similar to the nominal value of the flows after optimization.

  • \(P_{total}(p)\)

    Total installed capacity / energy in period p, equivalent to the nominal value of the flows after optimization.

  • \(P_{old}(p)\)

    Old capacity / energy to be decommissioned in period p due to reaching its lifetime; applicable only for multi-period models.

  • \(P_{old,exo}(p)\)

    Old exogenous capacity / energy to be decommissioned in period p due to reaching its lifetime, i.e. the amount that has been specified by existing when it is decommisioned; applicable only for multi-period models.

  • \(P_{old,end}(p)\)

    Old endogenous capacity / energy to be decommissioned in period p due to reaching its lifetime, i.e. the amount that has been invested in by the model itself that is decommissioned in a later period because of reaching its lifetime; applicable only for multi-period models.

  • \(Y_{invest}(p)\)

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

_create_sets(group)[source]

Creates all sets for investment flows.

_objective_expression()[source]

Objective expression for flows with investment attribute of type class:.Investment. The returned costs are fixed and investment costs. Variable costs are added from the standard flow objective expression.

Objective terms for a standard model and a multi-period model differ quite strongly. Besides, 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:

Standard model

  • nonconvex = False

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

    \[\begin{split}P_{invest}(0) \cdot c_{invest,var}(0) + c_{invest,fix}(0) \cdot Y_{invest}(0) \\\end{split}\]

Where 0 denotes the 0th (investment) period since in a standard model, there is only this one period.

Multi-period model

  • nonconvex = False

    \[\begin{split}& P_{invest}(p) \cdot A(c_{invest,var}(p), l, ir) \cdot \frac {1}{ANF(d, ir)} \cdot DF^{-p}\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]

In case, the remaining lifetime of an asset is greater than 0 and attribute use_remaining_value of the energy system is True, the difference in value for the investment period compared to the last period of the optimization horizon is accounted for as an adder to the investment costs:

\[\begin{split}& P_{invest}(p) \cdot (A(c_{invest,var}(p), l_{r}, ir) - A(c_{invest,var}(|P|), l_{r}, ir)\\ & \cdot \frac {1}{ANF(l_{r}, ir)} \cdot DF^{-|P|}\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]
  • nonconvex = True

    \[\begin{split}& (P_{invest}(p) \cdot A(c_{invest,var}(p), l, ir) \cdot \frac {1}{ANF(d, ir)}\\ & + c_{invest,fix}(p) \cdot b_{invest}(p)) \cdot DF^{-p}\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]

In case, the remaining lifetime of an asset is greater than 0 and attribute use_remaining_value of the energy system is True, the difference in value for the investment period compared to the last period of the optimization horizon is accounted for as an adder to the investment costs:

\[\begin{split}& (P_{invest}(p) \cdot (A(c_{invest,var}(p), l_{r}, ir) - A(c_{invest,var}(|P|), l_{r}, ir)\\ & \cdot \frac {1}{ANF(l_{r}, ir)} \cdot DF^{-|P|}\\ & + (c_{invest,fix}(p) - c_{invest,fix}(|P|)) \cdot b_{invest}(p)) \cdot DF^{-p}\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]
  • fixed_costs not None for investments

    \[\begin{split}& (\sum_{pp=year(p)}^{limit_{end}} P_{invest}(p) \cdot c_{fixed}(pp) \cdot DF^{-pp}) \cdot DF^{-p}\\ &\\ & \forall p \in \textrm{PERIODS}\end{split}\]
  • fixed_costs not None for existing capacity

    \[\sum_{pp=0}^{limit_{exo}} P_{exist} \cdot c_{fixed}(pp) \cdot DF^{-pp}\]

where:

  • \(A(c_{invest,var}(p), l, ir)\) A is the annuity for investment expenses \(c_{invest,var}(p)\), lifetime \(l\) and interest rate \(ir\).

  • \(l_{r}\) is the remaining lifetime at the end of the optimization horizon (in case it is greater than 0 and smaller than the actual lifetime).

  • \(ANF(d, ir)\) is the annuity factor for duration \(d\) and interest rate \(ir\).

  • \(d=min\{year_{max} - year(p), l\}\) defines the number of years within the optimization horizon that investment annuities are accounted for.

  • \(year(p)\) denotes the start year of period \(p\).

  • \(year_{max}\) denotes the last year of the optimization horizon, i.e. at the end of the last period.

  • \(limit_{end}=min\{year_{max}, year(p) + l\}\) is used as an upper bound to ensure fixed costs for endogenous investments to occur within the optimization horizon.

  • \(limit_{exo}=min\{year_{max}, l - a\}\) is used as an upper bound to ensure fixed costs for existing capacities to occur within the optimization horizon. \(a\) is the initial age of an asset.

  • \(DF=(1+dr)\) is the discount factor.

The annuity / annuity factor hereby is:

\[\begin{split}& A(c_{invest,var}(p), l, ir) = c_{invest,var}(p) \cdot \frac {(1+ir)^l \cdot ir} {(1+ir)^l - 1}\\ &\\ & ANF(d, ir)=\frac {(1+ir)^d \cdot ir} {(1+ir)^d - 1}\end{split}\]

They are derived using the reciprocal of the oemof.tools.economics annuity function with a capex of 1. The interest rate \(ir\) for the annuity is defined as weighted average costs of capital (wacc) and assumed constant over time.

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

See oemof.solph.flows._simple_flow_block.SimpleFlowBlock for all parameters of the SimpleFlowBlock class.

The overall summed cost expressions for all InvestmentFlowBlock objects can be accessed by

  • om.InvestmentFlowBlock.investment_costs,

  • om.InvestmentFlowBlock.fixed_costs and

  • om.InvestmentFlowBlock.costs.

Their values after optimization can be retrieved by

  • om.InvestmentFlowBlock.investment_costs(),

  • om.InvestmentFlowBlock.period_investment_costs (yielding a dict keyed by periods); note: this is not a Pyomo expression, but calculated,

  • om.InvestmentFlowBlock.fixed_costs() and

  • om.InvestmentFlowBlock.costs().

Note

In case of a nonconvex investment flow (nonconvex=True), the existing flow capacity \(P_{exist}\) needs to be zero.

Note

See also Flow, SimpleFlowBlock and Investment

NonConvexFlow

Creating sets, variables, constraints and parts of the objective function for Flow objects with nonconvex but without investment options.

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

Bases: ScalarBlock

_create_constraints()[source]

The following constraints are created:

_status_nominal_constraint()[source]
\[\begin{split}P_{max,status}(t) = Y_{status}(t) \cdot P_{nom}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_minimum_flow_constraint()[source]
\[\begin{split}P(t) \geq min(i, o, t) \cdot P_{nom} \ \cdot Y_{status}(t), \\ \forall (i, o) \in \textrm{NONCONVEX_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_maximum_flow_constraint()[source]
\[\begin{split}P(t) \leq max(i, o, t) \cdot P_{nom} \ \cdot status(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}Y_{startup}(t) \geq Y_{status}(t) - Y_{status}(t-1) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall \textrm{STARTUPFLOWS}.\end{split}\]
_max_startup_constraint()[source]
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} Y_{startup}(t) \leq \ N_{start}(i,o)\\ \forall (i,o) \in \textrm{MAXSTARTUPFLOWS}.\end{split}\]
_shutdown_constraint()[source]
\[\begin{split}Y_{shutdown}(t) \geq Y_{status}(t-1) - Y_{status}(t) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall \textrm{SHUTDOWNFLOWS}.\end{split}\]
_max_shutdown_constraint()[source]
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} Y_{startup}(t) \leq \ N_{shutdown}(i,o)\\ \forall (i,o) \in \textrm{MAXSHUTDOWNFLOWS}.\end{split}\]
_min_uptime_constraint()[source]
\[\begin{split}(Y_{status}(t)-Y_{status}(t-1)) \cdot t_{up,minimum} \\ \leq \sum_{n=0}^{t_{up,minimum}-1} Y_{status}(t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..t_{up,minimum}\} \cup \ \{t\_max-t_{up,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}. \\ \\ Y_{status}(t) = Y_{status,0} \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..t_{up,minimum}\} \cup \ \{t\_max-t_{up,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}.\end{split}\]
_min_downtime_constraint()[source]
\[\begin{split}(Y_{status}(t-1) - Y_{status}(t)) \ \cdot t_{down,minimum} \\ \leq t_{down,minimum} \ - \sum_{n=0}^{t_{down,minimum}-1} Y_{status}(t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..t_{down,minimum}\} \cup \ \{t\_max-t_{down,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}. \\ \\ Y_{status}(t) = Y_{status,0} \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..t_{down,minimum}\} \cup \ \{t\_max-t_{down,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}.\end{split}\]
positive_gradient_constraint
\[\begin{split}P(t) \cdot Y_{status}(t) - P(t-1) \cdot Y_{status}(t-1) \leq \ \dot{P}_{up}(t), \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
negative_gradient_constraint
\[\begin{split}P(t-1) \cdot Y_{status}(t-1) - P(t) \cdot Y_{status}(t) \leq \ \dot{P}_{down}(t), \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_create_variables()[source]
\(Y_{status}\) (binary) om.NonConvexFlowBlock.status:

Variable indicating if flow is >= 0

\(P_{max,status}\) Status_nominal (continuous)

Variable indicating if flow is >= 0

_variables_for_non_convex_flows()[source]
\(Y_{startup}\) (binary) NonConvexFlowBlock.startup:

Variable indicating startup of flow (component) indexed by STARTUPFLOWS

\(Y_{shutdown}\) (binary) NonConvexFlowBlock.shutdown:

Variable indicating shutdown of flow (component) indexed by SHUTDOWNFLOWS

\(\dot{P}_{up}\) (continuous)

NonConvexFlowBlock.positive_gradient: Variable indicating the positive gradient, i.e. the load increase between two consecutive timesteps, indexed by POSITIVE_GRADIENT_FLOWS

\(\dot{P}_{down}\) (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]

Creates all sets for non-convex flows.

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 > 0.

MINDOWNTIMEFLOWS

A subset of set NONCONVEX_FLOWS with the attribute minimum_downtime being > 0.

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 Y_{startup}(t) \ \cdot c_{startup}\]
_shutdown_costs()[source]
\[\sum_{SHUTDOWNFLOWS} \sum_t Y_{shutdown}(t) \ \cdot c_{shutdown}\]
_activity_costs()[source]
\[\sum_{ACTIVITYCOSTFLOWS} \sum_t Y_{status}(t) \ \cdot c_{activity}\]
_inactivity_costs()[source]
\[\sum_{INACTIVITYCOSTFLOWS} \sum_t (1 - Y_{status}(t)) \ \cdot c_{inactivity}\]

Parameters are defined in Flow.

InvestNonConvexFlow

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

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

Bases: NonConvexFlowBlock

_create_constraints()[source]
_shared_constraints_for_non_convex_flows()
_startup_constraint()
\[\begin{split}Y_{startup}(t) \geq Y_{status}(t) - Y_{status}(t-1) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall \textrm{STARTUPFLOWS}.\end{split}\]
_max_startup_constraint()
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} Y_{startup}(t) \leq \ N_{start}(i,o)\\ \forall (i,o) \in \textrm{MAXSTARTUPFLOWS}.\end{split}\]
_shutdown_constraint()
\[\begin{split}Y_{shutdown}(t) \geq Y_{status}(t-1) - Y_{status}(t) \\ \forall t \in \textrm{TIMESTEPS}, \\ \forall \textrm{SHUTDOWNFLOWS}.\end{split}\]
_max_shutdown_constraint()
\[\begin{split}\sum_{t \in \textrm{TIMESTEPS}} Y_{startup}(t) \leq \ N_{shutdown}(i,o)\\ \forall (i,o) \in \textrm{MAXSHUTDOWNFLOWS}.\end{split}\]
_min_uptime_constraint()
\[\begin{split}(Y_{status}(t)-Y_{status}(t-1)) \cdot t_{up,minimum} \\ \leq \sum_{n=0}^{t_{up,minimum}-1} Y_{status}(t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..t_{up,minimum}\} \cup \ \{t\_max-t_{up,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}. \\ \\ Y_{status}(t) = Y_{status,0} \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..t_{up,minimum}\} \cup \ \{t\_max-t_{up,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINUPTIMEFLOWS}.\end{split}\]
_min_downtime_constraint()
\[\begin{split}(Y_{status}(t-1) - Y_{status}(t)) \ \cdot t_{down,minimum} \\ \leq t_{down,minimum} \ - \sum_{n=0}^{t_{down,minimum}-1} Y_{status}(t+n) \\ \forall t \in \textrm{TIMESTEPS} | \\ t \neq \{0..t_{down,minimum}\} \cup \ \{t\_max-t_{down,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}. \\ \\ Y_{status}(t) = Y_{status,0} \\ \forall t \in \textrm{TIMESTEPS} | \\ t = \{0..t_{down,minimum}\} \cup \ \{t\_max-t_{down,minimum}..t\_max\} , \\ \forall (i,o) \in \textrm{MINDOWNTIMEFLOWS}.\end{split}\]
positive_gradient_constraint
\[\begin{split}P(t) \cdot Y_{status}(t) - P(t-1) \cdot Y_{status}(t-1) \leq \ \dot{P}_{up}(t), \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
negative_gradient_constraint
\[\begin{split}P(t-1) \cdot Y_{status}(t-1) - P(t) \cdot Y_{status}(t) \leq \ \dot{P}_{down}(t), \\ \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}P(t) \geq min(i, o, t) \cdot P_{nom} \ \cdot Y_{status}(t), \\ \forall (i, o) \in \textrm{NONCONVEX_FLOWS}, \\ \forall t \in \textrm{TIMESTEPS}.\end{split}\]
_maximum_flow_constraint()
\[\begin{split}P(t) \leq max(i, o, t) \cdot P_{nom} \ \cdot status(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) = Y_{status}(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 Y_{status}(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 - Y_{status}(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

:math::P_{invest} InvestNonConvexFlowBlock.invest

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

:math::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()
\(Y_{startup}\) (binary) NonConvexFlowBlock.startup:

Variable indicating startup of flow (component) indexed by STARTUPFLOWS

\(Y_{shutdown}\) (binary) NonConvexFlowBlock.shutdown:

Variable indicating shutdown of flow (component) indexed by SHUTDOWNFLOWS

\(\dot{P}_{up}\) (continuous)

NonConvexFlowBlock.positive_gradient: Variable indicating the positive gradient, i.e. the load increase between two consecutive timesteps, indexed by POSITIVE_GRADIENT_FLOWS

\(\dot{P}_{down}\) (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.

_sets_for_non_convex_flows(group)

Creates all sets for non-convex flows.

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 > 0.

MINDOWNTIMEFLOWS

A subset of set NONCONVEX_FLOWS with the attribute minimum_downtime being > 0.

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.

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