foxes 1.3__py3-none-any.whl → 1.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of foxes might be problematic. Click here for more details.

Files changed (190) hide show
  1. docs/source/conf.py +3 -3
  2. examples/abl_states/run.py +2 -2
  3. examples/compare_rotors_pwakes/run.py +1 -1
  4. examples/compare_wakes/run.py +1 -2
  5. examples/dyn_wakes/run.py +29 -6
  6. examples/induction/run.py +3 -3
  7. examples/multi_height/run.py +1 -1
  8. examples/power_mask/run.py +2 -2
  9. examples/quickstart/run.py +0 -1
  10. examples/random_timeseries/run.py +3 -4
  11. examples/scan_row/run.py +3 -3
  12. examples/sequential/run.py +33 -10
  13. examples/single_state/run.py +3 -4
  14. examples/states_lookup_table/run.py +3 -3
  15. examples/streamline_wakes/run.py +27 -4
  16. examples/tab_file/run.py +3 -3
  17. examples/timelines/run.py +29 -5
  18. examples/timeseries/run.py +3 -3
  19. examples/timeseries_slurm/run.py +3 -3
  20. examples/wind_rose/run.py +3 -3
  21. examples/yawed_wake/run.py +16 -8
  22. foxes/__init__.py +21 -17
  23. foxes/algorithms/__init__.py +6 -6
  24. foxes/algorithms/downwind/__init__.py +2 -2
  25. foxes/algorithms/downwind/downwind.py +44 -12
  26. foxes/algorithms/downwind/models/__init__.py +6 -6
  27. foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
  28. foxes/algorithms/downwind/models/init_farm_data.py +0 -1
  29. foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
  30. foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
  31. foxes/algorithms/iterative/__init__.py +7 -3
  32. foxes/algorithms/iterative/iterative.py +1 -2
  33. foxes/algorithms/iterative/models/__init__.py +7 -3
  34. foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
  35. foxes/algorithms/sequential/__init__.py +3 -3
  36. foxes/algorithms/sequential/models/__init__.py +2 -2
  37. foxes/algorithms/sequential/sequential.py +3 -4
  38. foxes/config/__init__.py +5 -1
  39. foxes/constants.py +16 -0
  40. foxes/core/__init__.py +45 -22
  41. foxes/core/algorithm.py +0 -1
  42. foxes/core/data.py +19 -18
  43. foxes/core/engine.py +9 -13
  44. foxes/core/farm_controller.py +2 -2
  45. foxes/core/ground_model.py +4 -13
  46. foxes/core/model.py +5 -5
  47. foxes/core/partial_wakes_model.py +147 -10
  48. foxes/core/point_data_model.py +2 -3
  49. foxes/core/rotor_model.py +3 -3
  50. foxes/core/states.py +2 -3
  51. foxes/core/turbine.py +2 -1
  52. foxes/core/wake_deflection.py +130 -0
  53. foxes/core/wake_model.py +222 -9
  54. foxes/core/wake_superposition.py +122 -4
  55. foxes/core/wind_farm.py +6 -6
  56. foxes/data/__init__.py +7 -2
  57. foxes/data/states/weibull_sectors_12.csv +13 -0
  58. foxes/data/states/weibull_sectors_12.nc +0 -0
  59. foxes/engines/__init__.py +14 -15
  60. foxes/engines/dask.py +39 -14
  61. foxes/engines/numpy.py +0 -3
  62. foxes/input/__init__.py +3 -3
  63. foxes/input/farm_layout/__init__.py +8 -8
  64. foxes/input/farm_layout/from_csv.py +1 -1
  65. foxes/input/farm_layout/ring.py +0 -1
  66. foxes/input/states/__init__.py +22 -12
  67. foxes/input/states/create/__init__.py +3 -2
  68. foxes/input/states/field_data_nc.py +10 -24
  69. foxes/input/states/multi_height.py +9 -6
  70. foxes/input/states/one_point_flow.py +0 -4
  71. foxes/input/states/single.py +1 -1
  72. foxes/input/states/states_table.py +10 -7
  73. foxes/input/states/weibull_sectors.py +225 -0
  74. foxes/input/states/wrg_states.py +7 -5
  75. foxes/input/yaml/__init__.py +9 -3
  76. foxes/input/yaml/dict.py +19 -19
  77. foxes/input/yaml/windio/__init__.py +10 -5
  78. foxes/input/yaml/windio/read_attributes.py +2 -2
  79. foxes/input/yaml/windio/read_farm.py +5 -5
  80. foxes/input/yaml/windio/read_fields.py +4 -2
  81. foxes/input/yaml/windio/read_site.py +52 -0
  82. foxes/input/yaml/windio/windio.py +1 -1
  83. foxes/models/__init__.py +15 -14
  84. foxes/models/axial_induction/__init__.py +2 -2
  85. foxes/models/farm_controllers/__init__.py +1 -1
  86. foxes/models/farm_models/__init__.py +1 -1
  87. foxes/models/ground_models/__init__.py +3 -2
  88. foxes/models/ground_models/wake_mirror.py +3 -3
  89. foxes/models/model_book.py +175 -49
  90. foxes/models/partial_wakes/__init__.py +6 -6
  91. foxes/models/partial_wakes/axiwake.py +30 -5
  92. foxes/models/partial_wakes/centre.py +47 -0
  93. foxes/models/partial_wakes/rotor_points.py +41 -11
  94. foxes/models/partial_wakes/segregated.py +2 -25
  95. foxes/models/partial_wakes/top_hat.py +27 -2
  96. foxes/models/point_models/__init__.py +4 -4
  97. foxes/models/rotor_models/__init__.py +3 -3
  98. foxes/models/turbine_models/__init__.py +11 -11
  99. foxes/models/turbine_models/set_farm_vars.py +0 -1
  100. foxes/models/turbine_types/PCt_file.py +0 -2
  101. foxes/models/turbine_types/PCt_from_two.py +0 -2
  102. foxes/models/turbine_types/__init__.py +9 -9
  103. foxes/models/vertical_profiles/__init__.py +7 -7
  104. foxes/models/wake_deflections/__init__.py +3 -0
  105. foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
  106. foxes/models/wake_deflections/jimenez.py +277 -0
  107. foxes/models/wake_deflections/no_deflection.py +94 -0
  108. foxes/models/wake_frames/__init__.py +6 -7
  109. foxes/models/wake_frames/dynamic_wakes.py +12 -3
  110. foxes/models/wake_frames/rotor_wd.py +3 -1
  111. foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
  112. foxes/models/wake_frames/streamlines.py +8 -6
  113. foxes/models/wake_frames/timelines.py +9 -3
  114. foxes/models/wake_models/__init__.py +7 -7
  115. foxes/models/wake_models/dist_sliced.py +50 -84
  116. foxes/models/wake_models/gaussian.py +20 -0
  117. foxes/models/wake_models/induction/__init__.py +5 -5
  118. foxes/models/wake_models/induction/rankine_half_body.py +30 -71
  119. foxes/models/wake_models/induction/rathmann.py +65 -64
  120. foxes/models/wake_models/induction/self_similar.py +65 -68
  121. foxes/models/wake_models/induction/self_similar2020.py +0 -3
  122. foxes/models/wake_models/induction/vortex_sheet.py +71 -75
  123. foxes/models/wake_models/ti/__init__.py +2 -2
  124. foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
  125. foxes/models/wake_models/ti/iec_ti.py +6 -4
  126. foxes/models/wake_models/top_hat.py +58 -7
  127. foxes/models/wake_models/wind/__init__.py +6 -4
  128. foxes/models/wake_models/wind/bastankhah14.py +25 -7
  129. foxes/models/wake_models/wind/bastankhah16.py +35 -3
  130. foxes/models/wake_models/wind/jensen.py +15 -2
  131. foxes/models/wake_models/wind/turbopark.py +28 -2
  132. foxes/models/wake_superpositions/__init__.py +18 -9
  133. foxes/models/wake_superpositions/ti_linear.py +4 -4
  134. foxes/models/wake_superpositions/ti_max.py +4 -4
  135. foxes/models/wake_superpositions/ti_pow.py +4 -4
  136. foxes/models/wake_superpositions/ti_quadratic.py +4 -4
  137. foxes/models/wake_superpositions/wind_vector.py +257 -0
  138. foxes/models/wake_superpositions/ws_linear.py +9 -10
  139. foxes/models/wake_superpositions/ws_max.py +8 -8
  140. foxes/models/wake_superpositions/ws_pow.py +8 -8
  141. foxes/models/wake_superpositions/ws_product.py +4 -4
  142. foxes/models/wake_superpositions/ws_quadratic.py +8 -8
  143. foxes/output/__init__.py +21 -19
  144. foxes/output/farm_layout.py +2 -2
  145. foxes/output/farm_results_eval.py +15 -15
  146. foxes/output/flow_plots_2d/__init__.py +2 -2
  147. foxes/output/flow_plots_2d/get_fig.py +4 -2
  148. foxes/output/rose_plot.py +3 -3
  149. foxes/output/seq_plugins/__init__.py +2 -2
  150. foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
  151. foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
  152. foxes/output/turbine_type_curves.py +7 -8
  153. foxes/utils/__init__.py +37 -19
  154. foxes/utils/abl/__init__.py +4 -4
  155. foxes/utils/cubic_roots.py +1 -1
  156. foxes/utils/data_book.py +4 -3
  157. foxes/utils/dict.py +3 -3
  158. foxes/utils/exec_python.py +5 -5
  159. foxes/utils/factory.py +1 -3
  160. foxes/utils/geom2d/__init__.py +7 -5
  161. foxes/utils/geopandas_utils.py +2 -2
  162. foxes/utils/pandas_utils.py +4 -3
  163. foxes/utils/tab_files.py +0 -1
  164. foxes/utils/weibull.py +28 -0
  165. foxes/utils/wrg_utils.py +3 -1
  166. foxes/utils/xarray_utils.py +9 -2
  167. foxes/variables.py +67 -9
  168. {foxes-1.3.dist-info → foxes-1.4.dist-info}/METADATA +6 -15
  169. foxes-1.4.dist-info/RECORD +320 -0
  170. {foxes-1.3.dist-info → foxes-1.4.dist-info}/WHEEL +1 -1
  171. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
  172. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
  173. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
  174. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
  175. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
  176. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
  177. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
  178. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
  179. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
  180. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
  181. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
  182. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
  183. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
  184. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
  185. foxes/output/round.py +0 -10
  186. foxes/utils/pandas_helpers.py +0 -178
  187. foxes-1.3.dist-info/RECORD +0 -313
  188. {foxes-1.3.dist-info → foxes-1.4.dist-info}/entry_points.txt +0 -0
  189. {foxes-1.3.dist-info → foxes-1.4.dist-info/licenses}/LICENSE +0 -0
  190. {foxes-1.3.dist-info → foxes-1.4.dist-info}/top_level.txt +0 -0
