foxes 0.6.1__py3-none-any.whl → 0.7__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 (129) hide show
  1. foxes/VERSION +1 -1
  2. foxes/algorithms/downwind/downwind.py +131 -65
  3. foxes/algorithms/downwind/models/__init__.py +2 -1
  4. foxes/algorithms/downwind/models/farm_wakes_calc.py +87 -55
  5. foxes/algorithms/downwind/models/init_farm_data.py +134 -0
  6. foxes/algorithms/downwind/models/point_wakes_calc.py +54 -65
  7. foxes/algorithms/downwind/models/{calc_order.py → reorder_farm_output.py} +28 -26
  8. foxes/algorithms/iterative/iterative.py +100 -51
  9. foxes/algorithms/iterative/models/convergence.py +3 -3
  10. foxes/algorithms/iterative/models/farm_wakes_calc.py +55 -48
  11. foxes/algorithms/sequential/models/seq_state.py +7 -6
  12. foxes/algorithms/sequential/sequential.py +81 -44
  13. foxes/constants.py +33 -18
  14. foxes/core/__init__.py +2 -2
  15. foxes/core/algorithm.py +31 -12
  16. foxes/core/data.py +335 -41
  17. foxes/core/data_calc_model.py +27 -23
  18. foxes/core/farm_controller.py +27 -28
  19. foxes/core/farm_data_model.py +26 -4
  20. foxes/core/model.py +186 -129
  21. foxes/core/partial_wakes_model.py +84 -81
  22. foxes/core/point_data_model.py +51 -18
  23. foxes/core/rotor_model.py +59 -77
  24. foxes/core/states.py +6 -6
  25. foxes/core/turbine_model.py +4 -4
  26. foxes/core/turbine_type.py +24 -0
  27. foxes/core/vertical_profile.py +3 -3
  28. foxes/core/wake_frame.py +91 -50
  29. foxes/core/wake_model.py +74 -43
  30. foxes/core/wake_superposition.py +29 -26
  31. foxes/input/farm_layout/__init__.py +1 -0
  32. foxes/input/farm_layout/from_random.py +49 -0
  33. foxes/input/states/__init__.py +1 -1
  34. foxes/input/states/create/__init__.py +1 -0
  35. foxes/input/states/create/random_abl_states.py +6 -2
  36. foxes/input/states/create/random_timeseries.py +56 -0
  37. foxes/input/states/field_data_nc.py +12 -8
  38. foxes/input/states/multi_height.py +24 -14
  39. foxes/input/states/scan_ws.py +13 -17
  40. foxes/input/states/single.py +28 -20
  41. foxes/input/states/states_table.py +22 -18
  42. foxes/models/axial_induction_models/betz.py +1 -1
  43. foxes/models/farm_models/turbine2farm.py +2 -2
  44. foxes/models/model_book.py +40 -14
  45. foxes/models/partial_wakes/__init__.py +2 -2
  46. foxes/models/partial_wakes/axiwake.py +73 -200
  47. foxes/models/partial_wakes/centre.py +40 -0
  48. foxes/models/partial_wakes/grid.py +7 -63
  49. foxes/models/partial_wakes/rotor_points.py +53 -147
  50. foxes/models/partial_wakes/segregated.py +158 -0
  51. foxes/models/partial_wakes/top_hat.py +88 -196
  52. foxes/models/point_models/set_uniform_data.py +4 -4
  53. foxes/models/point_models/tke2ti.py +4 -4
  54. foxes/models/point_models/wake_deltas.py +4 -4
  55. foxes/models/rotor_models/centre.py +15 -19
  56. foxes/models/rotor_models/grid.py +2 -1
  57. foxes/models/rotor_models/levels.py +2 -1
  58. foxes/models/turbine_models/__init__.py +0 -1
  59. foxes/models/turbine_models/calculator.py +11 -7
  60. foxes/models/turbine_models/kTI_model.py +13 -11
  61. foxes/models/turbine_models/lookup_table.py +22 -9
  62. foxes/models/turbine_models/power_mask.py +81 -51
  63. foxes/models/turbine_models/rotor_centre_calc.py +17 -20
  64. foxes/models/turbine_models/sector_management.py +5 -6
  65. foxes/models/turbine_models/set_farm_vars.py +49 -20
  66. foxes/models/turbine_models/table_factors.py +5 -5
  67. foxes/models/turbine_models/thrust2ct.py +9 -5
  68. foxes/models/turbine_models/yaw2yawm.py +7 -13
  69. foxes/models/turbine_models/yawm2yaw.py +7 -11
  70. foxes/models/turbine_types/PCt_file.py +84 -3
  71. foxes/models/turbine_types/PCt_from_two.py +7 -3
  72. foxes/models/turbine_types/null_type.py +2 -2
  73. foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -2
  74. foxes/models/turbine_types/wsti2PCt_from_two.py +6 -2
  75. foxes/models/wake_frames/farm_order.py +26 -22
  76. foxes/models/wake_frames/rotor_wd.py +32 -31
  77. foxes/models/wake_frames/seq_dynamic_wakes.py +112 -64
  78. foxes/models/wake_frames/streamlines.py +51 -47
  79. foxes/models/wake_frames/timelines.py +59 -47
  80. foxes/models/wake_frames/yawed_wakes.py +63 -40
  81. foxes/models/wake_models/axisymmetric.py +31 -35
  82. foxes/models/wake_models/dist_sliced.py +50 -56
  83. foxes/models/wake_models/gaussian.py +33 -35
  84. foxes/models/wake_models/induction/rankine_half_body.py +79 -87
  85. foxes/models/wake_models/induction/rathmann.py +56 -63
  86. foxes/models/wake_models/induction/self_similar.py +59 -62
  87. foxes/models/wake_models/ti/crespo_hernandez.py +83 -74
  88. foxes/models/wake_models/ti/iec_ti.py +65 -75
  89. foxes/models/wake_models/top_hat.py +60 -69
  90. foxes/models/wake_models/wake_mirror.py +49 -54
  91. foxes/models/wake_models/wind/bastankhah14.py +44 -66
  92. foxes/models/wake_models/wind/bastankhah16.py +84 -111
  93. foxes/models/wake_models/wind/jensen.py +67 -89
  94. foxes/models/wake_models/wind/turbopark.py +93 -133
  95. foxes/models/wake_superpositions/ti_linear.py +33 -27
  96. foxes/models/wake_superpositions/ti_max.py +33 -27
  97. foxes/models/wake_superpositions/ti_pow.py +35 -27
  98. foxes/models/wake_superpositions/ti_quadratic.py +33 -27
  99. foxes/models/wake_superpositions/ws_linear.py +39 -32
  100. foxes/models/wake_superpositions/ws_max.py +40 -33
  101. foxes/models/wake_superpositions/ws_pow.py +39 -32
  102. foxes/models/wake_superpositions/ws_product.py +35 -28
  103. foxes/models/wake_superpositions/ws_quadratic.py +39 -32
  104. foxes/opt/constraints/min_dist.py +1 -1
  105. foxes/opt/objectives/farm_vars.py +1 -1
  106. foxes/opt/problems/layout/farm_layout.py +38 -97
  107. foxes/output/__init__.py +1 -0
  108. foxes/output/farm_results_eval.py +1 -1
  109. foxes/output/flow_plots_2d/flow_plots.py +2 -0
  110. foxes/output/flow_plots_2d/get_fig.py +2 -0
  111. foxes/output/grids.py +1 -1
  112. foxes/output/rose_plot.py +3 -3
  113. foxes/output/rotor_point_plots.py +117 -0
  114. foxes/output/turbine_type_curves.py +2 -2
  115. foxes/utils/__init__.py +2 -1
  116. foxes/utils/load.py +29 -0
  117. foxes/utils/random_xy.py +56 -0
  118. foxes/utils/runners/runners.py +13 -1
  119. foxes/utils/windrose_plot.py +1 -1
  120. foxes/variables.py +10 -0
  121. {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/METADATA +13 -7
  122. {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/RECORD +126 -122
  123. {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/WHEEL +1 -1
  124. foxes/models/partial_wakes/distsliced.py +0 -322
  125. foxes/models/partial_wakes/mapped.py +0 -252
  126. foxes/models/turbine_models/set_XYHD.py +0 -130
  127. {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/LICENSE +0 -0
  128. {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/top_level.txt +0 -0
  129. {foxes-0.6.1.dist-info → foxes-0.7.dist-info}/zip-safe +0 -0
@@ -72,8 +72,8 @@ class TopHatWakeModel(AxisymmetricWakeModel):
72
72
  algo,
73
73
  mdata,
74
74
  fdata,
75
- pdata,
76
- states_source_turbine,
75
+ tdata,
76
+ downwind_index,
77
77
  x,
78
78
  ct,
79
79
  ):
@@ -84,41 +84,37 @@ class TopHatWakeModel(AxisymmetricWakeModel):
84
84
  ----------
85
85
  algo: foxes.core.Algorithm
86
86
  The calculation algorithm
87
- mdata: foxes.core.Data
87
+ mdata: foxes.core.MData
88
88
  The model data
89
- fdata: foxes.core.Data
89
+ fdata: foxes.core.FData
90
90
  The farm data
91
- pdata: foxes.core.Data
92
- The evaluation point data
93
- states_source_turbine: numpy.ndarray
94
- For each state, one turbine index for the
95
- wake causing turbine. Shape: (n_states,)
91
+ tdata: foxes.core.TData
92
+ The target point data
93
+ downwind_index: int
94
+ The index in the downwind order
96
95
  x: numpy.ndarray
97
- The x values, shape: (n_states, n_points)
98
- r: numpy.ndarray
99
- The radial values for each x value, shape:
100
- (n_states, n_points, n_r_per_x, 2)
96
+ The x values, shape: (n_states, n_targets)
101
97
  ct: numpy.ndarray
102
98
  The ct values of the wake-causing turbines,
103
- shape: (n_states, n_points)
99
+ shape: (n_states, n_targets)
104
100
 
105
101
  Returns
106
102
  -------
107
103
  wake_r: numpy.ndarray
108
- The wake radii, shape: (n_states, n_points)
104
+ The wake radii, shape: (n_states, n_targets)
109
105
 
110
106
  """
111
107
  pass
112
108
 
113
109
  @abstractmethod
114
- def calc_centreline_wake_deltas(
110
+ def calc_centreline(
115
111
  self,
116
112
  algo,
117
113
  mdata,
118
114
  fdata,
119
- pdata,
120
- states_source_turbine,
121
- sp_sel,
115
+ tdata,
116
+ downwind_index,
117
+ st_sel,
122
118
  x,
123
119
  wake_r,
124
120
  ct,
@@ -130,42 +126,41 @@ class TopHatWakeModel(AxisymmetricWakeModel):
130
126
  ----------
131
127
  algo: foxes.core.Algorithm
132
128
  The calculation algorithm
133
- mdata: foxes.core.Data
129
+ mdata: foxes.core.MData
134
130
  The model data
135
- fdata: foxes.core.Data
131
+ fdata: foxes.core.FData
136
132
  The farm data
137
- pdata: foxes.core.Data
138
- The evaluation point data
139
- states_source_turbine: numpy.ndarray
140
- For each state, one turbine index for the
141
- wake causing turbine. Shape: (n_states,)
142
- sp_sel: numpy.ndarray of bool
143
- The state-point selection, for which the wake
144
- is non-zero, shape: (n_states, n_points)
133
+ tdata: foxes.core.TData
134
+ The target point data
135
+ downwind_index: int
136
+ The index in the downwind order
137
+ st_sel: numpy.ndarray of bool
138
+ The state-target selection, for which the wake
139
+ is non-zero, shape: (n_states, n_targets)
145
140
  x: numpy.ndarray
146
- The x values, shape: (n_sp_sel,)
141
+ The x values, shape: (n_st_sel,)
147
142
  wake_r: numpy.ndarray
148
- The wake radii, shape: (n_sp_sel,)
143
+ The wake radii, shape: (n_st_sel,)
149
144
  ct: numpy.ndarray
150
145
  The ct values of the wake-causing turbines,
151
- shape: (n_sp_sel,)
146
+ shape: (n_st_sel,)
152
147
 
153
148
  Returns
154
149
  -------
155
150
  cl_del: dict
156
151
  The centre line wake deltas. Key: variable name str,
157
- varlue: numpy.ndarray, shape: (n_sp_sel,)
152
+ varlue: numpy.ndarray, shape: (n_st_sel,)
158
153
 
159
154
  """
160
155
  pass
161
156
 
162
- def calc_wakes_spsel_x_r(
157
+ def calc_wakes_x_r(
163
158
  self,
164
159
  algo,
165
160
  mdata,
166
161
  fdata,
167
- pdata,
168
- states_source_turbine,
162
+ tdata,
163
+ downwind_index,
169
164
  x,
170
165
  r,
171
166
  ):
@@ -176,61 +171,57 @@ class TopHatWakeModel(AxisymmetricWakeModel):
176
171
  ----------
177
172
  algo: foxes.core.Algorithm
178
173
  The calculation algorithm
179
- mdata: foxes.core.Data
174
+ mdata: foxes.core.MData
180
175
  The model data
181
- fdata: foxes.core.Data
176
+ fdata: foxes.core.FData
182
177
  The farm data
183
- pdata: foxes.core.Data
184
- The evaluation point data
185
- states_source_turbine: numpy.ndarray
186
- For each state, one turbine index for the
187
- wake causing turbine. Shape: (n_states,)
178
+ tdata: foxes.core.TData
179
+ The target point data
180
+ downwind_index: int
181
+ The index in the downwind order
188
182
  x: numpy.ndarray
189
- The x values, shape: (n_states, n_points)
183
+ The x values, shape: (n_states, n_targets)
190
184
  r: numpy.ndarray
191
185
  The radial values for each x value, shape:
192
- (n_states, n_points, n_r_per_x, 2)
186
+ (n_states, n_targets, n_yz_per_target)
193
187
 
194
188
  Returns
195
189
  -------
196
190
  wdeltas: dict
197
191
  The wake deltas. Key: variable name str,
198
- value: numpy.ndarray, shape: (n_sp_sel, n_r_per_x)
199
- sp_sel: numpy.ndarray of bool
200
- The state-point selection, for which the wake
201
- is non-zero, shape: (n_states, n_points)
192
+ value: numpy.ndarray, shape: (n_st_sel, n_r_per_x)
193
+ st_sel: numpy.ndarray of bool
194
+ The state-target selection, for which the wake
195
+ is non-zero, shape: (n_states, n_targets)
202
196
 
203
197
  """
204
198
  ct = self.get_data(
205
199
  FV.CT,
206
- FC.STATE_POINT,
200
+ FC.STATE_TARGET,
207
201
  lookup="w",
208
202
  fdata=fdata,
209
- pdata=pdata,
210
- states_source_turbine=states_source_turbine,
203
+ tdata=tdata,
204
+ downwind_index=downwind_index,
211
205
  algo=algo,
206
+ upcast=True,
212
207
  )
213
208
 
214
- wake_r = self.calc_wake_radius(
215
- algo, mdata, fdata, pdata, states_source_turbine, x, ct
216
- )
209
+ wake_r = self.calc_wake_radius(algo, mdata, fdata, tdata, downwind_index, x, ct)
217
210
 
218
211
  wdeltas = {}
219
- sp_sel = (ct > 0.0) & (x > 1e-5) & np.any(r < wake_r[:, :, None], axis=2)
220
- if np.any(sp_sel):
221
- x = x[sp_sel]
222
- r = r[sp_sel]
223
- ct = ct[sp_sel]
224
- wake_r = wake_r[sp_sel]
225
-
226
- cl_del = self.calc_centreline_wake_deltas(
227
- algo, mdata, fdata, pdata, states_source_turbine, sp_sel, x, wake_r, ct
212
+ st_sel = (ct > 0) & (x > 0) & np.any(r < wake_r[:, :, None], axis=2)
213
+ if np.any(st_sel):
214
+ x = x[st_sel]
215
+ r = r[st_sel]
216
+ ct = ct[st_sel]
217
+ wake_r = wake_r[st_sel]
218
+
219
+ cl_del = self.calc_centreline(
220
+ algo, mdata, fdata, tdata, downwind_index, st_sel, x, wake_r, ct
228
221
  )
229
222
 
230
- nsel = r >= wake_r[:, None]
223
+ isin = r < wake_r[:, None]
231
224
  for v, wdel in cl_del.items():
232
- wdeltas[v] = np.zeros_like(r)
233
- wdeltas[v][:] = wdel[:, None]
234
- wdeltas[v][nsel] = 0.0
225
+ wdeltas[v] = np.where(isin, wdel[:, None], 0.0)
235
226
 
236
- return wdeltas, sp_sel
227
+ return wdeltas, st_sel
@@ -51,98 +51,92 @@ class WakeMirror(WakeModel):
51
51
  """
52
52
  return [self.wmodel]
53
53
 
54
- def init_wake_deltas(self, algo, mdata, fdata, pdata, wake_deltas):
54
+ def new_wake_deltas(self, algo, mdata, fdata, tdata):
55
55
  """
56
- Initialize wake delta storage.
57
-
58
- They are added on the fly to the wake_deltas dict.
56
+ Creates new empty wake delta arrays.
59
57
 
60
58
  Parameters
61
59
  ----------
62
60
  algo: foxes.core.Algorithm
63
61
  The calculation algorithm
64
- mdata: foxes.core.Data
62
+ mdata: foxes.core.MData
65
63
  The model data
66
- fdata: foxes.core.Data
64
+ fdata: foxes.core.FData
67
65
  The farm data
68
- pdata: foxes.core.Data
69
- The evaluation point data
66
+ tdata: foxes.core.TData
67
+ The target point data
68
+
69
+ Returns
70
+ -------
70
71
  wake_deltas: dict
71
- The wake deltas storage, add wake deltas
72
- on the fly. Keys: Variable name str, for which the
73
- wake delta applies, values: numpy.ndarray with
74
- shape (n_states, n_points, ...)
72
+ Key: variable name, value: The zero filled
73
+ wake deltas, shape: (n_states, n_turbines, n_rpoints, ...)
75
74
 
76
75
  """
77
- self.wmodel.init_wake_deltas(algo, mdata, fdata, pdata, wake_deltas)
76
+ return self.wmodel.new_wake_deltas(algo, mdata, fdata, tdata)
78
77
 
79
- def contribute_to_wake_deltas(
78
+ def contribute(
80
79
  self,
81
80
  algo,
82
81
  mdata,
83
82
  fdata,
84
- pdata,
85
- states_source_turbine,
83
+ tdata,
84
+ downwind_index,
86
85
  wake_coos,
87
86
  wake_deltas,
88
87
  ):
89
88
  """
90
- Calculate the contribution to the wake deltas
91
- by this wake model.
92
-
93
- Modifies wake_deltas on the fly.
89
+ Modifies wake deltas at target points by
90
+ contributions from the specified wake source turbines.
94
91
 
95
92
  Parameters
96
93
  ----------
97
94
  algo: foxes.core.Algorithm
98
95
  The calculation algorithm
99
- mdata: foxes.core.Data
96
+ mdata: foxes.core.MData
100
97
  The model data
101
- fdata: foxes.core.Data
98
+ fdata: foxes.core.FData
102
99
  The farm data
103
- pdata: foxes.core.Data
104
- The evaluation point data
105
- states_source_turbine: numpy.ndarray
106
- For each state, one turbine index for the
107
- wake causing turbine. Shape: (n_states,)
100
+ tdata: foxes.core.TData
101
+ The target point data
102
+ downwind_index: int
103
+ The index of the wake causing turbine
104
+ in the downwnd order
108
105
  wake_coos: numpy.ndarray
109
106
  The wake frame coordinates of the evaluation
110
- points, shape: (n_states, n_points, 3)
107
+ points, shape: (n_states, n_targets, n_tpoints, 3)
111
108
  wake_deltas: dict
112
- The wake deltas, are being modified ob the fly.
113
- Key: Variable name str, for which the
114
- wake delta applies, values: numpy.ndarray with
115
- shape (n_states, n_points, ...)
109
+ The wake deltas. Key: variable name,
110
+ value: numpy.ndarray with shape
111
+ (n_states, n_targets, n_tpoints, ...)
116
112
 
117
113
  """
118
- stsel = (np.arange(algo.n_states), states_source_turbine)
119
- hh = fdata[FV.H][stsel]
120
- self.wmodel.contribute_to_wake_deltas(
121
- algo, mdata, fdata, pdata, states_source_turbine, wake_coos, wake_deltas
114
+ hh = fdata[FV.H][:, downwind_index].copy()
115
+ self.wmodel.contribute(
116
+ algo, mdata, fdata, tdata, downwind_index, wake_coos, wake_deltas
122
117
  )
123
118
 
124
- pdata[FC.POINTS] = pdata[FC.POINTS].copy() # making sure this is no ref
119
+ tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
125
120
 
126
121
  for h in self.heights:
127
122
 
128
- fdata[FV.H][stsel] = hh + 2 * (h - hh)
123
+ fdata[FV.H][:, downwind_index] = hh + 2 * (h - hh)
129
124
 
130
125
  nwcoos = algo.wake_frame.get_wake_coos(
131
- algo, mdata, fdata, pdata, states_source_turbine
126
+ algo, mdata, fdata, tdata, downwind_index
132
127
  )
133
128
 
134
- self.wmodel.contribute_to_wake_deltas(
135
- algo, mdata, fdata, pdata, states_source_turbine, nwcoos, wake_deltas
129
+ self.wmodel.contribute(
130
+ algo, mdata, fdata, tdata, downwind_index, nwcoos, wake_deltas
136
131
  )
137
132
 
138
- fdata[FV.H][stsel] = hh
133
+ fdata[FV.H][:, downwind_index] = hh
139
134
 
140
135
  def finalize_wake_deltas(
141
136
  self,
142
137
  algo,
143
138
  mdata,
144
139
  fdata,
145
- pdata,
146
140
  amb_results,
147
141
  wake_deltas,
148
142
  ):
@@ -155,25 +149,26 @@ class WakeMirror(WakeModel):
155
149
  ----------
156
150
  algo: foxes.core.Algorithm
157
151
  The calculation algorithm
158
- mdata: foxes.core.Data
152
+ mdata: foxes.core.MData
159
153
  The model data
160
- fdata: foxes.core.Data
154
+ fdata: foxes.core.FData
161
155
  The farm data
162
- pdata: foxes.core.Data
163
- The evaluation point data
164
156
  amb_results: dict
165
157
  The ambient results, key: variable name str,
166
- values: numpy.ndarray with shape (n_states, n_points)
158
+ values: numpy.ndarray with shape
159
+ (n_states, n_targets, n_tpoints)
167
160
  wake_deltas: dict
168
- The wake deltas, are being modified ob the fly.
169
- Key: Variable name str, for which the wake delta
170
- applies, values: numpy.ndarray with shape
171
- (n_states, n_points, ...) before evaluation,
172
- numpy.ndarray with shape (n_states, n_points) afterwards
161
+ The wake deltas object at the selected target
162
+ turbines. Key: variable str, value: numpy.ndarray
163
+ with shape (n_states, n_targets, n_tpoints)
173
164
 
174
165
  """
175
166
  self.wmodel.finalize_wake_deltas(
176
- algo, mdata, fdata, pdata, amb_results, wake_deltas
167
+ algo,
168
+ mdata,
169
+ fdata,
170
+ amb_results,
171
+ wake_deltas,
177
172
  )
178
173
 
179
174
 
@@ -45,10 +45,8 @@ class Bastankhah2014(GaussianWakeModel):
45
45
 
46
46
  Parameters
47
47
  ----------
48
- superpositions: dict
49
- The superpositions. Key: variable name str,
50
- value: The wake superposition model name,
51
- will be looked up in model book
48
+ superposition: str
49
+ The wind speed deficit superposition.
52
50
  k: float, optional
53
51
  The wake growth parameter k. If not given here
54
52
  it will be searched in the farm data.
@@ -70,8 +68,16 @@ class Bastankhah2014(GaussianWakeModel):
70
68
 
71
69
  def __repr__(self):
72
70
  k = getattr(self, self.k_var)
73
- s = super().__repr__()
74
- s += f"({self.k_var}={k}, sp={self.superpositions[FV.WS]})"
71
+ iname = (
72
+ self.induction if isinstance(self.induction, str) else self.induction.name
73
+ )
74
+ s = f"{type(self).__name__}"
75
+ s += f"({self.superpositions[FV.WS]}, induction={iname}"
76
+ if k is None:
77
+ s += f", k_var={self.k_var}"
78
+ else:
79
+ s += f", {self.k_var}={k}"
80
+ s += ")"
75
81
  return s
76
82
 
77
83
  def sub_models(self):
@@ -104,38 +110,13 @@ class Bastankhah2014(GaussianWakeModel):
104
110
  self.induction = algo.mbook.axial_induction[self.induction]
105
111
  super().initialize(algo, verbosity, force)
106
112
 
107
- def init_wake_deltas(self, algo, mdata, fdata, pdata, wake_deltas):
108
- """
109
- Initialize wake delta storage.
110
-
111
- They are added on the fly to the wake_deltas dict.
112
-
113
- Parameters
114
- ----------
115
- algo: foxes.core.Algorithm
116
- The calculation algorithm
117
- mdata: foxes.core.Data
118
- The model data
119
- fdata: foxes.core.Data
120
- The farm data
121
- pdata: foxes.core.Data
122
- The evaluation point data
123
- wake_deltas: dict
124
- The wake deltas storage, add wake deltas
125
- on the fly. Keys: Variable name str, for which the
126
- wake delta applies, values: numpy.ndarray with
127
- shape (n_states, n_points, ...)
128
-
129
- """
130
- wake_deltas[FV.WS] = np.zeros((mdata.n_states, pdata.n_points), dtype=FC.DTYPE)
131
-
132
- def calc_amplitude_sigma_spsel(
113
+ def calc_amplitude_sigma(
133
114
  self,
134
115
  algo,
135
116
  mdata,
136
117
  fdata,
137
- pdata,
138
- states_source_turbine,
118
+ tdata,
119
+ downwind_index,
139
120
  x,
140
121
  ):
141
122
  """
@@ -146,72 +127,69 @@ class Bastankhah2014(GaussianWakeModel):
146
127
  ----------
147
128
  algo: foxes.core.Algorithm
148
129
  The calculation algorithm
149
- mdata: foxes.core.Data
130
+ mdata: foxes.core.MData
150
131
  The model data
151
- fdata: foxes.core.Data
132
+ fdata: foxes.core.FData
152
133
  The farm data
153
- pdata: foxes.core.Data
154
- The evaluation point data
155
- states_source_turbine: numpy.ndarray
156
- For each state, one turbine index for the
157
- wake causing turbine. Shape: (n_states,)
134
+ tdata: foxes.core.TData
135
+ The target point data
136
+ downwind_index: int
137
+ The index in the downwind order
158
138
  x: numpy.ndarray
159
- The x values, shape: (n_states, n_points)
139
+ The x values, shape: (n_states, n_targets)
160
140
 
161
141
  Returns
162
142
  -------
163
143
  amsi: tuple
164
144
  The amplitude and sigma, both numpy.ndarray
165
- with shape (n_sp_sel,)
166
- sp_sel: numpy.ndarray of bool
167
- The state-point selection, for which the wake
168
- is non-zero, shape: (n_states, n_points)
145
+ with shape (n_st_sel,)
146
+ st_sel: numpy.ndarray of bool
147
+ The state-target selection, for which the wake
148
+ is non-zero, shape: (n_states, n_targets)
169
149
 
170
150
  """
171
151
  # get ct:
172
152
  ct = self.get_data(
173
153
  FV.CT,
174
- FC.STATE_POINT,
154
+ FC.STATE_TARGET,
175
155
  lookup="w",
176
156
  algo=algo,
177
157
  fdata=fdata,
178
- pdata=pdata,
158
+ tdata=tdata,
159
+ downwind_index=downwind_index,
179
160
  upcast=True,
180
- states_source_turbine=states_source_turbine,
181
161
  )
182
162
 
183
163
  # select targets:
184
- sp_sel = (x > 1e-5) & (ct > 0.0)
185
- if np.any(sp_sel):
164
+ st_sel = (x > 0) & (ct > 0)
165
+ if np.any(st_sel):
186
166
  # apply selection:
187
- x = x[sp_sel]
188
- ct = ct[sp_sel]
167
+ x = x[st_sel]
168
+ ct = ct[st_sel]
189
169
 
190
170
  # get D:
191
171
  D = self.get_data(
192
172
  FV.D,
193
- FC.STATE_POINT,
173
+ FC.STATE_TARGET,
194
174
  lookup="w",
195
175
  algo=algo,
196
176
  fdata=fdata,
197
- pdata=pdata,
177
+ tdata=tdata,
178
+ downwind_index=downwind_index,
198
179
  upcast=True,
199
- states_source_turbine=states_source_turbine,
200
- )
201
- D = D[sp_sel]
180
+ )[st_sel]
202
181
 
203
182
  # get k:
204
183
  k = self.get_data(
205
184
  self.k_var,
206
- FC.STATE_POINT,
185
+ FC.STATE_TARGET,
207
186
  lookup="sw",
208
187
  algo=algo,
209
188
  fdata=fdata,
210
- pdata=pdata,
189
+ tdata=tdata,
190
+ downwind_index=downwind_index,
211
191
  upcast=True,
212
- states_source_turbine=states_source_turbine,
213
- )
214
- k = k[sp_sel]
192
+ )[st_sel]
215
193
 
216
194
  # calculate sigma:
217
195
  # beta = 0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct)
@@ -226,9 +204,9 @@ class Bastankhah2014(GaussianWakeModel):
226
204
 
227
205
  # case no targets:
228
206
  else:
229
- sp_sel = np.zeros_like(x, dtype=bool)
230
- n_sp = np.sum(sp_sel)
207
+ st_sel = np.zeros_like(x, dtype=bool)
208
+ n_sp = np.sum(st_sel)
231
209
  ampld = np.zeros(n_sp, dtype=FC.DTYPE)
232
210
  sigma = np.zeros(n_sp, dtype=FC.DTYPE)
233
211
 
234
- return {FV.WS: (ampld, sigma)}, sp_sel
212
+ return {FV.WS: (ampld, sigma)}, st_sel