foxes 1.5.1__tar.gz → 1.5.2__tar.gz

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 (337) hide show
  1. {foxes-1.5.1/foxes.egg-info → foxes-1.5.2}/PKG-INFO +5 -6
  2. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/read_attributes.py +8 -2
  3. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/read_farm.py +20 -0
  4. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/read_fields.py +3 -0
  5. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/read_outputs.py +24 -12
  6. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/read_site.py +33 -12
  7. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/windio.py +1 -0
  8. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/farm_controllers/__init__.py +1 -0
  9. foxes-1.5.2/foxes/models/farm_controllers/op_flag.py +196 -0
  10. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/induction/self_similar.py +22 -4
  11. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/induction/self_similar2020.py +1 -1
  12. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/ti/crespo_hernandez.py +1 -1
  13. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/wind/bastankhah14.py +1 -1
  14. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/wind/bastankhah16.py +1 -1
  15. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/wind/turbopark.py +1 -1
  16. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/state_turbine_map.py +7 -4
  17. {foxes-1.5.1 → foxes-1.5.2}/foxes/variables.py +8 -3
  18. {foxes-1.5.1 → foxes-1.5.2/foxes.egg-info}/PKG-INFO +5 -6
  19. {foxes-1.5.1 → foxes-1.5.2}/foxes.egg-info/SOURCES.txt +2 -0
  20. {foxes-1.5.1 → foxes-1.5.2}/foxes.egg-info/requires.txt +4 -5
  21. {foxes-1.5.1 → foxes-1.5.2}/pyproject.toml +5 -6
  22. foxes-1.5.2/tests/2_models/turbine_models/test_set_farm_vars.py +64 -0
  23. {foxes-1.5.1 → foxes-1.5.2}/LICENSE +0 -0
  24. {foxes-1.5.1 → foxes-1.5.2}/Logo_FOXES.svg +0 -0
  25. {foxes-1.5.1 → foxes-1.5.2}/MANIFEST.in +0 -0
  26. {foxes-1.5.1 → foxes-1.5.2}/README.md +0 -0
  27. {foxes-1.5.1 → foxes-1.5.2}/docs/source/conf.py +0 -0
  28. {foxes-1.5.1 → foxes-1.5.2}/examples/abl_states/run.py +0 -0
  29. {foxes-1.5.1 → foxes-1.5.2}/examples/compare_rotors_pwakes/run.py +0 -0
  30. {foxes-1.5.1 → foxes-1.5.2}/examples/compare_wakes/run.py +0 -0
  31. {foxes-1.5.1 → foxes-1.5.2}/examples/dyn_wakes/run.py +0 -0
  32. {foxes-1.5.1 → foxes-1.5.2}/examples/field_data_nc/run.py +0 -0
  33. {foxes-1.5.1 → foxes-1.5.2}/examples/induction/run.py +0 -0
  34. {foxes-1.5.1 → foxes-1.5.2}/examples/multi_height/run.py +0 -0
  35. {foxes-1.5.1 → foxes-1.5.2}/examples/power_mask/run.py +0 -0
  36. {foxes-1.5.1 → foxes-1.5.2}/examples/quickstart/run.py +0 -0
  37. {foxes-1.5.1 → foxes-1.5.2}/examples/random_timeseries/run.py +0 -0
  38. {foxes-1.5.1 → foxes-1.5.2}/examples/scan_row/run.py +0 -0
  39. {foxes-1.5.1 → foxes-1.5.2}/examples/sector_management/run.py +0 -0
  40. {foxes-1.5.1 → foxes-1.5.2}/examples/sequential/run.py +0 -0
  41. {foxes-1.5.1 → foxes-1.5.2}/examples/single_state/run.py +0 -0
  42. {foxes-1.5.1 → foxes-1.5.2}/examples/states_lookup_table/run.py +0 -0
  43. {foxes-1.5.1 → foxes-1.5.2}/examples/streamline_wakes/run.py +0 -0
  44. {foxes-1.5.1 → foxes-1.5.2}/examples/tab_file/run.py +0 -0
  45. {foxes-1.5.1 → foxes-1.5.2}/examples/timelines/run.py +0 -0
  46. {foxes-1.5.1 → foxes-1.5.2}/examples/timeseries/run.py +0 -0
  47. {foxes-1.5.1 → foxes-1.5.2}/examples/timeseries_slurm/run.py +0 -0
  48. {foxes-1.5.1 → foxes-1.5.2}/examples/wind_rose/run.py +0 -0
  49. {foxes-1.5.1 → foxes-1.5.2}/examples/yawed_wake/run.py +0 -0
  50. {foxes-1.5.1 → foxes-1.5.2}/foxes/__init__.py +0 -0
  51. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/__init__.py +0 -0
  52. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/__init__.py +0 -0
  53. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/downwind.py +0 -0
  54. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/__init__.py +0 -0
  55. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/farm_wakes_calc.py +0 -0
  56. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/init_farm_data.py +0 -0
  57. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/point_wakes_calc.py +0 -0
  58. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/reorder_farm_output.py +0 -0
  59. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/set_amb_farm_results.py +0 -0
  60. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/downwind/models/set_amb_point_results.py +0 -0
  61. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/iterative/__init__.py +0 -0
  62. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/iterative/iterative.py +0 -0
  63. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/iterative/models/__init__.py +0 -0
  64. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/iterative/models/convergence.py +0 -0
  65. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/iterative/models/farm_wakes_calc.py +0 -0
  66. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/iterative/models/urelax.py +0 -0
  67. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/sequential/__init__.py +0 -0
  68. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/sequential/models/__init__.py +0 -0
  69. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/sequential/models/plugin.py +0 -0
  70. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/sequential/models/seq_state.py +0 -0
  71. {foxes-1.5.1 → foxes-1.5.2}/foxes/algorithms/sequential/sequential.py +0 -0
  72. {foxes-1.5.1 → foxes-1.5.2}/foxes/config/__init__.py +0 -0
  73. {foxes-1.5.1 → foxes-1.5.2}/foxes/config/config.py +0 -0
  74. {foxes-1.5.1 → foxes-1.5.2}/foxes/constants.py +0 -0
  75. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/__init__.py +0 -0
  76. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/algorithm.py +0 -0
  77. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/axial_induction_model.py +0 -0
  78. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/data.py +0 -0
  79. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/data_calc_model.py +0 -0
  80. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/engine.py +0 -0
  81. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/farm_controller.py +0 -0
  82. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/farm_data_model.py +0 -0
  83. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/farm_model.py +0 -0
  84. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/ground_model.py +0 -0
  85. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/model.py +0 -0
  86. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/partial_wakes_model.py +0 -0
  87. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/point_data_model.py +0 -0
  88. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/rotor_model.py +0 -0
  89. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/states.py +0 -0
  90. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/turbine.py +0 -0
  91. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/turbine_model.py +0 -0
  92. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/turbine_type.py +0 -0
  93. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/vertical_profile.py +0 -0
  94. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/wake_deflection.py +0 -0
  95. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/wake_frame.py +0 -0
  96. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/wake_model.py +0 -0
  97. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/wake_superposition.py +0 -0
  98. {foxes-1.5.1 → foxes-1.5.2}/foxes/core/wind_farm.py +0 -0
  99. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/__init__.py +0 -0
  100. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/farms/__init__.py +0 -0
  101. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/farms/test_farm_67.csv +0 -0
  102. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/parse.py +0 -0
  103. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/power_ct_curves/DTU-10MW-D178d3-H119.csv +0 -0
  104. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/power_ct_curves/IEA-15MW-D240-H150.csv +0 -0
  105. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/power_ct_curves/IWT-7d5MW-D164-H100.csv +0 -0
  106. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/power_ct_curves/NREL-5MW-D126-H90.csv +0 -0
  107. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/power_ct_curves/__init__.py +0 -0
  108. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/WRF-Timeseries-3000.nc +0 -0
  109. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/WRF-Timeseries-4464.csv.gz +0 -0
  110. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/__init__.py +0 -0
  111. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/abl_states_6000.csv.gz +0 -0
  112. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/point_cloud_100.nc +0 -0
  113. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/timeseries_100.csv.gz +0 -0
  114. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/timeseries_3000.csv.gz +0 -0
  115. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/timeseries_8000.csv.gz +0 -0
  116. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/weibull_cloud_4.nc +0 -0
  117. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/weibull_grid.nc +0 -0
  118. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/weibull_sectors_12.csv +0 -0
  119. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/weibull_sectors_12.nc +0 -0
  120. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/wind_rose_bremen.csv +0 -0
  121. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/wind_rotation.nc +0 -0
  122. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/states/winds100.tab +0 -0
  123. {foxes-1.5.1 → foxes-1.5.2}/foxes/data/static_data.py +0 -0
  124. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/__init__.py +0 -0
  125. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/dask.py +0 -0
  126. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/default.py +0 -0
  127. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/futures.py +0 -0
  128. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/mpi.py +0 -0
  129. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/multiprocess.py +0 -0
  130. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/numpy.py +0 -0
  131. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/pool.py +0 -0
  132. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/ray.py +0 -0
  133. {foxes-1.5.1 → foxes-1.5.2}/foxes/engines/single.py +0 -0
  134. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/__init__.py +0 -0
  135. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/__init__.py +0 -0
  136. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/from_arrays.py +0 -0
  137. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/from_csv.py +0 -0
  138. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/from_df.py +0 -0
  139. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/from_file.py +0 -0
  140. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/from_json.py +0 -0
  141. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/from_random.py +0 -0
  142. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/grid.py +0 -0
  143. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/ring.py +0 -0
  144. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/farm_layout/row.py +0 -0
  145. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/__init__.py +0 -0
  146. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/create/__init__.py +0 -0
  147. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/create/random_abl_states.py +0 -0
  148. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/create/random_timeseries.py +0 -0
  149. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/dataset_states.py +0 -0
  150. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/field_data.py +0 -0
  151. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/multi_height.py +0 -0
  152. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/one_point_flow.py +0 -0
  153. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/point_cloud_data.py +0 -0
  154. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/scan.py +0 -0
  155. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/single.py +0 -0
  156. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/states_table.py +0 -0
  157. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/weibull_sectors.py +0 -0
  158. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/states/wrg_states.py +0 -0
  159. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/__init__.py +0 -0
  160. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/dict.py +0 -0
  161. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/windio/__init__.py +0 -0
  162. {foxes-1.5.1 → foxes-1.5.2}/foxes/input/yaml/yaml.py +0 -0
  163. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/__init__.py +0 -0
  164. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/axial_induction/__init__.py +0 -0
  165. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/axial_induction/betz.py +0 -0
  166. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/axial_induction/madsen.py +0 -0
  167. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/farm_controllers/basic.py +0 -0
  168. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/farm_models/__init__.py +0 -0
  169. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/farm_models/turbine2farm.py +0 -0
  170. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/ground_models/__init__.py +0 -0
  171. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/ground_models/no_ground.py +0 -0
  172. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/ground_models/wake_mirror.py +0 -0
  173. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/model_book.py +0 -0
  174. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/__init__.py +0 -0
  175. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/axiwake.py +0 -0
  176. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/centre.py +0 -0
  177. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/grid.py +0 -0
  178. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/rotor_points.py +0 -0
  179. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/segregated.py +0 -0
  180. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/partial_wakes/top_hat.py +0 -0
  181. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/point_models/__init__.py +0 -0
  182. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/point_models/set_uniform_data.py +0 -0
  183. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/point_models/tke2ti.py +0 -0
  184. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/point_models/ustar2ti.py +0 -0
  185. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/point_models/wake_deltas.py +0 -0
  186. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/rotor_models/__init__.py +0 -0
  187. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/rotor_models/centre.py +0 -0
  188. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/rotor_models/direct_infusion.py +0 -0
  189. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/rotor_models/grid.py +0 -0
  190. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/rotor_models/levels.py +0 -0
  191. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/__init__.py +0 -0
  192. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/calculator.py +0 -0
  193. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/kTI_model.py +0 -0
  194. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/lookup_table.py +0 -0
  195. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/power_mask.py +0 -0
  196. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/rotor_centre_calc.py +0 -0
  197. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/sector_management.py +0 -0
  198. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/set_farm_vars.py +0 -0
  199. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/table_factors.py +0 -0
  200. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/thrust2ct.py +0 -0
  201. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/yaw2yawm.py +0 -0
  202. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_models/yawm2yaw.py +0 -0
  203. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/CpCt_file.py +0 -0
  204. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/CpCt_from_two.py +0 -0
  205. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/PCt_file.py +0 -0
  206. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/PCt_from_two.py +0 -0
  207. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/TBL_file.py +0 -0
  208. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/__init__.py +0 -0
  209. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/calculator_type.py +0 -0
  210. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/lookup.py +0 -0
  211. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/null_type.py +0 -0
  212. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/wsrho2PCt_from_two.py +0 -0
  213. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/turbine_types/wsti2PCt_from_two.py +0 -0
  214. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/__init__.py +0 -0
  215. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/abl_log_neutral_ws.py +0 -0
  216. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/abl_log_stable_ws.py +0 -0
  217. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/abl_log_unstable_ws.py +0 -0
  218. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/abl_log_ws.py +0 -0
  219. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/data_profile.py +0 -0
  220. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/sheared_ws.py +0 -0
  221. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/vertical_profiles/uniform.py +0 -0
  222. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_deflections/__init__.py +0 -0
  223. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_deflections/bastankhah2016.py +0 -0
  224. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_deflections/jimenez.py +0 -0
  225. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_deflections/no_deflection.py +0 -0
  226. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/__init__.py +0 -0
  227. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/dynamic_wakes.py +0 -0
  228. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/farm_order.py +0 -0
  229. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/rotor_wd.py +0 -0
  230. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/seq_dynamic_wakes.py +0 -0
  231. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/streamlines.py +0 -0
  232. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_frames/timelines.py +0 -0
  233. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/__init__.py +0 -0
  234. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/axisymmetric.py +0 -0
  235. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/dist_sliced.py +0 -0
  236. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/gaussian.py +0 -0
  237. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/induction/__init__.py +0 -0
  238. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/induction/rankine_half_body.py +0 -0
  239. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/induction/rathmann.py +0 -0
  240. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/induction/vortex_sheet.py +0 -0
  241. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/ti/__init__.py +0 -0
  242. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/ti/iec_ti.py +0 -0
  243. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/top_hat.py +0 -0
  244. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/wind/__init__.py +0 -0
  245. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_models/wind/jensen.py +0 -0
  246. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/__init__.py +0 -0
  247. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ti_linear.py +0 -0
  248. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ti_max.py +0 -0
  249. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ti_pow.py +0 -0
  250. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ti_quadratic.py +0 -0
  251. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/wind_vector.py +0 -0
  252. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ws_linear.py +0 -0
  253. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ws_max.py +0 -0
  254. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ws_pow.py +0 -0
  255. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ws_product.py +0 -0
  256. {foxes-1.5.1 → foxes-1.5.2}/foxes/models/wake_superpositions/ws_quadratic.py +0 -0
  257. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/__init__.py +0 -0
  258. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/animation.py +0 -0
  259. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/calc_points.py +0 -0
  260. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/farm_layout.py +0 -0
  261. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/farm_results_eval.py +0 -0
  262. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/flow_plots_2d/__init__.py +0 -0
  263. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/flow_plots_2d/flow_plots.py +0 -0
  264. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/flow_plots_2d/get_fig.py +0 -0
  265. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/grids.py +0 -0
  266. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/output.py +0 -0
  267. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/plt.py +0 -0
  268. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/results_writer.py +0 -0
  269. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/rose_plot.py +0 -0
  270. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/rotor_point_plots.py +0 -0
  271. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/seq_plugins/__init__.py +0 -0
  272. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -0
  273. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -0
  274. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/slice_data.py +0 -0
  275. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/slices_data.py +0 -0
  276. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/state_turbine_table.py +0 -0
  277. {foxes-1.5.1 → foxes-1.5.2}/foxes/output/turbine_type_curves.py +0 -0
  278. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/__init__.py +0 -0
  279. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/abl/__init__.py +0 -0
  280. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/abl/neutral.py +0 -0
  281. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/abl/sheared.py +0 -0
  282. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/abl/stable.py +0 -0
  283. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/abl/unstable.py +0 -0
  284. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/cubic_roots.py +0 -0
  285. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/data_book.py +0 -0
  286. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/dev_utils.py +0 -0
  287. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/dict.py +0 -0
  288. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/exec_python.py +0 -0
  289. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/factory.py +0 -0
  290. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/__init__.py +0 -0
  291. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/area_geometry.py +0 -0
  292. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/circle.py +0 -0
  293. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/example_intersection.py +0 -0
  294. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/example_union.py +0 -0
  295. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/half_plane.py +0 -0
  296. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geom2d/polygon.py +0 -0
  297. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/geopandas_utils.py +0 -0
  298. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/load.py +0 -0
  299. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/pandas_utils.py +0 -0
  300. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/random_xy.py +0 -0
  301. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/regularize.py +0 -0
  302. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/subclasses.py +0 -0
  303. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/tab_files.py +0 -0
  304. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/two_circles.py +0 -0
  305. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/weibull.py +0 -0
  306. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/wind_dir.py +0 -0
  307. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/wrg_utils.py +0 -0
  308. {foxes-1.5.1 → foxes-1.5.2}/foxes/utils/xarray_utils.py +0 -0
  309. {foxes-1.5.1 → foxes-1.5.2}/foxes.egg-info/dependency_links.txt +0 -0
  310. {foxes-1.5.1 → foxes-1.5.2}/foxes.egg-info/entry_points.txt +0 -0
  311. {foxes-1.5.1 → foxes-1.5.2}/foxes.egg-info/top_level.txt +0 -0
  312. {foxes-1.5.1 → foxes-1.5.2}/setup.cfg +0 -0
  313. {foxes-1.5.1 → foxes-1.5.2}/tests/0_consistency/iterative/test_iterative.py +0 -0
  314. {foxes-1.5.1 → foxes-1.5.2}/tests/0_consistency/partial_wakes/test_partial_wakes.py +0 -0
  315. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +0 -0
  316. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +0 -0
  317. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -0
  318. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +0 -0
  319. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -0
  320. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -0
  321. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +0 -0
  322. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -0
  323. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +0 -0
  324. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -0
  325. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +0 -0
  326. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -0
  327. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +0 -0
  328. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -0
  329. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +0 -0
  330. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -0
  331. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -0
  332. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +0 -0
  333. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +0 -0
  334. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -0
  335. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -0
  336. {foxes-1.5.1 → foxes-1.5.2}/tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -0
  337. {foxes-1.5.1 → foxes-1.5.2}/tests/3_examples/test_examples.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: foxes