@@ -39,3 +39,50 @@ class PartialCentre(RotorPoints):
39
39
 
40
40
  """
41
41
  return fdata[FV.TXYH][:, :, None], np.ones(1, dtype=config.dtype_double)
42
+
43
+ def map_rotor_results(
44
+ self,
45
+ algo,
46
+ mdata,
47
+ fdata,
48
+ tdata,
49
+ variable,
50
+ rotor_res,
51
+ rotor_weights,
52
+ ):
53
+ """
54
+ Map ambient rotor point results onto target points.
55
+
56
+ Parameters
57
+ ----------
58
+ algo: foxes.core.Algorithm
59
+ The calculation algorithm
60
+ mdata: foxes.core.MData
61
+ The model data
62
+ fdata: foxes.core.FData
63
+ The farm data
64
+ tdata: foxes.core.TData
65
+ The target point data
66
+ variable: str
67
+ The variable name to map
68
+ rotor_res: numpy.ndarray
69
+ The results at rotor points, shape:
70
+ (n_states, n_turbines, n_rotor_points)
71
+ rotor_weights: numpy.ndarray
72
+ The rotor point weights, shape: (n_rotor_points,)
73
+
74
+ Returns
75
+ -------
76
+ res: numpy.ndarray
77
+ The mapped results at target points, shape:
78
+ (n_states, n_targets, n_tpoints)
79
+
80
+ """
81
+ if rotor_res.shape[2] > 1:
82
+ return np.einsum(
83
+ "str,r->st",
84
+ rotor_res,
85
+ rotor_weights,
86
+ )[:, :, None]
87
+ else:
88
+ return rotor_res
@@ -39,13 +39,52 @@ class RotorPoints(PartialWakesModel):
39
39
  algo.get_from_chunk_store(FC.ROTOR_WEIGHTS, mdata=mdata),
40
40
  )
41
41
 
42
+ def map_rotor_results(
43
+ self,
44
+ algo,
45
+ mdata,
46
+ fdata,
47
+ tdata,
48
+ variable,
49
+ rotor_res,
50
+ rotor_weights,
51
+ ):
52
+ """
53
+ Map ambient rotor point results onto target points.
54
+
55
+ Parameters
56
+ ----------
57
+ algo: foxes.core.Algorithm
58
+ The calculation algorithm
59
+ mdata: foxes.core.MData
60
+ The model data
61
+ fdata: foxes.core.FData
62
+ The farm data
63
+ tdata: foxes.core.TData
64
+ The target point data
65
+ variable: str
66
+ The variable name to map
67
+ rotor_res: numpy.ndarray
68
+ The results at rotor points, shape:
69
+ (n_states, n_turbines, n_rotor_points)
70
+ rotor_weights: numpy.ndarray
71
+ The rotor point weights, shape: (n_rotor_points,)
72
+
73
+ Returns
74
+ -------
75
+ res: numpy.ndarray
76
+ The mapped results at target points, shape:
77
+ (n_states, n_targets, n_tpoints)
78
+
79
+ """
80
+ return rotor_res
81
+
42
82
  def finalize_wakes(
43
83
  self,
44
84
  algo,
45
85
  mdata,
46
86
  fdata,
47
87
  tdata,
48
- amb_res,
49
88
  rpoint_weights,
50
89
  wake_deltas,
51
90
  wmodel,
@@ -67,11 +106,6 @@ class RotorPoints(PartialWakesModel):
67
106
  The farm data
68
107
  tdata: foxes.core.Data
69
108
  The target point data
70
- amb_res: dict
71
- The ambient results at the target points
72
- of all rotors. Key: variable name, value
73
- np.ndarray of shape:
74
- (n_states, n_turbines, n_rotor_points)
75
109
  rpoint_weights: numpy.ndarray
76
110
  The rotor point weights, shape: (n_rotor_points,)
77
111
  wake_deltas: dict
@@ -91,14 +125,10 @@ class RotorPoints(PartialWakesModel):
91
125
  of shape (n_states, n_rotor_points)
92
126
 
93
127
  """
