예제 #1
0
def run_test_example():
    date_time_index = pd.date_range('1/1/2012', periods=5, freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    bgas = solph.Bus(label="natural_gas")
    bel = solph.Bus(label="electricity")
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})
    solph.Source(label='rgas', outputs={bgas: solph.Flow()})
    solph.Sink(label='demand',
               inputs={
                   bel:
                   solph.Flow(actual_value=[10, 20, 30, 40, 50],
                              fixed=True,
                              nominal_value=1)
               })
    solph.LinearTransformer(
        label="pp_gas",
        inputs={bgas: solph.Flow()},
        outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)},
        conversion_factors={bel: 0.58})
    om = solph.OperationalModel(energysystem)

    # check solvers
    solver = dict()
    for s in ['cbc', 'glpk', 'gurobi', 'cplex']:
        try:
            om.solve(solver=s)
            solver[s] = "working"
        except Exception:
            solver[s] = "not working"
    print("*********")
    print('Solver installed with oemof:')
    for s, t in solver.items():
        print("{0}: {1}".format(s, t))
    print("*********")
    print("oemof successfully installed.")
예제 #2
0
def optimise_storage_size(filename="storage_invest.csv",
                          solvername='cbc',
                          debug=True,
                          number_timesteps=8760,
                          tee_switch=True):
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/' + str(year),
                                    periods=number_timesteps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

    # Read data file
    full_filename = os.path.join(os.path.dirname(__file__), filename)
    data = pd.read_csv(full_filename, sep=",")
    data_demand = data['demand_el'] / data['demand_el'].sum()

    ##########################################################################
    # Create oemof object
    ##########################################################################
    consumption = 5165 * 1e6
    wind_installed = 1516 * 1e3
    pv_installed = 1491 * 1e3
    grid_share = 0.75

    logging.info('Create oemof objects')
    # create gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # create excess component for the electricity bus to allow overproduction
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})

    # Create commodity object for import electricity resource
    solph.Source(label='gridsource',
                 outputs={
                     bel:
                     solph.Flow(nominal_value=consumption * grid_share *
                                number_timesteps / 8760,
                                summed_max=1)
                 })

    # create fixed source object for wind
    solph.Source(label='wind',
                 outputs={
                     bel:
                     solph.Flow(actual_value=wind_feedin,
                                nominal_value=wind_installed,
                                fixed=True,
                                fixed_costs=20)
                 })

    # create fixed source object for pv
    solph.Source(label='pv',
                 outputs={
                     bel:
                     solph.Flow(actual_value=pv_feedin,
                                nominal_value=pv_installed,
                                fixed=True,
                                fixed_costs=15)
                 })

    # create simple sink object for demand
    solph.Sink(label='demand',
               inputs={
                   bel:
                   solph.Flow(actual_value=data_demand,
                              fixed=True,
                              nominal_value=consumption)
               })

    # Calculate ep_costs from capex to compare with old solph
    capex = 1000
    lifetime = 20
    wacc = 0.05
    epc = capex * (wacc * (1 + wacc)**lifetime) / ((1 + wacc)**lifetime - 1)

    # create storage transformer object for storage
    solph.Storage(
        label='storage',
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.Flow(variable_costs=10e10)},
        capacity_loss=0.00,
        initial_capacity=0,
        nominal_input_capacity_ratio=1,
        nominal_output_capacity_ratio=1,
        inflow_conversion_factor=1,
        outflow_conversion_factor=0.8,
        fixed_costs=35,
        investment=solph.Investment(ep_costs=epc),
    )

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

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(energysystem)

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

    logging.info('Solve the optimization problem')
    om.solve(solver=solvername, solve_kwargs={'tee': tee_switch})

    return energysystem
