Example #1
0
    def test_parameter_with_node_view(self):
        param_results = processing.parameter_as_dict(self.es,
                                                     exclude_none=True)
        bel1 = views.node(param_results, 'b_el1')
        eq_(bel1['scalars'][(('b_el1', 'storage'), 'variable_costs')], 3)

        bel1_m = views.node(param_results, 'b_el1', multiindex=True)
        eq_(bel1_m['scalars'].loc[('b_el1', 'storage', 'variable_costs')], 3)
Example #2
0
    def update_flows(self, results, comp_name=None):
        """Updates the flows of a component for each time step.

        :param results: The oemof results for the given time step
        :type results: object
        :param comp_name: The name of the component - while components can generate more
            than one oemof model, they sometimes need to give a custom name, defaults to None
        :type comp_name: str, optional
        :return: updated flow values for each flow in the 'flows' dict
        """
        # Check if the component has an attribute 'flows', if not, create it as an empty dict.
        if not hasattr(self, 'flows'):
            self.flows = {}

        if comp_name is None:
            comp_name = self.name

        this_comp_node = views.node(results, comp_name)
        this_df = this_comp_node['sequences']
        for i_result in this_df:
            # Check if this result is a flow
            if i_result[1] == 'flow':
                this_flow_name = i_result[0][:]
                # Check if there already is an array to store the flow
                # information, if not, create one.
                if this_flow_name not in self.flows:
                    self.flows[this_flow_name] = [
                        None
                    ] * self.sim_params.n_intervals
                # Saving this flow value to the results file
                self.flows[this_flow_name][
                    self.sim_params.i_interval] = this_df[i_result][0]
def test_results_with_old_dump():
    """
    Test again with a stored dump created with v0.3.2dev (896a6d50)
    """
    energysystem = solph.EnergySystem()
    energysystem.restore(dpath=os.path.dirname(os.path.realpath(__file__)),
                         filename='es_dump_test_3_2dev.oemof')

    results = energysystem.results['main']

    electricity_bus = views.node(results, 'electricity')
    my_results = electricity_bus['sequences'].sum(axis=0).to_dict()
    storage = energysystem.groups['storage']
    my_results['storage_invest'] = results[(storage,
                                            None)]['scalars']['invest']

    stor_invest_dict = {
        'storage_invest': 2040000,
        (('electricity', 'demand'), 'flow'): 105867395,
        (('electricity', 'excess_bel'), 'flow'): 211771291,
        (('electricity', 'storage'), 'flow'): 2350931,
        (('pp_gas', 'electricity'), 'flow'): 5148414,
        (('pv', 'electricity'), 'flow'): 7488607,
        (('storage', 'electricity'), 'flow'): 1880745,
        (('wind', 'electricity'), 'flow'): 305471851
    }

    for key in stor_invest_dict.keys():
        eq_(int(round(my_results[key])), int(round(stor_invest_dict[key])))
Example #4
0
 def test_output_by_type_view(self):
     results = processing.results(self.om)
     transformer_output = views.node_output_by_type(results,
                                                    node_type=Transformer)
     compare = views.node(results, 'diesel',
                          multiindex=True)['sequences'][('diesel', 'b_el1',
                                                         'flow')]
     eq_(int(transformer_output.sum()), int(compare.sum()))
Example #5
0
 def test_net_storage_flow(self):
     results = processing.results(self.om)
     storage_flow = views.net_storage_flow(results,
                                           node_type=GenericStorage)
     compare = views.node(results, 'storage', multiindex=True)['sequences']
     eq_(((compare[('storage', 'b_el2', 'flow')] -
           compare[('b_el1', 'storage',
                    'flow')]).to_frame() == storage_flow.values).all()[0],
         True)
def test_results_with_actual_dump():
    energysystem = solph.EnergySystem()
    energysystem.restore()

    # Results
    results = energysystem.results['main']
    meta = energysystem.results['meta']

    electricity_bus = views.node(results, 'electricity')
    my_results = electricity_bus['sequences'].sum(axis=0).to_dict()
    storage = energysystem.groups['storage']
    my_results['storage_invest'] = results[(storage,
                                            None)]['scalars']['invest']

    stor_invest_dict = {
        'storage_invest': 2040000,
        (('electricity', 'None'), 'duals'): 10800000000321,
        (('electricity', 'demand'), 'flow'): 105867395,
        (('electricity', 'excess_bel'), 'flow'): 211771291,
        (('electricity', 'storage'), 'flow'): 2350931,
        (('pp_gas', 'electricity'), 'flow'): 5148414,
        (('pv', 'electricity'), 'flow'): 7488607,
        (('storage', 'electricity'), 'flow'): 1880745,
        (('wind', 'electricity'), 'flow'): 305471851
    }

    for key in stor_invest_dict.keys():
        eq_(int(round(my_results[key])), int(round(stor_invest_dict[key])))

    # Solver results
    eq_(str(meta['solver']['Termination condition']), 'optimal')
    eq_(meta['solver']['Error rc'], 0)
    eq_(str(meta['solver']['Status']), 'ok')

    # Problem results
    eq_(meta['problem']['Lower bound'], 4.231675777e+17)
    eq_(meta['problem']['Upper bound'], 4.231675777e+17)
    eq_(meta['problem']['Number of variables'], 2805)
    eq_(meta['problem']['Number of constraints'], 2806)
    eq_(meta['problem']['Number of nonzeros'], 1197)
    eq_(meta['problem']['Number of objectives'], 1)
    eq_(str(meta['problem']['Sense']), 'minimize')

    # Objective function
    eq_(round(meta['objective']), 423167578261115584)
Example #7
0
def test_regression_investment_storage(solver='cbc'):
    """The problem was infeasible if the existing capacity and the maximum was
    defined in the Flow.
    """

    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2012', periods=4, freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)
    Node.registry = energysystem

    # Buses
    bgas = solph.Bus(label=('natural', 'gas'))
    bel = solph.Bus(label='electricity')

    solph.Sink(label='demand',
               inputs={
                   bel:
                   solph.Flow(fix=[209643, 207497, 200108, 191892],
                              nominal_value=1)
               })

    # Sources
    solph.Source(label='rgas', outputs={bgas: solph.Flow()})

    # Transformer
    solph.Transformer(label='pp_gas',
                      inputs={bgas: solph.Flow()},
                      outputs={bel: solph.Flow(nominal_value=300000)},
                      conversion_factors={bel: 0.58})

    # Investment storage
    solph.components.GenericStorage(
        label='storage',
        inputs={
            bel:
            solph.Flow(
                investment=solph.Investment(existing=625046 / 6, maximum=0))
        },
        outputs={
            bel:
            solph.Flow(
                investment=solph.Investment(existing=104174.33, maximum=1))
        },
        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=solph.Investment(ep_costs=50, existing=625046),
    )

    # Solve model
    om = solph.Model(energysystem)
    om.solve(solver=solver)

    # Results
    results = solph.processing.results(om)

    electricity_bus = views.node(results, 'electricity')
    my_results = electricity_bus['sequences'].sum(axis=0).to_dict()
    storage = energysystem.groups['storage']
    my_results['storage_invest'] = results[(storage,
                                            None)]['scalars']['invest']
Example #8
0
def test_variable_chp(filename="variable_chp.csv", 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=5, freq='H')
    energysystem = solph.EnergySystem(timeindex=date_time_index)
    Node.registry = energysystem

    # Read data file with heat and electrical demand (192 hours)
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")

    ##########################################################################
    # Create oemof.solph objects
    ##########################################################################

    logging.info('Create oemof.solph objects')

    # create natural gas bus
    bgas = solph.Bus(label=('natural', 'gas'))

    # create commodity object for gas resource
    solph.Source(label=('commodity', 'gas'),
                 outputs={bgas: solph.Flow(variable_costs=50)})

    # create two electricity buses and two heat buses
    bel = solph.Bus(label=('electricity', 1))
    bel2 = solph.Bus(label=('electricity', 2))
    bth = solph.Bus(label=('heat', 1))
    bth2 = solph.Bus(label=('heat', 2))

    # create excess components for the elec/heat bus to allow overproduction
    solph.Sink(label=('excess', 'bth_2'), inputs={bth2: solph.Flow()})
    solph.Sink(label=('excess', 'bth_1'), inputs={bth: solph.Flow()})
    solph.Sink(label=('excess', 'bel_2'), inputs={bel2: solph.Flow()})
    solph.Sink(label=('excess', 'bel_1'), inputs={bel: solph.Flow()})

    # create simple sink object for electrical demand for each electrical bus
    solph.Sink(
        label=('demand', 'elec1'),
        inputs={bel: solph.Flow(fix=data['demand_el'], nominal_value=1)})
    solph.Sink(
        label=('demand', 'elec2'),
        inputs={bel2: solph.Flow(fix=data['demand_el'], nominal_value=1)})

    # create simple sink object for heat demand for each thermal bus
    solph.Sink(
        label=('demand', 'therm1'),
        inputs={bth: solph.Flow(fix=data['demand_th'], nominal_value=741000)})
    solph.Sink(
        label=('demand', 'therm2'),
        inputs={bth2: solph.Flow(fix=data['demand_th'], nominal_value=741000)})

    # create a fixed transformer to distribute to the heat_2 and elec_2 buses
    solph.Transformer(label=('fixed_chp', 'gas'),
                      inputs={bgas: solph.Flow(nominal_value=10e10)},
                      outputs={
                          bel2: solph.Flow(),
                          bth2: solph.Flow()
                      },
                      conversion_factors={
                          bel2: 0.3,
                          bth2: 0.5
                      })

    # create a fixed transformer to distribute to the heat and elec buses
    solph.components.ExtractionTurbineCHP(
        label=('variable_chp', 'gas'),
        inputs={bgas: solph.Flow(nominal_value=10e10)},
        outputs={
            bel: solph.Flow(),
            bth: solph.Flow()
        },
        conversion_factors={
            bel: 0.3,
            bth: 0.5
        },
        conversion_factor_full_condensation={bel: 0.5})

    ##########################################################################
    # Optimise the energy system and plot the results
    ##########################################################################

    logging.info('Optimise the energy system')

    om = solph.Model(energysystem)

    logging.info('Solve the optimization problem')
    om.solve(solver=solver)

    optimisation_results = solph.processing.results(om)
    parameter = solph.processing.parameter_as_dict(energysystem)

    myresults = views.node(optimisation_results, "('natural', 'gas')")
    sumresults = myresults['sequences'].sum(axis=0)
    maxresults = myresults['sequences'].max(axis=0)

    variable_chp_dict_sum = {
        (("('natural', 'gas')", "('variable_chp', 'gas')"), 'flow'): 2823024,
        (("('natural', 'gas')", "('fixed_chp', 'gas')"), 'flow'): 3710208,
        (("('commodity', 'gas')", "('natural', 'gas')"), 'flow'): 6533232
    }

    variable_chp_dict_max = {
        (("('natural', 'gas')", "('variable_chp', 'gas')"), 'flow'): 630332,
        (("('natural', 'gas')", "('fixed_chp', 'gas')"), 'flow'): 785934,
        (("('commodity', 'gas')", "('natural', 'gas')"), 'flow'): 1416266
    }

    for key in variable_chp_dict_max.keys():
        logging.debug("Test the maximum value of {0}".format(key))
        eq_(int(round(maxresults[key])),
            int(round(variable_chp_dict_max[key])))

    for key in variable_chp_dict_sum.keys():
        logging.debug("Test the summed up value of {0}".format(key))
        eq_(int(round(sumresults[key])),
            int(round(variable_chp_dict_sum[key])))

    eq_(
        parameter[(energysystem.groups["('fixed_chp', 'gas')"],
                   None)]['scalars']['label'], "('fixed_chp', 'gas')")
    eq_(
        parameter[(energysystem.groups["('fixed_chp', 'gas')"],
                   None)]['scalars']["conversion_factors_('electricity', 2)"],
        0.3)

    # objective function
    eq_(round(solph.processing.meta_results(om)['objective']), 326661590)
               solph.Flow(my_keyword=True, fix=[0, 1, 1, 0], nominal_value=130)
           })

