{
"cells": [
{
"cell_type": "markdown",
"id": "9049fef9",
"metadata": {},
"source": [
"# Example 6: Getting Expected Power and AEP"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0f987b29",
"metadata": {},
"outputs": [],
"source": [
"\"\"\"Example 6: Getting Expected Power and AEP\n",
"\n",
"The expected power of a farm is computed by multiplying the power output of the farm by the\n",
"frequency of each findex. This is done by the `get_expected_farm_power` method. The expected\n",
"AEP is annual energy production is computed by multiplying the expected power by the number of\n",
"hours in a year.\n",
"\n",
"If a wind_data object is provided to the model, the expected power and AEP\n",
" can be computed directly by the`get_farm_AEP_with_wind_data` using the frequency table\n",
" of the wind data object. If not, a frequency table must be passed into these functions\n",
"\n",
"\n",
"\"\"\"\n",
"\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"from floris import (\n",
" FlorisModel,\n",
" TimeSeries,\n",
" WindRose,\n",
")\n",
"\n",
"\n",
"fmodel = FlorisModel(\"inputs/gch.yaml\")\n",
"\n",
"\n",
"# Set to a 3-turbine layout\n",
"D = 126.\n",
"fmodel.set(layout_x=[0.0, 5 * D, 10 * D],\n",
" layout_y=[0.0, 0.0, 0.0])\n",
"\n",
"# Using TimeSeries\n",
"\n",
"# Randomly generated a time series with time steps = 365 * 24\n",
"N = 365 * 24\n",
"wind_directions = np.random.uniform(0, 360, N)\n",
"wind_speeds = np.random.uniform(5, 25, N)\n",
"\n",
"# Set up a time series\n",
"time_series = TimeSeries(\n",
" wind_directions=wind_directions, wind_speeds=wind_speeds, turbulence_intensities=0.06\n",
")\n",
"\n",
"# Set the wind data\n",
"fmodel.set(wind_data=time_series)\n",
"\n",
"# Run the model\n",
"fmodel.run()\n",
"\n",
"expected_farm_power = fmodel.get_expected_farm_power()\n",
"aep = fmodel.get_farm_AEP()\n",
"\n",
"# Note this is equivalent to the following\n",
"aep_b = fmodel.get_farm_AEP(freq=time_series.unpack_freq())\n",
"\n",
"print(f\"AEP from time series: {aep}, and re-computed AEP: {aep_b}\")\n",
"\n",
"# Using WindRose==============================================\n",
"\n",
"# Load the wind rose from csv as in example 003\n",
"wind_rose = WindRose.read_csv_long(\n",
" \"inputs/wind_rose.csv\", wd_col=\"wd\", ws_col=\"ws\", freq_col=\"freq_val\", ti_col_or_value=0.06\n",
")\n",
"\n",
"\n",
"# Store some values\n",
"n_wd = len(wind_rose.wind_directions)\n",
"n_ws = len(wind_rose.wind_speeds)\n",
"\n",
"# Store the number of elements of the freq_table which are 0\n",
"n_zeros = np.sum(wind_rose.freq_table == 0)\n",
"\n",
"# Set the wind rose\n",
"fmodel.set(wind_data=wind_rose)\n",
"\n",
"# Run the model\n",
"fmodel.run()\n",
"\n",
"# Note that the frequency table contains 0 frequency for some wind directions and wind speeds\n",
"# and we've not selected to compute 0 frequency bins, therefore the n_findex will be less than\n",
"# the total number of wind directions and wind speed combinations\n",
"print(f\"Total number of wind direction and wind speed combination: {n_wd * n_ws}\")\n",
"print(f\"Number of 0 frequency bins: {n_zeros}\")\n",
"print(f\"n_findex: {fmodel.n_findex}\")\n",
"\n",
"# Get the AEP\n",
"aep = fmodel.get_farm_AEP()\n",
"\n",
"# Print the AEP\n",
"print(f\"AEP from wind rose: {aep/1E9:.3f} (GWh)\")\n",
"\n",
"# Run the model again, without wakes, and use the result to compute the wake losses\n",
"fmodel.run_no_wake()\n",
"\n",
"# Get the AEP without wake\n",
"aep_no_wake = fmodel.get_farm_AEP()\n",
"\n",
"# Compute the wake losses\n",
"wake_losses = 100 * (aep_no_wake - aep) / aep_no_wake\n",
"\n",
"# Print the wake losses\n",
"print(f\"Wake losses: {wake_losses:.2f}%\")\n",
"import warnings\n",
"warnings.filterwarnings('ignore')"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}