def _check_invest_attributes(self, dpr_msg): if self.nominal_input_capacity_ratio is not None: warnings.warn(dpr_msg, DeprecationWarning) self.invest_relation_input_capacity = ( self.nominal_input_capacity_ratio) if self.nominal_output_capacity_ratio is not None: warnings.warn(dpr_msg, DeprecationWarning) self.invest_relation_output_capacity = ( self.nominal_output_capacity_ratio) if self.investment and self.nominal_capacity is not None: e1 = ("If an investment object is defined the invest variable " "replaces the nominal_capacity.\n Therefore the " "nominal_capacity should be 'None'.\n") raise AttributeError(e1) if (self.invest_relation_input_output is not None and self.invest_relation_output_capacity is not None and self.invest_relation_input_capacity is not None): e2 = ("Overdetermined. Three investment object will be coupled" "with three constraints. Set one invest relation to 'None'.") raise AttributeError(e2) for flow in self.inputs.values(): if (self.invest_relation_input_capacity is not None and not isinstance(flow.investment, Investment)): flow.investment = Investment() for flow in self.outputs.values(): if (self.invest_relation_output_capacity is not None and not isinstance(flow.investment, Investment)): flow.investment = Investment()
def _investment(self): if self.expandable is True: if self.capacity_cost is None: msg = ("If you set `expandable`to True you need to set " "attribute `capacity_cost` of component {}!") raise ValueError(msg.format(self.label)) else: if isinstance(self, GenericStorage): if self.storage_capacity_cost is not None: self.investment = Investment( ep_costs=self.storage_capacity_cost, maximum=getattr( self, "storage_capacity_potential", float("+inf"), ), minimum=getattr(self, "minimum_storage_capacity", 0), existing=getattr(self, "storage_capacity", 0), ) else: self.investment = Investment() else: self.investment = Investment( ep_costs=self.capacity_cost, maximum=getattr(self, "capacity_potential", float("+inf")), existing=getattr(self, "capacity", 0), ) else: self.investment = None return self.investment
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.nominal_capacity = kwargs.get('nominal_capacity') self.nominal_input_capacity_ratio = kwargs.get( 'nominal_input_capacity_ratio', None) self.nominal_output_capacity_ratio = kwargs.get( 'nominal_output_capacity_ratio', None) self.initial_capacity = kwargs.get('initial_capacity') self.capacity_loss = solph_sequence(kwargs.get('capacity_loss', 0)) self.inflow_conversion_factor = solph_sequence( kwargs.get('inflow_conversion_factor', 1)) self.outflow_conversion_factor = solph_sequence( kwargs.get('outflow_conversion_factor', 1)) self.capacity_max = solph_sequence(kwargs.get('capacity_max', 1)) self.capacity_min = solph_sequence(kwargs.get('capacity_min', 0)) self.investment = kwargs.get('investment') # General error messages e_no_nv = ("If an investment object is defined the invest variable " "replaces the {0}.\n Therefore the {0} should be 'None'.\n") e_duplicate = ( "Duplicate definition.\nThe 'nominal_{0}_capacity_ratio'" "will set the nominal_value for the flow.\nTherefore " "either the 'nominal_{0}_capacity_ratio' or the " "'nominal_value' has to be 'None'.") # Check investment if self.investment and self.nominal_capacity is not None: raise AttributeError(e_no_nv.format('nominal_capacity')) # Check input flows for flow in self.inputs.values(): if self.investment and flow.nominal_value is not None: raise AttributeError(e_no_nv.format('nominal_value')) if (flow.nominal_value is not None and self.nominal_input_capacity_ratio is not None): raise AttributeError(e_duplicate) if (not self.investment and self.nominal_input_capacity_ratio is not None): flow.nominal_value = (self.nominal_input_capacity_ratio * self.nominal_capacity) if self.investment: if not isinstance(flow.investment, Investment): flow.investment = Investment() # Check output flows for flow in self.outputs.values(): if self.investment and flow.nominal_value is not None: raise AttributeError(e_no_nv.format('nominal_value')) if (flow.nominal_value is not None and self.nominal_output_capacity_ratio is not None): raise AttributeError(e_duplicate) if (not self.investment and self.nominal_output_capacity_ratio is not None): flow.nominal_value = (self.nominal_output_capacity_ratio * self.nominal_capacity) if self.investment: if not isinstance(flow.investment, Investment): flow.investment = Investment()
def get_sim_params(cost): """ The function adds parameters such as nominal capacity and investment to the components cost dict :param cost: cost dict :return: sim_params dict parameter inputs for the energy system model """ sim_params = {'pv': {'nominal_capacity': 264.07523381, 'investment': Investment( ep_costs=cost['pv']['epc'] )}, 'storage': {'nominal_capacity': 337.807019472, 'investment': Investment( ep_costs=cost['storage']['epc'] )}} return sim_params
def get_sim_params(cost): sim_params = { 'pv': { 'nominal_capacity': 265.017017, 'investment': Investment(ep_costs=cost['pv']['epc']) }, 'storage': { 'nominal_capacity': 268.1211092, 'investment': Investment(ep_costs=cost['storage']['epc']) } } return sim_params
def setUpClass(cls): cls.period = 24 cls.es = EnergySystem(timeindex=pandas.date_range( '2016-01-01', periods=cls.period, freq='H')) # BUSSES b_el1 = Bus(label="b_el1") b_el2 = Bus(label="b_el2") b_diesel = Bus(label='b_diesel', balanced=False) cls.es.add(b_el1, b_el2, b_diesel) # TEST DIESEL: dg = Transformer( label='diesel', inputs={b_diesel: Flow(variable_costs=2)}, outputs={ b_el1: Flow(variable_costs=1, investment=Investment(ep_costs=0.5)) }, conversion_factors={b_el1: 2}, ) batt = GenericStorage( label='storage', inputs={b_el1: Flow(variable_costs=3)}, outputs={b_el2: Flow(variable_costs=2.5)}, capacity_loss=0.00, initial_capacity=0, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, fixed_costs=35, investment=Investment(ep_costs=0.4), ) cls.demand_values = [100] * 8760 cls.demand_values[0] = 0.0 demand = Sink(label="demand_el", inputs={ b_el2: Flow(nominal_value=1, actual_value=cls.demand_values, fixed=True) }) cls.es.add(dg, batt, demand) cls.om = Model(cls.es) cls.om.receive_duals() cls.om.solve() cls.mod = Model(cls.es) cls.mod.solve()
def test_investment_flow_grouping(self): """ Flows of investment sink should be grouped. The constraint tests uncovered a spurious error where the flows of an investment `Sink` where not put into the `InvestmentFlow` group, although the corresponding grouping was present in the energy system. The error occured in the case where the investment `Sink` was not instantiated directly after the `Bus` it is connected to. This test recreates this error scenario and makes sure that the `InvestmentFlow` group is not empty. """ b = solph.Bus(label='Bus') solph.Source(label='Source', outputs={b: solph.Flow( actual_value=[12, 16, 14], nominal_value=1000000, fixed=True)}) solph.Sink(label='Sink', inputs={b: solph.Flow( summed_max=2.3, variable_costs=25, max=0.8, investment=Investment(ep_costs=500, maximum=10e5))}) ok_(self.es.groups.get(IF), ("Expected InvestmentFlow group to be nonempty.\n" + "Got: {}").format(self.es.groups.get(IF)))
def build_solph_components(self): """ """ self.nominal_storage_capacity = self.storage_capacity self.inflow_conversion_factor = sequence(self.efficiency) self.outflow_conversion_factor = sequence(self.efficiency) # make it investment but don't set costs (set below for flow (power)) self.investment = self._investment() if self.investment: self.invest_relation_input_output = 1 for attr in ["invest_relation_input_output"]: if getattr(self, attr) is None: raise AttributeError( ("You need to set attr " "`{}` " "for component {}").format(attr, self.label)) # set capacity costs at one of the flows fi = Flow(investment=Investment( ep_costs=self.capacity_cost, maximum=self.capacity_potential, existing=self.capacity, ), **self.input_parameters) # set investment, but no costs (as relation input / output = 1) fo = Flow(investment=Investment(), variable_costs=self.marginal_cost, **self.output_parameters) # required for correct grouping in oemof.solph.components self._invest_group = True else: fi = Flow(nominal_value=self._nominal_value(), **self.input_parameters) fo = Flow(nominal_value=self._nominal_value(), variable_costs=self.marginal_cost, **self.output_parameters) self.inputs.update({self.bus: fi}) self.outputs.update({self.bus: fo}) self._set_flows()
def _investment(self): if self.capacity is None: if self.capacity_cost is None: msg = ( "If you don't set `capacity`, you need to set attribute " + "`capacity_cost` of component {}!") raise ValueError(msg.format(self.label)) else: # TODO: calculate ep_costs from specific capex if isinstance(self, GenericStorage): self.investment = Investment() else: self.investment = Investment(ep_costs=self.capacity_cost, maximum=getattr( self, 'capacity_potential', float('+inf'))) else: self.investment = None return self.investment
def test_generic_storage_with_convex_invest_offset(): """Offset value is given and nonconvex is False.""" with pytest.raises(AttributeError, match=r"If `nonconvex` is `False`, the `offset`"): bel = Bus() components.GenericStorage(label='storage6', inputs={bel: Flow()}, outputs={bel: Flow()}, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, investment=Investment(offset=10))
def test_generic_storage_with_non_convex_invest_maximum(): """No investment maximum at nonconvex investment.""" with pytest.raises(AttributeError, match=r"Please provide an maximum investment value"): bel = Bus() components.GenericStorage(label='storage6', inputs={bel: Flow()}, outputs={bel: Flow()}, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, investment=Investment(nonconvex=True))
def test_generic_storage_with_non_convex_investment(): """Tests error if `offset` and `existing` attribute are given.""" with pytest.raises(AttributeError, match=r"Values for 'offset' and 'existing' are given"): bel = Bus() components.GenericStorage(label='storage4', inputs={bel: Flow()}, outputs={bel: Flow()}, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, investment=Investment(nonconvex=True, existing=5, maximum=25))
def test_generic_storage_2(): """Nominal value defined with investment model.""" bel = Bus() with pytest.raises(AttributeError, match="If an investment object"): components.GenericStorage(label='storage3', nominal_storage_capacity=45, inputs={bel: Flow(variable_costs=10e10)}, outputs={bel: Flow(variable_costs=10e10)}, loss_rate=0.00, initial_storage_level=0, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, investment=Investment(ep_costs=23))
def test_generic_storage_1(): """Duplicate definition inflow.""" bel = Bus() with pytest.raises(AttributeError, match="Overdetermined."): components.GenericStorage(label='storage1', inputs={bel: Flow(variable_costs=10e10)}, outputs={bel: Flow(variable_costs=10e10)}, loss_rate=0.00, initial_storage_level=0, invest_relation_input_output=1, invest_relation_output_capacity=1, invest_relation_input_capacity=1, investment=Investment(), inflow_conversion_factor=1, outflow_conversion_factor=0.8)
def test_generic_storage_with_invest_and_fixed_losses_absolute(): """ Storage with fixed losses in the investment mode but no minimum or existing value is set an AttributeError is raised because this may result in storage with zero capacity but fixed losses. """ msg = (r"With fixed_losses_absolute > 0, either investment.existing or" " investment.minimum has to be non-zero.") with pytest.raises(AttributeError, match=msg): bel = Bus() components.GenericStorage( label='storage4', inputs={bel: Flow()}, outputs={bel: Flow()}, investment=Investment(ep_costs=23, minimum=0, existing=0), fixed_losses_absolute=[0, 0, 4], )
energysystem.add( Transformer(label='pp_gas', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=41, variable_costs=40)}, conversion_factors={bel: 0.50})) if invest: epc = economics.annuity(1000, 20, 0.05) energysystem.add( Transformer(label='pp_oil', inputs={boil: Flow()}, outputs={ bel: Flow(investment=Investment(ep_costs=epc, maximum=100)) }, conversion_factors={bel: 0.28})) else: energysystem.add( Transformer(label='pp_oil', inputs={boil: Flow()}, outputs={bel: Flow(nominal_value=5, variable_costs=50)}, conversion_factors={bel: 0.28})) # combined heat and power plant (chp) energysystem.add( Transformer(label='pp_chp', inputs={bgas: Flow()}, outputs={
thbus = Bus(label='thermal') logging.info('Necessary buses for the system created') # Now creating the necessary components for the system epc_pv = economics.annuity(capex=1000, n=20, wacc=0.05) epc_storage = economics.annuity(capex=100, n=5, wacc=0.05) pv = Source(label='pv', outputs={ elbus: Flow(actual_value=data['pv'], nominal_value=None, fixed=True, investment=Investment(ep_costs=epc_pv, maximum=30)) }) demand_el = Sink(label='demand_el', inputs={ elbus: Flow(nominal_value=1, actual_value=data['demand_el'], fixed=True) }) demand_th = Sink(label='demand_th', inputs={ thbus: Flow(nominal_value=1, actual_value=data['demand_th'], fixed=True)
es = EnergySystem(timeindex=datetimeindex) b_el0 = custom.ElectricalBus(label="b_0", v_min=-1, v_max=1) b_el1 = custom.ElectricalBus(label="b_1", v_min=-1, v_max=1) b_el2 = custom.ElectricalBus(label="b_2", v_min=-1, v_max=1) es.add(b_el0, b_el1, b_el2) es.add( custom.ElectricalLine( input=b_el0, output=b_el1, reactance=0.0001, investment=Investment(ep_costs=10), min=-1, max=1, ) ) es.add( custom.ElectricalLine( input=b_el1, output=b_el2, reactance=0.0001, nominal_value=60, min=-1, max=1, ) )
def build_solph_components(self): """ """ self.inflow_conversion_factor = sequence(self.efficiency) self.outflow_conversion_factor = sequence(self.efficiency) self.loss_rate = sequence(self.loss_rate) self.fixed_losses_relative = sequence(self.fixed_losses_relative) self.fixed_losses_absolute = sequence(self.fixed_losses_absolute) # make it investment but don't set costs (set below for flow (power)) self.investment = self._investment() if self.investment: self.invest_relation_input_output = 1 for attr in ["invest_relation_input_output"]: if getattr(self, attr) is None: raise AttributeError( ("You need to set attr " "`{}` " "for component {}").format(attr, self.label)) # set capacity costs at one of the flows fi = Flow(investment=Investment( ep_costs=self.capacity_cost, maximum=self.capacity_potential, existing=self.capacity, ), **self.input_parameters) # set investment, but no costs (as relation input / output = 1) fo = Flow(investment=Investment(), variable_costs=self.marginal_cost, **self.output_parameters) # required for correct grouping in oemof.solph.components self._invest_group = True else: self.volume = calculate_storage_dimensions(self.height, self.diameter)[0] self.nominal_storage_capacity = calculate_capacities( self.volume, self.temp_h, self.temp_c, **{ key: value for key, value in self.water_properties.items() if value is not None }) fi = Flow(nominal_value=self._nominal_value(), **self.input_parameters) fo = Flow(nominal_value=self._nominal_value(), variable_costs=self.marginal_cost, **self.output_parameters) self.inputs.update({self.bus: fi}) self.outputs.update({self.bus: fo}) self._set_flows()
} ################################################################# # Create oemof object ################################################################# bel = Bus(label='micro_grid') Sink(label='excess', inputs={bel: Flow(variable_costs=10e3)}) Source(label='pp_wind', outputs={ bel: Flow(nominal_value=None, fixed=True, actual_value=timeseries['wind'], investment=Investment(ep_costs=costs['pp_wind']['epc'])) }) Source(label='pp_pv', outputs={ bel: Flow(nominal_value=None, fixed=True, actual_value=timeseries['pv'], investment=Investment(ep_costs=costs['pp_wind']['epc'])) }) Source(label='pp_diesel', outputs={ bel: Flow(nominal_value=None,
datetimeindex = pd.date_range('1/1/2017', periods=2, freq='H') es = EnergySystem(timeindex=datetimeindex) b_0 = Bus(label='b_0') b_1 = Bus(label='b_1') es.add(b_0, b_1) es.add(custom.Link(label="line_0", inputs={ b_0: Flow(), b_1: Flow()}, outputs={ b_1: Flow(investment=Investment()), b_0: Flow(investment=Investment())}, conversion_factors={ (b_0, b_1): 0.95, (b_1, b_0): 0.9})) es.add(Source(label="gen_0", outputs={ b_0: Flow(nominal_value=100, variable_costs=50)})) es.add(Source(label="gen_1", outputs={ b_1: Flow(nominal_value=100, variable_costs=50)})) es.add(Sink(label="load_0", inputs={ b_0: Flow(nominal_value=150,
inputs={ bus_el: Flow(nominal_value=85, actual_value=data['demand_el'], fixed=True) }) # power plants pp_coal = Transformer( label='pp_coal', inputs={bus_coal: Flow()}, outputs={bus_el: Flow(nominal_value=40, emission_factor=0.335)}, conversion_factors={bus_el: 0.39}) storage_el = GenericStorage(label='storage_el', invest=Investment(ep_cost=412), inputs={bus_el: Flow(nominal_value=200)}, outputs={bus_el: Flow(nominal_value=200)}, loss_rate=0.01, initial_storage_level=0, max_storage_level=0.9, inflow_conversion_factor=0.9, outflow_conversion_factor=0.9) # an excess and a shortage variable can help to avoid infeasible problems excess_el = Sink(label='excess_el', inputs={bus_el: Flow()}) shortage_el = Source(label='shortage_el', outputs={bus_el: Flow(variable_costs=100000)}) # ## Add all to the energysystem
bus_el: Flow(nominal_value=1, actual_value=data['demand_el'], fixed=True) }) epc_coal = economics.annuity(capex=1500000, n=50, wacc=0.05) epc_gas = economics.annuity(capex=900000, n=20, wacc=0.05) # create power plants pp_coal = Transformer(label='pp_coal', inputs={bus_coal: Flow()}, outputs={ bus_el: Flow(investment=Investment(ep_costs=epc_coal, maximum=5e9, existing=0), variable_costs=25) }, conversion_factors={bus_el: 0.39}) pp_gas = Transformer(label='pp_gas', inputs={bus_gas: Flow()}, outputs={ bus_el: Flow(investment=Investment(ep_costs=epc_gas, maximum=5e9, existing=0), variable_costs=40) }, conversion_factors={bus_el: 0.50})
def test_lopf(solver="cbc"): logging.info("Initialize the energy system") # create time index for 192 hours in May. date_time_index = pd.date_range("5/5/2012", periods=1, freq="H") es = EnergySystem(timeindex=date_time_index) ########################################################################## # Create oemof.solph objects ########################################################################## logging.info("Create oemof.solph objects") b_el0 = custom.ElectricalBus(label="b_0", v_min=-1, v_max=1) b_el1 = custom.ElectricalBus(label="b_1", v_min=-1, v_max=1) b_el2 = custom.ElectricalBus(label="b_2", v_min=-1, v_max=1) es.add(b_el0, b_el1, b_el2) es.add( custom.ElectricalLine( input=b_el0, output=b_el1, reactance=0.0001, investment=Investment(ep_costs=10), min=-1, max=1, )) es.add( custom.ElectricalLine( input=b_el1, output=b_el2, reactance=0.0001, nominal_value=60, min=-1, max=1, )) es.add( custom.ElectricalLine( input=b_el2, output=b_el0, reactance=0.0001, nominal_value=60, min=-1, max=1, )) es.add( Source( label="gen_0", outputs={b_el0: Flow(nominal_value=100, variable_costs=50)}, )) es.add( Source( label="gen_1", outputs={b_el1: Flow(nominal_value=100, variable_costs=25)}, )) es.add(Sink( label="load", inputs={b_el2: Flow(nominal_value=100, fix=1)}, )) ########################################################################## # Optimise the energy system and plot the results ########################################################################## logging.info("Creating optimisation model") om = Model(es) logging.info("Running lopf on 3-Node exmaple system") om.solve(solver=solver) results = processing.results(om) generators = views.node_output_by_type(results, Source) generators_test_results = { (es.groups["gen_0"], es.groups["b_0"], "flow"): 20, (es.groups["gen_1"], es.groups["b_1"], "flow"): 80, } for key in generators_test_results.keys(): logging.debug("Test genertor production of {0}".format(key)) eq_( int(round(generators[key])), int(round(generators_test_results[key])), ) eq_( results[es.groups["b_2"], es.groups["b_0"]]["sequences"]["flow"][0], -40, ) eq_(results[es.groups["b_1"], es.groups["b_2"]]["sequences"]["flow"][0], 60) eq_( results[es.groups["b_0"], es.groups["b_1"]]["sequences"]["flow"][0], -20, ) # objective function eq_(round(processing.meta_results(om)["objective"]), 3200)
def test_dispatch_example(solver='cbc', periods=24*5): """Create an energy system and optimize the dispatch at least costs.""" Node.registry = None filename = os.path.join(os.path.dirname(__file__), 'input_data.csv') data = pd.read_csv(filename, sep=",") # ######################### create energysystem components ################ # resource buses bcoal = Bus(label='coal', balanced=False) bgas = Bus(label='gas', balanced=False) boil = Bus(label='oil', balanced=False) blig = Bus(label='lignite', balanced=False) # electricity and heat bel = Bus(label='b_el') bth = Bus(label='b_th') # an excess and a shortage variable can help to avoid infeasible problems excess_el = Sink(label='excess_el', inputs={bel: Flow()}) # shortage_el = Source(label='shortage_el', # outputs={bel: Flow(variable_costs=200)}) # sources ep_wind = economics.annuity(capex=1000, n=20, wacc=0.05) wind = Source(label='wind', outputs={bel: Flow( fix=data['wind'], investment=Investment(ep_costs=ep_wind, existing=100))}) ep_pv = economics.annuity(capex=1500, n=20, wacc=0.05) pv = Source(label='pv', outputs={bel: Flow( fix=data['pv'], investment=Investment(ep_costs=ep_pv, existing=80))}) # demands (electricity/heat) demand_el = Sink(label='demand_elec', inputs={bel: Flow(nominal_value=85, fix=data['demand_el'])}) demand_th = Sink(label='demand_therm', inputs={bth: Flow(nominal_value=40, fix=data['demand_th'])}) # power plants pp_coal = Transformer(label='pp_coal', inputs={bcoal: Flow()}, outputs={bel: Flow(nominal_value=20.2, variable_costs=25)}, conversion_factors={bel: 0.39}) pp_lig = Transformer(label='pp_lig', inputs={blig: Flow()}, outputs={bel: Flow(nominal_value=11.8, variable_costs=19)}, conversion_factors={bel: 0.41}) pp_gas = Transformer(label='pp_gas', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=41, variable_costs=40)}, conversion_factors={bel: 0.50}) pp_oil = Transformer(label='pp_oil', inputs={boil: Flow()}, outputs={bel: Flow(nominal_value=5, variable_costs=50)}, conversion_factors={bel: 0.28}) # combined heat and power plant (chp) pp_chp = Transformer(label='pp_chp', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=30, variable_costs=42), bth: Flow(nominal_value=40)}, conversion_factors={bel: 0.3, bth: 0.4}) # heatpump with a coefficient of performance (COP) of 3 b_heat_source = Bus(label='b_heat_source') heat_source = Source(label='heat_source', outputs={b_heat_source: Flow()}) cop = 3 heat_pump = Transformer(label='el_heat_pump', inputs={bel: Flow(), b_heat_source: Flow()}, outputs={bth: Flow(nominal_value=10)}, conversion_factors={ bel: 1/3, b_heat_source: (cop-1)/cop}) datetimeindex = pd.date_range('1/1/2012', periods=periods, freq='H') energysystem = EnergySystem(timeindex=datetimeindex) energysystem.add(bcoal, bgas, boil, bel, bth, blig, excess_el, wind, pv, demand_el, demand_th, pp_coal, pp_lig, pp_oil, pp_gas, pp_chp, b_heat_source, heat_source, heat_pump) # ################################ optimization ########################### # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver) # write back results from optimization object to energysystem optimization_model.results() # ################################ results ################################ # generic result object results = processing.results(om=optimization_model) # subset of results that includes all flows into and from electrical bus # sequences are stored within a pandas.DataFrames and scalars e.g. # investment values within a pandas.Series object. # in this case the entry data['scalars'] does not exist since no investment # variables are used data = views.node(results, 'b_el') # generate results to be evaluated in tests comp_results = data['sequences'].sum(axis=0).to_dict() comp_results['pv_capacity'] = results[(pv, bel)]['scalars'].invest comp_results['wind_capacity'] = results[(wind, bel)]['scalars'].invest test_results = { (('wind', 'b_el'), 'flow'): 9239, (('pv', 'b_el'), 'flow'): 1147, (('b_el', 'demand_elec'), 'flow'): 7440, (('b_el', 'excess_el'), 'flow'): 6261, (('pp_chp', 'b_el'), 'flow'): 477, (('pp_lig', 'b_el'), 'flow'): 850, (('pp_gas', 'b_el'), 'flow'): 934, (('pp_coal', 'b_el'), 'flow'): 1256, (('pp_oil', 'b_el'), 'flow'): 0, (('b_el', 'el_heat_pump'), 'flow'): 202, 'pv_capacity': 44, 'wind_capacity': 246, } for key in test_results.keys(): eq_(int(round(comp_results[key])), int(round(test_results[key])))
heat_source = Source( label='heat_source', outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)}) shortage = Source(label='shortage', outputs={bus_heat: Flow(variable_costs=1e6)}) excess = Sink(label='excess', inputs={bus_heat: Flow()}) heat_demand = Sink( label='heat_demand', inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}) thermal_storage = GenericStorage( label='thermal_storage', inputs={bus_heat: Flow(investment=Investment(ep_costs=50))}, outputs={bus_heat: Flow(investment=Investment(), variable_costs=0.0001)}, min_storage_level=input_data['min_storage_level'], max_storage_level=input_data['max_storage_level'], loss_rate=loss_rate, fixed_losses_relative=fixed_losses_relative, fixed_losses_absolute=fixed_losses_absolute, inflow_conversion_factor=1., outflow_conversion_factor=1., invest_relation_input_output=1, investment=Investment(ep_costs=400, minimum=1)) energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) # Create and solve the optimization model
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs, _facade_requires_=['bus']) self.storage_capacity = kwargs.get('storage_capacity') self.capacity = kwargs.get('capacity') self.nominal_capacity = self.storage_capacity self.capacity_cost = kwargs.get('capacity_cost') self.loss = sequence(kwargs.get('loss', 0)) self.inflow_conversion_factor = sequence(kwargs.get('efficiency', 1)) self.outflow_conversion_factor = sequence(kwargs.get('efficiency', 1)) # make it investment but don't set costs (set below for flow (power)) self.investment = self._investment() self.input_edge_parameters = kwargs.get('input_edge_parameters', {}) self.output_edge_parameters = kwargs.get('output_edge_parameters', {}) if self.investment: if kwargs.get('capacity_ratio') is None: raise AttributeError( ("You need to set attr `capacity_ratio` for " "component {}").format(self.label)) else: self.invest_relation_input_capacity = kwargs.get( 'capacity_ratio') self.invest_relation_output_capacity = kwargs.get( 'capacity_ratio') self.invest_relation_input_output = 1 # set capacity costs at one of the flows fi = Flow(investment=Investment(ep_costs=self.capacity_cost, maximum=getattr( self, 'capacity_potential', float('+inf'))), **self.input_edge_parameters) # set investment, but no costs (as relation input / output = 1) fo = Flow(investment=Investment(), **self.output_edge_parameters) # required for correct grouping in oemof.solph.components self._invest_group = True else: investment = None fi = Flow(nominal_value=self.capacity, **self.input_edge_parameters) fo = Flow(nominal_value=self.capacity, **self.output_edge_parameters) self.inputs.update({self.bus: fi}) self.outputs.update({self.bus: fo}) # annoying oemof stuff, that requires _set_flows() to provide a # drepreciated warning self._set_flows('Ignore this warning...')
logging.info('ENERGY SYSTEM created and initialized') # Creating the necessary buses elbus = Bus(label='elbus') logging.info('Necessary buses for the system created') # Now creating the necessary components for the system epc_pv = economics.annuity(capex=1000, n=20, wacc=0.05) epc_storage = economics.annuity(capex=1000, n=5, wacc=0.05) pv = Source(label='pv', outputs={elbus: Flow(actual_value=data['pv'], nominal_value=None, fixed=True, investment=Investment(ep_costs=epc_pv))}) demand_el = Sink(label='demand_el', inputs={elbus: Flow(nominal_value=1, actual_value=data['demand_el'], fixed=True)}) # excess_el = Sink(label='excess_el', inputs={elbus: Flow(variable_costs=0)}) # shortage_el = Source(label='shortage_el', outputs={elbus: Flow(variable_costs=1e30)}) el_storage = GenericStorage(label='el_storage', inputs={elbus: Flow(variable_costs=0.0001)}, outputs={elbus: Flow()}, loss_rate=0.00, initial_storage_level=0.6, balanced=True, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, inflow_conversion_factor=0.9, outflow_conversion_factor=0.9,
thermal_storage = GenericStorage( label='thermal_storage', inputs={ bus_heat: Flow(nominal_value=maximum_heat_flow_charging, variable_costs=0.0001) }, outputs={bus_heat: Flow(nominal_value=maximum_heat_flow_discharging)}, min_storage_level=min_storage_level, max_storage_level=max_storage_level, loss_rate=loss_rate, fixed_losses_relative=fixed_losses_relative, fixed_losses_absolute=fixed_losses_absolute, inflow_conversion_factor=1., outflow_conversion_factor=1., investment=Investment(ep_costs=400, minimum=1)) energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) # create and solve the optimization model optimization_model = Model(energysystem) optimization_model.write('storage_model.lp', io_options={'symbolic_solver_labels': True}) optimization_model.solve(solver=solver, solve_kwargs={ 'tee': False, 'keepfiles': False }) # get results results = outputlib.processing.results(optimization_model)
def test_dispatch_fix_example(solver='cbc', periods=10): """Invest in a flow with a `fix` sequence containing values > 1.""" Node.registry = None filename = os.path.join(os.path.dirname(__file__), 'input_data.csv') data = pd.read_csv(filename, sep=",") # ######################### create energysystem components ################ # electricity and heat bel = Bus(label='b_el') # an excess and a shortage variable can help to avoid infeasible problems excess_el = Sink(label='excess_el', inputs={bel: Flow()}) # shortage_el = Source(label='shortage_el', # outputs={bel: Flow(variable_costs=200)}) # sources ep_pv = economics.annuity(capex=1500, n=20, wacc=0.05) pv = Source(label='pv', outputs={ bel: Flow(fix=data['pv'], investment=Investment(ep_costs=ep_pv)) }) # demands (electricity/heat) demand_el = Sink( label='demand_elec', inputs={bel: Flow(nominal_value=85, fix=data['demand_el'])}) datetimeindex = pd.date_range('1/1/2012', periods=periods, freq='H') energysystem = EnergySystem(timeindex=datetimeindex) energysystem.add(bel, excess_el, pv, demand_el) # ################################ optimization ########################### # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver) # ################################ results ################################ # generic result object results = processing.results(om=optimization_model) # subset of results that includes all flows into and from electrical bus # sequences are stored within a pandas.DataFrames and scalars e.g. # investment values within a pandas.Series object. # in this case the entry data['scalars'] does not exist since no investment # variables are used data = views.node(results, 'b_el') # generate results to be evaluated in tests comp_results = data['sequences'].sum(axis=0).to_dict() comp_results['pv_capacity'] = results[(pv, bel)]['scalars'].invest assert comp_results[(('pv', 'b_el'), 'flow')] > 0