예제 #1
0
def initialize_basic_energysystem():
    # initialize and provide data
    datetimeindex = pd.date_range('1/1/2016', periods=24, freq='H')
    filename = 'input_data.csv'
    data = pd.read_csv(filename, sep=",")
    energysystem = EnergySystem(timeindex=datetimeindex)

    # buses
    bcoal = Bus(label='coal', balanced=False)
    bgas = Bus(label='gas', balanced=False)
    bel = Bus(label='electricity')
    energysystem.add(bcoal, bgas, bel)

    # sources
    energysystem.add(
        Source(label='wind',
               outputs={
                   bel:
                   Flow(actual_value=data['wind'],
                        nominal_value=66.3,
                        fixed=True)
               }))

    energysystem.add(
        Source(label='pv',
               outputs={
                   bel:
                   Flow(actual_value=data['pv'],
                        nominal_value=65.3,
                        fixed=True)
               }))

    # excess and shortage to avoid infeasibilies
    energysystem.add(Sink(label='excess_el', inputs={bel: Flow()}))
    energysystem.add(
        Source(label='shortage_el', outputs={bel: Flow(variable_costs=200)}))

    # demands (electricity/heat)
    energysystem.add(
        Sink(label='demand_el',
             inputs={
                 bel:
                 Flow(nominal_value=85,
                      actual_value=data['demand_el'],
                      fixed=True)
             }))

    return bcoal, bgas, bel, energysystem
예제 #2
0
def add_conventional_mobility(table_collection, nodes):
    """

    Parameters
    ----------
    table_collection
    nodes

    Returns
    -------

    """
    mileage = table_collection["mobility_mileage"]["DE"]
    spec_demand = table_collection["mobility_spec_demand"]["DE"]
    energy_content = table_collection["mobility_energy_content"]["DE"]
    energy_tp = mileage.mul(spec_demand).mul(energy_content.iloc[0]) / 10**6
    energy = energy_tp.sum()
    idx = table_collection["demand_series"].index
    oil_key = Label("bus", "commodity", "oil", "DE")
    for fuel in ["diesel", "petrol"]:
        fix_value = pd.Series(energy / len(idx), index=idx, dtype=float)
        fuel_label = Label("Usage", "mobility", fuel, "DE")
        nodes[fuel_label] = Sink(
            label=fuel_label,
            inputs={nodes[oil_key]: Flow(actual_value=fix_value)},
        )

    return nodes
예제 #3
0
    def test_fixed_source_invest_sink(self):
        """ Wrong constraints for fixed source + invest sink w. `summed_max`.
        """

        bel = Bus(label='electricityBus')

        Source(label='wind',
               outputs={
                   bel:
                   Flow(actual_value=[12, 16, 14],
                        nominal_value=1000000,
                        fixed=True,
                        fixed_costs=20)
               })

        Sink(label='excess',
             inputs={
                 bel:
                 Flow(summed_max=2.3,
                      variable_costs=25,
                      max=0.8,
                      investment=Investment(ep_costs=500, maximum=10e5))
             })

        self.compare_lp_files('fixed_source_invest_sink.lp')
예제 #4
0
def add_decentralised_heating_systems(table_collection, nodes, extra_regions):
    logging.debug("Add decentralised_heating_systems to nodes dictionary.")
    cs = table_collection["commodity_source"]["DE"]
    dts = table_collection["demand_series"]
    dh = table_collection["decentralised_heat"]
    demand_regions = list({"DE_demand"}.union(set(extra_regions)))

    for d_region in demand_regions:
        region_name = d_region.replace("_demand", "")

        if region_name not in dh:
            data_name = "DE_demand"
        else:
            data_name = d_region

        fuels = [f for f in dh[data_name].columns if f in dts[d_region]]
        for fuel in fuels:
            src = dh.loc["source", (data_name, fuel)]
            bus_label = Label("bus", "commodity", src.replace(" ", "_"),
                              region_name)

            # Check if source bus exists
            if bus_label not in nodes:
                create_fuel_bus_with_source(nodes, src, region_name, cs)

            # Create heating bus as Bus
            heat_bus_label = Label("bus", "heat", fuel.replace(" ", "_"),
                                   region_name)
            nodes[heat_bus_label] = Bus(label=heat_bus_label)

            # Create heating system as Transformer
            trsf_label = Label("trsf", "heat", fuel.replace(" ", "_"),
                               region_name)

            efficiency = float(dh.loc["efficiency", (data_name, fuel)])

            nodes[trsf_label] = Transformer(
                label=trsf_label,
                inputs={nodes[bus_label]: Flow()},
                outputs={nodes[heat_bus_label]: Flow()},
                conversion_factors={nodes[heat_bus_label]: efficiency},
            )

            # Create demand as Sink
            d_heat_demand_label = Label("demand", "heat",
                                        fuel.replace(" ", "_"), region_name)
            nodes[d_heat_demand_label] = Sink(
                label=d_heat_demand_label,
                inputs={
                    nodes[heat_bus_label]:
                    Flow(
                        actual_value=dts[d_region, fuel],
                        nominal_value=1,
                        fixed=True,
                    )
                },
            )
