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
@@ -0,0 +1,103 @@
1
+ import argparse
2
+ from pathlib import Path
3
+
4
+ from foxes.utils import Dict
5
+
6
+ from .dict import run_dict
7
+
8
+
9
+ def foxes_yaml():
10
+ """
11
+ Command line tool for running foxes from yaml file input.
12
+
13
+ Examples
14
+ --------
15
+ >>> foxes_yaml input.yaml
16
+
17
+ :group: input.yaml
18
+
19
+ """
20
+
21
+ parser = argparse.ArgumentParser()
22
+ parser.add_argument(
23
+ "yml_file",
24
+ help="The input yaml file",
25
+ )
26
+ parser.add_argument("-o", "--out_dir", help="The output directory", default=".")
27
+ parser.add_argument("-r", "--rotor", help="The rotor model", default=None)
28
+ parser.add_argument(
29
+ "-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
30
+ )
31
+ parser.add_argument(
32
+ "-w",
33
+ "--wakes",
34
+ help="The wake models",
35
+ default=None,
36
+ nargs="+",
37
+ )
38
+ parser.add_argument("-f", "--frame", help="The wake frame", default=None)
39
+ parser.add_argument("-e", "--engine", help="The engine", default=None)
40
+ parser.add_argument(
41
+ "-n", "--n_procs", help="The number of processes", default=None, type=int
42
+ )
43
+ parser.add_argument(
44
+ "-c",
45
+ "--chunksize_states",
46
+ help="The chunk size for states",
47
+ default=None,
48
+ type=int,
49
+ )
50
+ parser.add_argument(
51
+ "-C",
52
+ "--chunksize_points",
53
+ help="The chunk size for points",
54
+ default=None,
55
+ type=int,
56
+ )
57
+ parser.add_argument(
58
+ "-it", "--iterative", help="Use iterative algorithm", action="store_true"
59
+ )
60
+ parser.add_argument(
61
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
62
+ )
63
+ parser.add_argument(
64
+ "-v",
65
+ "--verbosity",
66
+ help="The verbosity level, 0 = silent",
67
+ type=int,
68
+ default=None,
69
+ )
70
+ args = parser.parse_args()
71
+
72
+ v = 1 if args.verbosity is None else args.verbosity
73
+ fpath = Path(args.yml_file)
74
+ idata = Dict.from_yaml(fpath, verbosity=v)
75
+
76
+ if (
77
+ args.engine is not None
78
+ or args.n_procs is not None
79
+ or args.chunksize_states is not None
80
+ or args.chunksize_points is not None
81
+ ):
82
+ epars = dict(
83
+ engine_type=args.engine,
84
+ n_procs=args.n_procs,
85
+ chunk_size_states=args.chunksize_states,
86
+ chunk_size_points=args.chunksize_points,
87
+ verbosity=v,
88
+ )
89
+ else:
90
+ epars = None
91
+
92
+ run_dict(
93
+ idata,
94
+ rotor_model=args.rotor,
95
+ partial_wakes=args.pwakes,
96
+ wake_models=args.wakes,
97
+ wake_frame=args.frame,
98
+ engine_pars=epars,
99
+ iterative=args.iterative,
100
+ work_dir=fpath.parent,
101
+ out_dir=args.out_dir,
102
+ verbosity=args.verbosity,
103
+ )
@@ -2,6 +2,7 @@ import numpy as np
2
2
 
3
3
  from foxes.models.wake_models.axisymmetric import AxisymmetricWakeModel
4
4
  from foxes.utils.two_circles import calc_area
5
+ from foxes.config import config
5
6
  import foxes.variables as FV
6
7
  import foxes.constants as FC
7
8
 
@@ -130,11 +131,11 @@ class PartialAxiwake(PartialCentre):
130
131
  x = wcoos[..., 0, 0]
131
132
  n = wcoos[..., 0, 1:3]
132
133
  R = np.linalg.norm(n, axis=-1)
133
- r = np.zeros((n_states, n_targets, self.n), dtype=FC.DTYPE)
134
+ r = np.zeros((n_states, n_targets, self.n), dtype=config.dtype_double)
134
135
  del wcoos
135
136
 
136
137
  # prepare circle section area calculation:
137
- A = np.zeros((n_states, n_targets, self.n), dtype=FC.DTYPE)
138
+ A = np.zeros((n_states, n_targets, self.n), dtype=config.dtype_double)
138
139
  weights = np.zeros_like(A)
139
140
 
140
141
  # get normalized 2D vector between rotor and wake centres:
@@ -148,12 +149,12 @@ class PartialAxiwake(PartialCentre):
148
149
  sel = (x > 1e-8) & (R > D / 2)
149
150
  if np.any(sel):
150
151
  n_sel = np.sum(sel)
151
- Rsel = np.zeros((n_sel, self.n + 1), dtype=FC.DTYPE)
152
+ Rsel = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
152
153
  Rsel[:] = R[sel][:, None]
153
154
  Dsel = D[sel][:, None]
154
155
 
155
156
  # equal delta R2:
156
- R1 = np.zeros((n_sel, self.n + 1), dtype=FC.DTYPE)
157
+ R1 = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
157
158
  R1[:] = Dsel / 2
158
159
  steps = np.linspace(0.0, 1.0, self.n + 1, endpoint=True) - 0.5
159
160
  R2 = np.zeros_like(R1)
@@ -170,12 +171,12 @@ class PartialAxiwake(PartialCentre):
170
171
  sel = (x > 0) & (R < D / 2)
171
172
  if np.any(sel):
172
173
  n_sel = np.sum(sel)
173
- Rsel = np.zeros((n_sel, self.n + 1), dtype=FC.DTYPE)
174
+ Rsel = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
174
175
  Rsel[:] = R[sel][:, None]
175
176
  Dsel = D[sel][:, None]
176
177
 
177
178
  # equal delta R2:
178
- R1 = np.zeros((n_sel, self.n + 1), dtype=FC.DTYPE)
179
+ R1 = np.zeros((n_sel, self.n + 1), dtype=config.dtype_double)
179
180
  R1[:, 1:] = Dsel / 2
180
181
  R2 = np.zeros_like(R1)
181
182
  # R2[:, 1:] = Rsel[:, :-1] + Dsel/2
@@ -1,7 +1,8 @@
1
1
  import numpy as np
2
2
 
3
3
  import foxes.variables as FV
4
- import foxes.constants as FC
4
+ from foxes.config import config
5
+
5
6
  from .rotor_points import RotorPoints
6
7
 
7
8
 
@@ -37,4 +38,4 @@ class PartialCentre(RotorPoints):
37
38
  The target point weights, shape: (n_tpoints,)
38
39
 