model = solph.Model(energy_system)

# only one of the two flows may be active at a time
solph.constraints.limit_active_flow_count_by_keyword(model,
                                                     "my_keyword",
                                                     lower_limit=0,
                                                     upper_limit=1)

model.solve()

results = processing.results(model)

if plt is not None:
    data = views.node(results, 'bel')['sequences']
    ax = data.plot(kind='line', grid=True)
    ax.set_xlabel('Time (h)')
    ax.set_ylabel('P (MW)')

    plt.figure()
    ax = plt.gca()
    plt.plot(results[('my_keyword', 'my_keyword')]['sequences'],
             label="my_keyword_count")
    ax.set_xlabel('Time (h)')
    ax.set_ylabel('Count (1)')
    plt.grid()
    plt.legend()
    plt.show()
Example #10
0
    )
)

es.add(Sink(label="load", inputs={b_el2: Flow(nominal_value=100, fix=[1, 1])}))

m = Model(energysystem=es)

# m.write('lopf.lp', io_options={'symbolic_solver_labels': True})

m.solve(solver="cbc", solve_kwargs={"tee": True, "keepfiles": False})


m.results()

graph = create_nx_graph(es)

draw_graph(
    graph,
    plot=True,
    layout="neato",
    node_size=3000,
    node_color={"b_0": "#cd3333", "b_1": "#7EC0EE", "b_2": "#eeac7e"},
)


results = processing.results(m)

print(views.node(results, "gen_0"))
print(views.node(results, "gen_1"))
print(views.node(results, "line_1"))
Example #11
0
                         solve_kwargs={
                             "tee": True,
                             "keepfiles": False
                         })

# write back results from optimization object to energysystem
optimization_model.results()

# ################################ results ################################

# 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(optimization_model.results(), "bel")
data["sequences"].info()
print("Optimization successful. Showing some results:")

# see: https://pandas.pydata.org/pandas-docs/stable/visualization.html
node_results_bel = views.node(optimization_model.results(), "bel")
node_results_flows = node_results_bel["sequences"]

node_results_flows.to_csv("results.csv")

demand_el = node_results_flows.iloc[:, 0].sum()
print("electricity demand: {:.3f}".format(demand_el))
excess_el = node_results_flows.iloc[:, 1].sum()
print("{:04.1f} % excess generation: {:.3f}".format(
    100 * excess_el / demand_el, excess_el))
coal_generation = node_results_flows.iloc[:, 2].sum()
Example #12
0
def test_gen_caes():
    # read sequence data
    full_filename = os.path.join(os.path.dirname(__file__), 'generic_caes.csv')
    data = pd.read_csv(full_filename)

    # select periods
    periods = len(data)-1

    # create an energy system
    idx = pd.date_range('1/1/2017', periods=periods, freq='H')
    es = EnergySystem(timeindex=idx)
    Node.registry = es

    # resources
    bgas = Bus(label='bgas')

    Source(label='rgas', outputs={
        bgas: Flow(variable_costs=20)})

    # power
    bel_source = Bus(label='bel_source')
    Source(label='source_el', outputs={
        bel_source: Flow(variable_costs=data['price_el_source'])})

    bel_sink = Bus(label='bel_sink')
    Sink(label='sink_el', inputs={
        bel_sink: Flow(variable_costs=data['price_el_sink'])})

    # dictionary with parameters for a specific CAES plant
    # based on thermal modelling and linearization techniques
    concept = {
        'cav_e_in_b': 0,
        'cav_e_in_m': 0.6457267578,
        'cav_e_out_b': 0,
        'cav_e_out_m': 0.3739636077,
        'cav_eta_temp': 1.0,
        'cav_level_max': 211.11,
        'cmp_p_max_b': 86.0918959849,
        'cmp_p_max_m': 0.0679999932,
        'cmp_p_min': 1,
        'cmp_q_out_b': -19.3996965679,
        'cmp_q_out_m': 1.1066036114,
        'cmp_q_tes_share': 0,
        'exp_p_max_b': 46.1294016678,
        'exp_p_max_m': 0.2528340303,
        'exp_p_min': 1,
        'exp_q_in_b': -2.2073411014,
        'exp_q_in_m': 1.129249765,
        'exp_q_tes_share': 0,
        'tes_eta_temp': 1.0,
        'tes_level_max': 0.0
    }

    # generic compressed air energy storage (caes) plant
    custom.GenericCAES(
        label='caes',
        electrical_input={bel_source: Flow()},
        fuel_input={bgas: Flow()},
        electrical_output={bel_sink: Flow()},
        params=concept, fixed_costs=0)

    # create an optimization problem and solve it
    om = Model(es)

    # solve model
    om.solve(solver='cbc')

    # create result object
    results = processing.results(om)

    data = views.node(
        results, 'caes', keep_none_type=True
    )['sequences'].sum(axis=0).to_dict()

    test_dict = {
        (('caes', None), 'cav_level'): 25658.82964382,
        (('caes', None), 'exp_p'): 5020.801997000007,
        (('caes', None), 'exp_q_fuel_in'): 5170.880360999999,
        (('caes', None), 'tes_e_out'): 0.0,
        (('caes', None), 'exp_st'): 226.0,
        (('bgas', 'caes'), 'flow'): 5170.880360999999,
        (('caes', None), 'cav_e_out'): 1877.5972265299995,
        (('caes', None), 'exp_p_max'): 17512.352336,
        (('caes', None), 'cmp_q_waste'): 2499.9125993000007,
        (('caes', None), 'cmp_p'): 2907.7271520000004,
        (('caes', None), 'exp_q_add_in'): 0.0,
        (('caes', None), 'cmp_st'): 37.0,
        (('caes', None), 'cmp_q_out_sum'): 2499.9125993000007,
        (('caes', None), 'tes_level'): 0.0,
        (('caes', None), 'tes_e_in'): 0.0,
        (('caes', None), 'exp_q_in_sum'): 5170.880360999999,
        (('caes', None), 'cmp_p_max'): 22320.76334300001,
        (('caes', 'bel_sink'), 'flow'): 5020.801997000007,
        (('bel_source', 'caes'), 'flow'): 2907.7271520000004,
        (('caes', None), 'cav_e_in'): 1877.597226}

    for key in test_dict.keys():
        eq_(int(round(data[key])), int(round(test_dict[key])))
# add constraint for generic investment limit
om = solph.constraints.additional_investment_flow_limit(om, "space", limit=24)

# export lp file
filename = os.path.join(helpers.extend_basic_path('lp_files'),
                        'GenericInvest.lp')
logging.info('Store lp-file in {0}.'.format(filename))
om.write(filename, io_options={'symbolic_solver_labels': True})

# solve model
om.solve(solver='cbc', solve_kwargs={'tee': True})

# create result object
results = processing.results(om)

bus1 = views.node(results, 'bus_a_1')["sequences"]
bus2 = views.node(results, 'bus_b_1')["sequences"]

# plot the time series (sequences) of a specific component/bus
if plt is not None:
    bus1.plot(kind='line', drawstyle='steps-mid')
    plt.legend()
    plt.show()
    bus2.plot(kind='line', drawstyle='steps-mid')
    plt.legend()
    plt.show()