94
- ares = {
95
- v: d[:, downwind_index, None] if d.shape[1] > 1 else d[:, 0, None]
96
- for v, d in amb_res.items()
97
- }
98
128
  wdel = {
99
129
  v: d[:, downwind_index, None].copy() if d.shape[1] > 1 else d[:, 0, None]
100
130
  for v, d in wake_deltas.items()
101
131
  }
102
- wmodel.finalize_wake_deltas(algo, mdata, fdata, ares, wdel)
132
+ wmodel.finalize_wake_deltas(algo, mdata, fdata, tdata, wdel)
103
133
 
104
134
  return {v: d[:, 0] for v, d in wdel.items()}
@@ -87,7 +87,6 @@ class PartialSegregated(PartialWakesModel):
87
87
  mdata,
88
88
  fdata,
89
89
  tdata,
90
- amb_res,
91
90
  rpoint_weights,
92
91
  wake_deltas,
93
92
  wmodel,
@@ -109,11 +108,6 @@ class PartialSegregated(PartialWakesModel):
109
108
  The farm data
110
109
  tdata: foxes.core.Data
111
110
  The target point data
112
- amb_res: dict
113
- The ambient results at the target points
114
- of all rotors. Key: variable name, value
115
- np.ndarray of shape:
116
- (n_states, n_turbines, n_rotor_points)
117
111
  rpoint_weights: numpy.ndarray
