Пример #1
0
    def _create(self, group=None):
        """ Creates the linear constraint for the
        class:`.nodes.ExtractionTurbine`.

        Parameters
        ----------
        group : list
            List of :class:`ExtractionTurbine` objects
            e.g. group = [extr1, extr2, ...].
        """
        if group is None:
            return None

        m = self.parent_block()

        for n in group:
            n.power_heat_index = [
                n.conversion_factors[m.es.groups[n._power_output().label]][t] /
                n.conversion_factors[m.es.groups[n._heat_output().label]][t]
                for t in m.TIMESTEPS
            ]

        def _fuel_consumption_rule(block):
            """
            """
            for t in m.TIMESTEPS:
                for n in group:
                    lhs = m.flow[n._input(), n, t]
                    rhs = ((m.flow[n, n._power_output(), t] +
                            m.flow[n, n._heat_output(), t] *
                            n.power_loss_index[t]) / n.efficiency_condensing)
                    block.fuel_consumption.add((n, t), (lhs == rhs))

        self.fuel_consumption = Constraint(group, noruleinit=True)
        self.fuel_consuption_build = BuildAction(rule=_fuel_consumption_rule)

        def _power_to_heat_rule(block):
            """
            """
            for t in m.TIMESTEPS:
                for n in group:
                    lhs = m.flow[n, n._power_output(), t]
                    rhs = (m.flow[n, n._heat_output(), t] *
                           n.power_heat_index[t])
                    block.power_heat.add((n, t), (lhs >= rhs))

        self.power_heat = Constraint(group, noruleinit=True)
        self.power_heat_build = BuildAction(rule=_power_to_heat_rule)
Пример #2
0
    def _create(self, group=None):
        """Creates the balance constraints for the class:`Bus` block.

        Parameters
        ----------
        group : list
            List of oemof bus (b) object for which the bus balance is created
            e.g. group = [b1, b2, b3, .....]
        """
        if group is None:
            return None

        m = self.parent_block()

        ins = {}
        outs = {}
        for n in group:
            ins[n] = [i for i in n.inputs]
            outs[n] = [o for o in n.outputs]

        def _busbalance_rule(block):
            for t in m.TIMESTEPS:
                for g in group:
                    lhs = sum(m.flow[i, g, t] for i in ins[g])
                    rhs = sum(m.flow[g, o, t] for o in outs[g])
                    expr = (lhs == rhs)
                    # no inflows no outflows yield: 0 == 0 which is True
                    if expr is not True:
                        block.balance.add((g, t), expr)

        self.balance = Constraint(group, m.TIMESTEPS, noruleinit=True)
        self.balance_build = BuildAction(rule=_busbalance_rule)
Пример #3
0
    def _create(self, group=None):
        """ Creates constraints for backpressure turbine.

        Parameters
        ----------
        group : list
            List of :class:`BackpressureTurbine` objects
            e.g. group = [bp1, bp2, ...].
        """
        if group is None:
            return None

        for n in group:
            n.calculate_coefficients()

        m = self.parent_block()

        def _total_efficiency_rule(block):
            """Rule definition for electrical efficiency relation of
            backpressure turbine.
            """
            for t in m.TIMESTEPS:
                for n in group:
                    lhs = (m.flow[n._input(), n, t] *
                           sum(c[0] for c in n.conversion_factors.values()))
                    rhs = sum(m.flow[n, o, t] for o in n.outputs)
                    block.electrical_eff.add((n, t), (lhs == rhs))

        self.electrical_eff = Constraint(group, noruleinit=True)
        self.electrical_efficiency_build = BuildAction(
            rule=_total_efficiency_rule)

        def _electrical_efficiency_rule(block):
            """
            """
            for t in m.TIMESTEPS:
                for n in group:
                    lhs = m.flow[n._input(), n, t]
                    rhs = (m.BinaryFlow.status[n, n._power_output(), t] *
                           n.coeff[0] +
                           n.coeff[1] * m.flow[n, n._power_output(), t])
                    block.electrical_efficiency.add((n, t), lhs == rhs)

        self.electrical_efficiency = Constraint(group, noruleinit=True)
        self.electrical_efficiency_build = BuildAction(
            rule=_electrical_efficiency_rule)
