foxes 0.8.2__py3-none-any.whl → 1.1.0.2__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 (215) 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/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 +190 -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 +247 -111
  27. foxes/algorithms/downwind/models/farm_wakes_calc.py +12 -7
  28. foxes/algorithms/downwind/models/init_farm_data.py +2 -2
  29. foxes/algorithms/downwind/models/point_wakes_calc.py +6 -7
  30. foxes/algorithms/downwind/models/reorder_farm_output.py +1 -2
  31. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  32. foxes/algorithms/downwind/models/set_amb_point_results.py +5 -3
  33. foxes/algorithms/iterative/iterative.py +74 -34
  34. foxes/algorithms/iterative/models/farm_wakes_calc.py +12 -7
  35. foxes/algorithms/iterative/models/urelax.py +3 -3
  36. foxes/algorithms/sequential/models/plugin.py +5 -5
  37. foxes/algorithms/sequential/models/seq_state.py +1 -1
  38. foxes/algorithms/sequential/sequential.py +126 -255
  39. foxes/constants.py +22 -7
  40. foxes/core/__init__.py +1 -0
  41. foxes/core/algorithm.py +632 -147
  42. foxes/core/data.py +252 -20
  43. foxes/core/data_calc_model.py +15 -291
  44. foxes/core/engine.py +640 -0
  45. foxes/core/farm_controller.py +38 -10
  46. foxes/core/farm_data_model.py +16 -1
  47. foxes/core/ground_model.py +2 -2
  48. foxes/core/model.py +249 -182
  49. foxes/core/partial_wakes_model.py +1 -1
  50. foxes/core/point_data_model.py +17 -2
  51. foxes/core/rotor_model.py +27 -21
  52. foxes/core/states.py +17 -1
  53. foxes/core/turbine_type.py +28 -0
  54. foxes/core/wake_frame.py +30 -34
  55. foxes/core/wake_model.py +5 -5
  56. foxes/core/wake_superposition.py +1 -1
  57. foxes/data/windio/windio_5turbines_timeseries.yaml +31 -15
  58. foxes/engines/__init__.py +17 -0
  59. foxes/engines/dask.py +982 -0
  60. foxes/engines/default.py +75 -0
  61. foxes/engines/futures.py +72 -0
  62. foxes/engines/mpi.py +38 -0
  63. foxes/engines/multiprocess.py +71 -0
  64. foxes/engines/numpy.py +167 -0
  65. foxes/engines/pool.py +249 -0
  66. foxes/engines/ray.py +79 -0
  67. foxes/engines/single.py +141 -0
  68. foxes/input/farm_layout/__init__.py +1 -0
  69. foxes/input/farm_layout/from_csv.py +4 -0
  70. foxes/input/farm_layout/from_json.py +2 -2
  71. foxes/input/farm_layout/grid.py +2 -2
  72. foxes/input/farm_layout/ring.py +65 -0
  73. foxes/input/farm_layout/row.py +2 -2
  74. foxes/input/states/__init__.py +7 -0
  75. foxes/input/states/create/random_abl_states.py +1 -1
  76. foxes/input/states/field_data_nc.py +158 -33
  77. foxes/input/states/multi_height.py +128 -14
  78. foxes/input/states/one_point_flow.py +577 -0
  79. foxes/input/states/scan_ws.py +74 -3
  80. foxes/input/states/single.py +1 -1
  81. foxes/input/states/slice_data_nc.py +681 -0
  82. foxes/input/states/states_table.py +204 -35
  83. foxes/input/windio/__init__.py +2 -2
  84. foxes/input/windio/get_states.py +44 -23
  85. foxes/input/windio/read_attributes.py +48 -17
  86. foxes/input/windio/read_farm.py +116 -102
  87. foxes/input/windio/read_fields.py +16 -6
  88. foxes/input/windio/read_outputs.py +71 -24
  89. foxes/input/windio/runner.py +31 -17
  90. foxes/input/windio/windio.py +41 -23
  91. foxes/models/farm_models/turbine2farm.py +1 -1
  92. foxes/models/ground_models/wake_mirror.py +10 -6
  93. foxes/models/model_book.py +58 -20
  94. foxes/models/partial_wakes/axiwake.py +3 -3
  95. foxes/models/partial_wakes/rotor_points.py +3 -3
  96. foxes/models/partial_wakes/top_hat.py +2 -2
  97. foxes/models/point_models/set_uniform_data.py +1 -1
  98. foxes/models/point_models/tke2ti.py +1 -1
  99. foxes/models/point_models/wake_deltas.py +1 -1
  100. foxes/models/rotor_models/centre.py +4 -0
  101. foxes/models/rotor_models/grid.py +24 -25
  102. foxes/models/rotor_models/levels.py +4 -5
  103. foxes/models/turbine_models/calculator.py +4 -6
  104. foxes/models/turbine_models/kTI_model.py +22 -6
  105. foxes/models/turbine_models/lookup_table.py +30 -4
  106. foxes/models/turbine_models/rotor_centre_calc.py +4 -3
  107. foxes/models/turbine_models/set_farm_vars.py +103 -34
  108. foxes/models/turbine_types/PCt_file.py +27 -3
  109. foxes/models/turbine_types/PCt_from_two.py +27 -3
  110. foxes/models/turbine_types/TBL_file.py +80 -0
  111. foxes/models/turbine_types/__init__.py +2 -0
  112. foxes/models/turbine_types/lookup.py +316 -0
  113. foxes/models/turbine_types/null_type.py +51 -1
  114. foxes/models/turbine_types/wsrho2PCt_from_two.py +29 -5
  115. foxes/models/turbine_types/wsti2PCt_from_two.py +31 -7
  116. foxes/models/vertical_profiles/__init__.py +1 -1
  117. foxes/models/vertical_profiles/data_profile.py +1 -1
  118. foxes/models/wake_frames/__init__.py +1 -0
  119. foxes/models/wake_frames/dynamic_wakes.py +424 -0
  120. foxes/models/wake_frames/farm_order.py +25 -5
  121. foxes/models/wake_frames/rotor_wd.py +6 -4
  122. foxes/models/wake_frames/seq_dynamic_wakes.py +61 -74
  123. foxes/models/wake_frames/streamlines.py +21 -22
  124. foxes/models/wake_frames/timelines.py +330 -129
  125. foxes/models/wake_frames/yawed_wakes.py +7 -4
  126. foxes/models/wake_models/dist_sliced.py +2 -4
  127. foxes/models/wake_models/induction/rankine_half_body.py +5 -5
  128. foxes/models/wake_models/induction/rathmann.py +78 -24
  129. foxes/models/wake_models/induction/self_similar.py +78 -28
  130. foxes/models/wake_models/induction/vortex_sheet.py +86 -48
  131. foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
  132. foxes/models/wake_models/ti/iec_ti.py +40 -21
  133. foxes/models/wake_models/top_hat.py +1 -1
  134. foxes/models/wake_models/wind/bastankhah14.py +8 -6
  135. foxes/models/wake_models/wind/bastankhah16.py +17 -16
  136. foxes/models/wake_models/wind/jensen.py +4 -3
  137. foxes/models/wake_models/wind/turbopark.py +16 -13
  138. foxes/models/wake_superpositions/ti_linear.py +1 -1
  139. foxes/models/wake_superpositions/ti_max.py +1 -1
  140. foxes/models/wake_superpositions/ti_pow.py +1 -1
  141. foxes/models/wake_superpositions/ti_quadratic.py +1 -1
  142. foxes/models/wake_superpositions/ws_linear.py +8 -7
  143. foxes/models/wake_superpositions/ws_max.py +8 -7
  144. foxes/models/wake_superpositions/ws_pow.py +8 -7
  145. foxes/models/wake_superpositions/ws_product.py +5 -5
  146. foxes/models/wake_superpositions/ws_quadratic.py +8 -7
  147. foxes/output/__init__.py +4 -1
  148. foxes/output/farm_layout.py +16 -12
  149. foxes/output/farm_results_eval.py +1 -1
  150. foxes/output/flow_plots_2d/__init__.py +0 -1
  151. foxes/output/flow_plots_2d/flow_plots.py +70 -30
  152. foxes/output/grids.py +92 -22
  153. foxes/output/results_writer.py +2 -2
  154. foxes/output/rose_plot.py +3 -3
  155. foxes/output/seq_plugins/__init__.py +2 -0
  156. foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +64 -22
  157. foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
  158. foxes/output/slice_data.py +131 -111
  159. foxes/output/state_turbine_map.py +19 -14
  160. foxes/output/state_turbine_table.py +19 -19
  161. foxes/utils/__init__.py +1 -1
  162. foxes/utils/abl/neutral.py +2 -2
  163. foxes/utils/abl/stable.py +2 -2
  164. foxes/utils/abl/unstable.py +2 -2
  165. foxes/utils/data_book.py +1 -1
  166. foxes/utils/dev_utils.py +42 -0
  167. foxes/utils/dict.py +24 -1
  168. foxes/utils/exec_python.py +1 -1
  169. foxes/utils/factory.py +176 -53
  170. foxes/utils/geom2d/circle.py +1 -1
  171. foxes/utils/geom2d/polygon.py +1 -1
  172. foxes/utils/geopandas_utils.py +2 -2
  173. foxes/utils/load.py +2 -2
  174. foxes/utils/pandas_helpers.py +3 -2
  175. foxes/utils/wind_dir.py +0 -2
  176. foxes/utils/xarray_utils.py +24 -14
  177. foxes/variables.py +39 -2
  178. {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/METADATA +75 -33
  179. foxes-1.1.0.2.dist-info/RECORD +309 -0
  180. {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/WHEEL +1 -1
  181. foxes-1.1.0.2.dist-info/top_level.txt +4 -0
  182. tests/0_consistency/iterative/test_iterative.py +92 -0
  183. tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
  184. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
  185. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
  186. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
  187. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
  188. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
  189. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
  190. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
  191. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
  192. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
  193. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
  194. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
  195. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
  196. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
  197. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
  198. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
  199. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
  200. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
  201. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
  202. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
  203. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
  204. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
  205. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
  206. tests/3_examples/test_examples.py +34 -0
  207. foxes/VERSION +0 -1
  208. foxes/output/flow_plots_2d.py +0 -0
  209. foxes/utils/geopandas_helpers.py +0 -294
  210. foxes/utils/runners/__init__.py +0 -1
  211. foxes/utils/runners/runners.py +0 -280
  212. foxes-0.8.2.dist-info/RECORD +0 -247
  213. foxes-0.8.2.dist-info/top_level.txt +0 -1
  214. foxes-0.8.2.dist-info/zip-safe +0 -1
  215. {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/LICENSE +0 -0
@@ -0,0 +1,193 @@
1
+ import numpy as np
2
+ import time
3
+ import argparse
4
+ import matplotlib.pyplot as plt
5
+
6
+ import foxes
7
+ import foxes.variables as FV
8
+
9
+ if __name__ == "__main__":
10
+ parser = argparse.ArgumentParser()
11
+ parser.add_argument("-n_s", help="The number of states", type=int, default=30)
12
+ parser.add_argument("-n_t", help="The number of turbines", type=int, default=5)
13
+ parser.add_argument("--n_p", help="The number of turbines", type=int, default=2000)
14
+ parser.add_argument("--ws0", help="The lowest wind speed", type=float, default=3.0)
15
+ parser.add_argument(
16
+ "--ws1", help="The highest wind speed", type=float, default=30.0
17
+ )
18
+ parser.add_argument(
19
+ "-t",
20
+ "--turbine_file",
21
+ help="The P-ct-curve csv file (path or static)",
22
+ default="NREL-5MW-D126-H90.csv",
23
+ )
24
+ parser.add_argument(
25
+ "-w",
26
+ "--wakes",
27
+ help="The wake models",
28
+ default=["Bastankhah2014_linear"],
29
+ nargs="+",
30
+ )
31
+ parser.add_argument(
32
+ "-m", "--tmodels", help="The turbine models", default=["kTI_04"], nargs="+"
33
+ )
34
+ parser.add_argument("-r", "--rotor", help="The rotor model", default="centre")
35
+ parser.add_argument(
36
+ "-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
37
+ )
38
+ parser.add_argument(
39
+ "-cl", "--calc_cline", help="Calculate centreline", action="store_true"
40
+ )
41
+ parser.add_argument(
42
+ "-cm", "--calc_mean", help="Calculate states mean", action="store_true"
43
+ )
44
+ parser.add_argument("-e", "--engine", help="The engine", default="process")
45
+ parser.add_argument(
46
+ "-n", "--n_cpus", help="The number of cpus", default=None, type=int
47
+ )
48
+ parser.add_argument(
49
+ "-c",
50
+ "--chunksize_states",
51
+ help="The chunk size for states",
52
+ default=None,
53
+ type=int,
54
+ )
55
+ parser.add_argument(
56
+ "-C",
57
+ "--chunksize_points",
58
+ help="The chunk size for points",
59
+ default=None,
60
+ type=int,
61
+ )
62
+ parser.add_argument(
63
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
64
+ )
65
+ args = parser.parse_args()
66
+
67
+ n_s = args.n_s
68
+ n_t = args.n_t
69
+ n_p = args.n_p
70
+ p0 = np.array([0.0, 0.0])
71
+ stp = np.array([500.0, 0.0])
72
+
73
+ mbook = foxes.models.ModelBook()
74
+ ttype = foxes.models.turbine_types.PCtFile(args.turbine_file)
75
+ mbook.turbine_types[ttype.name] = ttype
76
+ D = ttype.D
77
+ H = ttype.H
78
+
79
+ states = foxes.input.states.ScanWS(
80
+ ws_list=np.linspace(args.ws0, args.ws1, n_s), wd=270.0, ti=0.08, rho=1.225
81
+ )
82
+
83
+ farm = foxes.WindFarm()
84
+ foxes.input.farm_layout.add_row(
85
+ farm=farm,
86
+ xy_base=p0,
87
+ xy_step=stp,
88
+ n_turbines=n_t,
89
+ turbine_models=args.tmodels + [ttype.name],
90
+ )
91
+
92
+ algo = foxes.algorithms.Downwind(
93
+ farm,
94
+ states,
95
+ rotor_model=args.rotor,
96
+ wake_models=args.wakes,
97
+ wake_frame="rotor_wd",
98
+ partial_wakes=args.pwakes,
99
+ mbook=mbook,
100
+ engine=args.engine,
101
+ n_procs=args.n_cpus,
102
+ chunk_size_states=args.chunksize_states,
103
+ chunk_size_points=args.chunksize_points,
104
+ )
105
+
106
+ time0 = time.time()
107
+ farm_results = algo.calc_farm()
108
+ time1 = time.time()
109
+
110
+ print("\nCalc time =", time1 - time0, "\n")
111
+
112
+ print("\nFarm results:\n", farm_results)
113
+
114
+ o = foxes.output.FarmResultsEval(farm_results)
115
+ o.add_capacity(algo)
116
+ o.add_capacity(algo, ambient=True)
117
+ o.add_efficiency()
118
+
119
+ # state-turbine results
120
+ farm_df = farm_results.to_dataframe()
121
+ print("\nFarm results data:\n")
122
+ print(
123
+ farm_df[
124
+ [
125
+ FV.X,
126
+ FV.WD,
127
+ FV.AMB_REWS,
128
+ FV.REWS,
129
+ FV.AMB_TI,
130
+ FV.TI,
131
+ FV.AMB_P,
132
+ FV.P,
133
+ FV.EFF,
134
+ ]
135
+ ]
136
+ )
137
+ print()
138
+
139
+ # results by turbine
140
+ turbine_results = o.reduce_states(
141
+ {
142
+ FV.AMB_P: "mean",
143
+ FV.P: "mean",
144
+ FV.AMB_CAP: "mean",
145
+ FV.CAP: "mean",
146
+ FV.EFF: "mean",
147
+ }
148
+ )
149
+ turbine_results[FV.AMB_YLD] = o.calc_turbine_yield(
150
+ algo=algo, annual=True, ambient=True
151
+ )
152
+ turbine_results[FV.YLD] = o.calc_turbine_yield(algo=algo, annual=True)
153
+ print("\nResults by turbine:\n")
154
+ print(turbine_results)
155
+
156
+ # power results
157
+ P0 = o.calc_mean_farm_power(ambient=True)
158
+ P = o.calc_mean_farm_power()
159
+ print(f"\nFarm power : {P/1000:.1f} MW")
160
+ print(f"Farm ambient power: {P0/1000:.1f} MW")
161
+ print(f"Farm efficiency : {o.calc_farm_efficiency()*100:.2f} %")
162
+ print(f"Annual farm yield : {turbine_results[FV.YLD].sum():.2f} GWh.")
163
+ print()
164
+
165
+ if not args.nofig and args.calc_cline:
166
+ points = np.zeros((n_s, n_p, 3))
167
+ points[:, :, 0] = np.linspace(p0[0], p0[0] + n_t * stp[0] + 10 * D, n_p)[
168
+ None, :
169
+ ]
170
+ points[:, :, 1] = p0[1]
171
+ points[:, :, 2] = H
172
+ print("\nPOINTS:\n", points[0])
173
+
174
+ time0 = time.time()
175
+ point_results = algo.calc_points(farm_results, points)
176
+ time1 = time.time()
177
+ print("\nCalc time =", time1 - time0, "\n")
178
+
179
+ print(point_results)
180
+
181
+ fig, ax = plt.subplots()
182
+ for s in range(points.shape[0]):
183
+ ax.plot(points[s, :, 0], point_results[FV.WS][s, :])
184
+ ax.set_xlabel("x [m]")
185
+ ax.set_ylabel("Wind speed [m/s]")
186
+ ax.set_title("Centreline wind speed")
187
+ plt.show()
188
+ plt.close(fig)
189
+
190
+ if not args.nofig and args.calc_mean:
191
+ o = foxes.output.FlowPlots2D(algo, farm_results)
192
+ fig = o.get_mean_fig_xy(FV.WS, resolution=10)
193
+ plt.show()
@@ -0,0 +1,162 @@
1
+ import time
2
+ import argparse
3
+ import matplotlib.pyplot as plt
4
+
5
+ import foxes
6
+ import foxes.variables as FV
7
+
8
+ if __name__ == "__main__":
9
+ parser = argparse.ArgumentParser()
10
+ parser.add_argument(
11
+ "-l",
12
+ "--layout",
13
+ help="The wind farm layout file (path or static)",
14
+ default="test_farm_67.csv",
15
+ )
16
+ parser.add_argument(
17
+ "-s",
18
+ "--states",
19
+ help="The states input file (path or static)",
20
+ default="wind_rose_bremen.csv",
21
+ )
22
+ parser.add_argument(
23
+ "-t",
24
+ "--turbine_file",
25
+ help="The P-ct-curve csv file (path or static)",
26
+ default="NREL-5MW-D126-H90.csv",
27
+ )
28
+ parser.add_argument(
29
+ "-sm",
30
+ "--sector_file",
31
+ help="The sector management file",
32
+ default="sector_rules.csv",
33
+ )
34
+ parser.add_argument("-r", "--rotor", help="The rotor model", default="centre")
35
+ parser.add_argument(
36
+ "-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
37
+ )
38
+ parser.add_argument(
39
+ "-w",
40
+ "--wakes",
41
+ help="The wake models",
42
+ default=["Bastankhah2014_linear_k002"],
43
+ nargs="+",
44
+ )
45
+ parser.add_argument(
46
+ "-m", "--tmodels", help="The turbine models", default=[], nargs="+"
47
+ )
48
+ parser.add_argument("-e", "--engine", help="The engine", default="process")
49
+ parser.add_argument(
50
+ "-n", "--n_cpus", help="The number of cpus", default=None, type=int
51
+ )
52
+ parser.add_argument(
53
+ "-c",
54
+ "--chunksize_states",
55
+ help="The chunk size for states",
56
+ default=None,
57
+ type=int,
58
+ )
59
+ parser.add_argument(
60
+ "-C",
61
+ "--chunksize_points",
62
+ help="The chunk size for points",
63
+ default=None,
64
+ type=int,
65
+ )
66
+ parser.add_argument(
67
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
68
+ )
69
+ args = parser.parse_args()
70
+
71
+ mbook = foxes.models.ModelBook()
72
+ ttype = foxes.models.turbine_types.PCtFile(args.turbine_file)
73
+ mbook.turbine_types[ttype.name] = ttype
74
+
75
+ mbook.turbine_models["sector_rules"] = foxes.models.turbine_models.SectorManagement(
76
+ data_source=args.sector_file,
77
+ col_tnames="tname",
78
+ range_vars=[FV.WD, FV.REWS],
79
+ target_vars=[FV.MAX_P],
80
+ colmap={"REWS_min": "WS_min", "REWS_max": "WS_max"},
81
+ )
82
+
83
+ states = foxes.input.states.StatesTable(
84
+ data_source=args.states,
85
+ output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
86
+ var2col={FV.WS: "ws", FV.WD: "wd", FV.WEIGHT: "weight"},
87
+ fixed_vars={FV.RHO: 1.225, FV.TI: 0.05},
88
+ )
89
+
90
+ farm = foxes.WindFarm()
91
+ foxes.input.farm_layout.add_row(
92
+ farm=farm,
93
+ xy_base=[0.0, 0.0],
94
+ xy_step=[600.0, 0.0],
95
+ n_turbines=2,
96
+ turbine_models=args.tmodels + [ttype.name, "sector_rules", "PMask"],
97
+ )
98
+
99
+ algo = foxes.algorithms.Downwind(
100
+ farm,
101
+ states,
102
+ rotor_model=args.rotor,
103
+ wake_models=args.wakes,
104
+ wake_frame="rotor_wd",
105
+ partial_wakes=args.pwakes,
106
+ mbook=mbook,
107
+ engine=args.engine,
108
+ n_procs=args.n_cpus,
109
+ chunk_size_states=args.chunksize_states,
110
+ chunk_size_points=args.chunksize_points,
111
+ )
112
+
113
+ outputs = [
114
+ FV.D,
115
+ FV.WD,
116
+ FV.AMB_WD,
117
+ FV.H,
118
+ FV.AMB_REWS,
119
+ FV.REWS,
120
+ FV.AMB_P,
121
+ FV.MAX_P,
122
+ FV.P,
123
+ FV.CT,
124
+ FV.WEIGHT,
125
+ ]
126
+
127
+ time0 = time.time()
128
+ farm_results = algo.calc_farm(outputs=outputs)
129
+ time1 = time.time()
130
+
131
+ print("\nCalc time =", time1 - time0, "\n")
132
+
133
+ print(farm_results)
134
+
135
+ fr = farm_results.to_dataframe()
136
+ sel = fr[FV.MAX_P].dropna().index
137
+ fr = fr.loc[sel]
138
+ print(fr)
139
+
140
+ if not args.nofig:
141
+ o = foxes.output.RosePlotOutput(farm_results)
142
+ fig = o.get_figure(
143
+ 16,
144
+ FV.P,
145
+ [100, 1000, 2000, 4000, 5001, 7000],
146
+ turbine=0,
147
+ title="Power turbine 0",
148
+ figsize=(12, 6),
149
+ rect=[0.05, 0.1, 0.4, 0.8],
150
+ )
151
+
152
+ o = foxes.output.RosePlotOutput(farm_results)
153
+ fig = o.get_figure(
154
+ 16,
155
+ FV.P,
156
+ [100, 1000, 2000, 4000, 5001, 7000],
157
+ turbine=1,
158
+ title="Power turbine 1",
159
+ fig=fig,
160
+ rect=[0.35, 0.1, 0.8, 0.8],
161
+ )
162
+ plt.show()
@@ -0,0 +1,209 @@
1
+ import argparse
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
4
+ from pathlib import Path
5
+
6
+ import foxes
7
+ import foxes.variables as FV
8
+
9
+ if __name__ == "__main__":
10
+ parser = argparse.ArgumentParser()
11
+ parser.add_argument(
12
+ "-a", "--animation", help="Write flow animation file", action="store_true"
13
+ )
14
+ parser.add_argument(
15
+ "-A",
16
+ "--ani_file",
17
+ help="Path to the animation file to be written",
18
+ default="ani.gif",
19
+ )
20
+ parser.add_argument(
21
+ "-F",
22
+ "--fps",
23
+ help="The frames per second value for the animation",
24
+ type=int,
25
+ default=4,
26
+ )
27
+ parser.add_argument(
28
+ "-d", "--debug", help="Switch on wake debugging", action="store_true"
29
+ )
30
+ parser.add_argument(
31
+ "-S",
32
+ "--n_states",
33
+ help="The number of states",
34
+ type=int,
35
+ default=50,
36
+ )
37
+ parser.add_argument(
38
+ "-l",
39
+ "--layout",
40
+ help="The wind farm layout file (path or static)",
41
+ default="test_farm_67.csv",
42
+ )
43
+ parser.add_argument(
44
+ "-t",
45
+ "--turbine_file",
46
+ help="The P-ct-curve csv file (path or static)",
47
+ default="NREL-5MW-D126-H90.csv",
48
+ )
49
+ parser.add_argument("-r", "--rotor", help="The rotor model", default="centre")
50
+ parser.add_argument(
51
+ "-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
52
+ )
53
+ parser.add_argument(
54
+ "-w",
55
+ "--wakes",
56
+ help="The wake models",
57
+ default=["Bastankhah2014_linear_lim_k004"],
58
+ nargs="+",
59
+ )
60
+ parser.add_argument(
61
+ "-f", "--frame", help="The wake frame", default="seq_dyn_wakes_1min"
62
+ )
63
+ parser.add_argument(
64
+ "-m", "--tmodels", help="The turbine models", default=[], nargs="+"
65
+ )
66
+ parser.add_argument(
67
+ "-sl",
68
+ "--show_layout",
69
+ help="Flag for showing layout figure",
70
+ action="store_true",
71
+ )
72
+ parser.add_argument(
73
+ "-V",
74
+ "--variable",
75
+ help="Plot variable",
76
+ default=FV.WS,
77
+ )
78
+ parser.add_argument(
79
+ "-VMAX",
80
+ "--max_variable",
81
+ help="Maximal plot variable",
82
+ default=10,
83
+ type=float,
84
+ )
85
+ parser.add_argument("-e", "--engine", help="The engine", default="NumpyEngine")
86
+ parser.add_argument(
87
+ "-n", "--n_cpus", help="The number of cpus", default=None, type=int
88
+ )
89
+ parser.add_argument(
90
+ "-c",
91
+ "--chunksize_states",
92
+ help="The chunk size for states",
93
+ default=None,
94
+ type=int,
95
+ )
96
+ parser.add_argument(
97
+ "-C",
98
+ "--chunksize_points",
99
+ help="The chunk size for points",
100
+ default=None,
101
+ type=int,
102
+ )
103
+ parser.add_argument(
104
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
105
+ )
106
+ args = parser.parse_args()
107
+
108
+ mbook = foxes.models.ModelBook()
109
+ ttype = foxes.models.turbine_types.PCtFile(args.turbine_file)
110
+ mbook.turbine_types[ttype.name] = ttype
111
+
112
+ states = foxes.input.states.Timeseries(
113
+ data_source="timeseries_3000.csv.gz",
114
+ output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
115
+ var2col={FV.WS: "WS", FV.WD: "WD", FV.TI: "TI", FV.RHO: "RHO"},
116
+ states_sel=range(240, 240 + args.n_states),
117
+ )
118
+
119
+ farm = foxes.WindFarm()
120
+ N = 3
121
+ foxes.input.farm_layout.add_grid(
122
+ farm,
123
+ xy_base=np.array([0.0, 0.0]),
124
+ step_vectors=np.array([[1000.0, 0], [0, 800.0]]),
125
+ steps=(N, N),
126
+ turbine_models=args.tmodels + [ttype.name],
127
+ )
128
+
129
+ if not args.nofig and args.show_layout:
130
+ ax = foxes.output.FarmLayoutOutput(farm).get_figure()
131
+ plt.show()
132
+ plt.close(ax.get_figure(figsize=(8, 8)))
133
+
134
+ with foxes.Engine.new(
135
+ engine_type=args.engine,
136
+ n_procs=args.n_cpus,
137
+ chunk_size_states=args.chunksize_states,
138
+ chunk_size_points=args.chunksize_points,
139
+ ):
140
+ algo = foxes.algorithms.Sequential(
141
+ farm,
142
+ states,
143
+ rotor_model=args.rotor,
144
+ wake_models=args.wakes,
145
+ wake_frame=args.frame,
146
+ partial_wakes=args.pwakes,
147
+ mbook=mbook,
148
+ verbosity=0,
149
+ )
150
+
151
+ # in case of animation, add a plugin that creates the images:
152
+ if args.animation:
153
+ anigen = foxes.output.SeqFlowAnimationPlugin(
154
+ orientation="xy",
155
+ var=args.variable,
156
+ resolution=10,
157
+ levels=None,
158
+ quiver_pars=dict(scale=0.01),
159
+ quiver_n=307,
160
+ xmin=-5000,
161
+ ymin=-5000,
162
+ xmax=7000,
163
+ ymax=7000,
164
+ vmin=0,
165
+ vmax=args.max_variable,
166
+ title=None,
167
+ animated=True,
168
+ )
169
+ algo.plugins.append(anigen)
170
+
171
+ if args.debug:
172
+ anigen_debug = foxes.output.SeqWakeDebugPlugin()
173
+ algo.plugins.append(anigen_debug)
174
+
175
+ # run all states sequentially:
176
+ for r in algo:
177
+ print(algo.index)
178
+
179
+ print("\nFarm results:\n")
180
+ print(algo.farm_results)
181
+
182
+ if args.animation:
183
+ print("\nCalculating animation")
184
+
185
+ fig, ax = plt.subplots()
186
+ anim = foxes.output.Animator(fig)
187
+ anim.add_generator(anigen.gen_images(ax))
188
+ if args.debug:
189
+ anim.add_generator(anigen_debug.gen_images(ax))
190
+ ani = anim.animate(interval=600)
191
+
192
+ lo = foxes.output.FarmLayoutOutput(farm)
193
+ lo.get_figure(
194
+ fig=fig,
195
+ ax=ax,
196
+ title="",
197
+ annotate=1,
198
+ anno_delx=-120,
199
+ anno_dely=-60,
200
+ alpha=0,
201
+ s=10,
202
+ )
203
+
204
+ fpath = Path(args.ani_file)
205
+ print("Writing file", fpath)
206
+ if fpath.suffix == ".gif":
207
+ ani.save(filename=fpath, writer="pillow", fps=args.fps)
208
+ else:
209
+ ani.save(filename=fpath, writer="ffmpeg", fps=args.fps)