Beispiel #1
0
    def _lookup_costs(self, wind_mw, solar_mw, interconnection_mw):
        if wind_mw + solar_mw == 0:
            return 0, 0, 0

        search_inputs = np.array([interconnection_mw, wind_mw, solar_mw])

        distance_norm = np.linalg.norm(self.contents - search_inputs, axis=1)
        min_index = np.argmin(distance_norm)
        min_distance = distance_norm[min_index]

        vals = []
        for i in range(len(self.desired_output_parameters)):
            vals.append(self.interpolating_fxns[i](search_inputs)[0])

        if np.isnan(vals).any():
            if min_distance / np.linalg.norm(search_inputs) < .05:
                wind_bos_cost = self.data.iloc[min_index:min_index+1]["Wind BOS Cost"].values
                solar_bos_cost = self.data.iloc[min_index:min_index+1]["Solar BOS Cost"].values
            else:
                raise ValueError("Inputs to BOSLookup outside of range and cannot be extrapolated")
        else:
            wind_bos_cost = vals[self.desired_output_parameters.index("Wind BOS Cost")]
            solar_bos_cost = vals[self.desired_output_parameters.index("Solar BOS Cost")]

        total_bos_cost = wind_bos_cost + solar_bos_cost

        logger.info("Total BOS Cost: {} Wind BOS Cost: {} Solar BOS Cost {}".
                    format(total_bos_cost, wind_bos_cost, solar_bos_cost))

        return wind_bos_cost, solar_bos_cost, total_bos_cost, min_distance
Beispiel #2
0
 def _calculate_greenfield(self,
                           wind_mw: float,
                           solar_mw: float,
                           interconnection_mw: float = 0):
     logger.info("Implemented")
     specify_construction_duration = False
     return HybridBOSSE._calculate(wind_mw, solar_mw, interconnection_mw,
                                   specify_construction_duration)
Beispiel #3
0
    def calculate_total_costs(self, wind_mw, solar_mw):
        """
        Calculates total installed cost of plant (BOS Cost + Installed Cost).
        Modifies the capex or opex costs as specified in cost_reductions if modify_costs is True
        :return: Total installed cost of plant (BOS Cost + Installed Cost)
        """
        logger.info(
            "Determining total costs for Wind size: {}MW and Solar size: {}MW and Interconnection size: {}MW"
            .format(wind_mw, solar_mw, self.interconnection_size))

        logger.info(
            "Using {}$/MW for installed Wind cost and {}$/MW for installed Solar cost"
            .format(self.wind_installed_cost_mw, self.solar_installed_cost_mw))

        logger.info("Using '{}' to determine BOS costs".format(
            self.model.name))

        wind_installed_cost, solar_installed_cost, total_installed_cost = self.calculate_installed_costs(
            wind_mw, solar_mw)
        wind_bos_cost, solar_bos_cost, total_bos_cost, _ = self.model.calculate_bos_costs(
            wind_mw, solar_mw, self.interconnection_size, self.scenario)
        total_wind_cost = wind_installed_cost + wind_bos_cost
        total_solar_cost = solar_installed_cost + solar_bos_cost
        total_project_cost = total_installed_cost + total_bos_cost

        if self.modify_costs:
            logger.info('Modifying costs using selected multipliers')
            logger.info("Total Project Cost Before Modifiers: {}".format(
                total_project_cost))
            if wind_mw > 0 and solar_mw > 0:
                total_project_cost = ((1 - self.cost_reductions['solar_capex_reduction_hybrid']) *
                                      solar_installed_cost) + \
                                 ((1 - self.cost_reductions[
                                     'solar_bos_reduction_hybrid']) * solar_bos_cost) + \
                                 ((1 - self.cost_reductions['wind_capex_reduction_hybrid']) *
                                  wind_installed_cost) + \
                                 ((1 - self.cost_reductions[
                                     'wind_bos_reduction_hybrid']) * wind_bos_cost)
            elif solar_mw > 0:
                total_project_cost = ((1 - self.cost_reductions['solar_capex_reduction']) *
                                      solar_installed_cost) + \
                                 ((1 - self.cost_reductions['solar_bos_reduction']) * solar_bos_cost)
            elif wind_mw > 0:
                total_project_cost = ((1 - self.cost_reductions['wind_capex_reduction']) *
                                      wind_installed_cost) + \
                                 ((1 - self.cost_reductions['wind_bos_reduction']) * wind_bos_cost)

            logger.info("Total Project Cost After Modifiers: {}".format(
                total_project_cost))
        # else:
        # logger.info('Not modifying costs')
        # Not modifying wind or solar costs

        logger.info(
            "Total Project Cost (Installed Cost + BOS Cost): {}".format(
                total_project_cost))
        return total_solar_cost, total_wind_cost, total_project_cost
