foxes 0.8.2__py3-none-any.whl → 1.0__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 (174) hide show
  1. docs/source/conf.py +353 -0
  2. examples/abl_states/run.py +160 -0
  3. examples/compare_rotors_pwakes/run.py +217 -0
  4. examples/compare_wakes/run.py +241 -0
  5. examples/dyn_wakes/run.py +311 -0
  6. examples/field_data_nc/run.py +121 -0
  7. examples/induction_RHB/run.py +201 -0
  8. examples/multi_height/run.py +113 -0
  9. examples/power_mask/run.py +249 -0
  10. examples/random_timeseries/run.py +210 -0
  11. examples/scan_row/run.py +193 -0
  12. examples/sector_management/run.py +162 -0
  13. examples/sequential/run.py +209 -0
  14. examples/single_state/run.py +201 -0
  15. examples/states_lookup_table/run.py +137 -0
  16. examples/streamline_wakes/run.py +138 -0
  17. examples/tab_file/run.py +142 -0
  18. examples/timelines/run.py +267 -0
  19. examples/timeseries/run.py +183 -0
  20. examples/timeseries_slurm/run.py +185 -0
  21. examples/wind_rose/run.py +141 -0
  22. examples/windio/run.py +29 -0
  23. examples/yawed_wake/run.py +196 -0
  24. foxes/__init__.py +4 -8
  25. foxes/algorithms/__init__.py +1 -1
  26. foxes/algorithms/downwind/downwind.py +232 -101
  27. foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -6
  28. foxes/algorithms/downwind/models/init_farm_data.py +1 -1
  29. foxes/algorithms/downwind/models/point_wakes_calc.py +5 -6
  30. foxes/algorithms/downwind/models/reorder_farm_output.py +0 -1
  31. foxes/algorithms/downwind/models/set_amb_point_results.py +4 -2
  32. foxes/algorithms/iterative/iterative.py +73 -33
  33. foxes/algorithms/iterative/models/farm_wakes_calc.py +11 -6
  34. foxes/algorithms/sequential/models/plugin.py +1 -1
  35. foxes/algorithms/sequential/sequential.py +126 -255
  36. foxes/constants.py +17 -2
  37. foxes/core/__init__.py +1 -0
  38. foxes/core/algorithm.py +631 -146
  39. foxes/core/data.py +252 -20
  40. foxes/core/data_calc_model.py +13 -289
  41. foxes/core/engine.py +630 -0
  42. foxes/core/farm_controller.py +37 -9
  43. foxes/core/farm_data_model.py +15 -0
  44. foxes/core/model.py +133 -80
  45. foxes/core/point_data_model.py +15 -0
  46. foxes/core/rotor_model.py +27 -21
  47. foxes/core/states.py +16 -0
  48. foxes/core/turbine_type.py +28 -0
  49. foxes/core/wake_frame.py +22 -4
  50. foxes/core/wake_model.py +2 -3
  51. foxes/data/windio/windio_5turbines_timeseries.yaml +23 -1
  52. foxes/engines/__init__.py +16 -0
  53. foxes/engines/dask.py +975 -0
  54. foxes/engines/default.py +75 -0
  55. foxes/engines/futures.py +72 -0
  56. foxes/engines/mpi.py +38 -0
  57. foxes/engines/multiprocess.py +74 -0
  58. foxes/engines/numpy.py +185 -0
  59. foxes/engines/pool.py +263 -0
  60. foxes/engines/single.py +139 -0
  61. foxes/input/farm_layout/__init__.py +1 -0
  62. foxes/input/farm_layout/from_csv.py +4 -0
  63. foxes/input/farm_layout/from_json.py +1 -1
  64. foxes/input/farm_layout/grid.py +2 -2
  65. foxes/input/farm_layout/ring.py +65 -0
  66. foxes/input/farm_layout/row.py +2 -2
  67. foxes/input/states/__init__.py +6 -0
  68. foxes/input/states/create/random_abl_states.py +1 -1
  69. foxes/input/states/field_data_nc.py +157 -32
  70. foxes/input/states/multi_height.py +127 -13
  71. foxes/input/states/one_point_flow.py +577 -0
  72. foxes/input/states/scan_ws.py +73 -2
  73. foxes/input/states/states_table.py +204 -35
  74. foxes/input/windio/__init__.py +1 -1
  75. foxes/input/windio/get_states.py +44 -23
  76. foxes/input/windio/read_attributes.py +41 -16
  77. foxes/input/windio/read_farm.py +116 -102
  78. foxes/input/windio/read_fields.py +13 -6
  79. foxes/input/windio/read_outputs.py +63 -22
  80. foxes/input/windio/runner.py +31 -17
  81. foxes/input/windio/windio.py +36 -22
  82. foxes/models/ground_models/wake_mirror.py +8 -4
  83. foxes/models/model_book.py +29 -18
  84. foxes/models/partial_wakes/rotor_points.py +3 -3
  85. foxes/models/rotor_models/centre.py +4 -0
  86. foxes/models/rotor_models/grid.py +22 -23
  87. foxes/models/rotor_models/levels.py +4 -5
  88. foxes/models/turbine_models/calculator.py +0 -2
  89. foxes/models/turbine_models/lookup_table.py +27 -2
  90. foxes/models/turbine_models/rotor_centre_calc.py +4 -3
  91. foxes/models/turbine_models/set_farm_vars.py +103 -34
  92. foxes/models/turbine_types/PCt_file.py +24 -0
  93. foxes/models/turbine_types/PCt_from_two.py +24 -0
  94. foxes/models/turbine_types/__init__.py +1 -0
  95. foxes/models/turbine_types/lookup.py +316 -0
  96. foxes/models/turbine_types/null_type.py +50 -0
  97. foxes/models/turbine_types/wsrho2PCt_from_two.py +24 -0
  98. foxes/models/turbine_types/wsti2PCt_from_two.py +24 -0
  99. foxes/models/vertical_profiles/data_profile.py +1 -1
  100. foxes/models/wake_frames/__init__.py +1 -0
  101. foxes/models/wake_frames/dynamic_wakes.py +424 -0
  102. foxes/models/wake_frames/farm_order.py +23 -3
  103. foxes/models/wake_frames/rotor_wd.py +4 -2
  104. foxes/models/wake_frames/seq_dynamic_wakes.py +56 -63
  105. foxes/models/wake_frames/streamlines.py +19 -20
  106. foxes/models/wake_frames/timelines.py +328 -127
  107. foxes/models/wake_frames/yawed_wakes.py +4 -1
  108. foxes/models/wake_models/dist_sliced.py +1 -3
  109. foxes/models/wake_models/induction/rankine_half_body.py +4 -4
  110. foxes/models/wake_models/induction/rathmann.py +2 -2
  111. foxes/models/wake_models/induction/self_similar.py +2 -2
  112. foxes/models/wake_models/induction/vortex_sheet.py +2 -2
  113. foxes/models/wake_models/ti/iec_ti.py +34 -17
  114. foxes/models/wake_models/top_hat.py +1 -1
  115. foxes/models/wake_models/wind/bastankhah14.py +2 -2
  116. foxes/models/wake_models/wind/bastankhah16.py +8 -7
  117. foxes/models/wake_models/wind/jensen.py +1 -1
  118. foxes/models/wake_models/wind/turbopark.py +2 -2
  119. foxes/output/__init__.py +4 -1
  120. foxes/output/farm_layout.py +2 -2
  121. foxes/output/flow_plots_2d/__init__.py +0 -1
  122. foxes/output/flow_plots_2d/flow_plots.py +70 -30
  123. foxes/output/grids.py +91 -21
  124. foxes/output/seq_plugins/__init__.py +2 -0
  125. foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +62 -20
  126. foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
  127. foxes/output/slice_data.py +131 -111
  128. foxes/output/state_turbine_map.py +18 -13
  129. foxes/output/state_turbine_table.py +19 -19
  130. foxes/utils/__init__.py +1 -1
  131. foxes/utils/dev_utils.py +42 -0
  132. foxes/utils/dict.py +1 -1
  133. foxes/utils/factory.py +147 -52
  134. foxes/utils/pandas_helpers.py +4 -3
  135. foxes/utils/wind_dir.py +0 -2
  136. foxes/utils/xarray_utils.py +23 -13
  137. foxes/variables.py +37 -0
  138. {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/METADATA +71 -33
  139. foxes-1.0.dist-info/RECORD +307 -0
  140. {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/WHEEL +1 -1
  141. foxes-1.0.dist-info/top_level.txt +4 -0
  142. tests/0_consistency/iterative/test_iterative.py +92 -0
  143. tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
  144. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
  145. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
  146. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
  147. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
  148. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
  149. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
  150. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
  151. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
  152. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
  153. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
  154. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
  155. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
  156. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
  157. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
  158. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
  159. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
  160. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
  161. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
  162. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
  163. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
  164. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
  165. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
  166. tests/3_examples/test_examples.py +34 -0
  167. foxes/VERSION +0 -1
  168. foxes/output/flow_plots_2d.py +0 -0
  169. foxes/utils/runners/__init__.py +0 -1
  170. foxes/utils/runners/runners.py +0 -280
  171. foxes-0.8.2.dist-info/RECORD +0 -247
  172. foxes-0.8.2.dist-info/top_level.txt +0 -1
  173. foxes-0.8.2.dist-info/zip-safe +0 -1
  174. {foxes-0.8.2.dist-info → foxes-1.0.dist-info}/LICENSE +0 -0
@@ -6,14 +6,14 @@ from foxes.core import Turbine, TurbineType
6
6
  import foxes.variables as FV
7
7
 
8
8
 
9
- def read_turbine_type(wio_trbns, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
9
+ def read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
10
10
  """
11
11
  Reads the turbine type from windio
12
12
 
13
13
  Parameters
14
14
  ----------
15
- wio_trbns: dict
16
- The windio turbines data
15
+ wio_farm: dict
16
+ The windio farm data
17
17
  algo_dict: dict
18
18
  The algorithm dictionary
19
19
  ws_exp_P: int
@@ -25,107 +25,116 @@ def read_turbine_type(wio_trbns, algo_dict, ws_exp_P, ws_exp_ct, verbosity):
25
25
 
26
26
  Returns
27
27
  -------
28
- ttype: str
29
- The turbine type model name
28
+ ttypes: dict
29
+ Mapping from turbine type key to turbine
30
+ type name in the model book
30
31
 
31
32
  :group: input.windio
32
33
 
33
34
  """
34
- tname = wio_trbns.pop("name")
35
- if verbosity > 2:
36
- print(" Reading wio_trbns")
37
- print(" Name:", tname)
38
- print(" Contents:", [k for k in wio_trbns.keys()])
39
-
40
- # read performance:
41
- performance = Dict(wio_trbns["performance"], name="performance")
42
- if verbosity > 2:
43
- print(" Reading performance")
44
- print(" Contents:", [k for k in performance.keys()])
45
-
46
- # P, ct data:
47
- if "power_curve" in performance:
48
- power_curve = Dict(performance["power_curve"], name="power_curve")
49
- if verbosity > 2:
50
- print(" Reading power_curve")
51
- print(" Contents:", [k for k in power_curve.keys()])
52
- P = power_curve["power_values"]
53
- ws_P = power_curve["power_wind_speeds"]
54
- ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
55
- if verbosity > 2:
56
- print(" Reading Ct_curve")
57
- print(" Contents:", [k for k in ct_curve.keys()])
58
- ct = ct_curve["Ct_values"]
59
- ws_ct = ct_curve["Ct_wind_speeds"]
60
-
61
- data_P = pd.DataFrame(data={"ws": ws_P, "P": P})
62
- data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
63
-
64
- def _get_wse_var(wse):
65
- if wse not in [1, 2, 3]:
66
- raise ValueError(f"Expecting wind speed exponent 1, 2 or 3, got {wse}")
67
- return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
68
-
69
- if verbosity > 2:
70
- print(f" Creating model '{tname}'")
71
- print(f" Turbine type class: PCtFromTwo")
72
- algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
73
- ttype_type="PCtFromTwo",
74
- data_source_P=data_P,
75
- data_source_ct=data_ct,
76
- col_ws_P_file="ws",
77
- col_ws_ct_file="ws",
78
- col_P="P",
79
- col_ct="ct",
80
- H=wio_trbns["hub_height"],
81
- D=wio_trbns["rotor_diameter"],
82
- var_ws_ct=_get_wse_var(ws_exp_ct),
83
- var_ws_P=_get_wse_var(ws_exp_P),
84
- rho=1.225,
85
- )
86
- if verbosity > 2:
87
- print(" ", algo_dict["mbook"].turbine_types[tname])
35
+ if "turbine_types" not in wio_farm:
36
+ wio_farm["turbine_types"] = {0: wio_farm["turbines"]}
88
37
 
89
- # P, ct data:
90
- elif "Cp_curve" in performance:
91
- cp_curve = Dict(performance["Cp_curve"], name="Cp_curve")
92
- if verbosity > 2:
93
- print(" Reading Cp_curve")
94
- print(" Contents:", [k for k in cp_curve.keys()])
95
- cp = cp_curve["Cp_values"]
96
- ws_cp = cp_curve["Cp_wind_speeds"]
97
- ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
38
+ ttypes = {}
39
+ for k, wio_trbns in wio_farm["turbine_types"].items():
40
+ tname = wio_trbns.pop("name")
41
+ ttypes[k] = tname
98
42
  if verbosity > 2:
99
- print(" Reading Ct_curve")
100
- print(" Contents:", [k for k in ct_curve.keys()])
101
- ct = ct_curve["Ct_values"]
102
- ws_ct = ct_curve["Ct_wind_speeds"]
103
-
104
- data_cp = pd.DataFrame(data={"ws": ws_cp, "cp": cp})
105
- data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
43
+ print(" Reading turbine type", k)
44
+ print(" Name:", tname)
45
+ print(" Contents:", [k for k in wio_trbns.keys()])
106
46
 
47
+ # read performance:
48
+ performance = Dict(wio_trbns["performance"], name="performance")
107
49
  if verbosity > 2:
108
- print(f" Creating model '{tname}'")
109
- print(f" Turbine type class: CpCtFromTwo")
110
- algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
111
- ttype_type="CpCtFromTwo",
112
- data_source_cp=data_cp,
113
- data_source_ct=data_ct,
114
- col_ws_cp_file="ws",
115
- col_ws_ct_file="ws",
116
- col_cp="cp",
117
- col_ct="ct",
118
- H=wio_trbns["hub_height"],
119
- D=wio_trbns["rotor_diameter"],
120
- )
121
-
122
- else:
123
- raise KeyError(f"Expecting either 'power_curve' or 'Cp_curve'")
124
-
125
- return tname
126
-
127
-
128
- def read_layout(lname, ldict, algo_dict, ttype, verbosity=1):
50
+ print(" Reading performance")
51
+ print(" Contents:", [k for k in performance.keys()])
52
+
53
+ # P, ct data:
54
+ if "power_curve" in performance:
55
+ power_curve = Dict(performance["power_curve"], name="power_curve")
56
+ if verbosity > 2:
57
+ print(" Reading power_curve")
58
+ print(" Contents:", [k for k in power_curve.keys()])
59
+ P = power_curve["power_values"]
60
+ ws_P = power_curve["power_wind_speeds"]
61
+ ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
62
+ if verbosity > 2:
63
+ print(" Reading Ct_curve")
64
+ print(" Contents:", [k for k in ct_curve.keys()])
65
+ ct = ct_curve["Ct_values"]
66
+ ws_ct = ct_curve["Ct_wind_speeds"]
67
+
68
+ data_P = pd.DataFrame(data={"ws": ws_P, "P": P})
69
+ data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
70
+
71
+ def _get_wse_var(wse):
72
+ if wse not in [1, 2, 3]:
73
+ raise ValueError(
74
+ f"Expecting wind speed exponent 1, 2 or 3, got {wse}"
75
+ )
76
+ return FV.REWS if wse == 1 else (FV.REWS2 if wse == 2 else FV.REWS3)
77
+
78
+ if verbosity > 2:
79
+ print(f" Creating model '{tname}'")
80
+ print(f" Turbine type class: PCtFromTwo")
81
+ algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
82
+ ttype_type="PCtFromTwo",
83
+ data_source_P=data_P,
84
+ data_source_ct=data_ct,
85
+ col_ws_P_file="ws",
86
+ col_ws_ct_file="ws",
87
+ col_P="P",
88
+ col_ct="ct",
89
+ H=wio_trbns["hub_height"],
90
+ D=wio_trbns["rotor_diameter"],
91
+ var_ws_ct=_get_wse_var(ws_exp_ct),
92
+ var_ws_P=_get_wse_var(ws_exp_P),
93
+ rho=1.225,
94
+ )
95
+ if verbosity > 2:
96
+ print(" ", algo_dict["mbook"].turbine_types[tname])
97
+
98
+ # P, ct data:
99
+ elif "Cp_curve" in performance:
100
+ cp_curve = Dict(performance["Cp_curve"], name="Cp_curve")
101
+ if verbosity > 2:
102
+ print(" Reading Cp_curve")
103
+ print(" Contents:", [k for k in cp_curve.keys()])
104
+ cp = cp_curve["Cp_values"]
105
+ ws_cp = cp_curve["Cp_wind_speeds"]
106
+ ct_curve = Dict(performance["Ct_curve"], name="Ct_values")
107
+ if verbosity > 2:
108
+ print(" Reading Ct_curve")
109
+ print(" Contents:", [k for k in ct_curve.keys()])
110
+ ct = ct_curve["Ct_values"]
111
+ ws_ct = ct_curve["Ct_wind_speeds"]
112
+
113
+ data_cp = pd.DataFrame(data={"ws": ws_cp, "cp": cp})
114
+ data_ct = pd.DataFrame(data={"ws": ws_ct, "ct": ct})
115
+
116
+ if verbosity > 2:
117
+ print(f" Creating model '{tname}'")
118
+ print(f" Turbine type class: CpCtFromTwo")
119
+ algo_dict["mbook"].turbine_types[tname] = TurbineType.new(
120
+ ttype_type="CpCtFromTwo",
121
+ data_source_cp=data_cp,
122
+ data_source_ct=data_ct,
123
+ col_ws_cp_file="ws",
124
+ col_ws_ct_file="ws",
125
+ col_cp="cp",
126
+ col_ct="ct",
127
+ H=wio_trbns["hub_height"],
128
+ D=wio_trbns["rotor_diameter"],
129
+ )
130
+
131
+ else:
132
+ raise KeyError(f"Expecting either 'power_curve' or 'Cp_curve'")
133
+
134
+ return ttypes
135
+
136
+
137
+ def read_layout(lname, ldict, algo_dict, ttypes, verbosity=1):
129
138
  """
130
139
  Read wind farm layout from windio input
131
140
 
@@ -137,8 +146,9 @@ def read_layout(lname, ldict, algo_dict, ttype, verbosity=1):
137
146
  The layout data
138
147
  algo_dict: dict
139
148
  The algorithm dictionary
140
- ttype: str
141
- Name of the turbine type model
149
+ ttypes: dict
150
+ Mapping from turbine type key to turbine
151
+ type name in the model book
142
152
  verbosity: int
143
153
  The verbosity level, 0=silent
144
154
 
@@ -154,10 +164,14 @@ def read_layout(lname, ldict, algo_dict, ttype, verbosity=1):
154
164
  print(f" Reading '{lname}'")
155
165
  cdict = Dict(ldict["coordinates"], name="coordinates")
156
166
  farm = algo_dict["farm"]
157
- for xy in zip(cdict["x"], cdict["y"]):
167
+ tmap = ldict.get("turbine_types", None)
168
+ if verbosity > 2:
169
+ print(f" Turbine type map:", tmap)
170
+ for i, xy in enumerate(zip(cdict["x"], cdict["y"])):
171
+ tt = ttypes[tmap[i] if tmap is not None else 0]
158
172
  farm.add_turbine(
159
- Turbine(xy=np.array(xy), turbine_models=[ttype]),
160
- verbosity=verbosity-3,
173
+ Turbine(xy=np.array(xy), turbine_models=[tt]),
174
+ verbosity=verbosity - 3,
161
175
  )
162
176
  if verbosity > 2:
163
- print(f" Added {farm.n_turbines} wio_trbns of type '{ttype}'")
177
+ print(f" Added {farm.n_turbines} turbines")
@@ -28,6 +28,7 @@ wio2foxes = {
28
28
  """
