From 361514017b8bc87bf9ec333ccb3f5af09f11c646 Mon Sep 17 00:00:00 2001 From: Rafael M Mudafort Date: Tue, 12 Dec 2023 10:42:29 -0600 Subject: [PATCH] Clean up docstrings and comments --- floris/simulation/floris.py | 9 +-- floris/simulation/grid.py | 6 +- floris/simulation/turbine.py | 81 +++++++++++--------------- floris/simulation/turbine_multi_dim.py | 13 +---- 4 files changed, 39 insertions(+), 70 deletions(-) diff --git a/floris/simulation/floris.py b/floris/simulation/floris.py index a31ef62df..329246ad3 100644 --- a/floris/simulation/floris.py +++ b/floris/simulation/floris.py @@ -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() @@ -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""" @@ -215,9 +214,6 @@ def steady_state_atmospheric_condition(self): vel_model = self.wake.model_strings["velocity_model"] - # <> - # start = time.time() - if vel_model in ["gauss", "cc", "turbopark", "jensen"] and \ self.farm.correct_cp_ct_for_tilt.any(): self.logger.warning( @@ -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 diff --git a/floris/simulation/grid.py b/floris/simulation/grid.py index 3786fc873..42e70289d 100644 --- a/floris/simulation/grid.py +++ b/floris/simulation/grid.py @@ -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. diff --git a/floris/simulation/turbine.py b/floris/simulation/turbine.py index e0db04f81..11b326910 100644 --- a/floris/simulation/turbine.py +++ b/floris/simulation/turbine.py @@ -16,7 +16,7 @@ import copy from collections.abc import Iterable -from typing import Any +from typing import Any, Dict import attrs import numpy as np @@ -529,41 +529,38 @@ def __attrs_post_init__(self) -> None: @define class Turbine(BaseClass): """ - Turbine is a class containing objects pertaining to the individual - turbines. - - Turbine is a model class representing a particular wind turbine. It - is largely a container of data and parameters, but also contains - methods to probe properties for output. - - Parameters: - rotor_diameter (:py:obj: float): The rotor diameter (m). - hub_height (:py:obj: float): The hub height (m). - pP (:py:obj: float): The cosine exponent relating the yaw - misalignment angle to power. - pT (:py:obj: float): The cosine exponent relating the rotor - tilt angle to power. - generator_efficiency (:py:obj: float): The generator - efficiency factor used to scale the power production. - ref_density_cp_ct (:py:obj: float): The density at which the provided - cp and ct is defined - power_thrust_table (PowerThrustTable): A dictionary containing the - following key-value pairs: - - power (:py:obj: List[float]): The coefficient of power at - different wind speeds. - thrust (:py:obj: List[float]): The coefficient of thrust - at different wind speeds. - wind_speed (:py:obj: List[float]): The wind speeds for - which the power and thrust values are provided (m/s). - ngrid (*int*, optional): The square root of the number - of points to use on the turbine grid. This number will be - squared so that the points can be evenly distributed. - Defaults to 5. - rloc (:py:obj: float, optional): A value, from 0 to 1, that determines - the width/height of the grid of points on the rotor as a ratio of - the rotor radius. - Defaults to 0.5. + A class containing the parameters and infrastructure to model a wind turbine's performance + for a particular atmospheric condition. + + Args: + turbine_type (str): An identifier for this type of turbine such as "NREL_5MW". + rotor_diameter (float): The rotor diameter in meters. + hub_height (float): The hub height in meters. + pP (float): The cosine exponent relating the yaw misalignment angle to turbine power. + pT (float): The cosine exponent relating the rotor tilt angle to turbine power. + TSR (float): The Tip Speed Ratio of the turbine. + generator_efficiency (float): The efficiency of the generator used to scale + power production. + ref_density_cp_ct (float): The density at which the provided Cp and Ct curves are defined. + ref_tilt_cp_ct (float): The implicit tilt of the turbine for which the Cp and Ct + curves are defined. This is typically the nacelle tilt. + power_thrust_table (dict[str, float]): Contains power coefficient and thrust coefficient + values at a series of wind speeds to define the turbine performance. + The dictionary must have the following three keys with equal length values: + { + "wind_speeds": List[float], + "power": List[float], + "thrust": List[float], + } + correct_cp_ct_for_tilt (bool): A flag to indicate whether to correct Cp and Ct for tilt. + Optional, defaults to False. + floating_tilt_table (TiltTable): A table containing tilt values for a floating turbine. + Required if `correct_cp_ct_for_tilt = True`, defaults to False. + floating_correct_cp_ct_for_tilt (bool): A flag to indicate whether to correct Cp and Ct + for tilt for a floating turbine. + Optional, defaults to False. + power_thrust_data_file (str): The path to the file containing power and thrust data. + multi_dimensional_cp_ct (bool): A flag to indicate whether Cp and Ct are multi-dimensional. """ turbine_type: str = field() @@ -575,16 +572,13 @@ class Turbine(BaseClass): generator_efficiency: float = field() ref_density_cp_ct: float = field() ref_tilt_cp_ct: float = field() - power_thrust_table: PowerThrustTable = field(default=None) correct_cp_ct_for_tilt: bool = field(default=None) + power_thrust_table: Dict[str, float] = field() floating_tilt_table: TiltTable = field(default=None) floating_correct_cp_ct_for_tilt: bool = field(default=None) power_thrust_data_file: str = field(default=None) multi_dimensional_cp_ct: bool = field(default=False) - # rloc: float = float_attrib() # TODO: goes here or on the Grid? - # use_points_on_perimeter: bool = bool_attrib() - # Initialized in the post_init function rotor_radius: float = field(init=False) rotor_area: float = field(init=False) @@ -595,14 +589,9 @@ class Turbine(BaseClass): fTilt_interp: interp1d = field(init=False) - # For the following parameters, use default values if not user-specified - # self.rloc = float(input_dictionary["rloc"]) if "rloc" in input_dictionary else 0.5 - # if "use_points_on_perimeter" in input_dictionary: - # self.use_points_on_perimeter = bool(input_dictionary["use_points_on_perimeter"]) - # else: - # self.use_points_on_perimeter = False def __attrs_post_init__(self) -> None: + # TODO validate that the wind speed, power, and thrust are floats and all the same size # Post-init initialization for the power curve interpolation functions self.power_thrust_table = PowerThrustTable.from_dict(self.power_thrust_table) diff --git a/floris/simulation/turbine_multi_dim.py b/floris/simulation/turbine_multi_dim.py index 06fd356f4..98370a93e 100644 --- a/floris/simulation/turbine_multi_dim.py +++ b/floris/simulation/turbine_multi_dim.py @@ -431,7 +431,7 @@ class TurbineMultiDimensional(Turbine): whichever is being used to load turbine definitions. Defaults to the internal turbine library. """ - power_thrust_data_file: str = field(default=None) + power_thrust_data_file: str = field(default=None) # TODO This is actually required and should not default to None. However, the super class has optional attributes so a required attribute here breaks power_thrust_data: MultiDimensionalPowerThrustTable = field(default=None) multi_dimensional_cp_ct: bool = field(default=False) turbine_library_path: Path = field( @@ -443,9 +443,6 @@ class TurbineMultiDimensional(Turbine): # Not to be provided by the user condition_keys: list[str] = field(init=False, factory=list) - # rloc: float = float_attrib() # TODO: goes here or on the Grid? - # use_points_on_perimeter: bool = bool_attrib() - # Initialized in the post_init function # rotor_radius: float = field(init=False) # rotor_area: float = field(init=False) @@ -454,14 +451,6 @@ class TurbineMultiDimensional(Turbine): # power_interp: interp1d = field(init=False) # tilt_interp: interp1d = field(init=False) - - # For the following parameters, use default values if not user-specified - # self.rloc = float(input_dictionary["rloc"]) if "rloc" in input_dictionary else 0.5 - # if "use_points_on_perimeter" in input_dictionary: - # self.use_points_on_perimeter = bool(input_dictionary["use_points_on_perimeter"]) - # else: - # self.use_points_on_perimeter = False - def __attrs_post_init__(self) -> None: # Solidify the data file path and name self.power_thrust_data_file = self.turbine_library_path / self.power_thrust_data_file