118
112
  The rotor point weights, shape: (n_rotor_points,)
119
113
  wake_deltas: dict
@@ -138,25 +132,8 @@ class PartialSegregated(PartialWakesModel):
138
132
  gweights = tdata[FC.TWEIGHTS]
139
133
 
140
134
  wdel = {v: d[:, downwind_index, None].copy() for v, d in wake_deltas.items()}
141
-
142
- if n_rotor_points == tdata.n_tpoints:
143
- ares = {
144
- v: d[:, downwind_index, None] if d.shape[1] > 1 else d[:, 0, None]
145
- for v, d in amb_res.items()
146
- }
147
- else:
148
- ares = {}
149
- for v, d in amb_res.items():
150
- ares[v] = np.zeros(
151
- (n_states, 1, tdata.n_tpoints), dtype=config.dtype_double
152
- )
153
- ares[v][:] = np.einsum(
154
- "sp,p->s",
155
- d[:, downwind_index] if d.shape[1] > 1 else d[:, 0],
156
- rpoint_weights,
157
- )[:, None, None]
158
-
159
- wmodel.finalize_wake_deltas(algo, mdata, fdata, ares, wdel)
135
+ htdata = tdata.get_slice([FC.TURBINE], np.s_[downwind_index])
136
+ wmodel.finalize_wake_deltas(algo, mdata, fdata, htdata, wdel)
160
137
 
