foxes 1.1.0.2__py3-none-any.whl → 1.2__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 (131) hide show
  1. docs/source/conf.py +3 -2
  2. examples/dyn_wakes/run.py +2 -2
  3. examples/timelines/run.py +1 -1
  4. foxes/__init__.py +13 -2
  5. foxes/algorithms/downwind/downwind.py +6 -1
  6. foxes/algorithms/downwind/models/init_farm_data.py +5 -2
  7. foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
  8. foxes/algorithms/iterative/iterative.py +1 -1
  9. foxes/algorithms/sequential/sequential.py +4 -3
  10. foxes/config/__init__.py +1 -0
  11. foxes/config/config.py +134 -0
  12. foxes/constants.py +15 -6
  13. foxes/core/algorithm.py +22 -10
  14. foxes/core/data.py +2 -1
  15. foxes/core/engine.py +40 -34
  16. foxes/core/farm_controller.py +4 -3
  17. foxes/core/farm_data_model.py +6 -2
  18. foxes/core/model.py +2 -1
  19. foxes/core/point_data_model.py +4 -2
  20. foxes/core/rotor_model.py +8 -4
  21. foxes/core/turbine_type.py +1 -1
  22. foxes/core/wake_frame.py +7 -5
  23. foxes/core/wake_model.py +6 -1
  24. foxes/data/__init__.py +1 -1
  25. foxes/data/static_data.py +0 -7
  26. foxes/engines/dask.py +4 -3
  27. foxes/engines/single.py +1 -1
  28. foxes/input/__init__.py +1 -1
  29. foxes/input/farm_layout/from_csv.py +3 -1
  30. foxes/input/farm_layout/from_file.py +10 -10
  31. foxes/input/farm_layout/from_json.py +4 -3
  32. foxes/input/farm_layout/grid.py +3 -3
  33. foxes/input/states/create/random_abl_states.py +5 -3
  34. foxes/input/states/field_data_nc.py +22 -14
  35. foxes/input/states/multi_height.py +26 -15
  36. foxes/input/states/one_point_flow.py +6 -5
  37. foxes/input/states/scan_ws.py +4 -1
  38. foxes/input/states/single.py +15 -6
  39. foxes/input/states/slice_data_nc.py +18 -12
  40. foxes/input/states/states_table.py +17 -10
  41. foxes/input/yaml/__init__.py +3 -0
  42. foxes/input/yaml/dict.py +210 -0
  43. foxes/input/yaml/windio/__init__.py +4 -0
  44. foxes/input/{windio → yaml/windio}/get_states.py +7 -7
  45. foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
  46. foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
  47. foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
  48. foxes/input/yaml/windio/read_outputs.py +147 -0
  49. foxes/input/yaml/windio/windio.py +269 -0
  50. foxes/input/yaml/yaml.py +103 -0
  51. foxes/models/partial_wakes/axiwake.py +7 -6
  52. foxes/models/partial_wakes/centre.py +3 -2
  53. foxes/models/partial_wakes/segregated.py +5 -2
  54. foxes/models/point_models/set_uniform_data.py +5 -3
  55. foxes/models/rotor_models/centre.py +2 -2
  56. foxes/models/rotor_models/grid.py +5 -5
  57. foxes/models/rotor_models/levels.py +6 -6
  58. foxes/models/turbine_models/kTI_model.py +3 -1
  59. foxes/models/turbine_models/lookup_table.py +7 -4
  60. foxes/models/turbine_models/power_mask.py +14 -8
  61. foxes/models/turbine_models/sector_management.py +4 -2
  62. foxes/models/turbine_models/set_farm_vars.py +53 -23
  63. foxes/models/turbine_models/table_factors.py +8 -7
  64. foxes/models/turbine_models/yaw2yawm.py +0 -1
  65. foxes/models/turbine_models/yawm2yaw.py +0 -1
  66. foxes/models/turbine_types/CpCt_file.py +6 -3
  67. foxes/models/turbine_types/CpCt_from_two.py +6 -3
  68. foxes/models/turbine_types/PCt_file.py +7 -6
  69. foxes/models/turbine_types/PCt_from_two.py +11 -2
  70. foxes/models/turbine_types/TBL_file.py +3 -4
  71. foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
  72. foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
  73. foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
  74. foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
  75. foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
  76. foxes/models/vertical_profiles/abl_log_ws.py +1 -1
  77. foxes/models/wake_frames/dynamic_wakes.py +17 -9
  78. foxes/models/wake_frames/farm_order.py +4 -3
  79. foxes/models/wake_frames/rotor_wd.py +3 -1
  80. foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
  81. foxes/models/wake_frames/streamlines.py +9 -6
  82. foxes/models/wake_frames/timelines.py +21 -14
  83. foxes/models/wake_frames/yawed_wakes.py +3 -1
  84. foxes/models/wake_models/induction/vortex_sheet.py +0 -1
  85. foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
  86. foxes/models/wake_models/wind/bastankhah14.py +3 -2
  87. foxes/models/wake_models/wind/bastankhah16.py +2 -1
  88. foxes/models/wake_models/wind/turbopark.py +9 -7
  89. foxes/models/wake_superpositions/ws_product.py +0 -1
  90. foxes/output/calc_points.py +7 -4
  91. foxes/output/farm_layout.py +30 -18
  92. foxes/output/farm_results_eval.py +4 -3
  93. foxes/output/grids.py +8 -7
  94. foxes/output/output.py +7 -2
  95. foxes/output/results_writer.py +10 -11
  96. foxes/output/rose_plot.py +38 -20
  97. foxes/output/rotor_point_plots.py +7 -3
  98. foxes/output/slice_data.py +1 -1
  99. foxes/output/state_turbine_map.py +5 -1
  100. foxes/output/state_turbine_table.py +7 -3
  101. foxes/output/turbine_type_curves.py +7 -2
  102. foxes/utils/dict.py +107 -3
  103. foxes/utils/geopandas_utils.py +3 -2
  104. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/METADATA +20 -21
  105. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/RECORD +122 -122
  106. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/WHEEL +1 -1
  107. foxes-1.2.dist-info/entry_points.txt +3 -0
  108. tests/0_consistency/iterative/test_iterative.py +65 -67
  109. tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
  110. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
  111. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
  112. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
  113. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +50 -50
  114. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +51 -52
  115. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +73 -74
  116. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +73 -74
  117. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +51 -49
  118. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
  119. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +61 -62
  120. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +51 -52
  121. examples/windio/run.py +0 -29
  122. foxes/data/states/windio_timeseries_5000.nc +0 -0
  123. foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
  124. foxes/data/windio/__init__.py +0 -0
  125. foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
  126. foxes/input/windio/__init__.py +0 -11
  127. foxes/input/windio/read_outputs.py +0 -172
  128. foxes/input/windio/runner.py +0 -183
  129. foxes/input/windio/windio.py +0 -193
  130. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/LICENSE +0 -0
  131. {foxes-1.1.0.2.dist-info → foxes-1.2.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ from scipy.spatial.distance import cdist
4
4
  from foxes.core import WakeFrame, TData
5
5
  from foxes.utils import wd2uv
6
6
  from foxes.algorithms.iterative import Iterative
7
+ from foxes.config import config
7
8
  import foxes.variables as FV
8
9
  import foxes.constants as FC
9
10
 
@@ -98,12 +99,14 @@ class DynamicWakes(WakeFrame):
98
99
  f"{self.name}: Expecting 'dt_min' for single step timeseries"
99
100
  )