예제 #3
0
파일: main.py 프로젝트: knut0815/reegis_hp
def berlin_model(berlin_e_system):
    """

    Parameters
    ----------
    berlin_e_system : solph.EnergySystem

    Returns
    -------

    """
    time_index = berlin_e_system.time_idx
    p = preferences.Basic()
    d = preferences.Data()

    logging.info("Adding objects to the energy system...")

    # Electricity
    solph.Bus(label='bus_el')

    heat_demand = heat.DemandHeat(time_index)
    heating_systems = [s for s in heat_demand.get().columns if "frac_" in s]

    remove_string = 'frac_'
    heat_demand.demand_by('total_loss_pres',
                          heating_systems,
                          d.bt_dict,
                          remove_string,
                          percentage=True)

    heat_demand.df = heat_demand.dissolve('bezirk', 'demand_by', index=True)

    heat_demand.df = heat_demand.df.rename(
        columns={
            k: k.replace('frac_', '')
            for k in heat_demand.df.columns.get_level_values(1)
        })

    for t in p.types:
        heat_demand.df[t] = (
            heat_demand.df[t].multiply(
                d.sanierungsanteil[t] * d.sanierungsreduktion[t]) +
            heat_demand.df[t].multiply(1 - d.sanierungsanteil[t])) * 1000

    ep = dict()
    ep['basic'] = pd.read_csv('/home/uwe/e_p.csv', ';')
    ep['stromanteil'] = pd.read_csv('/home/uwe/stromanteil_e_p.csv', ';')

    fraction_heating_system_saniert = {
        'off-peak_electricity_heating': 0,
        'district_heating': 0.6,
        'natural_gas_heating': 0.4,
        'oil_heating': 0.4,
        'coal_stove': 0,
        'wp': 1,
    }

    fraction_electrical_dhw = {
        'off-peak_electricity_heating': 1,
        'district_heating': 0.11,
        'natural_gas_heating': 0.09,
        'oil_heating': 0.58,
        'coal_stove': 1,
        'wp': 0,
    }
    ep_mix = dict()
    for e in ep.keys():
        ep_mix[e] = dict()
        for b in p.types:
            ep_mix[e][b] = dict()
            cols = [x.replace('_int_DHW', '') for x in ep[e].columns]
            cols = set([x.replace('_el_DHW', '') for x in cols])
            cols.remove('gtype')
            cols.remove('building')
            cols.remove('heating_system')
            for h in cols:
                tmp = dict()
                for bs in ['saniert', 'unsaniert']:
                    tmp[bs] = dict()
                    for hs in ['saniert', 'unsaniert']:
                        qu = 'gtype=="{0}"'.format(b.upper())
                        qu += ' and building=="{0}"'.format(bs)
                        qu += ' and heating_system=="{0}"'.format(hs)
                        # Mix internal DHW and electrical DHW
                        ep[e].ix[(ep[e].gtype == b.upper()) &
                                 (ep[e].building == bs) &
                                 (ep[e].heating_system == hs),
                                 h] = (ep[e].query(qu)[h + '_int_DHW'] *
                                       (1 - fraction_electrical_dhw[h]) +
                                       ep[e].query(qu)[h + '_el_DHW'] *
                                       fraction_electrical_dhw[h])
                        tmp[bs][hs] = ep[e].query(qu)[h]
                ep_mix[e][b][h] = (
                    float(tmp['saniert']['saniert']) * d.sanierungsanteil[b] *
                    fraction_heating_system_saniert[h] +
                    float(tmp['saniert']['unsaniert']) *
                    d.sanierungsanteil[b] *
                    (1 - fraction_heating_system_saniert[h]) +
                    float(tmp['unsaniert']['saniert']) *
                    (1 - d.sanierungsanteil[b]) *
                    fraction_heating_system_saniert[h] +
                    float(tmp['unsaniert']['unsaniert']) *
                    (1 - d.sanierungsanteil[b]) *
                    (1 - fraction_heating_system_saniert[h]))

    add_dict = {
        'district_dz': 'district_heating',
        'district_z': 'district_heating',
        'bhkw': 'district_heating',
    }

    for e in ep_mix.keys():
        for b in ep_mix[e].keys():
            for new_key in add_dict.keys():
                ep_mix[e][b][new_key] = ep_mix[e][b][add_dict[new_key]]

    # Add heating systems
    sum_wp = 6.42e+10  # Bei 2000 Volllaststunden
    sum_bhkw = 6.75e+11  # Bei 2000 Volllaststunden
    # sum_wp = 50e+9
    # sum_bhkw = 50e+9
    sum_existing = heat_demand.df.sum().sum()
    reduction = (sum_existing - (sum_wp + sum_bhkw)) / sum_existing
    frac_mfh = heat_demand.df.mfh.sum().sum() / heat_demand.df.sum().sum()
    new = {
        'efh': {
            'wp': sum_wp * (1 - frac_mfh),
            'bhkw': sum_bhkw * (1 - frac_mfh)
        },
        'mfh': {
            'wp': sum_wp * frac_mfh,
            'bhkw': sum_bhkw * frac_mfh
        }
    }
    heat_demand.df *= reduction

    # Join some categories
    ol = d.other_demand.pop('oil_light')
    oh = d.other_demand.pop('oil_heavy')
    oo = d.other_demand.pop('oil_other')
    for c in ['ghd', 'i']:
        d.other_demand['oil_heating'][c] = ol[c] + oh[c] + oo[c]
        d.other_demand['natural_gas_heating'][c] += d.other_demand[
            'liquid_gas'][c]
    d.other_demand.pop('liquid_gas')

    heat_demand.df.sortlevel(axis='columns', inplace=True)
    # noinspection PyTypeChecker
    district_z = heat_demand.df.loc[:, (slice(None),
                                        'district_heating')].multiply(
                                            d.fw_verteilung, axis=0).sum()
    # noinspection PyTypeChecker
    district_dz = heat_demand.df.loc[:,
                                     (slice(None),
                                      'district_heating')].multiply(
                                          (1 - d.fw_verteilung), axis=0).sum()

    dsum = heat_demand.df.sum()

    for b in ['efh', 'mfh']:
        dsum[b, 'district_dz'] = district_dz[b]['district_heating']
        dsum[b, 'district_z'] = district_z[b]['district_heating']
        dsum[b, 'bhkw'] = new[b]['bhkw']
        dsum[b, 'wp'] = new[b]['wp']

    dsum.drop('district_heating', 0, 'second', True)
    dsum.sort_index(inplace=True)

    ew = pd.read_csv('/home/uwe/chiba/RLI/data/stadtnutzung_erweitert.csv')[[
        'ew', 'schluessel_planungsraum'
    ]]
    grp = ew.schluessel_planungsraum.astype(str).str[:-8]
    grp = grp.apply(lambda x: '{0:0>2}'.format(x))
    ew = ew.groupby(grp).sum().drop('schluessel_planungsraum', 1)
    # dhw_profile = pd.read_csv('/home/uwe/dhw_demand.csv')
    # *ew.sum() * 657
    dhw = ew.sum() * 657000  # 657000 Wh pro EW

    dhw_factor = (dsum.sum().sum() + float(dhw)) / dsum.sum().sum()
    dsum *= dhw_factor

    dfull = d.other_demand
    aux_elec = dict()
    sum_aux = 0
    print(ep_mix)
    for b in dsum.keys().levels[0]:
        for h in dsum[b].keys():
            dfull.setdefault(h, dict())
            aux_elec.setdefault(h, dict())
            aux_elec[h][b] = (dsum[b][h] * ep_mix['basic'][b][h] *
                              ep_mix['stromanteil'][b][h] / 100)
            print("{:.2E}".format(aux_elec[h][b]))
            sum_aux += aux_elec[h][b]
            dfull[h][b] = dsum[b][h] * ep_mix['basic'][b][h] - aux_elec[h][b]
    # print(dfull)
    # e = 0
    # for a in dfull.keys():
    #     for b in dfull[a].keys():
    #         if b in ['i']:
    #             print(a, b, dfull[a][b])
    #             e += dfull[a][b]
    # print(e)
    # exit(0)
    create_objects.heating_systems(berlin_e_system, dfull, aux_elec, p)

    mylist = list(berlin_e_system.groups.items())
    # Add excess and slack for every BUS

    for k, g in mylist:
        if isinstance(g, solph.Bus):
            solph.Sink(label='excess_{0}'.format(k),
                       inputs={g: solph.Flow(variable_costs=9000)})
            solph.Source(label='slack_{0}'.format(k),
                         outputs={g: solph.Flow(variable_costs=9000)})
    # slacks = ['bus_el', 'bus_district_z', 'bus_district_dz']
    # for s in slacks:
    #     obj = berlin_e_system.groups[s]
    #     solph.Source(label='slack_{0}'.format(s),
    #                  outputs={obj: solph.Flow(variable_costs=9000)})

    # sources
    source_costs = {
        'lignite': 90,
        'natural_gas': 120,
        'fuel_bio': 150,
        'solar_thermal': 0,
        'biomass': 140,
        'oil': 130,
        'coal': 100
    }

    for src in source_costs:
        if 'bus_' + src in berlin_e_system.groups:
            solph.Source(label=src,
                         outputs={
                             berlin_e_system.groups['bus_' + src]:
                             solph.Flow(variable_costs=source_costs[src])
                         })
        else:
            logging.warning("No need for a {0} source.".format(src))

    # import pprint as pp
    # pp.pprint(berlin_e_system.groups)

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(berlin_e_system)

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

    logging.info('Solve the optimization problem')
    om.solve(solver='gurobi', solve_kwargs={'tee': True})

    berlin_e_system.dump('/home/uwe/')
    return berlin_e_system