161
138
  for v in wdel.keys():
162
139
  hdel = np.zeros((n_states, n_rotor_points), dtype=config.dtype_double)
@@ -126,8 +126,6 @@ class PartialTopHat(PartialCentre):
126
126
  The wake deltas. Key: variable name,
127
127
  value: numpy.ndarray with shape
128
128
  (n_states, n_targets, n_tpoints, ...)
129
- wmodel: foxes.core.WakeModel
130
- The wake model
131
129
 
132
130
  """
133
131
  self.check_wmodel(wmodel, error=True)
@@ -182,6 +180,33 @@ class PartialTopHat(PartialCentre):
182
180
 
183
181
  weights = calc_area(D / 2, wr, R) / (np.pi * (D / 2) ** 2)
184
182
 
183
+ # run superposition models:
184
+ if wmodel.affects_ws and wmodel.has_uv:
185
+ assert wmodel.has_vector_wind_superp, (
186
+ f"{self.name}: Expecting vector wind superposition in wake model '{wmodel.name}', got '{wmodel.wind_superposition}'"
187
+ )
188
+ if FV.UV in clw:
189
+ duv = clw.pop(FV.UV)
190
+ else:
191
+ clwe = {v: d[:, None] for v, d in clw.items()}
192
+ wmodel.vec_superp.wdeltas_ws2uv(
193
+ algo, fdata, tdata, downwind_index, clwe, st_sel
194
+ )
195
+ duv = np.einsum("sd,s->sd", clwe.pop(FV.UV)[:, 0], weights)
196
+ del clwe, clw[FV.WS]
197
+ if FV.WD in clw:
198
+ del clw[FV.WD]
199
+ wake_deltas[FV.UV] = wmodel.vec_superp.add_wake_vector(
200
+ algo,
201
+ mdata,
202
+ fdata,
203
+ tdata,
204
+ downwind_index,
205
+ st_sel,
206
+ wake_deltas[FV.UV],
207
+ duv[:, None],
208
+ )
209
+
185
210
  for v, d in clw.items():
186
211
  try:
187
212
  superp = wmodel.superp[v]
@@ -2,7 +2,7 @@
2
2
  Point models.
3
3
  """
4
4
 
5
- from .wake_deltas import WakeDeltas
6
- from .set_uniform_data import SetUniformData
7
- from .tke2ti import TKE2TI
8
- from .ustar2ti import Ustar2TI
5
+ from .wake_deltas import WakeDeltas as WakeDeltas
6
+ from .set_uniform_data import SetUniformData as SetUniformData
7
+ from .tke2ti import TKE2TI as TKE2TI
8
+ from .ustar2ti import Ustar2TI as Ustar2TI
@@ -2,6 +2,6 @@
2
2
  Rotor models.
3
3
  """
4
4
 
5
- from .centre import CentreRotor
6
- from .grid import GridRotor
7
- from .levels import LevelRotor
5
+ from .centre import CentreRotor as CentreRotor
6
+ from .grid import GridRotor as GridRotor
7
+ from .levels import LevelRotor as LevelRotor
@@ -2,14 +2,14 @@
2
2
  Turbine models.
3
3
  """
4
4
 