29
29
  foxes2wio = {d: k for k, d in wio2foxes.items()}
30
30
 
31
+
31
32
  def _read_nondimensional_coordinate(name, wio_data, coords):
32
33
  """read nondimensional coordinate
33
34
  :group: input.windio
@@ -37,6 +38,7 @@ def _read_nondimensional_coordinate(name, wio_data, coords):
37
38
  return True
38
39
  return False
39
40
 
41
+
40
42
  def _read_dimensional_coordinate(name, wio_data, coords):
41
43
  """read dimensional coordinate
42
44
  :group: input.windio
@@ -48,6 +50,7 @@ def _read_dimensional_coordinate(name, wio_data, coords):
48
50
  return True
49
51
  return False
50
52
 
53
+
51
54
  def _read_multi_dimensional_coordinate(name, wio_data, coords):
52
55
  """Read multi dimensional coordinate
53
56
  :group: input.windio
@@ -56,6 +59,7 @@ def _read_multi_dimensional_coordinate(name, wio_data, coords):
56
59
  name, wio_data, coords
57
60
  ) or _read_dimensional_coordinate(name, wio_data, coords)
58
61
 
62
+
59
63
  def _read_nondimensional_data(name, wio_data, fields, dims):
60
64
  """read nondimensional data
61
65
  :group: input.windio
