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.

Files changed (155) hide show
  1. docs/source/conf.py +3 -1
  2. examples/abl_states/run.py +5 -5
  3. examples/dyn_wakes/run.py +2 -2
  4. examples/induction/run.py +5 -5
  5. examples/random_timeseries/run.py +13 -13
  6. examples/scan_row/run.py +12 -7
  7. examples/sector_management/run.py +11 -7
  8. examples/single_state/run.py +5 -5
  9. examples/tab_file/run.py +1 -1
  10. examples/timelines/run.py +1 -1
  11. examples/timeseries/run.py +5 -5
  12. examples/timeseries_slurm/run.py +5 -5
  13. examples/wind_rose/run.py +1 -1
  14. examples/yawed_wake/run.py +5 -5
  15. foxes/__init__.py +13 -2
  16. foxes/algorithms/downwind/downwind.py +21 -6
  17. foxes/algorithms/downwind/models/init_farm_data.py +5 -2
  18. foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
  19. foxes/algorithms/iterative/iterative.py +1 -1
  20. foxes/algorithms/sequential/sequential.py +5 -4
  21. foxes/config/__init__.py +1 -0
  22. foxes/config/config.py +134 -0
  23. foxes/constants.py +15 -6
  24. foxes/core/algorithm.py +46 -30
  25. foxes/core/axial_induction_model.py +18 -0
  26. foxes/core/data.py +2 -1
  27. foxes/core/engine.py +43 -49
  28. foxes/core/farm_controller.py +22 -3
  29. foxes/core/farm_data_model.py +6 -2
  30. foxes/core/ground_model.py +19 -0
  31. foxes/core/model.py +2 -1
  32. foxes/core/partial_wakes_model.py +9 -21
  33. foxes/core/point_data_model.py +22 -2
  34. foxes/core/rotor_model.py +9 -21
  35. foxes/core/states.py +2 -17
  36. foxes/core/turbine_model.py +2 -18
  37. foxes/core/turbine_type.py +2 -18
  38. foxes/core/vertical_profile.py +8 -20
  39. foxes/core/wake_frame.py +9 -25
  40. foxes/core/wake_model.py +24 -20
  41. foxes/core/wake_superposition.py +19 -0
  42. foxes/data/__init__.py +1 -1
  43. foxes/data/static_data.py +0 -7
  44. foxes/engines/dask.py +4 -3
  45. foxes/engines/single.py +1 -1
  46. foxes/input/__init__.py +1 -1
  47. foxes/input/farm_layout/from_csv.py +3 -1
  48. foxes/input/farm_layout/from_file.py +10 -10
  49. foxes/input/farm_layout/from_json.py +4 -3
  50. foxes/input/farm_layout/grid.py +3 -3
  51. foxes/input/states/__init__.py +1 -1
  52. foxes/input/states/create/random_abl_states.py +5 -3
  53. foxes/input/states/field_data_nc.py +36 -15
  54. foxes/input/states/multi_height.py +26 -15
  55. foxes/input/states/one_point_flow.py +6 -5
  56. foxes/input/states/{scan_ws.py → scan.py} +42 -52
  57. foxes/input/states/single.py +15 -6
  58. foxes/input/states/slice_data_nc.py +18 -12
  59. foxes/input/states/states_table.py +17 -10
  60. foxes/input/yaml/__init__.py +3 -0
  61. foxes/input/yaml/dict.py +381 -0
  62. foxes/input/yaml/windio/__init__.py +4 -0
  63. foxes/input/{windio → yaml/windio}/get_states.py +7 -7
  64. foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
  65. foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
  66. foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
  67. foxes/input/yaml/windio/read_outputs.py +147 -0
  68. foxes/input/yaml/windio/windio.py +269 -0
  69. foxes/input/yaml/yaml.py +103 -0
  70. foxes/models/partial_wakes/axiwake.py +7 -6
  71. foxes/models/partial_wakes/centre.py +3 -2
  72. foxes/models/partial_wakes/segregated.py +5 -2
  73. foxes/models/point_models/set_uniform_data.py +5 -3
  74. foxes/models/rotor_models/centre.py +2 -2
  75. foxes/models/rotor_models/grid.py +5 -5
  76. foxes/models/rotor_models/levels.py +6 -6
  77. foxes/models/turbine_models/kTI_model.py +3 -1
  78. foxes/models/turbine_models/lookup_table.py +7 -4
  79. foxes/models/turbine_models/power_mask.py +14 -8
  80. foxes/models/turbine_models/sector_management.py +4 -2
  81. foxes/models/turbine_models/set_farm_vars.py +53 -23
  82. foxes/models/turbine_models/table_factors.py +8 -7
  83. foxes/models/turbine_models/yaw2yawm.py +0 -1
  84. foxes/models/turbine_models/yawm2yaw.py +0 -1
  85. foxes/models/turbine_types/CpCt_file.py +6 -3
  86. foxes/models/turbine_types/CpCt_from_two.py +6 -3
  87. foxes/models/turbine_types/PCt_file.py +7 -6
  88. foxes/models/turbine_types/PCt_from_two.py +11 -2
  89. foxes/models/turbine_types/TBL_file.py +3 -4
  90. foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
  91. foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
  92. foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
  93. foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
  94. foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
  95. foxes/models/vertical_profiles/abl_log_ws.py +1 -1
  96. foxes/models/wake_frames/dynamic_wakes.py +17 -9
  97. foxes/models/wake_frames/farm_order.py +4 -3
  98. foxes/models/wake_frames/rotor_wd.py +3 -1
  99. foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
  100. foxes/models/wake_frames/streamlines.py +9 -6
  101. foxes/models/wake_frames/timelines.py +21 -14
  102. foxes/models/wake_frames/yawed_wakes.py +3 -1
  103. foxes/models/wake_models/induction/vortex_sheet.py +0 -1
  104. foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
  105. foxes/models/wake_models/wind/bastankhah14.py +3 -2
  106. foxes/models/wake_models/wind/bastankhah16.py +2 -1
  107. foxes/models/wake_models/wind/turbopark.py +9 -7
  108. foxes/models/wake_superpositions/ws_product.py +0 -1
  109. foxes/output/__init__.py +2 -1
  110. foxes/output/calc_points.py +7 -4
  111. foxes/output/farm_layout.py +30 -18
  112. foxes/output/farm_results_eval.py +61 -38
  113. foxes/output/grids.py +8 -7
  114. foxes/output/output.py +9 -20
  115. foxes/output/plt.py +19 -0
  116. foxes/output/results_writer.py +10 -11
  117. foxes/output/rose_plot.py +448 -224
  118. foxes/output/rotor_point_plots.py +7 -3
  119. foxes/output/slice_data.py +1 -1
  120. foxes/output/state_turbine_map.py +5 -1
  121. foxes/output/state_turbine_table.py +7 -3
  122. foxes/output/turbine_type_curves.py +7 -2
  123. foxes/utils/__init__.py +1 -2
  124. foxes/utils/dict.py +107 -3
  125. foxes/utils/geopandas_utils.py +3 -2
  126. foxes/utils/subclasses.py +69 -0
  127. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/METADATA +18 -18
  128. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/RECORD +145 -145
  129. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/WHEEL +1 -1
  130. foxes-1.2.1.dist-info/entry_points.txt +3 -0
  131. tests/0_consistency/iterative/test_iterative.py +65 -67
  132. tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
  133. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
  134. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
  135. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
  136. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +57 -52
  137. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +58 -54
  138. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +80 -76
  139. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +80 -76
  140. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +58 -51
  141. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
  142. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +67 -64
  143. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +58 -54
  144. examples/windio/run.py +0 -29
  145. foxes/data/states/windio_timeseries_5000.nc +0 -0
  146. foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
  147. foxes/data/windio/__init__.py +0 -0
  148. foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
  149. foxes/input/windio/__init__.py +0 -11
  150. foxes/input/windio/read_outputs.py +0 -172
  151. foxes/input/windio/runner.py +0 -183
  152. foxes/input/windio/windio.py +0 -193
  153. foxes/utils/windrose_plot.py +0 -152
  154. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/LICENSE +0 -0
  155. {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=FC.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
- if not Path(self.data_source).is_file():
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=FC.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=FC.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((n_states, n_targets, n_tpoints), dtype=FC.DTYPE)
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((n_states, n_targets, n_tpoints), dtype=FC.DTYPE)
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
- if not Path(self.data_source).is_file():
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=FC.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((self._N, algo.n_turbines), dtype=FC.DTYPE)
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(FC.DTYPE),
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)] = ((FC.STATE,), d.astype(FC.DTYPE))
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=FC.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=FC.ITYPE)
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=FC.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=FC.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=FC.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 ScanWS(States):
9
+ class ScanStates(States):
9
10
  """
10
- A given list of wind speeds, all other variables are fixed.
11
+ Scan over selected variables
11
12
 
12
13
  Parameters
13
14
  ----------
14
- wd: float
15
- The wind direction
16
- ti: float
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, ws_list, wd, ti=None, rho=None):
23
+ def __init__(self, scans, **kwargs):
26
24
  """