space_used = om.invest_limit_space()
print('Space value: ', space_used)
print('Investment trafo_a: ', views.node(results, 'trafo_a')["scalars"][0])
print('Investment trafo_b: ', views.node(results, 'trafo_b')["scalars"][0])
Example #14
0
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
Example #15
0
def test_connect_invest():
    date_time_index = pd.date_range('1/1/2012', periods=24 * 7, freq='H')

    energysystem = EnergySystem(timeindex=date_time_index)
    network.Node.registry = energysystem

    # Read data file
    full_filename = os.path.join(os.path.dirname(__file__),
                                 'connect_invest.csv')
    data = pd.read_csv(full_filename, sep=",")

    logging.info('Create oemof objects')

    # create electricity bus
    bel1 = Bus(label="electricity1")
    bel2 = Bus(label="electricity2")

    # create excess component for the electricity bus to allow overproduction
    Sink(label='excess_bel', inputs={bel2: Flow()})
    Source(label='shortage', outputs={bel2: Flow(variable_costs=50000)})

    # create fixed source object representing wind power plants
    Source(label='wind',
           outputs={bel1: Flow(fix=data['wind'], nominal_value=1000000)})

    # create simple sink object representing the electrical demand
    Sink(label='demand',
         inputs={bel1: Flow(fix=data['demand_el'], nominal_value=1)})

    storage = components.GenericStorage(
        label='storage',
        inputs={bel1: Flow(variable_costs=10e10)},
        outputs={bel1: 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=0.2),
    )

    line12 = Transformer(
        label="line12",
        inputs={bel1: Flow()},
        outputs={bel2: Flow(investment=Investment(ep_costs=20))})

    line21 = Transformer(
        label="line21",
        inputs={bel2: Flow()},
        outputs={bel1: Flow(investment=Investment(ep_costs=20))})

    om = Model(energysystem)

    constraints.equate_variables(om, om.InvestmentFlow.invest[line12, bel2],
                                 om.InvestmentFlow.invest[line21, bel1], 2)
    constraints.equate_variables(
        om, om.InvestmentFlow.invest[line12, bel2],
        om.GenericInvestmentStorageBlock.invest[storage])

    # if tee_switch is true solver messages will be displayed
    logging.info('Solve the optimization problem')
    om.solve(solver='cbc')

    # check if the new result object is working for custom components
    results = processing.results(om)

    my_results = dict()
    my_results['line12'] = float(views.node(results, 'line12')['scalars'])
    my_results['line21'] = float(views.node(results, 'line21')['scalars'])
    stor_res = views.node(results, 'storage')['scalars']
    my_results['storage_in'] = stor_res[(('electricity1', 'storage'),
                                         'invest')]
    my_results['storage'] = stor_res[(('storage', 'None'), 'invest')]
    my_results['storage_out'] = stor_res[(('storage', 'electricity1'),
                                          'invest')]

    connect_invest_dict = {
        'line12': 814705,
        'line21': 1629410,
        'storage': 814705,
        'storage_in': 135784,
        'storage_out': 135784
    }

    for key in connect_invest_dict.keys():
        eq_(int(round(my_results[key])), int(round(connect_invest_dict[key])))
Example #16
0
def postprocessing(results, param, data):
    """
    Perform postprocessing of optimization results.

    Parameters
    ----------
    results : dict of pandas.Series and pandas.DataFrame
        Full results from solph.processing.results() call.

    param : dict
        JSON parameter file of user defined constants.

    data : pandas.DataFrame
        csv file of user defined time dependent parameters.

    """
    data_cost_units = pd.DataFrame()

    data_gnw = views.node(results, 'Gasnetzwerk')['sequences']
    data_enw = views.node(results, 'Elektrizitätsnetzwerk')['sequences']
    data_wnw = views.node(results, 'Wärmenetzwerk')['sequences']
    data_lt_wnw = views.node(results, 'LT-Wärmenetzwerk')['sequences']
    data_wnw_node = views.node(results, 'TES Knoten')['sequences']
    data_sol_node = views.node(results, 'Sol Knoten')['sequences']

    if param['Sol']['active']:
        data_solar_source = views.node(results, 'Solarthermie')['sequences']
        data_cost_units.loc['invest', 'Sol'] = (invest_sol(param['Sol']['A'],
                                                           col_type='flat'))
        data_cost_units.loc['op_cost', 'Sol'] = (
            data_solar_source[(('Solarthermie', 'Sol Knoten'), 'flow')].sum() *
            0.01 * data_cost_units.loc['invest', 'Sol'] / param['Sol']['A'] *
            data['solar_data_' + param['Sol']['usage']].sum())

    if param['EHK']['active']:
        data_cost_units.loc['invest', 'EHK'] = (param['EHK']['inv_spez'] *
                                                param['EHK']['Q_N'] *
                                                param['EHK']['amount'])

        data_cost_units.loc['op_cost', 'EHK'] = 0
        for i in range(1, param['EHK']['amount'] + 1):
            label_id = 'Elektroheizkessel_' + str(i)

            data_cost_units.loc['op_cost', 'EHK'] += (
                data_wnw[((label_id, 'Wärmenetzwerk'), 'flow')].sum() *
                param['EHK']['op_cost_var'] +
                (param['EHK']['op_cost_fix'] * param['EHK']['Q_N']))

    if param['SLK']['active']:
        data_cost_units.loc['invest', 'SLK'] = (param['SLK']['inv_spez'] *
                                                param['SLK']['Q_N'] *
                                                param['SLK']['amount'])

        data_cost_units.loc['op_cost', 'SLK'] = 0
        for i in range(1, param['SLK']['amount'] + 1):
            label_id = 'Spitzenlastkessel_' + str(i)

            data_cost_units.loc['op_cost', 'SLK'] += (
                data_wnw[((label_id, 'Wärmenetzwerk'), 'flow')].sum() *
                (param['SLK']['op_cost_var'] + param['param']['energy_tax']) +
                (param['SLK']['op_cost_fix'] * param['SLK']['Q_N']))

    if param['BHKW']['active']:
        if param['BHKW']['type'] == 'constant':
            ICE_P_max_woDH = param['BHKW']['P_max_woDH']
        elif param['BHKW']['type'] == 'time series':
            ICE_P_max_woDH = data['ICE_P_max_woDH'].mean()

        data_cost_units.loc['invest', 'BHKW'] = (ICE_P_max_woDH *
                                                 param['BHKW']['inv_spez'] *
                                                 param['BHKW']['amount'])

        data_cost_units.loc['op_cost', 'BHKW'] = 0
        for i in range(1, param['BHKW']['amount'] + 1):
            label_id = 'BHKW_' + str(i)

            data_cost_units.loc['op_cost', 'BHKW'] += (
                data_enw[((label_id, 'Elektrizitätsnetzwerk'), 'flow')].sum() *
                param['BHKW']['op_cost_var'] +
                (param['BHKW']['op_cost_fix'] * ICE_P_max_woDH))

    if param['GuD']['active']:
        if param['GuD']['type'] == 'constant':
            CCET_P_max_woDH = param['GuD']['P_max_woDH']
        elif param['GuD']['type'] == 'time series':
            CCET_P_max_woDH = data['CCET_P_max_woDH'].mean()

        data_cost_units.loc['invest', 'GuD'] = (CCET_P_max_woDH *
                                                param['GuD']['inv_spez'] *
                                                param['GuD']['amount'])

        data_cost_units.loc['op_cost', 'GuD'] = 0
        for i in range(1, param['GuD']['amount'] + 1):
            label_id = 'GuD_' + str(i)

            data_cost_units.loc['op_cost', 'GuD'] += (
                data_enw[((label_id, 'Elektrizitätsnetzwerk'), 'flow')].sum() *
                param['GuD']['op_cost_var'] +
                (param['GuD']['op_cost_fix'] * CCET_P_max_woDH))

    if param['HP']['active']:
        if param['HP']['type'] == 'constant':
            HP_Q_N = (param['HP']['c_1'] * param['HP']['P_max'] +
                      param['HP']['c_0'])
        elif param['HP']['type'] == 'time series':
            HP_Q_N = (data['c_1_hp'].mean() * data['P_max_hp'].mean() +
                      data['c_0_hp'].mean())
        data_cost_units.loc['invest', 'HP'] = (param['HP']['inv_spez'] *
                                               data['P_max_hp'].max() *
                                               HP_Q_N * param['HP']['amount'])

        data_cost_units.loc['op_cost', 'HP'] = 0
        for i in range(1, param['HP']['amount'] + 1):
            label_id = 'HP_' + str(i)

            data_cost_units.loc['op_cost', 'HP'] += (
                data_wnw[((label_id, 'Wärmenetzwerk'), 'flow')].sum() *
                param['HP']['op_cost_var'] +
                param['HP']['op_cost_fix'] * HP_Q_N)

    if param['LT-HP']['active']:
        LT_HP_Q_N = data_wnw[((label_id, 'Wärmenetzwerk'), 'flow')].mean()

        data_cost_units.loc['invest', 'LT-HP'] = 0
        data_cost_units.loc['op_cost', 'LT-HP'] = 0
        for i in range(1, param['LT-HP']['amount'] + 1):
            label_id = 'LT-HP_' + str(i)

            data_cost_units.loc['invest',
                                'LT-HP'] += (param['HP']['inv_spez'] *
                                             LT_HP_Q_N)

            data_cost_units.loc['op_cost', 'LT-HP'] += (
                data_wnw[((label_id, 'Wärmenetzwerk'), 'flow')].sum() *
                param['HP']['op_cost_var'] +
                param['HP']['op_cost_fix'] * LT_HP_Q_N)

    data_tes = pd.DataFrame()
    if param['TES']['active']:
        data_cost_units.loc['invest',
                            'TES'] = (invest_stes(param['TES']['Q']) *
                                      param['TES']['amount'])

        data_cost_units.loc['op_cost', 'TES'] = 0
        for i in range(1, param['TES']['amount'] + 1):
            label_id = 'TES_' + str(i)
            data_tes = pd.concat(
                [data_tes,
                 views.node(results, label_id)['sequences']], axis=1)

            data_cost_units.loc['op_cost', 'TES'] += (
                data_tes[(('TES Knoten', label_id), 'flow')].sum() *
                param['TES']['op_cost_var'] +
                (param['TES']['op_cost_fix'] * param['TES']['Q']))

    if param['ST-TES']['active']:
        data_cost_units.loc['invest',
                            'ST-TES'] = (invest_stes(param['ST-TES']['Q']) *
                                         param['ST-TES']['amount'])

        data_cost_units.loc['op_cost', 'ST-TES'] = 0
        for i in range(1, param['ST-TES']['amount'] + 1):
            label_id = 'ST-TES_' + str(i)
            data_tes = pd.concat(
                [data_tes,
                 views.node(results, label_id)['sequences']], axis=1)

            data_cost_units.loc['op_cost', 'ST-TES'] += (
                data_tes[(('Wärmenetzwerk', label_id), 'flow')].sum() *
                param['ST-TES']['op_cost_var'] +
                (param['ST-TES']['op_cost_fix'] * param['ST-TES']['Q']))

    cost_Anlagen = data_cost_units.loc['op_cost'].sum()
    invest_ges = data_cost_units.loc['invest'].sum()

    cost_gas = (data_gnw[(('Gasquelle', 'Gasnetzwerk'), 'flow')].sum() *
                (param['param']['gas_price'] +
                 (param['param']['co2_price'] * param['param']['ef_gas'])))

    specific_costs_el_grid = (param['param']['elec_consumer_charges_grid'] +
                              data['el_spot_price'] +
                              (param['param']['co2_price'] * data['ef_om']))
    cost_el_grid = (np.array(data_enw[(
        ('Stromquelle', 'Elektrizitätsnetzwerk'), 'flow')]) *
                    specific_costs_el_grid)
    cost_el_grid = cost_el_grid.sum()

    cost_el_internal = (
        (data_enw.loc[:, ['BHKW' in col
                          for col in data_enw.columns]].to_numpy().sum() +
         data_enw.loc[:, ['GuD' in col
                          for col in data_enw.columns]].to_numpy().sum() -
         data_enw[(('Elektrizitätsnetzwerk', 'Spotmarkt'), 'flow')].sum()) *
        param['param']['elec_consumer_charges_self'])

    cost_el = cost_el_grid + cost_el_internal

    revenues_spotmarkt_timeseries = (
        np.array(data_enw[(('Elektrizitätsnetzwerk', 'Spotmarkt'), 'flow')]) *
        (data['el_spot_price'] + param['param']['vNNE']))
    revenues_spotmarkt = revenues_spotmarkt_timeseries.sum()

    revenues_chpbonus = 0
    if param['BHKW']['active']:
        revenues_chpbonus += (
            data_enw.loc[:, ['BHKW' in col
                             for col in data_enw.columns]].to_numpy().sum() *
            (param['BHKW']['chp_bonus'] + param['BHKW']['TEHG_bonus']))
    if param['GuD']['active']:
        revenues_chpbonus += (
            data_enw.loc[:, ['GuD' in col
                             for col in data_enw.columns]].to_numpy().sum() *
            (param['GuD']['chp_bonus'] + param['GuD']['TEHG_bonus']))
    if param['BPT']['active']:
        revenues_chpbonus += (
            data_enw.loc[:, ['BPT' in col
                             for col in data_enw.columns]].to_numpy().sum() *
            (param['BPT']['chp_bonus'] + param['BPT']['TEHG_bonus']))

    revenues_heatdemand = (data_wnw[(
        ('Wärmenetzwerk', 'Wärmebedarf'), 'flow')].sum() *
                           param['param']['heat_price'])

    revenues_total = (revenues_spotmarkt + revenues_heatdemand +
                      revenues_chpbonus)
    cost_total = cost_Anlagen + cost_gas + cost_el
    Gesamtbetrag = revenues_total - cost_total

    result_dfs = [
        data_wnw, data_lt_wnw, data_wnw_node, data_sol_node, data_tes,
        data_enw, data_gnw
    ]

    labeldict = generate_labeldict(param)
    for df in result_dfs:
        result_labelling(labeldict, df)

    data_dhs = pd.concat(result_dfs, axis=1)

    data_invest = pd.DataFrame(
        data={
            'invest_ges': [invest_ges],
            'Q_tes': [param['TES']['Q']],
            'total_heat_demand':
            [data['heat_demand'].sum() * param['param']['rel_demand']],
            'Gesamtbetrag': [Gesamtbetrag],
            'revenues_spotmarkt': [revenues_spotmarkt],
            'revenues_heatdemand': [revenues_heatdemand],
            'revenues_chpbonus': [revenues_chpbonus],
            'cost_Anlagen': [cost_Anlagen],
            'cost_gas': [cost_gas],
            'cost_el': [cost_el],
            'cost_el_grid': [cost_el_grid],
            'cost_el_internal': [cost_el_internal],
            'cost_total': [cost_total],
            'revenues_total': [revenues_total]
        })

    data_emission = pd.concat(
        [data_gnw['H_source'], data_enw[['P_spot_market', 'P_source']]],
        axis=1)

    return data_dhs, data_invest, data_emission, data_cost_units
