Source code for foxes.algorithms.downwind.models.init_farm_data

import numpy as np

from foxes.core import FarmDataModel, TData
import foxes.variables as FV
import foxes.constants as FC
from foxes.config import config


[docs] class InitFarmData(FarmDataModel): """ Sets basic turbine data and applies downwind order :group: algorithms.downwind.models """
[docs] def __init__(self): """ Constructor. """ super().__init__(pre_rotor=True)
[docs] def output_farm_vars(self, algo): """ The variables which are being modified by the model. Parameters ---------- algo: foxes.core.Algorithm The calculation algorithm Returns ------- output_vars: list of str The output variable names """ return [ FV.X, FV.Y, FV.H, FV.D, FV.WD, FV.YAW, FV.ORDER, FV.WEIGHT, FV.ORDER_SSEL, FV.ORDER_INV, ]
[docs] def calculate(self, algo, mdata, fdata): """ The main model calculation. This function is executed on a single chunk of data, all computations should be based on numpy arrays. Parameters ---------- algo: foxes.core.Algorithm The calculation algorithm mdata: foxes.core.Data The model data fdata: foxes.core.Data The farm data Returns ------- results: dict The resulting data, keys: output variable str. Values: numpy.ndarray with shape (n_states, n_turbines) """ # prepare: n_states = fdata.n_states n_turbines = algo.n_turbines # define FV.TXYH as vector [X, Y, H]: fdata[FV.TXYH] = np.full( (n_states, n_turbines, 3), np.nan, dtype=config.dtype_double ) fdata.dims[FV.TXYH] = (FC.STATE, FC.TURBINE, FC.XYH) for i, v in enumerate([FV.X, FV.Y, FV.H]): fdata[v] = fdata[FV.TXYH][..., i] fdata.dims[v] = (FC.STATE, FC.TURBINE) # set X, Y, H, D: fdata[FV.D] = np.zeros((n_states, n_turbines), dtype=config.dtype_double) for ti, t in enumerate(algo.farm.turbines): if len(t.xy.shape) == 1: fdata[FV.TXYH][:, ti, :2] = t.xy[None, :] else: i0 = fdata.states_i0(counter=True) s = np.s_[i0 : i0 + fdata.n_states] fdata[FV.TXYH][:, ti, :2] = t.xy[s] H = t.H if H is None: H = algo.farm_controller.turbine_types[ti].H fdata[FV.TXYH][:, ti, 2] = H D = t.D if D is None: D = algo.farm_controller.turbine_types[ti].D fdata[FV.D][:, ti] = D # calc WD and YAW at rotor centres: tdata = TData.from_points(points=fdata[FV.TXYH]) sres = algo.states.calculate(algo, mdata, fdata, tdata) fdata[FV.WD] = sres[FV.WD][:, :, 0] del tdata, sres # calculate and inverse: order = algo.wake_frame.calc_order(algo, mdata, fdata) ssel = np.zeros_like(order) ssel[:] = np.arange(n_states)[:, None] fdata[FV.ORDER] = order fdata[FV.ORDER_SSEL] = ssel fdata[FV.ORDER_INV] = np.zeros_like(order) fdata[FV.ORDER_INV][ssel, order] = np.arange(n_turbines)[None, :] # apply downwind order to all data: fdata[FV.TXYH] = fdata[FV.TXYH][ssel, order] for i, v in enumerate([FV.X, FV.Y, FV.H]): fdata[v] = fdata[FV.TXYH][..., i] for v in [FV.D, FV.WD, FV.WEIGHT]: if np.any(fdata[v] != fdata[v][0, 0, None, None]): fdata[v] = fdata[v][ssel, order] fdata[FV.YAW] = fdata[FV.WD].copy() for k in mdata.keys(): if tuple(mdata.dims[k][:2]) == (FC.STATE, FC.TURBINE) and np.any( mdata[k] != mdata[k][0, 0, None, None] ): mdata[k] = mdata[k][ssel, order] return {v: fdata[v] for v in self.output_farm_vars(algo)}