def source_dispatchable_fix(model, dict_asset, **kwargs): r""" Defines a dispatchable source with a fixed capacity. See :py:func:`~.source` for more information, including parameters. Notes ----- Tested with: - test_source_dispatchable_fix_normalized_timeseries() - test_source_dispatchable_fix_timeseries_not_normalized_timeseries() Returns ------- Indirectly updated `model` and dict of asset in `kwargs` with the source object. """ if TIMESERIES_NORMALIZED in dict_asset: outputs = { kwargs[OEMOF_BUSSES][dict_asset[OUTFLOW_DIRECTION]]: solph.Flow( label=dict_asset[LABEL], max=dict_asset[TIMESERIES_NORMALIZED], existing=dict_asset[INSTALLED_CAP][VALUE], variable_costs=dict_asset[DISPATCH_PRICE][VALUE], # add emission_factor for emission contraint emission_factor=dict_asset[EMISSION_FACTOR][VALUE], ) } source_dispatchable = solph.Source( label=dict_asset[LABEL], outputs=outputs, ) else: if TIMESERIES in dict_asset: logging.info( f"Asset {dict_asset[LABEL]} is introduced as a dispatchable source with an availability schedule." ) logging.debug( f"The availability schedule is solely introduced because the key {TIMESERIES_NORMALIZED} was not in the asset´s dictionary. \n" f"It should only be applied to DSO sources. " f"If the asset should not have this behaviour, please create an issue.", ) outputs = { kwargs[OEMOF_BUSSES][dict_asset[OUTFLOW_DIRECTION]]: solph.Flow( label=dict_asset[LABEL], existing=dict_asset[INSTALLED_CAP][VALUE], variable_costs=dict_asset[DISPATCH_PRICE][VALUE], ) } source_dispatchable = solph.Source( label=dict_asset[LABEL], outputs=outputs, ) model.add(source_dispatchable) kwargs[OEMOF_SOURCE].update({dict_asset[LABEL]: source_dispatchable}) logging.debug( f"Added: Dispatchable source {dict_asset[LABEL]} (fixed capacity) to bus {dict_asset[OUTFLOW_DIRECTION]}." )
def test_something_else(): date_time_index = pd.date_range('1/1/2012', periods=5, freq='H') energysystem = solph.EnergySystem(timeindex=date_time_index) bel1 = solph.Bus(label='electricity1') bel2 = solph.Bus(label='electricity2') energysystem.add(bel1, bel2) energysystem.add( solph.Transformer( label='powerline_1_2', inputs={bel1: solph.Flow()}, outputs={ bel2: solph.Flow(investment=solph.Investment(ep_costs=20)) })) energysystem.add( solph.Transformer( label='powerline_2_1', inputs={bel2: solph.Flow()}, outputs={ bel1: solph.Flow(investment=solph.Investment(ep_costs=20)) })) om = solph.Model(energysystem) line12 = energysystem.groups['powerline_1_2'] line21 = energysystem.groups['powerline_2_1'] solph.constraints.equate_variables(om, om.InvestmentFlow.invest[line12, bel2], om.InvestmentFlow.invest[line21, bel1], name="my_name")
def add_to_oemof_model(self, busses, model): """Creates an oemof Transformer component from the information given in the Electrolyzer class, to be used in the oemof model :param busses: virtual buses used in the energy system :type busses: dict :param model: current oemof model :type model: oemof model :return: oemof component """ # Get the non-linear behaviour. self.update_nonlinear_behaviour() # Create the non-linear oemof component. electrolyzer = solph.custom.PiecewiseLinearTransformer( label=self.name, inputs={ busses[self.bus_el]: solph.Flow(nominal_value=self.energy_max, variable_costs=0) }, outputs={busses[self.bus_h2]: solph.Flow()}, in_breakpoints=self.supporting_points['energy'], conversion_function=self.conversion_fun_ely, pw_repn='CC') model.add(electrolyzer) return electrolyzer
def test_fixed_source_invest_sink(self): """ Wrong constraints for fixed source + invest sink w. `summed_max`. """ bel = solph.Bus(label='electricityBus') solph.Source(label='wind', outputs={ bel: solph.Flow(actual_value=[12, 16, 14], nominal_value=1000000, fixed=True) }) solph.Sink(label='excess', inputs={ bel: solph.Flow(summed_max=2.3, variable_costs=25, max=0.8, investment=solph.Investment(ep_costs=500, maximum=10e5, existing=50)) }) self.compare_lp_files('fixed_source_invest_sink.lp')
def test_linear_transformer_chp_invest(self): """Constraint test of a Transformer with Investment (two outputs). """ bgas = solph.Bus(label='gasBus') bheat = solph.Bus(label='heatBus') bel = solph.Bus(label='electricityBus') solph.Transformer(label='chp_powerplant_gas', inputs={ bgas: solph.Flow(variable_costs=50, investment=solph.Investment( maximum=1000, ep_costs=20)) }, outputs={ bel: solph.Flow(), bheat: solph.Flow() }, conversion_factors={ bel: 0.4, bheat: 0.5 }) self.compare_lp_files('linear_transformer_chp_invest.lp')
def test_transformer(self): """Constraint test of a LinearN1Transformer without Investment. """ bgas = solph.Bus(label='gasBus') bbms = solph.Bus(label='biomassBus') bel = solph.Bus(label='electricityBus') bth = solph.Bus(label='thermalBus') solph.Transformer(label='powerplantGasCoal', inputs={ bbms: solph.Flow(), bgas: solph.Flow() }, outputs={ bel: solph.Flow(variable_costs=50), bth: solph.Flow(nominal_value=5e10, variable_costs=20) }, conversion_factors={ bgas: 0.4, bbms: 0.1, bel: 0.3, bth: 0.5 }) self.compare_lp_files('transformer.lp')
def test_transformer_invest_with_existing(self): """Constraint test of a LinearN1Transformer with Investment. """ bgas = solph.Bus(label='gasBus') bcoal = solph.Bus(label='coalBus') bel = solph.Bus(label='electricityBus') bth = solph.Bus(label='thermalBus') solph.Transformer(label='powerplant_gas_coal', inputs={ bgas: solph.Flow(), bcoal: solph.Flow() }, outputs={ bel: solph.Flow(variable_costs=50, investment=solph.Investment( maximum=1000, ep_costs=20, existing=200)), bth: solph.Flow(variable_costs=20) }, conversion_factors={ bgas: 0.58, bcoal: 0.2, bel: 0.3, bth: 0.5 }) self.compare_lp_files('transformer_invest_with_existing.lp')
def add_to_oemof_model(self, busses, model): """Creates an oemof Transformer component using the information given in the CompressorH2 class, to be used in the oemof model :param busses: virtual buses used in the energy system :type busses: dict :param model: current oemof model :type model: oemof model :return: oemof component """ compressor = solph.Transformer( label=self.name, inputs={ busses[self.bus_h2_in]: solph.Flow(nominal_value=self.m_flow_max * self.sim_params.interval_time / 60), busses[self.bus_el]: solph.Flow() }, outputs={busses[self.bus_h2_out]: solph.Flow()}, conversion_factors={ busses[self.bus_h2_in]: 1, busses[self.bus_el]: self.spec_compression_energy, busses[self.bus_h2_out]: 1 }) model.add(compressor) return compressor
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 add_to_oemof_model(self, busses, model): """Creates an oemof Generic Storage component from the information given in the StorageH2 class, to be used in the oemof model. :param busses: virtual buses used in the energy system :type busses: dict :param model: current oemof model :type model: oemof model :return: oemof component """ storage = solph.components.GenericStorage( label=self.name, outputs={ busses[self.bus_out]: solph.Flow(nominal_value=self.delta_max, variable_costs=self.current_vac[1]) }, inputs={ busses[self.bus_in]: solph.Flow(nominal_value=self.delta_max, variable_costs=self.current_vac[0]) }, initial_storage_level=self.storage_level / self.storage_capacity, nominal_storage_capacity=self.storage_capacity, min_storage_level=self.storage_level_min / self.storage_capacity, balanced=False) model.add(storage) return storage
def add_to_oemof_model(self, busses, model): """Creates an oemof Generic Storage component from the information given in the Battery class, to be used in the oemof model. :param busses: virtual buses used in the energy system :type busses: dict :param model: current oemof model :type model: oemof model :return: oemof component """ battery = solph.components.GenericStorage( label=self.name, inputs={ busses[self.bus_in_and_out]: solph.Flow(nominal_value=self.p_in_max, variable_costs=self.current_vac[0]) }, outputs={ busses[self.bus_in_and_out]: solph.Flow(nominal_value=self.p_out_max, variable_costs=self.current_vac[1]) }, loss_rate=self.loss_rate, initial_storage_level=self.soc, nominal_storage_capacity=self.battery_capacity, min_storage_level=self.soc_min, inflow_conversion_factor=self.efficiency_charge, outflow_conversion_factor=self.efficiency_discharge, balanced=False, ) model.add(battery) return battery
def test_shared_limit(self): """ """ b1 = solph.Bus(label='bus') storage1 = solph.components.GenericStorage(label="storage1", nominal_storage_capacity=5, inputs={b1: solph.Flow()}, outputs={b1: solph.Flow()}) storage2 = solph.components.GenericStorage(label="storage2", nominal_storage_capacity=5, inputs={b1: solph.Flow()}, outputs={b1: solph.Flow()}) model = self.get_om() components = [storage1, storage2] solph.constraints.shared_limit( model, model.GenericStorageBlock.storage_content, "limit_storage", components, [0.5, 1.25], upper_limit=7) self.compare_lp_files('shared_limit.lp', my_om=model)
def test_nonconvex_investment_storage_with_offset(self): """All invest variables are coupled. The invest variables of the Flows will be created during the initialisation of the storage e.g. battery """ bel = solph.Bus(label='electricityBus') solph.components.GenericStorage( label='storagenon_convex', inputs={bel: solph.Flow(variable_costs=56)}, outputs={bel: solph.Flow(variable_costs=24)}, nominal_storage_capacity=None, loss_rate=0.13, max_storage_level=0.9, min_storage_level=0.1, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, inflow_conversion_factor=0.97, outflow_conversion_factor=0.86, investment=solph.Investment(ep_costs=145, minimum=19, offset=5, nonconvex=True, maximum=1454)) self.compare_lp_files('storage_invest_with_offset.lp')
def test_nonconvex_invest_storage_all_nonconvex(self): """All invest variables are free and nonconvex.""" b1 = solph.Bus(label='bus1') solph.components.GenericStorage( label='storage_all_nonconvex', inputs={ b1: solph.Flow(investment=solph.Investment(nonconvex=True, minimum=5, offset=10, maximum=30, ep_costs=10)) }, outputs={ b1: solph.Flow(investment=solph.Investment(nonconvex=True, minimum=8, offset=15, ep_costs=10, maximum=20)) }, investment=solph.Investment(nonconvex=True, ep_costs=20, offset=30, minimum=20, maximum=100)) self.compare_lp_files('storage_invest_all_nonconvex.lp')
def test_generic_invest_limit(self): """ """ bus = solph.Bus(label='bus_1') solph.Source( label='source_0', outputs={ bus: solph.Flow(investment=solph.Investment(ep_costs=50, space=4)) }) solph.Source( label='source_1', outputs={ bus: solph.Flow(investment=solph.Investment(ep_costs=100, space=1)) }) solph.Source(label='source_2', outputs={ bus: solph.Flow(investment=solph.Investment(ep_costs=75)) }) om = self.get_om() om = solph.constraints.additional_investment_flow_limit(om, "space", limit=20) self.compare_lp_files('generic_invest_limit.lp', my_om=om)
def check_oemof_installation(silent=False): date_time_index = pd.date_range('1/1/2012', periods=5, freq='H') energysystem = solph.EnergySystem(timeindex=date_time_index) bgas = solph.Bus(label="natural_gas") bel = solph.Bus(label="electricity") solph.Sink(label='excess_bel', inputs={bel: solph.Flow()}) solph.Source(label='rgas', outputs={bgas: solph.Flow()}) solph.Sink(label='demand', inputs={bel: solph.Flow( actual_value=[10, 20, 30, 40, 50], fixed=True, nominal_value=1)}) solph.Transformer( label="pp_gas", inputs={bgas: solph.Flow()}, outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)}, conversion_factors={bel: 0.58}) om = solph.Model(energysystem) # check solvers solver = dict() for s in ['cbc', 'glpk', 'gurobi', 'cplex']: try: om.solve(solver=s) solver[s] = "working" except Exception: solver[s] = "not working" if not silent: print("*********") print('Solver installed with oemof:') for s, t in solver.items(): print("{0}: {1}".format(s, t)) print("*********") print("oemof successfully installed.")
def auxiliary_transformer(label, input_bus, output_bus): r""" Get auxiliary transformer for Generic Model energy system. Parameters ---------- label : str Spezific label to reference transformer. input_bus : solph.Bus Spezific input bus to reference transformer. output_bus : solph.Bus Spezific output bus to reference transformer. Note ---- Auxiliary transformers are used to represent more complex networks. In solph individual busses have to be connected by a componente, in this case by 'auxiliary transformer'. In the Generic Model, these are used for the solar thermal and storage strand. The flow is not transformed, but transferred in an auxiliary way to make the calculation feasible. """ auxiliary_transformer = solph.Transformer( label=label, inputs={input_bus: solph.Flow()}, outputs={output_bus: solph.Flow(nominal_value=1, max=inf, min=0.0)}, conversion_factors={output_bus: 1}) return auxiliary_transformer
def add_electricity_storages(table_collection, nodes): """ Parameters ---------- table_collection nodes Returns ------- """ for idx, params in table_collection["electricity storages"].iterrows(): region = idx[0] name = idx[1] storage_label = Label("storage", "electricity", name, region) bus_label = Label("bus", "electricity", "all", region) nodes[storage_label] = solph.components.GenericStorage( label=storage_label, inputs={ nodes[bus_label]: solph.Flow( nominal_value=params["charge capacity"] ) }, outputs={ nodes[bus_label]: solph.Flow( nominal_value=params["discharge capacity"] ) }, nominal_storage_capacity=params["energy content"], loss_rate=params["loss rate"], initial_storage_level=None, inflow_conversion_factor=params["charge efficiency"], outflow_conversion_factor=params["discharge efficiency"], )
def test_equate_variables_constraint(self): """Testing the equate_variables function in the constraint module.""" bus1 = solph.Bus(label='Bus1') storage = solph.components.GenericStorage( label='storage_constraint', invest_relation_input_capacity=0.2, invest_relation_output_capacity=0.2, inputs={bus1: solph.Flow()}, outputs={bus1: solph.Flow()}, investment=solph.Investment(ep_costs=145)) sink = solph.Sink( label='Sink', inputs={ bus1: solph.Flow(investment=solph.Investment(ep_costs=500)) }) source = solph.Source( label='Source', outputs={ bus1: solph.Flow(investment=solph.Investment(ep_costs=123)) }) om = self.get_om() solph.constraints.equate_variables( om, om.InvestmentFlow.invest[source, bus1], om.InvestmentFlow.invest[bus1, sink], 2) solph.constraints.equate_variables( om, om.InvestmentFlow.invest[source, bus1], om.GenericInvestmentStorageBlock.invest[storage]) self.compare_lp_files('connect_investment.lp', my_om=om)
def add_storage(it, labels, nodes, busd): """Adds oemof.solph.GenericStorage objects to the list of components. If attribute `invest` is *True*, the investment version of the Storage is created. Parameters ---------- it : pd.DataFrame Table of storage attributes of the producers / consumers. labels : dict Dictonary containing specifications for label-tuple. nodes : list All oemof.solph components are added to the list. busd : dict All oemof.solph.Bus objects are given by this dictionary. Returns ------- list : Updated list of nodes. """ for _, s in it.iterrows(): label_storage = oh.Label(labels['l_1'], s['bus'], s['label'], labels['l_4']) label_bus = busd[(labels['l_1'], s['bus'], 'bus', labels['l_4'])] if s['invest']: epc_s = s['capex'] nodes.append( solph.components.GenericStorage( label=label_storage, inputs={label_bus: solph.Flow()}, outputs={label_bus: solph.Flow()}, loss_rate=s['capacity_loss'], fixed_losses_relative=s['fixed_losses_relative'], invest_relation_input_capacity=s[ 'invest_relation_input_capacity'], invest_relation_output_capacity=s[ 'invest_relation_output_capacity'], inflow_conversion_factor=s['inflow_conversion_factor'], outflow_conversion_factor=s[ 'outflow_conversion_factor'], investment=solph.Investment(ep_costs=epc_s))) else: nodes.append( solph.components.GenericStorage( label=label_storage, inputs={label_bus: solph.Flow()}, outputs={label_bus: solph.Flow()}, loss_rate=s['capacity_loss'], fixed_losses_relative=s['fixed_losses_relative'], nominal_storage_capacity=s['capacity'], inflow_conversion_factor=s['inflow_conversion_factor'], outflow_conversion_factor=s[ 'outflow_conversion_factor'])) return nodes
def add_transmission_lines_between_electricity_nodes(table_collection, nodes): """ Parameters ---------- table_collection nodes Returns ------- """ logging.debug("Add transmission lines to nodes dictionary.") power_lines = table_collection["power lines"] for idx, values in power_lines.iterrows(): b1, b2 = idx.split("-") lines = [(b1, b2), (b2, b1)] for line in lines: line_label = Label("line", "electricity", line[0], line[1]) bus_label_in = Label("bus", "electricity", "all", line[0]) bus_label_out = Label("bus", "electricity", "all", line[1]) if bus_label_in not in nodes: raise ValueError( "Bus {0} missing for power line from {0} to {1}".format( bus_label_in, bus_label_out ) ) if bus_label_out not in nodes: raise ValueError( "Bus {0} missing for power line from {0} to {1}".format( bus_label_out, bus_label_in ) ) if values.capacity != float("inf"): logging.debug( "Line %s has a capacity of %s", line_label, values.capacity ) nodes[line_label] = solph.Transformer( label=line_label, inputs={nodes[bus_label_in]: solph.Flow()}, outputs={ nodes[bus_label_out]: solph.Flow( nominal_value=values.capacity ) }, conversion_factors={ nodes[bus_label_out]: values.efficiency }, ) else: logging.debug("Line %s has no capacity limit", line_label) nodes[line_label] = solph.Transformer( label=line_label, inputs={nodes[bus_label_in]: solph.Flow()}, outputs={nodes[bus_label_out]: solph.Flow()}, conversion_factors={ nodes[bus_label_out]: values.efficiency }, )
def define_emission_limit(): bel = solph.Bus(label='electricityBus') solph.Source(label='source1', outputs={bel: solph.Flow( nominal_value=100, emission=0.8)}) solph.Source(label='source2', outputs={bel: solph.Flow( nominal_value=100)}) om = self.get_om() solph.constraints.emission_limit(om, om.flows, limit=777)
def test_min_max_values_for_bidirectional_flow(): a = solph.Flow(bidirectional=True) # use default values b = solph.Flow(bidirectional=True, min=-0.9, max=0.9) assert a.bidirectional assert a.max[0] == 1 assert a.min[0] == -1 assert b.max[0] == 0.9 assert b.min[0] == -0.9
def add_heatpipes(it, labels, gd, q, b_in, b_out, nodes): """ Adds *HeatPipeline* objects with *Investment* attribute to the list of oemof.solph components. Parameters ---------- it : pd.DataFrame Table of *Heatpipeline* attributes of the district heating grid labels : dict Dictonary containing specifications for label-tuple gd : dict Settings of the investment optimisation of the ThermalNetwork q : pd.Series Specific *Pipe* of ThermalNetwork b_in : oemof.solph.Bus Bus of Inflow b_out : oemof.solph.Bus Bus of Outflow nodes : list All oemof.solph components are added to the list Returns ------- list : Updated list of nodes. """ for _, t in it.iterrows(): # definition of tag3 of label -> type of pipe labels['l_3'] = t['label_3'] epc_p = t['capex_pipes'] * q['length'] epc_fix = t['fix_costs'] * q['length'] # Heatpipe with binary variable nc = bool(t['nonconvex']) # bidirectional heatpipelines yes or no flow_bi_args = { 'bidirectional': True, 'min': -1}\ if gd['bidirectional_pipes'] else {} nodes.append(oh.HeatPipeline( label=oh.Label(labels['l_1'], labels['l_2'], labels['l_3'], labels['l_4']), inputs={b_in: solph.Flow(**flow_bi_args)}, outputs={b_out: solph.Flow( nominal_value=None, **flow_bi_args, investment=solph.Investment( ep_costs=epc_p, maximum=t['cap_max'], minimum=t['cap_min'], nonconvex=nc, offset=epc_fix, ))}, heat_loss_factor=t['l_factor'] * q['length'], heat_loss_factor_fix=t['l_factor_fix'] * q['length'], )) return nodes
def add_power_plants(table_collection, nodes): """ Parameters ---------- table_collection nodes Returns ------- """ pp = table_collection["power plants"] check_in_out_buses(nodes, pp, table_collection) for idx, params in pp.iterrows(): region = idx[0] # Create label for in and out bus: fuel_bus = Label( "bus", "commodity", params.fuel, params["source region"] ) bus_elec = Label("bus", "electricity", "all", region) # Create power plants as 1x1 Transformer if capacity > 0 if params.capacity > 0: # if downtime_factor is in the parameters, use it if hasattr(params, "downtime_factor"): params.capacity *= 1 - params["downtime_factor"] # Define output flow with or without summed_max attribute if params.get("annual_limit_electricity", float("inf")) == float( "inf" ): outflow = solph.Flow(nominal_value=params.capacity) else: smax = params.annual_limit_electricity / params.capacity outflow = solph.Flow( nominal_value=params.capacity, summed_max=smax ) # if variable costs are defined add them to the outflow if hasattr(params, "variable_costs"): vc = params.variable_costs outflow.variable_costs = solph.sequence(vc) plant_name = idx[1].replace(" - ", "_").replace(".", "") trsf_label = Label("trsf", "pp", plant_name, region) nodes[trsf_label] = solph.Transformer( label=trsf_label, inputs={nodes[fuel_bus]: solph.Flow()}, outputs={nodes[bus_elec]: outflow}, conversion_factors={nodes[bus_elec]: params.efficiency}, )
def test_flow_classes(): with assert_raises(ValueError): solph.Flow(fixed=True) with assert_raises(ValueError): solph.Flow(investment=solph.Investment(), nominal_value=4) with assert_raises(ValueError): solph.Flow(investment=solph.Investment(), nonconvex=solph.NonConvex()) with assert_raises(AttributeError): solph.Flow(fixed_costs=34)
def test_flow_without_emission_for_emission_constraint_no_error(self): """ """ bel = solph.Bus(label='electricityBus') solph.Source(label='source1', outputs={bel: solph.Flow( nominal_value=100, emission=0.8)}) solph.Source(label='source2', outputs={bel: solph.Flow( nominal_value=100)}) om = self.get_om() solph.constraints.emission_limit(om, limit=777)
def test_generic_storage_3(): """Nominal value defined with investment model.""" bel = solph.Bus() solph.components.GenericStorage( label='storage4', nominal_storage_capacity=45, inputs={bel: solph.Flow(nominal_value=23, variable_costs=10e10)}, outputs={bel: solph.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 add_heatpipes_exist(pipes, labels, gd, q, b_in, b_out, nodes): """ Adds *HeatPipeline* objects with fix capacity for existing pipes to the list of oemof.solph components. Parameters ---------- pipes labels : dict Dictonary containing specifications for label-tuple. gd : dict Settings of the investment optimisation of the ThermalNetwork q : pd.Series Specific *Pipe* of ThermalNetwork b_in : oemof.solph.Bus Bus of Inflow b_out : oemof.solph.Bus Bus of Outflow nodes : list All oemof.solph components are added to the list Returns ------- list : Updated list of nodes. """ # get index of existing pipe label of pipe data ind_pipe = pipes[pipes['label_3'] == q['hp_type']].index[0] t = pipes.loc[ind_pipe] # get label of pipe labels['l_3'] = t['label_3'] hlf = t['l_factor'] * q['length'] hlff = t['l_factor_fix'] * q['length'] flow_bi_args = { 'bidirectional': True, 'min': -1} \ if gd['bidirectional_pipes'] else {} outflow_args = {'nonconvex': solph.NonConvex()} if t['nonconvex'] else {} nodes.append(oh.HeatPipeline( label=oh.Label(labels['l_1'], labels['l_2'], labels['l_3'], labels['l_4']), inputs={b_in: solph.Flow(**flow_bi_args)}, outputs={b_out: solph.Flow( nominal_value=q['capacity'], **flow_bi_args, **outflow_args, )}, heat_loss_factor=hlf, heat_loss_factor_fix=hlff, )) return nodes
def test_storage_invest_4(self): """Only the storage capacity can be extended. """ bel = solph.Bus(label='electricityBus') solph.components.GenericStorage( label='storage4', inputs={bel: solph.Flow(nominal_value=80)}, outputs={bel: solph.Flow(nominal_value=100)}, investment=solph.Investment(ep_costs=145, maximum=500)) self.compare_lp_files('storage_invest_4.lp')