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
@@ -11,7 +11,7 @@ def create_random_abl_states(
11
11
  """
12
12
  Create random abl states.
13
13
 
14
- Parameters
14
+ Parameters
15
15
  ----------
16
16
  n_states: int
17
17
  The number of states
@@ -32,7 +32,7 @@ def create_random_abl_states(
32
32
  data: pandas.DataFrame
33
33
  The created states data
34
34
 
35
- :group: input.states
35
+ :group: input.states.create
36
36
 
37
37
  """
38
38
 
@@ -70,6 +70,10 @@ def write_random_abl_states(
70
70
  **kwargs
71
71
  ):
72
72
  """
73
+ Writes random abl states to file
74
+
75
+ Parameters
76
+ ----------
73
77
  file_path: str
74
78
  Path to the file
75
79
  n_states: int
@@ -0,0 +1,56 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ import foxes.variables as FV
5
+
6
+
7
+ def random_timseries_data(
8
+ n_times,
9
+ data_ranges=None,
10
+ start_time="2000-01-01 00:00:00",
11
+ freq="h",
12
+ seed=None,
13
+ iname="Time",
14
+ ):
15
+ """
16
+ Creates random uniform timeseries data
17
+
18
+ Parameters
19
+ ----------
20
+ n_times: int
21
+ The number of time steps
22
+ data_ranges: dict, optional
23
+ The data ranges. Key: variable name,
24
+ value: tuple, [min, max) values
25
+ start_time: str
26
+ The first time stamp in the series
27
+ freq: str
28
+ The time period range frequency
29
+ seed: int, optional
30
+ The random seed
31
+ iname: str
32
+ The index name
33
+
34
+ Returns
35
+ -------
36
+ sdata: pandas.DataFrame
37
+ The timeseries data
38
+
39
+ :group: input.states.create
40
+
41
+ """
42
+ if seed:
43
+ np.random.seed(seed)
44
+
45
+ dranges = {FV.WS: (0.0, 30.0), FV.WD: (0.0, 360.0)}
46
+ if data_ranges:
47
+ dranges.update(data_ranges)
48
+
49
+ times = pd.period_range(start=start_time, periods=n_times, freq=freq)
50
+ times = times.astype(str).astype("datetime64[ns]")
51
+ sdata = pd.DataFrame(
52
+ index=times,
53
+ data={v: np.random.uniform(d[0], d[1], n_times) for v, d in dranges.items()},
54
+ )
55
+ sdata.index.name = iname
56
+ return sdata
@@ -421,7 +421,7 @@ class FieldDataNC(States):
421
421
  """
422
422
  return self._weights
423
423
 
424
- def calculate(self, algo, mdata, fdata, pdata):
424
+ def calculate(self, algo, mdata, fdata, tdata):
425
425
  """ "
426
426
  The main model calculation.
427
427
 
@@ -432,22 +432,26 @@ class FieldDataNC(States):
432
432
  ----------
433
433
  algo: foxes.core.Algorithm
434
434
  The calculation algorithm
435
- mdata: foxes.core.Data
435
+ mdata: foxes.core.MData
436
436
  The model data
437
- fdata: foxes.core.Data
437
+ fdata: foxes.core.FData
438
438
  The farm data
439
- pdata: foxes.core.Data
440
- The point data
439
+ tdata: foxes.core.TData
440
+ The target point data
441
441
 
442
442
  Returns
443
443
  -------
444
444
  results: dict
445
445
  The resulting data, keys: output variable str.
446
- Values: numpy.ndarray with shape (n_states, n_points)
446
+ Values: numpy.ndarray with shape
447
+ (n_states, n_targets, n_tpoints)
447
448
 
448
449
  """
449
450
  # prepare:
450
- points = pdata[FC.POINTS]
451
+ n_states = tdata.n_states
452
+ n_targets = tdata.n_targets
453
+ n_tpoints = tdata.n_tpoints
454
+ points = tdata[FC.TARGETS].reshape(n_states, n_targets * n_tpoints, 3)
451
455
  n_pts = points.shape[1]
452
456
  n_states = fdata.n_states
453
457
 
@@ -571,4 +575,4 @@ class FieldDataNC(States):
571
575
  (n_states, n_pts), self.fixed_vars[v], dtype=FC.DTYPE
572
576
  )
