예제 #1
0
        def supply_rule(self, sy, nd, ca):
            ''' Balance supply/demand '''

            list_neg = self.sll | self.curt
            prod = (# power output; negative if energy selling plant
                    sum(self.pwr[sy, pp, ca]
                        * (-1 if pp in list_neg else 1)
                        for (pp, nd, ca)
                        in set_to_list(self.ppall_ndca, [None, nd, ca]))
                    # incoming inter-node transmission
                    + sum(get_transmission(sy, nd, nd_2, ca, False)
                          / self.nd_weight[nd_2]
                          for (nd, nd_2, ca)
                          in set_to_list(self.ndcnn, [None, nd, ca]))
                   )
            exports = sum(get_transmission(sy, nd, nd_2, ca, True)
                          / self.nd_weight[nd]
                          for (nd, nd_2, ca)
                          in set_to_list(self.ndcnn, [nd, None, ca]))
            dmnd = (self.dmnd[sy, nd, ca]
                    + sum(self.pwr_st_ch[sy, st, ca] for (st, nd, ca)
                          in set_to_list(self.st_ndca, [None, nd, ca])))


            # demand of plants using ca as an input
            ca_cons = (po.ZeroConstant if not self.pp_ndcaca else
                       sum(self.pwr[sy, pp, ca_out] / self.pp_eff[pp, ca_out]
                           for (pp, nd, ca_out, ca)
                           in set_to_list(self.pp_ndcaca,
                                          [None, nd, None, ca])))
            gl = self.grid_losses[nd, ca]

            return prod == (dmnd + ca_cons) * (1 + gl) + exports
예제 #2
0
    def get_vc_fl(self):
        r'''
        Get total fuel cost calculated directly from power production:

        .. math::
           \sum_\mathrm{(t,p,c)\in sy\_lin\_ca}
           p_\mathrm{t,p,c} w_\mathrm{\tau(p),t}
           \cdot \mathrm{vc_{f(p),n(p)}}
           \cdot (f_\mathrm{0,p,c} + 0.5 p_\mathrm{t,p,c} f_\mathrm{1,p,c})

        '''


        def spec_vc_fl(lin, sy):

            fl_id, nd_id = (self.mps.dict_plant_2_fuel_id[lin],
                            self.mps.dict_plant_2_node_id[lin])

            if self.dict_par['vc_fl'].has_monthly_factors:
                mt_id = self.dict_soy_month[(self.dict_pp_tm_id[lin], sy)]
                return self.vc_fl[mt_id, fl_id, nd_id]
            else:
                return self.vc_fl[fl_id, nd_id]

        return \
        sum(self.pwr[sy, lin, ca]
            * self.weight[self.dict_pp_tm_id[lin], sy]
            * spec_vc_fl(lin, sy)
            * (self.factor_lin_0[lin, ca]
               + 0.5 * self.pwr[sy, lin, ca]
                     * self.factor_lin_1[lin, ca])
            * self.nd_weight[self.mps.dict_plant_2_node_id[lin]]
            for (sy, lin, ca) in set_to_list(self.sy_lin_ca, nnn))
예제 #3
0
        def yearly_energy_rule(self, pp, ca):
            ''' Sets variable erg_yr for fuel-consuming plants. '''

            tm = self.dict_pp_tm_id[pp]

            return (self.erg_yr[pp, ca]
                    == sum(self.pwr[sy, pp, ca] * self.weight[tm, sy]
                           for tm, sy in set_to_list(self.tmsy, [tm, None])))
예제 #4
0
        def yearly_ramp_rule(self, pp, ca):
            ''' Yearly ramping in MW/yrm, absolute aggregated up and down. '''

            tm = self.dict_pp_tm_id[pp]
            tmsy_list = set_to_list(self.tmsy, [tm, None])

            return (self.pwr_ramp_yr[pp, ca]
                    == sum(self.pwr_ramp_abs[sy, pp, ca]
                           for tm, sy in tmsy_list))
