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
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import pandas as pd
|
|
3
3
|
from xarray import Dataset, open_dataset
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
from scipy.interpolate import interp1d
|
|
6
5
|
|
|
7
6
|
from foxes.core import States
|
|
8
7
|
from foxes.utils import PandasFileHelper
|
|
9
8
|
from foxes.data import STATES
|
|
9
|
+
from foxes.config import config, get_path
|
|
10
|
+
from foxes.utils import wd2uv, uv2wd
|
|
10
11
|
import foxes.variables as FV
|
|
11
12
|
import foxes.constants as FC
|
|
12
|
-
from foxes.utils import wd2uv, uv2wd
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class MultiHeightStates(States):
|
|
@@ -92,7 +92,7 @@ class MultiHeightStates(States):
|
|
|
92
92
|
super().__init__()
|
|
93
93
|
|
|
94
94
|
self.ovars = output_vars
|
|
95
|
-
self.heights = np.array(heights, dtype=
|
|
95
|
+
self.heights = np.array(heights, dtype=config.dtype_double)
|
|
96
96
|
self.rpars = pd_read_pars
|
|
97
97
|
self.var2col = var2col
|
|
98
98
|
self.fixed_vars = fixed_vars
|
|
@@ -198,13 +198,14 @@ class MultiHeightStates(States):
|
|
|
198
198
|
|
|
199
199
|
"""
|
|
200
200
|
if not isinstance(self.data_source, pd.DataFrame):
|
|
201
|
-
|
|
201
|
+
self._data_source = get_path(self.data_source)
|
|
202
|
+
if not self.data_source.is_file():
|
|
202
203
|
if verbosity:
|
|
203
204
|
print(
|
|
204
205
|
f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
|
|
205
206
|
)
|
|
206
207
|
self._data_source = algo.dbook.get_file_path(
|
|
207
|
-
STATES, self.data_source, check_raw=False
|
|
208
|
+
STATES, self.data_source.name, check_raw=False
|
|
208
209
|
)
|
|
209
210
|
if verbosity:
|
|
210
211
|
print(f"Path: {self.data_source}")
|
|
@@ -226,7 +227,7 @@ class MultiHeightStates(States):
|
|
|
226
227
|
self._inds = data.index.to_numpy()
|
|
227
228
|
|
|
228
229
|
col_w = self.var2col.get(FV.WEIGHT, FV.WEIGHT)
|
|
229
|
-
self._weights = np.zeros((self._N, algo.n_turbines), dtype=
|
|
230
|
+
self._weights = np.zeros((self._N, algo.n_turbines), dtype=config.dtype_double)
|
|
230
231
|
if col_w in data:
|
|
231
232
|
self._weights[:] = data[col_w].to_numpy()[:, None]
|
|
232
233
|
elif FV.WEIGHT in self.var2col:
|
|
@@ -446,7 +447,7 @@ class MultiHeightStates(States):
|
|
|
446
447
|
vrs = list(mdata[self.VARS])
|
|
447
448
|
n_vars = len(vrs)
|
|
448
449
|
|
|
449
|
-
coeffs = np.zeros((n_h, n_h), dtype=
|
|
450
|
+
coeffs = np.zeros((n_h, n_h), dtype=config.dtype_double)
|
|
450
451
|
np.fill_diagonal(coeffs, 1.0)
|
|
451
452
|
ipars = dict(
|
|
452
453
|
assume_sorted=True,
|
|
@@ -499,10 +500,14 @@ class MultiHeightStates(States):
|
|
|
499
500
|
elif has_wd and v == FV.WS:
|
|
500
501
|
results[v] = np.linalg.norm(uv, axis=-1)
|
|
501
502
|
elif v in self.fixed_vars:
|
|
502
|
-
results[v] = np.zeros(
|
|
503
|
+
results[v] = np.zeros(
|
|
504
|
+
(n_states, n_targets, n_tpoints), dtype=config.dtype_double
|
|
505
|
+
)
|
|
503
506
|
results[v][:] = self.fixed_vars[v]
|
|
504
507
|
elif v in self._solo:
|
|
505
|
-
results[v] = np.zeros(
|
|
508
|
+
results[v] = np.zeros(
|
|
509
|
+
(n_states, n_targets, n_tpoints), dtype=config.dtype_double
|
|
510
|
+
)
|
|
506
511
|
results[v][:] = mdata[self.var(v)][:, None, None]
|
|
507
512
|
else:
|
|
508
513
|
results[v] = ires[vrs.index(v)]
|
|
@@ -620,13 +625,14 @@ class MultiHeightNCStates(MultiHeightStates):
|
|
|
620
625
|
|
|
621
626
|
"""
|
|
622
627
|
if not isinstance(self.data_source, Dataset):
|
|
623
|
-
|
|
628
|
+
self._data_source = get_path(self.data_source)
|
|
629
|
+
if not self.data_source.is_file():
|
|
624
630
|
if verbosity:
|
|
625
631
|
print(
|
|
626
632
|
f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
|
|
627
633
|
)
|
|
628
634
|
self._data_source = algo.dbook.get_file_path(
|
|
629
|
-
STATES, self.data_source, check_raw=False
|
|
635
|
+
STATES, self.data_source.name, check_raw=False
|
|
630
636
|
)
|
|
631
637
|
if verbosity:
|
|
632
638
|
print(f"Path: {self.data_source}")
|
|
@@ -652,7 +658,7 @@ class MultiHeightNCStates(MultiHeightStates):
|
|
|
652
658
|
self._inds = format_times_func(self._inds)
|
|
653
659
|
|
|
654
660
|
w_name = self.var2col.get(FV.WEIGHT, FV.WEIGHT)
|
|
655
|
-
self._weights = np.zeros((self._N, algo.n_turbines), dtype=
|
|
661
|
+
self._weights = np.zeros((self._N, algo.n_turbines), dtype=config.dtype_double)
|
|
656
662
|
if w_name in data.data_vars:
|
|
657
663
|
if data[w_name].dims != (self.state_coord,):
|
|
658
664
|
raise ValueError(
|
|
@@ -664,7 +670,9 @@ class MultiHeightNCStates(MultiHeightStates):
|
|
|
664
670
|
f"Weight variable '{w_name}' defined in var2col, but not found in data_vars {list(data.data_vars.keys())}"
|
|
665
671
|
)
|
|
666
672
|
else:
|
|
667
|
-
self._weights = np.zeros(
|
|
673
|
+
self._weights = np.zeros(
|
|
674
|
+
(self._N, algo.n_turbines), dtype=config.dtype_double
|
|
675
|
+
)
|
|
668
676
|
self._weights[:] = 1.0 / self._N
|
|
669
677
|
|
|
670
678
|
cols = {}
|
|
@@ -707,11 +715,14 @@ class MultiHeightNCStates(MultiHeightStates):
|
|
|
707
715
|
dims,
|
|
708
716
|
np.stack(
|
|
709
717
|
[data.data_vars[c].to_numpy() for c in cols.values()], axis=1
|
|
710
|
-
).astype(
|
|
718
|
+
).astype(config.dtype_double),
|
|
711
719
|
)
|
|
712
720
|
|
|
713
721
|
for v, d in self._solo.items():
|
|
714
|
-
idata["data_vars"][self.var(v)] = (
|
|
722
|
+
idata["data_vars"][self.var(v)] = (
|
|
723
|
+
(FC.STATE,),
|
|
724
|
+
d.astype(config.dtype_double),
|
|
725
|
+
)
|
|
715
726
|
self._solo = list(self._solo.keys())
|
|
716
727
|
|
|
717
728
|
return idata
|
|
@@ -4,6 +4,7 @@ from scipy.interpolate import interpn
|
|
|
4
4
|
from foxes.core import States
|
|
5
5
|
from foxes.utils import uv2wd
|
|
6
6
|
from foxes.models.wake_frames.timelines import Timelines
|
|
7
|
+
from foxes.config import config
|
|
7
8
|
import foxes.variables as FV
|
|
8
9
|
import foxes.constants as FC
|
|
9
10
|
|
|
@@ -65,7 +66,7 @@ class OnePointFlowStates(States):
|
|
|
65
66
|
|
|
66
67
|
"""
|
|
67
68
|
super().__init__()
|
|
68
|
-
self.ref_xy = np.array(ref_xy, dtype=
|
|
69
|
+
self.ref_xy = np.array(ref_xy, dtype=config.dtype_double)
|
|
69
70
|
self.heights = tl_heights
|
|
70
71
|
self.base_states = base_states
|
|
71
72
|
self.dt_min = dt_min
|
|
@@ -268,9 +269,9 @@ class OnePointFlowStates(States):
|
|
|
268
269
|
|
|
269
270
|
i0 = mdata.states_i0(counter=True)
|
|
270
271
|
trace_p = points[:, :, :2] - ref_xy[:, :, :2]
|
|
271
|
-
trace_si = np.zeros((n_states, n_points), dtype=
|
|
272
|
+
trace_si = np.zeros((n_states, n_points), dtype=config.dtype_int)
|
|
272
273
|
trace_si[:] = i0 + np.arange(n_states)[:, None]
|
|
273
|
-
coeffs = np.full((n_states, n_points), np.nan, dtype=
|
|
274
|
+
coeffs = np.full((n_states, n_points), np.nan, dtype=config.dtype_double)
|
|
274
275
|
|
|
275
276
|
# flake8: noqa: F821
|
|
276
277
|
def _eval_trace(sel, hdxy=None, hdxy0=None, trs=None):
|
|
@@ -396,7 +397,7 @@ class OnePointFlowStates(States):
|
|
|
396
397
|
sts = trace_si[hi]
|
|
397
398
|
cfs = coeffs[hi]
|
|
398
399
|
data = self.timelines_data[v].to_numpy()[hi]
|
|
399
|
-
out = np.zeros(sts.shape, dtype=
|
|
400
|
+
out = np.zeros(sts.shape, dtype=config.dtype_double)
|
|
400
401
|
|
|
401
402
|
sel_low = sts < 0
|
|
402
403
|
if np.any(sel_low):
|
|
@@ -436,7 +437,7 @@ class OnePointFlowStates(States):
|
|
|
436
437
|
vres = list(data.keys())
|
|
437
438
|
data = np.stack(list(data.values()), axis=-1)
|
|
438
439
|
|
|
439
|
-
eval = np.zeros((n_states, n_points, 3), dtype=
|
|
440
|
+
eval = np.zeros((n_states, n_points, 3), dtype=config.dtype_double)
|
|
440
441
|
eval[:, :, 0] = points[:, :, 2]
|
|
441
442
|
eval[:, :, 1] = ar_states[:, None]
|
|
442
443
|
eval[:, :, 2] = ar_points[None, :]
|
|
@@ -1,50 +1,40 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import States
|
|
4
|
+
from foxes.config import config
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
class
|
|
9
|
+
class ScanStates(States):
|
|
9
10
|
"""
|
|
10
|
-
|
|
11
|
+
Scan over selected variables
|
|
11
12
|
|
|
12
13
|
Parameters
|
|
13
14
|
----------
|
|
14
|
-
|
|
15
|
-
The
|
|
16
|
-
|
|
17
|
-
The TI value
|
|
18
|
-
rho: float
|
|
19
|
-
The air density
|
|
15
|
+
scans: dict
|
|
16
|
+
The scans, key: variable name,
|
|
17
|
+
value: scan values
|
|
20
18
|
|
|
21
19
|
:group: input.states
|
|
22
20
|
|
|
23
21
|
"""
|
|
24
22
|
|
|
25
|
-
def __init__(self,
|
|
23
|
+
def __init__(self, scans, **kwargs):
|
|
26
24
|
"""
|
|
27
25
|
Constructor.
|
|
28
26
|
|
|
29
27
|
Parameters
|
|
30
28
|
----------
|
|
31
|
-
|
|
32
|
-
The
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
The TI value
|
|
37
|
-
rho: float, optional
|
|
38
|
-
The air density
|
|
29
|
+
scans: dict
|
|
30
|
+
The scans, key: variable name,
|
|
31
|
+
value: scan values
|
|
32
|
+
kwargs: dict, optional
|
|
33
|
+
Parameters for the base class
|
|
39
34
|
|
|
40
35
|
"""
|
|
41
|
-
super().__init__()
|
|
42
|
-
|
|
43
|
-
self.__wsl = np.array(ws_list)
|
|
44
|
-
self.N = len(ws_list)
|
|
45
|
-
self.wd = wd
|
|
46
|
-
self.ti = ti
|
|
47
|
-
self.rho = rho
|
|
36
|
+
super().__init__(**kwargs)
|
|
37
|
+
self.scans = {v: np.asarray(d) for v, d in scans.items()}
|
|
48
38
|
|
|
49
39
|
def load_data(self, algo, verbosity=0):
|
|
50
40
|
"""
|
|
@@ -69,10 +59,24 @@ class ScanWS(States):
|
|
|
69
59
|
and `coords`, a dict with entries `dim_name_str -> dim_array`
|
|
70
60
|
|
|
71
61
|
"""
|
|
72
|
-
|
|
62
|
+
n_v = len(self.scans)
|
|
63
|
+
shp = [len(v) for v in self.scans.values()]
|
|
64
|
+
self._N = np.prod(shp)
|
|
65
|
+
self._vars = list(self.scans.keys())
|
|
66
|
+
|
|
67
|
+
data = np.zeros(shp + [n_v], dtype=config.dtype_double)
|
|
68
|
+
for i, d in enumerate(self.scans.values()):
|
|
69
|
+
s = [None] * n_v
|
|
70
|
+
s[i] = np.s_[:]
|
|
71
|
+
s = tuple(s)
|
|
72
|
+
data[..., i] = d[s]
|
|
73
|
+
data = data.reshape(self._N, n_v)
|
|
73
74
|
|
|
75
|
+
self.VARS = self.var("vars")
|
|
76
|
+
self.DATA = self.var("data")
|
|
74
77
|
idata = super().load_data(algo, verbosity)
|
|
75
|
-
idata["
|
|
78
|
+
idata["coords"][self.VARS] = self._vars
|
|
79
|
+
idata["data_vars"][self.DATA] = ((FC.STATE, self.VARS), data)
|
|
76
80
|
|
|
77
81
|
return idata
|
|
78
82
|
|
|
@@ -108,12 +112,8 @@ class ScanWS(States):
|
|
|
108
112
|
"""
|
|
109
113
|
super().set_running(algo, data_stash, sel, isel, verbosity)
|
|
110
114
|
|
|
111
|
-
data_stash[self.name].update(
|
|
112
|
-
|
|
113
|
-
wsl=self.__wsl,
|
|
114
|
-
)
|
|
115
|
-
)
|
|
116
|
-
del self.__wsl
|
|
115
|
+
data_stash[self.name].update(dict(scans=self.scans))
|
|
116
|
+
del self.scans
|
|
117
117
|
|
|
118
118
|
def unset_running(
|
|
119
119
|
self,
|
|
@@ -145,7 +145,7 @@ class ScanWS(States):
|
|
|
145
145
|
super().unset_running(algo, data_stash, sel, isel, verbosity)
|
|
146
146
|
|
|
147
147
|
data = data_stash[self.name]
|
|
148
|
-
self.
|
|
148
|
+
self.scans = data.pop("scans")
|
|
149
149
|
|
|
150
150
|
def size(self):
|
|
151
151
|
"""
|
|
@@ -157,7 +157,7 @@ class ScanWS(States):
|
|
|
157
157
|
The total number of states
|
|
158
158
|
|
|
159
159
|
"""
|
|
160
|
-
return self.
|
|
160
|
+
return self._N
|
|
161
161
|
|
|
162
162
|
def output_point_vars(self, algo):
|
|
163
163
|
"""
|
|
@@ -174,14 +174,7 @@ class ScanWS(States):
|
|
|
174
174
|
The output variable names
|
|
175
175
|
|
|
176
176
|
"""
|
|
177
|
-
|
|
178
|
-
if self.wd is not None:
|
|
179
|
-
pvars.append(FV.WD)
|
|
180
|
-
if self.ti is not None:
|
|
181
|
-
pvars.append(FV.TI)
|
|
182
|
-
if self.rho is not None:
|
|
183
|
-
pvars.append(FV.RHO)
|
|
184
|
-
return pvars
|
|
177
|
+
return self._vars
|
|
185
178
|
|
|
186
179
|
def weights(self, algo):
|
|
187
180
|
"""
|
|
@@ -198,7 +191,9 @@ class ScanWS(States):
|
|
|
198
191
|
The weights, shape: (n_states, n_turbines)
|
|
199
192
|
|
|
200
193
|
"""
|
|
201
|
-
return np.full(
|
|
194
|
+
return np.full(
|
|
195
|
+
(self._N, algo.n_turbines), 1.0 / self._N, dtype=config.dtype_double
|
|
196
|
+
)
|
|
202
197
|
|
|
203
198
|
def calculate(self, algo, mdata, fdata, tdata):
|
|
204
199
|
"""
|
|
@@ -226,14 +221,9 @@ class ScanWS(States):
|
|
|
226
221
|
(n_states, n_targets, n_tpoints)
|
|
227
222
|
|
|
228
223
|
"""
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
tdata[FV.WD] = np.full_like(tdata[FV.WS], self.wd)
|
|
234
|
-
if self.ti is not None:
|
|
235
|
-
tdata[FV.TI] = np.full_like(tdata[FV.WS], self.ti)
|
|
236
|
-
if self.rho is not None:
|
|
237
|
-
tdata[FV.RHO] = np.full_like(tdata[FV.WS], self.rho)
|
|
224
|
+
for i, v in enumerate(self._vars):
|
|
225
|
+
if v not in tdata:
|
|
226
|
+
tdata[v] = np.zeros_like(tdata[FC.TARGETS][..., 0])
|
|
227
|
+
tdata[v][:] = mdata[self.DATA][:, None, None, i]
|
|
238
228
|
|
|
239
229
|
return {v: tdata[v] for v in self.output_point_vars(algo)}
|
foxes/input/states/single.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
|
|
3
3
|
from foxes.core import States, VerticalProfile
|
|
4
|
+
from foxes.config import config
|
|
4
5
|
import foxes.variables as FV
|
|
5
6
|
import foxes.constants as FC
|
|
6
7
|
|
|
@@ -29,7 +30,15 @@ class SingleStateStates(States):
|
|
|
29
30
|
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
|
-
def __init__(
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
ws=None,
|
|
36
|
+
wd=None,
|
|
37
|
+
ti=None,
|
|
38
|
+
rho=None,
|
|
39
|
+
profiles={},
|
|
40
|
+
**profdata,
|
|
41
|
+
):
|
|
33
42
|
"""
|
|
34
43
|
Constructor.
|
|
35
44
|
|
|
@@ -163,7 +172,7 @@ class SingleStateStates(States):
|
|
|
163
172
|
The weights, shape: (n_states, n_turbines)
|
|
164
173
|
|
|
165
174
|
"""
|
|
166
|
-
return np.ones((1, algo.n_turbines), dtype=
|
|
175
|
+
return np.ones((1, algo.n_turbines), dtype=config.dtype_double)
|
|
167
176
|
|
|
168
177
|
def calculate(self, algo, mdata, fdata, tdata):
|
|
169
178
|
"""
|
|
@@ -195,25 +204,25 @@ class SingleStateStates(States):
|
|
|
195
204
|
tdata[FV.WS] = np.full(
|
|
196
205
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
197
206
|
self.ws,
|
|
198
|
-
dtype=
|
|
207
|
+
dtype=config.dtype_double,
|
|
199
208
|
)
|
|
200
209
|
if self.wd is not None:
|
|
201
210
|
tdata[FV.WD] = np.full(
|
|
202
211
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
203
212
|
self.wd,
|
|
204
|
-
dtype=
|
|
213
|
+
dtype=config.dtype_double,
|
|
205
214
|
)
|
|
206
215
|
if self.ti is not None:
|
|
207
216
|
tdata[FV.TI] = np.full(
|
|
208
217
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
209
218
|
self.ti,
|
|
210
|
-
dtype=
|
|
219
|
+
dtype=config.dtype_double,
|
|
211
220
|
)
|
|
212
221
|
if self.rho is not None:
|
|
213
222
|
tdata[FV.RHO] = np.full(
|
|
214
223
|
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
215
224
|
self.rho,
|
|
216
|
-
dtype=
|
|
225
|
+
dtype=config.dtype_double,
|
|
217
226
|
)
|
|
218
227
|
|
|
219
228
|
if len(self._profiles):
|
|
@@ -2,11 +2,11 @@ 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
|
|
9
|
+
from foxes.config import config, get_path
|
|
10
10
|
import foxes.variables as FV
|
|
11
11
|
import foxes.constants as FC
|
|
12
12
|
|
|
@@ -145,9 +145,11 @@ class SliceDataNC(States):
|
|
|
145
145
|
if "*" in str(self.data_source):
|
|
146
146
|
pass
|
|
147
147
|
else:
|
|
148
|
-
self.__data_source =
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
self.__data_source = get_path(self.data_source)
|
|
149
|
+
if not self.data_source.is_file():
|
|
150
|
+
self.__data_source = StaticData().get_file_path(
|
|
151
|
+
STATES, self.data_source.name, check_raw=False
|
|
152
|
+
)
|
|
151
153
|
if verbosity:
|
|
152
154
|
if pre_load:
|
|
153
155
|
print(
|
|
@@ -159,7 +161,8 @@ class SliceDataNC(States):
|
|
|
159
161
|
)
|
|
160
162
|
|
|
161
163
|
def _read_ds():
|
|
162
|
-
|
|
164
|
+
self._data_source = get_path(self.data_source)
|
|
165
|
+
if self.data_source.is_file():
|
|
163
166
|
return xr.open_dataset(self.data_source)
|
|
164
167
|
else:
|
|
165
168
|
# try to read multiple files, needs dask:
|
|
@@ -177,8 +180,7 @@ class SliceDataNC(States):
|
|
|
177
180
|
import_module("dask", hint="pip install dask")
|
|
178
181
|
raise e
|
|
179
182
|
|
|
180
|
-
|
|
181
|
-
self.__data_source = ds
|
|
183
|
+
self.__data_source = _read_ds()
|
|
182
184
|
|
|
183
185
|
if sel is not None:
|
|
184
186
|
self.__data_source = self.data_source.sel(self.sel)
|
|
@@ -264,7 +266,9 @@ class SliceDataNC(States):
|
|
|
264
266
|
f"States '{self.name}': Wrong coordinate order for variable '{ncv}': Found {ds[ncv].dims}, expecting {cor_sxy}, {cor_syx}, or {cor_s}"
|
|
265
267
|
)
|
|
266
268
|
|
|
267
|
-
data = np.zeros(
|
|
269
|
+
data = np.zeros(
|
|
270
|
+
(n_sts, n_y, n_x, len(self.var2ncvar)), dtype=config.dtype_double
|
|
271
|
+
)
|
|
268
272
|
for v in vars_syx:
|
|
269
273
|
ncv = self.var2ncvar[v]
|
|
270
274
|
if ds[ncv].dims == cor_syx:
|
|
@@ -276,7 +280,7 @@ class SliceDataNC(States):
|
|
|
276
280
|
data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, None, None]
|
|
277
281
|
if FV.WD in self.fixed_vars:
|
|
278
282
|
data[..., self._dkys[FV.WD]] = np.full(
|
|
279
|
-
(n_sts, n_y, n_x), self.fixed_vars[FV.WD], dtype=
|
|
283
|
+
(n_sts, n_y, n_x), self.fixed_vars[FV.WD], dtype=config.dtype_double
|
|
280
284
|
)
|
|
281
285
|
|
|
282
286
|
if verbosity > 1:
|
|
@@ -351,7 +355,7 @@ class SliceDataNC(States):
|
|
|
351
355
|
|
|
352
356
|
if self.__weights is None:
|
|
353
357
|
self.__weights = np.full(
|
|
354
|
-
(self._N, algo.n_turbines), 1.0 / self._N, dtype=
|
|
358
|
+
(self._N, algo.n_turbines), 1.0 / self._N, dtype=config.dtype_double
|
|
355
359
|
)
|
|
356
360
|
|
|
357
361
|
idata = super().load_data(algo, verbosity)
|
|
@@ -588,7 +592,9 @@ class SliceDataNC(States):
|
|
|
588
592
|
|
|
589
593
|
# prepare points:
|
|
590
594
|
sts = np.arange(n_states)
|
|
591
|
-
pts = np.append(
|
|
595
|
+
pts = np.append(
|
|
596
|
+
points, np.zeros((n_states, n_pts, 1), dtype=config.dtype_double), axis=2
|
|
597
|
+
)
|
|
592
598
|
pts[:, :, 3] = sts[:, None]
|
|
593
599
|
pts = pts.reshape(n_states * n_pts, 3)
|
|
594
600
|
pts = np.flip(pts, axis=1)
|
|
@@ -675,7 +681,7 @@ class SliceDataNC(States):
|
|
|
675
681
|
out[v] = data[..., self._dkys[v]]
|
|
676
682
|
else:
|
|
677
683
|
out[v] = np.full(
|
|
678
|
-
(n_states, n_pts), self.fixed_vars[v], dtype=
|
|
684
|
+
(n_states, n_pts), self.fixed_vars[v], dtype=config.dtype_double
|
|
679
685
|
)
|
|
680
686
|
|
|
681
687
|
return {v: d.reshape(n_states, n_targets, n_tpoints) for v, d in out.items()}
|
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
from foxes.core import States, VerticalProfile
|
|
7
7
|
from foxes.utils import PandasFileHelper, read_tab_file
|
|
8
8
|
from foxes.data import STATES
|
|
9
|
+
from foxes.config import config, get_path
|
|
9
10
|
import foxes.variables as FV
|
|
10
11
|
import foxes.constants as FC
|
|
11
12
|
|
|
@@ -214,13 +215,14 @@ class StatesTable(States):
|
|
|
214
215
|
data = self.data_source
|
|
215
216
|
isorg = True
|
|
216
217
|
else:
|
|
217
|
-
|
|
218
|
+
self._data_source = get_path(self.data_source)
|
|
219
|
+
if not self.data_source.is_file():
|
|
218
220
|
if verbosity:
|
|
219
221
|
print(
|
|
220
222
|
f"States '{self.name}': Reading static data '{self.data_source}' from context '{STATES}'"
|
|
221
223
|
)
|
|
222
224
|
self._data_source = algo.dbook.get_file_path(
|
|
223
|
-
STATES, self.data_source, check_raw=False
|
|
225
|
+
STATES, self.data_source.name, check_raw=False
|
|
224
226
|
)
|
|
225
227
|
if verbosity:
|
|
226
228
|
print(f"Path: {self.data_source}")
|
|
@@ -238,7 +240,7 @@ class StatesTable(States):
|
|
|
238
240
|
self.__inds = data.index.to_numpy()
|
|
239
241
|
|
|
240
242
|
col_w = self.var2col.get(FV.WEIGHT, FV.WEIGHT)
|
|
241
|
-
self.__weights = np.zeros((self._N, algo.n_turbines), dtype=
|
|
243
|
+
self.__weights = np.zeros((self._N, algo.n_turbines), dtype=config.dtype_double)
|
|
242
244
|
if col_w in data:
|
|
243
245
|
self.__weights[:] = data[col_w].to_numpy()[:, None]
|
|
244
246
|
elif FV.WEIGHT in self.var2col:
|
|
@@ -436,14 +438,17 @@ class StatesTable(States):
|
|
|
436
438
|
tdata[v][:] = mdata[self.DATA][:, i, None, None]
|
|
437
439
|
else:
|
|
438
440
|
tdata[v] = np.zeros(
|
|
439
|
-
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
441
|
+
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
442
|
+
dtype=config.dtype_double,
|
|
440
443
|
)
|
|
441
444
|
tdata[v][:] = mdata[self.DATA][:, i, None, None]
|
|
442
445
|
tdata.dims[v] = (FC.STATE, FC.TARGET, FC.TPOINT)
|
|
443
446
|
|
|
444
447
|
for v, f in self.fixed_vars.items():
|
|
445
448
|
tdata[v] = np.full(
|
|
446
|
-
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
449
|
+
(tdata.n_states, tdata.n_targets, tdata.n_tpoints),
|
|
450
|
+
f,
|
|
451
|
+
dtype=config.dtype_double,
|
|
447
452
|
)
|
|
448
453
|
|
|
449
454
|
z = tdata[FC.TARGETS][..., 2]
|
|
@@ -545,13 +550,14 @@ class TabStates(StatesTable):
|
|
|
545
550
|
"""
|
|
546
551
|
if self.data_source is None:
|
|
547
552
|
if self.__tab_data is None:
|
|
548
|
-
|
|
553
|
+
self.__tab_source = get_path(self.__tab_source)
|
|
554
|
+
if not self.__tab_source.is_file():
|
|
549
555
|
if verbosity:
|
|
550
556
|
print(
|
|
551
557
|
f"States '{self.name}': Reading static data '{self.__tab_source}' from context '{STATES}'"
|
|
552
558
|
)
|
|
553
559
|
self.__tab_source = algo.dbook.get_file_path(
|
|
554
|
-
STATES, self.__tab_source, check_raw=False
|
|
560
|
+
STATES, self.__tab_source.name, check_raw=False
|
|
555
561
|
)
|
|
556
562
|
if verbosity:
|
|
557
563
|
print(f"Path: {self.__tab_source}")
|
|
@@ -568,14 +574,15 @@ class TabStates(StatesTable):
|
|
|
568
574
|
|
|
569
575
|
wd0 = self.__tab_data["wd"].to_numpy()
|
|
570
576
|
ws0 = a * np.append(
|
|
571
|
-
np.array([0], dtype=
|
|
577
|
+
np.array([0], dtype=config.dtype_double),
|
|
578
|
+
self.__tab_data["ws"].to_numpy(),
|
|
572
579
|
)
|
|
573
580
|
ws0 = 0.5 * (ws0[:-1] + ws0[1:])
|
|
574
581
|
|
|
575
582
|
n_ws = self.__tab_data.sizes["ws"]
|
|
576
583
|
n_wd = self.__tab_data.sizes["wd"]
|
|
577
|
-
ws = np.zeros((n_ws, n_wd), dtype=
|
|
578
|
-
wd = np.zeros((n_ws, n_wd), dtype=
|
|
584
|
+
ws = np.zeros((n_ws, n_wd), dtype=config.dtype_double)
|
|
585
|
+
wd = np.zeros((n_ws, n_wd), dtype=config.dtype_double)
|
|
579
586
|
ws[:] = ws0[:, None]
|
|
580
587
|
wd[:] = wd0[None, :]
|
|
581
588
|
|