Beispiel #1
0
 def _check_invest_attributes(self, dpr_msg):
     if self.nominal_input_capacity_ratio is not None:
         warnings.warn(dpr_msg, DeprecationWarning)
         self.invest_relation_input_capacity = (
             self.nominal_input_capacity_ratio)
     if self.nominal_output_capacity_ratio is not None:
         warnings.warn(dpr_msg, DeprecationWarning)
         self.invest_relation_output_capacity = (
             self.nominal_output_capacity_ratio)
     if self.investment and self.nominal_capacity is not None:
         e1 = ("If an investment object is defined the invest variable "
               "replaces the nominal_capacity.\n Therefore the "
               "nominal_capacity should be 'None'.\n")
         raise AttributeError(e1)
     if (self.invest_relation_input_output is not None
             and self.invest_relation_output_capacity is not None
             and self.invest_relation_input_capacity is not None):
         e2 = ("Overdetermined. Three investment object will be coupled"
               "with three constraints. Set one invest relation to 'None'.")
         raise AttributeError(e2)
     for flow in self.inputs.values():
         if (self.invest_relation_input_capacity is not None
                 and not isinstance(flow.investment, Investment)):
             flow.investment = Investment()
     for flow in self.outputs.values():
         if (self.invest_relation_output_capacity is not None
                 and not isinstance(flow.investment, Investment)):
             flow.investment = Investment()
Beispiel #2
0
    def _investment(self):
        if self.expandable is True:
            if self.capacity_cost is None:
                msg = ("If you set `expandable`to True you need to set "
                       "attribute `capacity_cost` of component {}!")
                raise ValueError(msg.format(self.label))
            else:
                if isinstance(self, GenericStorage):
                    if self.storage_capacity_cost is not None:
                        self.investment = Investment(
                            ep_costs=self.storage_capacity_cost,
                            maximum=getattr(
                                self,
                                "storage_capacity_potential",
                                float("+inf"),
                            ),
                            minimum=getattr(self, "minimum_storage_capacity",
                                            0),
                            existing=getattr(self, "storage_capacity", 0),
                        )
                    else:
                        self.investment = Investment()
                else:
                    self.investment = Investment(
                        ep_costs=self.capacity_cost,
                        maximum=getattr(self, "capacity_potential",
                                        float("+inf")),
                        existing=getattr(self, "capacity", 0),
                    )
        else:
            self.investment = None

        return self.investment
Beispiel #3
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.nominal_capacity = kwargs.get('nominal_capacity')
        self.nominal_input_capacity_ratio = kwargs.get(
            'nominal_input_capacity_ratio', None)
        self.nominal_output_capacity_ratio = kwargs.get(
            'nominal_output_capacity_ratio', None)
        self.initial_capacity = kwargs.get('initial_capacity')
        self.capacity_loss = solph_sequence(kwargs.get('capacity_loss', 0))
        self.inflow_conversion_factor = solph_sequence(
            kwargs.get('inflow_conversion_factor', 1))
        self.outflow_conversion_factor = solph_sequence(
            kwargs.get('outflow_conversion_factor', 1))
        self.capacity_max = solph_sequence(kwargs.get('capacity_max', 1))
        self.capacity_min = solph_sequence(kwargs.get('capacity_min', 0))
        self.investment = kwargs.get('investment')

        # General error messages
        e_no_nv = ("If an investment object is defined the invest variable "
                   "replaces the {0}.\n Therefore the {0} should be 'None'.\n")
        e_duplicate = (
            "Duplicate definition.\nThe 'nominal_{0}_capacity_ratio'"
            "will set the nominal_value for the flow.\nTherefore "
            "either the 'nominal_{0}_capacity_ratio' or the "
            "'nominal_value' has to be 'None'.")
        # Check investment
        if self.investment and self.nominal_capacity is not None:
            raise AttributeError(e_no_nv.format('nominal_capacity'))

        # Check input flows
        for flow in self.inputs.values():
            if self.investment and flow.nominal_value is not None:
                raise AttributeError(e_no_nv.format('nominal_value'))
            if (flow.nominal_value is not None
                    and self.nominal_input_capacity_ratio is not None):
                raise AttributeError(e_duplicate)
            if (not self.investment
                    and self.nominal_input_capacity_ratio is not None):
                flow.nominal_value = (self.nominal_input_capacity_ratio *
                                      self.nominal_capacity)
            if self.investment:
                if not isinstance(flow.investment, Investment):
                    flow.investment = Investment()

        # Check output flows
        for flow in self.outputs.values():
            if self.investment and flow.nominal_value is not None:
                raise AttributeError(e_no_nv.format('nominal_value'))
            if (flow.nominal_value is not None
                    and self.nominal_output_capacity_ratio is not None):
                raise AttributeError(e_duplicate)
            if (not self.investment
                    and self.nominal_output_capacity_ratio is not None):
                flow.nominal_value = (self.nominal_output_capacity_ratio *
                                      self.nominal_capacity)
            if self.investment:
                if not isinstance(flow.investment, Investment):
                    flow.investment = Investment()