예제 #5
0
def add_shortage_excess(nodes):
    bus_keys = [key for key in nodes.keys() if "bus" in key.cat]
    for key in bus_keys:
        excess_label = Label("excess", key.tag, key.subtag, key.region)
        nodes[excess_label] = Sink(label=excess_label,
                                   inputs={nodes[key]: Flow()})
        shortage_label = Label("shortage", key.tag, key.subtag, key.region)
        nodes[shortage_label] = Source(
            label=shortage_label,
            outputs={nodes[key]: Flow(variable_costs=900)},
        )
예제 #6
0
    def setUpClass(cls):
        cls.period = 24
        cls.es = EnergySystem(timeindex=pandas.date_range(
            '2016-01-01', periods=cls.period, freq='H'))

        # BUSSES
        b_el1 = Bus(label="b_el1")
        b_el2 = Bus(label="b_el2")
        b_diesel = Bus(label='b_diesel', balanced=False)
        cls.es.add(b_el1, b_el2, b_diesel)

        # TEST DIESEL:
        dg = Transformer(
            label='diesel',
            inputs={b_diesel: Flow(variable_costs=2)},
            outputs={
                b_el1: Flow(variable_costs=1,
                            investment=Investment(ep_costs=0.5))
            },
            conversion_factors={b_el1: 2},
        )

        batt = GenericStorage(
            label='storage',
            inputs={b_el1: Flow(variable_costs=3)},
            outputs={b_el2: Flow(variable_costs=2.5)},
            capacity_loss=0.00,
            initial_capacity=0,
            invest_relation_input_capacity=1 / 6,
            invest_relation_output_capacity=1 / 6,
            inflow_conversion_factor=1,
            outflow_conversion_factor=0.8,
            fixed_costs=35,
            investment=Investment(ep_costs=0.4),
        )

        cls.demand_values = [100] * 8760
        cls.demand_values[0] = 0.0
        demand = Sink(label="demand_el",
                      inputs={
                          b_el2:
                          Flow(nominal_value=1,
                               actual_value=cls.demand_values,
                               fixed=True)
                      })
        cls.es.add(dg, batt, demand)
        cls.om = Model(cls.es)
        cls.om.receive_duals()
        cls.om.solve()
        cls.mod = Model(cls.es)
        cls.mod.solve()
예제 #7
0
파일: facades.py 프로젝트: znes/renpass
    def __init__(self, *args, **kwargs):

        super().__init__(*args,
                         **kwargs,
                         _facade_requires_=['bus', 'inflow', 'efficiency'])

        self.storage_capacity = kwargs.get('storage_capacity')

        self.capacity = kwargs.get('capacity')

        self.efficiency = kwargs.get('efficiency')

        self.nominal_capacity = self.storage_capacity

        self.capacity_cost = kwargs.get('capacity_cost')

        self.storage_capacity_cost = kwargs.get('storage_capacity_cost')

        self.spillage = kwargs.get('spillage', True)

        self.input_edge_parameters = kwargs.get('input_edge_parameters', {})

        self.output_edge_parameters = kwargs.get('output_edge_parameters', {})

        investment = self._investment()

        reservoir_bus = Bus(label="reservoir-bus-" + self.label)
        inflow = Source(label="inflow" + self.label,
                        outputs={
                            reservoir_bus:
                            Flow(nominal_value=1,
                                 actual_value=self.inflow,
                                 fixed=True)
                        })
        if self.spillage:
            f = Flow()
        else:
            f = Flow(actual_value=0, fixed=True)

        spillage = Sink(label="spillage" + self.label,
                        inputs={reservoir_bus: f})
        self.inputs.update({reservoir_bus: Flow(**self.input_edge_parameters)})

        self.outputs.update({
            self.bus:
            Flow(investment=investment, **self.output_edge_parameters)
        })

        self.subnodes = (reservoir_bus, inflow, spillage)
