|
| 1 | +# Copyright 2022 NREL |
| 2 | + |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| 4 | +# use this file except in compliance with the License. You may obtain a copy of |
| 5 | +# the License at http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | + |
| 7 | +# Unless required by applicable law or agreed to in writing, software |
| 8 | +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 9 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 10 | +# License for the specific language governing permissions and limitations under |
| 11 | +# the License. |
| 12 | + |
| 13 | +# See https://floris.readthedocs.io for documentation |
| 14 | + |
| 15 | + |
| 16 | +import numpy as np |
| 17 | +import pandas as pd |
| 18 | +from floris.tools import FlorisInterface |
| 19 | +import matplotlib.pyplot as plt |
| 20 | + |
| 21 | +""" |
| 22 | +This example demonstrates how to use turbine_wieghts to define a set of turbines belonging to a neighboring farm which |
| 23 | +impacts the power production of the farm under consideration via wake losses, but whose own power production is not |
| 24 | +considered in farm power / aep production |
| 25 | +
|
| 26 | +The use of neighboring farms in the context of wake steering design is considered in example examples/10_optimize_yaw_with_neighboring_farm.py |
| 27 | +""" |
| 28 | + |
| 29 | + |
| 30 | +# Instantiate FLORIS using either the GCH or CC model |
| 31 | +fi = FlorisInterface("inputs/gch.yaml") # GCH model matched to the default "legacy_gauss" of V2 |
| 32 | + |
| 33 | +# Define a 4 turbine farm turbine farm |
| 34 | +D = 126. |
| 35 | +layout_x = np.array([0, D*6, 0, D*6]) |
| 36 | +layout_y = [0, 0, D*3, D*3] |
| 37 | +fi.reinitialize(layout_x = layout_x, layout_y = layout_y) |
| 38 | + |
| 39 | +# Define a simple wind rose with just 1 wind speed |
| 40 | +wd_array = np.arange(0,360,4.) |
| 41 | +fi.reinitialize(wind_directions=wd_array, wind_speeds=[8.]) |
| 42 | + |
| 43 | + |
| 44 | +# Calculate |
| 45 | +fi.calculate_wake() |
| 46 | + |
| 47 | +# Collect the farm power |
| 48 | +farm_power_base = fi.get_farm_power() / 1E3 # In kW |
| 49 | + |
| 50 | +# Add a neighbor to the east |
| 51 | +layout_x = np.array([0, D*6, 0, D*6, D*12, D*15, D*12, D*15]) |
| 52 | +layout_y = np.array([0, 0, D*3, D*3, 0, 0, D*3, D*3]) |
| 53 | +fi.reinitialize(layout_x = layout_x, layout_y = layout_y) |
| 54 | + |
| 55 | +# Define the weights to exclude the neighboring farm from calcuations of power |
| 56 | +turbine_weights = np.zeros(len(layout_x), dtype=int) |
| 57 | +turbine_weights[0:4] = 1.0 |
| 58 | + |
| 59 | +# Calculate |
| 60 | +fi.calculate_wake() |
| 61 | + |
| 62 | +# Collect the farm power with the neightbor |
| 63 | +farm_power_neighbor = fi.get_farm_power(turbine_weights=turbine_weights) / 1E3 # In kW |
| 64 | + |
| 65 | +# Show the farms |
| 66 | +fig, ax = plt.subplots() |
| 67 | +ax.scatter(layout_x[turbine_weights==1],layout_y[turbine_weights==1], color='k',label='Base Farm') |
| 68 | +ax.scatter(layout_x[turbine_weights==0],layout_y[turbine_weights==0], color='r',label='Neighboring Farm') |
| 69 | +ax.legend() |
| 70 | + |
| 71 | +# Plot the power difference |
| 72 | +fig, ax = plt.subplots() |
| 73 | +ax.plot(wd_array,farm_power_base,color='k',label='Farm Power (no neighbor)') |
| 74 | +ax.plot(wd_array,farm_power_neighbor,color='r',label='Farm Power (neighboring farm due east)') |
| 75 | +ax.grid(True) |
| 76 | +ax.legend() |
| 77 | +ax.set_xlabel('Wind Direction (deg)') |
| 78 | +ax.set_ylabel('Power (kW)') |
| 79 | +plt.show() |
0 commit comments