Beispiel #4
0
    def _calculate(wind_size, solar_size, interconnection_rating,
                   specify_construction_duration):
        warnings.filterwarnings('ignore')  # ignore pandas FutureWarning
        hybrids_input_dict = dict()

        # shared infra inputs
        hybrids_input_dict['shared_interconnection'] = True
        hybrids_input_dict[
            'distance_to_interconnect_mi'] = 1  # Input not used for projects <= 15 MW
        hybrids_input_dict['new_switchyard'] = True
        grid_size_multiplier = 1
        grid_size = wind_size * grid_size_multiplier
        if grid_size > 15:
            hybrids_input_dict['distance_to_interconnect_mi'] = (
                0.0263 * grid_size) - 0.2632
        else:
            hybrids_input_dict['distance_to_interconnect_mi'] = 0
        if grid_size < 20:
            hybrids_input_dict['interconnect_voltage_kV'] = 15
        elif 20 < grid_size < 40:
            hybrids_input_dict['interconnect_voltage_kV'] = 34.5
        elif 40 <= grid_size < 75:
            hybrids_input_dict['interconnect_voltage_kV'] = 69  # should be 69
        elif grid_size >= 75:
            hybrids_input_dict[
                'interconnect_voltage_kV'] = 138  # should be 138
        hybrids_input_dict[
            'grid_interconnection_rating_MW'] = wind_size + solar_size
        hybrids_input_dict['shared_substation'] = True
        hybrids_input_dict[
            'hybrid_substation_rating_MW'] = wind_size + solar_size

        # Wind farm required inputs
        hybrids_input_dict['turbine_rating_MW'] = 1.5
        num_turbines = math.ceil(wind_size /
                                 hybrids_input_dict['turbine_rating_MW'])
        hybrids_input_dict['num_turbines'] = num_turbines
        hybrids_input_dict[
            'wind_dist_interconnect_mi'] = 0  # Only used for calculating grid cost of wind only. Input not used for projects <= 15 MW
        hybrids_input_dict['wind_construction_time_months'] = 5
        hybrids_input_dict['project_id'] = 'hybrids'

        # Solar farm required inputs
        hybrids_input_dict['solar_system_size_MW_DC'] = solar_size
        hybrids_input_dict[
            'solar_construction_time_months'] = 5  # Optional. Overrides the internal scaling MW vs. construction time relationship
        hybrids_input_dict['solar_dist_interconnect_mi'] = 0

        # pre-processed input data:
        hybrids_input_dict['wind_plant_size_MW'] = hybrids_input_dict['num_turbines'] * \
                                                   hybrids_input_dict['turbine_rating_MW']

        hybrids_input_dict['hybrid_plant_size_MW'] = hybrids_input_dict['wind_plant_size_MW'] + \
                                                     hybrids_input_dict['solar_system_size_MW_DC']

        hybrids_input_dict['hybrid_construction_months'] = \
            hybrids_input_dict['wind_construction_time_months'] + \
            hybrids_input_dict['solar_construction_time_months']

        hybrid_results, wind_only, solar_only = run_hybridbosse(
            hybrids_input_dict)

        logger.info('Hybrid Dictionary Results: {}'.format(hybrid_results))
        logger.info('Wind Only Dictionary Results:'.format(wind_only))
        logger.info('Solar Only Dictionary Results:'.format(solar_only))

        wind_hybrid_bos_cost = hybrid_results['Wind_BOS_results'][
            'total_bos_cost']
        solar_hybrid_bos_cost = hybrid_results['Solar_BOS_results'][
            'total_bos_cost']
        hybrid_total_bos_cost = wind_hybrid_bos_cost + solar_hybrid_bos_cost  #hybrid_results['hybrid']['hybrid_BOS_usd']

        return wind_hybrid_bos_cost, solar_hybrid_bos_cost, hybrid_total_bos_cost
