Skip to content

Prepare network common

add high voltage connections as links in the lossy transport model (see Neumann et al)

Parameters:

Name Type Description Default
network Network

the pypsa network

required
config dict

the configuration dictionary

required
n_years int

the number of years for discounting

required
Source code in workflow/scripts/prepare_network_common.py
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
def add_HV_links(network: pypsa.Network, config: dict, n_years: int):
    """add high voltage connections as links in the lossy transport model (see Neumann et al)

    Args:
        network (pypsa.Network): the pypsa network
        config (dict): the configuration dictionary
        n_years (int): the number of years for discounting
    """

    edge_path = config["edge_paths"].get(config["scenario"]["topology"], None)
    if edge_path is None:
        raise ValueError(f"No grid found for topology {config['scenario']['topology']}")
    else:
        edges = pd.read_csv(
            edge_path, sep=",", header=None, names=["bus0", "bus1", "p_nom"]
        ).fillna(0)

    # fix this to use map with x.y
    lengths = NON_LIN_PATH_SCALING * np.array(
        [
            haversine(
                [network.buses.at[bus0, "x"], network.buses.at[bus0, "y"]],
                [network.buses.at[bus1, "x"], network.buses.at[bus1, "y"]],
            )
            for bus0, bus1 in edges[["bus0", "bus1"]].values
        ]
    )

    cc = (
        (config["line_cost_factor"] * lengths * [HVAC_cost_curve(len_) for len_ in lengths])
        * LINE_SECURITY_MARGIN
        * FOM_LINES
        * n_years
        * annuity(ECON_LIFETIME_LINES, config["costs"]["discountrate"])
    )

    network.add(
        "Link",
        edges["bus0"] + "-" + edges["bus1"],
        p_nom=edges["p_nom"].values,
        p_nom_min=edges["p_nom"].values,
        bus0=edges["bus0"].values,
        bus1=edges["bus1"].values,
        p_nom_extendable=True,
        p_min_pu=-1,
        length=lengths,
        capital_cost=cc,
    )

calc_renewable_pu_avail(renewable_ds, planning_year, snapshots)

calaculate the renewable per unit availability

Parameters:

Name Type Description Default
renewable_ds Dataset

the renewable dataset from build_renewable_potential

required
planning_year int

the investment year

required
snapshots Index

the network snapshots

required
Source code in workflow/scripts/prepare_network_common.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def calc_renewable_pu_avail(
    renewable_ds: xr.Dataset, planning_year: int, snapshots: pd.Index
) -> pd.DataFrame:
    """calaculate the renewable per unit availability

    Args:
        renewable_ds (xr.Dataset): the renewable dataset from build_renewable_potential
        planning_year (int): the investment year
        snapshots (pd.Index): the network snapshots
    """
    rnwable_p_max_pu = renewable_ds["profile"].transpose("time", "bus").to_pandas()
    rnwable_p_max_pu = shift_profile_to_planning_year(rnwable_p_max_pu, planning_year)
    if not (snapshots.isin(rnwable_p_max_pu.index)).all():
        err = "Snapshots do not match renewable data profile data:"
        err += f"\n\tmissing {snapshots.difference(rnwable_p_max_pu.index)}.\n"
        tip = "You may may need to regenerate your cutout or adapt the snapshots"
        raise ValueError(err + tip)
    rnwable_p_max_pu = rnwable_p_max_pu.loc[snapshots]
    return rnwable_p_max_pu.sort_index(axis=1)