예제 #4
0
def optimise_storage_size(filename="storage_investment.csv",
                          solver='cbc',
                          debug=True,
                          number_timesteps=8760,
                          tee_switch=True):
    logging.info('Initialize the energy system')
    date_time_index = pd.date_range('1/1/2012',
                                    periods=number_timesteps,
                                    freq='H')

    energysystem = solph.EnergySystem(timeindex=date_time_index)

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

    ##########################################################################
    # Create oemof object
    ##########################################################################

    logging.info('Create oemof objects')
    # create natural gas bus
    bgas = solph.Bus(label="natural_gas")

    # create electricity bus
    bel = solph.Bus(label="electricity")

    # create excess component for the electricity bus to allow overproduction
    solph.Sink(label='excess_bel', inputs={bel: solph.Flow()})

    # create source object representing the natural gas commodity (annual limit)
    solph.Source(label='rgas',
                 outputs={
                     bgas:
                     solph.Flow(nominal_value=194397000 * number_timesteps /
                                8760,
                                summed_max=1)
                 })

    # create fixed source object representing wind power plants
    solph.Source(label='wind',
                 outputs={
                     bel:
                     solph.Flow(actual_value=data['wind'],
                                nominal_value=1000000,
                                fixed=True,
                                fixed_costs=20)
                 })

    # create fixed source object representing pv power plants
    solph.Source(label='pv',
                 outputs={
                     bel:
                     solph.Flow(actual_value=data['pv'],
                                nominal_value=582000,
                                fixed=True,
                                fixed_costs=15)
                 })

    # create simple sink object representing the electrical demand
    solph.Sink(label='demand',
               inputs={
                   bel:
                   solph.Flow(actual_value=data['demand_el'],
                              fixed=True,
                              nominal_value=1)
               })

    # create simple transformer object representing a gas power plant
    solph.LinearTransformer(
        label="pp_gas",
        inputs={bgas: solph.Flow()},
        outputs={bel: solph.Flow(nominal_value=10e10, variable_costs=50)},
        conversion_factors={bel: 0.58})

    # If the period is one year the equivalent periodical costs (epc) of an
    # investment are equal to the annuity. Use oemof's economic tools.
    epc = economics.annuity(capex=1000, n=20, wacc=0.05)

    # create storage object representing a battery
    solph.Storage(
        label='storage',
        inputs={bel: solph.Flow(variable_costs=10e10)},
        outputs={bel: solph.Flow(variable_costs=10e10)},
        capacity_loss=0.00,
        initial_capacity=0,
        nominal_input_capacity_ratio=1 / 6,
        nominal_output_capacity_ratio=1 / 6,
        inflow_conversion_factor=1,
        outflow_conversion_factor=0.8,
        fixed_costs=35,
        investment=solph.Investment(ep_costs=epc),
    )

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

    logging.info('Optimise the energy system')

    # initialise the operational model
    om = solph.OperationalModel(energysystem)

    # if debug is true an lp-file will be written
    if debug:
        filename = os.path.join(helpers.extend_basic_path('lp_files'),
                                'storage_invest.lp')
        logging.info('Store lp-file in {0}.'.format(filename))
        om.write(filename, io_options={'symbolic_solver_labels': True})

    # if tee_switch is true solver messages will be displayed
    logging.info('Solve the optimization problem')
    om.solve(solver=solver, solve_kwargs={'tee': tee_switch})

    return energysystem
