Skip to content

Commit

Permalink
Clean up and align Turbine and TurbineMultiDim class architectures (#762
Browse files Browse the repository at this point in the history
)

* Clean up docstrings and comments

* Update code quality docs to include v3.5

* Consolidate fTilt_interp and tilt_interp

It’s not clear why both exist, but they seem to be redundant so I’ve removed fTilt_interp in favor of tilt_interp

* Remove fCp_interp in favor of power_interp

* Remove PowerThrustTable class

Ultimately, it wasn’t used aside from validating the input data. That has been included through the attrs validator.

* Fix type hints and docstrings

* Propogate turbine tilt_interp name change

* Remove TiltTable class and replace with dict

* Consolidate redundant tilt-correction flags

* Fix tilt interpolation dictionary type

* Set NUM_EPS to frozen attribute

* Change tilt table key to wind_speed

All other keys use the singular version rather than the plural version, so this keeps it consistent

* Improve validation of tilt table data

* Align TurbineMultiDim with Turbine changes

* ruff formatting

* Fix example API
  • Loading branch information
rafmudaf authored Dec 13, 2023
1 parent da61128 commit bbcb8c3
Show file tree
Hide file tree
Showing 32 changed files with 423 additions and 499 deletions.
153 changes: 84 additions & 69 deletions docs/code_quality.ipynb

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions examples/18_check_turbine.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@

# Plot cp and ct onto the fig_cp_ct plot
axarr_cp_ct[0].plot(
fi.floris.farm.turbine_map[0].power_thrust_table.wind_speed,
fi.floris.farm.turbine_map[0].power_thrust_table.power,label=t
fi.floris.farm.turbine_map[0].power_thrust_table["wind_speed"],
fi.floris.farm.turbine_map[0].power_thrust_table["power"],label=t
)
axarr_cp_ct[0].grid(True)
axarr_cp_ct[0].legend()
axarr_cp_ct[0].set_ylabel('Cp')
axarr_cp_ct[1].plot(
fi.floris.farm.turbine_map[0].power_thrust_table.wind_speed,
fi.floris.farm.turbine_map[0].power_thrust_table.thrust,label=t
fi.floris.farm.turbine_map[0].power_thrust_table["wind_speed"],
fi.floris.farm.turbine_map[0].power_thrust_table["thrust"],label=t
)
axarr_cp_ct[1].grid(True)
axarr_cp_ct[1].legend()
Expand Down
6 changes: 3 additions & 3 deletions examples/24_floating_turbine_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