100
101
  self._dt = (
101
- (times[1:] - times[:-1]).astype("timedelta64[s]").astype(FC.ITYPE)
102
+ (times[1:] - times[:-1])
103
+ .astype("timedelta64[s]")
104
+ .astype(config.dtype_int)
102
105
  )
103
106
  else:
104
107
  n = max(len(times) - 1, 1)
105
108
  self._dt = np.full(n, self.dt_min * 60, dtype="timedelta64[s]").astype(
106
- FC.ITYPE
109
+ config.dtype_int
107
110
  )
108
111
  self._dt = np.append(self._dt, self._dt[-1, None], axis=0)
109
112
 
@@ -141,7 +144,7 @@ class DynamicWakes(WakeFrame):
141
144
  The turbine order, shape: (n_states, n_turbines)
142
145
 
143
146
  """
144
- order = np.zeros((fdata.n_states, fdata.n_turbines), dtype=FC.ITYPE)
147
+ order = np.zeros((fdata.n_states, fdata.n_turbines), dtype=config.dtype_int)
145
148
  order[:] = np.arange(fdata.n_turbines)[None, :]
146
149
  return order
147
150
 
@@ -163,10 +166,15 @@ class DynamicWakes(WakeFrame):
163
166
  # compute wakes that start within this chunk: x, y, z, length
164
167
  data = algo.get_from_chunk_store(name=key, mdata=mdata, error=False)
165
168
  if data is None:
166
- data = np.full((n_states, self.max_age, 4), np.nan, dtype=FC.DTYPE)
169
+ data = np.full(
170
+ (n_states, self.max_age, 4), np.nan, dtype=config.dtype_double
171
+ )
167
172
  data[:, 0, :3] = rxyh
168
173
  data[:, 0, 3] = 0
169
- tdt = {v: np.zeros((n_states, 1, 1), dtype=FC.DTYPE) for v in tdi.keys()}
174
+ tdt = {
175
+ v: np.zeros((n_states, 1, 1), dtype=config.dtype_double)
176
+ for v in tdi.keys()
177
+ }
170
178
  pts = data[:, 0, :3].copy()
171
179
  for age in range(self.max_age - 1):
172
180
  if age == n_states:
@@ -259,7 +267,7 @@ class DynamicWakes(WakeFrame):
259
267
  n_pts = len(pts)
260
268
 
261
269
  tdt = {
262
- v: np.zeros((n_states, n_pts, 1), dtype=FC.DTYPE)
270
+ v: np.zeros((n_states, n_pts, 1), dtype=config.dtype_double)
263
271
  for v in algo.states.output_point_vars(algo)
264
272
  }
265
273
 
@@ -368,9 +376,9 @@ class DynamicWakes(WakeFrame):
368
376
  i0 = mdata.states_i0(counter=True)
369
377
 
370
378
  # initialize:
371
- wcoos = np.full((n_states, n_points, 3), 1e20, dtype=FC.DTYPE)
379
+ wcoos = np.full((n_states, n_points, 3), 1e20, dtype=config.dtype_double)
372
380
  wcoos[:, :, 2] = points[:, :, 2] - rxyh[:, None, 2]
373
- wake_si = np.zeros((n_states, n_points), dtype=FC.ITYPE)
381
+ wake_si = np.zeros((n_states, n_points), dtype=config.dtype_int)
374
382
  wake_si[:] = i0 + np.arange(n_states)[:, None]
375
383
 
376
384
  # find nearest wake point:
@@ -400,7 +408,7 @@ class DynamicWakes(WakeFrame):
400
408
  if np.any(~sel):
401
409
  nx[~sel] -= wdata[sts[~sel], ags[~sel] - 1, :2]
402
410
  dx = np.linalg.norm(nx, axis=-1)
403
- nx /= dx[:, None]
411
+ nx /= dx[:, None] + 1e-14
404
412
 
405
413
  projx = np.einsum("sd,sd->s", dp, nx)
406
414
  sel = (projx > -dx) & (projx < dx)
@@ -1,9 +1,10 @@
1
1
  import numpy as np
2
2
 
3
- import foxes.constants as FC
4
- from .rotor_wd import RotorWD
3
+ from foxes.config import config
5
4
  from foxes.core import WakeFrame
6
5
 
6
+ from .rotor_wd import RotorWD
7
+
7
8
 
8
9
  class FarmOrder(WakeFrame):
9
10
  """
