foxes 0.8.1__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 (175) 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 +25 -13
  137. foxes/variables.py +37 -0
  138. {foxes-0.8.1.dist-info → foxes-1.0.dist-info}/METADATA +72 -34
  139. foxes-1.0.dist-info/RECORD +307 -0
  140. {foxes-0.8.1.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/plotly_helpers.py +0 -19
  170. foxes/utils/runners/__init__.py +0 -1
  171. foxes/utils/runners/runners.py +0 -280
  172. foxes-0.8.1.dist-info/RECORD +0 -248
  173. foxes-0.8.1.dist-info/top_level.txt +0 -1
  174. foxes-0.8.1.dist-info/zip-safe +0 -1
  175. {foxes-0.8.1.dist-info → foxes-1.0.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)