"""
This example demonstrates the impact of floating on turbine power and thurst (not wake behavior).
This example demonstrates the impact of floating on turbine power and thrust (not wake behavior).
A floating turbine in FLORIS is defined by including a `floating_tilt_table` in the turbine
input yaml which sets the steady tilt angle of the turbine based on wind speed. This tilt angle
is computed for each turbine based on effective velocity. This tilt angle is then passed on
Expand All @@ -29,10 +29,10 @@
The value of the parameter ref_tilt_cp_ct is the value of tilt at which the ct/cp curves
have been defined.
If floating_correct_cp_ct_for_tilt is True, then the difference between the current tilt as
If `correct_cp_ct_for_tilt` is True, then the difference between the current tilt as
interpolated from the floating tilt table is used to scale the turbine power and thrust.
If floating_correct_cp_ct_for_tilt is False, then it is assumed that the Cp/Ct tables provided
If `correct_cp_ct_for_tilt` is False, then it is assumed that the Cp/Ct tables provided
already account for the variation in tilt with wind speed (for example they were computed from
a turbine simulator with tilt degree-of-freedom enabled and the floating platform simulated),
and no correction is made.
Expand Down
2 changes: 1 addition & 1 deletion examples/29_floating_vs_fixedbottom_farm.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
The value of the parameter ref_tilt_cp_ct is the value of tilt at which the
ct/cp curves have been defined.
With floating_correct_cp_ct_for_tilt True, the difference between the current
With `correct_cp_ct_for_tilt` True, the difference between the current
tilt as interpolated from the floating tilt table is used to scale the turbine
power and thrust.
Expand Down
15 changes: 14 additions & 1 deletion examples/inputs_floating/turbine_files/nrel_5MW_fixed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rotor_diameter: 126.0
TSR: 8.0
ref_density_cp_ct: 1.225
ref_tilt_cp_ct: 5.0
floating_correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
power_thrust_table:
power:
- 0.0
Expand Down Expand Up @@ -165,3 +165,16 @@ power_thrust_table:
- 25.01
- 25.02
- 50.0
floating_tilt_table:
tilt:
- 5.0
- 5.0
- 5.0
- 5.0
- 5.0
wind_speed:
- 0.0
- 4.0
- 11.0
- 25.0
- 50.0
4 changes: 2 additions & 2 deletions examples/inputs_floating/turbine_files/nrel_5MW_floating.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rotor_diameter: 126.0
TSR: 8.0
ref_density_cp_ct: 1.225
ref_tilt_cp_ct: 5.0
floating_correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
power_thrust_table:
power:
- 0.0
Expand Down Expand Up @@ -172,7 +172,7 @@ floating_tilt_table:
- 9.0
- 5.0
- 5.0
wind_speeds:
wind_speed:
- 0.0
- 4.0
- 11.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rotor_diameter: 126.0
TSR: 8.0
ref_density_cp_ct: 1.225
ref_tilt_cp_ct: 5.0
floating_correct_cp_ct_for_tilt: False # Do not apply tilt correction to cp/ct
correct_cp_ct_for_tilt: False # Do not apply tilt correction to cp/ct
power_thrust_table:
power:
- 0.0
Expand Down Expand Up @@ -172,7 +172,7 @@ floating_tilt_table:
- 9.0
- 5.0
- 5.0
wind_speeds:
wind_speed:
- 0.0
- 4.0
- 11.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rotor_diameter: 126.0
TSR: 8.0
ref_density_cp_ct: 1.225
ref_tilt_cp_ct: 5.0
floating_correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
power_thrust_table:
power:
- 0.0
Expand Down Expand Up @@ -172,7 +172,7 @@ floating_tilt_table:
- 15.0
- 15.0
- 15.0
wind_speeds:
wind_speed:
- 0.0
- 4.0
- 11.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rotor_diameter: 126.0
TSR: 8.0
ref_density_cp_ct: 1.225
ref_tilt_cp_ct: 5.0
floating_correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
correct_cp_ct_for_tilt: True # Apply tilt correction to cp/ct
power_thrust_table:
power:
- 0.0
Expand Down Expand Up @@ -172,7 +172,7 @@ floating_tilt_table:
- 5.0
- 5.0
- 5.0
wind_speeds:
wind_speed:
- 0.0
- 4.0
- 11.0
Expand Down
1 change: 0 additions & 1 deletion floris/simulation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
Ct,
power,
rotor_effective_velocity,
TiltTable,
Turbine
)
from .turbine_multi_dim import (
Expand Down
8 changes: 2 additions & 6 deletions floris/simulation/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
define,
field,
fields,
setters,
)

from floris.logging_manager import LoggingManager
Expand Down Expand Up @@ -66,12 +67,7 @@ class BaseModel(BaseClass):
"""

# This is a numerical epsilon to prevent divide by zeros
NUM_EPS: Final[float] = field(init=False, default=0.001)

@NUM_EPS.validator
def lock_num_eps(self, attribute: Attribute, value: Any) -> None:
if value != 0.001:
raise ValueError("NUM_EPS should remain a fixed value. Don't change this!")
NUM_EPS: Final[float] = field(init=False, default=0.001, on_setattr=setters.frozen)

@abstractmethod
def prepare_function() -> dict:
Expand Down
10 changes: 6 additions & 4 deletions floris/simulation/farm.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class Farm(BaseClass):
turbine_fCts: Dict[str, interp1d] | List[interp1d] = field(init=False, factory=list)
turbine_fCts_sorted: NDArrayFloat = field(init=False, factory=list)

