Wind rose data

Here we demonstrate how mean results over wind rose data are calculated in foxes. We need the following imports:

%matplotlib inline
import matplotlib.pyplot as plt

import foxes
import foxes.variables as FV
/home/runner/work/foxes/foxes/foxes/core/engine.py:4: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)
  from tqdm.autonotebook import tqdm

First, we create the engine:

engine = foxes.Engine.new("process", chunk_size_states=1000, chunk_size_points=3000)

Next, let’s setup the wind farm. We choose 6 x 5 turbines on a regular grid:

farm = foxes.WindFarm()
foxes.input.farm_layout.add_grid(
    farm=farm,
    xy_base=[0.0, 0.0],
    step_vectors=[[900.0, 50.0], [-80.0, 500.0]],
    steps=[6, 5],
    turbine_models=["NREL5MW", "kTI_05"],
    verbosity=0,
)

ax = foxes.output.FarmLayoutOutput(farm).get_figure(figsize=(4, 3))
plt.show()
../_images/f02bc0327323ad1ddb9932b87fd957ad511041aa95f82b90d4c4d9a74ad4325b.png

Next, we create the states based on the static data file wind_rose_bremen.csv.gz. The data represents a (coarse) wind rose with 216 states. Each of them consists of the wind direction and wind speed bin centres, and the respective statistical weight of the bin (normalized such that 1 represents 100%):

state,wd,ws,weight
0,0.0,3.5,0.00158
1,0.0,6.0,0.00244
2,0.0,8.5,0.00319
3,0.0,12.5,0.0036700002
4,0.0,17.5,0.00042
...

Let’s create the states object and have a look at the wind rose:

states = foxes.input.states.StatesTable(
    data_source="wind_rose_bremen.csv",
    output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
    var2col={FV.WS: "ws", FV.WD: "wd", FV.WEIGHT: "weight"},
    fixed_vars={FV.RHO: 1.225, FV.TI: 0.05},
)

with engine:
    o = foxes.output.StatesRosePlotOutput(states, point=[0.0, 0.0, 100.0])
o.get_figure(16, FV.AMB_WS, [0, 3.5, 6, 10, 15, 20], figsize=(6, 6))
plt.show()
ProcessEngine: Calculating 216 states for 1 turbines
ProcessEngine: Starting calculation using 3 workers.
ProcessEngine: Completed all 1 chunks
../_images/ab29900792f59c7384e3c0c041704d4084aa0391dac95d547a6eb8e8b37df88d.png

We can now setup our algorithm. In this example, we invoke one wake model for the wind deficit, Bastankhah_linear (with linear wake superposition), and another for the turbulence intensity wake effect, CrespoHernandez_max (with maximum wake superposition). Both obtain the wake growth parameter k by a relation k = 0.5 * TI, see turbine_models choice in the wind farm setup. We use default partial wakes for both models, indicated py partial_wakes=None:

algo = foxes.algorithms.Downwind(
    farm,
    states,
    rotor_model="centre",
    wake_models=["Bastankhah2014_linear", "CrespoHernandez_max"],
    partial_wakes=None,
    verbosity=0,
)

We can now calculate the results:

with engine:
    farm_results = algo.calc_farm()

o = foxes.output.FarmResultsEval(farm_results)
o.add_efficiency()

fig, axs = plt.subplots(2, 1, figsize=(6, 7))
o = foxes.output.FarmLayoutOutput(farm, farm_results)
o.get_figure(
    fig=fig,
    ax=axs[0],
    color_by="mean_REWS",
    title="Mean REWS [m/s]",
    s=150,
    annotate=0,
)
o.get_figure(
    fig=fig,
    ax=axs[1],
    color_by="mean_EFF",
    title="Mean efficiency [%]",
    s=150,
    annotate=0,
)
plt.show()

o = foxes.output.FarmResultsEval(farm_results)
P0 = o.calc_mean_farm_power(ambient=True)
P = o.calc_mean_farm_power()
print(f"\nFarm power        : {P / 1000:.1f} MW")
print(f"Farm ambient power: {P0 / 1000:.1f} MW")
print(f"Farm efficiency   : {o.calc_farm_efficiency() * 100:.2f} %")
print(f"Annual farm yield : {o.calc_farm_yield(algo=algo):.2f} GWh")
ProcessEngine: Calculating 216 states for 30 turbines
ProcessEngine: Starting calculation using 3 workers.
ProcessEngine: Completed all 1 chunks
Efficiency added to farm results
../_images/848c365d6ec1181f02cb4928167979dedb72a05757f5979f11760ac68a469054.png
Farm power        : 76.5 MW
Farm ambient power: 81.7 MW
Farm efficiency   : 93.65 %
Annual farm yield : 670.45 GWh

Finally, we display the mean wind speed field as a 2D plot, including wake effects:

with engine:
    o = foxes.output.FlowPlots2D(algo, farm_results)
    plot_data = o.get_mean_data_xy(FV.WS, resolution=30)
o.get_mean_fig_xy(plot_data)
plt.show()
States 'StatesTable': Reading file /home/runner/work/foxes/foxes/foxes/data/states/wind_rose_bremen.csv
ProcessEngine: Calculating data at 21255 points for 216 states
ProcessEngine: Starting calculation using 3 workers, for 1 states chunks and 8 targets chunks.
ProcessEngine: Completed all 8 chunks
../_images/85f862c1d2cb693934aab1db61ae44bf5bfaba2f486da5d4ea4ace8d7b4d76d9.png