39
40
  """
40
- return fdata[FV.TXYH][:, :, None], np.ones(1, dtype=FC.DTYPE)
41
+ return fdata[FV.TXYH][:, :, None], np.ones(1, dtype=config.dtype_double)
@@ -1,6 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import PartialWakesModel
4
+ from foxes.config import config
4
5
  import foxes.variables as FV
5
6
  import foxes.constants as FC
6
7
 
@@ -143,7 +144,9 @@ class PartialSegregated(PartialWakesModel):
143
144
  else:
144
145
  ares = {}
145
146
  for v, d in amb_res.items():
146
- ares[v] = np.zeros((n_states, 1, tdata.n_tpoints), dtype=FC.DTYPE)
147
+ ares[v] = np.zeros(
148
+ (n_states, 1, tdata.n_tpoints), dtype=config.dtype_double
149
+ )
147
150
  ares[v][:] = np.einsum("sp,p->s", d[:, downwind_index], rpoint_weights)[
148
151
  :, None, None
149
152
  ]
@@ -151,7 +154,7 @@ class PartialSegregated(PartialWakesModel):
151
154
  wmodel.finalize_wake_deltas(algo, mdata, fdata, ares, wdel)
152
155
 
153
156
  for v in wdel.keys():
154
- hdel = np.zeros((n_states, n_rotor_points), dtype=FC.DTYPE)
157
+ hdel = np.zeros((n_states, n_rotor_points), dtype=config.dtype_double)
155
158
  hdel[:] = np.einsum("sp,p->s", wdel[v][:, 0], gweights)[:, None]
156
159
  wdel[v] = hdel
157
160
 
@@ -2,8 +2,8 @@ import pandas as pd
2
2
 
3
3
  from foxes.core.point_data_model import PointDataModel
4
4
  from foxes.utils import PandasFileHelper
5
+ from foxes.config import config
5
6
  import foxes.constants as FC
6
- import foxes.variables as FV
7
7
 
8
8
 
9
9
  class SetUniformData(PointDataModel):
@@ -84,7 +84,7 @@ class SetUniformData(PointDataModel):
84
84
  if isinstance(self.data_source, pd.DataFrame):
85
85
  data = self.data_source[
86
86
  [self.var2col.get(v, v) for v in self.ovars]
87
- ].to_numpy(FC.DTYPE)
87
+ ].to_numpy(config.dtype_double)
88
88
  elif isinstance(self.data_source, dict):
89
89
  pass
90
90
  else:
@@ -93,7 +93,9 @@ class SetUniformData(PointDataModel):
93
93
  rpars = dict(index_col=0)
94
94
  rpars.update(self._rpars)
95
95
  data = PandasFileHelper().read_file(self.data_source, **rpars)
96
- data = data[[self.var2col.get(v, v) for v in self.ovars]].to_numpy(FC.DTYPE)
96
+ data = data[[self.var2col.get(v, v) for v in self.ovars]].to_numpy(
97
+ config.dtype_double
98
+ )
97
99
 
98
100
  idata = super().load_data(algo, verbosity)
99
101
  idata["coords"][self.VARS] = self.ovars
@@ -3,7 +3,7 @@ import numpy as np
3
3
  from foxes.core import RotorModel
4
4
  from foxes.utils import wd2uv, uv2wd
5
5
  import foxes.variables as FV
6
- import foxes.constants as FC
6
+ from foxes.config import config
7
7
 
8
8
 
9
9
  class CentreRotor(RotorModel):
@@ -155,7 +155,7 @@ class CentreRotor(RotorModel):
155
155
  vdone = []
156
156
  for v in self.calc_vars:
157
157
  if v not in fdata:
158
- fdata[v] = np.zeros((n_states, n_turbines), dtype=FC.DTYPE)
158
+ fdata[v] = np.zeros((n_states, n_turbines), dtype=config.dtype_double)
159
159
 
160
160
  if v == FV.WD or v == FV.YAW:
161
161
  if wd is None:
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import RotorModel
4
- import foxes.constants as FC
4
+ from foxes.config import config
5
5
 
6
6
 
7
7
  class GridRotor(RotorModel):
@@ -75,12 +75,12 @@ class GridRotor(RotorModel):
75
75
  x = [-1.0 + (i + 0.5) * delta for i in range(self.n)]
76
76
  x, y = np.meshgrid(x, x, indexing="ij")
77
77
 
78
- self.__dpoints = np.zeros([N, 3], dtype=FC.DTYPE)
78
+ self.__dpoints = np.zeros([N, 3], dtype=config.dtype_double)
79
79
  self.__dpoints[:, 1] = x.reshape(N)
80
80
  self.__dpoints[:, 2] = y.reshape(N)
81
81
 
82
82
  if self.reduce:
83
- self.__weights = np.zeros((self.n, self.n), dtype=FC.DTYPE)
83
+ self.__weights = np.zeros((self.n, self.n), dtype=config.dtype_double)
84
84
  for i in range(0, self.n):
85
85
  for j in range(0, self.n):
86
86
  d = delta / self.nint
@@ -90,7 +90,7 @@ class GridRotor(RotorModel):
90
90
  hy = [
91
91
  y[i, j] - delta / 2.0 + (k + 0.5) * d for k in range(self.nint)
92
92
  ]
93
- pts = np.zeros((self.nint, self.nint, 2), dtype=FC.DTYPE)
93
+ pts = np.zeros((self.nint, self.nint, 2), dtype=config.dtype_double)
94
94
  pts[:, :, 0], pts[:, :, 1] = np.meshgrid(hx, hy, indexing="ij")
95
95
 
96
96
  d = np.linalg.norm(pts, axis=2)
@@ -105,7 +105,7 @@ class GridRotor(RotorModel):
105
105
  else:
106
106
  self.__dpoints[:, 1] = x.reshape(N)
107
107
  self.__dpoints[:, 2] = y.reshape(N)
108
- self.__weights = np.ones(N, dtype=FC.DTYPE) / N
108
+ self.__weights = np.ones(N, dtype=config.dtype_double) / N
109
109
 
110
110
  def n_rotor_points(self):
111
111
  """
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import RotorModel
4
- import foxes.constants as FC
4
+ from foxes.config import config
5
5
 