@@ -90,7 +91,7 @@ class FarmOrder(WakeFrame):
90
91
  The turbine order, shape: (n_states, n_turbines)
91
92
 
92
93
  """
93
- order = np.zeros((fdata.n_states, fdata.n_turbines), dtype=FC.ITYPE)
94
+ order = np.zeros((fdata.n_states, fdata.n_turbines), dtype=config.dtype_int)
94
95
  order[:] = np.arange(fdata.n_turbines)[None, :]
95
96
 
96
97
  return order
@@ -2,6 +2,8 @@ import numpy as np
2
2
 
3
3
  from foxes.core import WakeFrame
4
4
  from foxes.utils import wd2uv
5
+ from foxes.config import config
6
+
5
7
  import foxes.variables as FV
6
8
  import foxes.constants as FC
7
9
 
@@ -104,7 +106,7 @@ class RotorWD(WakeFrame):
104
106
 
105
107
  wd = fdata[self.var_wd][:, downwind_index]
106
108
 
107
- nax = np.zeros((n_states, 3, 3), dtype=FC.DTYPE)
109
+ nax = np.zeros((n_states, 3, 3), dtype=config.dtype_double)
108
110
  n = nax[:, 0, :2]
109
111
  n[:] = wd2uv(wd, axis=-1)
110
112
  m = nax[:, 1, :2]
@@ -3,9 +3,10 @@ from scipy.spatial.distance import cdist
3
3
 
4
4
  from foxes.utils import wd2uv
5
5
  from foxes.core.data import TData
6
+ from foxes.config import config
7
+ from foxes.algorithms.sequential import Sequential
6
8
  import foxes.variables as FV
7
9
  import foxes.constants as FC
8
- from foxes.algorithms.sequential import Sequential
9
10
 
10
11
  from .farm_order import FarmOrder
11
12
 
@@ -80,19 +81,25 @@ class SeqDynamicWakes(FarmOrder):
80
81
  f"{self.name}: Expecting 'dt_min' for single step timeseries"
81
82
  )
82
83
  self._dt = (
83
- (times[1:] - times[:-1]).astype("timedelta64[s]").astype(FC.ITYPE)
84
+ (times[1:] - times[:-1])
85
+ .astype("timedelta64[s]")
86
+ .astype(config.dtype_int)
84
87
  )
85
88
  else:
86
89
  n = max(len(times) - 1, 1)
87
90
  self._dt = np.full(n, self.dt_min * 60, dtype="timedelta64[s]").astype(
88
- FC.ITYPE
91
+ config.dtype_int
89
92
  )
90
93
 
91
94
  # init wake traces data:
92
- self._traces_p = np.zeros((algo.n_states, algo.n_turbines, 3), dtype=FC.DTYPE)
93
- self._traces_v = np.zeros((algo.n_states, algo.n_turbines, 3), dtype=FC.DTYPE)
95
+ self._traces_p = np.zeros(
96
+ (algo.n_states, algo.n_turbines, 3), dtype=config.dtype_double
97
+ )
98
+ self._traces_v = np.zeros(
99
+ (algo.n_states, algo.n_turbines, 3), dtype=config.dtype_double
100
+ )
94
101
  self._traces_l = np.full(
95
- (algo.n_states, algo.n_turbines), np.nan, dtype=FC.DTYPE
102
+ (algo.n_states, algo.n_turbines), np.nan, dtype=config.dtype_double
96
103
  )
97
104
 
98
105
  def calc_order(self, algo, mdata, fdata):
@@ -192,7 +199,7 @@ class SeqDynamicWakes(FarmOrder):
192
199
  del dists
193
200
 
194
201
  # project:
195
- wcoos = np.full((n_states, n_points, 3), 1e20, dtype=FC.DTYPE)
202
+ wcoos = np.full((n_states, n_points, 3), 1e20, dtype=config.dtype_double)
196
203
  wcoos[0, :, 2] = points[0, :, 2] - fdata[FV.TXYH][0, downwind_index, None, 2]
197
204
  nx = self._traces_v[tri, downwind_index, :2]
198
205
  mv = np.linalg.norm(nx, axis=-1)
@@ -4,6 +4,7 @@ from scipy.interpolate import interpn
4
4
  from foxes.core import WakeFrame
5
5
  from foxes.utils import wd2uv
6
6
  from foxes.core.data import TData
7
+ from foxes.config import config
7
8
  import foxes.variables as FV
8
9
  import foxes.constants as FC
9
10
 
@@ -64,7 +65,7 @@ class Streamlines2D(WakeFrame):
64
65
  N = int(self.max_length_km * 1e3 / self.step)
65
66
 
66
67
  # calc data: x, y, z, wd
67
- data = np.zeros((n_states, n_turbines, N, 4), dtype=FC.DTYPE)
68
+ data = np.zeros((n_states, n_turbines, N, 4), dtype=config.dtype_double)
68
69
  for i in range(N):
69
70
 
70
71
  # set streamline start point data (rotor centre):
@@ -86,7 +87,9 @@ class Streamlines2D(WakeFrame):
86
87
  tdata = TData.from_points(
87
88
  data[:, :, i, :3],
88
89
  data={
89
- v: np.full((n_states, n_turbines, 1), np.nan, dtype=FC.DTYPE)
90
+ v: np.full(
91
+ (n_states, n_turbines, 1), np.nan, dtype=config.dtype_double
92
+ )
90
93
  for v in svars
91
94
  },
92
95
  dims={v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in svars},
@@ -151,7 +154,7 @@ class Streamlines2D(WakeFrame):
151
154
  del dists, selp
152
155
 
153
156
  # calculate coordinates:
154
- coos = np.full((n_states, n_points, 3), np.nan, dtype=FC.DTYPE)
157
+ coos = np.full((n_states, n_points, 3), np.nan, dtype=config.dtype_double)
155
158
  coos[:, :, 2] = points[:, :, 2] - data[:, :, 2]
156
159
  delta = points[:, :, :2] - data[:, :, :2]
157
160
  nx = wd2uv(data[:, :, 3])
@@ -193,7 +196,7 @@ class Streamlines2D(WakeFrame):
193
196
 
194
197
  # calculate streamline x coordinates for turbines rotor centre points:
195
198
  # n_states, n_turbines_source, n_turbines_target
196
- coosx = np.zeros((n_states, n_turbines, n_turbines), dtype=FC.DTYPE)
199
+ coosx = np.zeros((n_states, n_turbines, n_turbines), dtype=config.dtype_double)
197
200
  for ti in range(n_turbines):
198
201
  coosx[:, ti, :] = self.get_wake_coos(algo, mdata, fdata, tdata, ti)[
199
202
  :, :, 0, 0
@@ -201,7 +204,7 @@ class Streamlines2D(WakeFrame):
201
204
 
202
205
  # derive turbine order:
203
206
  # TODO: Remove loop over states
204
- order = np.zeros((n_states, n_turbines), dtype=FC.ITYPE)
207
+ order = np.zeros((n_states, n_turbines), dtype=config.dtype_int)
205
208
  for si in range(n_states):
206
209
  order[si] = np.lexsort(keys=coosx[si])
207
210
 
@@ -273,7 +276,7 @@ class Streamlines2D(WakeFrame):
273
276
  xs = self.step * np.arange(n_spts)
274
277
 
275
278
  # interpolate to x of interest:
276
- qts = np.zeros((n_states, n_points, 2), dtype=FC.DTYPE)
279
+ qts = np.zeros((n_states, n_points, 2), dtype=config.dtype_double)
277
280
  qts[:, :, 0] = np.arange(n_states)[:, None]
278
281
  qts[:, :, 1] = np.minimum(x, xs[-1])
279
282
  qts = qts.reshape(n_states * n_points, 2)
@@ -4,6 +4,7 @@ from xarray import Dataset
4
4
  from foxes.core import WakeFrame, MData, FData, TData
5
5
  from foxes.utils import wd2uv
6
6
  from foxes.algorithms.iterative import Iterative
7
+ from foxes.config import config
7
8
  import foxes.variables as FV
8
9
  import foxes.constants as FC
9
10
 
@@ -69,10 +70,16 @@ class Timelines(WakeFrame):
69
70
  raise KeyError(
70
71
  f"{self.name}: Expecting 'dt_min' for single step timeseries"
71
72
  )
72
- dt = (times[1:] - times[:-1]).astype("timedelta64[s]").astype(FC.ITYPE)
73
+ dt = (
74
+ (times[1:] - times[:-1])
75
+ .astype("timedelta64[s]")
76
+ .astype(config.dtype_int)
77
+ )
73
78
  else:
74
79
  n = max(len(times) - 1, 1)
75
- dt = np.full(n, self.dt_min * 60, dtype="timedelta64[s]").astype(FC.ITYPE)
80
+ dt = np.full(n, self.dt_min * 60, dtype="timedelta64[s]").astype(
81
+ config.dtype_int
82
+ )
76
83
 
77
84
  # prepare mdata:
78
85
  data = algo.get_model_data(states)["coords"]
@@ -90,11 +97,11 @@ class Timelines(WakeFrame):
90
97
  # prepare tdata:
91
98
  n_states = states.size()
92
99
  data = {
93
- v: np.zeros((n_states, 1, 1), dtype=FC.DTYPE)
100
+ v: np.zeros((n_states, 1, 1), dtype=config.dtype_double)
94
101
  for v in states.output_point_vars(algo)
95
102
  }
96
103
  pdims = {v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in data.keys()}
97
- points = np.zeros((n_states, 1, 3), dtype=FC.DTYPE)
104
+ points = np.zeros((n_states, 1, 3), dtype=config.dtype_double)
98
105
 
99
106
  # calculate all heights:
100
107
  self.timelines_data = {"dxy": (("height", FC.STATE, "dir"), [])}
@@ -175,7 +182,7 @@ class Timelines(WakeFrame):
175
182
  super().initialize(algo, verbosity)
176
183
 
177
184
  # find turbine hub heights:
178
- t2h = np.zeros(algo.n_turbines, dtype=FC.DTYPE)
185
+ t2h = np.zeros(algo.n_turbines, dtype=config.dtype_double)
179
186
  for ti, t in enumerate(algo.farm.turbines):
180
187
  t2h[ti] = (
181
188
  t.H if t.H is not None else algo.farm_controller.turbine_types[ti].H
@@ -285,7 +292,7 @@ class Timelines(WakeFrame):
285
292
  The turbine order, shape: (n_states, n_turbines)
286
293
 
287
294
  """
