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,113 @@
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 timeseries input file (path or static)",
20
+ default="WRF-Timeseries-3000.nc",
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("-r", "--rotor", help="The rotor model", default="level10")
29
+ parser.add_argument(
30
+ "-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
31
+ )
32
+ parser.add_argument(
33
+ "-w",
34
+ "--wakes",
35
+ help="The wake models",
36
+ default=["Jensen_linear_k007"],
37
+ nargs="+",
38
+ )
39
+ parser.add_argument(
40
+ "-m", "--tmodels", help="The turbine models", default=[], nargs="+"
41
+ )
42
+ parser.add_argument(
43
+ "-sl",
44
+ "--show_layout",
45
+ help="Flag for showing layout figure",
46
+ action="store_true",
47
+ )
48
+ parser.add_argument("-e", "--engine", help="The engine", default=None)
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
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
61
+ )
62
+ args = parser.parse_args()
63
+
64
+ mbook = foxes.models.ModelBook()
65
+ ttype = foxes.models.turbine_types.PCtFile(args.turbine_file)
66
+ mbook.turbine_types[ttype.name] = ttype
67
+
68
+ states = foxes.input.states.MultiHeightNCTimeseries(
69
+ data_source=args.states,
70
+ time_coord="Time",
71
+ h_coord="height",
72
+ output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
73
+ var2col={FV.WS: "ws", FV.WD: "wd", FV.TI: "ti", FV.RHO: "rho"},
74
+ )
75
+
76
+ farm = foxes.WindFarm()
77
+ foxes.input.farm_layout.add_from_file(
78
+ farm, args.layout, turbine_models=args.tmodels + [ttype.name], H=170.0
79
+ )
80
+
81
+ if not args.nofig and args.show_layout:
82
+ ax = foxes.output.FarmLayoutOutput(farm).get_figure()
83
+ plt.show()
84
+ plt.close(ax.get_figure())
85
+
86
+ algo = foxes.algorithms.Downwind(
87
+ farm,
88
+ states,
89
+ rotor_model=args.rotor,
90
+ wake_models=args.wakes,
91
+ wake_frame="rotor_wd",
92
+ partial_wakes=args.pwakes,
93
+ mbook=mbook,
94
+ engine=args.engine,
95
+ n_procs=args.n_cpus,
96
+ chunk_size_states=args.chunksize_states,
97
+ )
98
+
99
+ time0 = time.time()
100
+ farm_results = algo.calc_farm()
101
+ time1 = time.time()
102
+
103
+ print("\nCalc time =", time1 - time0, "\n")
104
+
105
+ print(farm_results, "\n")
106
+
107
+ fr = farm_results.to_dataframe()
108
+ print(fr[[FV.WD, FV.AMB_REWS, FV.REWS, FV.AMB_P, FV.P]])
109
+
110
+ o = foxes.output.FarmResultsEval(farm_results)
111
+ P0 = o.calc_mean_farm_power(ambient=True)
112
+ P = o.calc_mean_farm_power()
113
+ print(f"\nFarm power: {P/1000:.1f} MW, Efficiency = {P/P0*100:.2f} %")
@@ -0,0 +1,249 @@
1
+ import argparse
2
+ import numpy as np
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+
6
+ import foxes
7
+ import foxes.variables as FV
8
+
9
+
10
+ if __name__ == "__main__":
11
+ parser = argparse.ArgumentParser()
12
+ parser.add_argument(
13
+ "-nt", "--n_t", help="The number of turbines", type=int, default=5
14
+ )
15
+ parser.add_argument(
16
+ "-s",
17
+ "--states",
18
+ help="The timeseries input file (path or static)",
19
+ default="states.csv",
20
+ )
21
+ parser.add_argument(
22
+ "-t",
23
+ "--turbine_file",
24
+ help="The P-ct-curve csv file (path or static)",
25
+ default="NREL-5MW-D126-H90.csv",
26
+ )
27
+ parser.add_argument(
28
+ "-dx", "--deltax", help="The turbine distance in x", type=float, default=500.0
29
+ )
30
+ parser.add_argument(
31
+ "-dy", "--deltay", help="Turbine layout y step", type=float, default=0.0
32
+ )
33
+ parser.add_argument("-r", "--rotor", help="The rotor model", default="centre")
34
+ parser.add_argument(
35
+ "-p", "--pwakes", help="The partial wakes models", default=None, nargs="+"
36
+ )
37
+ parser.add_argument(
38
+ "-f", "--pmax_file", help="The max_P csv file", default="power_mask.csv"
39
+ )
40
+ parser.add_argument(
41
+ "-w",
42
+ "--wakes",
43
+ help="The wake models",
44
+ default=["Jensen_linear_k007"],
45
+ nargs="+",
46
+ )
47
+ parser.add_argument(
48
+ "-m", "--tmodels", help="The turbine models", default=[], nargs="+"
49
+ )
50
+ parser.add_argument(
51
+ "-sl",
52
+ "--show_layout",
53
+ help="Flag for showing layout figure",
54
+ action="store_true",
55
+ )
56
+ parser.add_argument("-e", "--engine", help="The engine", default="process")
57
+ parser.add_argument(
58
+ "-n", "--n_cpus", help="The number of cpus", default=None, type=int
59
+ )
60
+ parser.add_argument(
61
+ "-c",
62
+ "--chunksize_states",
63
+ help="The chunk size for states",
64
+ default=None,
65
+ type=int,
66
+ )
67
+ parser.add_argument(
68
+ "-C",
69
+ "--chunksize_points",
70
+ help="The chunk size for points",
71
+ default=None,
72
+ type=int,
73
+ )
74
+ parser.add_argument(
75
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
76
+ )
77
+ args = parser.parse_args()
78
+
79
+ print("\nReading file", args.pmax_file)
80
+ cols = [f"Pmax_{i}" for i in range(args.n_t)]
81
+ Pmax_data = pd.read_csv(args.pmax_file, usecols=cols).to_numpy()
82
+
83
+ mbook = foxes.models.ModelBook()
84
+ ttype = foxes.models.turbine_types.PCtFile(args.turbine_file)
85
+ mbook.turbine_types[ttype.name] = ttype
86
+ mbook.turbine_models["set_Pmax"] = foxes.models.turbine_models.SetFarmVars()
87
+ mbook.turbine_models["set_Pmax"].add_var(FV.MAX_P, Pmax_data)
88
+ models = args.tmodels + ["set_Pmax", ttype.name, "PMask"]
89
+
90
+ with foxes.Engine.new(
91
+ engine_type=args.engine,
92
+ n_procs=args.n_cpus,
93
+ chunk_size_states=args.chunksize_states,
94
+ chunk_size_points=args.chunksize_points,
95
+ ):
96
+ if not args.nofig:
97
+ fig, axs = plt.subplots(1, 2, figsize=(10, 4))
98
+ o = foxes.output.TurbineTypeCurves(mbook)
99
+ o.plot_curves(ttype.name, [FV.P, FV.CT], axs=axs, P_max=3000.0)
100
+ plt.show()
101
+ plt.close(fig)
102
+
103
+ """
104
+ # TODO: ct needs fix
105
+ fig, axs = plt.subplots(1, 2, figsize=(10, 4))
106
+ o = foxes.output.TurbineTypeCurves(mbook)
107
+ o.plot_curves(ttype.name, [FV.P, FV.CT], axs=axs, P_max=6000.0)
108
+ plt.show()
109
+ plt.close(fig)
110
+ """
111
+
112
+ states = foxes.input.states.StatesTable(
113
+ data_source=args.states,
114
+ output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
115
+ fixed_vars={FV.WD: 270.0, FV.TI: 0.05, FV.RHO: 1.225},
116
+ )
117
+
118
+ farm = foxes.WindFarm()
119
+ foxes.input.farm_layout.add_row(
120
+ farm=farm,
121
+ xy_base=[0.0, 0.0],
122
+ xy_step=[args.deltax, args.deltay],
123
+ n_turbines=args.n_t,
124
+ turbine_models=models,
125
+ )
126
+
127
+ if not args.nofig and args.show_layout:
128
+ ax = foxes.output.FarmLayoutOutput(farm).get_figure()
129
+ plt.show()
130
+ plt.close(ax.get_figure())
131
+
132
+ algo = foxes.algorithms.Downwind(
133
+ farm,
134
+ states,
135
+ rotor_model=args.rotor,
136
+ wake_models=args.wakes,
137
+ wake_frame="rotor_wd",
138
+ partial_wakes=args.pwakes,
139
+ mbook=mbook,
140
+ verbosity=0,
141
+ )
142
+
143
+ outputs = [
144
+ FV.D,
145
+ FV.WD,
146
+ FV.AMB_REWS,
147
+ FV.REWS,
148
+ FV.AMB_P,
149
+ FV.P,
150
+ FV.CT,
151
+ FV.WEIGHT,
152
+ FV.MAX_P,
153
+ ]
154
+
155
+ # run calculation with power mask:
156
+
157
+ farm_results = algo.calc_farm(outputs=outputs)
158
+
159
+ fr = farm_results.to_dataframe()
160
+ print(fr[[FV.WD, FV.AMB_REWS, FV.REWS, FV.AMB_P, FV.P, FV.CT, FV.MAX_P]])
161
+
162
+ o = foxes.output.FarmResultsEval(farm_results)
163
+ P0 = o.calc_mean_farm_power(ambient=True)
164
+ P = o.calc_mean_farm_power()
165
+ print(f"\nFarm power: {P/1000:.1f} MW, Efficiency = {P/P0*100:.2f} %")
166
+
167
+ o1 = foxes.output.StateTurbineMap(farm_results)
168
+
169
+ # run calculation without power mask:
170
+
171
+ mbook.finalize(algo)
172
+ models.remove("set_Pmax")
173
+ models.remove("PMask")
174
+
175
+ farm_results = algo.calc_farm(outputs=outputs)
176
+
177
+ fr = farm_results.to_dataframe()
178
+ print(fr[[FV.WD, FV.AMB_REWS, FV.REWS, FV.AMB_P, FV.P, FV.CT, FV.MAX_P]])
179
+
180
+ o = foxes.output.FarmResultsEval(farm_results)
181
+ P0 = o.calc_mean_farm_power(ambient=True)
182
+ P = o.calc_mean_farm_power()
183
+ print(f"\nFarm power: {P/1000:.1f} MW, Efficiency = {P/P0*100:.2f} %")
184
+
185
+ if not args.nofig:
186
+ o0 = foxes.output.StateTurbineMap(farm_results)
187
+
188
+ # show power:
189
+ fig, axs = plt.subplots(1, 3, figsize=(15, 5))
190
+ o0.plot_map(
191
+ FV.P,
192
+ ax=axs[0],
193
+ edgecolor="white",
194
+ title="Power, no power mask",
195
+ cmap="YlOrRd",
196
+ vmin=0,
197
+ vmax=np.nanmax(Pmax_data),
198
+ )
199
+ o1.plot_map(
200
+ FV.MAX_P,
201
+ ax=axs[1],
202
+ edgecolor="white",
203
+ cmap="YlOrRd",
204
+ title="Power mask",
205
+ vmin=0,
206
+ vmax=np.nanmax(Pmax_data),
207
+ )
208
+ o1.plot_map(
209
+ FV.P,
210
+ ax=axs[2],
211
+ edgecolor="white",
212
+ cmap="YlOrRd",
213
+ title="Power, with power mask",
214
+ vmin=0,
215
+ vmax=np.nanmax(Pmax_data),
216
+ )
217
+ plt.show()
218
+ plt.close(fig)
219
+
220
+ # show ct:
221
+ fig, axs = plt.subplots(1, 3, figsize=(15, 5))
222
+ o0.plot_map(
223
+ FV.CT,
224
+ ax=axs[0],
225
+ edgecolor="white",
226
+ title="ct, no power mask",
227
+ cmap="YlGn",
228
+ vmin=0,
229
+ vmax=1.0,
230
+ )
231
+ o1.plot_map(
232
+ FV.MAX_P,
233
+ ax=axs[1],
234
+ edgecolor="white",
235
+ cmap="YlOrRd",
236
+ title="Power mask",
237
+ vmin=0,
238
+ vmax=np.nanmax(Pmax_data),
239
+ )
240
+ o1.plot_map(
241
+ FV.CT,
242
+ ax=axs[2],
243
+ edgecolor="white",
244
+ cmap="YlGn",
245
+ title="ct, with power mask",
246
+ vmin=0,
247
+ vmax=1.0,
248
+ )
249
+ plt.show()
@@ -0,0 +1,210 @@
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
+ "n_turbines",
12
+ help="The number of wind turbines",
13
+ type=int,
14
+ )
15
+ parser.add_argument(
16
+ "n_times",
17
+ help="The number of states in the time series",
18
+ type=int,
19
+ )
20
+ parser.add_argument(
21
+ "-s",
22
+ "--seed",
23
+ help="The random seed",
24
+ type=int,
25
+ default=None,
26
+ )
27
+ parser.add_argument(
28
+ "-t",
29
+ "--turbine_file",
30
+ help="The P-ct-curve csv file (path or static)",
31
+ default="NREL-5MW-D126-H90.csv",
32
+ )
33
+ parser.add_argument("-r", "--rotor", help="The rotor model", default="centre")
34
+ parser.add_argument(
35
+ "-p", "--pwakes", help="The partial wakes models", default="centre", nargs="+"
36
+ )
37
+ parser.add_argument(
38
+ "-w",
39
+ "--wakes",
40
+ help="The wake models",
41
+ default=["Bastankhah2014_linear_k004"],
42
+ nargs="+",
43
+ )
44
+ parser.add_argument("-f", "--frame", help="The wake frame", default="rotor_wd")
45
+ parser.add_argument(
46
+ "-m", "--tmodels", help="The turbine models", default=[], nargs="+"
47
+ )
48
+ parser.add_argument("-e", "--engine", help="The engine", default="default")
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
+ "-it", "--iterative", help="Use iterative algorithm", action="store_true"
68
+ )
69
+ parser.add_argument(
70
+ "-nf", "--nofig", help="Do not show figures", action="store_true"
71
+ )
72
+ args = parser.parse_args()
73
+
74
+ mbook = foxes.models.ModelBook()
75
+ ttype = foxes.models.turbine_types.PCtFile(args.turbine_file)
76
+ mbook.turbine_types[ttype.name] = ttype
77
+
78
+ sdata = foxes.input.states.create.random_timseries_data(
79
+ args.n_times, seed=args.seed
80
+ )
81
+ states = foxes.input.states.Timeseries(
82
+ data_source=sdata,
83
+ output_vars=[FV.WS, FV.WD, FV.TI, FV.RHO],
84
+ fixed_vars={FV.RHO: 1.225, FV.TI: 0.04},
85
+ )
86
+
87
+ farm = foxes.WindFarm()
88
+ foxes.input.farm_layout.add_random(
89
+ farm,
90
+ args.n_turbines,
91
+ min_dist=500,
92
+ turbine_models=args.tmodels + [ttype.name],
93
+ seed=args.seed,
94
+ )
95
+
96
+ with foxes.Engine.new(
97
+ engine_type=args.engine,
98
+ n_procs=args.n_cpus,
99
+ chunk_size_states=args.chunksize_states,
100
+ chunk_size_points=args.chunksize_points,
101
+ ):
102
+
103
+ if not args.nofig:
104
+ # fig, axs= plt.subplots(2, 1, figsize=(12,6))
105
+ # foxes.output.FarmLayoutOutput(farm).get_figure(ax=axs[0])
106
+
107
+ o = foxes.output.StatesRosePlotOutput(states, point=[0.0, 0.0, 100.0])
108
+ fig = o.get_figure(
109
+ 16,
110
+ FV.AMB_WS,
111
+ [0, 3.5, 6, 10, 15, 20],
112
+ figsize=(14.5, 7),
113
+ rect=[0.01, 0.05, 0.45, 0.85],
114
+ )
115
+
116
+ ax = plt.Axes(fig, rect=[0.3, 0.1, 0.8, 0.8])
117
+ fig.add_axes(ax)
118
+ foxes.output.FarmLayoutOutput(farm).get_figure(fig=fig, ax=ax)
119
+ plt.show()
120
+ plt.close(fig)
121
+
122
+ Algo = (
123
+ foxes.algorithms.Iterative if args.iterative else foxes.algorithms.Downwind
124
+ )
125
+ algo = Algo(
126
+ farm,
127
+ states,
128
+ rotor_model=args.rotor,
129
+ wake_models=args.wakes,
130
+ wake_frame=args.frame,
131
+ partial_wakes=args.pwakes,
132
+ mbook=mbook,
133
+ verbosity=0,
134
+ )
135
+
136
+ time0 = time.time()
137
+ farm_results = algo.calc_farm()
138
+ time1 = time.time()
139
+
140
+ print("\nFarm results:\n")
141
+ print(farm_results)
142
+ print(
143
+ farm_results.to_dataframe()[
144
+ [
145
+ FV.AMB_WD,
146
+ FV.AMB_TI,
147
+ FV.AMB_REWS,
148
+ FV.AMB_CT,
149
+ FV.AMB_P,
150
+ FV.TI,
151
+ FV.REWS,
152
+ FV.CT,
153
+ FV.P,
154
+ ]
155
+ ]
156
+ )
157
+ print("\nCalc time =", time1 - time0, "\n")
158
+
159
+ o = foxes.output.FarmResultsEval(farm_results)
160
+ o.add_capacity(algo)
161
+ o.add_capacity(algo, ambient=True)
162
+ o.add_efficiency()
163
+
164
+ print("\nFarm results:\n")
165
+ print(farm_results)
166
+
167
+ # state-turbine results
168
+ farm_df = farm_results.to_dataframe()
169
+ print("\nFarm results data:\n")
170
+ print(
171
+ farm_df[
172
+ [
173
+ FV.X,
174
+ FV.WD,
175
+ FV.AMB_REWS,
176
+ FV.REWS,
177
+ FV.AMB_TI,
178
+ FV.TI,
179
+ FV.AMB_P,
180
+ FV.P,
181
+ FV.EFF,
182
+ ]
183
+ ]
184
+ )
185
+ print()
186
+
187
+ # results by turbine
188
+ turbine_results = o.reduce_states(
189
+ {
190
+ FV.AMB_P: "mean",
191
+ FV.P: "mean",
192
+ FV.AMB_CAP: "mean",
193
+ FV.CAP: "mean",
194
+ FV.EFF: "mean",
195
+ }
196
+ )
197
+ turbine_results[FV.AMB_YLD] = o.calc_turbine_yield(
198
+ algo=algo, annual=True, ambient=True
199
+ )
200
+ turbine_results[FV.YLD] = o.calc_turbine_yield(algo=algo, annual=True)
201
+ print("\nResults by turbine:\n")
202
+ print(turbine_results)
203
+
204
+ # power results
205
+ P0 = o.calc_mean_farm_power(ambient=True)
206
+ P = o.calc_mean_farm_power()
207
+ print(f"\nFarm power : {P/1000:.1f} MW")
208
+ print(f"Farm ambient power: {P0/1000:.1f} MW")
209
+ print(f"Farm efficiency : {o.calc_farm_efficiency()*100:.2f} %")
210
+ print(f"Annual farm yield : {turbine_results[FV.YLD].sum():.2f} GWh")