foxes 1.1.1__py3-none-any.whl → 1.2.1__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 +3 -1
- examples/abl_states/run.py +5 -5
- examples/dyn_wakes/run.py +2 -2
- examples/induction/run.py +5 -5
- examples/random_timeseries/run.py +13 -13
- examples/scan_row/run.py +12 -7
- examples/sector_management/run.py +11 -7
- examples/single_state/run.py +5 -5
- examples/tab_file/run.py +1 -1
- examples/timelines/run.py +1 -1
- examples/timeseries/run.py +5 -5
- examples/timeseries_slurm/run.py +5 -5
- examples/wind_rose/run.py +1 -1
- examples/yawed_wake/run.py +5 -5
- foxes/__init__.py +13 -2
- foxes/algorithms/downwind/downwind.py +21 -6
- foxes/algorithms/downwind/models/init_farm_data.py +5 -2
- foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
- foxes/algorithms/iterative/iterative.py +1 -1
- foxes/algorithms/sequential/sequential.py +5 -4
- foxes/config/__init__.py +1 -0
- foxes/config/config.py +134 -0
- foxes/constants.py +15 -6
- foxes/core/algorithm.py +46 -30
- foxes/core/axial_induction_model.py +18 -0
- foxes/core/data.py +2 -1
- foxes/core/engine.py +43 -49
- foxes/core/farm_controller.py +22 -3
- foxes/core/farm_data_model.py +6 -2
- foxes/core/ground_model.py +19 -0
- foxes/core/model.py +2 -1
- foxes/core/partial_wakes_model.py +9 -21
- foxes/core/point_data_model.py +22 -2
- foxes/core/rotor_model.py +9 -21
- foxes/core/states.py +2 -17
- foxes/core/turbine_model.py +2 -18
- foxes/core/turbine_type.py +2 -18
- foxes/core/vertical_profile.py +8 -20
- foxes/core/wake_frame.py +9 -25
- foxes/core/wake_model.py +24 -20
- foxes/core/wake_superposition.py +19 -0
- foxes/data/__init__.py +1 -1
- foxes/data/static_data.py +0 -7
- foxes/engines/dask.py +4 -3
- foxes/engines/single.py +1 -1
- foxes/input/__init__.py +1 -1
- foxes/input/farm_layout/from_csv.py +3 -1
- foxes/input/farm_layout/from_file.py +10 -10
- foxes/input/farm_layout/from_json.py +4 -3
- foxes/input/farm_layout/grid.py +3 -3
- foxes/input/states/__init__.py +1 -1
- foxes/input/states/create/random_abl_states.py +5 -3
- foxes/input/states/field_data_nc.py +36 -15
- foxes/input/states/multi_height.py +26 -15
- foxes/input/states/one_point_flow.py +6 -5
- foxes/input/states/{scan_ws.py → scan.py} +42 -52
- foxes/input/states/single.py +15 -6
- foxes/input/states/slice_data_nc.py +18 -12
- foxes/input/states/states_table.py +17 -10
- foxes/input/yaml/__init__.py +3 -0
- foxes/input/yaml/dict.py +381 -0
- foxes/input/yaml/windio/__init__.py +4 -0
- foxes/input/{windio → yaml/windio}/get_states.py +7 -7
- foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
- foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
- foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
- foxes/input/yaml/windio/read_outputs.py +147 -0
- foxes/input/yaml/windio/windio.py +269 -0
- foxes/input/yaml/yaml.py +103 -0
- foxes/models/partial_wakes/axiwake.py +7 -6
- foxes/models/partial_wakes/centre.py +3 -2
- foxes/models/partial_wakes/segregated.py +5 -2
- foxes/models/point_models/set_uniform_data.py +5 -3
- foxes/models/rotor_models/centre.py +2 -2
- foxes/models/rotor_models/grid.py +5 -5
- foxes/models/rotor_models/levels.py +6 -6
- foxes/models/turbine_models/kTI_model.py +3 -1
- foxes/models/turbine_models/lookup_table.py +7 -4
- foxes/models/turbine_models/power_mask.py +14 -8
- foxes/models/turbine_models/sector_management.py +4 -2
- foxes/models/turbine_models/set_farm_vars.py +53 -23
- foxes/models/turbine_models/table_factors.py +8 -7
- foxes/models/turbine_models/yaw2yawm.py +0 -1
- foxes/models/turbine_models/yawm2yaw.py +0 -1
- foxes/models/turbine_types/CpCt_file.py +6 -3
- foxes/models/turbine_types/CpCt_from_two.py +6 -3
- foxes/models/turbine_types/PCt_file.py +7 -6
- foxes/models/turbine_types/PCt_from_two.py +11 -2
- foxes/models/turbine_types/TBL_file.py +3 -4
- foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
- foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
- foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
- foxes/models/vertical_profiles/abl_log_ws.py +1 -1
- foxes/models/wake_frames/dynamic_wakes.py +17 -9
- foxes/models/wake_frames/farm_order.py +4 -3
- foxes/models/wake_frames/rotor_wd.py +3 -1
- foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
- foxes/models/wake_frames/streamlines.py +9 -6
- foxes/models/wake_frames/timelines.py +21 -14
- foxes/models/wake_frames/yawed_wakes.py +3 -1
- foxes/models/wake_models/induction/vortex_sheet.py +0 -1
- foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
- foxes/models/wake_models/wind/bastankhah14.py +3 -2
- foxes/models/wake_models/wind/bastankhah16.py +2 -1
- foxes/models/wake_models/wind/turbopark.py +9 -7
- foxes/models/wake_superpositions/ws_product.py +0 -1
- foxes/output/__init__.py +2 -1
- foxes/output/calc_points.py +7 -4
- foxes/output/farm_layout.py +30 -18
- foxes/output/farm_results_eval.py +61 -38
- foxes/output/grids.py +8 -7
- foxes/output/output.py +9 -20
- foxes/output/plt.py +19 -0
- foxes/output/results_writer.py +10 -11
- foxes/output/rose_plot.py +448 -224
- foxes/output/rotor_point_plots.py +7 -3
- foxes/output/slice_data.py +1 -1
- foxes/output/state_turbine_map.py +5 -1
- foxes/output/state_turbine_table.py +7 -3
- foxes/output/turbine_type_curves.py +7 -2
- foxes/utils/__init__.py +1 -2
- foxes/utils/dict.py +107 -3
- foxes/utils/geopandas_utils.py +3 -2
- foxes/utils/subclasses.py +69 -0
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/METADATA +18 -18
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/RECORD +145 -145
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/WHEEL +1 -1
- foxes-1.2.1.dist-info/entry_points.txt +3 -0
- tests/0_consistency/iterative/test_iterative.py +65 -67
- tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +57 -52
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +58 -54
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +80 -76
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +80 -76
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +58 -51
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +67 -64
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +58 -54
- examples/windio/run.py +0 -29
- foxes/data/states/windio_timeseries_5000.nc +0 -0
- foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
- foxes/data/windio/__init__.py +0 -0
- foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
- foxes/input/windio/__init__.py +0 -11
- foxes/input/windio/read_outputs.py +0 -172
- foxes/input/windio/runner.py +0 -183
- foxes/input/windio/windio.py +0 -193
- foxes/utils/windrose_plot.py +0 -152
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/LICENSE +0 -0
- {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/top_level.txt +0 -0
foxes/core/turbine_type.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
|
+
from foxes.utils import new_instance
|
|
3
4
|
import foxes.constants as FC
|
|
4
|
-
from foxes.utils import all_subclasses
|
|
5
5
|
|
|
6
6
|
from .turbine_model import TurbineModel
|
|
7
7
|
|
|
@@ -127,20 +127,4 @@ class TurbineType(TurbineModel):
|
|
|
127
127
|
Additional parameters for constructor
|
|
128
128
|
|
|
129
129
|
"""
|
|
130
|
-
|
|
131
|
-
if ttype_type is None:
|
|
132
|
-
return None
|
|
133
|
-
|
|
134
|
-
allc = all_subclasses(cls)
|
|
135
|
-
found = ttype_type in [scls.__name__ for scls in allc]
|
|
136
|
-
|
|
137
|
-
if found:
|
|
138
|
-
for scls in allc:
|
|
139
|
-
if scls.__name__ == ttype_type:
|
|
140
|
-
return scls(*args, **kwargs)
|
|
141
|
-
|
|
142
|
-
else:
|
|
143
|
-
estr = "Turbine type class '{}' is not defined, available types are \n {}".format(
|
|
144
|
-
ttype_type, sorted([i.__name__ for i in allc])
|
|
145
|
-
)
|
|
146
|
-
raise KeyError(estr)
|
|
130
|
+
return new_instance(cls, ttype_type, *args, **kwargs)
|
foxes/core/vertical_profile.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
3
|
from .model import Model
|
|
4
|
-
from foxes.utils import
|
|
4
|
+
from foxes.utils import new_instance
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class VerticalProfile(Model):
|
|
@@ -48,30 +48,18 @@ class VerticalProfile(Model):
|
|
|
48
48
|
pass
|
|
49
49
|
|
|
50
50
|
@classmethod
|
|
51
|
-
def new(cls, profile_type, **kwargs):
|
|
51
|
+
def new(cls, profile_type, *args, **kwargs):
|
|
52
52
|
"""
|
|
53
|
-
Run-time profile factory.
|
|
53
|
+
Run-time vertical profile factory.
|
|
54
54
|
|
|
55
55
|
Parameters
|
|
56
56
|
----------
|
|
57
57
|
profile_type: str
|
|
58
58
|
The selected derived class name
|
|
59
|
+
args: tuple, optional
|
|
60
|
+
Additional parameters for the constructor
|
|
61
|
+
kwargs: dict, optional
|
|
62
|
+
Additional parameters for the constructor
|
|
59
63
|
|
|
60
64
|
"""
|
|
61
|
-
|
|
62
|
-
if profile_type is None:
|
|
63
|
-
return None
|
|
64
|
-
|
|
65
|
-
allc = all_subclasses(cls)
|
|
66
|
-
found = profile_type in [scls.__name__ for scls in allc]
|
|
67
|
-
|
|
68
|
-
if found:
|
|
69
|
-
for scls in allc:
|
|
70
|
-
if scls.__name__ == profile_type:
|
|
71
|
-
return scls(**kwargs)
|
|
72
|
-
|
|
73
|
-
else:
|
|
74
|
-
estr = "Vertical profile type '{}' is not defined, available types are \n {}".format(
|
|
75
|
-
profile_type, sorted([i.__name__ for i in allc])
|
|
76
|
-
)
|
|
77
|
-
raise KeyError(estr)
|
|
65
|
+
return new_instance(cls, profile_type, *args, **kwargs)
|
foxes/core/wake_frame.py
CHANGED
|
@@ -2,9 +2,10 @@ from abc import abstractmethod
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
from scipy.interpolate import interpn
|
|
4
4
|
|
|
5
|
-
from foxes.utils import
|
|
6
|
-
|
|
5
|
+
from foxes.utils import new_instance
|
|
6
|
+
from foxes.config import config
|
|
7
7
|
import foxes.variables as FV
|
|
8
|
+
import foxes.constants as FC
|
|
8
9
|
|
|
9
10
|
from .data import TData
|
|
10
11
|
from .model import Model
|
|
@@ -243,7 +244,7 @@ class WakeFrame(Model):
|
|
|
243
244
|
n_steps += 1
|
|
244
245
|
n_ix = n_steps + 1
|
|
245
246
|
xs = np.arange(xmin, xmin + n_ix * dx, dx)
|
|
246
|
-
xpts = np.zeros((n_states, n_steps), dtype=
|
|
247
|
+
xpts = np.zeros((n_states, n_steps), dtype=config.dtype_double)
|
|
247
248
|
xpts[:] = xs[None, 1:]
|
|
248
249
|
pts = self.get_centreline_points(algo, mdata, fdata, downwind_index, xpts)
|
|
249
250
|
|
|
@@ -251,7 +252,8 @@ class WakeFrame(Model):
|
|
|
251
252
|
tdata = TData.from_points(
|
|
252
253
|
pts,
|
|
253
254
|
data={
|
|
254
|
-
v: np.full((n_states, n_steps, 1), np.nan, dtype=
|
|
255
|
+
v: np.full((n_states, n_steps, 1), np.nan, dtype=config.dtype_double)
|
|
256
|
+
for v in vrs
|
|
255
257
|
},
|
|
256
258
|
dims={v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in vrs},
|
|
257
259
|
)
|
|
@@ -280,13 +282,13 @@ class WakeFrame(Model):
|
|
|
280
282
|
del wcalc, res
|
|
281
283
|
|
|
282
284
|
# collect integration results:
|
|
283
|
-
iresults = np.zeros((n_states, n_ix, n_vars), dtype=
|
|
285
|
+
iresults = np.zeros((n_states, n_ix, n_vars), dtype=config.dtype_double)
|
|
284
286
|
for vi, v in enumerate(variables):
|
|
285
287
|
for i in range(n_steps):
|
|
286
288
|
iresults[:, i + 1, vi] = iresults[:, i, vi] + tdata[v][:, i, 0] * dx
|
|
287
289
|
|
|
288
290
|
# interpolate to x of interest:
|
|
289
|
-
qts = np.zeros((n_states, n_points, 2), dtype=
|
|
291
|
+
qts = np.zeros((n_states, n_points, 2), dtype=config.dtype_double)
|
|
290
292
|
qts[:, :, 0] = np.arange(n_states)[:, None]
|
|
291
293
|
qts[:, :, 1] = x
|
|
292
294
|
qts = qts.reshape(n_states * n_points, 2)
|
|
@@ -316,22 +318,4 @@ class WakeFrame(Model):
|
|
|
316
318
|
Additional parameters for constructor
|
|
317
319
|
|
|
318
320
|
"""
|
|
319
|
-
|
|
320
|
-
if wframe_type is None:
|
|
321
|
-
return None
|
|
322
|
-
|
|
323
|
-
allc = all_subclasses(cls)
|
|
324
|
-
found = wframe_type in [scls.__name__ for scls in allc]
|
|
325
|
-
|
|
326
|
-
if found:
|
|
327
|
-
for scls in allc:
|
|
328
|
-
if scls.__name__ == wframe_type:
|
|
329
|
-
return scls(*args, **kwargs)
|
|
330
|
-
|
|
331
|
-
else:
|
|
332
|
-
estr = (
|
|
333
|
-
"Wake frame type '{}' is not defined, available types are \n {}".format(
|
|
334
|
-
wframe_type, sorted([i.__name__ for i in allc])
|
|
335
|
-
)
|
|
336
|
-
)
|
|
337
|
-
raise KeyError(estr)
|
|
321
|
+
return new_instance(cls, wframe_type, *args, **kwargs)
|
foxes/core/wake_model.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
-
from foxes.utils import
|
|
4
|
+
from foxes.utils import new_instance
|
|
5
5
|
import foxes.variables as FV
|
|
6
6
|
import foxes.constants as FC
|
|
7
7
|
|
|
@@ -141,25 +141,7 @@ class WakeModel(Model):
|
|
|
141
141
|
Additional parameters for constructor
|
|
142
142
|
|
|
143
143
|
"""
|
|
144
|
-
|
|
145
|
-
if wmodel_type is None:
|
|
146
|
-
return None
|
|
147
|
-
|
|
148
|
-
allc = all_subclasses(cls)
|
|
149
|
-
found = wmodel_type in [scls.__name__ for scls in allc]
|
|
150
|
-
|
|
151
|
-
if found:
|
|
152
|
-
for scls in allc:
|
|
153
|
-
if scls.__name__ == wmodel_type:
|
|
154
|
-
return scls(*args, **kwargs)
|
|
155
|
-
|
|
156
|
-
else:
|
|
157
|
-
estr = (
|
|
158
|
-
"Wake model type '{}' is not defined, available types are \n {}".format(
|
|
159
|
-
wmodel_type, sorted([i.__name__ for i in allc])
|
|
160
|
-
)
|
|
161
|
-
)
|
|
162
|
-
raise KeyError(estr)
|
|
144
|
+
return new_instance(cls, wmodel_type, *args, **kwargs)
|
|
163
145
|
|
|
164
146
|
|
|
165
147
|
class TurbineInductionModel(WakeModel):
|
|
@@ -184,6 +166,23 @@ class TurbineInductionModel(WakeModel):
|
|
|
184
166
|
"""
|
|
185
167
|
return False
|
|
186
168
|
|
|
169
|
+
@classmethod
|
|
170
|
+
def new(cls, induction_type, *args, **kwargs):
|
|
171
|
+
"""
|
|
172
|
+
Run-time turbine induction model factory.
|
|
173
|
+
|
|
174
|
+
Parameters
|
|
175
|
+
----------
|
|
176
|
+
induction_type: str
|
|
177
|
+
The selected derived class name
|
|
178
|
+
args: tuple, optional
|
|
179
|
+
Additional parameters for constructor
|
|
180
|
+
kwargs: dict, optional
|
|
181
|
+
Additional parameters for constructor
|
|
182
|
+
|
|
183
|
+
"""
|
|
184
|
+
return new_instance(cls, induction_type, *args, **kwargs)
|
|
185
|
+
|
|
187
186
|
|
|
188
187
|
class WakeK(Model):
|
|
189
188
|
"""
|
|
@@ -259,6 +258,11 @@ class WakeK(Model):
|
|
|
259
258
|
s = f"k_var={self.k_var}"
|
|
260
259
|
return s
|
|
261
260
|
|
|
261
|
+
@property
|
|
262
|
+
def is_kTI(self):
|
|
263
|
+
"""Flag for ka != 0"""
|
|
264
|
+
return self._ka is not None and self._ka != 0
|
|
265
|
+
|
|
262
266
|
@property
|
|
263
267
|
def all_none(self):
|
|
264
268
|
"""Flag for k=ka=kb=None"""
|
foxes/core/wake_superposition.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
|
|
3
|
+
from foxes.utils import new_instance
|
|
4
|
+
|
|
3
5
|
from .model import Model
|
|
4
6
|
|
|
5
7
|
|
|
@@ -106,3 +108,20 @@ class WakeSuperposition(Model):
|
|
|
106
108
|
|
|
107
109
|
"""
|
|
108
110
|
pass
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def new(cls, superp_type, *args, **kwargs):
|
|
114
|
+
"""
|
|
115
|
+
Run-time wake superposition model factory.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
superp_type: str
|
|
120
|
+
The selected derived class name
|
|
121
|
+
args: tuple, optional
|
|
122
|
+
Additional parameters for constructor
|
|
123
|
+
kwargs: dict, optional
|
|
124
|
+
Additional parameters for constructor
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
return new_instance(cls, superp_type, *args, **kwargs)
|
foxes/data/__init__.py
CHANGED
foxes/data/static_data.py
CHANGED
|
@@ -3,7 +3,6 @@ from foxes.utils import DataBook
|
|
|
3
3
|
from . import farms
|
|
4
4
|
from . import states
|
|
5
5
|
from . import power_ct_curves
|
|
6
|
-
from . import windio
|
|
7
6
|
|
|
8
7
|
FARM = "farm"
|
|
9
8
|
""" Static wind farm data identifier
|
|
@@ -20,11 +19,6 @@ PCTCURVE = "power_ct_curve"
|
|
|
20
19
|
:group: data
|
|
21
20
|
"""
|
|
22
21
|
|
|
23
|
-
WINDIO = "windio"
|
|
24
|
-
""" Static windio data identifier
|
|
25
|
-
:group: data
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
22
|
|
|
29
23
|
class StaticData(DataBook):
|
|
30
24
|
"""
|
|
@@ -41,4 +35,3 @@ class StaticData(DataBook):
|
|
|
41
35
|
self.add_data_package(FARM, farms, ".csv")
|
|
42
36
|
self.add_data_package(STATES, states, [".csv", ".csv.gz", ".nc", ".tab"])
|
|
43
37
|
self.add_data_package(PCTCURVE, power_ct_curves, ".csv")
|
|
44
|
-
self.add_data_package(WINDIO, windio, ".yaml")
|
foxes/engines/dask.py
CHANGED
|
@@ -5,6 +5,7 @@ from tqdm import tqdm
|
|
|
5
5
|
|
|
6
6
|
from foxes.core import Engine, MData, FData, TData
|
|
7
7
|
from foxes.utils import import_module
|
|
8
|
+
from foxes.config import config
|
|
8
9
|
import foxes.variables as FV
|
|
9
10
|
import foxes.constants as FC
|
|
10
11
|
|
|
@@ -212,7 +213,7 @@ def _run_as_ufunc(
|
|
|
212
213
|
odims = {v: tuple(out_coords) for v in out_vars}
|
|
213
214
|
odata = {
|
|
214
215
|
v: (
|
|
215
|
-
np.full(oshape, np.nan, dtype=
|
|
216
|
+
np.full(oshape, np.nan, dtype=config.dtype_double)
|
|
216
217
|
if v not in init_vars
|
|
217
218
|
else prev[init_vars.index(v)].copy()
|
|
218
219
|
)
|
|
@@ -264,7 +265,7 @@ def _run_as_ufunc(
|
|
|
264
265
|
|
|
265
266
|
# create output:
|
|
266
267
|
n_vars = len(out_vars)
|
|
267
|
-
data = np.zeros(oshape + [n_vars], dtype=
|
|
268
|
+
data = np.zeros(oshape + [n_vars], dtype=config.dtype_double)
|
|
268
269
|
for v in out_vars:
|
|
269
270
|
data[..., out_vars.index(v)] = results[v]
|
|
270
271
|
|
|
@@ -449,7 +450,7 @@ class XArrayEngine(DaskBaseEngine):
|
|
|
449
450
|
*ldata,
|
|
450
451
|
input_core_dims=[[]] + iidims + icdims,
|
|
451
452
|
output_core_dims=[out_core_vars],
|
|
452
|
-
output_dtypes=[
|
|
453
|
+
output_dtypes=[config.dtype_double],
|
|
453
454
|
dask="parallelized",
|
|
454
455
|
dask_gufunc_kwargs=dargs,
|
|
455
456
|
kwargs=wargs,
|
foxes/engines/single.py
CHANGED
foxes/input/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
|
|
3
3
|
from foxes.core import Turbine
|
|
4
|
+
from foxes.config import get_path
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def add_from_csv(
|
|
@@ -75,7 +76,8 @@ def add_from_csv(
|
|
|
75
76
|
else:
|
|
76
77
|
if verbosity:
|
|
77
78
|
print("Reading file", data_source)
|
|
78
|
-
|
|
79
|
+
pth = get_path(data_source)
|
|
80
|
+
data = pd.read_csv(pth, index_col=col_index)
|
|
79
81
|
|
|
80
82
|
tmodels = turbine_parameters.pop("turbine_models", [])
|
|
81
83
|
H = turbine_parameters.pop("H", None)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
1
|
from foxes.data import FARM, StaticData
|
|
2
|
+
from foxes.config import get_path
|
|
3
|
+
|
|
4
4
|
from .from_json import add_from_json
|
|
5
5
|
from .from_csv import add_from_csv
|
|
6
6
|
|
|
@@ -31,24 +31,24 @@ def add_from_file(farm, file_path, *args, verbosity=1, dbook=None, **kwargs):
|
|
|
31
31
|
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
-
fpath =
|
|
34
|
+
fpath = get_path(file_path)
|
|
35
35
|
dbook = StaticData() if dbook is None else dbook
|
|
36
36
|
|
|
37
37
|
if not fpath.is_file():
|
|
38
38
|
if verbosity:
|
|
39
39
|
print(f"Reading static data '{fpath.name}' from context '{FARM}'")
|
|
40
|
-
|
|
40
|
+
file_path = dbook.get_file_path(FARM, fpath.name, check_raw=False)
|
|
41
41
|
|
|
42
42
|
if fpath.suffix == ".json":
|
|
43
|
-
add_from_json(farm,
|
|
43
|
+
add_from_json(farm, file_path, *args, **kwargs)
|
|
44
44
|
elif (
|
|
45
45
|
fpath.suffix == ".csv"
|
|
46
|
-
or (len(
|
|
47
|
-
or (len(
|
|
48
|
-
or (len(
|
|
46
|
+
or (len(file_path) > 7 and file_path[-7:] == ".csv.gz")
|
|
47
|
+
or (len(file_path) > 8 and file_path[-8:] == ".csv.bz2")
|
|
48
|
+
or (len(file_path) > 8 and file_path[-8:] == ".csv.zip")
|
|
49
49
|
):
|
|
50
|
-
add_from_csv(farm,
|
|
50
|
+
add_from_csv(farm, file_path, *args, verbosity=verbosity, **kwargs)
|
|
51
51
|
else:
|
|
52
52
|
raise KeyError(
|
|
53
|
-
f"Unsupported file suffix: '{
|
|
53
|
+
f"Unsupported file suffix: '{file_path}'. Please provide any of: json, csv, csv.gz, csv.bz2, csv.zip"
|
|
54
54
|
)
|
|
@@ -3,6 +3,7 @@ import numpy as np
|
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
|
|
5
5
|
from foxes.core import Turbine
|
|
6
|
+
from foxes.config import get_path
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def add_from_json(
|
|
@@ -27,10 +28,10 @@ def add_from_json(
|
|
|
27
28
|
:group: input.farm_layout
|
|
28
29
|
|
|
29
30
|
"""
|
|
30
|
-
|
|
31
|
+
fpath = get_path(file_path)
|
|
31
32
|
if verbosity:
|
|
32
|
-
print("Reading file",
|
|
33
|
-
with open(
|
|
33
|
+
print("Reading file", fpath)
|
|
34
|
+
with open(fpath) as f:
|
|
34
35
|
dict = json.load(f)
|
|
35
36
|
|
|
36
37
|
keys = list(dict.keys())
|
foxes/input/farm_layout/grid.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import Turbine
|
|
4
|
-
|
|
4
|
+
from foxes.config import config
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def add_grid(
|
|
@@ -44,8 +44,8 @@ def add_grid(
|
|
|
44
44
|
inds = list(np.ndindex(*steps))
|
|
45
45
|
n_turbines = len(inds)
|
|
46
46
|
|
|
47
|
-
xy_base = np.array(xy_base, dtype=
|
|
48
|
-
step_vectors = np.array(step_vectors, dtype=
|
|
47
|
+
xy_base = np.array(xy_base, dtype=config.dtype_double)
|
|
48
|
+
step_vectors = np.array(step_vectors, dtype=config.dtype_double)
|
|
49
49
|
|
|
50
50
|
for i in range(n_turbines):
|
|
51
51
|
xi, yi = inds[i]
|
foxes/input/states/__init__.py
CHANGED
|
@@ -3,7 +3,7 @@ Atmospheric input states.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from .single import SingleStateStates
|
|
6
|
-
from .
|
|
6
|
+
from .scan import ScanStates
|
|
7
7
|
from .states_table import StatesTable, Timeseries, TabStates
|
|
8
8
|
from .field_data_nc import FieldDataNC
|
|
9
9
|
from .slice_data_nc import SliceDataNC
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
+
from foxes.config import config, get_path
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
@@ -41,7 +42,7 @@ def create_random_abl_states(
|
|
|
41
42
|
|
|
42
43
|
for v, mm in cols_minmax.items():
|
|
43
44
|
data[v] = np.random.uniform(low=mm[0], high=mm[1], size=(n_states,)).astype(
|
|
44
|
-
|
|
45
|
+
config.dtype_double
|
|
45
46
|
)
|
|
46
47
|
|
|
47
48
|
cmol = var2col.get(FV.MOL, FV.MOL)
|
|
@@ -98,8 +99,9 @@ def write_random_abl_states(
|
|
|
98
99
|
|
|
99
100
|
"""
|
|
100
101
|
|
|
102
|
+
fpath = get_path(file_path)
|
|
101
103
|
if verbosity:
|
|
102
|
-
print("Writing file",
|
|
104
|
+
print("Writing file", fpath)
|
|
103
105
|
|
|
104
106
|
data = create_random_abl_states(
|
|
105
107
|
n_states, cols_minmax, var2col, mol_abs_range, normalize
|
|
@@ -130,4 +132,4 @@ def write_random_abl_states(
|
|
|
130
132
|
if d is not None:
|
|
131
133
|
data[v] = data[v].round(d)
|
|
132
134
|
|
|
133
|
-
data.to_csv(
|
|
135
|
+
data.to_csv(fpath, **kwargs)
|
|
@@ -2,13 +2,13 @@ import numpy as np
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import xarray as xr
|
|
4
4
|
from scipy.interpolate import interpn
|
|
5
|
-
from pathlib import Path
|
|
6
5
|
|
|
7
6
|
from foxes.core import States
|
|
8
7
|
from foxes.utils import wd2uv, uv2wd, import_module
|
|
9
8
|
from foxes.data import STATES, StaticData
|
|
10
9
|
import foxes.variables as FV
|
|
11
10
|
import foxes.constants as FC
|
|
11
|
+
from foxes.config import config, get_path
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class FieldDataNC(States):
|
|
@@ -150,9 +150,11 @@ class FieldDataNC(States):
|
|
|
150
150
|
if "*" in str(self.data_source):
|
|
151
151
|
pass
|
|
152
152
|
else:
|
|
153
|
-
self.__data_source =
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
self.__data_source = get_path(self.data_source)
|
|
154
|
+
if not self.data_source.is_file():
|
|
155
|
+
self.__data_source = StaticData().get_file_path(
|
|
156
|
+
STATES, self.data_source.name, check_raw=False
|
|
157
|
+
)
|
|
156
158
|
if verbosity:
|
|
157
159
|
if pre_load:
|
|
158
160
|
print(
|
|
@@ -164,13 +166,14 @@ class FieldDataNC(States):
|
|
|
164
166
|
)
|
|
165
167
|
|
|
166
168
|
def _read_ds():
|
|
167
|
-
|
|
168
|
-
|
|
169
|
+
fpath = get_path(self.data_source)
|
|
170
|
+
if fpath.is_file():
|
|
171
|
+
return xr.open_dataset(fpath)
|
|
169
172
|
else:
|
|
170
173
|
# try to read multiple files, needs dask:
|
|
171
174
|
try:
|
|
172
175
|
return xr.open_mfdataset(
|
|
173
|
-
str(
|
|
176
|
+
str(fpath),
|
|
174
177
|
parallel=False,
|
|
175
178
|
concat_dim=self.states_coord,
|
|
176
179
|
combine="nested",
|
|
@@ -182,8 +185,7 @@ class FieldDataNC(States):
|
|
|
182
185
|
import_module("dask", hint="pip install dask")
|
|
183
186
|
raise e
|
|
184
187
|
|
|
185
|
-
|
|
186
|
-
self.__data_source = ds
|
|
188
|
+
self.__data_source = _read_ds()
|
|
187
189
|
|
|
188
190
|
if sel is not None:
|
|
189
191
|
self.__data_source = self.data_source.sel(self.sel)
|
|
@@ -258,30 +260,45 @@ class FieldDataNC(States):
|
|
|
258
260
|
|
|
259
261
|
cor_shxy = (self.states_coord, self.h_coord, self.x_coord, self.y_coord)
|
|
260
262
|
cor_shyx = (self.states_coord, self.h_coord, self.y_coord, self.x_coord)
|
|
263
|
+
cor_sxy = (self.states_coord, self.x_coord, self.y_coord)
|
|
264
|
+
cor_syx = (self.states_coord, self.y_coord, self.x_coord)
|
|
261
265
|
cor_sh = (self.states_coord, self.h_coord)
|
|
262
266
|
cor_s = (self.states_coord,)
|
|
263
267
|
vars_shyx = []
|
|
268
|
+
vars_syx = []
|
|
264
269
|
vars_sh = []
|
|
265
270
|
vars_s = []
|
|
266
271
|
for v, ncv in self.var2ncvar.items():
|
|
267
272
|
if ds[ncv].dims == cor_shyx or ds[ncv].dims == cor_shxy:
|
|
268
273
|
vars_shyx.append(v)
|
|
274
|
+
elif ds[ncv].dims == cor_syx or ds[ncv].dims == cor_sxy:
|
|
275
|
+
vars_syx.append(v)
|
|
269
276
|
elif ds[ncv].dims == cor_sh:
|
|
270
277
|
vars_sh.append(v)
|
|
271
278
|
elif ds[ncv].dims == cor_s:
|
|
272
279
|
vars_s.append(v)
|
|
273
280
|
else:
|
|
274
281
|
raise ValueError(
|
|
275
|
-
f"States '{self.name}': Wrong coordinate order for variable '{ncv}': Found {ds[ncv].dims}, expecting {cor_shxy}, {cor_shyx}, {cor_sh} or {cor_s}"
|
|
282
|
+
f"States '{self.name}': Wrong coordinate order for variable '{ncv}': Found {ds[ncv].dims}, expecting {cor_shxy}, {cor_shyx}, {cor_sxy}, {cor_syx}, {cor_sh} or {cor_s}"
|
|
276
283
|
)
|
|
277
284
|
|
|
278
|
-
data = np.zeros(
|
|
285
|
+
data = np.zeros(
|
|
286
|
+
(n_sts, n_h, n_y, n_x, len(self.var2ncvar)), dtype=config.dtype_double
|
|
287
|
+
)
|
|
279
288
|
for v in vars_shyx:
|
|
280
289
|
ncv = self.var2ncvar[v]
|
|
281
290
|
if ds[ncv].dims == cor_shyx:
|
|
282
291
|
data[..., self._dkys[v]] = ds[ncv][:]
|
|
283
292
|
else:
|
|
284
293
|
data[..., self._dkys[v]] = np.swapaxes(ds[ncv].to_numpy(), 2, 3)
|
|
294
|
+
for v in vars_syx:
|
|
295
|
+
ncv = self.var2ncvar[v]
|
|
296
|
+
if ds[ncv].dims == cor_syx:
|
|
297
|
+
data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, None]
|
|
298
|
+
else:
|
|
299
|
+
data[..., self._dkys[v]] = np.swapaxes(ds[ncv].to_numpy(), 1, 2)[
|
|
300
|
+
:, None
|
|
301
|
+
]
|
|
285
302
|
for v in vars_sh:
|
|
286
303
|
ncv = self.var2ncvar[v]
|
|
287
304
|
data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, :, None, None]
|
|
@@ -290,7 +307,9 @@ class FieldDataNC(States):
|
|
|
290
307
|
data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, None, None, None]
|
|
291
308
|
if FV.WD in self.fixed_vars:
|
|
292
309
|
data[..., self._dkys[FV.WD]] = np.full(
|
|
293
|
-
(n_sts, n_h, n_y, n_x),
|
|
310
|
+
(n_sts, n_h, n_y, n_x),
|
|
311
|
+
self.fixed_vars[FV.WD],
|
|
312
|
+
dtype=config.dtype_double,
|
|
294
313
|
)
|
|
295
314
|
|
|
296
315
|
if verbosity > 1:
|
|
@@ -365,7 +384,7 @@ class FieldDataNC(States):
|
|
|
365
384
|
|
|
366
385
|
if self.__weights is None:
|
|
367
386
|
self.__weights = np.full(
|
|
368
|
-
(self._N, algo.n_turbines), 1.0 / self._N, dtype=
|
|
387
|
+
(self._N, algo.n_turbines), 1.0 / self._N, dtype=config.dtype_double
|
|
369
388
|
)
|
|
370
389
|
|
|
371
390
|
idata = super().load_data(algo, verbosity)
|
|
@@ -608,7 +627,9 @@ class FieldDataNC(States):
|
|
|
608
627
|
|
|
609
628
|
# prepare points:
|
|
610
629
|
sts = np.arange(n_states)
|
|
611
|
-
pts = np.append(
|
|
630
|
+
pts = np.append(
|
|
631
|
+
points, np.zeros((n_states, n_pts, 1), dtype=config.dtype_double), axis=2
|
|
632
|
+
)
|
|
612
633
|
pts[:, :, 3] = sts[:, None]
|
|
613
634
|
pts = pts.reshape(n_states * n_pts, 4)
|
|
614
635
|
pts = np.flip(pts, axis=1)
|
|
@@ -697,7 +718,7 @@ class FieldDataNC(States):
|
|
|
697
718
|
out[v] = data[..., self._dkys[v]]
|
|
698
719
|
else:
|
|
699
720
|
out[v] = np.full(
|
|
700
|
-
(n_states, n_pts), self.fixed_vars[v], dtype=
|
|
721
|
+
(n_states, n_pts), self.fixed_vars[v], dtype=config.dtype_double
|
|
701
722
|
)
|
|
702
723
|
|
|
703
724
|
return {v: d.reshape(n_states, n_targets, n_tpoints) for v, d in out.items()}
|