def update_network(n_clicks, value1, value2): print(value2) self.net = Network() self.net.import_from_csv_folder(f"{self.output_dir}{value1}/") self.current_link_id = self.net.links.index[0] self.current_bus_id = self.net.buses.index[0] self.selected_types = value2 return get_map(), get_costs_table(), get_capacities(), get_total_generation(), get_load_gen()
def preprocess(plot: bool = False): # TODO: # - figure out what we really need # - converters? # - transformers? # - figure out if lines and/or links can be extended # - see prepare_network # - Probably best to do all these steps once in a preprocess function and then just # remove unwanted components at run time # Load main components # buses_df = load_buses_from_eg(countries, voltages) buses_df = load_buses_from_eg() # buses_df, links_df = load_links_from_eg(buses_df, config['links'], countries) buses_df, links_df = load_links_from_eg(buses_df) # converters_df = load_converters_from_eg(buses_df.index, config["links"]) converters_df = load_converters_from_eg(buses_df.index) # lines_df = load_lines_from_eg(buses_df.index, config["lines"], voltages, net.line_types) lines_df = load_lines_from_eg(buses_df.index) # transformers_df = load_transformers_from_eg(buses_df.index, config["transformers"]) transformers_df = load_transformers_from_eg(buses_df.index) # Add everything to the network net = Network() net.import_components_from_dataframe(buses_df, "Bus") net.import_components_from_dataframe(lines_df, "Line") net.import_components_from_dataframe(transformers_df, "Transformer") net.import_components_from_dataframe(links_df, "Link") net.import_components_from_dataframe(converters_df, "Link") # Update a bunch of parameters for given components according to parameters_correction.yaml apply_parameter_corrections(net) # Remove subnetworks with less than a given number of components net = remove_unconnected_components(net) # Determine to which country each bus (onshore or offshore) belong and do some stuff with substations # set_countries_and_substations(net, countries) set_countries_and_substations(net) # Set what portion of the link is under water # set_links_underwater_fraction(net, countries) set_links_underwater_fraction(net) # I have no clue what this is for... replace_b2b_converter_at_country_border_by_link(net) # Save base network net.export_to_csv_folder( f"{data_path}topologies/pypsa_entsoe_gridkit/generated/base_network/") if plot: import matplotlib.pyplot as plt net.plot(bus_sizes=0.001) plt.show() return net
def cluster_on_extra_high_voltage(network, busmap, with_time=True): network_c = Network() buses = aggregatebuses(network, busmap, { 'x': _leading(busmap, network.buses), 'y': _leading(busmap, network.buses) }) # keep attached lines lines = network.lines.copy() mask = lines.bus0.isin(buses.index) lines = lines.loc[mask, :] # keep attached transformer transformers = network.transformers.copy() mask = transformers.bus0.isin(buses.index) transformers = transformers.loc[mask, :] io.import_components_from_dataframe(network_c, buses, "Bus") io.import_components_from_dataframe(network_c, lines, "Line") io.import_components_from_dataframe(network_c, transformers, "Transformer") if with_time: network_c.now = network.now network_c.set_snapshots(network.snapshots) # dealing with generators network.generators['weight'] = 1 new_df, new_pnl = aggregategenerators(network, busmap, with_time) io.import_components_from_dataframe(network_c, new_df, 'Generator') for attr, df in iteritems(new_pnl): io.import_series_from_dataframe(network_c, df, 'Generator', attr) # dealing with all other components aggregate_one_ports = components.one_port_components.copy() aggregate_one_ports.discard('Generator') for one_port in aggregate_one_ports: new_df, new_pnl = aggregateoneport(network, busmap, component=one_port, with_time=with_time) io.import_components_from_dataframe(network_c, new_df, one_port) for attr, df in iteritems(new_pnl): io.import_series_from_dataframe(network_c, df, one_port, attr) network_c.determine_network_topology() return network_c
def init_pypsa_network(time_range_lim): """ Instantiate PyPSA network Parameters ---------- time_range_lim: Returns ------- network: PyPSA network object Contains powerflow problem snapshots: iterable Contains snapshots to be analyzed by powerplow calculation """ network = Network() network.set_snapshots(time_range_lim) snapshots = network.snapshots return network, snapshots
def __init__(self, output_dir, test_number=None): # Load css css_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), "assets/") self.app = dash.Dash(__name__, assets_url_path=css_folder) # Load net # If no test_number is specified, take the last run self.current_test_number = test_number if self.current_test_number is None: self.current_test_number = sorted(os.listdir(output_dir))[-1] self.output_dir = output_dir self.net = Network() self.net.import_from_csv_folder(f"{self.output_dir}{self.current_test_number}/") if len(self.net.lines) != 0: self.current_line_id = self.net.lines.index[0] if len(self.net.links) != 0: self.current_link_id = self.net.links.index[0] self.current_bus_id = self.net.buses.index[0] self.selected_types = sorted(list(set(self.net.generators.type.values)))
output_dir = f'../output/{topology}/{run_id}/' config_fn = join(output_dir, 'config.yaml') config = yaml.load(open(config_fn, 'r'), Loader=yaml.FullLoader) run_name = config["res"]["sites_dir"] + "_" + \ config["res"]["sites_fn"].split("_")[0].upper() name = run_name.split("_")[-3:] if "MAX" in name: name = "PROD" else: name = "COMP_c = " + name[1][1:] + "_" + name[0] run_names.append(name) net = Network() net.import_from_csv_folder(output_dir) nets += [net] with open(join(output_dir, "solver.log"), 'r') as f: for line in f: if "objective" in line: objectives[name] = float(line.split(' ')[-1]) * 1e-5 caption = ", ".join(run_name.split('_')[:-2]) table = generate_costs_table(nets, run_names, [ "ccgt", "wind_offshore", "wind_onshore", "pv_utility", "pv_residential", "AC", "DC", "Li-ion" ]) text = convert_cost_table_to_latex(table, objectives, caption)
topology = 'tyndp2018' main_output_dir = f'../output/{topology}/' results = 'compare' # 'compare', 'single' resolution = 'H' start = datetime(2015, 12, 13, 0, 0, 0) end = datetime(2015, 12, 19, 23, 0, 0) if results == 'single': run_id = '20200429_123543' output_dir = f"{main_output_dir}{run_id}/" net = Network() net.import_from_csv_folder(output_dir) pprp = SizingResultsSingleNet(net, start, end, resolution) pprp.make_plots_one_net() else: # first_run_id = '20200429_123543' # second_run_id = '20200429_132039' first_run_id = '20200429_123543' second_run_id = '20200429_154728' first_output_dir = f"{main_output_dir}{first_run_id}/" second_output_dir = f"{main_output_dir}{second_run_id}/"
def load_topology(nuts_codes, config, voltages: List[float] = None, plot: bool = False): net = Network() net.import_from_csv_folder( f"{data_path}topologies/pypsa_entsoe_gridkit/generated/base_network/") if 1: import matplotlib.pyplot as plt net.plot(bus_sizes=0.001) plt.show() exit() # Remove all buses outside desired regions region_shapes_ds = get_shapes(nuts_codes, save=True)["geometry"] buses_in_nuts_regions = \ net.buses[['x', 'y']].apply(lambda p: any([shape.contains(Point(p)) for shape in region_shapes_ds]), axis=1) net.buses = net.buses[buses_in_nuts_regions] if 0: plt.figure() net.plot(bus_sizes=0.001) # Remove all buses which are not at the desired voltage buses_with_v_nom_to_keep_b = net.buses.v_nom.isnull() if voltages is not None: buses_with_v_nom_to_keep_b |= net.buses.v_nom.isin(voltages) logger.info( "Removing buses with voltages {}" "".format( pd.Index( net.buses.v_nom.unique()).dropna().difference(voltages))) net.buses = net.buses[buses_with_v_nom_to_keep_b] if 1: plt.figure() net.plot(bus_sizes=0.001) plt.show() # Remove dangling branches net.lines = remove_dangling_branches(net.lines, net.buses.index) net.links = remove_dangling_branches(net.links, net.buses.index) net.transformers = remove_dangling_branches(net.transformers, net.buses.index) # Set electrical parameters set_electrical_parameters_lines(net, config['lines'], net.buses.v_nom.dropna().unique().tolist()) set_electrical_parameters_links(net, config['links']) set_electrical_parameters_transformers(net, config['transformers']) # Allows to set under construction links and lines to 0 or remove them completely, # and remove some unconnected components that might appear as a result net = adjust_capacities_of_under_construction_branches( net, config['lines'], config['links']) # Remove unconnected components # TODO: allow to simplify the network (i.e. convert everything to 380) or not ? net = cluster_network(net, nuts_codes) if plot: from epippy.topologies.core.plot import plot_topology all_lines = pd.concat( (net.links[['bus0', 'bus1']], net.lines[['bus0', 'bus1']])) plot_topology(net.buses, all_lines) plt.show() return net
def cluster_on_extra_high_voltage(network, busmap, with_time=True): """ Create a new clustered pypsa.Network given a busmap mapping all busids to other busids of the same set. Parameters ---------- network : pypsa.Network Container for all network components. busmap : dict Maps old bus_ids to new bus_ids. with_time : bool If true time-varying data will also be aggregated. Returns ------- network : pypsa.Network Container for all network components. """ network_c = Network() buses = aggregatebuses(network, busmap, { 'x': _leading(busmap, network.buses), 'y': _leading(busmap, network.buses) }) # keep attached lines lines = network.lines.copy() mask = lines.bus0.isin(buses.index) lines = lines.loc[mask, :] # keep attached transformer transformers = network.transformers.copy() mask = transformers.bus0.isin(buses.index) transformers = transformers.loc[mask, :] io.import_components_from_dataframe(network_c, buses, "Bus") io.import_components_from_dataframe(network_c, lines, "Line") io.import_components_from_dataframe(network_c, transformers, "Transformer") if with_time: network_c.snapshots = network.snapshots network_c.set_snapshots(network.snapshots) # dealing with generators network.generators.control = "PV" network.generators['weight'] = 1 new_df, new_pnl = aggregategenerators(network, busmap, with_time) io.import_components_from_dataframe(network_c, new_df, 'Generator') for attr, df in iteritems(new_pnl): io.import_series_from_dataframe(network_c, df, 'Generator', attr) # dealing with all other components aggregate_one_ports = components.one_port_components.copy() aggregate_one_ports.discard('Generator') for one_port in aggregate_one_ports: new_df, new_pnl = aggregateoneport(network, busmap, component=one_port, with_time=with_time) io.import_components_from_dataframe(network_c, new_df, one_port) for attr, df in iteritems(new_pnl): io.import_series_from_dataframe(network_c, df, one_port, attr) network_c.determine_network_topology() return network_c
def construct_partial_network(self, cluster, scenario): """ Compute the partial network that has been merged into a single cluster. The resulting network retains the external cluster buses that share some line with the cluster identified by `cluster`. These external buses will be prefixed by self.id_prefix in order to prevent name clashes with buses in the disaggregation :param cluster: Index of the cluster to disaggregate :return: Tuple of (partial_network, external_buses) where `partial_network` is the result of the partial decomposition and `external_buses` represent clusters adjacent to `cluster` that may be influenced by calculations done on the partial network. """ #Create an empty network partial_network = Network() # find all lines that have at least one bus inside the cluster busflags = (self.buses['cluster'] == cluster) def is_bus_in_cluster(conn): return busflags[conn] # Copy configurations to new network partial_network.snapshots = self.original_network.snapshots partial_network.snapshot_weightings = ( self.original_network.snapshot_weightings) partial_network.carriers = self.original_network.carriers # Collect all connectors that have some node inside the cluster external_buses = pd.DataFrame() line_types = ['lines', 'links', 'transformers'] for line_type in line_types: # Copy all lines that reside entirely inside the cluster ... setattr( partial_network, line_type, filter_internal_connector( getattr(self.original_network, line_type), is_bus_in_cluster)) # ... and their time series # TODO: These are all time series, not just the ones from lines # residing entirely in side the cluster. # Is this a problem? setattr(partial_network, line_type + '_t', getattr(self.original_network, line_type + '_t')) # Copy all lines whose `bus0` lies within the cluster left_external_connectors = filter_left_external_connector( getattr(self.original_network, line_type), is_bus_in_cluster) if not left_external_connectors.empty: f = lambda x: self.idx_prefix + self.clustering.busmap.loc[x] ca_option = pd.get_option('mode.chained_assignment') pd.set_option('mode.chained_assignment', None) left_external_connectors.loc[:, 'bus0'] = ( left_external_connectors.loc[:, 'bus0'].apply(f)) pd.set_option('mode.chained_assignment', ca_option) external_buses = pd.concat( (external_buses, left_external_connectors.bus0)) # Copy all lines whose `bus1` lies within the cluster right_external_connectors = filter_right_external_connector( getattr(self.original_network, line_type), is_bus_in_cluster) if not right_external_connectors.empty: f = lambda x: self.idx_prefix + self.clustering.busmap.loc[x] ca_option = pd.get_option('mode.chained_assignment') pd.set_option('mode.chained_assignment', None) right_external_connectors.loc[:, 'bus1'] = ( right_external_connectors.loc[:, 'bus1'].apply(f)) pd.set_option('mode.chained_assignment', ca_option) external_buses = pd.concat( (external_buses, right_external_connectors.bus1)) # Collect all buses that are contained in or somehow connected to the # cluster buses_in_lines = self.buses[busflags].index bus_types = [ 'loads', 'generators', 'stores', 'storage_units', 'shunt_impedances' ] # Copy all values that are part of the cluster partial_network.buses = self.original_network.buses[ self.original_network.buses.index.isin(buses_in_lines)] # Collect all buses that are external, but connected to the cluster ... externals_to_insert = self.clustered_network.buses[ self.clustered_network.buses.index.isin( map(lambda x: x[0][len(self.idx_prefix):], external_buses.values))] # ... prefix them to avoid name clashes with buses from the original # network ... self.reindex_with_prefix(externals_to_insert) # .. and insert them as well as their time series partial_network.buses = ( partial_network.buses.append(externals_to_insert)) partial_network.buses_t = self.original_network.buses_t # TODO: Rename `bustype` to on_bus_type for bustype in bus_types: # Copy loads, generators, ... from original network to network copy setattr( partial_network, bustype, filter_buses(getattr(self.original_network, bustype), buses_in_lines)) # Collect on-bus components from external, connected clusters buses_to_insert = filter_buses( getattr(self.clustered_network, bustype), map(lambda x: x[0][len(self.idx_prefix):], external_buses.values)) # Prefix their external bindings buses_to_insert.loc[:, 'bus'] = (self.idx_prefix + buses_to_insert.loc[:, 'bus']) setattr(partial_network, bustype, getattr(partial_network, bustype).append(buses_to_insert)) # Also copy their time series setattr(partial_network, bustype + '_t', getattr(self.original_network, bustype + '_t')) # Note: The code above copies more than necessary, because it # copies every time series for `bustype` from the original # network and not only the subset belonging to the partial # network. The commented code below tries to filter the time # series accordingly, but there must be bug somewhere because # using it, the time series in the clusters and sums of the # time series after disaggregation don't match up. """ series = getattr(self.original_network, bustype + '_t') partial_series = type(series)() for s in series: partial_series[s] = series[s].loc[ :, getattr(partial_network, bustype) .index.intersection(series[s].columns)] setattr(partial_network, bustype + '_t', partial_series) """ # Just a simple sanity check # TODO: Remove when sure that disaggregation will not go insane anymore for line_type in line_types: assert (getattr(partial_network, line_type).bus0.isin( partial_network.buses.index).all()) assert (getattr(partial_network, line_type).bus1.isin( partial_network.buses.index).all()) return partial_network, external_buses