Beispiel #4
0
def get_sim_params(cost):
    """
    The function adds parameters such as nominal capacity and investment to the components cost dict
    :param cost: cost dict
    :return: sim_params dict parameter inputs for the energy system model
    """

    sim_params = {'pv': {'nominal_capacity': 264.07523381,
                         'investment': Investment( ep_costs=cost['pv']['epc'] )},
                  'storage': {'nominal_capacity': 337.807019472,
                              'investment': Investment( ep_costs=cost['storage']['epc'] )}}
    return sim_params
Beispiel #5
0
def get_sim_params(cost):
    sim_params = {
        'pv': {
            'nominal_capacity': 265.017017,
            'investment': Investment(ep_costs=cost['pv']['epc'])
        },
        'storage': {
            'nominal_capacity': 268.1211092,
            'investment': Investment(ep_costs=cost['storage']['epc'])
        }
    }
    return sim_params
Beispiel #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()
Beispiel #7
0
    def test_investment_flow_grouping(self):
        """ Flows of investment sink should be grouped.

        The constraint tests uncovered a spurious error where the flows of an
        investment `Sink` where not put into the `InvestmentFlow` group,
        although the corresponding grouping was present in the energy system.
        The error occured in the case where the investment `Sink` was not
        instantiated directly after the `Bus` it is connected to.

        This test recreates this error scenario and makes sure that the
        `InvestmentFlow` group is not empty.
        """

        b = solph.Bus(label='Bus')

        solph.Source(label='Source', outputs={b: solph.Flow(
            actual_value=[12, 16, 14], nominal_value=1000000,
            fixed=True)})

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

        ok_(self.es.groups.get(IF),
            ("Expected InvestmentFlow group to be nonempty.\n" +
             "Got: {}").format(self.es.groups.get(IF)))
Beispiel #8
0
    def build_solph_components(self):
        """
        """
        self.nominal_storage_capacity = self.storage_capacity

        self.inflow_conversion_factor = sequence(self.efficiency)

        self.outflow_conversion_factor = sequence(self.efficiency)

        # make it investment but don't set costs (set below for flow (power))
        self.investment = self._investment()

        if self.investment:
            self.invest_relation_input_output = 1

            for attr in ["invest_relation_input_output"]:
                if getattr(self, attr) is None:
                    raise AttributeError(
                        ("You need to set attr "
                         "`{}` "
                         "for component {}").format(attr, self.label))

            # set capacity costs at one of the flows
            fi = Flow(investment=Investment(
                ep_costs=self.capacity_cost,
                maximum=self.capacity_potential,
                existing=self.capacity,
            ),
                      **self.input_parameters)
            # set investment, but no costs (as relation input / output = 1)
            fo = Flow(investment=Investment(),
                      variable_costs=self.marginal_cost,
                      **self.output_parameters)
            # required for correct grouping in oemof.solph.components
            self._invest_group = True
        else:
            fi = Flow(nominal_value=self._nominal_value(),
                      **self.input_parameters)
            fo = Flow(nominal_value=self._nominal_value(),
                      variable_costs=self.marginal_cost,
                      **self.output_parameters)

        self.inputs.update({self.bus: fi})

        self.outputs.update({self.bus: fo})

        self._set_flows()