@@ -67,6 +71,7 @@ def _read_nondimensional_data(name, wio_data, fields, dims):
67
71
  return True
68
72
  return False
69
73
 
74
+
70
75
  def _read_dimensional_data(name, wio_data, fields, dims):
71
76
  """read dimensional data
72
77
  :group: input.windio
@@ -83,6 +88,7 @@ def _read_dimensional_data(name, wio_data, fields, dims):
83
88
  return True
84
89
  return False
85
90
 
91
+
86
92
  def _read_multi_dimensional_data(name, wio_data, fields, dims):
87
93
  """Read multi dimensional data
88
94
  :group: input.windio
@@ -91,14 +97,15 @@ def _read_multi_dimensional_data(name, wio_data, fields, dims):
91
97
  name, wio_data, fields, dims
92
98
  ) or _read_dimensional_data(name, wio_data, fields, dims)
93
99
 
100
+
94
101
  def read_wind_resource_field(
95
- name,
96
- wio_data,
97
- coords,
98
- fields,
99
- dims,
102
+ name,
103
+ wio_data,
104
+ coords,
105
+ fields,
106
+ dims,
100
107
  verbosity,
101
- ):
108
+ ):
102
109
  """
103
110
  Reads wind resource data into fields and dims
104
111
 
@@ -5,28 +5,39 @@ from foxes.utils import Dict
5
5
  import foxes.variables as FV
6
6
  import foxes.constants as FC
7
7
 
8
+ from .read_fields import foxes2wio
9
+
10
+
8
11
  def _read_turbine_outputs(wio_outs, odir, out_dicts, verbosity):
9
- """ Reads the turbine outputs request """
10
- if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get("report", True):
12
+ """Reads the turbine outputs request"""
13
+ if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get(
14
+ "report", True
15
+ ):
11
16
  turbine_outputs = Dict(wio_outs["turbine_outputs"], name="turbine_outputs")
12
- turbine_nc_filename = turbine_outputs.pop("turbine_nc_filename", "turbine_outputs.nc")
17
+ turbine_nc_filename = turbine_outputs.pop(
18
+ "turbine_nc_filename", "turbine_outputs.nc"
19
+ )
13
20
  output_variables = turbine_outputs["output_variables"]
14
21
  if verbosity > 2:
15
22
  print(" Reading turbine_outputs")
16
23
  print(" File name:", turbine_nc_filename)
17
24
  print(" output_variables:", output_variables)
18
-
25
+
19
26
  vmap = Dict(
20
27
  power=FV.P,
21
28
  rotor_effective_velocity=FV.REWS,
22
29
  )
23
30
  ivmap = {d: k for k, d in vmap.items()}
24
- ivmap.update({
25
- FC.STATE: "time",
26
- FC.TURBINE: "turbine",
27
- })
28
-
29
- out_dicts.append(Dict({
31
+ ivmap.update(
32
+ {
33
+ FC.STATE: "time",
34
+ FC.TURBINE: "turbine",
35
+ }
36
+ )
37
+
38
+ out_dicts.append(
39
+ Dict(
40
+ {
30
41
  "output_type": "StateTurbineTable",
31
42
  "farm_results": True,
32
43
  "algo": False,
@@ -34,16 +45,23 @@ def _read_turbine_outputs(wio_outs, odir, out_dicts, verbosity):
34
45
  "run_kwargs": dict(
35
46
  variables=[vmap[v] for v in output_variables],
36
47
  name_map=ivmap,
37
- to_file=odir/turbine_nc_filename,
48
+ to_file=odir / turbine_nc_filename,
49
+ round={
50
+ vw: FV.get_default_digits(vf) for vw, vf in vmap.items()
51
+ },
38
52
  verbosity=verbosity,
39
53
  ),
40
54
  "output_yaml_update": {
41
55
  "power_table": f"include {turbine_nc_filename}",
42
56
  },
43
- }, name = "turbine_outputs"))
57
+ },
58
+ name="turbine_outputs",
59
+ )
60
+ )
61
+
44
62
 
45
63
  def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
46
- """ Reads the flow field request """
64
+ """Reads the flow field request"""
47
65
  if "flow_field" in wio_outs and wio_outs["flow_field"].get("report", True):
48
66
  flow_field = Dict(wio_outs["flow_field"], name="flow_field")
49
67
  flow_nc_filename = flow_field.pop("flow_nc_filename", "flow_field.nc")
@@ -51,10 +69,15 @@ def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
51
69
  z_planes = Dict(flow_field.pop("z_planes"), name="z_planes")
52
70
  z_sampling = z_planes["z_sampling"]
53
71
  xy_sampling = z_planes["xy_sampling"]
72
+ cases_run = Dict(flow_field.pop("cases_run", {}), name="cases_run")
73
+ states_isel = cases_run.get("subset", None)
74
+ if "all_occurences" in cases_run and cases_run.pop("all_occurences"):
75
+ states_isel = None
54
76
  if verbosity > 2:
55
77
  print(" Reading flow_field")
56
78
  print(" File name :", flow_nc_filename)
57
79
  print(" output_variables:", output_variables)
80
+ print(" states subset :", states_isel)
58
81
  print(" z_sampling :", z_sampling)
59
82
  print(" xy_sampling :", xy_sampling)
60
83
 
@@ -62,29 +85,47 @@ def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
62
85
  wind_speed=FV.WS,
63
86
  wind_direction=FV.WD,
64
87
  )
65
-
88
+
89
+ if z_sampling in ["hub_height", "default"]:
90
+ z = None
91
+ elif isinstance(z_sampling, (int, float)):
92
+ z = z_sampling
93
+ else:
94
+ raise NotImplementedError(
95
+ f"z_sampling '{z_sampling}' of type '{type(z_sampling).__name__}' is not supported (yet). Please give 'hub_height', 'default' or a float."
96
+ )
97
+
66
98
  if xy_sampling == "default":
67
- out_dicts.append(Dict({
99
+ out_dicts.append(
100
+ Dict(
101
+ {
68
102
  "output_type": "SliceData",
69
103
  "farm_results": True,
70
104
  "algo": True,
71
105
  "verbosity_delta": 3,
72
106
  "run_func": "get_states_data_xy",
73
107
  "run_kwargs": dict(
74
- resolution=30.,
108
+ states_isel=states_isel,
109
+ n_img_points=(100, 100),
75
110
  variables=[vmap[v] for v in output_variables],
76
- z=None if z_sampling == "hub_height" else z_sampling,
77
- to_file=odir/flow_nc_filename,
111
+ z=z,
112
+ to_file=odir / flow_nc_filename,
113
+ label_map=foxes2wio,
78
114
  verbosity=verbosity,
79
115
  ),
80
116
  "output_yaml_update": {
81
117
  "flow_field": f"include {flow_nc_filename}",
82
118
  },
83
- }, name = "flow_field"))
119
+ },
120
+ name="flow_field",
121
+ )
122
+ )
84
123
  else:
85
- raise NotImplementedError(f"xy_sampling '{xy_sampling}' is not supported (yet)")
86
-
87
-
124
+ raise NotImplementedError(
125
+ f"xy_sampling '{xy_sampling}' is not supported (yet)"
126
+ )
127
+
128
+
88
129
  def read_outputs(wio_outs, algo_dict, verbosity):
89
130
  """