573
577
 
574
- return out
578
+ return {v: d.reshape(n_states, n_targets, n_tpoints) for v, d in out.items()}
@@ -192,13 +192,13 @@ class MultiHeightStates(States):
192
192
  isorg = False
193
193
  else:
194
194
  isorg = True
195
+ data = self.data_source
195
196
 
196
197
  if self.states_sel is not None:
197
198
  data = data.iloc[self.states_sel]
198
199
  elif self.states_loc is not None:
199
200
  data = data.loc[self.states_loc]
200
- else:
201
- data = data
201
+
202
202
  self._N = len(data.index)
203
203
  self._inds = data.index.to_numpy()
204
204
 
@@ -308,7 +308,7 @@ class MultiHeightStates(States):
308
308
  """
309
309
  return self._weights
310
310
 
311
- def calculate(self, algo, mdata, fdata, pdata):
311
+ def calculate(self, algo, mdata, fdata, tdata):
312
312
  """ "
313
313
  The main model calculation.
314
314
 
@@ -319,24 +319,29 @@ class MultiHeightStates(States):
319
319
  ----------
320
320
  algo: foxes.core.Algorithm
321
321
  The calculation algorithm
322
- mdata: foxes.core.Data
322
+ mdata: foxes.core.MData
323
323
  The model data
324
- fdata: foxes.core.Data
324
+ fdata: foxes.core.FData
325
325
  The farm data
326
- pdata: foxes.core.Data
327
- The point data
326
+ tdata: foxes.core.TData
327
+ The target point data
328
328
 
329
329
  Returns
330
330
  -------
331
331
  results: dict
332
332
  The resulting data, keys: output variable str.
333
- Values: numpy.ndarray with shape (n_states, n_points)
333
+ Values: numpy.ndarray with shape
334
+ (n_states, n_targets, n_tpoints)
334
335
 
335
336
  """
337
+ n_states = tdata.n_states
338
+ n_targets = tdata.n_targets
339
+ n_tpoints = tdata.n_tpoints
336
340
  h = mdata[self.H]
337
- z = pdata[FC.POINTS][:, :, 2]
341
+ z = tdata[FC.TARGETS][..., 2].reshape(n_states, n_targets * n_tpoints)
338
342
  n_h = len(h)
339
343
  vrs = list(mdata[self.VARS])
344
+ n_vars = len(vrs)
340
345
 
341
346
  coeffs = np.zeros((n_h, n_h), dtype=FC.DTYPE)
342
347
  np.fill_diagonal(coeffs, 1.0)
@@ -364,24 +369,29 @@ class MultiHeightStates(States):
364
369
  raise KeyError(
365
370
  f"States '{self.name}': Found variable '{FV.WD}', but missing variable '{FV.WS}'"
366
371
  )
367
- uv = np.einsum("shd,sph->spd", uvh, ires)
372
+ uv = np.einsum("shd,sph->spd", uvh, ires).reshape(
373
+ n_states, n_targets, n_tpoints, 2
374
+ )
368
375
  del uvh
369
376
 
370
- ires = np.einsum("svh,sph->svp", mdata[self.DATA], ires)
377
+ ires = np.einsum("svh,sph->vsp", mdata[self.DATA], ires).reshape(
378
+ n_vars, n_states, n_targets, n_tpoints
379
+ )
371
380
 
372
381
  results = {}
373
382
  for v in self.ovars:
374
- results[v] = pdata[v]
375
383
  if has_wd and v == FV.WD:
376
384
  results[v] = uv2wd(uv, axis=-1)
377
385
  elif has_wd and v == FV.WS:
378
386
  results[v] = np.linalg.norm(uv, axis=-1)
379
387
  elif v in self.fixed_vars:
388
+ results[v] = np.zeros((n_states, n_targets, n_tpoints), dtype=FC.DTYPE)
380
389
  results[v][:] = self.fixed_vars[v]
381
390
  elif v in self._solo.keys():
382
- results[v][:] = mdata[self.var(v)][:, None]
391
+ results[v] = np.zeros((n_states, n_targets, n_tpoints), dtype=FC.DTYPE)
392
+ results[v][:] = mdata[self.var(v)][:, None, None]
383
393
  else:
384
- results[v] = ires[:, vrs.index(v)]
394
+ results[v] = ires[vrs.index(v)]
385
395
 
386
396
  return results
387
397
 
@@ -129,7 +129,7 @@ class ScanWS(States):
129
129
  """
