Beispiel #1
0
def remove_stubs(n):
    logger.info("Removing stubs")

    busmap = busmap_by_stubs(n, ['country'])
    _aggregate_and_move_components(n, busmap)

    return n, busmap
Beispiel #2
0
def remove_stubs(n):
    logger.info("Removing stubs")

    busmap = busmap_by_stubs(n)  #  ['country'])

    connection_costs_to_bus = _compute_connection_costs_to_bus(n, busmap)

    _aggregate_and_move_components(n, busmap, connection_costs_to_bus)

    return n, busmap
Beispiel #3
0
def kmean_clustering(network,
                     n_clusters=10,
                     load_cluster=False,
                     line_length_factor=1.25,
                     remove_stubs=False,
                     use_reduced_coordinates=False,
                     bus_weight_tocsv=None,
                     bus_weight_fromcsv=None,
                     n_init=10,
                     max_iter=300,
                     tol=1e-4,
                     n_jobs=1):
    """ Main function of the k-mean clustering approach. Maps an original
    network to a new one with adjustable number of nodes and new coordinates.

    Parameters
    ----------
    network : :class:`pypsa.Network
        Container for all network components.

    n_clusters : int
        Desired number of clusters.

    load_cluster : boolean
        Loads cluster coordinates from a former calculation.

    line_length_factor : float
        Factor to multiply the crow-flies distance between new buses in order
        to get new line lengths.

    remove_stubs: boolean
        Removes stubs and stubby trees (i.e. sequentially reducing dead-ends).

    use_reduced_coordinates: boolean
        If True, do not average cluster coordinates, but take from busmap.

    bus_weight_tocsv : str
        Creates a bus weighting based on conventional generation and load
        and save it to a csv file.

    bus_weight_fromcsv : str
        Loads a bus weighting from a csv file to apply it to the clustering
        algorithm.

    Returns
    -------
    network : pypsa.Network object
        Container for all network components.
    """
    def weighting_for_scenario(x, save=None):
        """
        """
        b_i = x.index
        g = normed(gen.reindex(b_i, fill_value=0))
        l = normed(load.reindex(b_i, fill_value=0))

        w = g + l
        weight = ((w * (100000. / w.max())).astype(int)).reindex(
            network.buses.index, fill_value=1)

        if save:
            weight.to_csv(save)

        return weight

    def normed(x):
        return (x / x.sum()).fillna(0.)

    print('start k-mean clustering')
    # prepare k-mean
    # k-means clustering (first try)
    network.generators.control = "PV"
    network.storage_units.control[network.storage_units.carrier == \
                                  'extendable_storage'] = "PV"
    network.buses['v_nom'] = 380.
    # problem our lines have no v_nom. this is implicitly defined by the
    # connected buses:
    network.lines["v_nom"] = network.lines.bus0.map(network.buses.v_nom)

    # adjust the x of the lines which are not 380.
    lines_v_nom_b = network.lines.v_nom != 380
    network.lines.loc[lines_v_nom_b, 'x'] *= \
        (380. / network.lines.loc[lines_v_nom_b, 'v_nom'])**2
    network.lines.loc[lines_v_nom_b, 'v_nom'] = 380.

    trafo_index = network.transformers.index
    transformer_voltages = \
        pd.concat([network.transformers.bus0.map(network.buses.v_nom),
                   network.transformers.bus1.map(network.buses.v_nom)], axis=1)

    network.import_components_from_dataframe(
        network.transformers.
        loc[:, ['bus0', 'bus1', 'x', 's_nom', 'capital_cost']].assign(
            x=network.transformers.x *
            (380. / transformer_voltages.max(axis=1))**2,
            length=1).set_index('T' + trafo_index), 'Line')
    network.transformers.drop(trafo_index, inplace=True)

    for attr in network.transformers_t:
        network.transformers_t[attr] = network.transformers_t[attr]\
            .reindex(columns=[])

    # remove stubs
    if remove_stubs:
        network.determine_network_topology()
        busmap = busmap_by_stubs(network)
        network.generators['weight'] = network.generators['p_nom']
        aggregate_one_ports = components.one_port_components.copy()
        aggregate_one_ports.discard('Generator')
        # reset coordinates to the new reduced guys, rather than taking an
        # average (copied from pypsa.networkclustering)
        if use_reduced_coordinates:
            # TODO : FIX THIS HACK THAT HAS UNEXPECTED SIDE-EFFECTS,
            # i.e. network is changed in place!!
            network.buses.loc[busmap.index, ['x', 'y']] = network.buses.loc[
                busmap, ['x', 'y']].values

        clustering = get_clustering_from_busmap(
            network,
            busmap,
            aggregate_generators_weighted=True,
            aggregate_one_ports=aggregate_one_ports,
            line_length_factor=line_length_factor)
        network = clustering.network

    # define weighting based on conventional 'old' generator spatial
    # distribution
    non_conv_types = {
        'biomass', 'wind_onshore', 'wind_offshore', 'solar', 'geothermal',
        'load shedding', 'extendable_storage'
    }
    # Attention: network.generators.carrier.unique()
    gen = (
        network.generators.loc[(network.generators.carrier.isin(non_conv_types)
                                == False)].groupby('bus').p_nom.sum().reindex(
                                    network.buses.index, fill_value=0.) +
        network.storage_units.loc[
            (network.storage_units.carrier.isin(non_conv_types)
             == False)].groupby('bus').p_nom.sum().reindex(network.buses.index,
                                                           fill_value=0.))

    load = network.loads_t.p_set.mean().groupby(network.loads.bus).sum()

    # k-mean clustering

    # busmap = busmap_by_kmeans(network, bus_weightings=pd.Series(np.repeat(1,
    #       len(network.buses)), index=network.buses.index) , n_clusters= 10)
    # State whether to create a bus weighting and save it, create or not save
    # it, or use a bus weighting from a csv file
    if bus_weight_tocsv is not None:
        weight = weighting_for_scenario(x=network.buses, save=bus_weight_tocsv)
    elif bus_weight_fromcsv is not None:
        weight = pd.Series.from_csv(bus_weight_fromcsv)
        weight.index = weight.index.astype(str)
    else:
        weight = weighting_for_scenario(x=network.buses, save=False)

    busmap = busmap_by_kmeans(network,
                              bus_weightings=pd.Series(weight),
                              n_clusters=n_clusters,
                              load_cluster=load_cluster,
                              n_init=n_init,
                              max_iter=max_iter,
                              tol=tol,
                              n_jobs=n_jobs)

    # ToDo change function in order to use bus_strategies or similar
    network.generators['weight'] = network.generators['p_nom']
    aggregate_one_ports = components.one_port_components.copy()
    aggregate_one_ports.discard('Generator')
    clustering = get_clustering_from_busmap(
        network,
        busmap,
        aggregate_generators_weighted=True,
        aggregate_one_ports=aggregate_one_ports)

    return clustering