3
- Version: 1.5.1
3
+ Version: 1.5.2
4
4
  Summary: Farm Optimization and eXtended yield Evaluation Software
5
5
  Author: Jonas Schulte
6
6
  Maintainer: Jonas Schulte
@@ -47,17 +47,16 @@ Classifier: Development Status :: 4 - Beta
47
47
  Requires-Python: >=3.9
48
48
  Description-Content-Type: text/markdown
49
49
  License-File: LICENSE
50
- Requires-Dist: cycler>=0.10
51
- Requires-Dist: h5netcdf>=1.0
52
50
  Requires-Dist: matplotlib>=3.8
53
51
  Requires-Dist: numpy>=1.26
54
52
  Requires-Dist: pandas>=2.0
55
- Requires-Dist: pyyaml>=4.0
56
53
  Requires-Dist: scipy>=1.12
57
- Requires-Dist: tqdm>=2.0
58
54
  Requires-Dist: xarray>=2023
55
+ Requires-Dist: h5netcdf>=1.0
56
+ Requires-Dist: pyyaml>=4.0
57
+ Requires-Dist: tqdm>=2.0
59
58
  Provides-Extra: opt
60
- Requires-Dist: foxes-opt>=0.5; extra == "opt"
59
+ Requires-Dist: foxes-opt>=0.6; extra == "opt"
61
60
  Provides-Extra: dask