def test_dispatch_one_time_step(solver='cbc'):
    """Create an energy system and optimize the dispatch at least costs."""

    # ######################### create energysystem components ################
    Node.registry = None

    # resource buses
    bgas = Bus(label='gas', 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()})

    # sources
    wind = Source(label='wind',
                  outputs={bel: Flow(fix=0.5, nominal_value=66.3)})

    # demands (electricity/heat)
    demand_el = Sink(label='demand_elec',
                     inputs={bel: Flow(nominal_value=85, fix=0.3)})

    demand_th = Sink(label='demand_therm',
                     inputs={bth: Flow(nominal_value=40, fix=0.2)})

    # 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='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
                            })

    energysystem = EnergySystem(timeindex=[1])
    energysystem.add(bgas, bel, bth, excess_el, wind, demand_el, demand_th,
                     pp_chp, b_heat_source, heat_source, heat_pump)

    # ################################ optimization ###########################

    # create optimization model based on energy_system
    optimization_model = Model(energysystem=energysystem, timeincrement=1)

    # solve problem
    optimization_model.solve(solver=solver)

    # write back results from optimization object to energysystem
    optimization_model.results()

    # ################################ results ################################
    data = views.node(processing.results(om=optimization_model), 'b_el')

    # generate results to be evaluated in tests
    results = data['sequences'].sum(axis=0).to_dict()

    test_results = {
        (('wind', 'b_el'), 'flow'): 33,
        (('b_el', 'demand_elec'), 'flow'): 26,
        (('b_el', 'excess_el'), 'flow'): 5,
        (('b_el', 'heat_pump'), 'flow'): 3,
    }

    for key in test_results.keys():
        eq_(int(round(results[key])), int(round(test_results[key])))
Example #18
0
m = Model(energysystem=es)

# m.write('transshipment.lp', io_options={'symbolic_solver_labels': True})

m.solve(solver='cbc', solve_kwargs={'tee': True, 'keepfiles': False})

m.results()

graph = create_nx_graph(es, m)

draw_graph(graph,
           plot=True,
           layout='neato',
           node_size=3000,
           node_color={
               'b_0': '#cd3333',
               'b_1': '#7EC0EE',
               'b_2': '#eeac7e'
           })

results = processing.results(m)

print(views.node(results, 'gen_0'))
print(views.node(results, 'gen_1'))

views.node(results, 'line_0')['sequences'].plot(kind='bar')

# look at constraints of Links in the pyomo model LinkBlock
m.LinkBlock.pprint()
Example #19
0
# %% Ergebnisse Energiesystem

# Ergebnisse in results
results = solph.processing.results(model)

# Main- und Metaergebnisse
es_ref.results['main'] = solph.processing.results(model)
es_ref.results['meta'] = solph.processing.meta_results(model)

invest_ges = 0
cost_Anlagen = 0
labeldict = {}

# Busses
data_gnw = views.node(results, 'Gasnetzwerk')['sequences']
data_enw = views.node(results, 'Elektrizitätsnetzwerk')['sequences']
data_wnw = views.node(results, 'Wärmenetzwerk')['sequences']
data_lt_wnw = views.node(results, 'LT-Wärmenetzwerk')['sequences']

labeldict[(('Gasquelle', 'Gasnetzwerk'), 'flow')] = 'H_source'
labeldict[(('Elektrizitätsnetzwerk', 'Spotmarkt'), 'flow')] = 'P_spot_market'
labeldict[(('Stromquelle', 'Elektrizitätsnetzwerk'), 'flow')] = 'P_source'
labeldict[(('Wärmenetzwerk', 'Wärmebedarf'), 'flow')] = 'Q_demand'

# Sources
data_gas_source = views.node(results, 'Gasquelle')['sequences']
data_elec_source = views.node(results, 'Stromquelle')['sequences']

if param.loc[('Sol', 'active'), 'value'] == 1:
    data_solar_source = views.node(results, 'Solarthermie')['sequences']