6
6
 
7
7
  class LevelRotor(RotorModel):
@@ -69,20 +69,20 @@ class LevelRotor(RotorModel):
69
69
 
70
70
  delta = 2.0 / self.n
71
71
  y = [-1.0 + (i + 0.5) * delta for i in range(self.n)]
72
- x = np.zeros(self.n, dtype=FC.DTYPE)
72
+ x = np.zeros(self.n, dtype=config.dtype_double)
73
73
 
74
- self.dpoints = np.zeros([self.n, 3], dtype=FC.DTYPE)
74
+ self.dpoints = np.zeros([self.n, 3], dtype=config.dtype_double)
75
75
  self.dpoints[:, 1] = x
76
76
  self.dpoints[:, 2] = y
77
77
 
78
78
  if self.reduce:
79
- self.weights = np.zeros((self.n), dtype=FC.DTYPE)
79
+ self.weights = np.zeros((self.n), dtype=config.dtype_double)
80
80
  hx = np.linspace(1, -1, self.nint)
81
81
 
82
82
  for i in range(0, self.n):
83
83
  d = delta / self.nint
84
84
  hy = [y[i] - delta / 2.0 + (k + 0.5) * d for k in range(self.nint)]
85
- pts = np.zeros((self.nint, self.nint, 2), dtype=FC.DTYPE)
85
+ pts = np.zeros((self.nint, self.nint, 2), dtype=config.dtype_double)
86
86
  pts[:, :, 0], pts[:, :, 1] = np.meshgrid(hx, hy, indexing="ij")
87
87
 
88
88
  d = np.linalg.norm(pts, axis=2)
@@ -96,7 +96,7 @@ class LevelRotor(RotorModel):
96
96
  else:
97
97
  self.dpoints[:, 1] = x
98
98
  self.dpoints[:, 2] = y
99
- self.weights = np.ones(self.n, dtype=FC.DTYPE) / self.n
99
+ self.weights = np.ones(self.n, dtype=config.dtype_double) / self.n
100
100
 
101
101
  def n_rotor_points(self):
102
102
  """
@@ -1,6 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import TurbineModel
4
+ from foxes.config import config
4
5
  import foxes.variables as FV
5
6
  import foxes.constants as FC
6
7
 
@@ -128,7 +129,8 @@ class kTI(TurbineModel):
128
129
  )
129
130
 
130
131
  k = fdata.get(
131
- self.k_var, np.zeros((fdata.n_states, fdata.n_turbines), dtype=FC.DTYPE)
132
+ self.k_var,
133
+ np.zeros((fdata.n_states, fdata.n_turbines), dtype=config.dtype_double),
132
134
  )
133
135
 
134
136
  k[st_sel] = kti * ti + kb
@@ -4,6 +4,7 @@ import xarray as xr
4
4
 
5
5
  from foxes.core import TurbineModel
6
6
  from foxes.utils import PandasFileHelper
7
+ from foxes.config import config, get_path
7
8
  import foxes.constants as FC
8
9
 
9
10
 
@@ -127,9 +128,10 @@ class LookupTable(TurbineModel):
127
128
  if isinstance(self.data_source, pd.DataFrame):
128
129
  data = self.data_source
129
130
  else:
131
+ fpath = get_path(self.data_source)
130
132
  if verbosity > 0:
131
- print(f"{self.name}: Reading file {self.data_source}")
132
- data = PandasFileHelper.read_file(self.data_source, **self._rpars)
133
+ print(f"{self.name}: Reading file {fpath}")
134
+ data = PandasFileHelper.read_file(fpath, **self._rpars)
133
135
 
134
136
  if verbosity > 0:
135
137
  print(f"{self.name}: Preparing interpolation data")
@@ -138,7 +140,8 @@ class LookupTable(TurbineModel):
138
140
  data = data[self.input_vars + self.output_vars]
139
141
  data.sort_values(by=self.input_vars, inplace=True)
140
142
  coords = {
141
- v: np.asarray(data[v].unique(), dtype=FC.DTYPE) for v in self.input_vars
143
+ v: np.asarray(data[v].unique(), dtype=config.dtype_double)
144
+ for v in self.input_vars
142
145
  }
143
146
 
144
147
  dvars = {}
@@ -146,7 +149,7 @@ class LookupTable(TurbineModel):
146
149
  pivot_matrix = data.pivot_table(index=self.input_vars, values=[oname])
147
150
  dvars[oname] = (
148
151
  self.input_vars,
149
- pivot_matrix.to_numpy(FC.DTYPE).reshape(
152
+ pivot_matrix.to_numpy(config.dtype_double).reshape(
150
153
  pivot_matrix.index.levshape
151
154
  ),
152
155
  )
@@ -1,9 +1,9 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import TurbineModel
4
- import foxes.variables as FV
5
- import foxes.constants as FC
4
+ from foxes.config import config
6
5
  from foxes.utils import cubic_roots
6
+ import foxes.variables as FV
7
7
 
8
8
 
9
9
  class PowerMask(TurbineModel):
@@ -33,7 +33,13 @@ class PowerMask(TurbineModel):
33
33
 
34
34
  """