288
- order = np.zeros((fdata.n_states, fdata.n_turbines), dtype=FC.ITYPE)
295
+ order = np.zeros((fdata.n_states, fdata.n_turbines), dtype=config.dtype_int)
289
296
  order[:] = np.arange(fdata.n_turbines)[None, :]
290
297
  return order
291
298
 
@@ -331,26 +338,26 @@ class Timelines(WakeFrame):
331
338
  heights = self.timelines_data["height"].to_numpy()
332
339
  data_dxy = self.timelines_data["dxy"].to_numpy()
333
340
 
334
- D = np.zeros((n_states, n_points), dtype=FC.DTYPE)
341
+ D = np.zeros((n_states, n_points), dtype=config.dtype_double)
335
342
  D[:] = fdata[FV.D][:, downwind_index, None]
336
343
 
337
- wcoos = np.full((n_states, n_points, 3), 1e20, dtype=FC.DTYPE)
344
+ wcoos = np.full((n_states, n_points, 3), 1e20, dtype=config.dtype_double)
338
345
  wcoosx = wcoos[:, :, 0]
339
346
  wcoosy = wcoos[:, :, 1]
340
347
  wcoos[:, :, 2] = points[:, :, 2] - rxyz[:, None, 2]
341
348
 
342
349
  i0 = mdata.states_i0(counter=True)