예제 #5
0
        def calc_vc_fl_pp_rule(self, pp, nd, ca, fl):
            '''Yearly fuel cost calculation (constant supply curve plants).'''

            tm = self.dict_nd_tm_id[nd]
            list_sy = self.dict_tm_sy[tm]

            sign = -1 if pp in self.sll else 1

            # Case 1: fuel has price profile
            if (fl, nd, ca) in {**self.dict_pricebuy_pf,
                                **self.dict_pricesll_pf}:

                pprf = (self.pricesllprof if sign is -1 else self.pricebuyprof)

                pf = (self.dict_pricesll_pf[(fl, nd, ca)] if sign is -1 else
                      self.dict_pricebuy_pf[(fl, nd, ca)])

                sums = (sign * sum(self.weight[tm, sy]
                                   * pprf[sy, pf]
                                   / self.pp_eff[pp, ca]
                                   * self.pwr[sy, pp, ca]
                                   for (sy, _, _)
                                   in set_to_list(self.sy_pp_ca,
                                                  [None, pp, ca])))

            # Case 2: monthly adjustment factors have been applied to vc_fl
            elif self.dict_par['vc_fl'].has_monthly_factors:
                sums = (sign * sum(self.weight[tm, sy]
                                   * self.vc_fl[self.dict_soy_month[(tm, sy)], fl, nd]
                                   / self.pp_eff[pp, ca]
                                   * self.pwr[sy, pp, ca] for (sy, _pp, _ca)
                                   in set_to_list(self.sy_pp_ca,
                                                  [None, pp, ca])))

            # Case 3: ordinary single fuel price
            else:
                sums = (sign * self.erg_fl_yr[pp, nd, ca, fl]
                             / self.pp_eff[pp, ca]
                             * self.vc_fl[fl, nd])

            return self.vc_fl_pp_yr[pp, ca, fl] == sums
예제 #6
0
        def objective_rule_quad(self):

            return (# FUEL COST CONSTANT
                    sum(self.vc_fl_pp_yr[pp, ca, fl]
                        * self.nd_weight[self.mps.dict_plant_2_node_id[pp]]
                        for (pp, ca, fl)
                        in set_to_list(self.pp_cafl - self.lin_cafl, nnn))
                    # FUEL COST LINEAR
                  + self.get_vc_fl()
                    # EMISSION COST LINEAR
                  + self.get_vc_co()
                  + sum(self.vc_co2_pp_yr[pp, ca]
                        * self.nd_weight[self.mps.dict_plant_2_node_id[pp]]
                        for (pp, ca) in set_to_list(self.pp_ca - self.lin_ca, nn))
                  + sum(self.vc_om_pp_yr[pp, ca]
                        * self.nd_weight[self.mps.dict_plant_2_node_id[pp]]
                        for (pp, ca) in set_to_list(self.ppall_ca, nn))
                  + sum(self.vc_ramp_yr[pp, ca]
                        * self.nd_weight[self.mps.dict_plant_2_node_id[pp]]
                        for (pp, ca) in set_to_list(self.rp_ca, nn))
                  + sum(self.fc_om_pp_yr[pp, ca]
                        * self.nd_weight[self.mps.dict_plant_2_node_id[pp]]
                        for (pp, ca) in set_to_list(self.ppall_ca, nn))
                  + sum(self.fc_cp_pp_yr[pp, ca]
                        * self.nd_weight[self.mps.dict_plant_2_node_id[pp]]
                        for (pp, ca) in set_to_list(self.add_ca, nn)))
예제 #7
0
        def calc_vc_co2_pp_rule(self, pp, nd, ca, fl):
            '''Yearly emission ncost calculation (constant supply curves).'''

            tm = self.dict_nd_tm_id[nd]

            # Case 1: monthly adjustment factors have been applied to vc_fl
            if self.dict_par['price_co2'].has_monthly_factors:
                sums = sum(self.pwr[sy, pp, ca] # POWER!
                           / self.pp_eff[pp, ca] * self.weight[tm, sy]
                           * self.price_co2[mt, nd] * self.co2_int[fl]
                           for (_tm, sy, mt) in set_to_list(self.tmsy_mt,
                                                       [tm, None, None]))
            # Case 2: ordinary single CO2 price
            else:
                sums = (self.erg_fl_yr[pp, nd, ca, fl] # ENERGY!
                            / self.pp_eff[pp, ca]
                            * self.price_co2[nd] * self.co2_int[fl])

            return self.vc_co2_pp_yr[pp, ca] == sums
예제 #8
0
        def pp_max_fuel_rule(self, nd, ca, fl):
            '''Constrain energy produced from certain fuels.'''

            is_constr = fl in self.fl_erg
            erg_inp_is_zero = self.erg_inp[nd, ca, fl] == 0

            ret = po.Constraint.Skip

            if is_constr and not erg_inp_is_zero:

                plant_list = set_to_list(self.ppall_ndcafl, [None, nd, ca, fl])

                if plant_list:

                    left = sum(self.erg_fl_yr[pp, nd_1, ca_1, fl_1]
                               for (pp, nd_1, ca_1, fl_1) in plant_list)
                    right = self.erg_inp[nd, ca, fl]
                    ret = left <= right

            return ret
