foxes 1.3__py3-none-any.whl → 1.5__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 (228) hide show
  1. docs/source/conf.py +3 -3
  2. examples/abl_states/run.py +2 -2
  3. examples/compare_rotors_pwakes/run.py +1 -1
  4. examples/compare_wakes/run.py +1 -2
  5. examples/dyn_wakes/run.py +29 -6
  6. examples/field_data_nc/run.py +1 -1
  7. examples/induction/run.py +3 -3
  8. examples/multi_height/run.py +1 -1
  9. examples/power_mask/run.py +2 -2
  10. examples/quickstart/run.py +0 -1
  11. examples/random_timeseries/run.py +3 -4
  12. examples/scan_row/run.py +3 -3
  13. examples/sequential/run.py +33 -10
  14. examples/single_state/run.py +3 -4
  15. examples/states_lookup_table/run.py +3 -3
  16. examples/streamline_wakes/run.py +29 -6
  17. examples/tab_file/run.py +3 -3
  18. examples/timelines/run.py +29 -5
  19. examples/timeseries/run.py +3 -3
  20. examples/timeseries_slurm/run.py +3 -3
  21. examples/wind_rose/run.py +3 -3
  22. examples/yawed_wake/run.py +19 -9
  23. foxes/__init__.py +21 -17
  24. foxes/algorithms/__init__.py +6 -6
  25. foxes/algorithms/downwind/__init__.py +2 -2
  26. foxes/algorithms/downwind/downwind.py +49 -17
  27. foxes/algorithms/downwind/models/__init__.py +6 -6
  28. foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
  29. foxes/algorithms/downwind/models/init_farm_data.py +58 -29
  30. foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
  31. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  32. foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
  33. foxes/algorithms/iterative/__init__.py +7 -3
  34. foxes/algorithms/iterative/iterative.py +1 -2
  35. foxes/algorithms/iterative/models/__init__.py +7 -3
  36. foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
  37. foxes/algorithms/sequential/__init__.py +3 -3
  38. foxes/algorithms/sequential/models/__init__.py +2 -2
  39. foxes/algorithms/sequential/sequential.py +3 -4
  40. foxes/config/__init__.py +5 -1
  41. foxes/constants.py +16 -0
  42. foxes/core/__init__.py +45 -22
  43. foxes/core/algorithm.py +5 -6
  44. foxes/core/data.py +94 -22
  45. foxes/core/data_calc_model.py +4 -2
  46. foxes/core/engine.py +42 -53
  47. foxes/core/farm_controller.py +2 -2
  48. foxes/core/farm_data_model.py +16 -13
  49. foxes/core/ground_model.py +4 -13
  50. foxes/core/model.py +24 -6
  51. foxes/core/partial_wakes_model.py +147 -10
  52. foxes/core/point_data_model.py +21 -17
  53. foxes/core/rotor_model.py +4 -3
  54. foxes/core/states.py +2 -3
  55. foxes/core/turbine.py +2 -1
  56. foxes/core/wake_deflection.py +130 -0
  57. foxes/core/wake_model.py +222 -9
  58. foxes/core/wake_superposition.py +122 -4
  59. foxes/core/wind_farm.py +6 -6
  60. foxes/data/__init__.py +7 -2
  61. foxes/data/states/point_cloud_100.nc +0 -0
  62. foxes/data/states/weibull_cloud_4.nc +0 -0
  63. foxes/data/states/weibull_grid.nc +0 -0
  64. foxes/data/states/weibull_sectors_12.csv +13 -0
  65. foxes/data/states/weibull_sectors_12.nc +0 -0
  66. foxes/engines/__init__.py +14 -15
  67. foxes/engines/dask.py +42 -20
  68. foxes/engines/default.py +2 -2
  69. foxes/engines/numpy.py +11 -13
  70. foxes/engines/pool.py +20 -11
  71. foxes/engines/single.py +8 -6
  72. foxes/input/__init__.py +3 -3
  73. foxes/input/farm_layout/__init__.py +9 -8
  74. foxes/input/farm_layout/from_arrays.py +68 -0
  75. foxes/input/farm_layout/from_csv.py +1 -1
  76. foxes/input/farm_layout/ring.py +0 -1
  77. foxes/input/states/__init__.py +28 -12
  78. foxes/input/states/create/__init__.py +3 -2
  79. foxes/input/states/dataset_states.py +710 -0
  80. foxes/input/states/field_data.py +531 -0
  81. foxes/input/states/multi_height.py +11 -6
  82. foxes/input/states/one_point_flow.py +1 -4
  83. foxes/input/states/point_cloud_data.py +618 -0
  84. foxes/input/states/scan.py +2 -0
  85. foxes/input/states/single.py +3 -1
  86. foxes/input/states/states_table.py +23 -30
  87. foxes/input/states/weibull_sectors.py +330 -0
  88. foxes/input/states/wrg_states.py +8 -6
  89. foxes/input/yaml/__init__.py +9 -3
  90. foxes/input/yaml/dict.py +42 -41
  91. foxes/input/yaml/windio/__init__.py +10 -5
  92. foxes/input/yaml/windio/read_attributes.py +42 -29
  93. foxes/input/yaml/windio/read_farm.py +17 -15
  94. foxes/input/yaml/windio/read_fields.py +4 -2
  95. foxes/input/yaml/windio/read_outputs.py +25 -15
  96. foxes/input/yaml/windio/read_site.py +172 -11
  97. foxes/input/yaml/windio/windio.py +23 -11
  98. foxes/input/yaml/yaml.py +1 -0
  99. foxes/models/__init__.py +15 -14
  100. foxes/models/axial_induction/__init__.py +2 -2
  101. foxes/models/farm_controllers/__init__.py +1 -1
  102. foxes/models/farm_models/__init__.py +1 -1
  103. foxes/models/ground_models/__init__.py +3 -2
  104. foxes/models/ground_models/wake_mirror.py +3 -3
  105. foxes/models/model_book.py +190 -63
  106. foxes/models/partial_wakes/__init__.py +6 -6
  107. foxes/models/partial_wakes/axiwake.py +30 -5
  108. foxes/models/partial_wakes/centre.py +47 -0
  109. foxes/models/partial_wakes/rotor_points.py +41 -11
  110. foxes/models/partial_wakes/segregated.py +2 -25
  111. foxes/models/partial_wakes/top_hat.py +27 -2
  112. foxes/models/point_models/__init__.py +4 -4
  113. foxes/models/rotor_models/__init__.py +4 -3
  114. foxes/models/rotor_models/centre.py +1 -1
  115. foxes/models/rotor_models/direct_infusion.py +241 -0
  116. foxes/models/turbine_models/__init__.py +11 -11
  117. foxes/models/turbine_models/calculator.py +16 -3
  118. foxes/models/turbine_models/kTI_model.py +1 -0
  119. foxes/models/turbine_models/lookup_table.py +2 -0
  120. foxes/models/turbine_models/power_mask.py +1 -0
  121. foxes/models/turbine_models/rotor_centre_calc.py +2 -0
  122. foxes/models/turbine_models/sector_management.py +1 -0
  123. foxes/models/turbine_models/set_farm_vars.py +3 -9
  124. foxes/models/turbine_models/table_factors.py +2 -0
  125. foxes/models/turbine_models/thrust2ct.py +1 -0
  126. foxes/models/turbine_models/yaw2yawm.py +2 -0
  127. foxes/models/turbine_models/yawm2yaw.py +2 -0
  128. foxes/models/turbine_types/PCt_file.py +2 -6
  129. foxes/models/turbine_types/PCt_from_two.py +1 -2
  130. foxes/models/turbine_types/__init__.py +10 -9
  131. foxes/models/turbine_types/calculator_type.py +123 -0
  132. foxes/models/turbine_types/null_type.py +1 -0
  133. foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -0
  134. foxes/models/turbine_types/wsti2PCt_from_two.py +3 -1
  135. foxes/models/vertical_profiles/__init__.py +7 -7
  136. foxes/models/wake_deflections/__init__.py +3 -0
  137. foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
  138. foxes/models/wake_deflections/jimenez.py +277 -0
  139. foxes/models/wake_deflections/no_deflection.py +94 -0
  140. foxes/models/wake_frames/__init__.py +6 -7
  141. foxes/models/wake_frames/dynamic_wakes.py +12 -3
  142. foxes/models/wake_frames/rotor_wd.py +3 -1
  143. foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
  144. foxes/models/wake_frames/streamlines.py +8 -6
  145. foxes/models/wake_frames/timelines.py +9 -3
  146. foxes/models/wake_models/__init__.py +7 -7
  147. foxes/models/wake_models/dist_sliced.py +50 -84
  148. foxes/models/wake_models/gaussian.py +20 -0
  149. foxes/models/wake_models/induction/__init__.py +5 -5
  150. foxes/models/wake_models/induction/rankine_half_body.py +30 -71
  151. foxes/models/wake_models/induction/rathmann.py +65 -64
  152. foxes/models/wake_models/induction/self_similar.py +65 -68
  153. foxes/models/wake_models/induction/self_similar2020.py +0 -3
  154. foxes/models/wake_models/induction/vortex_sheet.py +71 -75
  155. foxes/models/wake_models/ti/__init__.py +2 -2
  156. foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
  157. foxes/models/wake_models/ti/iec_ti.py +6 -4
  158. foxes/models/wake_models/top_hat.py +58 -7
  159. foxes/models/wake_models/wind/__init__.py +6 -4
  160. foxes/models/wake_models/wind/bastankhah14.py +25 -7
  161. foxes/models/wake_models/wind/bastankhah16.py +35 -3
  162. foxes/models/wake_models/wind/jensen.py +15 -2
  163. foxes/models/wake_models/wind/turbopark.py +28 -2
  164. foxes/models/wake_superpositions/__init__.py +18 -9
  165. foxes/models/wake_superpositions/ti_linear.py +4 -4
  166. foxes/models/wake_superpositions/ti_max.py +4 -4
  167. foxes/models/wake_superpositions/ti_pow.py +4 -4
  168. foxes/models/wake_superpositions/ti_quadratic.py +4 -4
  169. foxes/models/wake_superpositions/wind_vector.py +257 -0
  170. foxes/models/wake_superpositions/ws_linear.py +9 -10
  171. foxes/models/wake_superpositions/ws_max.py +8 -8
  172. foxes/models/wake_superpositions/ws_pow.py +8 -8
  173. foxes/models/wake_superpositions/ws_product.py +4 -4
  174. foxes/models/wake_superpositions/ws_quadratic.py +8 -8
  175. foxes/output/__init__.py +21 -19
  176. foxes/output/farm_layout.py +4 -2
  177. foxes/output/farm_results_eval.py +19 -16
  178. foxes/output/flow_plots_2d/__init__.py +2 -2
  179. foxes/output/flow_plots_2d/flow_plots.py +18 -0
  180. foxes/output/flow_plots_2d/get_fig.py +5 -2
  181. foxes/output/output.py +6 -1
  182. foxes/output/results_writer.py +1 -1
  183. foxes/output/rose_plot.py +13 -3
  184. foxes/output/rotor_point_plots.py +3 -0
  185. foxes/output/seq_plugins/__init__.py +2 -2
  186. foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
  187. foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
  188. foxes/output/state_turbine_map.py +3 -0
  189. foxes/output/turbine_type_curves.py +10 -8
  190. foxes/utils/__init__.py +37 -19
  191. foxes/utils/abl/__init__.py +4 -4
  192. foxes/utils/cubic_roots.py +1 -1
  193. foxes/utils/data_book.py +4 -3
  194. foxes/utils/dict.py +49 -37
  195. foxes/utils/exec_python.py +5 -5
  196. foxes/utils/factory.py +3 -5
  197. foxes/utils/geom2d/__init__.py +7 -5
  198. foxes/utils/geopandas_utils.py +2 -2
  199. foxes/utils/pandas_utils.py +4 -3
  200. foxes/utils/tab_files.py +0 -1
  201. foxes/utils/weibull.py +28 -0
  202. foxes/utils/wrg_utils.py +3 -1
  203. foxes/utils/xarray_utils.py +9 -2
  204. foxes/variables.py +67 -9
  205. {foxes-1.3.dist-info → foxes-1.5.dist-info}/METADATA +34 -63
  206. foxes-1.5.dist-info/RECORD +328 -0
  207. {foxes-1.3.dist-info → foxes-1.5.dist-info}/WHEEL +1 -1
  208. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
  209. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
  210. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
  211. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
  212. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
  213. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
  214. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
  215. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
  216. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
  217. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
  218. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
  219. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
  220. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
  221. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
  222. foxes/input/states/field_data_nc.py +0 -847
  223. foxes/output/round.py +0 -10
  224. foxes/utils/pandas_helpers.py +0 -178
  225. foxes-1.3.dist-info/RECORD +0 -313
  226. {foxes-1.3.dist-info → foxes-1.5.dist-info}/entry_points.txt +0 -0
  227. {foxes-1.3.dist-info → foxes-1.5.dist-info/licenses}/LICENSE +0 -0
  228. {foxes-1.3.dist-info → foxes-1.5.dist-info}/top_level.txt +0 -0