62
61
  Requires-Dist: dask>=2022.0; extra == "dask"
63
62
  Requires-Dist: distributed>=2022.0; extra == "dask"
@@ -167,7 +167,13 @@ def _read_blockage(blockage_model, induction, algo_dict, mbook, verbosity):
167
167
  print(" Name:", wname)
168
168
  print(" Contents:", [k for k in blockage_model.keys()])
169
169
  if wname not in ["None", "none"]:
170
- indc_dict = Dict(wmodel_type=indc_def_map[wname], induction=induction)
170
+ kys = list(blockage_model.keys())
171
+ for k in kys:
172
+ if len(k) > 3 and k[:3] == "ss_":
173
+ blockage_model[k[3:]] = blockage_model.pop_item(k)
174
+ indc_dict = Dict(
175
+ wmodel_type=indc_def_map[wname], induction=induction, **blockage_model
176
+ )
171
177
  mbook.wake_models[wname] = WakeModel.new(**indc_dict)
172
178
  if verbosity > 2:
173
179
  print(f" Created wake model '{wname}':")
@@ -378,7 +384,7 @@ def read_attributes(wio_attrs, idict, mbook, verbosity=1):
378
384
  print(" Reading flow_model")
379
385
  print(" Name:", fmname)
380
386
  print(" Contents:", [k for k in flow_model.keys()])