27
25
  Constructor.
28
26
 
29
27
  Parameters
30
28
  ----------
31
- ws_list: array_like
32
- The wind speed values
33
- wd: float
34
- The wind direction
35
- ti: float, optional
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
- self.WS = self.var(FV.WS)
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["data_vars"][self.WS] = ((FC.STATE,), self.__wsl)
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
- dict(
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.__wsl = data.pop("wsl")
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.N
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
- pvars = [FV.WS]
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((self.N, algo.n_turbines), 1.0 / self.N, dtype=FC.DTYPE)
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
- tdata[FV.WS] = np.zeros_like(tdata[FC.TARGETS][..., 0])
230
- tdata[FV.WS][:] = mdata[self.WS][:, None, None]
231
-
232
- if self.wd is not None:
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)}
@@ -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__(self, ws=None, wd=None, ti=None, rho=None, profiles={}, **profdata):
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=FC.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=FC.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=FC.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=FC.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=FC.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 = StaticData().get_file_path(
149
- STATES, self.data_source, check_raw=True
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
- if Path(self.data_source).is_file():
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
- with _read_ds() as ds:
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((n_sts, n_y, n_x, len(self.var2ncvar)), dtype=FC.DTYPE)
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=FC.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=FC.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(points, np.zeros((n_states, n_pts, 1), dtype=FC.DTYPE), axis=2)
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=FC.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
- if not Path(self.data_source).is_file():
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=FC.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), dtype=FC.DTYPE
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), f, dtype=FC.DTYPE
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
- if not Path(self.__tab_source).is_file():
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=FC.DTYPE), self.__tab_data["ws"].to_numpy()
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=FC.DTYPE)
578
- wd = np.zeros((n_ws, n_wd), dtype=FC.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
 
@@ -0,0 +1,3 @@
1
+ from .dict import read_dict, run_dict, run_outputs
2
+ from .yaml import foxes_yaml
3
+ from .windio.windio import read_windio, foxes_windio