Beispiel #9
0
 def _investment(self):
     if self.capacity is None:
         if self.capacity_cost is None:
             msg = (
                 "If you don't set `capacity`, you need to set attribute " +
                 "`capacity_cost` of component {}!")
             raise ValueError(msg.format(self.label))
         else:
             # TODO: calculate ep_costs from specific capex
             if isinstance(self, GenericStorage):
                 self.investment = Investment()
             else:
                 self.investment = Investment(ep_costs=self.capacity_cost,
                                              maximum=getattr(
                                                  self,
                                                  'capacity_potential',
                                                  float('+inf')))
     else:
         self.investment = None
     return self.investment
Beispiel #10
0
def test_generic_storage_with_convex_invest_offset():
    """Offset value is given and nonconvex is False."""
    with pytest.raises(AttributeError,
                       match=r"If `nonconvex` is `False`, the `offset`"):
        bel = Bus()
        components.GenericStorage(label='storage6',
                                  inputs={bel: Flow()},
                                  outputs={bel: Flow()},
                                  invest_relation_input_capacity=1 / 6,
                                  invest_relation_output_capacity=1 / 6,
                                  investment=Investment(offset=10))
Beispiel #11
0
def test_generic_storage_with_non_convex_invest_maximum():
    """No investment maximum at nonconvex investment."""
    with pytest.raises(AttributeError,
                       match=r"Please provide an maximum investment value"):
        bel = Bus()
        components.GenericStorage(label='storage6',
                                  inputs={bel: Flow()},
                                  outputs={bel: Flow()},
                                  invest_relation_input_capacity=1 / 6,
                                  invest_relation_output_capacity=1 / 6,
                                  investment=Investment(nonconvex=True))
Beispiel #12
0
def test_generic_storage_with_non_convex_investment():
    """Tests error if `offset` and `existing` attribute are given."""
    with pytest.raises(AttributeError,
                       match=r"Values for 'offset' and 'existing' are given"):
        bel = Bus()
        components.GenericStorage(label='storage4',
                                  inputs={bel: Flow()},
                                  outputs={bel: Flow()},
                                  invest_relation_input_capacity=1 / 6,
                                  invest_relation_output_capacity=1 / 6,
                                  investment=Investment(nonconvex=True,
                                                        existing=5,
                                                        maximum=25))
Beispiel #13
0
def test_generic_storage_2():
    """Nominal value defined with investment model."""
    bel = Bus()
    with pytest.raises(AttributeError, match="If an investment object"):
        components.GenericStorage(label='storage3',
                                  nominal_storage_capacity=45,
                                  inputs={bel: Flow(variable_costs=10e10)},
                                  outputs={bel: Flow(variable_costs=10e10)},
                                  loss_rate=0.00,
                                  initial_storage_level=0,
                                  invest_relation_input_capacity=1 / 6,
                                  invest_relation_output_capacity=1 / 6,
                                  inflow_conversion_factor=1,
                                  outflow_conversion_factor=0.8,
                                  investment=Investment(ep_costs=23))
Beispiel #14
0
def test_generic_storage_1():
    """Duplicate definition inflow."""
    bel = Bus()
    with pytest.raises(AttributeError, match="Overdetermined."):
        components.GenericStorage(label='storage1',
                                  inputs={bel: Flow(variable_costs=10e10)},
                                  outputs={bel: Flow(variable_costs=10e10)},
                                  loss_rate=0.00,
                                  initial_storage_level=0,
                                  invest_relation_input_output=1,
                                  invest_relation_output_capacity=1,
                                  invest_relation_input_capacity=1,
                                  investment=Investment(),
                                  inflow_conversion_factor=1,
                                  outflow_conversion_factor=0.8)
Beispiel #15
0
def test_generic_storage_with_invest_and_fixed_losses_absolute():
    """
    Storage with fixed losses in the investment mode but no minimum or existing
    value is set an AttributeError is raised because this may result in storage
    with zero capacity but fixed losses.
    """
    msg = (r"With fixed_losses_absolute > 0, either investment.existing or"
           " investment.minimum has to be non-zero.")
    with pytest.raises(AttributeError, match=msg):
        bel = Bus()
        components.GenericStorage(
            label='storage4',
            inputs={bel: Flow()},
            outputs={bel: Flow()},
            investment=Investment(ep_costs=23, minimum=0, existing=0),
            fixed_losses_absolute=[0, 0, 4],
        )