Пример #4
0
    def _create(self, group=None):
        """ Creates constraints for backpressure turbine.

        Parameters
        ----------
        group : list
            List of :class:`BackpressureTurbine` objects
            e.g. group = [bp1, bp2, ...].
        """
        if group is None:
            return None

        m = self.parent_block()

        def _electrical_efficiency_rule(block):
            """Rule definition for electrical efficiency relation of
            backpressure turbine.
            """
            for t in m.TIMESTEPS:
                for n in group:
                    lhs = (m.flow[n._input(), n, t] *
                           n.conversion_factors[n._power_output()][t])
                    rhs = m.flow[n, n._power_output(), t]
                    block.electrical_eff.add((n, t), (lhs == rhs))

        self.electrical_eff = Constraint(group, noruleinit=True)
        self.electrical_efficiency_build = BuildAction(
            rule=_electrical_efficiency_rule)

        def _power_to_heat_rule(block):
            """Rule definition of power to heat relation of backpressure
            turbine.
            """
            for t in m.TIMESTEPS:
                for n in group:
                    lhs = (m.flow[n, n._power_output(), t] /
                           n.conversion_factors[n._power_output()][t])
                    rhs = (m.flow[n, n._heat_output(), t] /
                           n.conversion_factors[n._heat_output()][t])
                    block.power_heat.add((n, t), (lhs == rhs))

        self.power_heat = Constraint(group, noruleinit=True)
        self.power_heat_build = BuildAction(rule=_power_to_heat_rule)
Пример #5
0
    def _create(self, group=None):
        """ Creates the linear constraint for the class:`Transformer`
        block.
        Parameters
        ----------
        group : list
            List of oemof.solph.Transformers objects for which
            the linear relation of inputs and outputs is created
            e.g. group = [trsf1, trsf2, trsf3, ...]. Note that the relation
            is created for all existing relations of all inputs and all outputs
            of the transformer. The components inside the list need to hold
            an attribute `conversion_factors` of type dict containing the
            conversion factors for all inputs to outputs.
        """
        if group is None:
            return None

        m = self.parent_block()

        in_flows = {n: [i for i in n.inputs.keys()] for n in group}
        out_flows = {n: [o for o in n.outputs.keys()] for n in group}


        self.relation = Constraint(
            [(n, i, o, t)
             for t in m.TIMESTEPS
             for n in group
             for o in out_flows[n]
             for i in in_flows[n]], noruleinit=True)

        def _input_output_relation(block):
            for t in m.TIMESTEPS:
                for n in group:
                    for o in out_flows[n]:
                        for i in in_flows[n]:
                            try:
                                lhs = (m.flow[i, n, t] /
                                       n.conversion_factors[i][t])
                                rhs = (m.flow[n, o, t] /
                                       n.conversion_factors[o][t])
                            except ValueError:
                                raise ValueError(
                                    "Error in constraint creation",
                                    "source: {0}, target: {1}".format(
                                        n.label, o.label))
                            block.relation.add((n, i, o, t), (lhs == rhs))
        self.relation_build = BuildAction(rule=_input_output_relation)
