Note
Go to the end to download the full example code.
Estimate Net AEP and P90 AEP
Example of estimating the Net AEP and P90 AEP using a loss table and an uncertainty table. For a more detailed overview see PyWAsP Tutorial 6.
We part from the fact that user has already calculated the Potential AEP and the Gross AEP.
import pywasp as pw
import windkit as wk
import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
from scipy.stats import norm
from pathlib import Path
data_dir = Path("../../../modules/examples/tutorial_1/data/")
gross_aep = xr.open_dataset(data_dir / "aep_nowake.nc")
potential_aep = xr.open_dataset(data_dir / "aep_park2.nc")
wtg = wk.read_wtg(data_dir / "Bonus_1_MW.wtg")
Losses towards P50 - Importing a loss table
loss_table = wk.get_loss_table("dtu_default")
# Modify loss values as needed
loss_table.loc[0, "loss_percentage"] = 0.5
loss_table.loc[2, "loss_percentage"] = 0.1
print(loss_table.head())
loss_name ... description
0 turbine_availability ... Turbine availability losses, including downtim...
1 balance_plant_availability ... Balance of plant availability losses, includin...
2 grid_availability ... Grid availability losses, excluding curtailmen...
3 electrical_operation ... Electrical losses, including transformer and c...
4 wf_consumption ... Wind farm consumption losses, including auxili...
[5 rows x 7 columns]
Losses towards P50 - Calculating the Net AEP
net_aep = pw.net_aep(loss_table, potential_aep)
print("Net AEP:", net_aep["net_aep"].values.sum(), "GWh")
Net AEP: 39.19268893208979 GWh
Uncertainties towards P90 - Importing a uncertainty table
uncertainty_table = wk.get_uncertainty_table()
print(uncertainty_table.head())
print(uncertainty_table.tail())
uncertainty_kind ... description
0 wind ... Uncertainty associated with the statistical re...
1 wind ... Uncertainty associated with the accuracy or re...
2 wind ... Uncertainty associated with the MCP process, i...
3 wind ... Uncertainty associated with the representative...
4 wind ... Uncertainty associated with gap-filling missin...
[5 rows x 8 columns]
uncertainty_kind ... description
29 energy ... Uncertainty associated with exposure changes l...
30 energy ... Uncertainty associated with load curtailment l...
31 energy ... Uncertainty associated with grid curtailment l...
32 energy ... Uncertainty associated with environmental curt...
33 energy ... Uncertainty associated with operational strate...
[5 rows x 8 columns]
Note
Terms that are part of the “energy” kind are those related to the uncertainties of the technical losses. Terms that are part of the “wind” kind are those related to the uncertainties of the predicted wind climate.
Uncertainties towards P90 - Calculating the Px yield
Note
For a P90 value, x = 90.
p90 = pw.px_aep(uncertainty_table, net_aep, sensitivity_factor=1.5, percentile=90)
print("The P90 is:", p90["P_90_aep"].values.sum(), "Gwh")
The P90 is: 34.81814675313252 Gwh
tot_sigma, _, _ = wk.total_uncertainty(uncertainty_table, 1.5)
p50 = np.round(net_aep["net_aep"].values.sum(), 2)
sigma_tot_dimensional = np.round(tot_sigma / 100 * p50, 2)
plt.figure(figsize=(14, 6))
x = np.linspace(15, 60, 100)
plt.axvline(
gross_aep["gross_aep"].values.sum(),
color="k",
linestyle="-.",
linewidth=2,
label="Gross AEP mean",
)
plt.axvline(
potential_aep["potential_aep"].values.sum(),
color="b",
linestyle="--",
alpha=0.7,
linewidth=2,
label="Potential AEP mean",
)
plt.axvline(p50, color="r", linestyle="solid", linewidth=2, label="P50")
plt.axvline(
p50 + sigma_tot_dimensional,
color="r",
linestyle="dashed",
linewidth=1,
label="P50 -+ σ",
)
plt.axvline(p50 - sigma_tot_dimensional, color="r", linestyle="dashed", linewidth=1)
plt.axvline(
p90["P_90_aep"].values.sum(), color="g", linestyle="-.", linewidth=1.5, label="P90"
)
pdf = norm.pdf(x, p50, sigma_tot_dimensional)
plt.plot(x, pdf, color="r", linewidth=2, alpha=0.5)
plt.grid(True)
plt.legend()
plt.title("Gaussian distributio of the AEP")
plt.xlabel("AEP [GWh]")

Text(0.5, 36.72222222222221, 'AEP [GWh]')
Total running time of the script: (0 minutes 0.179 seconds)