Beispiel #16
0
energysystem.add(
    Transformer(label='pp_gas',
                inputs={bgas: Flow()},
                outputs={bel: Flow(nominal_value=41, variable_costs=40)},
                conversion_factors={bel: 0.50}))

if invest:

    epc = economics.annuity(1000, 20, 0.05)
    energysystem.add(
        Transformer(label='pp_oil',
                    inputs={boil: Flow()},
                    outputs={
                        bel:
                        Flow(investment=Investment(ep_costs=epc, maximum=100))
                    },
                    conversion_factors={bel: 0.28}))

else:
    energysystem.add(
        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)
energysystem.add(
    Transformer(label='pp_chp',
                inputs={bgas: Flow()},
                outputs={
Beispiel #17
0
thbus = Bus(label='thermal')

logging.info('Necessary buses for the system created')

# Now creating the necessary components for the system

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)
Beispiel #18
0
es = EnergySystem(timeindex=datetimeindex)

b_el0 = custom.ElectricalBus(label="b_0", v_min=-1, v_max=1)

b_el1 = custom.ElectricalBus(label="b_1", v_min=-1, v_max=1)

b_el2 = custom.ElectricalBus(label="b_2", v_min=-1, v_max=1)

es.add(b_el0, b_el1, b_el2)

es.add(
    custom.ElectricalLine(
        input=b_el0,
        output=b_el1,
        reactance=0.0001,
        investment=Investment(ep_costs=10),
        min=-1,
        max=1,
    )
)

es.add(
    custom.ElectricalLine(
        input=b_el1,
        output=b_el2,
        reactance=0.0001,
        nominal_value=60,
        min=-1,
        max=1,
    )
)
Beispiel #19
0
    def build_solph_components(self):
        """
        """
        self.inflow_conversion_factor = sequence(self.efficiency)

        self.outflow_conversion_factor = sequence(self.efficiency)

        self.loss_rate = sequence(self.loss_rate)

        self.fixed_losses_relative = sequence(self.fixed_losses_relative)

        self.fixed_losses_absolute = sequence(self.fixed_losses_absolute)

        # make it investment but don't set costs (set below for flow (power))
        self.investment = self._investment()

        if self.investment:
            self.invest_relation_input_output = 1

            for attr in ["invest_relation_input_output"]:
                if getattr(self, attr) is None:
                    raise AttributeError(
                        ("You need to set attr "
                         "`{}` "
                         "for component {}").format(attr, self.label))

            # set capacity costs at one of the flows
            fi = Flow(investment=Investment(
                ep_costs=self.capacity_cost,
                maximum=self.capacity_potential,
                existing=self.capacity,
            ),
                      **self.input_parameters)
            # set investment, but no costs (as relation input / output = 1)
            fo = Flow(investment=Investment(),
                      variable_costs=self.marginal_cost,
                      **self.output_parameters)
            # required for correct grouping in oemof.solph.components
            self._invest_group = True
        else:
            self.volume = calculate_storage_dimensions(self.height,
                                                       self.diameter)[0]

            self.nominal_storage_capacity = calculate_capacities(
                self.volume, self.temp_h, self.temp_c, **{
                    key: value
                    for key, value in self.water_properties.items()
                    if value is not None
                })

            fi = Flow(nominal_value=self._nominal_value(),
                      **self.input_parameters)
            fo = Flow(nominal_value=self._nominal_value(),
                      variable_costs=self.marginal_cost,
                      **self.output_parameters)

        self.inputs.update({self.bus: fi})

        self.outputs.update({self.bus: fo})

        self._set_flows()
}
#################################################################
# 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,
                actual_value=timeseries['pv'],
                investment=Investment(ep_costs=costs['pp_wind']['epc']))
       })