Пример #6
0
    def _create(self, group=None):
        r""" Creates sets, variables and constraints for all standard flows.

        Parameters
        ----------
        group : list
            List containing tuples containing flow (f) objects and the
            associated source (s) and target (t)
            of flow e.g. groups=[(s1, t1, f1), (s2, t2, f2),..]
        """
        if group is None:
            return None

        m = self.parent_block()

        # ########################## SETS #################################
        # set for all flows with an global limit on the flow over time
        self.SUMMED_MAX_FLOWS = Set(
            initialize=[(g[0], g[1]) for g in group
                        if g[2].summed_max is not None
                        and g[2].nominal_value is not None])

        self.SUMMED_MIN_FLOWS = Set(
            initialize=[(g[0], g[1]) for g in group
                        if g[2].summed_min is not None
                        and g[2].nominal_value is not None])

        self.NEGATIVE_GRADIENT_FLOWS = Set(
            initialize=[(g[0], g[1]) for g in group
                        if g[2].negative_gradient['ub'][0] is not None])

        self.POSITIVE_GRADIENT_FLOWS = Set(
            initialize=[(g[0], g[1]) for g in group
                        if g[2].positive_gradient['ub'][0] is not None])

        self.INTEGER_FLOWS = Set(initialize=[(g[0], g[1]) for g in group
                                             if g[2].integer])
        # ######################### Variables  ################################

        self.positive_gradient = Var(self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS)

        self.negative_gradient = Var(self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS)

        self.integer_flow = Var(self.INTEGER_FLOWS,
                                m.TIMESTEPS,
                                within=NonNegativeIntegers)
        # set upper bound of gradient variable
        for i, o, f in group:
            if m.flows[i, o].positive_gradient['ub'][0] is not None:
                for t in m.TIMESTEPS:
                    self.positive_gradient[i, o, t].setub(
                        f.positive_gradient['ub'][t] * f.nominal_value)
            if m.flows[i, o].negative_gradient['ub'][0] is not None:
                for t in m.TIMESTEPS:
                    self.negative_gradient[i, o, t].setub(
                        f.negative_gradient['ub'][t] * f.nominal_value)

        # ######################### CONSTRAINTS ###############################

        def _flow_summed_max_rule(model):
            """Rule definition for build action of max. sum flow constraint.
            """
            for inp, out in self.SUMMED_MAX_FLOWS:
                lhs = sum(m.flow[inp, out, ts] * m.timeincrement[ts]
                          for ts in m.TIMESTEPS)
                rhs = (m.flows[inp, out].summed_max *
                       m.flows[inp, out].nominal_value)
                self.summed_max.add((inp, out), lhs <= rhs)

        self.summed_max = Constraint(self.SUMMED_MAX_FLOWS, noruleinit=True)
        self.summed_max_build = BuildAction(rule=_flow_summed_max_rule)

        def _flow_summed_min_rule(model):
            """Rule definition for build action of min. sum flow constraint.
            """
            for inp, out in self.SUMMED_MIN_FLOWS:
                lhs = sum(m.flow[inp, out, ts] * m.timeincrement[ts]
                          for ts in m.TIMESTEPS)
                rhs = (m.flows[inp, out].summed_min *
                       m.flows[inp, out].nominal_value)
                self.summed_min.add((inp, out), lhs >= rhs)

        self.summed_min = Constraint(self.SUMMED_MIN_FLOWS, noruleinit=True)
        self.summed_min_build = BuildAction(rule=_flow_summed_min_rule)

        def _positive_gradient_flow_rule(model):
            """Rule definition for positive gradient constraint.
            """
            for inp, out in self.POSITIVE_GRADIENT_FLOWS:
                for ts in m.TIMESTEPS:
                    if ts > 0:
                        lhs = m.flow[inp, out, ts] - m.flow[inp, out, ts - 1]
                        rhs = self.positive_gradient[inp, out, ts]
                        self.positive_gradient_constr.add((inp, out, ts),
                                                          lhs <= rhs)
                    else:
                        pass  # return(Constraint.Skip)

        self.positive_gradient_constr = Constraint(
            self.POSITIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True)
        self.positive_gradient_build = BuildAction(
            rule=_positive_gradient_flow_rule)

        def _negative_gradient_flow_rule(model):
            """Rule definition for negative gradient constraint.
            """
            for inp, out in self.NEGATIVE_GRADIENT_FLOWS:
                for ts in m.TIMESTEPS:
                    if ts > 0:
                        lhs = m.flow[inp, out, ts - 1] - m.flow[inp, out, ts]
                        rhs = self.negative_gradient[inp, out, ts]
                        self.negative_gradient_constr.add((inp, out, ts),
                                                          lhs <= rhs)
                    else:
                        pass  # return(Constraint.Skip)

        self.negative_gradient_constr = Constraint(
            self.NEGATIVE_GRADIENT_FLOWS, m.TIMESTEPS, noruleinit=True)
        self.negative_gradient_build = BuildAction(
            rule=_negative_gradient_flow_rule)

        def _integer_flow_rule(block, ii, oi, ti):
            """Force flow variable to NonNegativeInteger values.
            """
            return self.integer_flow[ii, oi, ti] == m.flow[ii, oi, ti]

        self.integer_flow_constr = Constraint(self.INTEGER_FLOWS,
                                              m.TIMESTEPS,
                                              rule=_integer_flow_rule)