turbine_fTilts: list = field(init=False, factory=list)
turbine_tilt_interps: dict[str, interp1d] = field(init=False, factory=dict)

yaw_angles: NDArrayFloat = field(init=False)
yaw_angles_sorted: NDArrayFloat = field(init=False)
Expand Down Expand Up @@ -298,8 +298,10 @@ def construct_turbine_fCts(self):
def construct_multidim_turbine_fCts(self):
self.turbine_fCts = [turb.fCt_interp for turb in self.turbine_map]

def construct_turbine_fTilts(self):
self.turbine_fTilts = [(turb.turbine_type, turb.fTilt_interp) for turb in self.turbine_map]
def construct_turbine_tilt_interps(self):
self.turbine_tilt_interps = {
turb.turbine_type: turb.tilt_interp for turb in self.turbine_map
}

def construct_turbine_power_interps(self):
self.turbine_power_interps = {
Expand Down Expand Up @@ -423,7 +425,7 @@ def calculate_tilt_for_eff_velocities(self, rotor_effective_velocities):
tilt_angles = compute_tilt_angles_for_floating_turbines(
self.turbine_type_map_sorted,
self.tilt_angles_sorted,
self.turbine_fTilts,
self.turbine_tilt_interps,
rotor_effective_velocities,
)
return tilt_angles
Expand Down
11 changes: 2 additions & 9 deletions floris/simulation/floris.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def __attrs_post_init__(self) -> None:

self.check_deprecated_inputs()

# Initialize farm quanitities that depend on other objects
# Initialize farm quantities that depend on other objects
self.farm.construct_turbine_map()
if self.wake.model_strings['velocity_model'] == 'multidim_cp_ct':
self.farm.construct_multidim_turbine_fCts()
Expand All @@ -96,7 +96,7 @@ def __attrs_post_init__(self) -> None:
self.farm.construct_turbine_pTs()
self.farm.construct_turbine_ref_density_cp_cts()
self.farm.construct_turbine_ref_tilt_cp_cts()
self.farm.construct_turbine_fTilts()
self.farm.construct_turbine_tilt_interps()
self.farm.construct_turbine_correct_cp_ct_for_tilt()
self.farm.set_yaw_angles(self.flow_field.n_wind_directions, self.flow_field.n_wind_speeds)
self.farm.set_tilt_to_ref_tilt(
Expand Down Expand Up @@ -195,7 +195,6 @@ def check_deprecated_inputs(self):
"\n\n".join(error_messages)
)

# @profile
def initialize_domain(self):
"""Initialize solution space prior to wake calculations"""

Expand All @@ -215,9 +214,6 @@ def steady_state_atmospheric_condition(self):

vel_model = self.wake.model_strings["velocity_model"]

# <<interface>>
# start = time.time()

if vel_model in ["gauss", "cc", "turbopark", "jensen"] and \
self.farm.correct_cp_ct_for_tilt.any():
self.logger.warning(
Expand Down Expand Up @@ -261,11 +257,8 @@ def steady_state_atmospheric_condition(self):
self.grid,
self.wake
)
# end = time.time()
# elapsed_time = end - start

self.finalize()
# return elapsed_time

def solve_for_viz(self):
# Do the calculation with the TurbineGrid for a single wind speed
Expand Down
6 changes: 2 additions & 4 deletions floris/simulation/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ class Grid(ABC, BaseClass):
"""
Grid should establish domain bounds based on given criteria,
and develop three arrays to contain components of the grid
locations in space.
This could be generalized to any number of dimensions to be
used by perhaps a turbulence field.
locations in space. This could be generalized to any number
of dimensions to be used by perhaps a turbulence field.
The grid will have to be reestablished for each wind direction since the planform
area of the farm will be different.
Expand Down
Loading

0 comments on commit bbcb8c3

Please sign in to comment.