def electric_postprocessing(config_path, var_number):
    global df_all_var

    with open(config_path, 'r') as ymlfile:
        cfg = yaml.load(ymlfile, Loader=yaml.CLoader)

    # Define the used directories
    abs_path = os.path.dirname(os.path.abspath(os.path.join(__file__, '..')))
    results_path = abs_path + '/results'
    csv_path = results_path + '/optimisation_results/'
    plot_path = results_path + '/plots/'

    energysystem = solph.EnergySystem()
    energysystem.restore(dpath=(results_path + '/dumps'),
                         filename='electric_model_{0}_{1}.oemof'.format(
                             cfg['exp_number'], var_number))

    sp = cfg['start_of_plot']
    ep = cfg['end_of_plot']

    # Look up investment costs. Therefor parameters must read again.
    if type(cfg['parameters_variation']) == list:
        file_path_param_01 = abs_path + '/data/data_public/' + cfg[
            'parameters_system']
        file_path_param_02 = abs_path + '/data/data_public/' + cfg[
            'parameters_variation'][var_number]
    elif type(cfg['parameters_system']) == list:
        file_path_param_01 = abs_path + '/data/data_public/' + cfg[
            'parameters_system'][var_number]
        file_path_param_02 = abs_path + '/data/data_public/' + cfg[
            'parameters_variation']
    else:
        file_path_param_01 = abs_path + '/data/data_public/' + cfg[
            'parameters_system']
        file_path_param_02 = abs_path + '/data/data_public/' + cfg[
            'parameters_variation']
    param_df_01 = pd.read_csv(file_path_param_01, index_col=1)
    param_df_02 = pd.read_csv(file_path_param_02, index_col=1)
    param_df = pd.concat([param_df_01, param_df_02], sort=True)
    param_value = param_df['value']

    logging.info('results received')

    #########################
    # Work with the results #
    #########################

    cool_bus = views.node(energysystem.results['main'], 'cool')
    waste_bus = views.node(energysystem.results['main'], 'waste')
    el_bus = views.node(energysystem.results['main'], 'electricity')
    ambient_res = views.node(energysystem.results['main'], 'ambient')
    none_res = views.node(energysystem.results['main'], 'None')

    # Sequences:
    cool_seq = cool_bus['sequences']
    waste_seq = waste_bus['sequences']
    el_seq = el_bus['sequences']
    ambient_seq = ambient_res['sequences']

    # Scalars
    cool_scal = cool_bus['scalars']
    waste_scal = waste_bus['scalars']
    el_scal = el_bus['scalars']
    none_scal = none_res['scalars']
    none_scal_given = views.node(energysystem.results['param'],
                                 'None')['scalars']
    el_scal[(('pv', 'electricity'),
             'invest')] = (el_scal[(('pv', 'electricity'), 'invest')] *
                           param_value['size_pv'])
    # Conversion of the pv-investment-size, because Invest-object is normalized
    # at 0.970873786 kWpeak

    # solar fraction
    # electric:
    # control_el (No Power must go from grid to excess)
    df_control_el = pd.DataFrame()
    df_control_el['grid_el'] = el_seq[(('grid_el', 'electricity'), 'flow')]
    df_control_el['excess'] = el_seq[(('electricity', 'excess_el'), 'flow')]
    df_control_el['Product'] = (df_control_el['grid_el'] *
                                df_control_el['excess'])

    el_from_grid = el_seq[(('grid_el', 'electricity'), 'flow')].sum()
    el_from_pv = el_seq[(('pv', 'electricity'), 'flow')].sum()
    el_to_excess = el_seq[(('electricity', 'excess_el'), 'flow')].sum()
    el_pv_used = el_from_pv - el_to_excess
    sol_fraction_el = el_pv_used / (el_pv_used + el_from_grid)

    # Power usage:
    el_used = el_seq[(('grid_el', 'electricity'), 'flow')].sum()

    # Power to the output:
    electricity_output = el_seq[(('electricity', 'excess_el'), 'flow')].sum()
    electricity_output_pv = el_seq[(('pv', 'electricity'), 'flow')].sum()

    # ## costs ## #

    costs_total = energysystem.results['meta']['objective']

    # Storage costs must be subtract for reference scenario or added
    # for the other scenarios.

    # reference scenario:
    if param_value['nominal_capacitiy_stor_el'] == 0:
        costs_total_wo_stor = (
            costs_total - (none_scal[(
                ('storage_electricity', 'None'), 'invest')] * none_scal_given[(
                    ('storage_electricity', 'None'), 'investment_ep_costs')]) -
            (none_scal[(
                ('storage_cool', 'None'), 'invest')] * none_scal_given[(
                    ('storage_cool', 'None'), 'investment_ep_costs')]))
    # other scenarios:
    else:
        # calculation of ep_costs
        ep_costs_el_stor = ep_costs_func(
            param_value['invest_costs_stor_el_capacity'],
            param_value['lifetime_stor_el'], param_value['opex_stor_el'],
            param_value['wacc'])
        ep_costs_cool_stor = ep_costs_func(
            param_value['invest_costs_stor_cool_capacity'],
            param_value['lifetime_stor_cool'], param_value['opex_stor_cool'],
            param_value['wacc'])
        # calculation of the scenario costs inclusive storage costs
        costs_total_w_stor = (
            costs_total +
            (none_scal_given[(('storage_cool', 'None'), 'nominal_capacity')] *
             ep_costs_cool_stor) + (none_scal_given[(
                 ('storage_electricity', 'None'), 'nominal_capacity')] *
                                    ep_costs_el_stor))

    ########################
    # Write results in csv #
    ########################

    # ## scalars ## #
    # base scalars:
    scalars_all = cool_scal\
        .append(waste_scal)\
        .append(el_scal)\
        .append(none_scal)
    for i in range(0, none_scal_given.count()):
        if 'nominal_capacity' in none_scal_given.index[i]:
            scalars_all = pd.concat([
                scalars_all,
                pd.Series([none_scal_given[i]],
                          index=[none_scal_given.index[i]])
            ])

    # solar fractions
    scalars_all = pd.concat([
        scalars_all,
        pd.Series([sol_fraction_el],
                  index=["('solar fraction', 'electric'), ' ')"])
    ])
    if df_control_el['Product'].sum() != 0:
        scalars_all = pd.concat([
            scalars_all,
            pd.Series([df_control_el['Product'].sum()],
                      index=["Has to be 0!!!"])
        ])

    # various results
    scalars_all = pd.concat([
        scalars_all,
        pd.Series([el_used], index=["('grid_el', 'electricity'), 'summe')"])
    ])
    scalars_all = pd.concat([
        scalars_all,
        pd.Series([electricity_output],
                  index=["('electricity', 'output'), 'summe')"])
    ])
    scalars_all = pd.concat([
        scalars_all,
        pd.Series([electricity_output_pv],
                  index=["('pv', 'electricity'), 'summe')"])
    ])

    # costs with or without storage (depends on reference scenario or not)
    if param_value['nominal_capacitiy_stor_el'] != 0:
        scalars_all = pd.concat([
            scalars_all,
            pd.Series([costs_total_w_stor],
                      index=["('costs', 'w_stor'), 'per year')"])
        ])
    scalars_all = pd.concat([
        scalars_all,
        pd.Series([costs_total], index=["('costs', 'wo_stor'), 'per year')"])
    ])
    if param_value['nominal_capacitiy_stor_el'] == 0:
        scalars_all = pd.concat([
            scalars_all,
            pd.Series([costs_total_wo_stor],
                      index=["('costs', 'wo stor'), 'per year')"])
        ])

    # experiment number and variation
    scalars_all = pd.concat([
        scalars_all,
        pd.Series(['{0}_{1}'.format(cfg['exp_number'], var_number)],
                  index=["('Exp', 'Var'), 'number')"])
    ])

    # write scalars into csv for this experiment and variation
    scalars_all.to_csv(csv_path + 'electric_model_{0}_{1}_scalars.csv'.format(
        cfg['exp_number'], var_number),
                       header=False)

    # write scalars for all variations of the experiment into csv
    df_all_var = pd.concat([df_all_var, scalars_all], axis=1, sort=True)
    if var_number == (cfg['number_of_variations'] - 1):
        df_all_var.to_csv(csv_path +
                          'electric_model_{0}_scalars_all_variations.csv'.
                          format(cfg['exp_number']))
        logging.info('Writing the results for all variations into csv')

    # ## sequences ## #
    sequences_df = pd.merge(ambient_seq,
                            waste_seq,
                            left_index=True,
                            right_index=True)
    sequences_df = pd.merge(sequences_df,
                            el_seq,
                            left_index=True,
                            right_index=True)
    sequences_df = pd.merge(sequences_df,
                            cool_seq,
                            left_index=True,
                            right_index=True)
    sequences_df.to_csv(csv_path +
                        'electric_model_{0}_{1}_sequences.csv'.format(
                            cfg['exp_number'], var_number),
                        header=False)

    ########################
    # Plotting the results # # to adapt for the use case
    ########################

    cool_seq_resample = cool_seq.iloc[sp:ep]
    waste_seq_resample = waste_seq.iloc[sp:ep]
    el_seq_resample = el_seq.iloc[sp:ep]
    ambient_seq_resample = ambient_seq.iloc[sp:ep]

    def shape_legend(node, reverse=False, **kwargs):  # just copied
        handels = kwargs['handles']
        labels = kwargs['labels']
        axes = kwargs['ax']
        parameter = {}

        new_labels = []
        for label in labels:
            label = label.replace('(', '')
            label = label.replace('), flow)', '')
            label = label.replace(node, '')
            label = label.replace(',', '')
            label = label.replace(' ', '')
            new_labels.append(label)
        labels = new_labels

        parameter['bbox_to_anchor'] = kwargs.get('bbox_to_anchor', (1, 1))
        parameter['loc'] = kwargs.get('loc', 'upper left')
        parameter['ncol'] = kwargs.get('ncol', 1)
        plotshare = kwargs.get('plotshare', 0.9)

        if reverse:
            handels = handels.reverse()
            labels = labels.reverse()

        box = axes.get_position()
        axes.set_position([box.x0, box.y0, box.width * plotshare, box.height])

        parameter['handles'] = handels
        parameter['labels'] = labels
        axes.legend(**parameter)
        return axes

    cdict = {
        (('storage_cool', 'cool'), 'flow'): '#555555',
        (('cool', 'storage_cool'), 'flow'): '#9acd32',
        (('cool', 'demand'), 'flow'): '#cd0000',
        (('grid_el', 'electricity'), 'flow'): '#999999',
        (('pv', 'electricity'), 'flow'): '#ffde32',
        (('storage_electricity', 'electricity'), 'flow'): '#9acd32',
        (('electricity', 'storage_electricity'), 'flow'): '#9acd32',
        (('electricity', 'compression_chiller'), 'flow'): '#4682b4',
        (('electricity', 'cooling_tower'), 'flow'): '#ff0000',
        (('storage_cool', 'None'), 'capacity'): '#555555',
        (('storage_cool', 'cool'), 'flow'): '#9acd32',
        (('compression_chiller', 'waste'), 'flow'): '#4682b4',
        (('electricity', 'excess_el'), 'flow'): '#999999',
        (('waste', 'cool_tower'), 'flow'): '#42c77a'
    }

    # define order of inputs and outputs
    inorderel = [(('pv', 'electricity'), 'flow'),
                 (('storage_electricity', 'electricity'), 'flow'),
                 (('grid_el', 'electricity'), 'flow')]
    outorderel = [(('electricity', 'compression_chiller'), 'flow'),
                  (('electricity', 'cooling_tower'), 'flow'),
                  (('electricity', 'storage_electricity'), 'flow'),
                  (('electricity', 'excess_el'), 'flow')]

    fig = plt.figure(figsize=(15, 15))

    # plot electrical energy
    my_plot_el = oev.plot.io_plot('electricity',
                                  el_seq_resample,
                                  cdict=cdict,
                                  inorder=inorderel,
                                  outorder=outorderel,
                                  ax=fig.add_subplot(2, 2, 1),
                                  smooth=False)

    ax_el = shape_legend('electricity', **my_plot_el)

    ax_el.set_ylabel('Power in kW')
    ax_el.set_xlabel('time')
    ax_el.set_title("results of the electric model - electricity flows")

    plt.savefig(plot_path + 'electric_model_results_plot_{0}_{1}.png'.format(
        cfg['exp_number'], var_number))
    csv_plot = pd.merge(el_seq_resample,
                        cool_seq_resample,
                        left_index=True,
                        right_index=True)
    csv_plot = pd.merge(csv_plot,
                        el_seq_resample,
                        left_index=True,
                        right_index=True)
    csv_plot.to_csv(plot_path +
                    'electric_model_results_plot_data_{0}_{1}.csv'.format(
                        cfg['exp_number'], var_number))

    return df_all_var
Example #21
0
 def test_multiindex_sequences(self):
     results = processing.results(self.om)
     bel1 = views.node(results, 'b_el1', multiindex=True)
     eq_(int(bel1['sequences'][('diesel', 'b_el1', 'flow')].sum()), 2875)