130
130
  return np.full((self.N, algo.n_turbines), 1.0 / self.N, dtype=FC.DTYPE)
131
131
 
132
- def calculate(self, algo, mdata, fdata, pdata):
132
+ def calculate(self, algo, mdata, fdata, tdata):
133
133
  """ "
134
134
  The main model calculation.
135
135
 
@@ -140,33 +140,29 @@ class ScanWS(States):
140
140
  ----------
141
141
  algo: foxes.core.Algorithm
142
142
  The calculation algorithm
143
- mdata: foxes.core.Data
143
+ mdata: foxes.core.MData
144
144
  The model data
145
- fdata: foxes.core.Data
145
+ fdata: foxes.core.FData
146
146
  The farm data
147
- pdata: foxes.core.Data
148
- The point data
147
+ tdata: foxes.core.TData
148
+ The target point data
149
149
 
150
150
  Returns
151
151
  -------
152
152
  results: dict
153
153
  The resulting data, keys: output variable str.
154
- Values: numpy.ndarray with shape (n_states, n_points)
154
+ Values: numpy.ndarray with shape
155
+ (n_states, n_targets, n_tpoints)
155
156
 
156
157
  """
157
- pdata[FV.WS][:] = mdata[self.WS][:, None]
158
+ tdata[FV.WS] = np.zeros_like(tdata[FC.TARGETS][..., 0])
159
+ tdata[FV.WS][:] = mdata[self.WS][:, None, None]
158
160
 
159
161
  if self.wd is not None:
160
- pdata[FV.WD] = np.full(
161
- (pdata.n_states, pdata.n_points), self.wd, dtype=FC.DTYPE
162
- )
162
+ tdata[FV.WD] = np.full_like(tdata[FV.WS], self.wd)
163
163
  if self.ti is not None:
164
- pdata[FV.TI] = np.full(
165
- (pdata.n_states, pdata.n_points), self.ti, dtype=FC.DTYPE
166
- )
164
+ tdata[FV.TI] = np.full_like(tdata[FV.WS], self.ti)
167
165
  if self.rho is not None:
168
- pdata[FV.RHO] = np.full(
169
- (pdata.n_states, pdata.n_points), self.rho, dtype=FC.DTYPE
170
- )
166
+ tdata[FV.RHO] = np.full_like(tdata[FV.WS], self.rho)
171
167
 
172
- return {v: pdata[v] for v in self.output_point_vars(algo)}
168
+ return {v: tdata[v] for v in self.output_point_vars(algo)}
@@ -165,7 +165,7 @@ class SingleStateStates(States):
165
165
  """
166
166
  return np.ones((1, algo.n_turbines), dtype=FC.DTYPE)
167
167
 
168
- def calculate(self, algo, mdata, fdata, pdata):
168
+ def calculate(self, algo, mdata, fdata, tdata):
169
169
  """ "
170
170
  The main model calculation.
171
171
 
@@ -176,44 +176,52 @@ class SingleStateStates(States):
176
176
  ----------
177
177
  algo: foxes.core.Algorithm
178
178
  The calculation algorithm
179
- mdata: foxes.core.Data
179
+ mdata: foxes.core.MData
180
180
  The model data
181
- fdata: foxes.core.Data
181
+ fdata: foxes.core.FData
182
182
  The farm data
183
- pdata: foxes.core.Data
184
- The point data
183
+ tdata: foxes.core.TData
184
+ The target point data
185
185
 
186
186
  Returns
187
187
  -------
188
188
  results: dict
189
189
  The resulting data, keys: output variable str.
190
- Values: numpy.ndarray with shape (n_states, n_points)
190
+ Values: numpy.ndarray with shape
191
+ (n_states, n_targets, n_tpoints)
191
192
 