5
- from .kTI_model import kTI
6
- from .set_farm_vars import SetFarmVars
7
- from .thrust2ct import Thrust2Ct
8
- from .power_mask import PowerMask
9
- from .sector_management import SectorManagement
10
- from .table_factors import TableFactors
11
- from .yaw2yawm import YAW2YAWM
12
- from .yawm2yaw import YAWM2YAW
13
- from .calculator import Calculator
14
- from .rotor_centre_calc import RotorCentreCalc
15
- from .lookup_table import LookupTable
5
+ from .kTI_model import kTI as kTI
6
+ from .set_farm_vars import SetFarmVars as SetFarmVars
7
+ from .thrust2ct import Thrust2Ct as Thrust2Ct
8
+ from .power_mask import PowerMask as PowerMask
9
+ from .sector_management import SectorManagement as SectorManagement
10
+ from .table_factors import TableFactors as TableFactors
11
+ from .yaw2yawm import YAW2YAWM as YAW2YAWM
12
+ from .yawm2yaw import YAWM2YAW as YAWM2YAW
13
+ from .calculator import Calculator as Calculator
14
+ from .rotor_centre_calc import RotorCentreCalc as RotorCentreCalc
15
+ from .lookup_table import LookupTable as LookupTable
@@ -270,7 +270,6 @@ class SetFarmVars(TurbineModel):
270
270
  """
271
271
  i0 = mdata.states_i0(counter=True)
272
272
  if not self.once or i0 not in self.__once_done:
273
-
274
273
  if self.pre_rotor:
275
274
  order = np.s_[:]
276
275
  ssel = np.s_[:]
@@ -1,6 +1,5 @@
1
1
  import numpy as np
2
2
  import pandas as pd
3
- from pathlib import Path
4
3
 
5
4
  from foxes.core import TurbineType
6
5
  from foxes.utils import PandasFileHelper
@@ -232,7 +231,6 @@ class PCtFile(TurbineType):
232
231
 
233
232
  """
234
233
  if modify_ct or modify_P:
235
-
236
234
  ws = self.data_ws
237
235
  ct = self.data_ct
238
236
  P = self.data_P
@@ -263,7 +263,6 @@ class PCtFromTwo(TurbineType):
263
263
 
264
264
  """
265
265
  if modify_ct:
266
-
267
266
  ws = self._data_ws_ct
268
267
  ct = self._data_ct
269
268
 
@@ -291,7 +290,6 @@ class PCtFromTwo(TurbineType):
291
290
  self._data_ct = np.concatenate([new_ct[:-1], ct], axis=0)
292
291
 
293
292
  if modify_P:
294
-
295
293
  ws = self._data_ws_P
296
294
  P = self._data_P
297
295
 
@@ -2,12 +2,12 @@
2
2
  Turbine type models.
3
3
  """
4
4
 
5
- from .PCt_file import PCtFile
6
- from .PCt_from_two import PCtFromTwo
7
- from .CpCt_file import CpCtFile
8
- from .CpCt_from_two import CpCtFromTwo
9
- from .null_type import NullType
10
- from .wsrho2PCt_from_two import WsRho2PCtFromTwo
11
- from .wsti2PCt_from_two import WsTI2PCtFromTwo
12
- from .lookup import FromLookupTable
13
- from .TBL_file import TBLFile
5
+ from .PCt_file import PCtFile as PCtFile
6
+ from .PCt_from_two import PCtFromTwo as PCtFromTwo
7
+ from .CpCt_file import CpCtFile as CpCtFile
8
+ from .CpCt_from_two import CpCtFromTwo as CpCtFromTwo
9
+ from .null_type import NullType as NullType
10
+ from .wsrho2PCt_from_two import WsRho2PCtFromTwo as WsRho2PCtFromTwo
11
+ from .wsti2PCt_from_two import WsTI2PCtFromTwo as WsTI2PCtFromTwo
12
+ from .lookup import FromLookupTable as FromLookupTable
13
+ from .TBL_file import TBLFile as TBLFile
@@ -2,10 +2,10 @@
2
2
  Vertical profile models.
3
3
  """
4
4
 
5
- from .uniform import UniformProfile
6
- from .abl_log_neutral_ws import ABLLogNeutralWsProfile
7
- from .abl_log_stable_ws import ABLLogStableWsProfile
8
- from .abl_log_unstable_ws import ABLLogUnstableWsProfile
9
- from .abl_log_ws import ABLLogWsProfile
10
- from .sheared_ws import ShearedProfile
11
- from .data_profile import DataProfile
5
+ from .uniform import UniformProfile as UniformProfile
6
+ from .abl_log_neutral_ws import ABLLogNeutralWsProfile as ABLLogNeutralWsProfile
7
+ from .abl_log_stable_ws import ABLLogStableWsProfile as ABLLogStableWsProfile
8
+ from .abl_log_unstable_ws import ABLLogUnstableWsProfile as ABLLogUnstableWsProfile
9
+ from .abl_log_ws import ABLLogWsProfile as ABLLogWsProfile
10
+ from .sheared_ws import ShearedProfile as ShearedProfile
11
+ from .data_profile import DataProfile as DataProfile
@@ -0,0 +1,3 @@
1
+ from .no_deflection import NoDeflection as NoDeflection
2
+ from .bastankhah2016 import Bastankhah2016Deflection as Bastankhah2016Deflection
3
+ from .jimenez import JimenezDeflection as JimenezDeflection
@@ -1,18 +1,17 @@
1
1
  import numpy as np
2
2
 
3
- from foxes.core import WakeFrame, WakeK, TData
3
+ from foxes.config import config
4
+ from foxes.core.wake_deflection import WakeDeflection
5
+ from foxes.core.wake_model import WakeK
4
6
  from foxes.models.wake_models.wind.bastankhah16 import (
5
7
  Bastankhah2016Model,
6
8
  Bastankhah2016,
7
9
  )
8
- from foxes.config import config
9
- import foxes.variables as FV
10
10
  import foxes.constants as FC
11
-
12
- from .rotor_wd import RotorWD
11
+ import foxes.variables as FV
13
12
 
14
13
 
15
- class YawedWakes(WakeFrame):
14
+ class Bastankhah2016Deflection(WakeDeflection):
16
15
  """
