def calculate_dc_inv_costs(scenario, sum_results=True, base_grid=None):
    """Calculate cost of upgrading HVDC lines in a scenario.

    :param powersimdata.scenario.scenario.Scenario scenario: scenario instance.
    :param bool sum_results: whether to sum series to return total cost. Defaults to
        True.
    :param powersimdata.input.grid.Grid base_grid: a Grid to compare against. If None,
        the grid model and interconnect from the ``scenario`` are used to instantiate a
        corresponding unmodified Grid.
    :return: (*pandas.Series/float*) -- cost of upgrading HVDC lines, in $USD,
        inflation-adjusted to today. If ``sum_results``, a float is returned, otherwise
        a Series.
    """
    grid_differences = scenario.get_grid()
    if base_grid is None:
        base_grid = scenario.get_base_grid()
    else:
        _check_grid_models_match(base_grid, grid_differences)

    # find upgraded DC lines
    capacity_difference = calculate_dcline_difference(base_grid, grid_differences)
    grid_differences.dcline = grid_differences.dcline.assign(
        Pmax=capacity_difference["diff"].to_numpy()
    )
    grid_differences.dcline = grid_differences.dcline.query("Pmax != 0.0")

    costs = _calculate_dc_inv_costs(grid_differences, sum_results)
    return costs
def calculate_gen_inv_costs(
    scenario,
    year,
    cost_case,
    sum_results=True,
    base_grid=None,
):
    """Calculate cost of upgrading generators in a scenario. ReEDS regions are used to
    find regional multipliers.

    :param powersimdata.scenario.scenario.Scenario scenario: scenario instance.
    :param int/str year: building year.
    :param str cost_case: ATB cost case of data. *'Moderate'*: mid cost case,
        *'Conservative'*: generally higher costs, *'Advanced'*: generally lower costs
    :param bool sum_results: whether to sum data frame for plant costs. Defaults to
        True.
    :param powersimdata.input.grid.Grid base_grid: a Grid to compare against. If None,
        the grid model and interconnect from the ``scenario`` are used to instantiate a
        corresponding unmodified Grid.
    :return: (*pandas.Series*) -- Overnight generation investment cost.
        If ``sum_results``, indices are technologies and values are total cost.
        Otherwise, indices are IDs of plants (including storage, which is given
        pseudo-plant-IDs), and values are individual generator costs.
        Whether summed or not, values are $USD, inflation-adjusted to today.

    .. todo:: it currently uses one (arbitrary) sub-technology. The rest of the costs
        are dropped. Wind and solar will need to be fixed based on the resource supply
        curves.
    """
    grid_differences = scenario.get_grid()
    if base_grid is None:
        base_grid = scenario.get_base_grid()
    else:
        _check_grid_models_match(base_grid, grid_differences)

    # Find change in generation capacity
    capacity_difference = calculate_plant_difference(
        base_grid.plant, grid_differences.plant
    )
    grid_differences.plant = grid_differences.plant.assign(
        Pmax=capacity_difference["diff"].to_numpy()
    )
    grid_differences.plant = grid_differences.plant.query("Pmax >= 0.01")
    # Find change in storage capacity
    # Reindex so that we don't get NaN when calculating upgrades for new storage
    base_grid.storage["gen"] = base_grid.storage["gen"].reindex(
        grid_differences.storage["gen"].index, fill_value=0
    )
    grid_differences.storage["gen"].Pmax = (
        grid_differences.storage["gen"].Pmax - base_grid.storage["gen"].Pmax
    )
    grid_differences.storage["gen"]["type"] = "storage"

    costs = _calculate_gen_inv_costs(grid_differences, year, cost_case, sum_results)
    return costs
def calculate_ac_inv_costs(
    scenario,
    sum_results=True,
    exclude_branches=None,
    base_grid=None,
):
    """Calculate cost of upgrading AC lines and/or transformers in a scenario.
    NEEM regions are used to find regional multipliers.

    :param powersimdata.scenario.scenario.Scenario scenario: scenario instance.
    :param bool sum_results: whether to sum data frame for each branch type. Defaults to
        True.
    :param powersimdata.input.grid.Grid base_grid: a Grid to compare against. If None,
        the grid model and interconnect from the ``scenario`` are used to instantiate a
        corresponding unmodified Grid.
    :return: (*dict*) -- keys are {'line_cost', 'transformer_cost'}, values are either
        float if ``sum_results``, or pandas Series indexed by branch ID.
        Whether summed or not, values are $USD, inflation-adjusted to today.
    """
    grid_differences = scenario.get_grid()
    if base_grid is None:
        base_grid = scenario.get_base_grid()
    else:
        _check_grid_models_match(base_grid, grid_differences)

    # find upgraded AC lines
    capacity_difference = calculate_branch_difference(
        base_grid.branch, grid_differences.branch
    )
    grid_differences.branch = grid_differences.branch.assign(
        rateA=capacity_difference["diff"].to_numpy()
    )
    grid_differences.branch = grid_differences.branch.query("rateA != 0.0")
    if exclude_branches is not None:
        present_exclude_branches = set(exclude_branches) & set(
            grid_differences.branch.index
        )
        grid_differences.branch.drop(index=present_exclude_branches, inplace=True)

    costs = _calculate_ac_inv_costs(grid_differences, sum_results)
    return costs
Esempio n. 4
0
def check_grid_models_match_failure():
    grid1 = Grid("Western")
    grid2 = Grid("Texas")
    grid2.grid_model == "foo"
    with pytest.raises(ValueError):
        _check_grid_models_match(grid1, grid2)
Esempio n. 5
0
def check_grid_models_match_success():
    _check_grid_models_match(Grid("Western"), Grid("Texas"))