192
193
  """
193
-
194
194
  if self.ws is not None:
195
- pdata[FV.WS] = np.full(
196
- (pdata.n_states, pdata.n_points), self.ws, dtype=FC.DTYPE
195
+ tdata[FV.WS] = np.full(
196
+ (tdata.n_states, tdata.n_targets, tdata.n_tpoints),
197
+ self.ws,
198
+ dtype=FC.DTYPE,
197
199
  )
198
200
  if self.wd is not None:
199
- pdata[FV.WD] = np.full(
200
- (pdata.n_states, pdata.n_points), self.wd, dtype=FC.DTYPE
201
+ tdata[FV.WD] = np.full(
202
+ (tdata.n_states, tdata.n_targets, tdata.n_tpoints),
203
+ self.wd,
204
+ dtype=FC.DTYPE,
201
205
  )
202
206
  if self.ti is not None:
203
- pdata[FV.TI] = np.full(
204
- (pdata.n_states, pdata.n_points), self.ti, dtype=FC.DTYPE
207
+ tdata[FV.TI] = np.full(
208
+ (tdata.n_states, tdata.n_targets, tdata.n_tpoints),
209
+ self.ti,
210
+ dtype=FC.DTYPE,
205
211
  )
206
212
  if self.rho is not None:
207
- pdata[FV.RHO] = np.full(
208
- (pdata.n_states, pdata.n_points), self.rho, dtype=FC.DTYPE
213
+ tdata[FV.RHO] = np.full(
214
+ (tdata.n_states, tdata.n_targets, tdata.n_tpoints),
215
+ self.rho,
216
+ dtype=FC.DTYPE,
209
217
  )
210
218
 
211
219
  if len(self._profiles):
212
- z = pdata[FC.POINTS][:, :, 2]
220
+ z = tdata[FC.TARGETS][..., 2]
213
221
  for k, v in self.profdata.items():
214
- pdata[k] = v
222
+ tdata[k] = v
215
223
  for v, p in self._profiles.items():
216
- pres = p.calculate(pdata, z)
217
- pdata[v] = pres
224
+ pres = p.calculate(tdata, z)
225
+ tdata[v] = pres
218
226
 
219
- return {v: pdata[v] for v in self.output_point_vars(algo)}
227
+ return {v: tdata[v] for v in self.output_point_vars(algo)}
@@ -309,7 +309,7 @@ class StatesTable(States):
309
309
  """
310
310
  return self._weights
311
311
 
312
- def calculate(self, algo, mdata, fdata, pdata):
312
+ def calculate(self, algo, mdata, fdata, tdata):
313
313
  """ "
314
314
  The main model calculation.
315
315
 
@@ -320,37 +320,41 @@ class StatesTable(States):
320
320
  ----------
321
321
  algo: foxes.core.Algorithm
322
322
  The calculation algorithm
323
- mdata: foxes.core.Data
323
+ mdata: foxes.core.MData
324
324
  The model data
325
- fdata: foxes.core.Data
325
+ fdata: foxes.core.FData
326
326
  The farm data
327
- pdata: foxes.core.Data
328
- The point data
327
+ tdata: foxes.core.TData
328
+ The target point data
329
329
 
330
330
  Returns
331
331
  -------
332
332
  results: dict
333
333
  The resulting data, keys: output variable str.
334
- Values: numpy.ndarray with shape (n_states, n_points)
334
+ Values: numpy.ndarray with shape
335
+ (n_states, n_targets, n_tpoints)
335
336
 
336
337
  """
337
- z = pdata[FC.POINTS][:, :, 2]
338
-
339
338
  for i, v in enumerate(self._tvars):
340
- if v in pdata:
341
- pdata[v][:] = mdata[self.DATA][:, i, None]
339
+ if v in tdata:
340
+ tdata[v][:] = mdata[self.DATA][:, i, None, None]
342
341
  else:
343
- pdata[v] = mdata[self.DATA][:, i, None]
344
- pdata.dims[v] = (FC.STATE, FC.POINT)
342
+ tdata[v] = np.zeros(
343
+ (tdata.n_states, tdata.n_targets, tdata.n_tpoints), dtype=FC.DTYPE
344
+ )
345
+ tdata[v][:] = mdata[self.DATA][:, i, None, None]
346
+ tdata.dims[v] = (FC.STATE, FC.TARGET, FC.TPOINT)
345
347
 
346
348
  for v, f in self.fixed_vars.items():