예제 #5
0
def optimise_storage_size(energysystem,
                          filename="variable_chp.csv",
                          solver='cbc',
                          debug=True,
                          tee_switch=True):

    # 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='rgas', outputs={bgas: solph.Flow(variable_costs=50)})

    # create two electricity buses and two heat buses
    bel = solph.Bus(label="electricity")
    bel2 = solph.Bus(label="electricity_2")
    bth = solph.Bus(label="heat")
    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_therm', inputs={bth: solph.Flow()})
    solph.Sink(label='excess_bel_2', inputs={bel2: solph.Flow()})
    solph.Sink(label='excess_elec', inputs={bel: solph.Flow()})

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

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

    # This is just a dummy transformer with a nominal input of zero
    solph.LinearTransformer(label='fixed_chp_gas',
                            inputs={bgas: solph.Flow(nominal_value=0)},
                            outputs={
                                bel: solph.Flow(),
                                bth: solph.Flow()
                            },
                            conversion_factors={
                                bel: 0.3,
                                bth: 0.5
                            })

    # create a fixed transformer to distribute to the heat_2 and elec_2 buses
    solph.LinearTransformer(label='fixed_chp_gas_2',
                            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.VariableFractionTransformer(
        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_single_flow={bel: 0.5})

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

    logging.info('Optimise the energy system')

    om = solph.OperationalModel(energysystem)

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

    logging.info('Solve the optimization problem')
    om.solve(solver=solver, solve_kwargs={'tee': tee_switch})

    return energysystem