17
16
  Bend the wakes for yawed turbines, based on the
18
17
  Bastankhah 2016 wake model
@@ -28,25 +27,26 @@ class YawedWakes(WakeFrame):
28
27
  ----------
29
28
  model: Bastankhah2016Model
30
29
  The model for computing common data
31
- model_pars: dict
32
- Model parameters
33
- YAWM: float
34
- The yaw misalignment YAWM. If not given here
35
- it will be searched in the farm data.
36
- base_frame: foxes.core.WakeFrame
37
- The wake frame from which to start
38
-
39
- :group: models.wake_frames
30
+ alpha: float
31
+ model parameter used to determine onset of far wake region,
32
+ if not found in wake model
33
+ beta: float
34
+ model parameter used to determine onset of far wake region,
35
+ if not found in wake model
36
+ wake_k: dict
37
+ Parameters for the WakeK class, if not found in wake model
38
+ induction: foxes.core.AxialInductionModel
39
+ The induction model, if not found in wake model
40
+
41
+ :group: models.wake_deflections
40
42
 
41
43
  """
42
44
 
43
45
  def __init__(
44
46
  self,
45
- base_frame=RotorWD(),
46
47
  alpha=0.58,
47
48
  beta=0.07,
48
49
  induction="Madsen",
49
- max_length_km=30,
50
50
  **wake_k,
51
51
  ):
52
52
  """
@@ -54,8 +54,6 @@ class YawedWakes(WakeFrame):
54
54
 
55
55
  Parameters
56
56
  ----------
57
- base_frame: foxes.core.WakeFrame
58
- The wake frame from which to start
59
57
  alpha: float
60
58
  model parameter used to determine onset of far wake region,
61
59
  if not found in wake model
@@ -66,13 +64,10 @@ class YawedWakes(WakeFrame):
66
64
  The induction model, if not found in wake model
67
65
  wake_k: dict, optional
68
66
  Parameters for the WakeK class, if not found in wake model
69
- max_length_km: float
70
- The maximal wake length in km
71
67
 
72
68
  """
73
- super().__init__(max_length_km=max_length_km)
69
+ super().__init__()
74
70
 
75
- self.base_frame = base_frame
76
71
  self.model = None
77
72
  self.alpha = alpha
78
73
  self.beta = beta
@@ -98,7 +93,7 @@ class YawedWakes(WakeFrame):
98
93
  Names of all sub models
99
94
 
100
95
  """
101
- return [self.wake_k, self.base_frame, self.model]
96
+ return [self.wake_k, self.model]
102
97
 
103
98
  def initialize(self, algo, verbosity=0, force=False):
104
99
  """
@@ -138,30 +133,6 @@ class YawedWakes(WakeFrame):
138
133
 
139
134
  super().initialize(algo, verbosity, force)
140
135
 
141
- def calc_order(self, algo, mdata, fdata):
142
- """
143
- Calculates the order of turbine evaluation.
144
-
145
- This function is executed on a single chunk of data,
146
- all computations should be based on numpy arrays.
147
-
148
- Parameters
149
- ----------
150
- algo: foxes.core.Algorithm
151
- The calculation algorithm
152
- mdata: foxes.core.MData
153
- The model data
154
- fdata: foxes.core.FData
155
- The farm data
156
-
157
- Returns
158
- -------
159
- order: numpy.ndarray
160
- The turbine order, shape: (n_states, n_turbines)
161
-
162
- """
163
- return self.base_frame.calc_order(algo, mdata, fdata)
164
-
165
136
  def _update_y(self, algo, mdata, fdata, tdata, downwind_index, x, y):
166
137
  """