35
35
 
36
- def __init__(self, var_ws_P=FV.REWS3, factor_P=1.0e3, P_lim=100, induction="Betz"):
36
+ def __init__(
37
+ self,
38
+ var_ws_P=FV.REWS3,
39
+ factor_P=1.0e3,
40
+ P_lim=100,
41
+ induction="Betz",
42
+ ):
37
43
  """
38
44
  Constructor.
39
45
 
@@ -110,13 +116,13 @@ class PowerMask(TurbineModel):
110
116
 
111
117
  self._P_rated = []
112
118
  for t in algo.farm_controller.turbine_types:
113
- Pnom = FC.DTYPE(t.P_nominal)
119
+ Pnom = config.dtype_double(t.P_nominal)
114
120
  if np.isnan(Pnom):
115
121
  raise ValueError(
116
122
  f"Model '{self.name}': P_nominal is NaN for turbine type '{t.name}'"
117
123
  )
118
124
  self._P_rated.append(Pnom)
119
- self._P_rated = np.array(self._P_rated, dtype=FC.DTYPE)
125
+ self._P_rated = np.array(self._P_rated, dtype=config.dtype_double)
120
126
 
121
127
  def calculate(self, algo, mdata, fdata, st_sel):
122
128
  """
@@ -183,9 +189,9 @@ class PowerMask(TurbineModel):
183
189
 
184
190
  # find roots:
185
191
  N = len(cp)
186
- a3 = np.full(N, 4.0, dtype=FC.DTYPE)
187
- a2 = np.full(N, -8.0, dtype=FC.DTYPE)
188
- a1 = np.full(N, 4.0, dtype=FC.DTYPE)
192
+ a3 = np.full(N, 4.0, dtype=config.dtype_double)
193
+ a2 = np.full(N, -8.0, dtype=config.dtype_double)
194
+ a1 = np.full(N, 4.0, dtype=config.dtype_double)
189
195
  a0 = -cp / e
190
196
  rts = cubic_roots(a0, a1, a2, a3)
191
197
  rts[np.isnan(rts)] = np.inf
@@ -3,6 +3,7 @@ import pandas as pd
3
3
 
4
4
  from foxes.core import TurbineModel
5
5
  from foxes.utils import PandasFileHelper
6
+ from foxes.config import get_path
6
7
  import foxes.variables as FV
7
8
  import foxes.constants as FC
8
9
 
@@ -90,9 +91,10 @@ class SectorManagement(TurbineModel):
90
91
  if isinstance(self.source, pd.DataFrame):
91
92
  data = self.source
92
93
  else:
94
+ fpath = get_path(self.source)
93
95
  if verbosity > 0:
94
- print(f"{self.name}: Reading file {self.source}")
95
- data = PandasFileHelper.read_file(self.source, **self._rpars)
96
+ print(f"{self.name}: Reading file {fpath}")
97
+ data = PandasFileHelper.read_file(fpath, **self._rpars)
96
98
 
97
99
  if self._trbs is None:
98
100
  if self._col_i is not None and self._col_t is None:
@@ -1,8 +1,9 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import TurbineModel
4
- import foxes.constants as FC
4
+ from foxes.config import config
5
5
  import foxes.variables as FV
6
+ import foxes.constants as FC
6
7
 
7
8
 
8
9
  class SetFarmVars(TurbineModel):
@@ -13,12 +14,14 @@ class SetFarmVars(TurbineModel):
13
14
  ----------
14
15
  vars: list of str