90
131
  Reads the windio outputs
@@ -5,7 +5,7 @@ from foxes.output import Output
5
5
 
6
6
 
7
7
  def _write_yaml(data, fpath):
8
- """ Write the data to yaml """
8
+ """Write the data to yaml"""
9
9
  rmap = {
10
10
  "include": "!include",
11
11
  }
@@ -13,11 +13,12 @@ def _write_yaml(data, fpath):
13
13
  yaml.dump(data, file)
14
14
  with open(fpath, "r") as f:
15
15
  s = f.read()
16
- with open(fpath, 'w') as f:
16
+ with open(fpath, "w") as f:
17
17
  for k1, k2 in rmap.items():
18
18
  s = s.replace(k1, k2)
19
19
  f.write(s)
20
-
20
+
21
+
21
22
  class WindioRunner:
22
23
  """
23
24
  Runner for windio input
@@ -40,6 +41,10 @@ class WindioRunner:
40
41
  Name of the written input data file
41
42
  file_name_output_yaml: str
42
43
  Name of the written output data file
44
+ write_input_yaml: bool
45
+ Flag for writing file_name_input_yaml
46
+ write_output_yaml: bool
47
+ Flag for writing file_name_output_yaml
43
48
  verbosity: int
44
49
  The verbosity level, 0 = silent
45
50
 
@@ -48,15 +53,17 @@ class WindioRunner:
48
53
  """
