Skip to content

Commit

Permalink
Add TKE and TI mixing to GCH (#158)
Browse files Browse the repository at this point in the history
* Updates to the gch model: TKE and TI mixing

* Adding example

* Updated tuning

* Updated mask for V and W

* Bug fix

* Update models

* bugfix in energy ratio example

* Update models

* Apparantly no more writeline function

* Changing opt settings for examples

* change default ti to 6%

* Updating default crespo turbulence values

* Minor cleanup

Co-authored-by: King <jennifer.king@nrel.gov>
Co-authored-by: Paul <paul.fleming@nrel.gov>
Co-authored-by: Rafael M Mudafort <rafmudaf@gmail.com>
  • Loading branch information
4 people committed Sep 25, 2020
1 parent c4ba986 commit 6f19d4b
Show file tree
Hide file tree
Showing 14 changed files with 300 additions and 220 deletions.
2 changes: 1 addition & 1 deletion examples/aep_calculation/compute_aep.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import floris.tools.wind_rose as rose
import floris.tools.power_rose as pr
import floris.tools.visualization as vis
from floris.tools.optimization.scipy.yaw_wind_rose import importYawOptimizationWindRose
from floris.tools.optimization.scipy.yaw_wind_rose import YawOptimizationWindRose


# Instantiate the FLORIS object
Expand Down
Binary file modified examples/compare_models/floris_models.p
Binary file not shown.
2 changes: 1 addition & 1 deletion examples/energy_ratio/demo_energy_ratio.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
# demonstrate how to change coordinates
D = fi.floris.farm.flow_field.turbine_map.turbines[0].rotor_diameter
layout_x = [0, 0, 7 * D]
layout_y = [0, 5 * D, 0, 0]
layout_y = [0, 5 * D, 0]
fi.reinitialize_flow_field(layout_array=(layout_x, layout_y))

# Calculate wake
Expand Down
116 changes: 59 additions & 57 deletions examples/example_input.json
Original file line number Diff line number Diff line change
@@ -1,63 +1,62 @@
{
"type": "floris_input",
"name": "floris_input_file_Example",
"description": "Example FLORIS Input file",
"floris_version": "v2.0.0",
"logging": {
"console": {
"enable": true,
"level": "INFO"
},
"file": {
"enable": false,
"level": "INFO"
}
},
"farm": {
"type": "farm",
"name": "farm_example_2x2",
"description": "Example 2x2 Wind Farm",
"name": "farm_example_2x2",
"properties": {
"wind_speed": [
8.0
],
"wind_direction": [
270.0
],
"turbulence_intensity": [
0.06
],
"wind_shear": 0.12,
"__comment__": "specified_wind_height of -1 uses the first turbine's hub height; After initialization, specified_wind_height is a free parameter.",
"specified_wind_height": -1,
"wind_veer": 0.0,
"air_density": 1.225,
"layout_x": [
0.0
],
"layout_y": [
0.0
],
"specified_wind_height": -1,
"turbulence_intensity": [
0.06
],
"wind_direction": [
270.0
],
"wind_shear": 0.12,
"wind_speed": [
9.0
],
"wind_veer": 0.0,
"wind_x": [
0
],
"wind_y": [
0
]
},
"type": "farm"
},
"floris_version": "v2.0.0",
"logging": {
"console": {
"enable": true,
"level": "INFO"
},
"file": {
"enable": false,
"level": "INFO"
}
},
"name": "floris_input_file_Example",
"turbine": {
"type": "turbine",
"name": "nrel_5mw",
"description": "NREL 5MW",
"name": "nrel_5mw",
"properties": {
"use_points_on_perimeter": false,
"rotor_diameter": 126.0,
"hub_height": 90.0,
"TSR": 8.0,
"blade_count": 3,
"blade_pitch": 0.0,
"generator_efficiency": 1.0,
"hub_height": 90.0,
"ngrid": 5,
"pP": 1.88,
"pT": 1.88,
"generator_efficiency": 1.0,
"power_thrust_table": {
"power": [
0.0,
Expand Down Expand Up @@ -210,47 +209,50 @@
25.5
]
},
"blade_pitch": 0.0,
"yaw_angle": 0.0,
"rloc": 0.5,
"rotor_diameter": 126.0,
"tilt_angle": 0.0,
"TSR": 8.0
}
"use_points_on_perimeter": false,
"yaw_angle": 0.0
},
"type": "turbine"
},
"type": "floris_input",
"wake": {
"type": "wake",
"name": "wake_default",
"description": "wake",
"name": "wake_default",
"properties": {
"velocity_model": "gauss_legacy",
"turbulence_model": "crespo_hernandez",
"deflection_model": "gauss",
"combination_model": "sosfs",
"deflection_model": "gauss",
"parameters": {
"wake_velocity_parameters": {
"gauss_legacy": {
"ka": 0.38,
"kb": 0.004,
"eps_gain": 0.2,
"calculate_VW_velocities": true,
"use_yaw_added_recovery": true
}
},
"wake_deflection_parameters": {
"gauss": {
"dm": 1.0,
"eps_gain": 0.2,
"use_secondary_steering":true
"use_secondary_steering": true
}
},
"wake_turbulence_parameters": {
"crespo_hernandez": {
"initial": 0.1,
"constant": 0.37,
"ai": 0.8,
"downstream": -0.275
"constant": 0.5,
"downstream": -0.32,
"initial": 0.1
}
},
"wake_velocity_parameters": {
"gauss_legacy": {
"calculate_VW_velocities": true,
"eps_gain": 0.2,
"ka": 0.38,
"kb": 0.004,
"use_yaw_added_recovery": true
}
}
}
},
"turbulence_model": "crespo_hernandez",
"velocity_model": "gauss_legacy"
},
"type": "wake"
}
}
}
122 changes: 73 additions & 49 deletions examples/gch_comparisons/five_turbine/test_tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,52 @@
# See read the https://floris.readthedocs.io for documentation