Example #22
0
def test_gen_chp():
    # read sequence data
    full_filename = os.path.join(os.path.dirname(__file__), 'ccet.csv')
    data = pd.read_csv(full_filename)

    # select periods
    periods = len(data) - 1

    # create an energy system
    idx = pd.date_range('1/1/2017', periods=periods, freq='H')
    es = solph.EnergySystem(timeindex=idx)
    Node.registry = es

    # resources
    bgas = solph.Bus(label='bgas')

    solph.Source(label='rgas', outputs={bgas: solph.Flow()})

    # heat
    bth = solph.Bus(label='bth')

    solph.Source(label='source_th',
                 outputs={bth: solph.Flow(variable_costs=1000)})

    solph.Sink(
        label='demand_th',
        inputs={bth: solph.Flow(fix=data['demand_th'], nominal_value=200)})

    # power
    bel = solph.Bus(label='bel')

    solph.Sink(label='demand_el',
               inputs={bel: solph.Flow(variable_costs=data['price_el'])})

    # generic chp
    # (for back pressure characteristics Q_CW_min=0 and back_pressure=True)
    solph.components.GenericCHP(
        label='combined_cycle_extraction_turbine',
        fuel_input={
            bgas: solph.Flow(H_L_FG_share_max=data['H_L_FG_share_max'])
        },
        electrical_output={
            bel:
            solph.Flow(P_max_woDH=data['P_max_woDH'],
                       P_min_woDH=data['P_min_woDH'],
                       Eta_el_max_woDH=data['Eta_el_max_woDH'],
                       Eta_el_min_woDH=data['Eta_el_min_woDH'])
        },
        heat_output={bth: solph.Flow(Q_CW_min=data['Q_CW_min'])},
        Beta=data['Beta'],
        back_pressure=False)

    # create an optimization problem and solve it
    om = solph.Model(es)

    # solve model
    om.solve(solver='cbc')

    # create result object
    results = processing.results(om)

    data = views.node(results, 'bth')['sequences'].sum(axis=0).to_dict()

    test_dict = {
        (('bth', 'demand_th'), 'flow'): 20000.0,
        (('combined_cycle_extraction_turbine', 'bth'), 'flow'): 14070.15215799,
        (('source_th', 'bth'), 'flow'): 5929.8478649200015
    }

    for key in test_dict.keys():
        eq_(int(round(data[key])), int(round(test_dict[key])))
Example #23
0
 def test_duals(self):
     results = processing.results(self.om)
     bel = views.node(results, 'b_el1', multiindex=True)
     eq_(int(bel['sequences']['b_el1', 'None', 'duals'].sum()), 48)