예제 #8
0
    def test_max_source_min_sink(self):
        """
        """
        bel = Bus(label='electricityBus')

        Source(label='wind',
               outputs={bel: Flow(nominal_value=54, max=(.85, .95, .61))})

        Sink(label='minDemand',
             inputs={
                 bel:
                 Flow(nominal_value=54, min=(.84, .94, .59), variable_costs=14)
             })

        self.compare_lp_files('max_source_min_sink.lp')
예제 #9
0
    def test_fixed_source_variable_sink(self):
        """Constraint test with a fixed source and a variable sink.
        """

        bel = Bus(label='electricityBus')

        Source(label='wind',
               outputs={
                   bel:
                   Flow(actual_value=[.43, .72, .29],
                        nominal_value=10e5,
                        fixed=True,
                        fixed_costs=20)
               })

        Sink(label='excess', inputs={bel: Flow(variable_costs=40)})

        self.compare_lp_files('fixed_source_variable_sink.lp')
예제 #10
0
def add_district_heating_systems(table_collection, nodes):
    logging.debug("Add district heating systems to nodes dictionary.")
    dts = table_collection["demand_series"]
    for region in dts["district heating"].columns:
        if dts["district heating"][region].sum() > 0:
            bus_label = Label("bus", "heat", "district", region)
            if bus_label not in nodes:
                nodes[bus_label] = Bus(label=bus_label)
            heat_demand_label = Label("demand", "heat", "district", region)
            nodes[heat_demand_label] = Sink(
                label=heat_demand_label,
                inputs={
                    nodes[bus_label]:
                    Flow(
                        actual_value=dts["district heating", region],
                        nominal_value=1,
                        fixed=True,
                    )
                },
            )
예제 #11
0
def add_electricity_demand(table_collection, nodes):
    logging.debug("Add local electricity demand to nodes dictionary.")
    dts = table_collection["demand_series"]
    dts.columns = dts.columns.swaplevel()
    for region in dts["electrical_load"].columns:
        if dts["electrical_load"][region].sum() > 0:
            bus_label = Label("bus", "electricity", "all", region)
            if bus_label not in nodes:
                nodes[bus_label] = Bus(label=bus_label)
            elec_demand_label = Label("demand", "electricity", "all", region)
            nodes[elec_demand_label] = Sink(
                label=elec_demand_label,
                inputs={
                    nodes[bus_label]:
                    Flow(
                        actual_value=dts["electrical_load", region],
                        nominal_value=1,
                        fixed=True,
                    )
                },
            )
예제 #12
0
    def test_bus_to_sink_outputs_in_results_dataframe(self):
        bus = Bus(uid="bus")
        source = FS(
            label="source",
            outputs={bus: Flow(nominal_value=1, actual_value=0.5, fixed=True)})
        sink = Sink(label="sink", inputs={bus: Flow(nominal_value=1)})

        es = self.es
        om = OM(es)
        es.results = om.results()
        es.results[bus][sink] = [0.7]
        rdf = RDF(energy_system=es)
        try:
            eq_(
                rdf.loc[(slice(None), slice(None), slice(None),
                         "sink"), :].val[0], 0.7,
                "Output from bus to sink does not have the correct value.")
        except KeyError:
            self.failed = True
        if self.failed:
            ok_(
                False,
                "Output from bus to sink does not appear in results dataframe."
            )

        es.results[bus][bus] = [-1]
        rdf = RDF(energy_system=es)
        try:
            eq_(
                rdf.loc[(slice(None), slice(None), slice(None),
                         "sink"), :].val[0], 0.7,
                "Output from bus to sink does not have the correct value.")
        except KeyError:
            self.failed = True
        if self.failed:
            ok_(
                False, "Output from bus (with duals) to sink " +
                "does not appear in results dataframe.")
