def test_linear_transformer_chp_invest(self): """Constraint test of a LinearTransformer with Investment (two outputs). """ bgas = Bus(label='gasBus') bheat = Bus(label='heatBus') bel = Bus(label='electricityBus') LinearTransformer(label='chp_powerplant_gas', inputs={ bgas: Flow(variable_costs=50, investment=Investment(maximum=1000, ep_costs=20)) }, outputs={ bel: Flow(), bheat: Flow() }, conversion_factors={ bel: 0.4, bheat: 0.5 }) self.compare_lp_files('linear_transformer_chp_invest.lp')
def test_linear_n1transformer_invest(self): """Constraint test of a LinearN1Transformer with Investment. """ bgas = Bus(label='gasBus') bcoal = Bus(label='coalBus') bel = Bus(label='electricityBus') LinearN1Transformer(label='powerplant_gas_coal', inputs={ bgas: Flow(), bcoal: Flow() }, outputs={ bel: Flow(variable_costs=50, investment=Investment(maximum=1000, ep_costs=20)) }, conversion_factors={ bgas: 0.58, bcoal: 0.2 }) self.compare_lp_files('linear_n1_transformer_invest.lp')
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_linear_transformer(self): """Constraint test of a LinearTransformer without Investment. """ bgas = Bus(label='gas') bel = Bus(label='electricity') LinearTransformer( label='powerplantGas', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=10e10, variable_costs=50)}, conversion_factors={bel: 0.58}) self.compare_lp_files('linear_transformer.lp')
def initialize_basic_energysystem(): # initialize and provide data datetimeindex = pd.date_range('1/1/2016', periods=24, freq='H') filename = 'input_data.csv' data = pd.read_csv(filename, sep=",") energysystem = EnergySystem(timeindex=datetimeindex) # buses bcoal = Bus(label='coal', balanced=False) bgas = Bus(label='gas', balanced=False) bel = Bus(label='electricity') energysystem.add(bcoal, bgas, bel) # sources energysystem.add( Source(label='wind', outputs={ bel: Flow(actual_value=data['wind'], nominal_value=66.3, fixed=True) })) energysystem.add( Source(label='pv', outputs={ bel: Flow(actual_value=data['pv'], nominal_value=65.3, fixed=True) })) # excess and shortage to avoid infeasibilies energysystem.add(Sink(label='excess_el', inputs={bel: Flow()})) energysystem.add( Source(label='shortage_el', outputs={bel: Flow(variable_costs=200)})) # demands (electricity/heat) energysystem.add( Sink(label='demand_el', inputs={ bel: Flow(nominal_value=85, actual_value=data['demand_el'], fixed=True) })) return bcoal, bgas, bel, energysystem
def test_fixed_source_invest_sink(self): """ Wrong constraints for fixed source + invest sink w. `summed_max`. """ bel = Bus(label='electricityBus') Source(label='wind', outputs={ bel: Flow(actual_value=[12, 16, 14], nominal_value=1000000, fixed=True, fixed_costs=20) }) Sink(label='excess', inputs={ bel: Flow(summed_max=2.3, variable_costs=25, max=0.8, investment=Investment(ep_costs=500, maximum=10e5)) }) self.compare_lp_files('fixed_source_invest_sink.lp')
def test_offsettransformer_wrong_flow_type(): """No NonConvexFlow for Inflow defined.""" with pytest.raises(TypeError, match=r'Input flows must be of type NonConvexFlow!'): bgas = Bus(label='gasBus') components.OffsetTransformer(label='gasboiler', inputs={bgas: Flow()}, coefficients=(-17, 0.9))
def test_generic_chp_without_warning(): warnings.filterwarnings("error", category=SuspiciousUsageWarning) bel = Bus(label='electricityBus') bth = Bus(label='heatBus') bgas = Bus(label='commodityBus') components.GenericCHP(label='combined_cycle_extraction_turbine', fuel_input={bgas: Flow(H_L_FG_share_max=[0.183])}, electrical_output={ bel: Flow(P_max_woDH=[155.946], P_min_woDH=[68.787], Eta_el_max_woDH=[0.525], Eta_el_min_woDH=[0.444]) }, heat_output={bth: Flow(Q_CW_min=[10.552])}, Beta=[0.122], back_pressure=False) warnings.filterwarnings("always", category=SuspiciousUsageWarning)
def add_decentralised_heating_systems(table_collection, nodes, extra_regions): logging.debug("Add decentralised_heating_systems to nodes dictionary.") cs = table_collection["commodity_source"]["DE"] dts = table_collection["demand_series"] dh = table_collection["decentralised_heat"] demand_regions = list({"DE_demand"}.union(set(extra_regions))) for d_region in demand_regions: region_name = d_region.replace("_demand", "") if region_name not in dh: data_name = "DE_demand" else: data_name = d_region fuels = [f for f in dh[data_name].columns if f in dts[d_region]] for fuel in fuels: src = dh.loc["source", (data_name, fuel)] bus_label = Label("bus", "commodity", src.replace(" ", "_"), region_name) # Check if source bus exists if bus_label not in nodes: create_fuel_bus_with_source(nodes, src, region_name, cs) # Create heating bus as Bus heat_bus_label = Label("bus", "heat", fuel.replace(" ", "_"), region_name) nodes[heat_bus_label] = Bus(label=heat_bus_label) # Create heating system as Transformer trsf_label = Label("trsf", "heat", fuel.replace(" ", "_"), region_name) efficiency = float(dh.loc["efficiency", (data_name, fuel)]) nodes[trsf_label] = Transformer( label=trsf_label, inputs={nodes[bus_label]: Flow()}, outputs={nodes[heat_bus_label]: Flow()}, conversion_factors={nodes[heat_bus_label]: efficiency}, ) # Create demand as Sink d_heat_demand_label = Label("demand", "heat", fuel.replace(" ", "_"), region_name) nodes[d_heat_demand_label] = Sink( label=d_heat_demand_label, inputs={ nodes[heat_bus_label]: Flow( actual_value=dts[d_region, fuel], nominal_value=1, fixed=True, ) }, )
def test_offsettransformer_too_many_output_flows(): """Too many Output Flows defined.""" with pytest.raises(ValueError, match='OffsetTransformer` must not have more than 1'): bm1 = Bus(label='my_offset_Bus1') bm2 = Bus(label='my_offset_Bus2') components.OffsetTransformer(label='ostf_2_out', inputs={ bm1: Flow(nominal_value=60, min=0.5, max=1.0, nonconvex=NonConvex()) }, outputs={ bm1: Flow(), bm2: Flow() }, coefficients=(20, 0.5))
def test_offsettransformer__too_many_input_flows(): """Too many Input Flows defined.""" with pytest.raises(ValueError, match=r"OffsetTransformer` must not have more than 1"): bgas = Bus(label='GasBus') bcoal = Bus(label='CoalBus') components.OffsetTransformer(label='ostf_2_in', inputs={ bgas: Flow(nominal_value=60, min=0.5, max=1.0, nonconvex=NonConvex()), bcoal: Flow(nominal_value=30, min=0.3, max=1.0, nonconvex=NonConvex()) }, coefficients=(20, 0.5))
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_linear_n1transformer(self): """Constraint test of a LinearN1Transformer without Investment. """ bgas = Bus(label='gasBus') bbms = Bus(label='biomassBus') bel = Bus(label='electricityBus') LinearN1Transformer( label='powerplantGasCoal', inputs={ bbms: Flow(), bgas: Flow() }, outputs={bel: Flow(nominal_value=10e10, variable_costs=50)}, conversion_factors={ bgas: 0.4, bbms: 0.1 }) self.compare_lp_files('linear_n1_transformer.lp')
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_variable_chp(self): """ """ bel = Bus(label='electricityBus') bth = Bus(label='heatBus') bgas = Bus(label='commodityBus') VariableFractionTransformer( label='variable_chp_gas', inputs={bgas: solph.Flow(nominal_value=100)}, outputs={ bel: solph.Flow(), bth: solph.Flow() }, conversion_factors={ bel: 0.3, bth: 0.5 }, conversion_factor_single_flow={bel: 0.5}) self.compare_lp_files('variable_chp.lp')
def test_generic_storage_3(): """Nominal value defined with investment model.""" bel = Bus() components.GenericStorage( label='storage4', nominal_storage_capacity=45, inputs={bel: Flow(nominal_value=23, variable_costs=10e10)}, outputs={bel: Flow(nominal_value=7.5, variable_costs=10e10)}, loss_rate=0.00, initial_storage_level=0, inflow_conversion_factor=1, outflow_conversion_factor=0.8)
def test_linear_transformer_chp(self): """Constraint test of a LinearTransformer without Investment (two outputs). """ bgas = Bus(label='gasBus') bheat = Bus(label='heatBus') bel = Bus(label='electricityBus') LinearTransformer( label='CHPpowerplantGas', inputs={bgas: Flow(nominal_value=10e10, variable_costs=50)}, outputs={ bel: Flow(), bheat: Flow() }, conversion_factors={ bel: 0.4, bheat: 0.5 }) self.compare_lp_files('linear_transformer_chp.lp')
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 __init__(self, *args, **kwargs): super().__init__(*args, **kwargs, _facade_requires_=['bus', 'inflow', 'efficiency']) self.storage_capacity = kwargs.get('storage_capacity') self.capacity = kwargs.get('capacity') self.efficiency = kwargs.get('efficiency') self.nominal_capacity = self.storage_capacity self.capacity_cost = kwargs.get('capacity_cost') self.storage_capacity_cost = kwargs.get('storage_capacity_cost') self.spillage = kwargs.get('spillage', True) self.input_edge_parameters = kwargs.get('input_edge_parameters', {}) self.output_edge_parameters = kwargs.get('output_edge_parameters', {}) investment = self._investment() reservoir_bus = Bus(label="reservoir-bus-" + self.label) inflow = Source(label="inflow" + self.label, outputs={ reservoir_bus: Flow(nominal_value=1, actual_value=self.inflow, fixed=True) }) if self.spillage: f = Flow() else: f = Flow(actual_value=0, fixed=True) spillage = Sink(label="spillage" + self.label, inputs={reservoir_bus: f}) self.inputs.update({reservoir_bus: Flow(**self.input_edge_parameters)}) self.outputs.update({ self.bus: Flow(investment=investment, **self.output_edge_parameters) }) self.subnodes = (reservoir_bus, inflow, spillage)
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_max_source_min_sink(self): """ """ bel = Bus(label='electricityBus') Source(label='wind', outputs={bel: Flow(nominal_value=54, max=(.85, .95, .61))}) Sink(label='minDemand', inputs={ bel: Flow(nominal_value=54, min=(.84, .94, .59), variable_costs=14) }) self.compare_lp_files('max_source_min_sink.lp')
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], )
def test_storage(self): """ """ bel = Bus(label='electricityBus') Storage(label='storage', inputs={bel: Flow(variable_costs=56)}, outputs={bel: Flow(variable_costs=24)}, nominal_capacity=10e4, capacity_loss=0.13, nominal_input_capacity_ratio=1 / 6, nominal_output_capacity_ratio=1 / 6, inflow_conversion_factor=0.97, outflow_conversion_factor=0.86, fixed_costs=35) self.compare_lp_files('storage.lp')
def test_fixed_source_variable_sink(self): """Constraint test with a fixed source and a variable sink. """ bel = Bus(label='electricityBus') Source(label='wind', outputs={ bel: Flow(actual_value=[.43, .72, .29], nominal_value=10e5, fixed=True, fixed_costs=20) }) Sink(label='excess', inputs={bel: Flow(variable_costs=40)}) self.compare_lp_files('fixed_source_variable_sink.lp')
def add_volatile_sources(table_collection, nodes): """ Parameters ---------- table_collection nodes Returns ------- """ logging.debug("Add volatile sources to nodes dictionary.") vs = table_collection["volatile_source"] for region in vs.columns.get_level_values(0).unique(): for vs_type in vs[region].columns: vs_label = Label("source", "ee", vs_type, region) capacity = vs.loc["capacity", (region, vs_type)] try: feedin = table_collection["volatile_series"][region, vs_type] except KeyError: if capacity > 0: msg = "Missing time series for {0} (capacity: {1}) in {2}." raise ValueError(msg.format(vs_type, capacity, region)) feedin = [0] bus_label = Label("bus", "electricity", "all", region) if bus_label not in nodes: nodes[bus_label] = Bus(label=bus_label) if capacity * sum(feedin) > 0: nodes[vs_label] = Source( label=vs_label, outputs={ nodes[bus_label]: Flow( actual_value=feedin, nominal_value=capacity, fixed=True, emission=0, ) }, )
def add_district_heating_systems(table_collection, nodes): logging.debug("Add district heating systems to nodes dictionary.") dts = table_collection["demand_series"] for region in dts["district heating"].columns: if dts["district heating"][region].sum() > 0: bus_label = Label("bus", "heat", "district", region) if bus_label not in nodes: nodes[bus_label] = Bus(label=bus_label) heat_demand_label = Label("demand", "heat", "district", region) nodes[heat_demand_label] = Sink( label=heat_demand_label, inputs={ nodes[bus_label]: Flow( actual_value=dts["district heating", region], nominal_value=1, fixed=True, ) }, )
def create_fuel_bus_with_source(nodes, fuel, region, data): bus_label = Label("bus", "commodity", fuel.replace(" ", "_"), region) if bus_label not in nodes: nodes[bus_label] = Bus(label=bus_label) cs_label = Label("source", "commodity", fuel.replace(" ", "_"), region) if cs_label not in nodes: nodes[cs_label] = Source( label=cs_label, outputs={ nodes[bus_label]: Flow( variable_costs=data.loc["costs", fuel.replace("_", " ")], emission=data.loc["emission", fuel.replace("_", " ")], ) }, )
def test_storage_invest(self): """ """ bel = Bus(label='electricityBus') Storage(label='storage', inputs={bel: Flow(variable_costs=56)}, outputs={bel: Flow(variable_costs=24)}, nominal_capacity=None, capacity_loss=0.13, capacity_max=0.9, capacity_min=0.1, nominal_input_capacity_ratio=1 / 6, nominal_output_capacity_ratio=1 / 6, inflow_conversion_factor=0.97, outflow_conversion_factor=0.86, fixed_costs=35, investment=Investment(ep_costs=145, maximum=234)) self.compare_lp_files('storage_invest.lp')
def add_electricity_demand(table_collection, nodes): logging.debug("Add local electricity demand to nodes dictionary.") dts = table_collection["demand_series"] dts.columns = dts.columns.swaplevel() for region in dts["electrical_load"].columns: if dts["electrical_load"][region].sum() > 0: bus_label = Label("bus", "electricity", "all", region) if bus_label not in nodes: nodes[bus_label] = Bus(label=bus_label) elec_demand_label = Label("demand", "electricity", "all", region) nodes[elec_demand_label] = Sink( label=elec_demand_label, inputs={ nodes[bus_label]: Flow( actual_value=dts["electrical_load", region], nominal_value=1, fixed=True, ) }, )