Example #24
0
def main():
    """Execute main script."""
    def invest_sol(A, col_type=''):
        """Pehnt et al. 2017, Markus [38].

        A:                Kollektorfläche der Solarthermie
        col_type:         Kollektortyp der Solarthermie
        specific_coasts:  Spezifische Kosten
        invest:           Investitionskosten
        """
        if col_type == 'flat':
            specific_costs = -34.06 * np.log(A) + 592.48
            invest = A * specific_costs
            return invest
        elif col_type == 'vacuum':
            specific_costs = -40.63 * np.log(A) + 726.64
            invest = A * specific_costs
            return invest
        else:
            raise ValueError(
                "Choose a valid collector type: 'flat' or 'vacuum'")

    def liste(parameter):
        """Get timeseries list of parameter for solph components."""
        return [parameter for p in range(0, periods)]

    def result_labelling(dataframe):
        for col in dataframe.columns:
            if col in labeldict:
                dataframe.rename(columns={col: labeldict[col]}, inplace=True)
            else:
                print(col, ' not in labeldict')

    # %% Preprocessing

    # %% Daten einlesen

    dirpath = path.abspath(path.join(__file__, "../.."))
    filename = path.join(dirpath, 'Eingangsdaten\\simulation_data.csv')
    data = pd.read_csv(filename, sep=";")
    # filename = path.join(dirpath, 'Eingangsdaten\\All_parameters.csv')
    # param = pd.read_csv(filename, sep=";", index_col=['plant', 'parameter'])

    filepath = path.join(dirpath, 'Eingangsdaten\\parameter_v2b.json')
    with open(filepath, 'r') as file:
        param = json.load(file)

    # TODO
    cop_lt = 4.9501
    A = param['Sol']['A']

    invest_solar = invest_sol(A, col_type="flat")

    # %% Zeitreihe

    periods = len(data)
    date_time_index = pd.date_range('1/1/2016 00:00:00',
                                    periods=periods,
                                    freq='h')

    # %% Energiesystem erstellen

    es_ref = solph.EnergySystem(timeindex=date_time_index)

    # %% Wärmebedarf
    # rel_demand ist die Variable, die den Wärmebedarf der Region
    # prozentual von FL angibt.

    heat_demand_FL = data['heat_demand']
    rel_heat_demand = 1
    heat_demand_local = heat_demand_FL * rel_heat_demand
    total_heat_demand = float(heat_demand_local.sum())

    # %% Energiesystem

    # %% LT-WNW Plausibilität prüfen
    if (param['LT-HP']['active'] and not param['Sol']['active']
            and not param['TES']['active']):
        print("WARNING: You can't have the low temp heat pump active without ",
              "using either the TES or solar heat.")
        exit()
    elif (not param['LT-HP']['active']
          and (param['Sol']['active'] or param['TES']['active'])):
        print(
            "WARNING: You can't use TES or solar heat without using the low ",
            "temp heat pump.")
        exit()

        # %% Busses

    gnw = solph.Bus(label='Gasnetzwerk')
    enw = solph.Bus(label='Elektrizitätsnetzwerk')
    wnw = solph.Bus(label='Wärmenetzwerk')
    lt_wnw = solph.Bus(label='LT-Wärmenetzwerk')

    es_ref.add(gnw, enw, wnw, lt_wnw)

    # %% Soruces

    gas_source = solph.Source(
        label='Gasquelle',
        outputs={
            gnw:
            solph.Flow(variable_costs=(param['param']['gas_price'] +
                                       param['param']['co2_certificate']))
        })

    elec_source = solph.Source(
        label='Stromquelle',
        outputs={
            enw:
            solph.Flow(
                variable_costs=(param['param']['elec_consumer_charges'] +
                                data['el_spot_price']))
        })

    es_ref.add(gas_source, elec_source)

    if param['Sol']['active']:
        solar_source = solph.Source(
            label='Solarthermie',
            outputs={
                lt_wnw:
                solph.Flow(variable_costs=(0.01 * invest_solar) /
                           (A * data['solar_data'].sum()),
                           nominal_value=(max(data['solar_data']) * A),
                           actual_value=(data['solar_data']) /
                           (max(data['solar_data'])),
                           fixed=True)
            })

        es_ref.add(solar_source)

    if param['MR']['active']:
        mr_source = solph.Source(label='Mustrun',
                                 outputs={
                                     wnw:
                                     solph.Flow(variable_costs=0,
                                                nominal_value=float(
                                                    param['MR']['Q_N']),
                                                actual_value=1)
                                 })

        es_ref.add(mr_source)

        # %% Sinks

    elec_sink = solph.Sink(
        label='Spotmarkt',
        inputs={enw: solph.Flow(variable_costs=-data['el_spot_price'])})

    heat_sink = solph.Sink(
        label='Wärmebedarf',
        inputs={
            wnw:
            solph.Flow(variable_costs=-param['param']['heat_price'],
                       nominal_value=max(heat_demand_local),
                       actual_value=heat_demand_local / max(heat_demand_local),
                       fixed=True)
        })

    es_ref.add(elec_sink, heat_sink)

    if param['EC']['active']:
        ec_sink = solph.Sink(label='Emergency-cooling',
                             inputs={wnw: solph.Flow(variable_costs=0)})

        es_ref.add(ec_sink)

        # %% Transformer

    if param['EHK']['active']:
        for i in range(1, param['EHK']['amount'] + 1):
            ehk = solph.Transformer(
                label='Elektroheizkessel_' + str(i),
                inputs={enw: solph.Flow()},
                outputs={
                    wnw:
                    solph.Flow(nominal_value=param['EHK']['Q_N'],
                               max=1,
                               min=0,
                               variable_costs=param['EHK']['op_cost_var'])
                },
                conversion_factors={wnw: param['EHK']['eta']})

            es_ref.add(ehk)

    if param['SLK']['active']:
        for i in range(1, param['SLK']['amount'] + 1):
            slk = solph.Transformer(
                label='Spitzenlastkessel_' + str(i),
                inputs={gnw: solph.Flow()},
                outputs={
                    wnw:
                    solph.Flow(nominal_value=param['SLK']['Q_N'],
                               max=1,
                               min=0,
                               variable_costs=(param['SLK']['op_cost_var'] +
                                               param['param']['energy_tax']))
                },
                conversion_factors={wnw: param['SLK']['eta']})

            es_ref.add(slk)

    if param['BHKW']['active']:
        for i in range(1, param['BHKW']['amount'] + 1):
            bhkw = solph.components.GenericCHP(
                label='BHKW_' + str(i),
                fuel_input={
                    gnw:
                    solph.Flow(H_L_FG_share_max=liste(
                        param['BHKW']['H_L_FG_share_max']),
                               H_L_FG_share_min=liste(
                                   param['BHKW']['H_L_FG_share_min']),
                               nominal_value=param['BHKW']['Q_in'])
                },
                electrical_output={
                    enw:
                    solph.Flow(variable_costs=param['BHKW']['op_cost_var'],
                               P_max_woDH=liste(param['BHKW']['P_max_woDH']),
                               P_min_woDH=liste(param['BHKW']['P_min_woDH']),
                               Eta_el_max_woDH=liste(
                                   param['BHKW']['Eta_el_max_woDH']),
                               Eta_el_min_woDH=liste(
                                   param['BHKW']['Eta_el_min_woDH']))
                },
                heat_output={
                    wnw: solph.Flow(Q_CW_min=liste(0), Q_CW_max=liste(0))
                },
                Beta=liste(0),
                back_pressure=False)

            es_ref.add(bhkw)

    if param['GuD']['active']:
        for i in range(1, param['GuD']['amount'] + 1):
            gud = solph.components.GenericCHP(
                label='GuD_' + str(i),
                fuel_input={
                    gnw:
                    solph.Flow(H_L_FG_share_max=liste(
                        param['GuD']['H_L_FG_share_max']),
                               nominal_value=param['GuD']['Q_in'])
                },
                electrical_output={
                    enw:
                    solph.Flow(
                        variable_costs=param['GuD']['op_cost_var'],
                        P_max_woDH=liste(param['GuD']['P_max_woDH']),
                        P_min_woDH=liste(param['GuD']['P_min_woDH']),
                        Eta_el_max_woDH=liste(param['GuD']['Eta_el_max_woDH']),
                        Eta_el_min_woDH=liste(param['GuD']['Eta_el_min_woDH']))
                },
                heat_output={
                    wnw:
                    solph.Flow(Q_CW_min=liste(param['GuD']['Q_CW_min']),
                               Q_CW_max=liste(0))
                },
                Beta=liste(param['GuD']['beta']),
                back_pressure=False)

            es_ref.add(gud)

    if param['BPT']['active']:
        for i in range(1, param['BPT']['amount'] + 1):
            bpt = solph.components.GenericCHP(
                label='bpt' + str(i),
                fuel_input={
                    gnw:
                    solph.Flow(H_L_FG_share_max=liste(
                        param['bpt']['H_L_FG_share_max']),
                               nominal_value=param['bpt']['Q_in'])
                },
                electrical_output={
                    enw:
                    solph.Flow(
                        variable_costs=param['bpt']['op_cost_var'],
                        P_max_woDH=liste(param['bpt']['P_max_woDH']),
                        P_min_woDH=liste(param['bpt']['P_min_woDH']),
                        Eta_el_max_woDH=liste(param['bpt']['Eta_el_max_woDH']),
                        Eta_el_min_woDH=liste(param['bpt']['Eta_el_min_woDH']))
                },
                heat_output={
                    wnw: solph.Flow(Q_CW_min=liste(0), Q_CW_max=liste(0))
                },
                Beta=liste(0),
                back_pressure=True)

            es_ref.add(bpt)

    # 30% m-Teillast bei 65-114°C und 50% m-Teillast bei 115-124°C
    if param['HP']['active']:
        for i in range(1, param['HP']['amount'] + 1):
            hp = solph.components.OffsetTransformer(
                label='HP_' + str(i),
                inputs={
                    enw:
                    solph.Flow(nominal_value=1,
                               max=data['P_max_hp'],
                               min=data['P_min_hp'],
                               variable_costs=param['HP']['op_cost_var'],
                               nonconvex=solph.NonConvex())
                },
                outputs={wnw: solph.Flow()},
                coefficients=[data['c_0_hp'], data['c_1_hp']])

            es_ref.add(hp)

        # %% Speicher

    # Saisonaler Speicher
    if param['TES']['active']:
        for i in range(1, param['TES']['amount'] + 1):
            tes = solph.components.GenericStorage(
                label='TES_' + str(i),
                nominal_storage_capacity=param['TES']['Q'],
                inputs={
                    wnw:
                    solph.Flow(
                        storageflowlimit=True,
                        nominal_value=param['TES']['Q_N_in'],
                        max=param['TES']['Q_rel_in_max'],
                        min=param['TES']['Q_rel_in_min'],
                        variable_costs=param['TES']['op_cost_var'],
                        nonconvex=solph.NonConvex(
                            minimum_uptime=int(param['TES']['min_uptime']),
                            initial_status=int(param['TES']['init_status'])))
                },
                outputs={
                    lt_wnw:
                    solph.Flow(
                        storageflowlimit=True,
                        nominal_value=param['TES']['Q_N_out'],
                        max=param['TES']['Q_rel_out_max'],
                        min=param['TES']['Q_rel_out_min'],
                        nonconvex=solph.NonConvex(
                            minimum_uptime=int(param['TES']['min_uptime'])))
                },
                initial_storage_level=param['TES']['init_storage'],
                loss_rate=param['TES']['Q_rel_loss'],
                inflow_conversion_factor=param['TES']['inflow_conv'],
                outflow_conversion_factor=param['TES']['outflow_conv'])

            es_ref.add(tes)

    # Low temperature heat pump

    if param['LT-HP']['active']:
        for i in range(1, param['LT-HP']['amount'] + 1):
            lthp = solph.Transformer(
                label="LT-HP_" + str(i),
                inputs={
                    lt_wnw: solph.Flow(),
                    enw: solph.Flow(variable_costs=param['HP']['op_cost_var'])
                },
                outputs={wnw: solph.Flow()},
                conversion_factors={
                    enw: 1 / data['cop_lthp'],
                    lt_wnw: (data['cop_lthp'] - 1) / data['cop_lthp']
                }
                # conversion_factors={enw: 1/cop_lt,
                #                     lt_wnw: (cop_lt-1)/cop_lt}
            )

            es_ref.add(lthp)

    # %% Processing

    # %% Solve

    # Was bedeutet tee?
    model = solph.Model(es_ref)
    solph.constraints.limit_active_flow_count_by_keyword(model,
                                                         'storageflowlimit',
                                                         lower_limit=0,
                                                         upper_limit=1)
    # model.write('my_model.lp', io_options={'symbolic_solver_labels': True})
    model.solve(solver='gurobi',
                solve_kwargs={'tee': True},
                cmdline_options={"mipgap": "0.05"})

    # %% Ergebnisse Energiesystem

    # Ergebnisse in results
    results = solph.processing.results(model)

    # Main- und Metaergebnisse
    es_ref.results['main'] = solph.processing.results(model)
    es_ref.results['meta'] = solph.processing.meta_results(model)

    invest_ges = 0
    cost_Anlagen = 0
    labeldict = {}

    # Busses
    data_gnw = views.node(results, 'Gasnetzwerk')['sequences']
    data_enw = views.node(results, 'Elektrizitätsnetzwerk')['sequences']
    data_wnw = views.node(results, 'Wärmenetzwerk')['sequences']
    data_lt_wnw = views.node(results, 'LT-Wärmenetzwerk')['sequences']

    labeldict[(('Gasquelle', 'Gasnetzwerk'), 'flow')] = 'H_source'
    labeldict[(('Elektrizitätsnetzwerk', 'Spotmarkt'),
               'flow')] = 'P_spot_market'
    labeldict[(('Stromquelle', 'Elektrizitätsnetzwerk'), 'flow')] = 'P_source'
    labeldict[(('Wärmenetzwerk', 'Wärmebedarf'), 'flow')] = 'Q_demand'

    # Sources
    data_gas_source = views.node(results, 'Gasquelle')['sequences']
    data_elec_source = views.node(results, 'Stromquelle')['sequences']

    if param['Sol']['active']:
        data_solar_source = views.node(results, 'Solarthermie')['sequences']
        invest_ges += invest_solar
        cost_Anlagen += (data_solar_source[(
            ('Solarthermie', 'LT-Wärmenetzwerk'), 'flow')].sum() *
                         (0.01 * invest_solar) /
                         (A * data['solar_data'].sum()))
        labeldict[(('Solarthermie', 'LT-Wärmenetzwerk'), 'flow')] = 'Q_Sol'

    if param['MR']['active']:
        data_mr_source = views.node(results, 'Mustrun')['sequences']
        labeldict[(('Mustrun', 'Wärmenetzwerk'), 'flow')] = 'Q_MR'

    # Sinks
    data_elec_sink = views.node(results, 'Spotmarkt')['sequences']
    data_heat_sink = views.node(results, 'Wärmebedarf')['sequences']

    if param['EC']['active']:
        data_ec = views.node(results, 'Emergency-cooling')['sequences']
        labeldict[(('Wärmenetzwerk', 'Emergency-cooling'), 'flow')] = 'Q_EC'

    # Transformer
    if param['EHK']['active']:
        invest_ges += (param['EHK']['inv_spez'] * param['EHK']['Q_N'] *
                       param['EHK']['amount'])

        for i in range(1, param['EHK']['amount'] + 1):
            label_id = 'Elektroheizkessel_' + str(i)
            data_ehk = views.node(results, label_id)['sequences']

            cost_Anlagen += (
                data_ehk[((label_id, 'Wärmenetzwerk'), 'flow')].sum() *
                param['EHK']['op_cost_var'] +
                (param['EHK']['op_cost_fix'] * param['EHK']['Q_N']))

            labeldict[((label_id, 'Wärmenetzwerk'),
                       'flow')] = 'Q_EHK_' + str(i)
            labeldict[(('Elektrizitätsnetzwerk', label_id),
                       'flow')] = 'P_zu_EHK_' + str(i)

    if param['SLK']['active']:
        invest_ges += (param['SLK']['inv_spez'] * param['SLK']['Q_N'] *
                       param['SLK']['amount'])

        for i in range(1, param['SLK']['amount'] + 1):
            label_id = 'Spitzenlastkessel_' + str(i)
            data_slk = views.node(results, label_id)['sequences']

            cost_Anlagen += (
                data_slk[((label_id, 'Wärmenetzwerk'), 'flow')].sum() *
                (param['SLK']['op_cost_var'] + param['param']['energy_tax']) +
                (param['SLK']['op_cost_fix'] * param['SLK']['Q_N']))

            labeldict[((label_id, 'Wärmenetzwerk'),
                       'flow')] = 'Q_SLK_' + str(i)
            labeldict[(('Gasnetzwerk', label_id), 'flow')] = 'H_SLK_' + str(i)

    if param['BHKW']['active']:
        invest_ges += (param['BHKW']['P_max_woDH'] *
                       param['BHKW']['inv_spez'] * param['BHKW']['amount'])

        for i in range(1, param['BHKW']['amount'] + 1):
            label_id = 'BHKW_' + str(i)
            data_bhkw = views.node(results, label_id)['sequences']

            cost_Anlagen += (
                data_bhkw[(
                    (label_id, 'Elektrizitätsnetzwerk'), 'flow')].sum() *
                param['BHKW']['op_cost_var'] +
                (param['BHKW']['op_cost_fix'] * param['BHKW']['P_max_woDH']))

            labeldict[((label_id, 'Wärmenetzwerk'), 'flow')] = 'Q_' + label_id
            labeldict[((label_id, 'Elektrizitätsnetzwerk'),
                       'flow')] = 'P_' + label_id
            labeldict[(('Gasnetzwerk', label_id), 'flow')] = 'H_' + label_id

    if param['GuD']['active']:
        invest_ges += (param['GuD']['P_max_woDH'] * param['GuD']['inv_spez'] *
                       param['GuD']['amount'])

        for i in range(1, param['GuD']['amount'] + 1):
            label_id = 'GuD_' + str(i)
            data_gud = views.node(results, label_id)['sequences']

            cost_Anlagen += (
                data_gud[((label_id, 'Elektrizitätsnetzwerk'), 'flow')].sum() *
                param['GuD']['op_cost_var'] +
                (param['GuD']['op_cost_fix'] * param['GuD']['P_max_woDH']))

            labeldict[((label_id, 'Wärmenetzwerk'), 'flow')] = 'Q_' + label_id
            labeldict[((label_id, 'Elektrizitätsnetzwerk'),
                       'flow')] = 'P_' + label_id
            labeldict[(('Gasnetzwerk', label_id), 'flow')] = 'H_' + label_id

    if param['HP']['active']:
        invest_ges += (param['HP']['inv_spez'] * data['P_max_hp'].max() *
                       param['HP']['amount'])

        for i in range(1, param['HP']['amount'] + 1):
            label_id = 'HP_' + str(i)
            data_hp = views.node(results, label_id)['sequences']

            cost_Anlagen += (
                data_hp[(('Elektrizitätsnetzwerk', label_id), 'flow')].sum() *
                param['HP']['op_cost_var'] +
                (param['HP']['op_cost_fix'] * data['P_max_hp'].max()))

            labeldict[((label_id, 'Wärmenetzwerk'),
                       'flow')] = 'Q_ab_' + label_id
            labeldict[(('Elektrizitätsnetzwerk', label_id),
                       'flow')] = 'P_zu_' + label_id
            labeldict[(('Elektrizitätsnetzwerk', label_id),
                       'status')] = 'Status_' + label_id

    if param['LT-HP']['active']:
        for i in range(1, param['LT-HP']['amount'] + 1):
            label_id = 'LT-HP_' + str(i)
            data_lt_hp = views.node(results, label_id)['sequences']

            invest_ges += (param['HP']['inv_spez'] * data_wnw[(
                (label_id, 'Wärmenetzwerk'), 'flow')].max() /
                           data['cop_lthp'].mean())

            cost_Anlagen += (data_lt_hp[(
                ('Elektrizitätsnetzwerk', label_id), 'flow')].sum() *
                             param['HP']['op_cost_var'] +
                             (param['HP']['op_cost_fix'] * data_wnw[(
                                 (label_id, 'Wärmenetzwerk'), 'flow')].max() /
                              data['cop_lthp'].mean()))

            labeldict[((label_id, 'Wärmenetzwerk'),
                       'flow')] = 'Q_ab_' + label_id
            labeldict[(('Elektrizitätsnetzwerk', label_id),
                       'flow')] = 'P_zu_' + label_id
            labeldict[(('LT-Wärmenetzwerk', label_id),
                       'flow')] = 'Q_zu_' + label_id

    # Speicher
    if param['TES']['active']:
        invest_ges += (param['TES']['inv_spez'] * param['TES']['Q'] *
                       param['TES']['amount'])

        for i in range(1, param['TES']['amount'] + 1):
            label_id = 'TES_' + str(i)
            data_tes = views.node(results, label_id)['sequences']

            cost_Anlagen += (data_tes[(
                ('Wärmenetzwerk', label_id), 'flow')].sum() *
                             param['TES']['op_cost_var'] +
                             (param['TES']['op_cost_fix'] * param['TES']['Q']))

            labeldict[((label_id, 'LT-Wärmenetzwerk'),
                       'flow')] = 'Q_ab_' + label_id
            labeldict[((label_id, 'LT-Wärmenetzwerk'),
                       'status')] = 'Status_ab_' + label_id
            labeldict[(('Wärmenetzwerk', label_id),
                       'flow')] = 'Q_zu_' + label_id
            labeldict[(('Wärmenetzwerk', label_id),
                       'status')] = 'Status_zu_' + label_id
            labeldict[((label_id, 'None'),
                       'storage_content')] = 'Speicherstand_' + label_id

        # %% Zahlungsströme Ergebnis

    objective = abs(es_ref.results['meta']['objective'])

    # %% Geldflüsse

    # # Primärenergiebezugskoste
    cost_gas = (
        data_gnw[(('Gasquelle', 'Gasnetzwerk'), 'flow')].sum() *
        (param['param']['gas_price'] + param['param']['co2_certificate']))

    el_flow = np.array(data_enw[(('Stromquelle', 'Elektrizitätsnetzwerk'),
                                 'flow')])
    cost_el_timeseries = np.array(data['el_price'])
    cost_el_array = el_flow * cost_el_timeseries
    cost_el = cost_el_array.sum()

    # Erlöse
    revenues_spotmarkt_timeseries = (np.array(data_enw[(
        ('Elektrizitätsnetzwerk', 'Spotmarkt'), 'flow')]) *
                                     np.array(data['el_spot_price']))
    revenues_spotmarkt = revenues_spotmarkt_timeseries.sum()

    revenues_heatdemand = (data_wnw[(
        ('Wärmenetzwerk', 'Wärmebedarf'), 'flow')].sum() *
                           param['param']['heat_price'])
    # Summe der Geldströme
    Gesamtbetrag = (revenues_spotmarkt + revenues_heatdemand - cost_Anlagen -
                    cost_gas - cost_el)

    # %% Output Ergebnisse

    # Umbenennen der Spaltennamen der Ergebnisdataframes
    result_dfs = [data_wnw, data_lt_wnw, data_tes, data_enw, data_gnw]

    for df in result_dfs:
        result_labelling(df)

    # Daten zum Plotten der Wärmeversorgung
    df1 = pd.concat([data_wnw, data_lt_wnw, data_tes, data_enw], axis=1)
    df1.to_csv(path.join(dirpath, 'Ergebnisse\\Vorarbeit\\Vor_wnw.csv'),
               sep=";")

    # Daten zum Plotten der Investitionsrechnung
    df2 = pd.DataFrame(
        data={
            'invest_ges': [invest_ges],
            'Q_tes': [param['TES']['Q']],
            'total_heat_demand': [total_heat_demand],
            'Gesamtbetrag': [Gesamtbetrag]
        })
    df2.to_csv(path.join(dirpath, 'Ergebnisse\\Vorarbeit\\Vor_Invest.csv'),
               sep=";")

    # Daten für die ökologische Bewertung
    df3 = pd.concat(
        [data_gnw[['H_source']], data_enw[['P_spot_market', 'P_source']]],
        axis=1)
    df3.to_csv(path.join(dirpath, 'Ergebnisse\\Vorarbeit\\Vor_CO2.csv'),
               sep=";")