@@ -12,9 +12,7 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
12
12
  if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get_item(
13
13
  "report", True
14
14
  ):
15
- turbine_outputs = Dict(
16
- wio_outs["turbine_outputs"], name=wio_outs.name + ".turbine_outputs"
17
- )
15
+ turbine_outputs = wio_outs["turbine_outputs"]
18
16
  turbine_nc_filename = turbine_outputs.pop_item(
19
17
  "turbine_nc_filename", "turbine_outputs.nc"
20
18
  )
@@ -27,6 +25,7 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
27
25
  vmap = Dict(
28
26
  power=FV.P,
29
27
  rotor_effective_velocity=FV.REWS,
28
+ _name="vmap",
30
29
  )
31
30
  ivmap = {d: k for k, d in vmap.items()}
32
31
  ivmap.update(
@@ -56,7 +55,7 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
56
55
  verbosity=verbosity,
57
56
  )
58
57
  ],
59
- name=f"outputs.output{len(olist)}.StateTurbineTable",
58
+ _name=f"outputs.{len(olist)}.StateTurbineTable",
60
59
  )
61
60
  )
62
61
 
@@ -64,13 +63,11 @@ def _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity):
64
63
  def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
65
64
  """Reads the flow field request"""
66
65
  if "flow_field" in wio_outs and wio_outs["flow_field"].get_item("report", True):
