Source code for oemof.solph.constraints.investment_limit

# -*- coding: utf-8 -*-

"""Limits for investments.

SPDX-FileCopyrightText: Uwe Krien <krien@uni-bremen.de>
SPDX-FileCopyrightText: Simon Hilpert
SPDX-FileCopyrightText: Patrik Schönfeldt
SPDX-FileCopyrightText: Johannes Röder

SPDX-License-Identifier: MIT

"""

from pyomo import environ as po


[docs]def investment_limit(model, limit=None): r"""Set an absolute limit for the total investment costs of an investment optimization problem: .. math:: \sum_{investment\_costs} \leq limit Parameters ---------- model : oemof.solph.Model Model to which the constraint is added limit : float Absolute limit of the investment (i.e. RHS of constraint) """ def investment_rule(m): expr = 0 if hasattr(m, "InvestmentFlow"): expr += m.InvestmentFlow.investment_costs if hasattr(m, "GenericInvestmentStorageBlock"): expr += m.GenericInvestmentStorageBlock.investment_costs return expr <= limit model.investment_limit = po.Constraint(rule=investment_rule) return model
[docs]def additional_investment_flow_limit(model, keyword, limit=None): r""" Global limit for investment flows weighted by an attribute keyword. This constraint is only valid for Flows not for components such as an investment storage. The attribute named by keyword has to be added to every Investment attribute of the flow you want to take into account. Total value of keyword attributes after optimization can be retrieved calling the :attr:`oemof.solph.Model.invest_limit_${keyword}()`. .. math:: \sum_{i \in IF} P_i \cdot w_i \leq limit With `IF` being the set of InvestmentFlows considered for the integral limit. The symbols used are defined as follows (with Variables (V) and Parameters (P)): +---------------+-------------------------------+------+--------------------------------------------------------------+ | symbol | attribute | type | explanation | +===============+===============================+======+==============================================================+ | :math:`P_{i}` | `InvestmentFlow.invest[i, o]` | V | installed capacity of investment flow | +---------------+-------------------------------+------+--------------------------------------------------------------+ | :math:`w_i` | `keyword` | P | weight given to investment flow named according to `keyword` | +---------------+-------------------------------+------+--------------------------------------------------------------+ | :math:`limit` | `limit` | P | global limit given by keyword `limit` | +---------------+-------------------------------+------+--------------------------------------------------------------+ Parameters ---------- model : oemof.solph.Model Model to which constraints are added. keyword : attribute to consider All flows with Investment attribute containing the keyword will be used. limit : numeric Global limit of keyword attribute for the energy system. Note ---- The Investment attribute of the considered (Investment-)flows requires an attribute named like keyword! Examples -------- >>> import pandas as pd >>> from oemof import solph >>> date_time_index = pd.date_range('1/1/2020', periods=5, freq='H') >>> es = solph.EnergySystem(timeindex=date_time_index) >>> bus = solph.Bus(label='bus_1') >>> sink = solph.Sink(label="sink", inputs={bus: ... solph.Flow(nominal_value=10, fix=[10, 20, 30, 40, 50])}) >>> src1 = solph.Source(label='source_0', outputs={bus: solph.Flow( ... investment=solph.Investment(ep_costs=50, space=4))}) >>> src2 = solph.Source(label='source_1', outputs={bus: solph.Flow( ... investment=solph.Investment(ep_costs=100, space=1))}) >>> es.add(bus, sink, src1, src2) >>> model = solph.Model(es) >>> model = solph.constraints.additional_investment_flow_limit( ... model, "space", limit=1500) >>> a = model.solve(solver="cbc") >>> int(round(model.invest_limit_space())) 1500 """ # noqa: E501 invest_flows = {} for (i, o) in model.flows: if hasattr(model.flows[i, o].investment, keyword): invest_flows[(i, o)] = model.flows[i, o].investment limit_name = "invest_limit_" + keyword setattr( model, limit_name, po.Expression( expr=sum( model.InvestmentFlow.invest[inflow, outflow] * getattr(invest_flows[inflow, outflow], keyword) for (inflow, outflow) in invest_flows ) ), ) setattr( model, limit_name + "_constraint", po.Constraint(expr=(getattr(model, limit_name) <= limit)), ) return model