347
- pdata[v] = np.full((pdata.n_states, pdata.n_points), f, dtype=FC.DTYPE)
349
+ tdata[v] = np.full(
350
+ (tdata.n_states, tdata.n_targets, tdata.n_tpoints), f, dtype=FC.DTYPE
351
+ )
348
352
 
353
+ z = tdata[FC.TARGETS][..., 2]
349
354
  for v, p in self._profiles.items():
350
- pres = p.calculate(pdata, z)
351
- pdata[v] = pres
355
+ tdata[v] = p.calculate(tdata, z)
352
356
 
353
- return {v: pdata[v] for v in self.output_point_vars(algo)}
357
+ return {v: tdata[v] for v in self.output_point_vars(algo)}
354
358
 
355
359
  def finalize(self, algo, verbosity=0):
356
360
  """
@@ -472,8 +476,8 @@ class TabStates(StatesTable):
472
476
  )
473
477
  ws0 = 0.5 * (ws0[:-1] + ws0[1:])
474
478
 
475
- n_ws = self._tab_data.dims["ws"]
476
- n_wd = self._tab_data.dims["wd"]
479
+ n_ws = self._tab_data.sizes["ws"]
480
+ n_wd = self._tab_data.sizes["wd"]
477
481
  ws = np.zeros((n_ws, n_wd), dtype=FC.DTYPE)
478
482
  wd = np.zeros((n_ws, n_wd), dtype=FC.DTYPE)
479
483
  ws[:] = ws0[:, None]
@@ -17,7 +17,7 @@ class BetzAxialInduction(AxialInductionModel):
17
17
 
18
18
  """
19
19
 