예제 #9
0
    def get_vc_co(self):
        r'''
        Get total |CO2| emission cost calculated directly from power
        production:

        .. math::
           \sum_\mathrm{(t,p,c)\in sy\_lin\_ca}
           p_\mathrm{t,p,c} w_\mathrm{\tau(p),t}
           \cdot \pi_\mathrm{CO_2, m(t), n(p)} i_\mathrm{CO_2,f}
           \cdot (f_\mathrm{0,p,c} + 0.5 p_\mathrm{t,p,c} f_\mathrm{1,p,c})

        '''

        return \
        sum(self.pwr[sy, lin, ca] * self.weight[self.dict_pp_tm_id[lin], sy]
            * (self.price_co2[self.dict_soy_month[(self.dict_pp_tm_id[lin], sy)],
                              self.mps.dict_plant_2_node_id[lin]]
               if self.dict_par['price_co2'].has_monthly_factors
               else self.price_co2[self.mps.dict_plant_2_node_id[lin]])
            * self.co2_int[self.mps.dict_plant_2_fuel_id[lin]]
                * (self.factor_lin_0[lin, ca]
                   + 0.5 * self.pwr[sy, lin, ca] * self.factor_lin_1[lin, ca])
            * self.nd_weight[self.mps.dict_plant_2_node_id[lin]]
            for (sy, lin, ca) in set_to_list(self.sy_lin_ca, nnn))
예제 #10
0
    def add_parameters(self):
        '''
        Adds all parameters to the model.

        Generates :class:`ParameterAdder` instances for each of the parameters
        and calls their :meth:`ParameterAdder.init_update` method.

        '''

        if __name__ == '__main__':
            self = ml.m

        list_par = (
            Par('dmnd', self.sy_ndca, self._get_df_demand(), 'value'),
            Par('supprof', self.sy_pr_ca, self._get_df_supply(), 'value'),
            Par('chpprof', (self.sy_ndca), 'df_profchp_soy', 'value'),
            Par('inflowprof', (self.sy_hyrs_ca | self.sy_ror_ca),
                'df_profinflow_soy',
                'value',
                index_cols=['sy', 'pp_id', 'ca_id']),
            Par('pricebuyprof', (self.sy, self.pricebuy_pf),
                'df_profpricebuy_soy', 'value'),
            Par('pricesllprof', (self.sy, self.pricesll_pf),
                'df_profpricesll_soy', 'value'),
            Par('min_erg_mt_out_share', self.hyrs, 'df_hydro'),
            Par('max_erg_mt_in_share', self.hyrs, 'df_hydro', default=1),
            Par('min_erg_share', self.hyrs, 'df_hydro'),
            Par('weight', self.tmsy, 'df_tm_soy', default=1),
            Par('grid_losses', (self.nd, self.ca), 'df_node_encar'),
            Par('cap_trme_leg', (self.mt, self.ndcnn), 'df_node_connect'),
            Par('cap_trmi_leg', (self.mt, self.ndcnn), 'df_node_connect'),
            Par('vc_ramp', (self.ppall, self.ca), 'df_plant_encar', None,
                ['pp_id', 'ca_id'], set_to_list(self.rp_ca, [None, None])),
            Par('pp_eff', (self.pp - self.lin, self.ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.pp - self.lin,
                default=1),
            Par('cf_max', (self.pp, self.ca), 'df_plant_encar', None,
                ['pp_id'], self.pp),
            Par('erg_chp', (self.chp, self.ca), 'df_plant_encar', None,
                ['pp_id'], self.chp),
            Par('erg_inp', self.ndcafl, 'df_fuel_node_encar'),
            Par('vc_fl', (self.fl, self.nd), 'df_fuel_node_encar', default=0),
            Par('factor_lin_0', (self.lin, self.ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.lin,
                default=0),
            Par('factor_lin_1', (self.lin, self.ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.lin,
                default=0),
            Par('price_co2', self.nd, 'df_def_node'),
            Par('nd_weight', self.nd, 'df_def_node', default=1),
            Par('co2_int', self.fl, 'df_def_fuel', default=0),
            Par('cap_pwr_leg', (self.ppall_ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.ppall,
                index_cols=['pp_id', 'ca_id']),
            Par('vc_om', (self.ppall, self.ca), 'df_plant_encar', None,
                ['pp_id'], self.ppall),
            Par('fc_om', (self.add, self.ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.add,
                default=0),
            Par('fc_cp_ann', (self.add, self.ca), 'df_plant_encar', None,
                ['pp_id'], self.add),
            Par('pwr_pot', (self.add, self.ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.add,
                default=1e9),
            Par('cap_avlb', (self.pp, self.ca),
                'df_plant_encar',
                None, ['pp_id'],
                self.pp,
                default=1),
            Par('st_lss_hr', (self.st, self.ca), 'df_plant_encar', None,
                ['pp_id'], self.st),
            Par('st_lss_rt', (self.st, self.ca), 'df_plant_encar', None,
                ['pp_id'], self.st),
            Par('discharge_duration', (self.st | self.hyrs, self.ca),
                'df_plant_encar', None, ['pp_id'], self.st | self.hyrs),
            Par('hyd_erg_bc', (self.sy_hydbc, self.hyrs), 'df_plant_month'),
        )

        self.dict_par = {}
        for par in list_par:
            parameter = ParameterAdder(self, par)
            self.dict_par[par.parameter_name] = parameter
            parameter.init_update()