167
138
  Helper function for y deflection
@@ -227,16 +198,20 @@ class YawedWakes(WakeFrame):
227
198
  # apply deflection:
228
199
  y[st_sel] -= ydef
229
200
 
230
- def get_wake_coos(
201
+ def calc_deflection(
231
202
  self,
232
203
  algo,
233
204
  mdata,
234
205
  fdata,
235
206
  tdata,
236
207
  downwind_index,
208
+ coos,
237
209
  ):
238
210
  """
239
- Calculate wake coordinates of rotor points.
211
+ Calculates the wake deflection.
212
+
213
+ This function optionally adds FC.WDEFL_ROT_ANGLE or
214
+ FC.WDEFL_DWS_FACTOR to the tdata.
240
215
 
241
216
  Parameters
242
217
  ----------
@@ -251,79 +226,25 @@ class YawedWakes(WakeFrame):
251
226
  downwind_index: int
252
227
  The index of the wake causing turbine
253
228
  in the downwind order
229
+ coos: numpy.ndarray
230
+ The wake frame coordinates of the evaluation
231
+ points, shape: (n_states, n_targets, n_tpoints, 3)
254
232
 
255
233
  Returns
256
234
  -------
257
- wake_coos: numpy.ndarray
235
+ coos: numpy.ndarray
258
236
  The wake frame coordinates of the evaluation
259
237
  points, shape: (n_states, n_targets, n_tpoints, 3)
260
238
 
261
239
  """
262
- # get unyawed results:
263
- xyz = self.base_frame.get_wake_coos(
264
- algo,
265
- mdata,
266
- fdata,
267
- tdata,
268
- downwind_index,
269
- )
270
240
 
271
241
  # take rotor average:
272
- xy = np.einsum("stpd,p->std", xyz[..., :2], tdata[FC.TWEIGHTS])
242
+ xy = np.einsum("stpd,p->std", coos[..., :2], tdata[FC.TWEIGHTS])
273
243
  x = xy[:, :, 0]
274
244
  y = xy[:, :, 1]
275
245
 
276
246
  # apply deflection:
277
247
  self._update_y(algo, mdata, fdata, tdata, downwind_index, x, y)
278
- xyz[..., 1] = y[:, :, None]
279
-
280
- return xyz
281
-
282
- def get_centreline_points(self, algo, mdata, fdata, downwind_index, x):
283
- """
284
- Gets the points along the centreline for given
285
- values of x.
286
-
287
- Parameters
288
- ----------
289
- algo: foxes.core.Algorithm
290
- The calculation algorithm
291
- mdata: foxes.core.MData
292
- The model data
293
- fdata: foxes.core.FData
294
- The farm data
295
- downwind_index: int
296
- The index in the downwind order
297
- x: numpy.ndarray
298
- The wake frame x coordinates, shape: (n_states, n_points)
299
-
300
- Returns
301
- -------
302
- points: numpy.ndarray
303
- The centreline points, shape: (n_states, n_points, 3)
304
-
305
- """
306
- points = self.base_frame.get_centreline_points(
307
- algo, mdata, fdata, downwind_index, x
308
- )
309
- tdata = TData.from_points(points)
310
-
311
- nx = np.zeros_like(points)
312
- nx[:, 0] = points[:, 1] - points[:, 0]
313
- nx[:, -1] = points[:, -1] - points[:, -2]
314
- nx[:, 1:-1] = 0.5 * (points[:, 1:-1] - points[:, :-2]) + 0.5 * (
315
- points[:, 2:] - points[:, 1:-1]
316
- )
317
- nx /= np.linalg.norm(nx, axis=-1)[:, :, None]
318
-
319
- nz = np.zeros_like(nx)
320
- nz[:, :, 2] = 1
321
- ny = np.cross(nz, nx, axis=-1)
322
- del nx, nz
323
-
324
- y = np.zeros_like(x)
325
- self._update_y(algo, mdata, fdata, tdata, downwind_index, x, y)
326
-
327
- points += y[:, :, None] * ny
248
+ coos[..., 1] = y[:, :, None]
328
249
 
329
- return points
250
+ return coos