Beispiel #5
0
    def calculate_total_costs(self,
                              wind_mw,
                              pv_mw,
                              storage_mw=0.,
                              storage_mwh=0.):
        """
        Calculates total installed cost of plant (BOS Cost + Installed Cost).
        Modifies the capex or opex costs as specified in cost_reductions if modify_costs is True
        :return: Total installed cost of plant (BOS Cost + Installed Cost)
        """

        wind_installed_cost, solar_installed_cost, storage_installed_cost, total_installed_cost = \
            self.calculate_installed_costs(wind_mw, pv_mw, storage_mw, storage_mwh)

        if self.bos_cost_source.lower() == 'costpermw':
            wind_bos_cost, solar_bos_cost, storage_bos_cost, total_bos_cost, _ = \
                self.model.calculate_bos_costs(wind_mw, pv_mw, storage_mw, storage_mwh, self.wind_bos_cost_mw,
                                               self.pv_bos_cost_mw, self.storage_bos_cost_mw, self.storage_bos_cost_mwh,
                                               self.interconnection_size, self.scenario)
        else:
            wind_bos_cost, solar_bos_cost, total_bos_cost, min_distance = \
                self.model.calculate_bos_costs(wind_mw, pv_mw, self.interconnection_size)
            storage_bos_cost = 0.

        total_wind_cost = wind_installed_cost + wind_bos_cost
        total_solar_cost = solar_installed_cost + solar_bos_cost
        total_storage_cost = storage_installed_cost + storage_bos_cost
        total_project_cost = total_installed_cost + total_bos_cost

        if self.modify_costs:
            logger.info('Modifying costs using selected multipliers')
            logger.info("Total Project Cost Before Modifiers: {}".format(
                total_project_cost))
            if wind_mw > 0 and pv_mw > 0:
                total_project_cost = ((1 - self.cost_reductions['solar_capex_reduction_hybrid']) *
                                      solar_installed_cost) + \
                                 ((1 - self.cost_reductions[
                                     'solar_bos_reduction_hybrid']) * solar_bos_cost) + \
                                 ((1 - self.cost_reductions['wind_capex_reduction_hybrid']) *
                                  wind_installed_cost) + \
                                 ((1 - self.cost_reductions[
                                     'wind_bos_reduction_hybrid']) * wind_bos_cost)
            elif pv_mw > 0:
                total_project_cost = ((1 - self.cost_reductions['solar_capex_reduction']) *
                                      solar_installed_cost) + \
                                 ((1 - self.cost_reductions['solar_bos_reduction']) * solar_bos_cost)
            elif wind_mw > 0:
                total_project_cost = ((1 - self.cost_reductions['wind_capex_reduction']) *
                                      wind_installed_cost) + \
                                 ((1 - self.cost_reductions['wind_bos_reduction']) * wind_bos_cost)

            logger.info("Total Project Cost After Modifiers: {}".format(
                total_project_cost))
        # else:
        # logger.info('Not modifying costs')
        # Not modifying wind or solar costs

        logger.info(
            "Total Project Cost (Installed Cost + BOS Cost): {}".format(
                total_project_cost))
        return total_solar_cost, total_wind_cost, total_storage_cost, total_project_cost