381
- if fmname != "foxes":
387
+ if verbosity > 0 and fmname != "foxes":
382
388
  print(f"Running flow model 'foxes', overruling original choice '{fmname}'")
383
389
 
384
390
  # read analysis:
@@ -3,7 +3,9 @@ import pandas as pd
3
3
 
4
4
  from foxes.utils import Dict
5
5
  from foxes.core import Turbine, TurbineType, WindFarm
6
+ from foxes.models.farm_controllers import BasicFarmController, OpFlagController
6
7
  import foxes.variables as FV
8
+ import foxes.constants as FC
7
9
 
8
10
 
9
11
  def read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity):
@@ -204,6 +206,22 @@ def read_farm(wio_dict, mbook, verbosity):
204
206
  ws_exp_P = 1
205
207
  ws_exp_ct = 1
206
208
 
209
+ # create farm controller:
210
+ if FV.OPERATING in wio_farm:
211
+ op_dims, operating = wio_farm.pop_item(FV.OPERATING)
212
+ assert (
213
+ len(op_dims) == 2
214
+ and op_dims[1] == FC.TURBINE
215
+ and op_dims[0] in [FC.STATE, FC.TIME]
216
+ ), f"Expecting operating field to have dims (state, turbine), got {op_dims}"
217
+ mbook.farm_controllers["farm_cntrl"] = OpFlagController(operating)
218
+ else:
219
+ mbook.farm_controllers["farm_cntrl"] = BasicFarmController()
220
+ if verbosity > 1:
221
+ print(
222
+ f" Farm controller type: {type(mbook.farm_controllers['farm_cntrl']).__name__}"
223
+ )
224
+
207
225
  # read turbine type:
208
226
  ttypes = read_turbine_types(wio_farm, mbook, ws_exp_P, ws_exp_ct, verbosity)
209
227
 
@@ -211,6 +229,8 @@ def read_farm(wio_dict, mbook, verbosity):
211
229
  farm = WindFarm()
212
230
  wfarm = wio_farm["layouts"]
213
231
  if isinstance(wfarm, dict):
232
+ if "coordinates" in wfarm:
233
+ wfarm = {"0": wfarm}
214
234
  layouts = Dict(wfarm, _name=wio_farm.name + ".layouts")
215
235
  else:
216
236
  layouts = {str(i): lf for i, lf in enumerate(wfarm)}
@@ -24,6 +24,7 @@ wio2foxes = {
24
24
  "reference_height": FV.H,
25
25
  "weibull_a": FV.WEIBULL_A,
26
26
  "weibull_k": FV.WEIBULL_k,
27
+ "operating": FV.OPERATING,
27
28
  }
28
29
 
29
30
  """ Mapping from foxes to windio variables
@@ -137,6 +138,7 @@ def read_wind_resource_field(
137
138
  """
138
139
  if name in [
139
140
  "potential_temperature",
141
+ "real_temperature",
140
142
  "friction_velocity",
141
143
  "k",
142
144
  "epsilon",
@@ -180,6 +182,7 @@ def read_wind_resource_field(
180
182
  "reference_height",
181
183
  "weibull_a",
182
184
  "weibull_k",
185
+ "operating",
183
186
  ] and _read_multi_dimensional_data(name, wio_data, fields, dims):
184
187
  return True
185
188
 
@@ -110,14 +110,28 @@ def _read_flow_field(wio_outs, olist, algo, states_isel, verbosity):
110
110
  assert len(xb) == 2, f"Expecting two entries for x_bounds, got {xb}"
111
111
  yb = z_planes.pop_item("y_bounds")
112
112
  assert len(yb) == 2, f"Expecting two entries for y_bounds, got {yb}"
113
- dx = z_planes.pop_item("dx")
114
- dy = z_planes.pop_item("dy")
115
- nx = max(int((xb[1] - xb[0]) / dx), 1) + 1
116
- if (xb[1] - xb[0]) / (nx - 1) > dx:
117
- nx += 1
118
- ny = max(int((yb[1] - yb[0]) / dy), 1) + 1
119
- if (yb[1] - yb[0]) / (ny - 1) > dy:
120
- ny += 1
113
+ if "dx" in z_planes or "dy" in z_planes:
114
+ assert "dx" in z_planes and "dy" in z_planes, (
115
+ f"Expecting both 'dx' and 'dy' in z_planes, got {list(z_planes.keys())}"
116
+ )
117
+ dx = z_planes.pop_item("dx")
118
+ dy = z_planes.pop_item("dy")
119
+ nx = max(int((xb[1] - xb[0]) / dx), 1) + 1
120
+ if (xb[1] - xb[0]) / (nx - 1) > dx:
121
+ nx += 1
122
+ ny = max(int((yb[1] - yb[0]) / dy), 1) + 1
123
+ if (yb[1] - yb[0]) / (ny - 1) > dy:
124
+ ny += 1
125
+ elif "Nx" in z_planes or "Ny" in z_planes:
126
+ assert "Nx" in z_planes and "Ny" in z_planes, (
127
+ f"Expecting both 'Nx' and 'Ny' in z_planes, got {list(z_planes.keys())}"
128
+ )
129
+ nx = z_planes.pop_item("Nx")
130
+ ny = z_planes.pop_item("Ny")
131
+ else:
132
+ raise KeyError(
133
+ f"Expecting either 'dx' and 'dy' or 'Nx' and 'Ny' in z_planes, got {list(z_planes.keys())}"
134
+ )
121
135
  z_list = np.asarray(z_list)
122
136
  if verbosity > 2:
123
137
  print(" x_bounds :", xb)
@@ -186,11 +200,10 @@ def read_outputs(wio_outs, idict, algo, verbosity=1):
186
200
 
187
201
  # read subset:
188
202
  run_configuration = wio_outs.pop_item("run_configuration", {})
203
+ states_isel = None
189
204
  if "times_run" in run_configuration:
190
205
  times_run = run_configuration.pop_item("times_run")
191
- if times_run.get_item("all_occurences"):
192
- states_isel = None
193
- else:
206
+ if not times_run.get_item("all_occurences"):
194
207
  states_isel = times_run.get_item("subset")
195
208
  elif "wind_speeds_run" in run_configuration:
196
209
  wind_speeds_run = run_configuration.get_item("wind_speeds_run")
@@ -203,7 +216,6 @@ def read_outputs(wio_outs, idict, algo, verbosity=1):
203
216
  raise NotImplementedError(
204
217
  f"Wind speed and direction subsets are not yet supported, got {directions_run.name} {directions_run}"
205
218
  )
206
- states_isel = None
207
219
 
208
220
  # read turbine_outputs:
209
221
  _read_turbine_outputs(wio_outs, olist, algo, states_isel, verbosity)
@@ -11,6 +11,14 @@ import foxes.constants as FC
11
11
  from .read_fields import read_wind_resource_field
12
12
 
13
13
 
14
+ default_values = {
15
+ FV.WS: 8.0,
16
+ FV.WD: 270.0,
17
+ FV.TI: 0.1,
18
+ FV.RHO: 1.225,
19
+ }
20
+
21
+
14
22
  def _get_profiles(coords, fields, dims, ovars, fixval, verbosity):
15
23
  """Read ABL profiles information
16
24
  :group: input.yaml.windio
@@ -22,6 +30,8 @@ def _get_profiles(coords, fields, dims, ovars, fixval, verbosity):
22
30
  print(
23
31
  f"Ignoring '{FV.Z0}', since no reference_height found. No ABL profile activated."
24
32
  )
33
+ fields.pop(FV.Z0)
34
+ dims.pop(FV.Z0)
25
35
  elif FV.MOL in fields:
26
36
  ovars.append(FV.MOL)
27
37
  fixval[FV.H] = fields[FV.H]
@@ -56,7 +66,7 @@ def _get_SingleStateStates(
56
66
 
57
67
  smap = {FV.WS: "ws", FV.WD: "wd", FV.TI: "ti", FV.RHO: "rho"}
58
68
 
59
- data = {smap[v]: d for v, d in fixval.items()}
69
+ data = {smap[v]: fixval.get(v, default_values[v]) for v in ovars}
60
70
  for v, d in coords.items():
61
71
  if v in smap:
62
72
  data[smap[v]] = d
@@ -91,7 +101,7 @@ def _get_Timeseries(
91
101
  print(" selecting class 'Timeseries'")
92
102
 
93
103
  data = {}
94
- fix = {}
104
+ fix = {v: fixval.get(v, default_values[v]) for v in ovars if v not in fields}
95
105
  for v, d in fields.items():
96
106
  if dims[v] == (FC.TIME,):
97
107
  data[v] = d
@@ -99,7 +109,6 @@ def _get_Timeseries(
99
109
  fix[v] = d
100
110
  elif verbosity > 2:
101
111
  print(f" ignoring field '{v}' with dims {dims[v]}")
102
- fix.update({v: d for v, d in fixval.items() if v not in data})
103
112
 
104
113
  sdata = pd.DataFrame(index=coords[FC.TIME], data=data)
105
114
  sdata.index.name = FC.TIME
@@ -132,7 +141,7 @@ def _get_MultiHeightNCTimeseries(
132
141
  )
133
142
 
134
143
  data = {}
135
- fix = {}
144
+ fix = {v: fixval.get(v, default_values[v]) for v in ovars if v not in fields}
136
145
  for v, d in fields.items():
137
146
  if dims[v] == (FC.TIME, FV.H):
138
147
  data[v] = ((FC.TIME, FV.H), d)
@@ -142,7 +151,6 @@ def _get_MultiHeightNCTimeseries(
142
151
  fix[v] = d
143
152
  elif verbosity > 2:
144
153
  print(f" ignoring field '{v}' with dims {dims[v]}")
145
- fix.update({v: d for v, d in fixval.items() if v not in data})
146
154
 
147
155
  sdata = Dataset(coords=coords, data_vars=data)
148
156
  states_dict.update(
@@ -153,6 +161,7 @@ def _get_MultiHeightNCTimeseries(
153
161
  data_source=sdata,
154
162
  output_vars=ovars,
155
163
  fixed_vars=fix,
164
+ bounds_error=False,
156
165
  )
157
166
  )
158
167
  return True
@@ -177,7 +186,7 @@ def _get_WeibullSectors(
177
186
  print(" selecting class 'WeibullSectors'")
178
187
 
179
188
  data = {}
180
- fix = {}
189
+ fix = {v: fixval.get(v, default_values[v]) for v in ovars if v not in fields}
181
190
  c = dims[FV.WEIBULL_A][0]
182
191
  for v, d in fields.items():
183
192
  if dims[v] == (c,):
@@ -186,7 +195,6 @@ def _get_WeibullSectors(
186
195
  fix[v] = d
187
196
  elif verbosity > 2:
188
197
  print(f" ignoring field '{v}' with dims {dims[v]}")
189
- fix.update({v: d for v, d in fixval.items() if v not in data})
190
198
 
191
199
  if FV.WD in coords:
192
200
  data[FV.WD] = coords[FV.WD]
@@ -230,13 +238,12 @@ def _get_WeibullPointCloud(
230
238
  print(" selecting class 'WeibullPointCloud'")
231
239
 
232
240
  data = {}
233
- fix = {}
241
+ fix = {v: fixval.get(v, default_values[v]) for v in ovars if v not in fields}
234
242
  for v, d in fields.items():
235
243
  if len(dims[v]) == 0:
236
244
  fix[v] = d
237
245
  elif v not in fixval:
238
246
  data[v] = (dims[v], d)
239
- fix.update({v: d for v, d in fixval.items() if v not in data})
240
247
 
241
248
  sdata = Dataset(
242
249
  coords=coords,
@@ -282,13 +289,12 @@ def _get_WeibullField(
282
289
  print(" selecting class 'WeibullField'")
283
290
 
284
291
  data = {}
285
- fix = {}
292
+ fix = {v: fixval.get(v, default_values[v]) for v in ovars if v not in fields}
286
293
  for v, d in fields.items():
287
294
  if len(dims[v]) == 0:
288
295
  fix[v] = d
289
296
  elif v not in fixval:
290
297
  data[v] = (dims[v], d)
291
- fix.update({v: d for v, d in fixval.items() if v not in data})
292
298
 
293
299
  sdata = Dataset(
294
300
  coords=coords,
@@ -342,7 +348,7 @@ def get_states(coords, fields, dims, verbosity=1):
342
348
  print(" Creating states")
343
349
 
344
350
  ovars = [FV.WS, FV.WD, FV.TI, FV.RHO]
345
- fixval = {FV.RHO: 1.225}
351
+ fixval = {}
346
352
  profiles = _get_profiles(coords, fields, dims, ovars, fixval, verbosity)
347
353
 
348
354
  states_dict = {}
@@ -421,6 +427,21 @@ def read_site(wio_dict, verbosity=1):
421
427
  dims = Dict(_name="dims")
422
428
  for n, d in wind_resource.items():
423
429
  read_wind_resource_field(n, d, coords, fields, dims, verbosity)
430
+
431
+ # special case: operating field
432
+ if FV.OPERATING in fields:
433
+ wio_dict["wind_farm"][FV.OPERATING] = (
434
+ dims.pop(FV.OPERATING),
435
+ fields.pop(FV.OPERATING),
436
+ )
437
+ if FC.TURBINE in coords:
438
+ if not any([FC.TURBINE in dms for dms in dims.values()]):
439
+ if verbosity > 2:
440
+ print(
441
+ f" Removing coordinate '{FC.TURBINE}', since only relevant for operating flag"
442
+ )
443
+ coords.pop(FC.TURBINE)
444
+
424
445
  if verbosity > 2:
425
446
  print(" Coords:")
426
447
  for c, d in coords.items():
@@ -55,6 +55,7 @@ def read_windio(wio_dict, verbosity=1):
55
55
  algorithm=Dict(
56
56
  algo_type="Downwind",
57
57
  wake_models=[],
58
+ farm_controller="farm_cntrl",
58
59
  _name="wio2fxs.algorithm",
59
60
  verbosity=verbosity - 3,
60
61
  ),
@@ -3,3 +3,4 @@ Farm controller models.
3
3
  """
4
4
 
5
5
  from .basic import BasicFarmController as BasicFarmController
6
+ from .op_flag import OpFlagController as OpFlagController
@@ -0,0 +1,196 @@
1
+ import numpy as np
2
+ from xarray import open_dataset, Dataset
3
+
4
+ from foxes.core import FarmController
5
+ import foxes.constants as FC
6
+ import foxes.variables as FV
7
+
8
+
9
+ class OpFlagController(FarmController):
10
+ """
11
+ A basic controller with a flag for
12
+ turbine operation at each state.
13
+
14
+ Parameters
15
+ ----------
16
+ non_op_values: dict
17
+ The non-operational values for variables,
18
+ keys: variable str, values: float
19
+ var2ncvar: dict
20
+ The mapping of variable names to NetCDF variable names,
21
+ only needed if data_source is a path to a NetCDF file
22
+
23
+ :group: models.farm_controllers
24
+
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ data_source,
30
+ non_op_values=None,
31
+ var2ncvar={},
32
+ **kwargs,
33
+ ):
34
+ """
35
+ Constructor.
36
+
37
+ Parameters
38
+ ----------
39
+ data_source: numpy.ndarray or str
40
+ The operating flag data, shape: (n_states, n_turbines),
41
+ or path to a NetCDF file
42
+ non_op_values: dict, optional
43
+ The non-operational values for variables,
44
+ keys: variable str, values: float
45
+ var2ncvar: dict
46
+ The mapping of variable names to NetCDF variable names,
47
+ only needed if data_source is a path to a NetCDF file
48
+ kwargs: dict, optional
49
+ Additional keyword arguments for the
50
+ base class constructor
51
+
52
+ """
53
+ super().__init__(**kwargs)
54
+ self.data_source = data_source
55
+ self.var2ncvar = var2ncvar
56
+
57
+ self.non_op_values = {
58
+ FV.P: 0.0,
59
+ FV.CT: 0.0,
60
+ }
61
+ if non_op_values is not None:
62
+ self.non_op_values.update(non_op_values)
63
+
64
+ self._op_flags = None
65
+
66
+ def output_farm_vars(self, algo):
67
+ """
68
+ The variables which are being modified by the model.
69
+
70
+ Parameters
71
+ ----------
72
+ algo: foxes.core.Algorithm
73
+ The calculation algorithm
74
+
75
+ Returns
76
+ -------
77
+ output_vars: list of str
78
+ The output variable names
79
+
80
+ """
81
+ vrs = set(super().output_farm_vars(algo))
82
+ vrs.update([FV.OPERATING])
83
+ return list(vrs)
84
+
85
+ def load_data(self, algo, verbosity=0):
86
+ """
87
+ Load and/or create all model data that is subject to chunking.
88
+
89
+ Such data should not be stored under self, for memory reasons. The
90
+ data returned here will automatically be chunked and then provided
91
+ as part of the mdata object during calculations.
92
+
93
+ Parameters
94
+ ----------
95
+ algo: foxes.core.Algorithm
96
+ The calculation algorithm
97
+ verbosity: int
98
+ The verbosity level, 0 = silent
99
+
100
+ Returns
101
+ -------
102
+ idata: dict
103
+ The dict has exactly two entries: `data_vars`,
104
+ a dict with entries `name_str -> (dim_tuple, data_ndarray)`;
105
+ and `coords`, a dict with entries `dim_name_str -> dim_array`
106
+
107
+ """
108
+
109
+ idata = super().load_data(algo, verbosity)
110
+
111
+ if isinstance(self.data_source, np.ndarray):
112
+ self._op_flags = self.data_source
113
+
114
+ elif isinstance(self.data_source, Dataset):
115
+ cop = self.var2ncvar.get(FV.OPERATING, FV.OPERATING)
116
+ self._op_flags = self.data_source[cop].to_numpy()
117
+
118
+ else:
119
+ if verbosity > 0:
120
+ print(f"OpFlagController: Reading data from {self.data_source}")
121
+ ds = open_dataset(self.data_source)
122
+ cop = self.var2ncvar.get(FV.OPERATING, FV.OPERATING)
123
+ self._op_flags = ds[cop].to_numpy()
124
+ del ds
125
+
126
+ assert self._op_flags.shape == (algo.n_states, algo.n_turbines), (
127
+ f"OpFlagController data shape {self._op_flags.shape} does not match "
128
+ f"(n_states, n_turbines)=({algo.n_states}, {algo.n_turbines})"
129
+ )
130
+ op_flags = self._op_flags.astype(bool)
131
+
132
+ off = np.where(~op_flags)
133
+ tmsels = idata["data_vars"][FC.TMODEL_SELS][1]
134
+ tmsels[off[0], off[1], :] = False
135
+ self._tmall = [np.all(t) for t in tmsels]
136
+
137
+ idata["data_vars"][FC.TMODEL_SELS] = (
138
+ (FC.STATE, FC.TURBINE, FC.TMODELS),
139
+ tmsels,
140
+ )
141
+ idata["data_vars"][FV.OPERATING] = (
142
+ (FC.STATE, FC.TURBINE),
143
+ op_flags,
144
+ )
145
+
146
+ return idata
147
+
148
+ def calculate(self, algo, mdata, fdata, pre_rotor, downwind_index=None):
149
+ """
150
+ The main model calculation.
151
+
152
+ This function is executed on a single chunk of data,
153
+ all computations should be based on numpy arrays.
154
+
155
+ Parameters
156
+ ----------
157
+ algo: foxes.core.Algorithm
158
+ The calculation algorithm
159
+ mdata: foxes.core.MData
160
+ The model data
161
+ fdata: foxes.core.FData
162
+ The farm data
163
+ pre_rotor: bool
164
+ Flag for running pre-rotor or post-rotor
165
+ models
166
+ downwind_index: int, optional
167
+ The index in the downwind order
168
+
169
+ Returns
170
+ -------
171
+ results: dict
172
+ The resulting data, keys: output variable str.
173
+ Values: numpy.ndarray with shape (n_states, n_turbines)
174
+
175
+ """
176
+ self.ensure_output_vars(algo, fdata)
177
+
178
+ # compute data for all operating turbines:
179
+ op = mdata[FV.OPERATING].astype(bool)
180
+ fdata[FV.OPERATING] = op
181
+ results = super().calculate(algo, mdata, fdata, pre_rotor, downwind_index)
182
+ results[FV.OPERATING] = fdata[FV.OPERATING]
183
+
184
+ # set non-operating values:
185
+ if downwind_index is None:
186
+ off = np.where(~op)
187
+ for v in self.output_farm_vars(algo):
188
+ if v != FV.OPERATING:
189
+ fdata[v][off[0], off[1]] = self.non_op_values.get(v, np.nan)
190
+ else:
191
+ off = np.where(~op[:, downwind_index])
192
+ for v in self.output_farm_vars(algo):
193
+ if v != FV.OPERATING:
194
+ fdata[v][off[0], downwind_index] = self.non_op_values.get(v, np.nan)
195
+
196
+ return results
@@ -27,6 +27,12 @@ class SelfSimilar(TurbineInductionModel):
27
27
 
28
28
  Attributes
29
29
  ----------
30
+ alpha: float
31
+ The alpha parameter
32
+ beta: float
33
+ The beta parameter
34
+ gamma: float
35
+ The gamma parameter
30
36
  pre_rotor_only: bool
31
37
  Calculate only the pre-rotor region
32
38
  induction: foxes.core.AxialInductionModel or str
@@ -40,6 +46,8 @@ class SelfSimilar(TurbineInductionModel):
40
46
  self,
41
47
  superposition="ws_linear",
42
48
  induction="Madsen",
49
+ alpha=8 / 9,
50
+ beta=np.sqrt(2),
43
51
  gamma=1.1,
44
52
  pre_rotor_only=False,
45
53
  ):
@@ -52,8 +60,12 @@ class SelfSimilar(TurbineInductionModel):
52
60
  The wind speed superposition.
53
61
  induction: foxes.core.AxialInductionModel or str
54
62
  The induction model
55
- gamma: float, default=1.1
56
- The parameter that multiplies Ct in the ct2a calculation
63
+ alpha: float
64
+ The alpha parameter
65
+ beta: float
66
+ The beta parameter
67
+ gamma: float
68
+ The gamma parameter
57
69
  pre_rotor_only: bool
58
70
  Calculate only the pre-rotor region
59
71
 
@@ -61,6 +73,8 @@ class SelfSimilar(TurbineInductionModel):
61
73
  super().__init__(wind_superposition=superposition)
62
74
  self.induction = induction
63
75
  self.pre_rotor_only = pre_rotor_only
76
+ self.alpha = alpha
77
+ self.beta = beta
64
78
  self.gamma = gamma
65
79
 
66
80
  def __repr__(self):
@@ -163,9 +177,13 @@ class SelfSimilar(TurbineInductionModel):
163
177
  """Helper function: using eqn 13 from [2]"""
164
178
  return np.sqrt(0.587 * (1.32 + x_R**2))
165
179
 
166
- def _rad_fn(self, x_R, r_R, beta=np.sqrt(2), alpha=8 / 9):
180
+ def _rad_fn(self, x_R, r_R):
167
181
  """Helper function: define radial shape function (eqn 12 from [1])"""
168
- return (1 / np.cosh(beta * (r_R) / self._r_half(x_R))) ** alpha # * (x_R < 0)
182
+ with np.errstate(over="ignore"):
183
+ result = (
184
+ 1 / np.cosh(self.beta * (r_R) / self._r_half(x_R))
185
+ ) ** self.alpha # * (x_R < 0)
186
+ return result
169
187
 
170
188
  def contribute(
171
189
  self,
@@ -25,7 +25,7 @@ class SelfSimilar2020(SelfSimilar):
25
25
 
26
26
  """
27
27
 
28
- def _a0(self, ct, x_R, gamma=1.1):
28
+ def _a0(self, ct, x_R):
29
29
  """Helper function: define a0 with gamma factor, eqn 8 from [2]"""
30
30
 
31
31
  x_new = np.minimum(np.maximum(-1 * np.abs(x_R), -6), -1)
@@ -218,7 +218,7 @@ class CrespoHernandezTIWake(TopHatWakeModel):
218
218
 
219
219
  # calculate:
220
220
  a = self.induction.ct2a(ct)
221
- beta = (1 - a) / (1 - 2 * a)
221
+ beta = np.maximum((1 - a) / (1 - 2 * a), 0)
222
222
  radius = 2 * (k * x + self.sbeta_factor * np.sqrt(beta) * D)
223
223
 
224
224
  return radius
@@ -194,7 +194,7 @@ class Bastankhah2014(GaussianWakeModel):
194
194
  # calculate sigma:
195
195
  # beta = 0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct)
196
196
  a = self.induction.ct2a(ct)
197
- beta = (1 - a) / (1 - 2 * a)
197
+ beta = np.maximum((1 - a) / (1 - 2 * a), 0)
198
198
  sigma = k * x + self.sbeta_factor * np.sqrt(beta) * D
199
199
  del beta, a
200
200
 
@@ -423,7 +423,7 @@ class Bastankhah2016(DistSlicedWakeModel):
423
423
  self,
424
424
  superposition,
425
425
  alpha=0.58,
426
- beta=0.07,
426
+ beta=0.077,
427
427
  induction="Madsen",
428
428
  **wake_k,
429
429
  ):
@@ -220,7 +220,7 @@ class TurbOParkWake(GaussianWakeModel):
220
220
  # calculate sigma:
221
221
  # beta = np.sqrt(0.5 * (1 + np.sqrt(1.0 - ct)) / np.sqrt(1.0 - ct))
222
222
  a = self.induction.ct2a(ct)
223
- beta = (1 - a) / (1 - 2 * a)
223
+ beta = np.maximum((1 - a) / (1 - 2 * a), 0)
224
224
  epsilon = self.sbeta_factor * np.sqrt(beta)
225
225
  del a, beta
226
226