import numpy as np
import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt

import floris.tools as wfct
import numpy as np


print('Running FLORIS with no yaw...')
matplotlib.use("tkagg")


print("Running FLORIS with no yaw...")
# Instantiate the FLORIS object

initial = np.linspace(0.1,0.9,4)
constant = np.linspace(0.1,0.9,4)
ai = np.linspace(0.1,0.9,4)
downstream = np.linspace(0.1,0.9,4)
initial = np.linspace(0.1, 0.9, 4)
constant = np.linspace(0.1, 0.9, 4)
ai = np.linspace(0.1, 0.9, 4)
downstream = np.linspace(0.1, 0.9, 4)

fi = wfct.floris_interface.FlorisInterface("../../example_input.json")

# Set turbine locations to 3 turbines in a row
D = fi.floris.farm.turbines[0].rotor_diameter

l_x = [0,6*D,12*D,18*D,24*D]
l_x = [0, 6 * D, 12 * D, 18 * D, 24 * D]
# l_x = [0,7*D,14*D]
l_y = [0,0,0,0,0]
l_y = [0, 0, 0, 0, 0]

# fi.reinitialize_flow_field(layout_array=(layout_x, layout_y),wind_direction=wind_direction)
fi.reinitialize_flow_field(layout_array=(l_x, l_y),wind_direction=270)
fi.reinitialize_flow_field(layout_array=(l_x, l_y), wind_direction=270)
fi.calculate_wake()

# Initial power output
power_initial = fi.get_farm_power()
print('Initial farm power = ', power_initial)
print("Initial farm power = ", power_initial)
for i in range(len(l_x)):
print('Turbine ', i, ' velocity = ', fi.floris.farm.turbines[i].average_velocity, fi.floris.farm.turbines[i].power/(10**3))
print(
"Turbine ",
i,
" velocity = ",
fi.floris.farm.turbines[i].average_velocity,
fi.floris.farm.turbines[i].power / (10 ** 3),
)


# =============================================================================
print('Finding optimal yaw angles in FLORIS...')
print("Finding optimal yaw angles in FLORIS...")
# =============================================================================
# Set bounds for allowable wake steering
min_yaw = 0.0
Expand All @@ -62,28 +71,37 @@
# Perform optimization
# yaw_angles = yaw_opt.optimize()
# yaw_angles = [24,24,22,16,0]
yaw_angles = [25,25,25,0,0]
yaw_angles = [25, 25, 25, 0, 0]
# yaw_angles = [23.6, 23.2, 21., 18.1, 13.9, 0. ]
# yaw_angles = [20,20,0]
# yaw_angles = [0,0,0,0,0]

fi.reinitialize_flow_field()
print('==========================================')
print("==========================================")
fi.calculate_wake(yaw_angles=yaw_angles)

for i in range(len(l_x)):
print('Turbine ', i, ' velocity = ', fi.floris.farm.turbines[i].average_velocity, fi.floris.farm.turbines[i].power/(10**3))
print(
"Turbine ",
i,
" velocity = ",
fi.floris.farm.turbines[i].average_velocity,
fi.floris.farm.turbines[i].power / (10 ** 3),
)

# Assign yaw angles to turbines and calculate wake
power_opt = fi.get_farm_power()
print('Power initial = ', power_initial/(10**3))
print('Power optimal = ', power_opt/(10**3))
print("Power initial = ", power_initial / (10 ** 3))
print("Power optimal = ", power_opt / (10 ** 3))