Source(label='pp_diesel',
       outputs={
           bel:
           Flow(nominal_value=None,
Beispiel #21
0
datetimeindex = pd.date_range('1/1/2017', periods=2, freq='H')

es = EnergySystem(timeindex=datetimeindex)

b_0 = Bus(label='b_0')

b_1 = Bus(label='b_1')

es.add(b_0, b_1)

es.add(custom.Link(label="line_0",
                   inputs={
                       b_0: Flow(), b_1: Flow()},
                   outputs={
                       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,
                 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',
                            invest=Investment(ep_cost=412),
                            inputs={bus_el: Flow(nominal_value=200)},
                            outputs={bus_el: Flow(nominal_value=200)},
                            loss_rate=0.01,
                            initial_storage_level=0,
                            max_storage_level=0.9,
                            inflow_conversion_factor=0.9,
                            outflow_conversion_factor=0.9)

# an excess and a shortage variable can help to avoid infeasible problems
excess_el = Sink(label='excess_el', inputs={bus_el: Flow()})

shortage_el = Source(label='shortage_el',
                     outputs={bus_el: Flow(variable_costs=100000)})

# ## Add all to the energysystem
Beispiel #23
0
                     bus_el:
                     Flow(nominal_value=1,
                          actual_value=data['demand_el'],
                          fixed=True)
                 })

epc_coal = economics.annuity(capex=1500000, n=50, wacc=0.05)
epc_gas = economics.annuity(capex=900000, n=20, wacc=0.05)

# create power plants
pp_coal = Transformer(label='pp_coal',
                      inputs={bus_coal: Flow()},
                      outputs={
                          bus_el:
                          Flow(investment=Investment(ep_costs=epc_coal,
                                                     maximum=5e9,
                                                     existing=0),
                               variable_costs=25)
                      },
                      conversion_factors={bus_el: 0.39})

pp_gas = Transformer(label='pp_gas',
                     inputs={bus_gas: Flow()},
                     outputs={
                         bus_el:
                         Flow(investment=Investment(ep_costs=epc_gas,
                                                    maximum=5e9,
                                                    existing=0),
                              variable_costs=40)
                     },
                     conversion_factors={bus_el: 0.50})
Beispiel #24
0
def test_lopf(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=1, freq="H")
    es = EnergySystem(timeindex=date_time_index)

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

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

    b_el0 = custom.ElectricalBus(label="b_0", v_min=-1, v_max=1)

    b_el1 = custom.ElectricalBus(label="b_1", v_min=-1, v_max=1)

    b_el2 = custom.ElectricalBus(label="b_2", v_min=-1, v_max=1)

    es.add(b_el0, b_el1, b_el2)

    es.add(
        custom.ElectricalLine(
            input=b_el0,
            output=b_el1,
            reactance=0.0001,
            investment=Investment(ep_costs=10),
            min=-1,
            max=1,
        ))

    es.add(
        custom.ElectricalLine(
            input=b_el1,
            output=b_el2,
            reactance=0.0001,
            nominal_value=60,
            min=-1,
            max=1,
        ))

    es.add(
        custom.ElectricalLine(
            input=b_el2,
            output=b_el0,
            reactance=0.0001,
            nominal_value=60,
            min=-1,
            max=1,
        ))

    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)},
    ))

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

    logging.info("Creating optimisation model")
    om = Model(es)

    logging.info("Running lopf on 3-Node exmaple system")
    om.solve(solver=solver)

    results = processing.results(om)

    generators = views.node_output_by_type(results, Source)

    generators_test_results = {
        (es.groups["gen_0"], es.groups["b_0"], "flow"): 20,
        (es.groups["gen_1"], es.groups["b_1"], "flow"): 80,
    }

    for key in generators_test_results.keys():
        logging.debug("Test genertor production of {0}".format(key))
        eq_(
            int(round(generators[key])),
            int(round(generators_test_results[key])),
        )

    eq_(
        results[es.groups["b_2"], es.groups["b_0"]]["sequences"]["flow"][0],
        -40,
    )

    eq_(results[es.groups["b_1"], es.groups["b_2"]]["sequences"]["flow"][0],
        60)

    eq_(
        results[es.groups["b_0"], es.groups["b_1"]]["sequences"]["flow"][0],
        -20,
    )

    # objective function
    eq_(round(processing.meta_results(om)["objective"]), 3200)
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])))
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 = GenericStorage(
    label='thermal_storage',
    inputs={bus_heat: Flow(investment=Investment(ep_costs=50))},
    outputs={bus_heat: Flow(investment=Investment(), variable_costs=0.0001)},
    min_storage_level=input_data['min_storage_level'],
    max_storage_level=input_data['max_storage_level'],
    loss_rate=loss_rate,
    fixed_losses_relative=fixed_losses_relative,
    fixed_losses_absolute=fixed_losses_absolute,
    inflow_conversion_factor=1.,
    outflow_conversion_factor=1.,
    invest_relation_input_output=1,
    investment=Investment(ep_costs=400, minimum=1))

energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand,
                 thermal_storage)

# Create and solve the optimization model
Beispiel #27
0
    def __init__(self, *args, **kwargs):

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

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

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

        self.nominal_capacity = self.storage_capacity

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

        self.loss = sequence(kwargs.get('loss', 0))

        self.inflow_conversion_factor = sequence(kwargs.get('efficiency', 1))

        self.outflow_conversion_factor = sequence(kwargs.get('efficiency', 1))

        # make it investment but don't set costs (set below for flow (power))
        self.investment = self._investment()

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

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

        if self.investment:
            if kwargs.get('capacity_ratio') is None:
                raise AttributeError(
                    ("You need to set attr `capacity_ratio` for "
                     "component {}").format(self.label))
            else:
                self.invest_relation_input_capacity = kwargs.get(
                    'capacity_ratio')
                self.invest_relation_output_capacity = kwargs.get(
                    'capacity_ratio')
                self.invest_relation_input_output = 1

            # set capacity costs at one of the flows
            fi = Flow(investment=Investment(ep_costs=self.capacity_cost,
                                            maximum=getattr(
                                                self, 'capacity_potential',
                                                float('+inf'))),
                      **self.input_edge_parameters)
            # set investment, but no costs (as relation input / output = 1)
            fo = Flow(investment=Investment(), **self.output_edge_parameters)
            # required for correct grouping in oemof.solph.components
            self._invest_group = True
        else:
            investment = None

            fi = Flow(nominal_value=self.capacity,
                      **self.input_edge_parameters)
            fo = Flow(nominal_value=self.capacity,
                      **self.output_edge_parameters)

        self.inputs.update({self.bus: fi})

        self.outputs.update({self.bus: fo})

        # annoying oemof stuff, that requires _set_flows() to provide a
        # drepreciated warning
        self._set_flows('Ignore this warning...')
Beispiel #28
0
logging.info('ENERGY SYSTEM created and initialized')

# Creating the necessary buses

elbus = Bus(label='elbus')

logging.info('Necessary buses for the system created')

# Now creating the necessary components for the system

epc_pv = economics.annuity(capex=1000, n=20, wacc=0.05)
epc_storage = economics.annuity(capex=1000, 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))})

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

# excess_el = Sink(label='excess_el', inputs={elbus: Flow(variable_costs=0)})
# shortage_el = Source(label='shortage_el', outputs={elbus: Flow(variable_costs=1e30)})

el_storage = GenericStorage(label='el_storage',
                            inputs={elbus: Flow(variable_costs=0.0001)},
                            outputs={elbus: Flow()},
                            loss_rate=0.00,
                            initial_storage_level=0.6, balanced=True,
                            invest_relation_input_capacity=1 / 6,
                            invest_relation_output_capacity=1 / 6,
                            inflow_conversion_factor=0.9,
                            outflow_conversion_factor=0.9,
thermal_storage = GenericStorage(
    label='thermal_storage',
    inputs={
        bus_heat:
        Flow(nominal_value=maximum_heat_flow_charging, variable_costs=0.0001)
    },
    outputs={bus_heat: Flow(nominal_value=maximum_heat_flow_discharging)},
    min_storage_level=min_storage_level,
    max_storage_level=max_storage_level,
    loss_rate=loss_rate,
    fixed_losses_relative=fixed_losses_relative,
    fixed_losses_absolute=fixed_losses_absolute,
    inflow_conversion_factor=1.,
    outflow_conversion_factor=1.,
    investment=Investment(ep_costs=400, minimum=1))

energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand,
                 thermal_storage)

# create and solve the optimization model
optimization_model = Model(energysystem)
optimization_model.write('storage_model.lp',
                         io_options={'symbolic_solver_labels': True})
optimization_model.solve(solver=solver,
                         solve_kwargs={
                             'tee': False,
                             'keepfiles': False
                         })
# get results
results = outputlib.processing.results(optimization_model)
Beispiel #30
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