Пример #7
0
    def _create(self, group=None):
        """ Creates the linear constraint for the class:`LinearTransformer`
        block.

        Parameters
        ----------
        group : list
            List of oemof.solph.LinearTransformers (trsf) objects for which
            the linear relation of inputs and outputs is created
            e.g. group = [trsf1, trsf2, trsf3, ...]. Note that the relation
            is created for all existing relations of the inputs and all outputs
            of the transformer. The components inside the list need to hold
            a attribute `conversion_factors` of type dict containing the
            conversion factors from inputs to outputs.
        """
        if group is None:
            return None

        m = self.parent_block()

        for n in group:
            n.inflow = list(n.inputs)[0]
            n.label_main_flow = str(
                [k for k, v in n.conversion_factor_single_flow.items()][0])
            n.main_output = [
                o for o in n.outputs if n.label_main_flow == o.label
            ][0]
            n.tapped_output = [
                o for o in n.outputs if n.label_main_flow != o.label
            ][0]
            n.conversion_factor_single_flow_sq = (
                n.conversion_factor_single_flow[m.es.groups[
                    n.main_output.label]])
            n.flow_relation_index = [
                n.conversion_factors[m.es.groups[n.main_output.label]][t] /
                n.conversion_factors[m.es.groups[n.tapped_output.label]][t]
                for t in m.TIMESTEPS
            ]
            n.main_flow_loss_index = [
                (n.conversion_factor_single_flow_sq[t] -
                 n.conversion_factors[m.es.groups[n.main_output.label]][t]) /
                n.conversion_factors[m.es.groups[n.tapped_output.label]][t]
                for t in m.TIMESTEPS
            ]

        def _input_output_relation_rule(block):
            """Connection between input, main output and tapped output.
            """
            for t in m.TIMESTEPS:
                for g in group:
                    lhs = m.flow[g.inflow, g, t]
                    rhs = ((m.flow[g, g.main_output, t] +
                            m.flow[g, g.tapped_output, t] *
                            g.main_flow_loss_index[t]) /
                           g.conversion_factor_single_flow_sq[t])
                    block.input_output_relation.add((n, t), (lhs == rhs))

        self.input_output_relation = Constraint(group, noruleinit=True)
        self.input_output_relation_build = BuildAction(
            rule=_input_output_relation_rule)

        def _out_flow_relation_rule(block):
            """Relation between main and tapped output in full chp mode.
            """
            for t in m.TIMESTEPS:
                for g in group:
                    lhs = m.flow[g, g.main_output, t]
                    rhs = (m.flow[g, g.tapped_output, t] *
                           g.flow_relation_index[t])
                    block.out_flow_relation.add((g, t), (lhs >= rhs))

        self.out_flow_relation = Constraint(group, noruleinit=True)
        self.out_flow_relation_build = BuildAction(
            rule=_out_flow_relation_rule)