20
- def __init__(self, ct_max=1):
20
+ def __init__(self, ct_max=0.99999):
21
21
  """
22
22
  Constructor.
23
23
 
@@ -75,9 +75,9 @@ class Turbine2FarmModel(FarmModel):
75
75
  ----------
76
76
  algo: foxes.core.Algorithm
77
77
  The calculation algorithm
78
- mdata: foxes.core.Data
78
+ mdata: foxes.core.MData
79
79
  The model data
80
- fdata: foxes.core.Data
80
+ fdata: foxes.core.FData
81
81
  The farm data
82
82
  **parameters: dict, optional
83
83
  Init parameters forwarded to the turbine model
@@ -14,6 +14,7 @@ from foxes.core import (
14
14
  WakeSuperposition,
15
15
  WakeModel,
16
16
  AxialInductionModel,
17
+ TurbineInductionModel,
17
18
  )
18
19
 
19
20
 
@@ -93,16 +94,16 @@ class ModelBook:
93
94
  self.turbine_types = Dict(name="turbine_types")
94
95
  self.turbine_types["null_type"] = fm.turbine_types.NullType()
95
96
  self.turbine_types["NREL5MW"] = fm.turbine_types.PCtFile(
96
- "NREL-5MW-D126-H90.csv"
97
+ "NREL-5MW-D126-H90.csv", rho=1.225
97
98
  )
98
99
  self.turbine_types["DTU10MW"] = fm.turbine_types.PCtFile(
99
- "DTU-10MW-D178d3-H119.csv"
100
+ "DTU-10MW-D178d3-H119.csv", rho=1.225
100
101
  )
101
102
  self.turbine_types["IEA15MW"] = fm.turbine_types.PCtFile(
102
- "IEA-15MW-D240-H150.csv"
103
+ "IEA-15MW-D240-H150.csv", rho=1.225
103
104
  )
104
105
  self.turbine_types["IWT7.5MW"] = fm.turbine_types.PCtFile(
105
- "IWT-7d5MW-D164-H100.csv"
106
+ "IWT-7d5MW-D164-H100.csv", rho=1.225
106
107
  )
107
108
  if Pct_file is not None:
108
109
  self.turbine_types["Pct"] = fm.turbine_types.PCtFile(Pct_file)
@@ -148,24 +149,21 @@ class ModelBook:
148
149
  name="partial_wakes",
149
150
  rotor_points=fm.partial_wakes.RotorPoints(),
150
151
  top_hat=fm.partial_wakes.PartialTopHat(),
151
- distsliced=fm.partial_wakes.PartialDistSlicedWake(),
152
- auto=fm.partial_wakes.Mapped(),
152
+ centre=fm.partial_wakes.PartialCentre(),
153
153
  )
154
154
  nlst = list(range(2, 11)) + [20]
155
155
  for n in nlst:
156
156
  self.partial_wakes[f"axiwake{n}"] = fm.partial_wakes.PartialAxiwake(n)
157
157
  for n in nlist:
158
- self.partial_wakes[f"distsliced{n**2}"] = (
159
- fm.partial_wakes.PartialDistSlicedWake(n)
160
- )
161
- for n in nlist:
162
- self.partial_wakes[f"grid{n**2}"] = fm.partial_wakes.PartialGrid(n)
158
+ self.partial_wakes[f"grid{n**2}"] = fm.partial_wakes.PartialGrid(n=n)
163
159
 
164
160
  self.wake_frames = Dict(
165
161
  name="wake_frames",
166
162
  rotor_wd=fm.wake_frames.RotorWD(var_wd=FV.WD),
167
163
  rotor_wd_farmo=fm.wake_frames.FarmOrder(),
168
164
  yawed=fm.wake_frames.YawedWakes(),
165
+ yawed_k002=fm.wake_frames.YawedWakes(k=0.02),
166
+ yawed_k004=fm.wake_frames.YawedWakes(k=0.04),
169
167
  )
170
168
  stps = [1.0, 5.0, 10.0, 50.0, 100.0, 500.0]
171
169
  for s in stps:
@@ -246,7 +244,7 @@ class ModelBook:
246
244
  "linear_amb",
247
245
  "linear_amb_lim",
248
246
  "quadratic",
249
- "wquadratic_lim",
247
+ "quadratic_lim",
250
248
  "quadratic_amb",
251
249
  "quadratic_amb_lim",
252
250
  "cubic",
@@ -416,13 +414,12 @@ class ModelBook:
416
414
  )
417
415
 
418
416
  self.wake_models[f"RHB"] = fm.wake_models.induction.RankineHalfBody()
417
+ self.wake_models[f"Rathmann"] = fm.wake_models.induction.Rathmann()
419
418
  self.wake_models[f"SelfSimilar"] = fm.wake_models.induction.SelfSimilar()
420
419
  self.wake_models[f"SelfSimilar2020"] = (
421
420
  fm.wake_models.induction.SelfSimilar2020()
422
421
  )
423
422
 
424
- self.wake_models[f"Rathmann"] = fm.wake_models.induction.Rathmann()
425
-
426
423
  self.sources = Dict(
427
424
  name="sources",
428
425
  point_models=self.point_models,
@@ -518,6 +515,35 @@ class ModelBook:
518
515
  self.sources[model_type][name] = bclass.new(class_name, *args, **kwargs)
519
516
  return self.sources[model_type][name]
520
517
 
518
+ def default_partial_wakes(self, wake_model):
519
+ """
520
+ Gets a default partial wakes model name
521
+ for a given wake model
522
+
523
+ Parameters
524
+ ----------
525
+ wake_model: foxes.core.WakeModel
526
+ The wake model
527
+
528
+ Returns
529
+ -------
530
+ pwake: str
531
+ The partial wake model name
532
+
533
+ """
534
+ if isinstance(wake_model, TurbineInductionModel):
535
+ return "grid9"
536
+ elif isinstance(wake_model, fm.wake_models.TopHatWakeModel):
537
+ return "top_hat"
538
+ elif isinstance(wake_model, fm.wake_models.AxisymmetricWakeModel):
539
+ return "axiwake6"
540
+ elif isinstance(wake_model, fm.wake_models.DistSlicedWakeModel):
541
+ return "grid9"
542
+ else:
543
+ raise TypeError(
544
+ f"No default partial wakes model defined for wake model type '{type(wake_model).__name__}'"
545
+ )
546
+
521
547
  def finalize(self, algo, verbosity=0):
522
548
  """
523
549
  Finalizes the model.
@@ -2,9 +2,9 @@
2
2
  Partial wake models.
3
3
  """
4
4
 
5
+ from .centre import PartialCentre
5
6
  from .rotor_points import RotorPoints
6
7
  from .top_hat import PartialTopHat
7
8
  from .axiwake import PartialAxiwake
8
- from .distsliced import PartialDistSlicedWake
9
+ from .segregated import PartialSegregated
9
10
  from .grid import PartialGrid
10
- from .mapped import Mapped