49
54
 
50
55
  def __init__(
51
- self,
52
- algo_dict,
56
+ self,
57
+ algo_dict,
53
58
  output_dir=".",
54
- output_dicts=[],
55
- wio_input_data=None,
59
+ output_dicts=[],
60
+ wio_input_data=None,
56
61
  file_name_input_yaml="recorded_input.yaml",
57
62
  file_name_output_yaml="recorded_output.yaml",
63
+ write_input_yaml=False,
64
+ write_output_yaml=False,
58
65
  verbosity=1,
59
- ):
66
+ ):
60
67
  """
61
68
  Conbstructor
62
69
 
@@ -74,6 +81,10 @@ class WindioRunner:
74
81
  Name of the written input data file
75
82
  file_name_output_yaml: str
76
83
  Name of the written output data file
84
+ write_input_yaml: bool
85
+ Flag for writing file_name_input_yaml
86
+ write_output_yaml: bool
87
+ Flag for writing file_name_output_yaml
77
88
  verbosity: int
78
89
  The verbosity level, 0 = silent
79
90
 
@@ -84,15 +95,17 @@ class WindioRunner:
84
95
  self.wio_input_data = wio_input_data
85
96
  self.file_name_input_yaml = file_name_input_yaml
86
97
  self.file_name_output_yaml = file_name_output_yaml
98
+ self.write_input_yaml = write_input_yaml
99
+ self.write_output_yaml = write_output_yaml
87
100
  self.verbosity = verbosity
88
101
  self.farm_results = None
89
102
  self.output_results = None
90
103
 
91
104
  self.__initialized = False
92
-
105
+
93
106
  self._output_yaml = {}
94
- if wio_input_data is not None and len(wio_input_data):
95
- fpath = output_dir/file_name_input_yaml
107
+ if self.write_input_yaml and len(wio_input_data):
108
+ fpath = output_dir / file_name_input_yaml
96
109
  self.print(f"Writing file", fpath)
97
110
  _write_yaml(wio_input_data, fpath)
98
111
  self._output_yaml["wind_energy_system"] = f"include {file_name_input_yaml}"
@@ -131,7 +144,7 @@ class WindioRunner:
131
144
  run_fname = odict.pop("run_func")
132
145
  run_args = odict.pop("run_args", ())
133
146
  run_kwargs = odict.pop("run_kwargs", {})
134
-
147
+
135
148
  _odict = odict.copy()
136
149
  if "output_yaml_update" in _odict:
137
150
  self._output_yaml.update(_odict.pop("output_yaml_update"))
@@ -142,11 +155,12 @@ class WindioRunner:
142
155
  o = Output.new(**_odict)
143
156
  f = getattr(o, run_fname)
144
157
  self.output_results.append(f(*run_args, **run_kwargs))
145
-
146
- fpath = self.output_dir/self.file_name_output_yaml
147
- self.print(f"Writing file", fpath)
148
- _write_yaml(self._output_yaml, fpath)
149
-
158
+
159
+ if self.write_output_yaml:
160
+ fpath = self.output_dir / self.file_name_output_yaml
161
+ self.print(f"Writing file", fpath)
162
+ _write_yaml(self._output_yaml, fpath)
163
+
150
164
  def run(self):
151
165
  """Runs all calculations"""
152
166
  self.run_farm_calc()