343
350
  i1 = i0 + mdata.n_states
344
- trace_si = np.zeros((n_states, n_points), dtype=FC.ITYPE)
351
+ trace_si = np.zeros((n_states, n_points), dtype=config.dtype_int)
345
352
  trace_si[:] = i0 + np.arange(n_states)[:, None]
346
353
  for hi, h in enumerate(heights):
347
354
  dxy = data_dxy[hi][:i1]
348
355
  precond = theights[:, None] == h
349
356
 
350
- trace_p = np.zeros((n_states, n_points, 2), dtype=FC.DTYPE)
357
+ trace_p = np.zeros((n_states, n_points, 2), dtype=config.dtype_double)
351
358
  trace_p[:] = points[:, :, :2] - rxyz[:, None, :2]
352
- trace_l = np.zeros((n_states, n_points), dtype=FC.DTYPE)
353
- trace_d = np.full((n_states, n_points), np.inf, dtype=FC.DTYPE)
359
+ trace_l = np.zeros((n_states, n_points), dtype=config.dtype_double)
360
+ trace_d = np.full((n_states, n_points), np.inf, dtype=config.dtype_double)
354
361
  h_trace_si = trace_si.copy()
355
362
 
356
363
  # flake8: noqa: F821
@@ -446,12 +453,12 @@ class Timelines(WakeFrame):
446
453
  heights = self.timelines_data["height"].to_numpy()
