You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If a NonConvex flow has an investment to be optimized and the solph.Investment object contains an offset (i.e. fix cost independent of the flows nominal_capacity), this offset is added to the objective function, whether or not the flow is optimized to a nominal_capacity greater then zero.
Why this is a bug:
This behavior is most likely not what most users would expect when setting the offset parameter. Even if it was, it is not in line with other components, e.g. the GenericStorage class, which adds the invest_status binary variable. The varible is 0 when no investment is made, so it can be multiplied with the offset in the objective function.
How to reproduce:
Add a cost to the offset parameter of an solph.Investment object in a flow of a Converter, that itself is set to be NonConvex (e.g. setting a min and max value, so NonConvex allows the flow to be zero nevertheless). Use the model.write method and investigate the objective expression. The cost set in the offset parameter should be added onto other constant cost/revenues in the ONE_VAR_CONSTANT expression.
Additional information:
This excerpt of the LP generated using the model.write method shows how the GenericInvestmentStorageBlock handels the constant additional cost differently to the InvestNonConvexFlowBlock.
Here is a comparison between the objective expressions of the GenericInvestmentStorageBlock and InvestNonConvexFlowBlock:
Excerpt of the objective_expression of the GenericInvestmentStorageBlock
def_objective_expression(self):
"""Objective expression with fixed and investment costs."""m=self.parent_block()
investment_costs=0period_investment_costs= {p: 0forpinm.PERIODS}
fixed_costs=0ifm.es.periodsisNone:
forninself.CONVEX_INVESTSTORAGES:
forpinm.PERIODS:
investment_costs+= (
self.invest[n, p] *n.investment.ep_costs[p]
)
forninself.NON_CONVEX_INVESTSTORAGES:
forpinm.PERIODS:
investment_costs+= (
self.invest[n, p] *n.investment.ep_costs[p]
+self.invest_status[n, p] *n.investment.offset[p] # <- here the offset is eliminated in case no investment is made
)
Excerpt of the objective_expression of the InvestNonConvexFlowBlock
def_objective_expression(self):
r"""Objective expression for nonconvex investment flows. If `nonconvex.startup_costs` is set by the user: .. math:: \sum_{i, o \in STARTUPFLOWS} \sum_t startup(i, o, t) \ \cdot c_{startup} If `nonconvex.shutdown_costs` is set by the user: .. math:: \sum_{i, o \in SHUTDOWNFLOWS} \sum_t shutdown(i, o, t) \ \cdot c_{shutdown} .. math:: P_{invest} \cdot c_{invest,var} """ifnothasattr(self, "INVEST_NON_CONVEX_FLOWS"):
return0m=self.parent_block()
startup_costs=self._startup_costs()
shutdown_costs=self._shutdown_costs()
activity_costs=self._activity_costs()
inactivity_costs=self._inactivity_costs()
investment_costs=0fori, oinself.INVEST_NON_CONVEX_FLOWS:
forpinm.PERIODS:
investment_costs+= (
self.invest[i, o, p] *m.flows[i, o].investment.ep_costs[p]
+m.flows[i, o].investment.offset[p] # <- here the offset is added whether or not an investment is made
)
self.investment_costs=Expression(expr=investment_costs)
The text was updated successfully, but these errors were encountered:
Short description:
If a NonConvex flow has an investment to be optimized and the
solph.Investment
object contains anoffset
(i.e. fix cost independent of the flowsnominal_capacity
), thisoffset
is added to the objective function, whether or not the flow is optimized to anominal_capacity
greater then zero.Why this is a bug:
This behavior is most likely not what most users would expect when setting the
offset
parameter. Even if it was, it is not in line with other components, e.g. theGenericStorage
class, which adds theinvest_status
binary variable. The varible is0
when no investment is made, so it can be multiplied with theoffset
in the objective function.How to reproduce:
Add a cost to the
offset
parameter of ansolph.Investment
object in a flow of aConverter
, that itself is set to beNonConvex
(e.g. setting a min and max value, so NonConvex allows the flow to be zero nevertheless). Use themodel.write
method and investigate the objective expression. The cost set in the offset parameter should be added onto other constant cost/revenues in theONE_VAR_CONSTANT
expression.Additional information:
This excerpt of the LP generated using the
model.write
method shows how theGenericInvestmentStorageBlock
handels the constant additional cost differently to theInvestNonConvexFlowBlock
.LP file excerpt
* Source Pyomo model name=Model *\
min
objective:
+774240.8738468975 ONE_VAR_CONSTANT
+20.5 flow(electricity_network_heat_pump_0_0)
+0.01 flow(heat_network_st_tes_0_0)
-35.32 flow(spotmarket_node_spotmarket_0_0)
+28.75154 flow(gas_source_gas_network_0_0)
+60.34 flow(electricity_source_electricity_network_0_0)
+1.2 flow(heat_pump_heat_network_0_0)
+4.4 flow(ccet_ccet_node_0_0)
+6.6 flow(peak_load_boiler_heat_network_0_0)
+0.01 flow(st_tes_heat_network_0_0)
+185784.83113797754 InvestNonConvexFlowBlock_invest(ccet_heat_network_0)
+24824.439073550922 InvestNonConvexFlowBlock_invest(heat_pump_heat_network_0)
+6764.555231441481 InvestNonConvexFlowBlock_invest(peak_load_boiler_heat_network_0)
+21.9765694447266 GenericInvestmentStorageBlock_invest(st_tes_0)
+16635.489556160563 GenericInvestmentStorageBlock_invest_status(st_tes_0)
Here is a comparison between the objective expressions of the GenericInvestmentStorageBlock and InvestNonConvexFlowBlock:
Excerpt of the objective_expression of the GenericInvestmentStorageBlock
Excerpt of the objective_expression of the InvestNonConvexFlowBlock
The text was updated successfully, but these errors were encountered: