foxes 1.1.1__py3-none-any.whl → 1.2.1__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 (155) hide show
  1. docs/source/conf.py +3 -1
  2. examples/abl_states/run.py +5 -5
  3. examples/dyn_wakes/run.py +2 -2
  4. examples/induction/run.py +5 -5
  5. examples/random_timeseries/run.py +13 -13
  6. examples/scan_row/run.py +12 -7
  7. examples/sector_management/run.py +11 -7
  8. examples/single_state/run.py +5 -5
  9. examples/tab_file/run.py +1 -1
  10. examples/timelines/run.py +1 -1
  11. examples/timeseries/run.py +5 -5
  12. examples/timeseries_slurm/run.py +5 -5
  13. examples/wind_rose/run.py +1 -1
  14. examples/yawed_wake/run.py +5 -5
  15. foxes/__init__.py +13 -2
  16. foxes/algorithms/downwind/downwind.py +21 -6
  17. foxes/algorithms/downwind/models/init_farm_data.py +5 -2
  18. foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
  19. foxes/algorithms/iterative/iterative.py +1 -1
  20. foxes/algorithms/sequential/sequential.py +5 -4
  21. foxes/config/__init__.py +1 -0
  22. foxes/config/config.py +134 -0
  23. foxes/constants.py +15 -6
  24. foxes/core/algorithm.py +46 -30
  25. foxes/core/axial_induction_model.py +18 -0
  26. foxes/core/data.py +2 -1
  27. foxes/core/engine.py +43 -49
  28. foxes/core/farm_controller.py +22 -3
  29. foxes/core/farm_data_model.py +6 -2
  30. foxes/core/ground_model.py +19 -0
  31. foxes/core/model.py +2 -1
  32. foxes/core/partial_wakes_model.py +9 -21
  33. foxes/core/point_data_model.py +22 -2
  34. foxes/core/rotor_model.py +9 -21
  35. foxes/core/states.py +2 -17
  36. foxes/core/turbine_model.py +2 -18
  37. foxes/core/turbine_type.py +2 -18
  38. foxes/core/vertical_profile.py +8 -20
  39. foxes/core/wake_frame.py +9 -25
  40. foxes/core/wake_model.py +24 -20
  41. foxes/core/wake_superposition.py +19 -0
  42. foxes/data/__init__.py +1 -1
  43. foxes/data/static_data.py +0 -7
  44. foxes/engines/dask.py +4 -3
  45. foxes/engines/single.py +1 -1
  46. foxes/input/__init__.py +1 -1
  47. foxes/input/farm_layout/from_csv.py +3 -1
  48. foxes/input/farm_layout/from_file.py +10 -10
  49. foxes/input/farm_layout/from_json.py +4 -3
  50. foxes/input/farm_layout/grid.py +3 -3
  51. foxes/input/states/__init__.py +1 -1
  52. foxes/input/states/create/random_abl_states.py +5 -3
  53. foxes/input/states/field_data_nc.py +36 -15
  54. foxes/input/states/multi_height.py +26 -15
  55. foxes/input/states/one_point_flow.py +6 -5
  56. foxes/input/states/{scan_ws.py → scan.py} +42 -52
  57. foxes/input/states/single.py +15 -6
  58. foxes/input/states/slice_data_nc.py +18 -12
  59. foxes/input/states/states_table.py +17 -10
  60. foxes/input/yaml/__init__.py +3 -0
  61. foxes/input/yaml/dict.py +381 -0
  62. foxes/input/yaml/windio/__init__.py +4 -0
  63. foxes/input/{windio → yaml/windio}/get_states.py +7 -7
  64. foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
  65. foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
  66. foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
  67. foxes/input/yaml/windio/read_outputs.py +147 -0
  68. foxes/input/yaml/windio/windio.py +269 -0
  69. foxes/input/yaml/yaml.py +103 -0
  70. foxes/models/partial_wakes/axiwake.py +7 -6
  71. foxes/models/partial_wakes/centre.py +3 -2
  72. foxes/models/partial_wakes/segregated.py +5 -2
  73. foxes/models/point_models/set_uniform_data.py +5 -3
  74. foxes/models/rotor_models/centre.py +2 -2
  75. foxes/models/rotor_models/grid.py +5 -5
  76. foxes/models/rotor_models/levels.py +6 -6
  77. foxes/models/turbine_models/kTI_model.py +3 -1
  78. foxes/models/turbine_models/lookup_table.py +7 -4
  79. foxes/models/turbine_models/power_mask.py +14 -8
  80. foxes/models/turbine_models/sector_management.py +4 -2
  81. foxes/models/turbine_models/set_farm_vars.py +53 -23
  82. foxes/models/turbine_models/table_factors.py +8 -7
  83. foxes/models/turbine_models/yaw2yawm.py +0 -1
  84. foxes/models/turbine_models/yawm2yaw.py +0 -1
  85. foxes/models/turbine_types/CpCt_file.py +6 -3
  86. foxes/models/turbine_types/CpCt_from_two.py +6 -3
  87. foxes/models/turbine_types/PCt_file.py +7 -6
  88. foxes/models/turbine_types/PCt_from_two.py +11 -2
  89. foxes/models/turbine_types/TBL_file.py +3 -4
  90. foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
  91. foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
  92. foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
  93. foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
  94. foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
  95. foxes/models/vertical_profiles/abl_log_ws.py +1 -1
  96. foxes/models/wake_frames/dynamic_wakes.py +17 -9
  97. foxes/models/wake_frames/farm_order.py +4 -3
  98. foxes/models/wake_frames/rotor_wd.py +3 -1
  99. foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
  100. foxes/models/wake_frames/streamlines.py +9 -6
  101. foxes/models/wake_frames/timelines.py +21 -14
  102. foxes/models/wake_frames/yawed_wakes.py +3 -1
  103. foxes/models/wake_models/induction/vortex_sheet.py +0 -1
  104. foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
  105. foxes/models/wake_models/wind/bastankhah14.py +3 -2
  106. foxes/models/wake_models/wind/bastankhah16.py +2 -1
  107. foxes/models/wake_models/wind/turbopark.py +9 -7
  108. foxes/models/wake_superpositions/ws_product.py +0 -1
  109. foxes/output/__init__.py +2 -1
  110. foxes/output/calc_points.py +7 -4
  111. foxes/output/farm_layout.py +30 -18
  112. foxes/output/farm_results_eval.py +61 -38
  113. foxes/output/grids.py +8 -7
  114. foxes/output/output.py +9 -20
  115. foxes/output/plt.py +19 -0
  116. foxes/output/results_writer.py +10 -11
  117. foxes/output/rose_plot.py +448 -224
  118. foxes/output/rotor_point_plots.py +7 -3
  119. foxes/output/slice_data.py +1 -1
  120. foxes/output/state_turbine_map.py +5 -1
  121. foxes/output/state_turbine_table.py +7 -3
  122. foxes/output/turbine_type_curves.py +7 -2
  123. foxes/utils/__init__.py +1 -2
  124. foxes/utils/dict.py +107 -3
  125. foxes/utils/geopandas_utils.py +3 -2
  126. foxes/utils/subclasses.py +69 -0
  127. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/METADATA +18 -18
  128. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/RECORD +145 -145
  129. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/WHEEL +1 -1
  130. foxes-1.2.1.dist-info/entry_points.txt +3 -0
  131. tests/0_consistency/iterative/test_iterative.py +65 -67
  132. tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
  133. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
  134. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
  135. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
  136. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +57 -52
  137. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +58 -54
  138. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +80 -76
  139. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +80 -76
  140. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +58 -51
  141. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
  142. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +67 -64
  143. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +58 -54
  144. examples/windio/run.py +0 -29
  145. foxes/data/states/windio_timeseries_5000.nc +0 -0
  146. foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
  147. foxes/data/windio/__init__.py +0 -0
  148. foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
  149. foxes/input/windio/__init__.py +0 -11
  150. foxes/input/windio/read_outputs.py +0 -172
  151. foxes/input/windio/runner.py +0 -183
  152. foxes/input/windio/windio.py +0 -193
  153. foxes/utils/windrose_plot.py +0 -152
  154. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/LICENSE +0 -0
  155. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/top_level.txt +0 -0
examples/windio/run.py DELETED
@@ -1,29 +0,0 @@
1
- import argparse
2
-
3
- import foxes
4
-
5
- if __name__ == "__main__":
6
- # define arguments and options:
7
- parser = argparse.ArgumentParser()
8
- parser.add_argument(
9
- "-wio",
10
- "--windio_yaml",
11
- help="The windio wind energy systems yaml file",
12
- default="windio_5turbines_timeseries.yaml",
13
- )
14
- parser.add_argument(
15
- "-nf", "--nofig", help="Do not show figures", action="store_true"
16
- )
17
- parser.add_argument(
18
- "-V", "--verbosity", help="The verbosity level, 0=silent", type=int, default=1
19
- )
20
- args = parser.parse_args()
21
-
22
- try:
23
- wio_runner = foxes.input.windio.read_windio(
24
- args.windio_yaml, verbosity=args.verbosity
25
- )
26
- with wio_runner as runner:
27
- runner.run()
28
- except ModuleNotFoundError as e:
29
- print(e.msg)
Binary file
@@ -1,10 +0,0 @@
1
- name: DTU 10MW Offshore Reference Turbine
2
- performance:
3
- power_curve:
4
- power_values: [263388., 751154., 1440738., 2355734., 3506858., 4993092., 6849310., 9116402., 10000754., 10009590., 10000942., 10042678., 10003480., 10001600., 10001506., 10013632., 10007428., 10005360., 10002728., 10001130., 10004984., 9997558.]
5
- power_wind_speeds: [4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.]
6
- Ct_curve:
7
- Ct_values: [0.923,0.919,0.904,0.858,0.814,0.814,0.814,0.814,0.577,0.419,0.323,0.259,0.211,0.175,0.148,0.126,0.109,0.095,0.084,0.074,0.066,0.059]
8
- Ct_wind_speeds: [4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.]
9
- hub_height: 119.0
10
- rotor_diameter: 178.3
File without changes
@@ -1,79 +0,0 @@
1
- name: 5 turbines and a wind timeseries
2
-
3
- site:
4
- name: Site with wind timeseries data
5
- boundaries:
6
- polygons: [
7
- x: [-10, -10, 1610, 1610],
8
- y: [-10, 10, 10, -10]
9
- ]
10
- energy_resource:
11
- name: NetCDF timeseries with 5000 states
12
- wind_resource: !include ../states/windio_timeseries_5000.nc
13
-
14
- wind_farm:
15
- name: One row with 5 turbines
16
- layouts:
17
- - coordinates:
18
- x: [0, 0, 0, 0, 0]
19
- y: [0, 600, 1150, 1730, 2400]
20
- turbines: !include DTU_10MW_turbine.yaml
21
-
22
- attributes:
23
- flow_model:
24
- name: foxes
25
-
26
- analysis:
27
-
28
- #pywake and foxes
29
- wind_deficit_model:
30
- name: Bastankhah2014
31
- wake_expansion_coefficient: # k = ka*ti + kb
32
- k_a: 0.0
33
- k_b: 0.04
34
- free_stream_ti: false
35
- ceps: 0.2
36
- use_effective_ws: true
37
- axial_induction_model: Madsen
38
- deflection_model:
39
- name: None
40
- turbulence_model:
41
- name: CrespoHernandez
42
- superposition_model:
43
- ws_superposition: Linear
44
- ti_superposition: Quadratic
45
- rotor_averaging:
46
- grid: grid
47
- n_x_grid_points: 4
48
- n_y_grid_points: 4
49
- background_averaging: center
50
- wake_averaging: centre
51
- wind_speed_exponent_for_power: 3
52
- wind_speed_exponent_for_ct: 2
53
- blockage_model:
54
- name: None
55
-
56
- outputs:
57
- output_folder: "results"
58
- turbine_outputs:
59
- turbine_nc_filename: 'turbine_data.nc' # dimension = states, turbine
60
- output_variables: ['power', 'rotor_effective_velocity'] #'frequency'
61
- #
62
- flow_field:
63
- report: False
64
- flow_nc_filename: flow_field.nc
65
- cases_run:
66
- all_occurences: True
67
- output_variables: ['wind_speed', 'wind_direction']
68
- z_planes:
69
- z_sampling: "hub_height"
70
- xy_sampling: "default"
71
- #
72
- statistics:
73
- stats_filename: None
74
- AEP: False
75
- AEP_per_turbine: False
76
- power_percentiles:
77
- report: False
78
- percentiles: None
79
-
@@ -1,11 +0,0 @@
1
- """
2
- Functions for using windIO yaml files as input.
3
- """
4
-
5
- from .windio import read_windio
6
- from .read_fields import wio2foxes, foxes2wio
7
- from .get_states import get_states
8
- from .read_farm import read_turbine_types, read_layout
9
- from .read_attributes import read_attributes
10
- from .read_outputs import read_outputs
11
- from .runner import WindioRunner
@@ -1,172 +0,0 @@
1
- import numpy as np
2
- from pathlib import Path
3
-
4
- from foxes.utils import Dict
5
- import foxes.variables as FV
6
- import foxes.constants as FC
7
-
8
- from .read_fields import foxes2wio
9
-
10
-
11
- def _read_turbine_outputs(wio_outs, odir, out_dicts, verbosity):
12
- """Reads the turbine outputs request"""
13
- if "turbine_outputs" in wio_outs and wio_outs["turbine_outputs"].get(
14
- "report", True
15
- ):
16
- turbine_outputs = Dict(wio_outs["turbine_outputs"], name="turbine_outputs")
17
- turbine_nc_filename = turbine_outputs.pop(
18
- "turbine_nc_filename", "turbine_outputs.nc"
19
- )
20
- output_variables = turbine_outputs["output_variables"]
21
- if verbosity > 2:
22
- print(" Reading turbine_outputs")
23
- print(" File name:", turbine_nc_filename)
24
- print(" output_variables:", output_variables)
25
-
26
- vmap = Dict(
27
- power=FV.P,
28
- rotor_effective_velocity=FV.REWS,
29
- )
30
- ivmap = {d: k for k, d in vmap.items()}
31
- ivmap.update(
32
- {
33
- FC.STATE: "time",
34
- FC.TURBINE: "turbine",
35
- }
36
- )
37
-
38
- out_dicts.append(
39
- Dict(
40
- {
41
- "output_type": "StateTurbineTable",
42
- "farm_results": True,
43
- "algo": False,
44
- "run_func": "get_dataset",
45
- "run_kwargs": dict(
46
- variables=[vmap[v] for v in output_variables],
47
- name_map=ivmap,
48
- to_file=odir / turbine_nc_filename,
49
- round={
50
- vw: FV.get_default_digits(vf) for vw, vf in vmap.items()
51
- },
52
- verbosity=verbosity,
53
- ),
54
- "output_yaml_update": {
55
- "power_table": f"include {turbine_nc_filename}",
56
- },
57
- },
58
- name="turbine_outputs",
59
- )
60
- )
61
-
62
-
63
- def _read_flow_field(wio_outs, odir, out_dicts, verbosity):
64
- """Reads the flow field request"""
65
- if "flow_field" in wio_outs and wio_outs["flow_field"].get("report", True):
66
- flow_field = Dict(wio_outs["flow_field"], name="flow_field")
67
- flow_nc_filename = flow_field.pop("flow_nc_filename", "flow_field.nc")
68
- output_variables = flow_field.pop("output_variables")
69
- z_planes = Dict(flow_field.pop("z_planes"), name="z_planes")
70
- z_sampling = z_planes["z_sampling"]
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
76
- if verbosity > 2:
77
- print(" Reading flow_field")
78
- print(" File name :", flow_nc_filename)
79
- print(" output_variables:", output_variables)
80
- print(" states subset :", states_isel)
81
- print(" z_sampling :", z_sampling)
82
- print(" xy_sampling :", xy_sampling)
83
-
84
- vmap = Dict(
85
- wind_speed=FV.WS,
86
- wind_direction=FV.WD,
87
- )
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
-
98
- if xy_sampling == "default":
99
- out_dicts.append(
100
- Dict(
101
- {
102
- "output_type": "SliceData",
103
- "farm_results": True,
104
- "algo": True,
105
- "verbosity_delta": 3,
106
- "run_func": "get_states_data_xy",
107
- "run_kwargs": dict(
108
- states_isel=states_isel,
109
- n_img_points=(100, 100),
110
- variables=[vmap[v] for v in output_variables],
111
- z=z,
112
- to_file=odir / flow_nc_filename,
113
- label_map=foxes2wio,
114
- verbosity=verbosity,
115
- ),
116
- "output_yaml_update": {
117
- "flow_field": f"include {flow_nc_filename}",
118
- },
119
- },
120
- name="flow_field",
121
- )
122
- )
123
- else:
124
- raise NotImplementedError(
125
- f"xy_sampling '{xy_sampling}' is not supported (yet)"
126
- )
127
-
128
-
129
- def read_outputs(wio_outs, algo_dict, output_dir=None, verbosity=1):
130
- """
131
- Reads the windio outputs
132
-
133
- Parameters
134
- ----------
135
- wio_outs: dict
136
- The windio output data
137
- algo_dict: dict
138
- The algorithm dictionary
139
- output_dir: pathlib.Path, optional
140
- Path to the output folder
141
- verbosity: int
142
- The verbosity level, 0=silent
143
-
144
- Returns
145
- -------
146
- out_dicts: list of dict
147
- The output dictionaries
148
- odir: pathlib.Path
149
- Path to the output folder
150
-
151
- :group: input.windio
152
-
153
- """
154
- out_dicts = []
155
- odir = (
156
- Path(output_dir)
157
- if output_dir is not None
158
- else Path(wio_outs.pop("output_folder", "results"))
159
- )
160
- odir.mkdir(exist_ok=True, parents=True)
161
- if verbosity > 2:
162
- print(" Reading outputs")
163
- print(" Output folder:", odir)
164
- print(" Contents:", [k for k in wio_outs.keys()])
165
-
166
- # read turbine_outputs:
167
- _read_turbine_outputs(wio_outs, odir, out_dicts, verbosity)
168
-
169
- # read flow field:
170
- _read_flow_field(wio_outs, odir, out_dicts, verbosity)
171
-
172
- return out_dicts, odir
@@ -1,183 +0,0 @@
1
- import yaml
2
-
3
- from foxes.core import Algorithm
4
- from foxes.output import Output
5
-
6
-
7
- def _write_yaml(data, fpath):
8
- """Write the data to yaml"""
9
- rmap = {
10
- "include": "!include",
11
- }
12
- with open(fpath, "w") as file:
13
- yaml.dump(data, file)
14
- with open(fpath, "r") as f:
15
- s = f.read()
16
- with open(fpath, "w") as f:
17
- for k1, k2 in rmap.items():
18
- s = s.replace(k1, k2)
19
- f.write(s)
20
-
21
-
22
- class WindioRunner:
23
- """
24
- Runner for windio input
25
-
26
- Attributes
27
- ----------
28
- algo: foxes.core.Algorithm
29
- The algorithm object
30
- output_dir: pathlib.Path
31
- Path to the output folder
32
- output_dicts: list of dict
33
- The output dictionaries
34
- farm_results: xarray.Dataset
35
- The farm results
36
- output_results: list
37
- The output results
38
- wio_input_data: dict
39
- The wind_energy_system windio input data
40
- file_name_input_yaml: str
41
- Name of the written input data file
42
- file_name_output_yaml: str
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
48
- verbosity: int
49
- The verbosity level, 0 = silent
50
-
51
- :group: input.windio
52
-
53
- """
54
-
55
- def __init__(
56
- self,
57
- algo_dict,
58
- output_dir=".",
59
- output_dicts=[],
60
- wio_input_data=None,
61
- file_name_input_yaml="recorded_input.yaml",
62
- file_name_output_yaml="recorded_output.yaml",
63
- write_input_yaml=False,
64
- write_output_yaml=False,
65
- verbosity=1,
66
- ):
67
- """
68
- Conbstructor
69
-
70
- Parameters
71
- ----------
72
- algo_dict: dict
73
- The algorithm dictionary
74
- output_dir: pathlib.Path
75
- Path to the output folder
76
- output_dicts: list of dict
77
- The output dictionaries
78
- wio_input_data: dict
79
- The wind_energy_system windio input data
80
- file_name_input_yaml: str
81
- Name of the written input data file
82
- file_name_output_yaml: str
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
88
- verbosity: int
89
- The verbosity level, 0 = silent
90
-
91
- """
92
- self.algo = algo_dict
93
- self.output_dir = output_dir
94
- self.output_dicts = output_dicts
95
- self.wio_input_data = wio_input_data
96
- self.file_name_input_yaml = file_name_input_yaml
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
100
- self.verbosity = verbosity
101
- self.farm_results = None
102
- self.output_results = None
103
-
104
- self.__initialized = False
105
-
106
- self._output_yaml = {}
107
- if self.write_input_yaml and len(wio_input_data):
108
- fpath = output_dir / file_name_input_yaml
109
- self.print(f"Writing file", fpath)
110
- _write_yaml(wio_input_data, fpath)
111
- self._output_yaml["wind_energy_system"] = f"include {file_name_input_yaml}"
112
-
113
- def print(self, *args, level=1, **kwargs):
114
- """Print based on verbosity"""
115
- if self.verbosity >= level:
116
- print(*args, **kwargs)
117
-
118
- def initialize(self):
119
- """Initializes the runner"""
120
- if isinstance(self.algo, dict):
121
- self.print(f"Creating algorithm '{self.algo['algo_type']}'", level=2)
122
- self.algo = Algorithm.new(**self.algo)
123
- if not self.algo.initialized:
124
- self.algo.initialize()
125
- self.__initialized = True
126
-
127
- @property
128
- def initialized(self):
129
- """Flag for initialization"""
130
- return self.__initialized
131
-
132
- def run_farm_calc(self):
133
- """Runs the farm calculation"""
134
- if not self.__initialized:
135
- self.initialize()
136
- self.print("Running farm_calc")
137
- self.farm_results = self.algo.calc_farm()
138
-
139
- def run_outputs(self):
140
- """Runs the output calculation"""
141
- self.output_results = []
142
- for odict in self.output_dicts:
143
- self.print("Running output:", odict["output_type"])
144
- run_fname = odict.pop("run_func")
145
- run_args = odict.pop("run_args", ())
146
- run_kwargs = odict.pop("run_kwargs", {})
147
-
148
- _odict = odict.copy()
149
- if "output_yaml_update" in _odict:
150
- self._output_yaml.update(_odict.pop("output_yaml_update"))
151
- if _odict.pop("farm_results", False):
152
- _odict["farm_results"] = self.farm_results
153
- if _odict.pop("algo", False):
154
- _odict["algo"] = self.algo
155
- o = Output.new(**_odict)
156
- f = getattr(o, run_fname)
157
- self.output_results.append(f(*run_args, **run_kwargs))
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
-
164
- def run(self):
165
- """Runs all calculations"""
166
- self.run_farm_calc()
167
- self.run_outputs()
168
-
169
- def finalize(self):
170
- """Initializes the runner"""
171
- if self.algo.initialized:
172
- self.algo.finalize(clear_mem=True)
173
- self.algo = None
174
- self.farm_results = None
175
- self.output_results = None
176
- self.__initialized = False
177
-
178
- def __enter__(self):
179
- self.initialize()
180
- return self
181
-
182
- def __exit__(self, *args):
183
- self.finalize()
@@ -1,193 +0,0 @@
1
- from pathlib import Path
2
-
3
- from foxes.core import WindFarm
4
- from foxes.models import ModelBook
5
- from foxes.utils import import_module, Dict
6
- from foxes.data import StaticData, WINDIO
7
-
8
- from .read_fields import read_wind_resource_field
9
- from .get_states import get_states
10
- from .read_farm import read_layout, read_turbine_types
11
- from .read_attributes import read_attributes
12
- from .runner import WindioRunner
13
-
14
-
15
- def _read_site(wio, algo_dict, verbosity):
16
- """Reads the site information"""
17
- wio_site = Dict(wio["site"], name="site")
18
- if verbosity > 1:
19
- print("Reading site")
20
- print(" Name:", wio_site.pop("name", None))
21
- print(" Contents:", [k for k in wio_site.keys()])
22
-
23
- # ignore boundaries:
24
- if verbosity > 2:
25
- print(" Ignoring boundaries")
26
-
27
- # read energy_resource:
28
- energy_resource = Dict(wio_site["energy_resource"], name="energy_resource")
29
- if verbosity > 2:
30
- print(" Reading energy_resource")
31
- print(" Name:", energy_resource.pop("name", None))
32
- print(" Contents:", [k for k in energy_resource.keys()])
33
-
34
- # read wind_resource:
35
- wind_resource = Dict(energy_resource["wind_resource"], name="wind_resource")
36
- if verbosity > 2:
37
- print(" Reading wind_resource")
38
- print(" Name:", wind_resource.pop("name", None))
39
- print(" Contents:", [k for k in wind_resource.keys()])
40
-
41
- # read fields
42
- coords = Dict(name="coords")
43
- fields = Dict(name="fields")
44
- dims = Dict(name="dims")
45
- for n, d in wind_resource.items():
46
- read_wind_resource_field(n, d, coords, fields, dims, verbosity)
47
- if verbosity > 2:
48
- print(" Coords:")
49
- for c, d in coords.items():
50
- print(f" {c}: Shape {d.shape}")
51
- print(" Fields:")
52
- for f, d in dims.items():
53
- if len(d):
54
- print(f" {f}: Dims {d}, shape {fields[f].shape}")
55
- else:
56
- print(f" {f} = {fields[f]}")
57
-
58
- algo_dict["states"] = get_states(coords, fields, dims, verbosity)
59
-
60
-
61
- def _read_farm(wio, algo_dict, verbosity):
62
- """Reads the wind farm information"""
63
- wio_farm = Dict(wio["wind_farm"], name="wind_farm")
64
- if verbosity > 1:
65
- print("Reading wind farm")
66
- print(" Name:", wio_farm.pop("name", None))
67
- print(" Contents:", [k for k in wio_farm.keys()])
68
-
69
- # find REWS exponents:
70
- try:
71
- rotor_averaging = wio["attributes"]["analysis"]["rotor_averaging"]
72
- ws_exp_P = rotor_averaging["wind_speed_exponent_for_power"]
73
- ws_exp_ct = rotor_averaging["wind_speed_exponent_for_ct"]
74
- except KeyError:
75
- ws_exp_P = 1
76
- ws_exp_ct = 1
77
-
78
- # read turbine type:
79
- ttypes = read_turbine_types(wio_farm, algo_dict, ws_exp_P, ws_exp_ct, verbosity)
80
-
81
- # read layouts:
82
- wfarm = wio_farm["layouts"]
83
- if isinstance(wfarm, dict):
84
- layouts = Dict(wfarm, name="layouts")
85
- else:
86
- layouts = Dict({i: l for i, l in enumerate(wfarm)}, name="layouts")
87
- if verbosity > 2:
88
- print(" Reading layouts")
89
- print(" Contents:", [k for k in layouts.keys()])
90
- for lname, ldict in layouts.items():
91
- read_layout(lname, ldict, algo_dict, ttypes, verbosity)
92
-
93
-
94
- def read_windio(
95
- windio_yaml,
96
- verbosity=1,
97
- algo_pars=None,
98
- output_dir=None,
99
- **runner_pars,
100
- ):
101
- """
102
- Reads a complete WindIO case.
103
-
104
- This is the main entry point for windio case
105
- calculations.
106
-
107
- Parameters
108
- ----------
109
- windio_yaml: str
110
- Path to the windio yaml file
111
- verbosity: int
112
- The verbosity level, 0 = silent
113
- algo_pars: dict, optional
114
- Additional algorithm parameters
115
- output_dir: str, optional
116
- Path to the output folder
117
- runner_pars: dict, optional
118
- Additional parameters for the WindioRunner
119
-
120
- Returns
121
- -------
122
- runner: foxes.input.windio.WindioRunner
123
- The windio runner, call its run function
124
- for the complete exection
125
-
126
- :group: input.windio
127
-
128
- """
129
- wio_file = Path(windio_yaml)
130
- if not wio_file.is_file():
131
- wio_file = StaticData().get_file_path(WINDIO, wio_file, check_raw=False)
132
-
133
- if verbosity > 0:
134
- print(f"Reading windio file {wio_file}")
135
-
136
- yml_utils = import_module("windIO.utils.yml_utils", hint="pip install git+https://github.com/kilojoules/windIO@master#egg=windIO")
137
- wio = yml_utils.load_yaml(wio_file)
138
-
139
- if verbosity > 1:
140
- print(" Name:", wio.pop("name", None))
141
- print(" Contents:", [k for k in wio.keys()])
142
-
143
- algo_dict = Dict(algo_type="Downwind", name="algo_dict")
144
- if algo_pars is not None:
145
- algo_dict.update(algo_pars)
146
- algo_dict.update(
147
- dict(
148
- mbook=ModelBook(),
149
- farm=WindFarm(),
150
- wake_models=[],
151
- verbosity=verbosity - 3,
152
- )
153
- )
154
-
155
- _read_site(wio, algo_dict, verbosity)
156
- _read_farm(wio, algo_dict, verbosity)
157
-
158
- out_dicts, odir = read_attributes(
159
- wio,
160
- algo_dict,
161
- output_dir=output_dir,
162
- verbosity=verbosity,
163
- )
164
-
165
- if verbosity > 1:
166
- print("Creating windio runner")
167
- runner = WindioRunner(
168
- algo_dict,
169
- output_dir=odir,
170
- output_dicts=out_dicts,
171
- wio_input_data=wio,
172
- verbosity=verbosity,
173
- **runner_pars,
174
- )
175
-
176
- return runner
177
-
178
-
179
- if __name__ == "__main__":
180
- import argparse
181
-
182
- parser = argparse.ArgumentParser()
183
- parser.add_argument(
184
- "-f",
185
- "--file",
186
- help="The windio yaml file",
187
- default="windio_5turbines_timeseries.yaml",
188
- )
189
- args = parser.parse_args()
190
-
191
- runner = read_windio(args.file)
192
-
193
- runner.run()