67
- flow_field = Dict(wio_outs["flow_field"], name=wio_outs.name + ".flow_field")
66
+ flow_field = wio_outs["flow_field"]
68
67
  flow_nc_filename = flow_field.pop_item("flow_nc_filename", "flow_field.nc")
69
68
  output_variables = flow_field.pop_item("output_variables")
70
69
 
71
- z_planes = Dict(
72
- flow_field.pop_item("z_planes"), name=flow_field.name + ".z_planes"
73
- )
70
+ z_planes = flow_field.pop_item("z_planes")
74
71
  z_sampling = z_planes["z_sampling"]
75
72
  xy_sampling = z_planes["xy_sampling"]
76
73
 
@@ -85,6 +82,7 @@ def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
85
82
  vmap = Dict(
86
83
  wind_speed=FV.WS,
87
84
  wind_direction=FV.WD,
85
+ _name="vmap",
88
86
  )
89
87
 
90
88
  z_list = []
@@ -147,7 +145,7 @@ def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
147
145
  verbosity=verbosity,
148
146
  )
149
147
  ],
150
- name=f"outputs.output{len(olist)}.SliceData",
148
+ _name=f"outputs.output{len(olist)}.SliceData",
151
149
  )
152
150
  )
153
151
  else:
@@ -187,13 +185,25 @@ def read_outputs(wio_outs, idict, algo, verbosity=1):
187
185
  print(" Contents :", [k for k in wio_outs.keys()])