Example #25
0
 def test_input_by_type_view(self):
     results = processing.results(self.om)
     sink_input = views.node_input_by_type(results, node_type=Sink)
     compare = views.node(results, 'demand_el', multiindex=True)
     eq_(int(sink_input.sum()),
         int(compare['sequences'][('b_el2', 'demand_el', 'flow')].sum()))
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])))
def test_tuples_as_labels_example(filename="storage_investment.csv",
                                  solver='cbc'):

    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2012', periods=40, freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)
    Node.registry = energysystem

    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")

    # Buses
    bgas = solph.Bus(label=Label('bus', 'natural_gas', None))
    bel = solph.Bus(label=Label('bus', 'electricity', ''))

    # Sinks
    solph.Sink(label=Label('sink', 'electricity', 'excess'),
               inputs={bel: solph.Flow()})

    solph.Sink(
        label=Label('sink', 'electricity', 'demand'),
        inputs={bel: solph.Flow(fix=data['demand_el'], nominal_value=1)})

    # Sources
    solph.Source(label=Label('source', 'natural_gas', 'commodity'),
                 outputs={
                     bgas:
                     solph.Flow(nominal_value=194397000 * 400 / 8760,
                                summed_max=1)
                 })

    solph.Source(
        label=Label('renewable', 'electricity', 'wind'),
        outputs={bel: solph.Flow(fix=data['wind'], nominal_value=1000000)})

    solph.Source(
        label=Label('renewable', 'electricity', 'pv'),
        outputs={bel: solph.Flow(
            fix=data['pv'],
            nominal_value=582000,
        )})

    # Transformer
    solph.Transformer(
        label=Label('pp', 'electricity', 'natural_gas'),
        inputs={bgas: solph.Flow()},
        outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)},
        conversion_factors={bel: 0.58})

    # Investment storage
    solph.components.GenericStorage(
        label=Label('storage', 'electricity', 'battery'),
        nominal_storage_capacity=204685,
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.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,
    )

    # Solve model
    om = solph.Model(energysystem)
    om.solve(solver=solver)
    energysystem.results['main'] = processing.results(om)
    energysystem.results['meta'] = processing.meta_results(om)

    # Check dump and restore
    energysystem.dump()
    es = solph.EnergySystem()
    es.restore()

    # Results
    results = es.results['main']
    meta = es.results['meta']

    electricity_bus = views.node(results, 'bus_electricity_')
    my_results = electricity_bus['sequences'].sum(axis=0).to_dict()
    storage = es.groups['storage_electricity_battery']
    storage_node = views.node(results, storage)
    my_results['max_load'] = storage_node['sequences'].max()[((
        storage, None), 'storage_content')]
    commodity_bus = views.node(results, 'bus_natural_gas_None')

    gas_usage = commodity_bus['sequences'][(('source_natural_gas_commodity',
                                             'bus_natural_gas_None'), 'flow')]

    my_results['gas_usage'] = gas_usage.sum()

    stor_invest_dict = {
        'gas_usage': 1304112,
        'max_load': 0,
        (('bus_electricity_', 'sink_electricity_demand'), 'flow'): 8239764,
        (('bus_electricity_', 'sink_electricity_excess'), 'flow'): 22036732,
        (('bus_electricity_', 'storage_electricity_battery'), 'flow'): 0,
        (('pp_electricity_natural_gas', 'bus_electricity_'), 'flow'): 756385,
        (('renewable_electricity_pv', 'bus_electricity_'), 'flow'): 744132,
        (('renewable_electricity_wind', 'bus_electricity_'), 'flow'): 28775978,
        ((
            'storage_electricity_battery',
            'bus_electricity_',
        ), 'flow'): 0
    }

    for key in stor_invest_dict.keys():
        eq_(int(round(my_results[key])), int(round(stor_invest_dict[key])))

    # Solver results
    eq_(str(meta['solver']['Termination condition']), 'optimal')
    eq_(meta['solver']['Error rc'], 0)
    eq_(str(meta['solver']['Status']), 'ok')

    # Problem results
    eq_(int(meta['problem']['Lower bound']), 37819254)
    eq_(int(meta['problem']['Upper bound']), 37819254)
    eq_(meta['problem']['Number of variables'], 281)
    eq_(meta['problem']['Number of constraints'], 163)
    eq_(meta['problem']['Number of nonzeros'], 116)
    eq_(meta['problem']['Number of objectives'], 1)
    eq_(str(meta['problem']['Sense']), 'minimize')

    # Objective function
    eq_(round(meta['objective']), 37819254)