447
454
  data_dxy = self.timelines_data["dxy"].to_numpy()
448
455
 
449
- points = np.zeros((n_states, n_points, 3), dtype=FC.DTYPE)
456
+ points = np.zeros((n_states, n_points, 3), dtype=config.dtype_double)
450
457
  points[:] = rxyz[:, None, :]
451
458
 
452
459
  trace_dp = np.zeros_like(points[..., :2])
453
460
  trace_l = x.copy()
454
- trace_si = np.zeros((n_states, n_points), dtype=FC.ITYPE)
461
+ trace_si = np.zeros((n_states, n_points), dtype=config.dtype_int)
455
462
  trace_si[:] = np.arange(n_states)[:, None]
456
463
 
457
464
  for hi, h in enumerate(heights):
@@ -5,8 +5,10 @@ from foxes.models.wake_models.wind.bastankhah16 import (
5
5
  Bastankhah2016Model,
6
6
  Bastankhah2016,
7
7
  )
8
+ from foxes.config import config
8
9
  import foxes.variables as FV
9
10
  import foxes.constants as FC
11
+
10
12
  from .rotor_wd import RotorWD
11
13
 
12
14
 
@@ -200,7 +202,7 @@ class YawedWakes(WakeFrame):
200
202
  if np.any(st_sel):
201
203
  # prepare:
202
204
  n_st_sel = np.sum(st_sel)
203
- ydef = np.zeros((n_st_sel,), dtype=FC.DTYPE)
205
+ ydef = np.zeros((n_st_sel,), dtype=config.dtype_double)
204
206
 
205
207
  # collect data:
206
208
  near = self.model.get_data(Bastankhah2016Model.NEAR, mdata)
@@ -1,7 +1,6 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import TurbineInductionModel
4
- from foxes.utils import uv2wd, wd2uv
5
4
  import foxes.variables as FV
6
5
  import foxes.constants as FC
7
6
 
@@ -2,6 +2,7 @@ import numpy as np
2
2
 
3
3
  from foxes.core import WakeK
4
4
  from foxes.models.wake_models.top_hat import TopHatWakeModel
5
+ from foxes.config import config
5
6
  import foxes.variables as FV
6
7
  import foxes.constants as FC
7
8
 
@@ -299,7 +300,7 @@ class CrespoHernandezTIWake(TopHatWakeModel):
299
300
  twoa = 2 * self.induction.ct2a(ct)
300
301
 
301
302
  # prepare output:
302
- wake_deltas = np.zeros(n_targts, dtype=FC.DTYPE)
303
+ wake_deltas = np.zeros(n_targts, dtype=config.dtype_double)
303
304
 
304
305
  # calc near wake length, if not given
305
306
  if self.near_wake_D is None:
@@ -2,6 +2,7 @@ import numpy as np
2
2
 
3
3
  from foxes.core import WakeK
4
4
  from foxes.models.wake_models.gaussian import GaussianWakeModel
5
+ from foxes.config import config
5
6
  import foxes.variables as FV
6
7
  import foxes.constants as FC
7
8
 
@@ -187,7 +188,7 @@ class Bastankhah2014(GaussianWakeModel):
187
188
  else:
188
189
  st_sel = np.zeros_like(x, dtype=bool)
189
190
  n_sp = np.sum(st_sel)
190
- ampld = np.zeros(n_sp, dtype=FC.DTYPE)
191
- sigma = np.zeros(n_sp, dtype=FC.DTYPE)
191
+ ampld = np.zeros(n_sp, dtype=config.dtype_double)
192
+ sigma = np.zeros(n_sp, dtype=config.dtype_double)
192
193
 
193
194
  return {FV.WS: (ampld, sigma)}, st_sel
@@ -2,6 +2,7 @@ import numpy as np
2
2
 
3
3
  from foxes.models.wake_models.dist_sliced import DistSlicedWakeModel
4
4
  from foxes.core import Model, WakeK
5
+ from foxes.config import config
5
6
  import foxes.variables as FV
6
7
  import foxes.constants as FC
7
8
 
@@ -570,7 +571,7 @@ class Bastankhah2016(DistSlicedWakeModel):
570
571
  # select targets:
571
572
  st_sel = self.model.get_data(Bastankhah2016Model.ST_SEL, mdata)
572
573
  n_sp_sel = np.sum(st_sel)
573
- wdeltas = {FV.WS: np.zeros((n_sp_sel, n_y_per_z), dtype=FC.DTYPE)}
574
+ wdeltas = {FV.WS: np.zeros((n_sp_sel, n_y_per_z), dtype=config.dtype_double)}
574
575
  if np.any(st_sel):
575
576
  # apply filter:
576
577
  yz = yz[st_sel]
@@ -2,6 +2,7 @@ import numpy as np
2
2
 
3
3
  from foxes.core import WakeK