15
16
  The variables to be set
17
+ once: bool
18
+ Flag for running only once
16
19
 
17
20
  :group: models.turbine_models
18
21
 
19
22
  """
20
23
 
21
- def __init__(self, pre_rotor=False):
24
+ def __init__(self, pre_rotor=False, once=False):
22
25
  """
23
26
  Constructor.
24
27
 
@@ -27,9 +30,12 @@ class SetFarmVars(TurbineModel):
27
30
  pre_rotor: bool
28
31
  Flag for running this model before
29
32
  running the rotor model.
33
+ once: bool
34
+ Flag for running only once
30
35
 
31
36
  """
32
37
  super().__init__(pre_rotor=pre_rotor)
38
+ self.once = once
33
39
  self.reset()
34
40
 
35
41
  def add_var(self, var, data):
@@ -51,7 +57,7 @@ class SetFarmVars(TurbineModel):
51
57
  if self.running:
52
58
  raise ValueError(f"Model '{self.name}': Cannot add_var while running")
53
59
  self.vars.append(var)
54
- self.__vdata.append(np.asarray(data, dtype=FC.DTYPE))
60
+ self.__vdata.append(np.asarray(data, dtype=config.dtype_double))
55
61
 
56
62
  def reset(self):
57
63
  """
@@ -62,6 +68,23 @@ class SetFarmVars(TurbineModel):
62
68
  self.vars = []
63
69
  self.__vdata = []
64
70
 
71
+ def initialize(self, algo, verbosity=0, force=False):
72
+ """
73
+ Initializes the model.
74
+
75
+ Parameters
76
+ ----------
77
+ algo: foxes.core.Algorithm
78
+ The calculation algorithm
79
+ verbosity: int
80
+ The verbosity level, 0 = silent
81
+ force: bool
82
+ Overwrite existing data
83
+
84
+ """
85
+ super().initialize(algo, verbosity, force)
86
+ self.__once_done = set()
87
+
65
88
  def output_farm_vars(self, algo):
66
89
  """
67
90
  The variables which are being modified by the model.
@@ -105,7 +128,9 @@ class SetFarmVars(TurbineModel):
105
128
  idata = super().load_data(algo, verbosity)
106
129
 
107
130
  for i, v in enumerate(self.vars):
108
- data = np.full((algo.n_states, algo.n_turbines), np.nan, dtype=FC.DTYPE)
131
+ data = np.full(
132
+ (algo.n_states, algo.n_turbines), np.nan, dtype=config.dtype_double
133
+ )
109
134
  vdata = self.__vdata[i]
110
135
 
111
136
  # handle special case of call during vectorized optimization:
@@ -117,7 +142,7 @@ class SetFarmVars(TurbineModel):
117
142
  n_pop = algo.states.n_pop
118
143
  n_ost = algo.states.states.size()
119
144
  n_trb = algo.n_turbines
120
- vdata = np.zeros((n_pop, n_ost, n_trb), dtype=FC.DTYPE)
145
+ vdata = np.zeros((n_pop, n_ost, n_trb), dtype=config.dtype_double)
121
146
  vdata[:] = self.__vdata[i][None, :]
122
147
  vdata = vdata.reshape(n_pop * n_ost, n_trb)
123
148
 
@@ -130,7 +155,7 @@ class SetFarmVars(TurbineModel):
130
155
  for ti in range(algo.n_turbines):
131
156
  t = algo.farm.turbines[ti]
132
157
  if len(t.xy.shape) == 1:
133
- xy = np.zeros((algo.n_states, 2), dtype=FC.DTYPE)
158
+ xy = np.zeros((algo.n_states, 2), dtype=config.dtype_double)
134
159
  xy[:] = t.xy[None, :]
135
160
  t.xy = xy
136
161
  t.xy[:, i] = np.where(
@@ -141,7 +166,7 @@ class SetFarmVars(TurbineModel):
141
166
  if v in [FV.D, FV.H]:
142
167
  for ti in range(algo.n_turbines):
143
168
  t = algo.farm.turbines[ti]
144
- x = np.zeros(algo.n_states, dtype=FC.DTYPE)
169
+ x = np.zeros(algo.n_states, dtype=config.dtype_double)
145
170
  if v == FV.D:
146
171
  x[:] = t.D
147
172
  t.D = x
@@ -243,21 +268,26 @@ class SetFarmVars(TurbineModel):
243
268
  Values: numpy.ndarray with shape (n_states, n_turbines)
244
269
 
245
270
  """