188
186
 
189
187
  # read subset:
190
- cases_run = Dict(
191
- wio_outs.pop_item("cases_run", {}), name=wio_outs.name + ".cases_run"
192
- )
193
- if cases_run.pop_item("all_occurences"):
188
+ run_configuration = wio_outs.pop_item("run_configuration", {})
189
+ if "times_run" in run_configuration:
190
+ times_run = run_configuration.pop_item("times_run")
191
+ if times_run.get_item("all_occurences"):
192
+ states_isel = None
193
+ else:
194
+ states_isel = times_run.get_item("subset")
195
+ elif "wind_speeds_run" in run_configuration:
196
+ wind_speeds_run = run_configuration.get_item("wind_speeds_run")
197
+ directions_run = run_configuration.get_item("directions_run")
198
+ if not wind_speeds_run.get_item("all_values"):
199
+ raise NotImplementedError(
200
+ f"Wind speed and direction subsets are not yet supported, got {wind_speeds_run.name} {wind_speeds_run}"
201
+ )
202
+ if not directions_run.get_item("all_values"):
203
+ raise NotImplementedError(
204
+ f"Wind speed and direction subsets are not yet supported, got {directions_run.name} {directions_run}"
205
+ )
194
206
  states_isel = None
195
- else:
196
- states_isel = cases_run.pop_item("subset")
197
207
 