예제 #13
0
    def test_issue_74(self):
        Storage.optimization_options.update({'investment': True})
        bus = Bus(uid="bus")
        store = Storage(uid="store",
                        inputs=[bus],
                        outputs=[bus],
                        c_rate_out=0.1,
                        c_rate_in=0.1)
        sink = Sink(uid="sink", inputs=[bus], val=[1])

        es = self.es
        om = OM(es)
        om.objective.set_value(-1)
        es.results = om.results()

        try:
            es.dump()
        except AttributeError as ae:
            self.failed = ae
        if self.failed:
            ok_(
                False,
                "EnergySystem#dump should not raise `AttributeError`: \n" +
                " Error message: " + str(self.failed))
예제 #14
0
    def test_invest_source_fixed_sink(self):
        """Constraint test with a fixed sink and a dispatch invest source.
        """

        bel = Bus(label='electricityBus')

        Source(label='pv',
               outputs={
                   bel:
                   Flow(max=[45, 83, 65],
                        fixed_costs=20,
                        variable_costs=13,
                        investment=Investment(ep_costs=123))
               })

        Sink(label='excess',
             inputs={
                 bel:
                 Flow(actual_value=[.5, .8, .3],
                      nominal_value=10e4,
                      fixed=True)
             })

        self.compare_lp_files('invest_source_fixed_sink.lp')
예제 #15
0
# set timeindex and create data
periods = 20
datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H')
step = 5
demand = np.arange(0, step * periods, step)

# set up EnergySystem
energysystem = EnergySystem(timeindex=datetimeindex)
b_gas = Bus(label='gas', balanced=False)
b_el = Bus(label='electricity')
energysystem.add(b_gas, b_el)
energysystem.add(
    Source(label='shortage', outputs={b_el: Flow(variable_costs=1e6)}))
energysystem.add(
    Sink(label='demand',
         inputs={b_el: Flow(nominal_value=1, actual_value=demand,
                            fixed=True)}))

conv_func = lambda x: 0.01 * x**2
in_breakpoints = np.arange(0, 110, 25)

pwltf = solph.custom.PiecewiseLinearTransformer(
    label='pwltf',
    inputs={b_gas: solph.Flow(nominal_value=100, variable_costs=1)},
    outputs={b_el: solph.Flow()},
    in_breakpoints=in_breakpoints,
    conversion_function=conv_func,
    pw_repn='CC')  # 'CC', 'DCC', 'INC', 'MC'

# DCC TODO: Solve problem in outputlib with DCC
예제 #16
0
epc_pv = economics.annuity(capex=1000, n=20, wacc=0.05)
epc_storage = economics.annuity(capex=100, n=5, wacc=0.05)

pv = Source(label='pv',
            outputs={
                elbus:
                Flow(actual_value=data['pv'],
                     nominal_value=None,
                     fixed=True,
                     investment=Investment(ep_costs=epc_pv, maximum=30))
            })

demand_el = Sink(label='demand_el',
                 inputs={
                     elbus:
                     Flow(nominal_value=1,
                          actual_value=data['demand_el'],
                          fixed=True)
                 })
demand_th = Sink(label='demand_th',
                 inputs={
                     thbus:
                     Flow(nominal_value=1,
                          actual_value=data['demand_th'],
                          fixed=True)
                 })
excess_el = Sink(label='excess_el',
                 inputs={elbus: Flow(variable_costs=-0.005)})
shortage_el = Source(label='shortage_el',
                     outputs={elbus: Flow(variable_costs=1e10)})
예제 #17
0
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])))
demand_timeseries[-5:] = 1
heat_feedin_timeseries = np.zeros(periods)
heat_feedin_timeseries[:10] = 1

energysystem = EnergySystem(timeindex=datetimeindex)

bus_heat = Bus(label='bus_heat')

heat_source = Source(
    label='heat_source',
    outputs={bus_heat: Flow(nominal_value=1, fix=heat_feedin_timeseries)})

shortage = Source(label='shortage',
                  outputs={bus_heat: Flow(variable_costs=1e6)})

excess = Sink(label='excess', inputs={bus_heat: Flow()})

heat_demand = Sink(
    label='heat_demand',
    inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)})

thermal_storage = facades.StratifiedThermalStorage(
    label='thermal_storage',
    bus=bus_heat,
    diameter=input_data[
        'diameter'],  # TODO: setting to zero should give an error
    temp_h=input_data['temp_h'],
    temp_c=input_data['temp_c'],
    temp_env=input_data['temp_env'],
    u_value=u_value,
    expandable=True,
                  Flow(actual_value=data['wind'],
                       nominal_value=66.3,
                       fixed=True)
              })