print('==========================================')
print('Total Power Gain = %.1f%%' %
(100.*(power_opt - power_initial)/power_initial))
print('==========================================')
print("==========================================")
print(
"Total Power Gain = %.1f%%" % (100.0 * (power_opt - power_initial) / power_initial)
)
print("==========================================")

# =============================================================================
print('Finding optimal yaw angles in FLORIS low ti...')
print("Finding optimal yaw angles in FLORIS low ti...")
# =============================================================================

# Set bounds for allowable wake steering
Expand All @@ -99,53 +117,62 @@

# Perform optimization
# yaw_angles = yaw_opt.optimize()
yaw_angles = [25,25,22,18,0]
# yaw_angles = [25,25,25,0,0]
# yaw_angles = [25,25,22,18,0]
yaw_angles = [25, 25, 25, 0, 0]
# yaw_angles = [20,20,0]
print('==========================================')
# yaw_angles = [0,0,0,0,0]

print("==========================================")
fi.reinitialize_flow_field()
fi.calculate_wake(yaw_angles=yaw_angles)

for i in range(len(l_x)):
print('Turbine ', i, ' velocity = ', fi.floris.farm.turbines[i].average_velocity, fi.floris.farm.turbines[i].power/(10**3))
print(
"Turbine ",
i,
" velocity = ",
fi.floris.farm.turbines[i].average_velocity,
fi.floris.farm.turbines[i].power / (10 ** 3),
)

# Assign yaw angles to turbines and calculate wake
power_opt = fi.get_farm_power()
print('Power initial = ', power_initial/(10**3))
print('Power optimal = ', power_opt/(10**3))
print("Power initial = ", power_initial / (10 ** 3))
print("Power optimal = ", power_opt / (10 ** 3))

print('==========================================')
print('Total Power Gain = %.1f%%' %
(100.*(power_opt - power_initial)/power_initial))
print('==========================================')
print("==========================================")
print(
"Total Power Gain = %.1f%%" % (100.0 * (power_opt - power_initial) / power_initial)
)
print("==========================================")

## For tuning TI model
# For tuning TI model

SB = [2419000., 915100., 945100., 1046200., 1037700., 1077700.]
SOC = [2046400., 1062300., 1239500., 1353700., 1421400., 1761700.]
layout_x = [1145.6, 1791.2, 2436.8, 3082.4, 3728., 4373.6]
SB = [2419000.0, 915100.0, 945100.0, 1046200.0, 1037700.0, 1077700.0]
SOC = [2046400.0, 1062300.0, 1239500.0, 1353700.0, 1421400.0, 1761700.0]
layout_x = [1145.6, 1791.2, 2436.8, 3082.4, 3728.0, 4373.6]
layout_y = [2436.8, 2436.8, 2436.8, 2436.8, 2436.8, 2436.8]
yaw = [23.6, 23.2, 21., 18.1, 13.9, 0. ]
yaw = [23.6, 23.2, 21.0, 18.1, 13.9, 0.0]

# no yaw
fi.reinitialize_flow_field(layout_array=(layout_x,layout_y),turbulence_intensity=0.09)
fi.reinitialize_flow_field(layout_array=(layout_x, layout_y), turbulence_intensity=0.09)
fi.calculate_wake(yaw_angles=np.zeros(len(layout_x)))
GCH_Base = fi.get_turbine_power()

# yaw
fi.reinitialize_flow_field(layout_array=(layout_x,layout_y),turbulence_intensity=0.09)
fi.reinitialize_flow_field(layout_array=(layout_x, layout_y), turbulence_intensity=0.09)
fi.calculate_wake(yaw_angles=yaw)
GCH_opt = fi.get_turbine_power()

plt.figure()
turb = np.linspace(0,5,6)
plt.plot(turb,SB,'ko--',label='sowfa_base')
plt.plot(turb,GCH_Base,'ro--',label='gch_base')
plt.plot(turb,SOC,'ko-',label='sowfa_opt')
plt.plot(turb,GCH_opt,'ro-',label='gch_opt')
turb = np.linspace(0, 5, 6)
plt.plot(turb, SB, "ko--", label="sowfa_base")
plt.plot(turb, GCH_Base, "ro--", label="gch_base")
plt.plot(turb, SOC, "ko-", label="sowfa_opt")
plt.plot(turb, GCH_opt, "ro-", label="gch_opt")
plt.grid()
plt.legend()
plt.title('Baseline Power (middle row)')
plt.title("Baseline Power (middle row)")

# # Get horizontal plane at default height (hub-height)
# hor_plane = fi.get_hor_plane()
Expand All @@ -154,6 +181,3 @@
# fig, ax = plt.subplots()
# wfct.visualization.visualize_cut_plane(hor_plane, ax=ax)
plt.show()



Binary file modified examples/sowfa_comparisons/floris_models.p
Binary file not shown.
Loading

0 comments on commit 6f19d4b

Please sign in to comment.