foxes 0.8.2__py3-none-any.whl → 1.0__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.
- docs/source/conf.py +353 -0
- examples/abl_states/run.py +160 -0
- examples/compare_rotors_pwakes/run.py +217 -0
- examples/compare_wakes/run.py +241 -0
- examples/dyn_wakes/run.py +311 -0
- examples/field_data_nc/run.py +121 -0
- examples/induction_RHB/run.py +201 -0
- examples/multi_height/run.py +113 -0
- examples/power_mask/run.py +249 -0
- examples/random_timeseries/run.py +210 -0
- examples/scan_row/run.py +193 -0
- examples/sector_management/run.py +162 -0
- examples/sequential/run.py +209 -0
- examples/single_state/run.py +201 -0
- examples/states_lookup_table/run.py +137 -0
- examples/streamline_wakes/run.py +138 -0
- examples/tab_file/run.py +142 -0
- examples/timelines/run.py +267 -0
- examples/timeseries/run.py +183 -0
- examples/timeseries_slurm/run.py +185 -0
- examples/wind_rose/run.py +141 -0
- examples/windio/run.py +29 -0
- examples/yawed_wake/run.py +196 -0
- foxes/__init__.py +4 -8
- foxes/algorithms/__init__.py +1 -1
- foxes/algorithms/downwind/downwind.py +232 -101
- foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -6
- foxes/algorithms/downwind/models/init_farm_data.py +1 -1
- foxes/algorithms/downwind/models/point_wakes_calc.py +5 -6
- foxes/algorithms/downwind/models/reorder_farm_output.py +0 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +4 -2
- foxes/algorithms/iterative/iterative.py +73 -33
- foxes/algorithms/iterative/models/farm_wakes_calc.py +11 -6
- foxes/algorithms/sequential/models/plugin.py +1 -1
- foxes/algorithms/sequential/sequential.py +126 -255
- foxes/constants.py +17 -2
- foxes/core/__init__.py +1 -0
- foxes/core/algorithm.py +631 -146
- foxes/core/data.py +252 -20
- foxes/core/data_calc_model.py +13 -289
- foxes/core/engine.py +630 -0
- foxes/core/farm_controller.py +37 -9
- foxes/core/farm_data_model.py +15 -0
- foxes/core/model.py +133 -80
- foxes/core/point_data_model.py +15 -0
- foxes/core/rotor_model.py +27 -21
- foxes/core/states.py +16 -0
- foxes/core/turbine_type.py +28 -0
- foxes/core/wake_frame.py +22 -4
- foxes/core/wake_model.py +2 -3
- foxes/data/windio/windio_5turbines_timeseries.yaml +23 -1
- foxes/engines/__init__.py +16 -0
- foxes/engines/dask.py +975 -0
- foxes/engines/default.py +75 -0
- foxes/engines/futures.py +72 -0
- foxes/engines/mpi.py +38 -0
- foxes/engines/multiprocess.py +74 -0
- foxes/engines/numpy.py +185 -0
- foxes/engines/pool.py +263 -0
- foxes/engines/single.py +139 -0
- foxes/input/farm_layout/__init__.py +1 -0
- foxes/input/farm_layout/from_csv.py +4 -0
- foxes/input/farm_layout/from_json.py +1 -1
- foxes/input/farm_layout/grid.py +2 -2
- foxes/input/farm_layout/ring.py +65 -0
- foxes/input/farm_layout/row.py +2 -2
- foxes/input/states/__init__.py +6 -0
- foxes/input/states/create/random_abl_states.py +1 -1
- foxes/input/states/field_data_nc.py +157 -32
- foxes/input/states/multi_height.py +127 -13
- foxes/input/states/one_point_flow.py +577 -0
- foxes/input/states/scan_ws.py +73 -2
- foxes/input/states/states_table.py +204 -35
- foxes/input/windio/__init__.py +1 -1
- foxes/input/windio/get_states.py +44 -23
- foxes/input/windio/read_attributes.py +41 -16
- foxes/input/windio/read_farm.py +116 -102
- foxes/input/windio/read_fields.py +13 -6
- foxes/input/windio/read_outputs.py +63 -22
- foxes/input/windio/runner.py +31 -17
- foxes/input/windio/windio.py +36 -22
- foxes/models/ground_models/wake_mirror.py +8 -4
- foxes/models/model_book.py +29 -18
- foxes/models/partial_wakes/rotor_points.py +3 -3
- foxes/models/rotor_models/centre.py +4 -0
- foxes/models/rotor_models/grid.py +22 -23
- foxes/models/rotor_models/levels.py +4 -5
- foxes/models/turbine_models/calculator.py +0 -2
- foxes/models/turbine_models/lookup_table.py +27 -2
- foxes/models/turbine_models/rotor_centre_calc.py +4 -3
- foxes/models/turbine_models/set_farm_vars.py +103 -34
- foxes/models/turbine_types/PCt_file.py +24 -0
- foxes/models/turbine_types/PCt_from_two.py +24 -0
- foxes/models/turbine_types/__init__.py +1 -0
- foxes/models/turbine_types/lookup.py +316 -0
- foxes/models/turbine_types/null_type.py +50 -0
- foxes/models/turbine_types/wsrho2PCt_from_two.py +24 -0
- foxes/models/turbine_types/wsti2PCt_from_two.py +24 -0
- foxes/models/vertical_profiles/data_profile.py +1 -1
- foxes/models/wake_frames/__init__.py +1 -0
- foxes/models/wake_frames/dynamic_wakes.py +424 -0
- foxes/models/wake_frames/farm_order.py +23 -3
- foxes/models/wake_frames/rotor_wd.py +4 -2
- foxes/models/wake_frames/seq_dynamic_wakes.py +56 -63
- foxes/models/wake_frames/streamlines.py +19 -20
- foxes/models/wake_frames/timelines.py +328 -127
- foxes/models/wake_frames/yawed_wakes.py +4 -1
- foxes/models/wake_models/dist_sliced.py +1 -3
- foxes/models/wake_models/induction/rankine_half_body.py +4 -4
- foxes/models/wake_models/induction/rathmann.py +2 -2
- foxes/models/wake_models/induction/self_similar.py +2 -2
- foxes/models/wake_models/induction/vortex_sheet.py +2 -2
- foxes/models/wake_models/ti/iec_ti.py +34 -17
- foxes/models/wake_models/top_hat.py +1 -1
- foxes/models/wake_models/wind/bastankhah14.py +2 -2
- foxes/models/wake_models/wind/bastankhah16.py +8 -7
- foxes/models/wake_models/wind/jensen.py +1 -1
- foxes/models/wake_models/wind/turbopark.py +2 -2
- foxes/output/__init__.py +4 -1
- foxes/output/farm_layout.py +2 -2
- foxes/output/flow_plots_2d/__init__.py +0 -1
- foxes/output/flow_plots_2d/flow_plots.py +70 -30
- foxes/output/grids.py +91 -21
- foxes/output/seq_plugins/__init__.py +2 -0
- foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +62 -20
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
- foxes/output/slice_data.py +131 -111
- foxes/output/state_turbine_map.py +18 -13
- foxes/output/state_turbine_table.py +19 -19
- foxes/utils/__init__.py +1 -1
- foxes/utils/dev_utils.py +42 -0
- foxes/utils/dict.py +1 -1
- foxes/utils/factory.py +147 -52
- foxes/utils/pandas_helpers.py +4 -3
- foxes/utils/wind_dir.py +0 -2
- foxes/utils/xarray_utils.py +23 -13
- foxes/variables.py +37 -0
- {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/METADATA +71 -33
- foxes-1.0.dist-info/RECORD +307 -0
- {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/WHEEL +1 -1
- foxes-1.0.dist-info/top_level.txt +4 -0
- tests/0_consistency/iterative/test_iterative.py +92 -0
- tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
- tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
- tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
- tests/3_examples/test_examples.py +34 -0
- foxes/VERSION +0 -1
- foxes/output/flow_plots_2d.py +0 -0
- foxes/utils/runners/__init__.py +0 -1
- foxes/utils/runners/runners.py +0 -280
- foxes-0.8.2.dist-info/RECORD +0 -247
- foxes-0.8.2.dist-info/top_level.txt +0 -1
- foxes-0.8.2.dist-info/zip-safe +0 -1
- {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/LICENSE +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from xarray import Dataset
|
|
3
3
|
|
|
4
|
-
from foxes.algorithms
|
|
4
|
+
from foxes.algorithms import Iterative
|
|
5
5
|
import foxes.constants as FC
|
|
6
6
|
import foxes.variables as FV
|
|
7
|
-
from foxes.core
|
|
7
|
+
from foxes.core import get_engine
|
|
8
8
|
|
|
9
9
|
from . import models as mdls
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class Sequential(
|
|
12
|
+
class Sequential(Iterative):
|
|
13
13
|
"""
|
|
14
14
|
A sequential calculation of states without chunking.
|
|
15
15
|
|
|
@@ -65,7 +65,6 @@ class Sequential(Downwind):
|
|
|
65
65
|
points=None,
|
|
66
66
|
ambient=False,
|
|
67
67
|
calc_pars={},
|
|
68
|
-
chunks={FC.STATE: None, FC.POINT: 4000},
|
|
69
68
|
plugins=[],
|
|
70
69
|
outputs=None,
|
|
71
70
|
**kwargs,
|
|
@@ -88,8 +87,6 @@ class Sequential(Downwind):
|
|
|
88
87
|
calc_pars: dict
|
|
89
88
|
Parameters for model calculation.
|
|
90
89
|
Key: model name str, value: parameter dict
|
|
91
|
-
chunks: dict
|
|
92
|
-
The xarray.Dataset chunk parameters
|
|
93
90
|
plugins: list of foxes.algorithm.sequential.SequentialIterPlugin
|
|
94
91
|
The plugins, updated with every iteration
|
|
95
92
|
outputs: list of str, optional
|
|
@@ -98,7 +95,7 @@ class Sequential(Downwind):
|
|
|
98
95
|
Additional arguments for Downwind
|
|
99
96
|
|
|
100
97
|
"""
|
|
101
|
-
super().__init__(farm, mdls.SeqState(states), *args,
|
|
98
|
+
super().__init__(farm, mdls.SeqState(states), *args, **kwargs)
|
|
102
99
|
self.ambient = ambient
|
|
103
100
|
self.calc_pars = calc_pars
|
|
104
101
|
self.states0 = self.states.states
|
|
@@ -106,6 +103,10 @@ class Sequential(Downwind):
|
|
|
106
103
|
self.plugins = plugins
|
|
107
104
|
self.outputs = outputs if outputs is not None else self.DEFAULT_FARM_OUTPUTS
|
|
108
105
|
|
|
106
|
+
self._verbo0 = self.verbosity + 1
|
|
107
|
+
self.verbosity -= 1
|
|
108
|
+
get_engine().verbosity -= 2
|
|
109
|
+
|
|
109
110
|
self._i = None
|
|
110
111
|
|
|
111
112
|
@property
|
|
@@ -121,6 +122,13 @@ class Sequential(Downwind):
|
|
|
121
122
|
"""
|
|
122
123
|
return self._i is not None
|
|
123
124
|
|
|
125
|
+
def get_models_data(self, sel=None, isel=None):
|
|
126
|
+
if sel is not None and len(sel):
|
|
127
|
+
raise ValueError(f"calc_points does not support sel, got sel={sel}")
|
|
128
|
+
if isel is not None and len(isel):
|
|
129
|
+
raise ValueError(f"calc_points does not support isel, got isel={isel}")
|
|
130
|
+
return self._model_data.isel({FC.STATE: [self.counter]})
|
|
131
|
+
|
|
124
132
|
def __iter__(self):
|
|
125
133
|
"""Initialize the iterator"""
|
|
126
134
|
|
|
@@ -134,62 +142,39 @@ class Sequential(Downwind):
|
|
|
134
142
|
self._i = 0
|
|
135
143
|
self._counter = 0
|
|
136
144
|
|
|
137
|
-
self.
|
|
138
|
-
|
|
145
|
+
self._it = 0
|
|
146
|
+
mlist, __ = self._collect_farm_models(
|
|
147
|
+
None, self.calc_pars, ambient=self.ambient
|
|
139
148
|
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
self.
|
|
144
|
-
|
|
145
|
-
self.
|
|
146
|
-
if self.verbosity > 0:
|
|
147
|
-
s = "\n".join(
|
|
148
|
-
[
|
|
149
|
-
f" {v}: {d[0]} {d[1].dtype}, shape {d[1].shape}"
|
|
150
|
-
for v, d in self._mdata["data_vars"].items()
|
|
151
|
-
]
|
|
152
|
-
)
|
|
149
|
+
self._calc_farm_vars(mlist)
|
|
150
|
+
self._it = None
|
|
151
|
+
|
|
152
|
+
self._model_data = Dataset(**super().get_models_idata())
|
|
153
|
+
|
|
154
|
+
if self._verbo0 > 0:
|
|
153
155
|
print("\nInput data:\n")
|
|
154
|
-
print(
|
|
155
|
-
print(f"
|
|
156
|
+
print(self._model_data)
|
|
157
|
+
print(f"\nOutput farm variables:", ", ".join(self.farm_vars))
|
|
156
158
|
print()
|
|
157
159
|
|
|
158
|
-
self.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
self._fdata = FData(
|
|
166
|
-
data={
|
|
167
|
-
v: np.zeros((self.n_states, self.n_turbines), dtype=FC.DTYPE)
|
|
160
|
+
self._farm_results = Dataset(
|
|
161
|
+
coords={FC.STATE: self._model_data[FC.STATE].to_numpy()},
|
|
162
|
+
data_vars={
|
|
163
|
+
v: (
|
|
164
|
+
(FC.STATE, FC.TURBINE),
|
|
165
|
+
np.zeros_like(self._model_data[FV.WEIGHT].to_numpy()),
|
|
166
|
+
)
|
|
168
167
|
for v in self.farm_vars
|
|
169
168
|
},
|
|
170
|
-
dims={v: (FC.STATE, FC.TURBINE) for v in self.farm_vars},
|
|
171
|
-
loop_dims=[FC.STATE],
|
|
172
|
-
name="fdata",
|
|
173
169
|
)
|
|
174
|
-
|
|
175
|
-
if
|
|
176
|
-
self.
|
|
177
|
-
|
|
178
|
-
)
|
|
179
|
-
if not self._plist.initialized:
|
|
180
|
-
self._plist.initialize(self, self.verbosity)
|
|
181
|
-
self._pvars = self._plist.output_point_vars(self)
|
|
182
|
-
self.print(f"\nOutput point variables:", ", ".join(self._pvars), "\n")
|
|
183
|
-
|
|
184
|
-
n_points = self.points.shape[1]
|
|
185
|
-
self._tdata = TData.from_points(
|
|
186
|
-
self.points,
|
|
187
|
-
data={
|
|
188
|
-
v: np.zeros((self.n_states, n_points, 1), dtype=FC.DTYPE)
|
|
189
|
-
for v in self._pvars
|
|
190
|
-
},
|
|
191
|
-
dims={v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in self._pvars},
|
|
170
|
+
self._farm_results[FC.TNAME] = ((FC.TURBINE,), self.farm.turbine_names)
|
|
171
|
+
if FV.ORDER in self._farm_results:
|
|
172
|
+
self._farm_results[FV.ORDER] = self._farm_results[FV.ORDER].astype(
|
|
173
|
+
FC.ITYPE
|
|
192
174
|
)
|
|
175
|
+
self._farm_results_dwnd = self._farm_results.copy(deep=True)
|
|
176
|
+
|
|
177
|
+
self._point_results = None
|
|
193
178
|
|
|
194
179
|
for p in self.plugins:
|
|
195
180
|
p.initialize(self)
|
|
@@ -200,45 +185,29 @@ class Sequential(Downwind):
|
|
|
200
185
|
"""Run calculation for current step, then iterate to next"""
|
|
201
186
|
|
|
202
187
|
if self._i < len(self._inds):
|
|
188
|
+
|
|
203
189
|
self._counter = self._i
|
|
204
190
|
self.states._counter = self._i
|
|
205
191
|
self.states._size = 1
|
|
206
192
|
self.states._indx = self._inds[self._i]
|
|
207
193
|
self.states._weight = self._weights[self._i]
|
|
208
194
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
v: d[self._i, None] if self._mdata.dims[v][0] == FC.STATE else d
|
|
212
|
-
for v, d in self._mdata.items()
|
|
213
|
-
},
|
|
214
|
-
dims={v: d for v, d in self._mdata.dims.items()},
|
|
215
|
-
loop_dims=[FC.STATE],
|
|
216
|
-
name="mdata",
|
|
217
|
-
)
|
|
195
|
+
if self._verbo0 > 0:
|
|
196
|
+
print(f"{self.name}: Running state {self.states.index()[0]}")
|
|
218
197
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
dims={v: (FC.STATE, FC.TURBINE) for v in self.farm_vars},
|
|
225
|
-
loop_dims=[FC.STATE],
|
|
226
|
-
name="fdata",
|
|
198
|
+
fres, fres_dnwnd = super().calc_farm(
|
|
199
|
+
outputs=self.farm_vars,
|
|
200
|
+
finalize=False,
|
|
201
|
+
ret_dwnd_order=True,
|
|
202
|
+
**self.calc_pars,
|
|
227
203
|
)
|
|
228
204
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
fres = Dataset(
|
|
236
|
-
coords={FC.STATE: [self.index]},
|
|
237
|
-
data_vars={v: ((FC.STATE, FC.TURBINE), d) for v, d in fres.items()},
|
|
238
|
-
)
|
|
239
|
-
fres[FC.TNAME] = ((FC.TURBINE,), self.farm.turbine_names)
|
|
240
|
-
if FV.ORDER in fres:
|
|
241
|
-
fres[FV.ORDER] = fres[FV.ORDER].astype(FC.ITYPE)
|
|
205
|
+
for v in self._farm_results.data_vars.keys():
|
|
206
|
+
if FC.STATE in self._farm_results[v].dims:
|
|
207
|
+
self._farm_results[v].loc[{FC.STATE: [self.index]}] = fres[v]
|
|
208
|
+
self._farm_results_dwnd[v].loc[{FC.STATE: [self.index]}] = (
|
|
209
|
+
fres_dnwnd[v]
|
|
210
|
+
)
|
|
242
211
|
|
|
243
212
|
if self.points is None:
|
|
244
213
|
for p in self.plugins:
|
|
@@ -248,30 +217,31 @@ class Sequential(Downwind):
|
|
|
248
217
|
return fres
|
|
249
218
|
|
|
250
219
|
else:
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
220
|
+
pres = super().calc_points(fres, points=self.points, finalize=False)
|
|
221
|
+
|
|
222
|
+
if self._point_results is None:
|
|
223
|
+
n_states = self._model_data.sizes[FC.STATE]
|
|
224
|
+
self._point_results = Dataset(
|
|
225
|
+
coords={
|
|
226
|
+
FC.STATE: self._model_data[FC.STATE].to_numpy(),
|
|
227
|
+
**{c: d for c, d in pres.coords.items() if c != FC.STATE},
|
|
228
|
+
},
|
|
229
|
+
data_vars={
|
|
230
|
+
v: (
|
|
231
|
+
d.dims,
|
|
232
|
+
np.zeros([n_states] + list(d.shape[1:]), dtype=d.dtype),
|
|
233
|
+
)
|
|
234
|
+
for v, d in pres.data_vars.items()
|
|
235
|
+
if d.dims[0] == FC.STATE
|
|
236
|
+
},
|
|
237
|
+
)
|
|
238
|
+
for v, d in pres.data_vars.items():
|
|
239
|
+
if FC.STATE not in d.dims:
|
|
240
|
+
self._point_results[v] = d
|
|
241
|
+
|
|
242
|
+
for v in self._point_results.data_vars.keys():
|
|
243
|
+
if FC.STATE in self._point_results[v].dims:
|
|
244
|
+
self._point_results[v].loc[{FC.STATE: [self.index]}] = pres[v]
|
|
275
245
|
|
|
276
246
|
for p in self.plugins:
|
|
277
247
|
p.update(self, fres, pres)
|
|
@@ -280,7 +250,7 @@ class Sequential(Downwind):
|
|
|
280
250
|
return fres, pres
|
|
281
251
|
|
|
282
252
|
else:
|
|
283
|
-
del self.
|
|
253
|
+
del self._model_data
|
|
284
254
|
|
|
285
255
|
self._i = None
|
|
286
256
|
self.states._counter = None
|
|
@@ -365,45 +335,6 @@ class Sequential(Downwind):
|
|
|
365
335
|
"""
|
|
366
336
|
return self.states._weight if self.iterating else None
|
|
367
337
|
|
|
368
|
-
@property
|
|
369
|
-
def mdata(self):
|
|
370
|
-
"""
|
|
371
|
-
Get the current model data
|
|
372
|
-
|
|
373
|
-
Returns
|
|
374
|
-
-------
|
|
375
|
-
d: foxes.core.MData
|
|
376
|
-
The current model data
|
|
377
|
-
|
|
378
|
-
"""
|
|
379
|
-
return self._mdata if self.iterating else None
|
|
380
|
-
|
|
381
|
-
@property
|
|
382
|
-
def fdata(self):
|
|
383
|
-
"""
|
|
384
|
-
Get the current farm data
|
|
385
|
-
|
|
386
|
-
Returns
|
|
387
|
-
-------
|
|
388
|
-
d: foxes.core.FData
|
|
389
|
-
The current farm data
|
|
390
|
-
|
|
391
|
-
"""
|
|
392
|
-
return self._fdata
|
|
393
|
-
|
|
394
|
-
@property
|
|
395
|
-
def tdata(self):
|
|
396
|
-
"""
|
|
397
|
-
Get the current point data
|
|
398
|
-
|
|
399
|
-
Returns
|
|
400
|
-
-------
|
|
401
|
-
d: foxes.core.TData
|
|
402
|
-
The current point data
|
|
403
|
-
|
|
404
|
-
"""
|
|
405
|
-
return self._tdata if self.points is not None and self.iterating else None
|
|
406
|
-
|
|
407
338
|
@property
|
|
408
339
|
def farm_results(self):
|
|
409
340
|
"""
|
|
@@ -415,21 +346,13 @@ class Sequential(Downwind):
|
|
|
415
346
|
The overall farm results
|
|
416
347
|
|
|
417
348
|
"""
|
|
418
|
-
|
|
419
|
-
coords={FC.STATE: self._inds, FC.TURBINE: np.arange(self.n_turbines)},
|
|
420
|
-
data_vars={v: (self._fdata.dims[v], d) for v, d in self._fdata.items()},
|
|
421
|
-
)
|
|
422
|
-
|
|
423
|
-
results[FC.TNAME] = ((FC.TURBINE,), self.farm.turbine_names)
|
|
424
|
-
if FV.ORDER in results:
|
|
425
|
-
results[FV.ORDER] = results[FV.ORDER].astype(FC.ITYPE)
|
|
426
|
-
|
|
427
|
-
return results
|
|
349
|
+
return self._farm_results
|
|
428
350
|
|
|
429
351
|
@property
|
|
430
|
-
def
|
|
352
|
+
def farm_results_downwind(self):
|
|
431
353
|
"""
|
|
432
|
-
|
|
354
|
+
The overall farm results, with turbine
|
|
355
|
+
dimension in downwind order
|
|
433
356
|
|
|
434
357
|
Returns
|
|
435
358
|
-------
|
|
@@ -437,7 +360,7 @@ class Sequential(Downwind):
|
|
|
437
360
|
The overall farm results
|
|
438
361
|
|
|
439
362
|
"""
|
|
440
|
-
return self.
|
|
363
|
+
return self._farm_results_dwnd
|
|
441
364
|
|
|
442
365
|
@property
|
|
443
366
|
def cur_farm_results(self):
|
|
@@ -450,20 +373,7 @@ class Sequential(Downwind):
|
|
|
450
373
|
The current farm results
|
|
451
374
|
|
|
452
375
|
"""
|
|
453
|
-
|
|
454
|
-
i = self.counter
|
|
455
|
-
results = Dataset(
|
|
456
|
-
coords={FC.STATE: [self.index], FC.TURBINE: np.arange(self.n_turbines)},
|
|
457
|
-
data_vars={
|
|
458
|
-
v: (self._fdata.dims[v], d[i, None]) for v, d in self._fdata.items()
|
|
459
|
-
},
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
results[FC.TNAME] = ((FC.TURBINE,), self.farm.turbine_names)
|
|
463
|
-
if FV.ORDER in results:
|
|
464
|
-
results[FV.ORDER] = results[FV.ORDER].astype(FC.ITYPE)
|
|
465
|
-
|
|
466
|
-
return results
|
|
376
|
+
return self._farm_results.isel({FC.STATE: [self.counter]})
|
|
467
377
|
|
|
468
378
|
@property
|
|
469
379
|
def point_results(self):
|
|
@@ -476,18 +386,7 @@ class Sequential(Downwind):
|
|
|
476
386
|
The overall point results
|
|
477
387
|
|
|
478
388
|
"""
|
|
479
|
-
|
|
480
|
-
results = Dataset(
|
|
481
|
-
coords={
|
|
482
|
-
FC.STATE: self._inds,
|
|
483
|
-
FC.TURBINE: np.arange(self.n_turbines),
|
|
484
|
-
FC.POINT: np.arange(n_points),
|
|
485
|
-
FC.XYH: np.arange(3),
|
|
486
|
-
},
|
|
487
|
-
data_vars={v: (self._tdata.dims[v], d) for v, d in self._tdata.items()},
|
|
488
|
-
)
|
|
489
|
-
|
|
490
|
-
return results
|
|
389
|
+
return self._point_results
|
|
491
390
|
|
|
492
391
|
@property
|
|
493
392
|
def cur_point_results(self):
|
|
@@ -500,80 +399,52 @@ class Sequential(Downwind):
|
|
|
500
399
|
The current point results
|
|
501
400
|
|
|
502
401
|
"""
|
|
402
|
+
return self._point_results.isel({FC.STATE: [self.counter]})
|
|
503
403
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
results = Dataset(
|
|
508
|
-
coords={
|
|
509
|
-
FC.STATE: [self.index],
|
|
510
|
-
FC.TURBINE: np.arange(self.n_turbines),
|
|
511
|
-
FC.POINT: np.arange(n_points),
|
|
512
|
-
FC.XYH: np.arange(3),
|
|
513
|
-
},
|
|
514
|
-
data_vars={
|
|
515
|
-
v: (self._tdata.dims[v], d[i, None]) for v, d in self._tdata.items()
|
|
516
|
-
},
|
|
517
|
-
)
|
|
404
|
+
def calc_farm(self):
|
|
405
|
+
"""
|
|
406
|
+
Calculate farm data.
|
|
518
407
|
|
|
519
|
-
|
|
408
|
+
Returns
|
|
409
|
+
-------
|
|
410
|
+
farm_results: xarray.Dataset
|
|
411
|
+
The farm results. The calculated variables have
|
|
412
|
+
dimensions (state, turbine)
|
|
520
413
|
|
|
521
|
-
|
|
414
|
+
"""
|
|
522
415
|
if not self.iterating:
|
|
523
416
|
raise ValueError(f"calc_farm call is only allowed during iterations")
|
|
524
|
-
|
|
525
417
|
return self.cur_farm_results
|
|
526
418
|
|
|
527
|
-
def calc_points(
|
|
419
|
+
def calc_points(
|
|
420
|
+
self,
|
|
421
|
+
farm_results,
|
|
422
|
+
points,
|
|
423
|
+
**kwargs,
|
|
424
|
+
):
|
|
425
|
+
"""
|
|
426
|
+
Calculate data at a given set of points.
|
|
427
|
+
|
|
428
|
+
Parameters
|
|
429
|
+
----------
|
|
430
|
+
farm_results: xarray.Dataset
|
|
431
|
+
The farm results. The calculated variables have
|
|
432
|
+
dimensions (state, turbine)
|
|
433
|
+
points: numpy.ndarray
|
|
434
|
+
The points of interest, shape: (n_states, n_points, 3)
|
|
435
|
+
states_sel: list, optional
|
|
436
|
+
Reduce to selected states
|
|
437
|
+
states_isel: list, optional
|
|
438
|
+
Reduce to the selected states indices
|
|
439
|
+
|
|
440
|
+
Returns
|
|
441
|
+
-------
|
|
442
|
+
point_results: xarray.Dataset
|
|
443
|
+
The point results. The calculated variables have
|
|
444
|
+
dimensions (state, point)
|
|
445
|
+
|
|
446
|
+
"""
|
|
528
447
|
if not self.iterating:
|
|
529
448
|
raise ValueError(f"calc_points call is only allowed during iterations")
|
|
530
449
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
plist, calc_pars = self._collect_point_models(ambient=self.ambient)
|
|
534
|
-
if not plist.initialized:
|
|
535
|
-
plist.initialize(self, self.verbosity)
|
|
536
|
-
pvars = plist.output_point_vars(self)
|
|
537
|
-
|
|
538
|
-
mdata = self.get_models_idata()
|
|
539
|
-
mdata = MData(
|
|
540
|
-
data={v: d[1] for v, d in mdata["data_vars"].items()},
|
|
541
|
-
dims={v: d[0] for v, d in mdata["data_vars"].items()},
|
|
542
|
-
loop_dims=[FC.STATE],
|
|
543
|
-
name="mdata",
|
|
544
|
-
)
|
|
545
|
-
mdata = MData(
|
|
546
|
-
data={
|
|
547
|
-
v: d[self.states.counter, None] if mdata.dims[v][0] == FC.STATE else d
|
|
548
|
-
for v, d in mdata.items()
|
|
549
|
-
},
|
|
550
|
-
dims={v: d for v, d in mdata.dims.items()},
|
|
551
|
-
loop_dims=[FC.STATE],
|
|
552
|
-
name="mdata",
|
|
553
|
-
)
|
|
554
|
-
|
|
555
|
-
fdata = FData(
|
|
556
|
-
data={v: farm_results[v].to_numpy() for v in self.farm_vars},
|
|
557
|
-
dims={v: (FC.STATE, FC.TURBINE) for v in self.farm_vars},
|
|
558
|
-
loop_dims=[FC.STATE],
|
|
559
|
-
name="fdata",
|
|
560
|
-
)
|
|
561
|
-
|
|
562
|
-
tdata = TData.from_points(
|
|
563
|
-
points[0, None],
|
|
564
|
-
data={v: np.zeros((1, n_points, 1), dtype=FC.DTYPE) for v in pvars},
|
|
565
|
-
dims={v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in pvars},
|
|
566
|
-
name="tdata",
|
|
567
|
-
)
|
|
568
|
-
|
|
569
|
-
pres = plist.calculate(self, mdata, fdata, tdata, parameters=calc_pars)
|
|
570
|
-
pres = Dataset(
|
|
571
|
-
coords={FC.STATE: self.states.index()},
|
|
572
|
-
data_vars={
|
|
573
|
-
v: ((FC.STATE, FC.TARGET, FC.TPOINT), d) for v, d in pres.items()
|
|
574
|
-
},
|
|
575
|
-
)
|
|
576
|
-
|
|
577
|
-
# plist.finalize(self, self.verbosity)
|
|
578
|
-
|
|
579
|
-
return pres
|
|
450
|
+
return super().calc_points(farm_results, points, finalize=False, **kwargs)
|
foxes/constants.py
CHANGED
|
@@ -65,8 +65,18 @@ POINTS = "points"
|
|
|
65
65
|
:group: foxes.constants
|
|
66
66
|
"""
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
""
|
|
68
|
+
|
|
69
|
+
ROTOR_POINTS = "rotor_points"
|
|
70
|
+
""" Identifier for rotor points
|
|
71
|
+
:group: foxes.constants
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
ROTOR_WEIGHTS = "rotor_weights"
|
|
75
|
+
""" Identifier for rotor point weights
|
|
76
|
+
:group: foxes.constants
|
|
77
|
+
"""
|
|
78
|
+
AMB_ROTOR_RES = "amb_rotor_res"
|
|
79
|
+
""" Identifier for ambient rotor point results
|
|
70
80
|
:group: foxes.constants
|
|
71
81
|
"""
|
|
72
82
|
|
|
@@ -126,6 +136,11 @@ ITYPE = np.int64
|
|
|
126
136
|
:group: foxes.constants
|
|
127
137
|
"""
|
|
128
138
|
|
|
139
|
+
BLOCK_CONVERGENCE = "block_convergence"
|
|
140
|
+
"""Identifier for convergence blocking signal
|
|
141
|
+
:group: foxes.constants
|
|
142
|
+
"""
|
|
143
|
+
|
|
129
144
|
|
|
130
145
|
KAPPA = 0.41
|
|
131
146
|
""" The Van-Karman constant
|
foxes/core/__init__.py
CHANGED
|
@@ -5,6 +5,7 @@ Abstract classes and core functionality.
|
|
|
5
5
|
from .data import Data, MData, FData, TData
|
|
6
6
|
from .model import Model
|
|
7
7
|
from .data_calc_model import DataCalcModel
|
|
8
|
+
from .engine import Engine, get_engine, has_engine, reset_engine
|
|
8
9
|
from .states import States, ExtendedStates
|
|
9
10
|
from .wind_farm import WindFarm
|
|
10
11
|
from .algorithm import Algorithm
|