pv = Source(label='pv',
            outputs={
                bus_el:
                Flow(actual_value=data['pv'], nominal_value=65.3, fixed=True)
            })

# Electricity demand
demand_el = Sink(label='demand_el',
                 inputs={
                     bus_el:
                     Flow(nominal_value=85,
                          actual_value=data['demand_el'],
                          fixed=True)
                 })

# power plants
pp_coal = Transformer(
    label='pp_coal',
    inputs={bus_coal: Flow()},
    outputs={bus_el: Flow(nominal_value=40, emission_factor=0.335)},
    conversion_factors={bus_el: 0.39})

storage_el = GenericStorage(label='storage_el',
                            nominal_storage_capacity=1000,
                            inputs={bus_el: Flow(nominal_value=200)},
                            outputs={bus_el: Flow(nominal_value=200)},
예제 #20
0
es.add(
    Source(
        label="gen_0",
        outputs={b_el0: Flow(nominal_value=100, variable_costs=50)},
    )
)

es.add(
    Source(
        label="gen_1",
        outputs={b_el1: Flow(nominal_value=100, variable_costs=25)},
    )
)

es.add(Sink(label="load", inputs={b_el2: Flow(nominal_value=100, fix=[1, 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,
예제 #21
0
# ######################### 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='bel')
bth = Bus(label='bth')

energysystem.add(bcoal, bgas, boil, blig, bel, bth)

# an excess and a shortage variable can help to avoid infeasible problems
energysystem.add(Sink(label='excess_el', inputs={bel: Flow()}))
# shortage_el = Source(label='shortage_el',
#                      outputs={bel: Flow(variable_costs=200)})

# sources
energysystem.add(
    Source(label='wind',
           outputs={
               bel: Flow(actual_value=data['wind'],
                         nominal_value=66.3,
                         fixed=True)
           }))

energysystem.add(
    Source(label='pv',
           outputs={
예제 #22
0
                       b_1: Flow(investment=Investment()),
                       b_0: Flow(investment=Investment())},
                   conversion_factors={
                       (b_0, b_1): 0.95, (b_1, b_0): 0.9}))


es.add(Source(label="gen_0", outputs={
                                b_0: Flow(nominal_value=100,
                                          variable_costs=50)}))

es.add(Source(label="gen_1", outputs={
                                b_1: Flow(nominal_value=100,
                                          variable_costs=50)}))

es.add(Sink(label="load_0", inputs={
                                b_0: Flow(nominal_value=150,
                                          actual_value=[0, 1],
                                          fixed=True)}))

es.add(Sink(label="load_1", inputs={
                                b_1: Flow(nominal_value=150,
                                          actual_value=[1, 0],
                                          fixed=True)}))

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()
# set timeindex and create data
periods = 20
datetimeindex = pd.date_range('1/1/2019', periods=periods, freq='H')
step = 5
demand = np.arange(0, step * periods, step)

# set up EnergySystem
energysystem = EnergySystem(timeindex=datetimeindex)
b_gas = Bus(label='gas', balanced=False)
b_el = Bus(label='electricity')
energysystem.add(b_gas, b_el)
energysystem.add(
    Source(label='shortage', outputs={b_el: Flow(variable_costs=1e6)}))
energysystem.add(
    Sink(label='demand',
         inputs={b_el: Flow(nominal_value=1, fix=demand, fixed=0)}))

conv_func = lambda x: 0.01 * x**2
in_breakpoints = np.arange(0, 110, 25)

pwltf = solph.custom.PiecewiseLinearTransformer(
    label='pwltf',
    inputs={b_gas: solph.Flow(nominal_value=100, variable_costs=1)},
    outputs={b_el: solph.Flow()},
    in_breakpoints=in_breakpoints,
    conversion_function=conv_func,
    pw_repn='CC')  # 'CC', 'DCC', 'INC', 'MC'

# DCC TODO: Solve problem in outputlib with DCC

energysystem.add(pwltf)
    'pp_bio': {
        'epc': economics.annuity(capex=1000, n=10, wacc=0.05),
        'var': 50
    },
    'storage': {
        'epc': economics.annuity(capex=1500, n=10, wacc=0.05),
        'var': 0
    }
}
#################################################################
# Create oemof object
#################################################################

bel = Bus(label='micro_grid')

Sink(label='excess', inputs={bel: Flow(variable_costs=10e3)})

Source(label='pp_wind',
       outputs={
           bel:
           Flow(nominal_value=None,
                fixed=True,
                actual_value=timeseries['wind'],
                investment=Investment(ep_costs=costs['pp_wind']['epc']))
       })

Source(label='pp_pv',
       outputs={
           bel:
           Flow(nominal_value=None,
                fixed=True,
예제 #25
0
def run_add_constraints_example(solver='cbc', nologg=False):
    if not nologg:
        logging.basicConfig(level=logging.INFO)
    # ##### creating an oemof solph optimization model, nothing special here ##
    # create an energy system object for the oemof solph nodes
    es = EnergySystem(timeindex=pd.date_range('1/1/2017', periods=4, freq='H'))
    # add some nodes

    boil = Bus(label="oil", balanced=False)
    blig = Bus(label="lignite", balanced=False)
    b_el = Bus(label="b_el")

    es.add(boil, blig, b_el)

    sink = Sink(label="Sink",
                inputs={
                    b_el:
                    Flow(nominal_value=40,
                         actual_value=[0.5, 0.4, 0.3, 1],
                         fixed=True)
                })
    pp_oil = Transformer(
        label='pp_oil',
        inputs={boil: Flow()},
        outputs={b_el: Flow(nominal_value=50, variable_costs=25)},
        conversion_factors={b_el: 0.39})
    pp_lig = Transformer(
        label='pp_lig',
        inputs={blig: Flow()},
        outputs={b_el: Flow(nominal_value=50, variable_costs=10)},
        conversion_factors={b_el: 0.41})

    es.add(sink, pp_oil, pp_lig)

    # create the model
    om = Model(energysystem=es)

    # add specific emission values to flow objects if source is a commodity bus
    for s, t in om.flows.keys():
        if s is boil:
            om.flows[s, t].emission_factor = 0.27  # t/MWh
        if s is blig:
            om.flows[s, t].emission_factor = 0.39  # t/MWh
    emission_limit = 60e3

    # add the outflow share
    om.flows[(boil, pp_oil)].outflow_share = [1, 0.5, 0, 0.3]

    # Now we are going to add a 'sub-model' and add a user specific constraint
    # first we add a pyomo Block() instance that we can use to add our
    # constraints. Then, we add this Block to our previous defined
    # Model instance and add the constraints.
    myblock = po.Block()

    # create a pyomo set with the flows (i.e. list of tuples),
    # there will of course be only one flow inside this set, the one we used to
    # add outflow_share
    myblock.MYFLOWS = po.Set(initialize=[
        k for (k, v) in om.flows.items() if hasattr(v, 'outflow_share')
    ])

    # pyomo does not need a po.Set, we can use a simple list as well
    myblock.COMMODITYFLOWS = [
        k for (k, v) in om.flows.items() if hasattr(v, 'emission_factor')
    ]

    # add the sub-model to the oemof Model instance
    om.add_component('MyBlock', myblock)

    def _inflow_share_rule(m, s, e, t):
        """pyomo rule definition: Here we can use all objects from the block or
        the om object, in this case we don't need anything from the block
        except the newly defined set MYFLOWS.
        """
        expr = (om.flow[s, e, t] >= om.flows[s, e].outflow_share[t] *
                sum(om.flow[i, o, t] for (i, o) in om.FLOWS if o == e))
        return expr

    myblock.inflow_share = po.Constraint(myblock.MYFLOWS,
                                         om.TIMESTEPS,
                                         rule=_inflow_share_rule)
    # add emission constraint
    myblock.emission_constr = po.Constraint(
        expr=(sum(om.flow[i, o, t] for (i, o) in myblock.COMMODITYFLOWS
                  for t in om.TIMESTEPS) <= emission_limit))

    # solve and write results to dictionary
    # you may print the model with om.pprint()
    om.solve(solver=solver)
    logging.info("Successfully finished.")
예제 #26
0
def diesel_only(mode,
                feedin,
                initial_batt_cap,
                cost,
                iterstatus=None,
                PV_source=True,
                storage_source=True,
                logger=False):

    if logger == 1:
        logger.define_logging()

    ##################################### Initialize the energy system##################################################

    # times = pd.DatetimeIndex(start='04/01/2017', periods=10, freq='H')
    times = feedin.index

    energysystem = EnergySystem(timeindex=times)

    # switch on automatic registration of entities of EnergySystem-object=energysystem

    Node.registry = energysystem

    # add components

    b_el = Bus(label='electricity')
    b_dc = Bus(label='electricity_dc')
    b_oil = Bus(label='diesel_source')

    demand_feedin = feedin['demand_el']

    Sink(label='demand',
         inputs={
             b_el: Flow(actual_value=demand_feedin,
                        nominal_value=1,
                        fixed=True)
         })

    Sink(label='excess', inputs={b_el: Flow()})

    Source(label='diesel', outputs={b_oil: Flow()})

    generator1 = custom.DieselGenerator(
        label='pp_oil_1',
        fuel_input={b_oil: Flow(variable_costs=cost['pp_oil_1']['var'])},
        electrical_output={
            b_el:
            Flow(nominal_value=186,
                 min=0.3,
                 max=1,
                 nonconvex=NonConvex(om_costs=cost['pp_oil_1']['o&m']),
                 fixed_costs=cost['pp_oil_1']['fix'])
        },
        fuel_curve={
            '1': 42,
            '0.75': 33,
            '0.5': 22,
            '0.25': 16
        })

    generator2 = custom.DieselGenerator(
        label='pp_oil_2',
        fuel_input={b_oil: Flow(variable_costs=cost['pp_oil_2']['var'])},
        electrical_output={
            b_el:
            Flow(nominal_value=186,
                 min=0.3,
                 max=1,
                 nonconvex=NonConvex(om_costs=cost['pp_oil_2']['o&m']),
                 fixed_costs=cost['pp_oil_2']['fix'],
                 variable_costs=0)
        },
        fuel_curve={
            '1': 42,
            '0.75': 33,
            '0.5': 22,
            '0.25': 16
        })

    generator3 = custom.DieselGenerator(
        label='pp_oil_3',
        fuel_input={b_oil: Flow(variable_costs=cost['pp_oil_3']['var'])},
        electrical_output={
            b_el:
            Flow(nominal_value=320,
                 min=0.3,
                 max=1,
                 nonconvex=NonConvex(om_costs=cost['pp_oil_3']['o&m']),
                 fixed_costs=cost['pp_oil_3']['fix'],
                 variable_costs=0)
        },
        fuel_curve={
            '1': 73,
            '0.75': 57,
            '0.5': 38,
            '0.25': 27
        })

    # List all generators in a list called gen_set
    gen_set = [generator1, generator2, generator3]

    sim_params = get_sim_params(cost)

    if mode == 'simulation':
        nominal_cap_pv = sim_params['pv']['nominal_capacity']
        inv_pv = None
        nominal_cap_batt = sim_params['storage']['nominal_capacity']
        inv_batt = None
    elif mode == 'investment':
        nominal_cap_pv = None
        inv_pv = sim_params['pv']['investment']
        nominal_cap_batt = None
        inv_batt = sim_params['storage']['investment']
    else:
        raise (
            UserWarning,
            'Energysystem cant be build. Check if mode is spelled correctely. '
            'It can be either [simulation] or [investment]')

    if PV_source == 1:
        PV = Source(label='PV',
                    outputs={
                        b_dc:
                        Flow(nominal_value=nominal_cap_pv,
                             fixed_costs=cost['pv']['fix'],
                             actual_value=feedin['PV'],
                             fixed=True,
                             investment=inv_pv)
                    })
    else:
        PV = None

    if storage_source == 1:
        storage = components.GenericStorage(
            label='storage',
            inputs={b_dc: Flow()},
            outputs={
                b_dc:
                Flow(variable_costs=cost['storage']['var'],
                     fixed_costs=cost['storage']['fix'])
            },
            nominal_capacity=nominal_cap_batt,
            capacity_loss=0.00,
            initial_capacity=initial_batt_cap,
            nominal_input_capacity_ratio=0.546,
            nominal_output_capacity_ratio=0.546,
            inflow_conversion_factor=0.92,
            outflow_conversion_factor=0.92,
            capacity_min=0.5,
            capacity_max=1,
            investment=inv_batt,
            initial_iteration=iterstatus)
    else:
        storage = None

    if storage_source == 1 or PV_source == 1:
        inverter1 = add_inverter(b_dc, b_el, 'Inv_pv')

    ################################# optimization ############################
    # create Optimization model based on energy_system
    logging.info("Create optimization problem")

    m = Model(energysystem)

    ################################# constraints ############################

    sr_requirement = 0.2
    sr_limit = demand_feedin * sr_requirement

    rm_requirement = 0.4
    rm_limit = demand_feedin * rm_requirement

    constraints.spinning_reserve_constraint(m,
                                            sr_limit,
                                            groups=gen_set,
                                            storage=storage)

    # constraints.n1_constraint(m, demand_feedin, groups=gen_set)

    constraints.gen_order_constraint(m, groups=gen_set)

    constraints.rotating_mass_constraint(m,
                                         rm_limit,
                                         groups=gen_set,
                                         storage=storage)

    return [m, gen_set]
예제 #27
0
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)

# electricity and heat
bel = Bus(label="bel")

energysystem.add(bcoal, bgas, boil, bel)

# an excess and a shortage variable can help to avoid infeasible problems
energysystem.add(Sink(label="excess_el", inputs={bel: Flow()}))
shortage_el = Source(label='shortage_el',
                     outputs={bel: Flow(variable_costs=20000)},
                     conversion_factors={bel: 0.33})

energysystem.add(shortage_el)

# sources
energysystem.add(
    Source(label="pv",
           outputs={bel: Flow(fix=data["pv"], nominal_value=256e3)}))

# demands (electricity/heat)
energysystem.add(
    Sink(
        label="demand_el",
energysystem = EnergySystem(timeindex=datetimeindex)

bus_heat = Bus(label='bus_heat')

heat_source = Source(label='heat_source',
                     outputs={
                         bus_heat:
                         Flow(nominal_value=1,
                              actual_value=heat_feedin_timeseries,
                              fixed=True)
                     })

shortage = Source(label='shortage',
                  outputs={bus_heat: Flow(variable_costs=1e6)})

excess = Sink(label='excess', inputs={bus_heat: Flow()})

heat_demand = Sink(label='heat_demand',
                   inputs={
                       bus_heat:
                       Flow(nominal_value=1,
                            actual_value=demand_timeseries,
                            fixed=True)
                   })

thermal_storage = GenericStorage(
    label='thermal_storage',
    inputs={bus_heat: Flow(nominal_value=maximum_heat_flow_charging)},
    outputs={
        bus_heat:
        Flow(nominal_value=maximum_heat_flow_discharging,
예제 #29
0
                        conversion_factors={thbus: COP})
"""

cop = 3

heat_pump = Transformer(
    label='heat_pump',
    inputs={elbus: Flow()},
    outputs={thbus: Flow()},
    conversion_factors={elbus: cop})

logging.info('Necessary components created')

# Creating the demands

eldemand = Sink(label='eldemand', inputs={elbus: Flow(nominal_value=85, actual_value=data['demand_el'], fixed=True)})

thdemand = Sink(label='thdemand', inputs={thbus: Flow(nominal_value=40, actual_value=data['demand_th'], fixed=True)})


# Creating the excess sink and the shortage source

excess_el = Sink(label='excess_el', inputs={elbus: Flow()})

shortage_el = Source(label='shortage_el', outputs={elbus: Flow(variable_costs=1e20)})

# Adding all the components to the energy system

es.add(excess_el, shortage_el, thdemand, eldemand, heat_pump, el_storage, chp_gas, pv, gas, gasbus, thbus, elbus)

# Create the model for optimization and run the optimization
예제 #30
0
# resources
bgas = Bus(label='bgas')

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

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

# dummy source at high costs that serves the residual load
source_th = Source(label='source_th', outputs={bth: Flow(variable_costs=1000)})

demand_th = Sink(label='demand_th',
                 inputs={
                     bth:
                     Flow(fixed=True,
                          actual_value=data['demand_th'],
                          nominal_value=200)
                 })

# power bus and components
bel = Bus(label='bel')

demand_el = Sink(label='demand_el',
                 inputs={
                     bel:
                     Flow(fixed=True,
                          actual_value=data['demand_el'],
                          nominal_value=100)
                 })