246
- if self.pre_rotor:
247
- order = np.s_[:]
248
- ssel = np.s_[:]
249
- else:
250
- order = fdata[FV.ORDER]
251
- ssel = fdata[FV.ORDER_SSEL]
252
-
253
- bsel = np.zeros((fdata.n_states, fdata.n_turbines), dtype=bool)
254
- bsel[st_sel] = True
255
-
256
- for v in self.vars:
257
- data = mdata[self.var(v)][ssel, order]
258
- hsel = ~np.isnan(data)
259
- tsel = bsel & hsel
260
-
261
- fdata[v][tsel] = data[tsel]
271
+ i0 = mdata.states_i0(counter=True)
272
+ if not self.once or i0 not in self.__once_done:
273
+
274
+ if self.pre_rotor:
275
+ order = np.s_[:]
276
+ ssel = np.s_[:]
277
+ else:
278
+ order = fdata[FV.ORDER]
279
+ ssel = fdata[FV.ORDER_SSEL]
280
+
281
+ bsel = np.zeros((fdata.n_states, fdata.n_turbines), dtype=bool)
282
+ bsel[st_sel] = True
283
+
284
+ for v in self.vars:
285
+ data = mdata[self.var(v)][ssel, order]
286
+ hsel = ~np.isnan(data)
287
+ tsel = bsel & hsel
288
+
289
+ fdata[v][tsel] = data[tsel]
290
+
291
+ self.__once_done.add(i0)
262
292
 
263
293
  return {v: fdata[v] for v in self.vars}
@@ -4,7 +4,7 @@ from scipy.interpolate import interpn
4
4
 
5
5
  from foxes.core import TurbineModel
6
6
  from foxes.utils import PandasFileHelper
7
- import foxes.constants as FC
7
+ from foxes.config import config, get_path
8
8
 
9
9
 
10
10
  class TableFactors(TurbineModel):
@@ -106,15 +106,16 @@ class TableFactors(TurbineModel):
106
106
  if isinstance(self.data_source, pd.DataFrame):
107
107
  self._data = self.data_source
108
108
  else:
109
+ fpath = get_path(self.data_source)
109
110
  if verbosity > 0:
110
- print(f"{self.name}: Reading file {self.data_source}")
111
+ print(f"{self.name}: Reading file {fpath}")
111
112
  rpars = dict(index_col=0)
112
113
  rpars.update(self._rpars)
113
- self._data = PandasFileHelper.read_file(self.data_source, **rpars)
114
+ self._data = PandasFileHelper.read_file(fpath, **rpars)
114
115
 
115
- self._rvals = self._data.index.to_numpy(FC.DTYPE)
116
- self._cvals = self._data.columns.to_numpy(FC.DTYPE)
117
- self._data = self._data.to_numpy(FC.DTYPE)
116
+ self._rvals = self._data.index.to_numpy(config.dtype_double)
117
+ self._cvals = self._data.columns.to_numpy(config.dtype_double)
118
+ self._data = self._data.to_numpy(config.dtype_double)
118
119
 
119
120
  def calculate(self, algo, mdata, fdata, st_sel):
120
121
  """
@@ -143,7 +144,7 @@ class TableFactors(TurbineModel):
143
144
 
144
145
  """
145
146
  n_sel = np.sum(st_sel)
146
- qts = np.zeros((n_sel, 2), dtype=FC.DTYPE)
147
+ qts = np.zeros((n_sel, 2), dtype=config.dtype_double)
147
148
  qts[:, 0] = fdata[self.row_var][st_sel]
148
149
  qts[:, 1] = fdata[self.col_var][st_sel]
149
150
 
@@ -1,6 +1,5 @@
1
1
  from foxes.core import TurbineModel
2
2
  import foxes.variables as FV
3
- import foxes.constants as FC
4
3
  from foxes.utils import delta_wd
5
4
 
6
5
 
@@ -2,7 +2,6 @@ import numpy as np
2
2
 
3
3
  from foxes.core import TurbineModel
4
4
  import foxes.variables as FV
5
- import foxes.constants as FC
6
5
 
7
6
 
8
7
  class YAWM2YAW(TurbineModel):