4
4
  from foxes.models.wake_models.gaussian import GaussianWakeModel
5
+ from foxes.config import config
5
6
  import foxes.variables as FV
6
7
  import foxes.constants as FC
7
8
 
@@ -188,8 +189,7 @@ class TurbOParkWake(GaussianWakeModel):
188
189
  fdata=fdata,
189
190
  tdata=tdata,
190
191
  downwind_index=downwind_index,
191
- upcast=False,
192
- selection=st_sel,
192
+ upcast=True,
193
193
  )
194
194
 
195
195
  # get k:
@@ -211,6 +211,7 @@ class TurbOParkWake(GaussianWakeModel):
211
211
  epsilon = self.sbeta_factor * np.sqrt(beta)
212
212
  del a, beta
213
213
 
214
+ ati = ati[st_sel]
214
215
  alpha = self.c1 * ati
215
216
  beta = self.c2 * ati / np.sqrt(ct)
216
217
 
@@ -218,7 +219,6 @@ class TurbOParkWake(GaussianWakeModel):
218
219
  sigma = D * (
219
220
  epsilon
220
221
  + k
221
- * ati
222
222
  / beta
223
223
  * (
224
224
  np.sqrt((alpha + beta * x / D) ** 2 + 1)
@@ -246,8 +246,8 @@ class TurbOParkWake(GaussianWakeModel):
246
246
  else:
247
247
  st_sel = np.zeros_like(x, dtype=bool)
248
248
  n_sp = np.sum(st_sel)
249
- ampld = np.zeros(n_sp, dtype=FC.DTYPE)
250
- sigma = np.zeros(n_sp, dtype=FC.DTYPE)
249
+ ampld = np.zeros(n_sp, dtype=config.dtype_double)
250
+ sigma = np.zeros(n_sp, dtype=config.dtype_double)
251
251
 
252
252
  return {FV.WS: (ampld, sigma)}, st_sel
253
253
 
@@ -318,6 +318,8 @@ class TurbOParkWakeIX(GaussianWakeModel):
318
318
  self.induction = induction
319
319
  self.wake_k = WakeK(**wake_k)
320
320
 
321
+ assert not self.wake_k.is_kTI, f"{self.name}: Cannot apply ka or ambka setup"
322
+
321
323
  def __repr__(self):
322
324
  iname = (
323
325
  self.induction if isinstance(self.induction, str) else self.induction.name
@@ -507,8 +509,8 @@ class TurbOParkWakeIX(GaussianWakeModel):
507
509
  else:
508
510
  st_sel = np.zeros_like(x, dtype=bool)
509
511
  n_sp = np.sum(st_sel)
510
- ampld = np.zeros(n_sp, dtype=FC.DTYPE)
511
- sigma = np.zeros(n_sp, dtype=FC.DTYPE)
512
+ ampld = np.zeros(n_sp, dtype=config.dtype_double)
513
+ sigma = np.zeros(n_sp, dtype=config.dtype_double)
512
514
 
513
515
  return {FV.WS: (ampld, sigma)}, st_sel
514
516
 
@@ -2,7 +2,6 @@ import numpy as np
2
2
 
3
3
  from foxes.core import WakeSuperposition
4
4
  import foxes.variables as FV
5
- import foxes.constants as FC
6
5
 
7
6
 
8
7
  class WSProduct(WakeSuperposition):
@@ -1,9 +1,10 @@
1
1
  import numpy as np
2
2
  from xarray import Dataset
3
3
 
4
- import foxes.constants as FC
5
- import foxes.variables as FV
4
+ from foxes.config import config
6
5
  from foxes.utils import write_nc
6
+ import foxes.variables as FV
7
+ import foxes.constants as FC
7
8
 
8
9
  from .output import Output
9
10
 
@@ -67,7 +68,7 @@ class PointCalculator(Output):
67
68
  weight_turbine: int, optional
68
69
  Index of the turbine from which to take the weight
69
70
  to_file: str, optional
70
- Path to the output netCDF file
71
+ The output netCDF file name
71
72
  write_vars: list of str
72
73
  The variables to be written to file, or None
73
74
  for all
@@ -87,7 +88,9 @@ class PointCalculator(Output):
87
88
  pts = points
88
89
  p_has_s = True
89
90
  elif points.shape[-1] == 3 and len(points.shape) == 2:
90
- pts = np.zeros([self.algo.n_states] + list(points.shape), dtype=FC.DTYPE)
91
+ pts = np.zeros(
92
+ [self.algo.n_states] + list(points.shape), dtype=config.dtype_double
93
+ )
91
94
  pts[:] = points[None, :]
92
95
  p_has_s = False
93
96
  else:
@@ -4,7 +4,7 @@ import pandas as pd
4
4
  import matplotlib.pyplot as plt
5
5
  from mpl_toolkits.axes_grid1 import make_axes_locatable
6
6
 
7
- import foxes.constants as FC
7
+ from foxes.config import config
8
8
  import foxes.variables as FV
9
9
  from foxes.output.output import Output
10
10
 
@@ -31,7 +31,13 @@ class FarmLayoutOutput(Output):
31
31
  """
32
32
 
33
33
  def __init__(
34
- self, farm, farm_results=None, from_results=False, results_state=None, D=None
34
+ self,
35
+ farm,
36
+ farm_results=None,
37
+ from_results=False,
38
+ results_state=None,
39
+ D=None,
40
+ **kwargs,
35
41
  ):
36
42
  """
37
43
  Constructor.
@@ -48,8 +54,11 @@ class FarmLayoutOutput(Output):
48
54
  The state index, for from_res
49
55
  D: float, optional
50
56
  The rotor diameter, if not from data
57
+ kwargs: dict, optional
58
+ Additional parameters for the base class
51
59
 
52
60
  """
61
+ super().__init__(**kwargs)
53
62
  self.farm = farm
54
63
  self.fres = farm_results
55
64
  self.from_res = from_results
@@ -75,7 +84,7 @@ class FarmLayoutOutput(Output):
75
84
 
76
85
  """
77
86
 
78
- data = np.zeros([self.farm.n_turbines, 3], dtype=FC.DTYPE)
87
+ data = np.zeros([self.farm.n_turbines, 3], dtype=config.dtype_double)
79
88
 
80
89
  if self.from_res:
81
90
  data[:, 0] = self.fres[FV.X][self.rstate]
@@ -284,14 +293,14 @@ class FarmLayoutOutput(Output):
284
293
 
285
294
  return ax
286
295
 
287
- def write_plot(self, file_path=None, fontsize=8, **kwargs):
296
+ def write_plot(self, file_name=None, fontsize=8, **kwargs):
288
297
  """
289
298
  Writes the layout plot to file.
290
299
 
291
300
  Parameters
292
301
  ----------
293
- file_path: str
294
- The file into which to plot, or None
302
+ file_name: str
303
+ Name of the file into which to plot, or None
295
304
  for default
296
305
  fontsize: int
297
306
  Size of the turbine numbers
@@ -303,8 +312,9 @@ class FarmLayoutOutput(Output):
303
312
  ax = self.get_figure(fontsize=fontsize, ret_im=False, **kwargs)
304
313
  fig = ax.get_figure()
305
314
 
306
- fname = file_path if file_path is not None else self.farm.name + ".png"
307
- fig.savefig(fname, bbox_inches="tight")
315
+ fname = file_name if file_name is not None else self.farm.name + ".png"
316
+ fpath = self.get_fpath(fname)
317
+ fig.savefig(fpath, bbox_inches="tight")
308
318
 
309
319
  plt.close(fig)
310
320
 
@@ -325,14 +335,14 @@ class FarmLayoutOutput(Output):
325
335
  fname = file_path if file_path is not None else self.farm.name + ".xyh"
326
336
  np.savetxt(fname, data, header="x y h")
327
337
 
328
- def write_csv(self, file_path=None, type_col=None, algo=None):
338
+ def write_csv(self, file_name=None, type_col=None, algo=None):
329
339
  """
330
340
  Writes csv layout file.
331
341
 
332
342
  Parameters
333
343
  ----------
334
- file_path: str
335
- The file into which to plot, or None
344
+ file_name: str
345
+ Name of the file into which to plot, or None
336
346
  for default
337
347
  type_col: str, optional
338
348
  Name of the turbine type column
@@ -343,7 +353,8 @@ class FarmLayoutOutput(Output):
343
353
 
344
354
  data = self.get_layout_data()
345
355
 
346
- fname = file_path if file_path is not None else self.farm.name + ".csv"
356
+ fname = file_name if file_name is not None else self.farm.name + ".csv"
357
+ fpath = self.get_fpath(fname)
347
358
 
348
359
  lyt = pd.DataFrame(index=range(len(data)), columns=["name", "x", "y", "h", "D"])
349
360
  lyt.index.name = "index"
@@ -356,22 +367,23 @@ class FarmLayoutOutput(Output):
356
367
  if type_col is not None:
357
368
  lyt[type_col] = [m.name for m in algo.farm_controller.turbine_types]
358
369
 
359
- lyt.to_csv(fname)
370
+ lyt.to_csv(fpath)
360
371
 
361
- def write_json(self, file_path=None):
372
+ def write_json(self, file_name=None):
362
373
  """
363
374
  Writes xyh layout file.
364
375
 
365
376
  Parameters
366
377
  ----------
367
- file_path: str
368
- The file into which to plot, or None
378
+ file_name: str
379
+ Name of the file into which to plot, or None
369
380
  for default
370
381
 
371
382
  """
372
383
 
373
384
  data = self.get_layout_dict()
374
385
 
375
- fname = file_path if file_path is not None else self.farm.name + ".json"
376
- with open(fname, "w") as outfile:
386
+ fname = file_name if file_name is not None else self.farm.name + ".json"
387
+ fpath = self.get_fpath(fname)
388
+ with open(fpath, "w") as outfile:
377
389
  json.dump(data, outfile, indent=4)