198
208
  # read turbine_outputs:
199
209
  _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity)
@@ -159,6 +159,162 @@ def _get_MultiHeightNCTimeseries(
159
159
  return False
160
160
 
161
161
 
162
+ def _get_WeibullSectors(
163
+ coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
164
+ ):
165
+ """Try to generate Weibull sector parameters
166
+ :group: input.yaml.windio
167
+ """
168
+ if (
169
+ FV.WEIBULL_A in fields
170
+ and FV.WEIBULL_k in fields
171
+ and "sector_probability" in fields
172
+ and len(dims[FV.WEIBULL_A]) == 1
173
+ and len(dims[FV.WEIBULL_k]) == 1
174
+ and len(dims["sector_probability"]) == 1
175
+ ):
176
+ if verbosity > 2:
177
+ print(" selecting class 'WeibullSectors'")
178
+
179
+ data = {}
180
+ fix = {}
181
+ c = dims[FV.WEIBULL_A][0]
182
+ for v, d in fields.items():
183
+ if dims[v] == (c,):
184
+ data[v] = d
185
+ elif len(dims[v]) == 0:
186
+ fix[v] = d
187
+ elif verbosity > 2:
188
+ print(f" ignoring field '{v}' with dims {dims[v]}")
189
+ fix.update({v: d for v, d in fixval.items() if v not in data})
190
+
191
+ if FV.WD in coords:
192
+ data[FV.WD] = coords[FV.WD]
193
+
194
+ sdata = pd.DataFrame(index=range(len(fields[FV.WEIBULL_A])), data=data)
195
+ sdata.index.name = "sector"
196
+ states_dict.update(
197
+ dict(
198
+ states_type="WeibullSectors",
199
+ data_source=sdata,
200
+ ws_bins=np.arange(60) / 2 if FV.WS not in sdata else None,
201
+ output_vars=ovars,
202
+ var2ncvar={FV.WEIGHT: "sector_probability"},
203
+ fixed_vars=fix,
204
+ profiles=profiles,
205
+ )
206
+ )
207
+ return True
208
+ return False
209
+
210
+
211
+ def _get_WeibullPointCloud(
212
+ coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
213
+ ):
214
+ """Try to generate Weibull sector parameters
215
+ :group: input.yaml.windio
216
+ """
217
+ if (
218
+ FV.WD in coords
219
+ and FV.WEIBULL_A in fields
220
+ and FV.WEIBULL_k in fields
221
+ and "sector_probability" in fields
222
+ and FV.X in fields
223
+ and FV.Y in fields
224
+ and len(dims[FV.X]) == 1
225
+ and dims[FV.X] == dims[FV.Y]
226
+ and dims[FV.X][0] != FV.WD
227
+ and dims[FV.X][0] in coords
228
+ ):
229
+ if verbosity > 2:
230
+ print(" selecting class 'WeibullPointCloud'")
231
+
232
+ data = {}
233
+ fix = {}
234
+ for v, d in fields.items():
235
+ if len(dims[v]) == 0:
236
+ fix[v] = d
237
+ elif v not in fixval:
238
+ data[v] = (dims[v], d)
239
+ fix.update({v: d for v, d in fixval.items() if v not in data})
240
+
241
+ sdata = Dataset(
242
+ coords=coords,
243
+ data_vars=data,
244
+ )
245
+
246
+ states_dict.update(
247
+ dict(
248
+ states_type="WeibullPointCloud",
249
+ data_source=sdata,
250
+ output_vars=ovars,
251
+ var2ncvar={},
252
+ fixed_vars=fix,
253
+ point_coord=dims[FV.X][0],
254
+ wd_coord=FV.WD,
255
+ ws_coord=FV.WS if FV.WS in sdata.coords else None,
256
+ ws_bins=np.arange(60) / 2 if FV.WS not in sdata else None,
257
+ x_ncvar=FV.X,
258
+ y_ncvar=FV.Y,
259
+ h_ncvar=FV.H if FV.H in sdata.data_vars else None,
260
+ weight_ncvar="sector_probability",
261
+ )
262
+ )
263
+ return True
264
+ return False
265
+
266
+
267
+ def _get_WeibullField(
268
+ coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
269
+ ):
270
+ """Try to generate Weibull sector parameters
271
+ :group: input.yaml.windio
272
+ """
273
+ if (
274
+ FV.WD in coords
275
+ and FV.X in coords
276
+ and FV.Y in coords
277
+ and FV.WEIBULL_A in fields
278
+ and FV.WEIBULL_k in fields
279
+ and "sector_probability" in fields
280
+ ):
281
+ if verbosity > 2:
282
+ print(" selecting class 'WeibullField'")
283
+
284
+ data = {}
285
+ fix = {}
286
+ for v, d in fields.items():
287
+ if len(dims[v]) == 0:
288
+ fix[v] = d
289
+ elif v not in fixval:
290
+ data[v] = (dims[v], d)
291
+ fix.update({v: d for v, d in fixval.items() if v not in data})
292
+
293
+ sdata = Dataset(
294
+ coords=coords,
295
+ data_vars=data,
296
+ )
297
+
298
+ states_dict.update(
299
+ dict(
300
+ states_type="WeibullField",
301
+ data_source=sdata,
302
+ output_vars=ovars,
303
+ wd_coord=FV.WD,
304
+ x_coord=FV.X,
305
+ y_coord=FV.Y,
306
+ h_coord=FV.H if FV.H in sdata.coords else None,
307
+ weight_ncvar="sector_probability",
308
+ var2ncvar={},
309
+ fixed_vars=fix,
310
+ ws_bins=np.arange(60) / 2 if FV.WS not in sdata.coords else None,
311
+ ws_coord=FV.WS if FV.WS in sdata.coords else None,
312
+ )
313
+ )
314
+ return True
315
+ return False
316
+
317
+
162
318
  def get_states(coords, fields, dims, verbosity=1):
163
319
  """
164
320
  Reads states parameters from windio input
@@ -186,7 +342,7 @@ def get_states(coords, fields, dims, verbosity=1):
186
342
  print(" Creating states")
187
343
 
188
344
  ovars = [FV.WS, FV.WD, FV.TI, FV.RHO]
189
- fixval = {FV.TI: 0.05, FV.RHO: 1.225}
345
+ fixval = {FV.RHO: 1.225}
190
346
  profiles = _get_profiles(coords, fields, dims, ovars, fixval, verbosity)
191
347
 
192
348
  states_dict = {}
@@ -200,6 +356,15 @@ def get_states(coords, fields, dims, verbosity=1):
200
356
  or _get_MultiHeightNCTimeseries(
201
357
  coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
202
358
  )
359
+ or _get_WeibullPointCloud(
360
+ coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
361
+ )
362
+ or _get_WeibullSectors(
363
+ coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
364
+ )
365
+ or _get_WeibullField(
366
+ coords, fields, dims, states_dict, ovars, fixval, profiles, verbosity
367
+ )
203
368
  ):
204
369
  return States.new(**states_dict)
205
370
  else:
@@ -232,32 +397,28 @@ def read_site(wio_dict, verbosity=1):
232
397
  if verbosity >= level:
233
398
  print(*args, **kwargs)
234
399
 
235
- wio_site = Dict(wio_dict["site"], name=wio_dict.name + ".site")
400
+ wio_site = wio_dict["site"]
236
401
  _print("Reading site")
237
402
  _print(" Name:", wio_site.pop_item("name", None))
238
403
  _print(" Contents:", [k for k in wio_site.keys()])
239
404
  _print(" Ignoring boundaries", level=2)
240
405
 
241
406
  # read energy_resource:
242
- energy_resource = Dict(
243
- wio_site["energy_resource"], name=wio_site.name + ".energy_resource"
244
- )
407
+ energy_resource = wio_site["energy_resource"]
245
408
  _print(" Reading energy_resource", level=2)
246
409
  _print(" Name:", energy_resource.pop_item("name", None), level=2)
247
410
  _print(" Contents:", [k for k in energy_resource.keys()], level=2)
248
411
 
249
412
  # read wind_resource:
250
- wind_resource = Dict(
251
- energy_resource["wind_resource"], name=energy_resource.name + ".wind_resource"
252
- )
413
+ wind_resource = energy_resource["wind_resource"]
253
414
  _print(" Reading wind_resource", level=3)
254
415
  _print(" Name:", wind_resource.pop_item("name", None), level=3)
255
416
  _print(" Contents:", [k for k in wind_resource.keys()], level=3)
256
417
 
257
418
  # read fields
258
- coords = Dict(name="coords")
259
- fields = Dict(name="fields")
260
- dims = Dict(name="dims")
419
+ coords = Dict(_name="coords")
420
+ fields = Dict(_name="fields")
421
+ dims = Dict(_name="dims")
261
422
  for n, d in wind_resource.items():
262
423
  read_wind_resource_field(n, d, coords, fields, dims, verbosity)
263
424
  if verbosity > 2:
@@ -41,40 +41,52 @@ def read_windio(wio_dict, verbosity=1):
41
41
  print(*args, **kwargs)
42
42
 
43
43
  if not isinstance(wio_dict, Dict):
44
- wio_dict = Dict(wio_dict, name="windio")
44
+ tmp = Dict(_name="windio")
45
+ for k, d in wio_dict.items():
46
+ tmp[k] = d
47
+ wio_dict = tmp
45
48
 
46
- _print(f"Reading windio data")
49
+ _print("Reading windio data")
47
50
  _print(" Name:", wio_dict.pop_item("name", None))
48
51
  _print(" Contents:", [k for k in wio_dict.keys()])
49
52
 
50
53
  idict = Dict(
51
- wind_farm=Dict(name="wio2fxs.farm"),
54
+ wind_farm=Dict(_name="wio2fxs.farm"),
52
55
  algorithm=Dict(
53
56
  algo_type="Downwind",
54
57
  wake_models=[],
55
- name="wio2fxs.algorithm",
58
+ _name="wio2fxs.algorithm",
56
59
  verbosity=verbosity - 3,
57
60
  ),
58
- calc_farm=Dict(run=True, name="wio2fxs.calc_farm"),
59
- name="wio2fxs",
61
+ calc_farm=Dict(run=True, _name="wio2fxs.calc_farm"),
62
+ _name="wio2fxs",
60
63
  )
61
64
 
62
65
  mbook = ModelBook()
63
66
  states = read_site(wio_dict, verbosity)
64
67
  farm = read_farm(wio_dict, mbook, verbosity)
65
68
 
66
- wio_attrs = Dict(wio_dict["attributes"], name=wio_dict.name + ".attributes")
69
+ wio_attrs = wio_dict["attributes"]
67
70
  read_attributes(wio_attrs, idict, mbook, verbosity=verbosity)
68
71
 
72
+ # special case WeibullPointCloud:
73
+ if (
74
+ type(states).__name__ == "WeibullPointCloud"
75
+ and idict["algorithm"]["rotor_model"] == "centre"
76
+ ):
77
+ _print(
78
+ "Found WeibullPointCloud states, changing rotor model from 'centre' to 'direct_mdata'",
79
+ level=3,
80
+ )
81
+ idict["algorithm"]["rotor_model"] = "direct_mdata"
82
+
69
83
  algo = Algorithm.new(
70
84
  farm=farm, states=states, mbook=mbook, **idict.pop_item("algorithm")
71
85
  )
72
86
 
73
87
  odir = None
74
88
  if "model_outputs_specification" in wio_attrs:
75
- outputs = Dict(
76
- wio_attrs["model_outputs_specification"], name=wio_attrs.name + ".outputs"
77
- )
89
+ outputs = wio_attrs["model_outputs_specification"]
78
90
  odir = read_outputs(outputs, idict, algo, verbosity=verbosity)
79
91
 
80
92
  return idict, algo, odir
@@ -171,7 +183,7 @@ def foxes_windio():
171
183
  conda_hint="",
172
184
  )
173
185
 
174
- wio = Dict(yml_utils.load_yaml(wio_file), name="windio")
186
+ wio = Dict(yml_utils.load_yaml(wio_file), _name="windio")
175
187
  idict, algo, odir = read_windio(wio, verbosity=args.verbosity)
176
188
 
177
189
  if args.output_dir is not None:
foxes/input/yaml/yaml.py CHANGED
@@ -99,5 +99,6 @@ def foxes_yaml():
99
99
  iterative=args.iterative,
100
100
  input_dir=fpath.parent,
101
101
  output_dir=args.output_dir,
102
+ nofig=args.nofig,
102
103
  verbosity=args.verbosity,
103
104
  )
foxes/models/__init__.py CHANGED
@@ -2,18 +2,19 @@
2
2
  Model collection.
3
3
  """
4
4
 
5
- from . import turbine_types
6
- from . import rotor_models
7
- from . import turbine_models
8
- from . import farm_models
9
- from . import partial_wakes
10
- from . import wake_frames
11
- from . import wake_models
12
- from . import wake_superpositions
13
- from . import farm_controllers
14
- from . import vertical_profiles
15
- from . import point_models
16
- from . import axial_induction
17
- from . import ground_models
5
+ from . import turbine_types as turbine_types
6
+ from . import rotor_models as rotor_models
7
+ from . import turbine_models as turbine_models
8
+ from . import farm_models as farm_models
9
+ from . import partial_wakes as partial_wakes
10
+ from . import wake_frames as wake_frames
11
+ from . import wake_models as wake_models
12
+ from . import wake_deflections as wake_deflections
13
+ from . import wake_superpositions as wake_superpositions
14
+ from . import farm_controllers as farm_controllers
15
+ from . import vertical_profiles as vertical_profiles
16
+ from . import point_models as point_models
17
+ from . import axial_induction as axial_induction
18
+ from . import ground_models as ground_models
18
19
 
19
- from .model_book import ModelBook
20
+ from .model_book import ModelBook as ModelBook
@@ -1,2 +1,2 @@
1
- from .betz import BetzAxialInduction
2
- from .madsen import MadsenAxialInduction
1
+ from .betz import BetzAxialInduction as BetzAxialInduction
2
+ from .madsen import MadsenAxialInduction as MadsenAxialInduction
@@ -2,4 +2,4 @@
2
2
  Farm controller models.
3
3
  """
4
4
 
5
- from .basic import BasicFarmController
5
+ from .basic import BasicFarmController as BasicFarmController
@@ -2,4 +2,4 @@
2
2
  Farm models.
3
3
  """
4
4
 
5
- from .turbine2farm import Turbine2FarmModel
5
+ from .turbine2farm import Turbine2FarmModel as Turbine2FarmModel
@@ -1,2 +1,3 @@
1
- from .no_ground import NoGround
2
- from .wake_mirror import WakeMirror, GroundMirror
1
+ from .no_ground import NoGround as NoGround
2
+ from .wake_mirror import WakeMirror as WakeMirror
3
+ from .wake_mirror import GroundMirror as GroundMirror
@@ -75,13 +75,14 @@ class WakeMirror(GroundModel):
75
75
  # assert(np.all(fdata[FV.H]==fdata[FV.TXYH[..., 2]]))
76
76
 
77
77
  # contribution from main wake:
78
- wcoos = algo.wake_frame.get_wake_coos(algo, mdata, fdata, tdata, downwind_index)
78
+ wcoos = algo.wake_frame.get_wake_coos(
79
+ algo, mdata, fdata, tdata, downwind_index, wmodel
80
+ )
79
81
  wmodel.contribute(algo, mdata, fdata, tdata, downwind_index, wcoos, wake_deltas)
80
82
 
81
83
  # contribution from mirrors:
82
84
  tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
83
85
  for h in self.heights:
84
-
85
86
  fdata[FV.TXYH][:, downwind_index, 2] = hh + 2 * (h - hh)
86
87
 
87
88
  pwake.contribute(
@@ -136,7 +137,6 @@ class WakeMirror(GroundModel):
136
137
  # contribution from mirrors:
137
138
  tdata[FC.TARGETS] = tdata[FC.TARGETS].copy() # making sure this is no ref
138
139
  for h in self.heights:
139
-
140
140
  fdata[FV.TXYH][:, downwind_index, 2] = hh + 2 * (h - hh)
141
141
 
142
142
  wcoos = algo.wake_frame.get_wake_coos(