Source code for foxes.core.wind_farm

import numpy as np

from foxes.config import config


[docs] class WindFarm: """ The wind farm. Attributes ---------- name: str The wind farm name turbines: list of foxes.core.Turbine The wind turbines boundary: foxes.utils.geom2d.AreaGeometry, optional The wind farm boundary :group: core """
[docs] def __init__(self, name="wind_farm", boundary=None): """ Constructor. Parameters ---------- name: str The wind farm name """ self.name = name self.turbines = [] self.boundary = boundary
[docs] def add_turbine(self, turbine, verbosity=1): """ Add a wind turbine to the list. Parameters ---------- turbine: foxes.core.Turbine The wind turbine verbosity: int The output verbosity, 0 = silent """ if turbine.index is None: turbine.index = len(self.turbines) if turbine.name is None: turbine.name = f"T{turbine.index}" self.turbines.append(turbine) if verbosity > 0: print( f"Turbine {turbine.index}, {turbine.name}: xy=({turbine.xy[0]:.2f}, {turbine.xy[1]:.2f}), {', '.join(turbine.models)}" )
@property def n_turbines(self): """ The number of turbines in the wind farm Returns ------- n_turbines: int The total number of turbines """ return len(self.turbines) @property def turbine_names(self): """ The list of names of all turbines Returns ------- names: list of str The names of all turbines """ return [t.name for t in self.turbines] @property def xy_array(self): """ Returns an array of the wind farm ground points Returns ------- xya: numpy.ndarray The turbine ground positions, shape: (n_turbines, 2) """ return np.array([t.xy for t in self.turbines], dtype=config.dtype_double)
[docs] def get_xy_bounds(self, extra_space=None, algo=None): """ Returns min max points of the wind farm ground points Parameters ---------- extra_space: float or str, optional The extra space, either float in m, or str for units of D, e.g. '2.5D' algo: foxes.core.Algorithm, optional The algorithm Returns ------- x_mima: numpy.ndarray The (x_min, x_max) point y_mima: numpy.ndarray The (y_min, y_max) point """ if self.boundary is not None: xy = None p_min, p_max = self.boundary.p_min(), self.boundary.p_max() else: xy = self.xy_array p_min, p_max = np.min(xy, axis=0), np.max(xy, axis=0) if extra_space is not None: if isinstance(extra_space, str): assert ( algo is not None ), f"WindFarm: require algo argument for extra_space '{extra_space}'" assert ( len(extra_space) > 1 and extra_space[-1] == "D" ), f"Expecting float or str like '2.5D', got extra_space = '{extra_space}'" extra_space = float(extra_space[:-1]) rds = self.get_rotor_diameters(algo) if xy is None: extra_space *= np.max(rds) else: p_min = np.min(xy - extra_space * rds[:, None], axis=0) p_max = np.max(xy + extra_space * rds[:, None], axis=0) return p_min, p_max p_min -= extra_space p_max += extra_space return p_min, p_max
[docs] def get_rotor_diameters(self, algo): """ Gets the rotor diameters Parameters ---------- algo: foxes.core.Algorithm The algorithm Returns ------- rds: numpy.ndarray The rotor diameters, shape: (n_turbienes,) """ rds = [ t.D if t.D is not None else algo.farm_controller.turbine_types[i].D for i, t in enumerate(self.turbines) ] return np.array(rds, dtype=config.dtype_double)
[docs] def get_hub_heights(self, algo): """ Gets the hub heights Parameters ---------- algo: foxes.core.Algorithm The algorithm Returns ------- hhs: numpy.ndarray The hub heights, shape: (n_turbienes,) """ hhs = [ t.H if t.H is not None else algo.farm_controller.turbine_types[i].H for i, t in enumerate(self.turbines) ] return np.array(hhs, dtype=config.dtype_double)