rafmudaf-floris 4.6.4.post1.dev9__tar.gz → 4.6.4.post1.dev21__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.
Files changed (305) hide show
  1. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/PKG-INFO +1 -1
  2. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/gradient_layout_optimization.py +10 -7
  3. rafmudaf_floris-4.6.4.post1.dev21/examples/gradient_yaw_optimization.py +562 -0
  4. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/cpp_core.py +143 -79
  5. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/default_inputs.yaml +3 -3
  6. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/floris_model.py +8 -7
  7. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/pyproject.toml +1 -0
  8. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/rafmudaf_floris.egg-info/PKG-INFO +1 -1
  9. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/rafmudaf_floris.egg-info/SOURCES.txt +1 -0
  10. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.codecov.yml +0 -0
  11. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  12. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  13. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  14. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  15. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/dependabot.yml +0 -0
  16. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/workflows/check-working-examples.yaml +0 -0
  17. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/workflows/continuous-integration-workflow.yaml +0 -0
  18. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/workflows/cpp-backend-tests.yml +0 -0
  19. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/workflows/deploy-pages.yaml +0 -0
  20. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/workflows/python-publish.yml +0 -0
  21. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.github/workflows/quality-metrics-workflow.yaml +0 -0
  22. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.gitignore +0 -0
  23. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/.pre-commit-config.yaml +0 -0
  24. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/CONTRIBUTING.md +0 -0
  25. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/LICENSE.txt +0 -0
  26. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/README.md +0 -0
  27. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/benchmarks/bench.py +0 -0
  28. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/.nojekyll +0 -0
  29. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/_config.yml +0 -0
  30. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/_toc.yml +0 -0
  31. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/advanced_concepts.ipynb +0 -0
  32. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/api_docs.md +0 -0
  33. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/architecture.md +0 -0
  34. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/bibliography.md +0 -0
  35. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/cc.yaml +0 -0
  36. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/code_quality.ipynb +0 -0
  37. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/dev_guide.md +0 -0
  38. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/docs_image.png +0 -0
  39. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/empirical_gauss_model.md +0 -0
  40. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/floating_wind_turbine.md +0 -0
  41. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/floris_models.ipynb +0 -0
  42. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/gch.yaml +0 -0
  43. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/heterogeneous_map.ipynb +0 -0
  44. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/index.md +0 -0
  45. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/input_reference_main.md +0 -0
  46. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/input_reference_turbine.md +0 -0
  47. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/installation.md +0 -0
  48. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/intro_concepts.ipynb +0 -0
  49. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/jensen.yaml +0 -0
  50. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/layout_optimization.md +0 -0
  51. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/multidimensional_wind_turbine.ipynb +0 -0
  52. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/nrel_5MW.yaml +0 -0
  53. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/operation_models_user.ipynb +0 -0
  54. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/plot_complex_docs.png +0 -0
  55. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/powerthrust_helix.png +0 -0
  56. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/references.bib +0 -0
  57. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/turbine_library.md +0 -0
  58. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/turbine_models.ipynb +0 -0
  59. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/v3_to_v4.md +0 -0
  60. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/wake_models.ipynb +0 -0
  61. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/docs/wind_data_user.ipynb +0 -0
  62. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/001_opening_floris_computing_power.py +0 -0
  63. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/002_visualizations.py +0 -0
  64. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/003_wind_data_objects.py +0 -0
  65. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/004_set.py +0 -0
  66. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/005_getting_power.py +0 -0
  67. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/006_get_farm_aep.py +0 -0
  68. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/007_sweeping_variables.py +0 -0
  69. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/008_uncertain_models.py +0 -0
  70. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/009_parallel_models.py +0 -0
  71. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/010_compare_farm_power_with_neighbor.py +0 -0
  72. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/_convert_examples_to_notebooks.py +0 -0
  73. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/001_opt_yaw_single_ws.py +0 -0
  74. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/002_opt_yaw_single_ws_uncertain.py +0 -0
  75. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/003_opt_yaw_multiple_ws.py +0 -0
  76. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/004_optimize_yaw_aep.py +0 -0
  77. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/005_optimize_yaw_aep_parallel.py +0 -0
  78. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/006_compare_yaw_optimizers.py +0 -0
  79. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/007_optimize_yaw_with_neighbor_farms.py +0 -0
  80. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_optimization/008_optimize_yaw_with_disabled_turbines.py +0 -0
  81. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_types/001_derating_control.py +0 -0
  82. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_types/002_disable_turbines.py +0 -0
  83. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_types/003_setting_yaw_and_disabling.py +0 -0
  84. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_types/004_helix_active_wake_mixing.py +0 -0
  85. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_control_types/005_peak_shaving.py +0 -0
  86. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_emgauss/001_empirical_gauss_velocity_deficit_parameters.py +0 -0
  87. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_emgauss/002_empirical_gauss_deflection_parameters.py +0 -0
  88. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_floating/001_floating_turbine_models.py +0 -0
  89. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_floating/002_floating_vs_fixedbottom_farm.py +0 -0
  90. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_floating/003_tilt_driven_vertical_wake_deflection.py +0 -0
  91. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_get_flow/001_extract_wind_speed_at_turbines.py +0 -0
  92. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_get_flow/002_extract_wind_speed_at_points.py +0 -0
  93. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_get_flow/003_extract_turbulence_intensity_at_points.py +0 -0
  94. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_get_flow/004_plot_velocity_deficit_profiles.py +0 -0
  95. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_heterogeneous/001_heterogeneous_inflow_single.py +0 -0
  96. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_heterogeneous/002_heterogeneous_using_wind_data.py +0 -0
  97. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_heterogeneous/003_heterogeneous_speedup_by_wd_and_ws.py +0 -0
  98. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_heterogeneous/004_heterogeneous_2d_and_3d.py +0 -0
  99. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_layout_optimization/001_optimize_layout.py +0 -0
  100. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_layout_optimization/002_optimize_layout_with_heterogeneity.py +0 -0
  101. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_layout_optimization/003_genetic_random_search.py +0 -0
  102. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_layout_optimization/004_generate_gridded_layout.py +0 -0
  103. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_layout_optimization/005_layout_optimization_complex_boundary.py +0 -0
  104. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_load_optimization/001_lti_and_voc.py +0 -0
  105. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_load_optimization/002_row_opt_example.py +0 -0
  106. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_multidim/001_multi_dimensional_cp_ct.py +0 -0
  107. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_multidim/002_multi_dimensional_cp_ct_2Hs.py +0 -0
  108. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_multidim/003_multi_dimensional_cp_ct_TI.py +0 -0
  109. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_operation_models/001_compare_yaw_loss.py +0 -0
  110. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_turbine/001_reference_turbines.py +0 -0
  111. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_turbine/002_multiple_turbine_types.py +0 -0
  112. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_turbine/003_specify_turbine_power_curve.py +0 -0
  113. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_turbopark/001_compare_turbopark_implementations.py +0 -0
  114. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_turbopark/comparison_data/Rowpark_Orsted.csv +0 -0
  115. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_turbopark/comparison_data/WindDirection_Sweep_Orsted.csv +0 -0
  116. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_uncertain/001_uncertain_model_params.py +0 -0
  117. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_uncertain/002_approx_floris_model.py +0 -0
  118. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_uncertain/003_uncertain_model_with_parallelization.py +0 -0
  119. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_visualizations/001_layout_visualizations.py +0 -0
  120. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_visualizations/002_visualize_y_cut_plane.py +0 -0
  121. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_visualizations/003_visualize_cross_plane.py +0 -0
  122. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_visualizations/004_visualize_rotor_values.py +0 -0
  123. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_visualizations/005_visualize_flow_by_sweeping_turbines.py +0 -0
  124. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_data/001_wind_data_comparisons.py +0 -0
  125. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_data/002_generate_ti.py +0 -0
  126. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_data/003_generate_value.py +0 -0
  127. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_resource_grid/000_generate_example_wrg.py +0 -0
  128. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_resource_grid/001_wind_rose_wrg.py +0 -0
  129. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_resource_grid/002_set_floris_with_wrg.py +0 -0
  130. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_resource_grid/003_wrg_compar_layout_optimization.py +0 -0
  131. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/examples_wind_resource_grid/wrg_example.wrg +0 -0
  132. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/cc.yaml +0 -0
  133. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/emgauss.yaml +0 -0
  134. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/emgauss_helix.yaml +0 -0
  135. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/gch.yaml +0 -0
  136. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/gch_heterogeneous_inflow.yaml +0 -0
  137. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/gch_multi_dim_cp_ct.yaml +0 -0
  138. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/gch_multi_dim_cp_ct_TI.yaml +0 -0
  139. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/gch_multiple_turbine_types.yaml +0 -0
  140. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/jensen.yaml +0 -0
  141. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/turbine_files/iea_15MW_multi_dim_TI.csv +0 -0
  142. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/turbine_files/iea_15MW_multi_dim_TI.yaml +0 -0
  143. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/turbopark.yaml +0 -0
  144. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/turbopark_cubature.yaml +0 -0
  145. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/turboparkgauss.yaml +0 -0
  146. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/turboparkgauss_cubature.yaml +0 -0
  147. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs/wind_rose.csv +0 -0
  148. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/emgauss_fixed.yaml +0 -0
  149. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/emgauss_floating.yaml +0 -0
  150. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/emgauss_floating_fixedtilt15.yaml +0 -0
  151. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/emgauss_floating_fixedtilt5.yaml +0 -0
  152. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/gch_fixed.yaml +0 -0
  153. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/gch_floating.yaml +0 -0
  154. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/gch_floating_defined_floating.yaml +0 -0
  155. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/turbine_files/nrel_5MW_fixed.yaml +0 -0
  156. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/turbine_files/nrel_5MW_floating.yaml +0 -0
  157. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/turbine_files/nrel_5MW_floating_defined_floating.yaml +0 -0
  158. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/turbine_files/nrel_5MW_floating_fixedtilt15.yaml +0 -0
  159. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/examples/inputs_floating/turbine_files/nrel_5MW_floating_fixedtilt5.yaml +0 -0
  160. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/__init__.py +0 -0
  161. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/convert_floris_input_v3_to_v4.py +0 -0
  162. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/convert_turbine_v3_to_v4.py +0 -0
  163. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/__init__.py +0 -0
  164. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/base.py +0 -0
  165. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/core.py +0 -0
  166. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/farm.py +0 -0
  167. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/flow_field.py +0 -0
  168. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/grid.py +0 -0
  169. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/rotor_velocity.py +0 -0
  170. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/solver.py +0 -0
  171. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/turbine/__init__.py +0 -0
  172. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/turbine/controller_dependent_operation_model.py +0 -0
  173. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/turbine/operation_models.py +0 -0
  174. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/turbine/turbine.py +0 -0
  175. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/turbine/unified_momentum_model.py +0 -0
  176. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake.py +0 -0
  177. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_combination/__init__.py +0 -0
  178. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_combination/fls.py +0 -0
  179. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_combination/max.py +0 -0
  180. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_combination/sosfs.py +0 -0
  181. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_deflection/__init__.py +0 -0
  182. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_deflection/empirical_gauss.py +0 -0
  183. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_deflection/gauss.py +0 -0
  184. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_deflection/jimenez.py +0 -0
  185. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_deflection/none.py +0 -0
  186. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_turbulence/__init__.py +0 -0
  187. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_turbulence/crespo_hernandez.py +0 -0
  188. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_turbulence/none.py +0 -0
  189. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_turbulence/wake_induced_mixing.py +0 -0
  190. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/__init__.py +0 -0
  191. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/cumulative_gauss_curl.py +0 -0
  192. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/empirical_gauss.py +0 -0
  193. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/gauss.py +0 -0
  194. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/jensen.py +0 -0
  195. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/none.py +0 -0
  196. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/turbopark.py +0 -0
  197. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/turbopark_lookup_table.mat +0 -0
  198. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/core/wake_velocity/turboparkgauss.py +0 -0
  199. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/cut_plane.py +0 -0
  200. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/flow_visualization.py +0 -0
  201. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/heterogeneous_map.py +0 -0
  202. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/layout_visualization.py +0 -0
  203. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/logging_manager.py +0 -0
  204. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/__init__.py +0 -0
  205. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/__init__.py +0 -0
  206. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_base.py +0 -0
  207. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_boundary_grid.py +0 -0
  208. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_gridded.py +0 -0
  209. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_pyoptsparse.py +0 -0
  210. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_pyoptsparse_spread.py +0 -0
  211. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_random_search.py +0 -0
  212. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/layout_optimization/layout_optimization_scipy.py +0 -0
  213. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/load_optimization/__init__.py +0 -0
  214. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/load_optimization/load_optimization.py +0 -0
  215. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/other/__init__.py +0 -0
  216. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/other/boundary_grid.py +0 -0
  217. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/yaw_optimization/__init__.py +0 -0
  218. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/yaw_optimization/yaw_optimization_base.py +0 -0
  219. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/yaw_optimization/yaw_optimization_tools.py +0 -0
  220. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/yaw_optimization/yaw_optimizer_geometric.py +0 -0
  221. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/yaw_optimization/yaw_optimizer_scipy.py +0 -0
  222. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/optimization/yaw_optimization/yaw_optimizer_sr.py +0 -0
  223. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/par_floris_model.py +0 -0
  224. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/parallel_floris_model.py +0 -0
  225. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/__init__.py +0 -0
  226. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/demo_cp_ct_surfaces/iea_10MW_demo_cp_ct_surface.npz +0 -0
  227. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/demo_cp_ct_surfaces/iea_15MW_demo_cp_ct_surface.npz +0 -0
  228. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/demo_cp_ct_surfaces/nrel_5MW_demo_cp_ct_surface.npz +0 -0
  229. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_10MW.yaml +0 -0
  230. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_15MW.yaml +0 -0
  231. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_15MW_floating_multi_dim_cp_ct.yaml +0 -0
  232. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_15MW_multi_dim_TI_u.csv +0 -0
  233. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_15MW_multi_dim_Tp_Hs.csv +0 -0
  234. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_15MW_multi_dim_cp_ct.yaml +0 -0
  235. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/iea_22MW.yaml +0 -0
  236. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/nrel_5MW.yaml +0 -0
  237. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/turbine_previewer.py +0 -0
  238. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/turbine_library/turbine_utilities.py +0 -0
  239. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/type_dec.py +0 -0
  240. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/uncertain_floris_model.py +0 -0
  241. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/utilities.py +0 -0
  242. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/floris/wind_data.py +0 -0
  243. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/profiling/conftest.py +0 -0
  244. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/profiling/linux_perf.py +0 -0
  245. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/profiling/profiling.py +0 -0
  246. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/profiling/quality_metrics.py +0 -0
  247. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/profiling/serial_vectorize.py +0 -0
  248. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/profiling/timing.py +0 -0
  249. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/rafmudaf_floris.egg-info/dependency_links.txt +0 -0
  250. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/rafmudaf_floris.egg-info/requires.txt +0 -0
  251. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/rafmudaf_floris.egg-info/top_level.txt +0 -0
  252. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/setup.cfg +0 -0
  253. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/__init__.py +0 -0
  254. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/base_unit_test.py +0 -0
  255. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/conftest.py +0 -0
  256. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/controller_dependent_operation_model_unit_test.py +0 -0
  257. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/convert_v3_to_v4_test.py +0 -0
  258. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/core_unit_test.py +0 -0
  259. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/__init__.py +0 -0
  260. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/iea_15MW_multi_dim_TI.csv +0 -0
  261. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/input_full.yaml +0 -0
  262. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/nrel_5MW.yaml +0 -0
  263. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/nrel_5MW_custom.yaml +0 -0
  264. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/wind_rose.csv +0 -0
  265. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/wind_ti_rose.csv +0 -0
  266. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/data/wrg_test.wrg +0 -0
  267. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/farm_unit_test.py +0 -0
  268. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/floris_model_integration_test.py +0 -0
  269. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/flow_field_unit_test.py +0 -0
  270. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/geometric_yaw_unit_test.py +0 -0
  271. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/heterogeneous_map_integration_test.py +0 -0
  272. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/layout_optimization_integration_test.py +0 -0
  273. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/layout_visualization_test.py +0 -0
  274. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/load_optimization_test.py +0 -0
  275. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/par_floris_model_unit_test.py +0 -0
  276. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/parallel_floris_model_integration_test.py +0 -0
  277. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/cumulative_curl_regression_test.py +0 -0
  278. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/empirical_gauss_regression_test.py +0 -0
  279. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/gauss_regression_test.py +0 -0
  280. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/jensen_jimenez_regression_test.py +0 -0
  281. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/none_regression_test.py +0 -0
  282. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/random_search_layout_opt_regression_test.py +0 -0
  283. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/scipy_layout_opt_regression.py +0 -0
  284. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/turbopark_regression_test.py +0 -0
  285. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/turboparkgauss_regression_test.py +0 -0
  286. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/turbulence_models_regression_test.py +0 -0
  287. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/reg_tests/yaw_optimization_regression_test.py +0 -0
  288. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/rotor_velocity_unit_test.py +0 -0
  289. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/serial_refine_unit_test.py +0 -0
  290. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/turbine_grid_unit_test.py +0 -0
  291. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/turbine_multi_dim_unit_test.py +0 -0
  292. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/turbine_operation_models_unit_test.py +0 -0
  293. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/turbine_unit_test.py +0 -0
  294. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/turbine_utilities_unit_test.py +0 -0
  295. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/turboparkgauss_unit_test.py +0 -0
  296. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/type_dec_unit_test.py +0 -0
  297. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/uncertain_floris_model_integration_test.py +0 -0
  298. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/unified_momentum_operation_model_unit_test.py +0 -0
  299. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/utilities_unit_test.py +0 -0
  300. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/v3_to_v4_convert_test/gch.yaml +0 -0
  301. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/v3_to_v4_convert_test/nrel_5MW_v3.yaml +0 -0
  302. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/wake_unit_tests.py +0 -0
  303. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/wind_data_integration_test.py +0 -0
  304. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/wind_rose_wrg_test.py +0 -0
  305. {rafmudaf_floris-4.6.4.post1.dev9 → rafmudaf_floris-4.6.4.post1.dev21}/tests/yaw_optimization_integration_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rafmudaf-floris
3
- Version: 4.6.4.post1.dev9
3
+ Version: 4.6.4.post1.dev21
4
4
  Summary: A controls-oriented engineering wake model.
5
5
  Author-email: Rafael Mudafort <rafael@clementinescientific.com>
6
6
  License: BSD 3-Clause License
@@ -34,7 +34,6 @@ def _get_fmodel(cpp=False, device="cpu") -> FlorisModel:
34
34
  fdefaults["wake"]["enable_transverse_velocities"] = False
35
35
  fdefaults["wake"]["enable_active_wake_mixing"] = False
36
36
  fmodel = FlorisModel(fdefaults)
37
- print(fmodel.core.logging)
38
37
  return fmodel
39
38
 
40
39
 
@@ -257,8 +256,10 @@ def run_gradient_optimization(
257
256
  lr: float,
258
257
  live_plot: bool = True,
259
258
  seed: int = 42,
259
+ device: str = "cpu",
260
260
  ):
261
261
  """Run gradient-based layout optimization and return results dict."""
262
+
262
263
  rng = np.random.default_rng(seed)
263
264
  D = 126.0 # NREL 5 MW rotor diameter (m)
264
265
  min_dist = 2 * D # minimum turbine spacing
@@ -269,13 +270,13 @@ def run_gradient_optimization(
269
270
 
270
271
  # Wind resource
271
272
  freq_np = wind_rose.unpack_freq() # [F], sums to ≈1
272
- freq_t = torch.tensor(freq_np, dtype=torch.float32)
273
+ freq_t = torch.tensor(freq_np, dtype=torch.float32, device=device) # [F]
273
274
 
274
275
  # Initial layout: grid + jitter (stays within boundaries)
275
276
  lx_init_np, ly_init_np = _grid_layout(n_turbs, xmin, xmax, ymin, ymax, rng)
276
277
 
277
278
  # FLORIS model with FLORAF backend
278
- fmodel = _get_fmodel(cpp=True, device="cpu")
279
+ fmodel = _get_fmodel(cpp=True, device=device)
279
280
  fmodel.set(
280
281
  layout_x=lx_init_np.tolist(),
281
282
  layout_y=ly_init_np.tolist(),
@@ -283,8 +284,8 @@ def run_gradient_optimization(
283
284
  )
284
285
 
285
286
  # Optimization variables - leaf tensors for layout positions
286
- lx = torch.tensor(lx_init_np, dtype=torch.float32, requires_grad=True)
287
- ly = torch.tensor(ly_init_np, dtype=torch.float32, requires_grad=True)
287
+ lx = torch.tensor(lx_init_np, dtype=torch.float32, device=device, requires_grad=True)
288
+ ly = torch.tensor(ly_init_np, dtype=torch.float32, device=device, requires_grad=True)
288
289
 
289
290
  # Plant the grad-tracked tensors into the FLORAF farm once.
290
291
  fmodel.core._cpp_farm.layout_x = lx
@@ -351,8 +352,8 @@ def run_gradient_optimization(
351
352
  elapsed = time.perf_counter() - t0
352
353
 
353
354
  # Final positions and AEP
354
- final_lx = lx.detach().numpy().copy()
355
- final_ly = ly.detach().numpy().copy()
355
+ final_lx = lx.detach().cpu().numpy().copy()
356
+ final_ly = ly.detach().cpu().numpy().copy()
356
357
  final_aep = aep_history[-1]
357
358
 
358
359
  print(f"\nGradient opt finished in {elapsed:.1f} s ({n_iters} iterations)")
@@ -549,6 +550,7 @@ if __name__ == "__main__":
549
550
  parser.add_argument("--n-wdirs", type=int, default=36, help="Number of wind directions in wind rose (default: 36).")
550
551
  parser.add_argument("--n-wspeeds", type=int, default=5, help="Number of wind speed bins in wind rose (default: 5).")
551
552
  parser.add_argument("--seed", type=int, default=42, help="Random seed for initial layout jitter (default: 42).")
553
+ parser.add_argument("--device", type=str, default="cpu", choices=["cpu", "cuda", "mps"], help="Device for C++ solver (default: cpu). Use 'cuda' if torch.cuda.is_available().")
552
554
  args = parser.parse_args()
553
555
 
554
556
  print("=" * 62)
@@ -573,6 +575,7 @@ if __name__ == "__main__":
573
575
  lr=args.lr,
574
576
  live_plot=args.plot,
575
577
  seed=args.seed,
578
+ device=args.device,
576
579
  )
577
580
 
578
581
  pct = 100 * (grad_res["final_aep"] / grad_res["base_aep"] - 1)
@@ -0,0 +1,562 @@
1
+ """
2
+ Gradient-based yaw optimization using PyTorch autograd through the FLORAF
3
+ C++ sequential solver. Exact analytical gradients of AEP with respect to
4
+ per-turbine, per-wind-condition yaw angles are back-propagated via ``autograd``
5
+ and consumed by an Adam optimizer.
6
+
7
+ Variable shape
8
+ --------------
9
+ The optimization variable ``yaw`` has shape ``[n_findex, n_turbines]``:
10
+ one yaw angle per turbine per wind condition. This is the physically correct
11
+ parameterization — the optimal yaw for a given turbine depends on wind
12
+ direction and speed, so no reduction across conditions is applied.
13
+
14
+ Usage
15
+ -----
16
+ python gradient_yaw_optimization.py
17
+ python gradient_yaw_optimization.py --iters 300 --lr 1.0 --n-turbs 9
18
+ python gradient_yaw_optimization.py --no-plot
19
+ """
20
+
21
+ import argparse
22
+ import time
23
+
24
+ import matplotlib.pyplot as plt
25
+ import numpy as np
26
+ import torch
27
+
28
+ from floris import FlorisModel, WindRose
29
+ from floris.optimization.yaw_optimization.yaw_optimizer_sr import YawOptimizationSR
30
+
31
+
32
+ # ---------------------------------------------------------------------------
33
+ # Model / wind-rose helpers (shared with gradient_layout_optimization.py)
34
+ # ---------------------------------------------------------------------------
35
+
36
+ def _get_fmodel(device: str = "cpu") -> FlorisModel:
37
+ """Build a FLORIS model using the FLORAF C++ sequential solver."""
38
+ fdefaults = FlorisModel.get_defaults()
39
+ fdefaults["logging"]["console"]["enable"] = False
40
+ fdefaults["logging"]["file"]["enable"] = False
41
+ fdefaults["solver"]["backend"] = "cpp"
42
+ fdefaults["solver"]["device"] = device
43
+ fdefaults["solver"]["cpp_solver"] = "sequential"
44
+ fdefaults["wake"]["enable_secondary_steering"] = False
45
+ fdefaults["wake"]["enable_yaw_added_recovery"] = False
46
+ fdefaults["wake"]["enable_transverse_velocities"] = False
47
+ fdefaults["wake"]["enable_active_wake_mixing"] = False
48
+ return FlorisModel(fdefaults)
49
+
50
+
51
+ def _wind_rose(n_wdirs: int = 36, n_wspeeds: int = 5, ti: float = 0.06) -> WindRose:
52
+ """Synthetic North Sea wind rose with a dominant SW peak."""
53
+ wd = np.linspace(0.0, 360.0, n_wdirs, endpoint=False)
54
+ ws = np.linspace(4.0, 18.0, n_wspeeds)
55
+
56
+ dir_freq = 0.45 * np.exp(-0.5 * ((wd - 240) % 360 / 38) ** 2) + 0.04
57
+ dir_freq /= dir_freq.sum()
58
+
59
+ k, c = 2.0, 11.0
60
+ spd_freq = (k / c) * (ws / c) ** (k - 1) * np.exp(-(ws / c) ** k)
61
+ spd_freq /= spd_freq.sum()
62
+
63
+ freq_table = np.outer(dir_freq, spd_freq)
64
+ freq_table /= freq_table.sum()
65
+
66
+ return WindRose(
67
+ wind_directions=wd,
68
+ wind_speeds=ws,
69
+ freq_table=freq_table,
70
+ ti_table=ti,
71
+ )
72
+
73
+
74
+ def _row_layout(n_turbs: int, spacing_D: float = 5.0, D: float = 126.0):
75
+ """Place turbines in a single east-west row."""
76
+ lx = np.arange(n_turbs, dtype=float) * spacing_D * D
77
+ ly = np.zeros(n_turbs)
78
+ return lx, ly
79
+
80
+
81
+ def _grid_layout(
82
+ n_turbs: int,
83
+ spacing_x_D: float = 5.0,
84
+ spacing_y_D: float = 3.0,
85
+ stagger_D: float = 1.5,
86
+ D: float = 126.0,
87
+ ):
88
+ """
89
+ Place turbines on a staggered grid.
90
+
91
+ Turbines are arranged in rows running east-west. Odd-numbered rows are
92
+ offset by *stagger_D* diameters in x to break the regular grid pattern,
93
+ which creates a more realistic farm layout where not all turbines are in
94
+ direct wake of upstream neighbours.
95
+
96
+ Parameters
97
+ ----------
98
+ n_turbs:
99
+ Total number of turbines.
100
+ spacing_x_D:
101
+ Down-wind spacing between turbines in the same row, in rotor diameters.
102
+ spacing_y_D:
103
+ Cross-wind row spacing, in rotor diameters.
104
+ stagger_D:
105
+ x-offset applied to every other row, in rotor diameters.
106
+ D:
107
+ Rotor diameter (m).
108
+ """
109
+ cols = int(np.ceil(np.sqrt(n_turbs)))
110
+ rows = int(np.ceil(n_turbs / cols))
111
+
112
+ lx_list, ly_list = [], []
113
+ for row in range(rows):
114
+ x_offset = (stagger_D * D) if (row % 2 == 1) else 0.0
115
+ for col in range(cols):
116
+ if len(lx_list) >= n_turbs:
117
+ break
118
+ lx_list.append(col * spacing_x_D * D + x_offset)
119
+ ly_list.append(row * spacing_y_D * D)
120
+
121
+ return np.array(lx_list), np.array(ly_list)
122
+
123
+
124
+ # ---------------------------------------------------------------------------
125
+ # Forward pass
126
+ # ---------------------------------------------------------------------------
127
+
128
+ def _aep_tensor(fmodel: FlorisModel, freq_tensor: torch.Tensor) -> torch.Tensor:
129
+ """
130
+ Return a scalar AEP tensor (Wh/yr) with ``grad_fn`` connected to
131
+ ``fmodel.core._cpp_farm.yaw_angles``.
132
+
133
+ The caller must have already injected the ``requires_grad=True`` yaw
134
+ tensor into ``fmodel.core._cpp_farm.yaw_angles`` before calling this.
135
+ """
136
+ fmodel.run()
137
+ power = fmodel.core.get_farm_power_tensor() # [F, T] W
138
+ farm_power_per_findex = power.sum(dim=1) # [F]
139
+ return (freq_tensor * farm_power_per_findex).sum() * 8760.0
140
+
141
+
142
+ # ---------------------------------------------------------------------------
143
+ # Main optimization loop
144
+ # ---------------------------------------------------------------------------
145
+
146
+ def run_yaw_optimization(
147
+ n_turbs: int,
148
+ wind_rose: WindRose,
149
+ n_iters: int,
150
+ lr: float,
151
+ yaw_max_deg: float = 30.0,
152
+ layout: str = "row",
153
+ live_plot: bool = True,
154
+ device: str = "cpu",
155
+ ) -> dict:
156
+ """
157
+ Optimize yaw angles to maximise AEP and return a results dict.
158
+
159
+ Parameters
160
+ ----------
161
+ n_turbs:
162
+ Number of turbines.
163
+ wind_rose:
164
+ Wind resource description.
165
+ n_iters:
166
+ Number of Adam gradient steps.
167
+ lr:
168
+ Adam learning rate in degrees.
169
+ yaw_max_deg:
170
+ Hard constraint: yaw angles are clamped to ``[-yaw_max_deg, yaw_max_deg]``
171
+ after every optimizer step.
172
+ layout:
173
+ ``"row"`` — single east-west row (default).
174
+ ``"grid"`` — staggered multi-row grid.
175
+ live_plot:
176
+ Show a live convergence plot.
177
+ device:
178
+ Torch device string, e.g. ``"cpu"`` or ``"cuda"``.
179
+ """
180
+ D = 126.0
181
+ if layout == "grid":
182
+ lx, ly = _grid_layout(n_turbs, D=D)
183
+ else:
184
+ lx, ly = _row_layout(n_turbs, spacing_D=5.0, D=D)
185
+ n_turbs = len(lx) # _grid_layout may round up to fill the grid
186
+
187
+ freq_np = wind_rose.unpack_freq() # [F]
188
+ freq_t = torch.tensor(freq_np, dtype=torch.float32, device=device)
189
+
190
+ n_findex = len(freq_np)
191
+
192
+ # Build model and set layout + wind conditions.
193
+ fmodel = _get_fmodel(device=device)
194
+ fmodel.set(layout_x=lx.tolist(), layout_y=ly.tolist(), wind_data=wind_rose)
195
+
196
+ # ------------------------------------------------------------------
197
+ # Baseline AEP (zero yaw)
198
+ # ------------------------------------------------------------------
199
+ with torch.no_grad():
200
+ base_aep_t = _aep_tensor(fmodel, freq_t)
201
+ base_aep = base_aep_t.item()
202
+ print(f"\nInitial AEP (zero yaw): {base_aep / 1e9:.4f} GWh/yr")
203
+
204
+ # ------------------------------------------------------------------
205
+ # Optimization variable: yaw [n_findex, n_turbines], degrees
206
+ # ------------------------------------------------------------------
207
+ yaw = torch.zeros(
208
+ n_findex, n_turbs,
209
+ dtype=torch.float32,
210
+ device=device,
211
+ requires_grad=True,
212
+ )
213
+
214
+ # Inject the leaf tensor into the C++ farm struct. It will be preserved
215
+ # across calls to initialize_domain() because _preserve_if_grad detects
216
+ # requires_grad=True. Do NOT call fmodel.set(yaw_angles=...) inside the
217
+ # optimization loop — that writes to _py_core only, bypassing _cpp_farm.
218
+ fmodel.core._cpp_farm.yaw_angles = yaw
219
+
220
+ optimizer = torch.optim.Adam([yaw], lr=lr)
221
+
222
+ if live_plot:
223
+ plt.ion()
224
+ fig, ax = plt.subplots(figsize=(8, 5))
225
+ ax.set_xlabel("Iteration")
226
+ ax.set_ylabel("AEP improvement (%)")
227
+ ax.set_title("Gradient-based yaw optimization (PyTorch autograd + Adam)")
228
+ ax.axhline(0, color="grey", ls="--", lw=1)
229
+ ax.grid(True, alpha=0.4)
230
+ (aep_line,) = ax.plot([], [], "o-", color="#2c7fb8", ms=3, lw=1.5)
231
+ plt.tight_layout()
232
+ plt.pause(0.05)
233
+
234
+ aep_history = [base_aep]
235
+ t0 = time.perf_counter()
236
+
237
+ for step in range(1, n_iters + 1):
238
+ optimizer.zero_grad()
239
+
240
+ aep = _aep_tensor(fmodel, freq_t)
241
+ loss = -aep
242
+ loss.backward()
243
+ optimizer.step()
244
+
245
+ # Hard constraint: clamp yaw angles to physical range.
246
+ with torch.no_grad():
247
+ yaw.clamp_(-yaw_max_deg, yaw_max_deg)
248
+ yaw.grad.zero_()
249
+
250
+ current_aep = aep.item()
251
+ aep_history.append(current_aep)
252
+ improvement = 100.0 * (current_aep / base_aep - 1.0)
253
+ print(
254
+ f" Step {step:4d}/{n_iters}"
255
+ f" | AEP = {current_aep / 1e9:.4f} GWh/yr"
256
+ f" | Δ = {improvement:+.3f}%"
257
+ )
258
+
259
+ if live_plot:
260
+ iters = np.arange(len(aep_history))
261
+ improv = 100.0 * (np.array(aep_history) / base_aep - 1.0)
262
+ aep_line.set_data(iters, improv)
263
+ ax.set_xlim(-1, max(len(aep_history) + 1, 10))
264
+ pad = max(abs(improv).max() * 0.15, 0.05)
265
+ ax.set_ylim(improv.min() - pad, improv.max() + pad)
266
+ fig.canvas.draw()
267
+ fig.canvas.flush_events()
268
+ plt.pause(0.001)
269
+
270
+ elapsed = time.perf_counter() - t0
271
+ final_aep = aep_history[-1]
272
+ final_yaw = yaw.detach().cpu().numpy().copy() # [n_findex, n_turbines], degrees
273
+
274
+ print(f"\nYaw opt finished in {elapsed:.1f} s ({n_iters} iterations)")
275
+ print(
276
+ f"Final AEP: {final_aep / 1e9:.4f} GWh/yr"
277
+ f" ({100 * (final_aep / base_aep - 1):+.3f}% vs zero-yaw)\n"
278
+ )
279
+
280
+ return dict(
281
+ base_aep=base_aep,
282
+ final_aep=final_aep,
283
+ aep_history=aep_history,
284
+ final_yaw=final_yaw,
285
+ elapsed=elapsed,
286
+ n_iters=n_iters,
287
+ n_findex=n_findex,
288
+ n_turbs=n_turbs,
289
+ yaw_max_deg=yaw_max_deg,
290
+ )
291
+
292
+
293
+ # ---------------------------------------------------------------------------
294
+ # Serial Refine (SR) yaw optimization for comparison
295
+ # ---------------------------------------------------------------------------
296
+
297
+ def _get_fmodel_python() -> FlorisModel:
298
+ """Build a FLORIS model using the standard Python backend (GCH-like defaults)."""
299
+ fdefaults = FlorisModel.get_defaults()
300
+ fdefaults["logging"]["console"]["enable"] = False
301
+ fdefaults["logging"]["file"]["enable"] = False
302
+ fdefaults["wake"]["enable_secondary_steering"] = False
303
+ fdefaults["wake"]["enable_yaw_added_recovery"] = False
304
+ fdefaults["wake"]["enable_transverse_velocities"] = False
305
+ fdefaults["wake"]["enable_active_wake_mixing"] = False
306
+ return FlorisModel(fdefaults)
307
+
308
+
309
+ def run_sr_optimization(
310
+ lx: np.ndarray,
311
+ ly: np.ndarray,
312
+ wind_rose: WindRose,
313
+ base_aep: float,
314
+ yaw_max_deg: float = 30.0,
315
+ ) -> dict:
316
+ """
317
+ Run YawOptimizationSR on the same layout and wind rose and return a results dict.
318
+
319
+ Parameters
320
+ ----------
321
+ lx, ly:
322
+ Turbine positions (metres), matching the gradient optimizer layout.
323
+ wind_rose:
324
+ Wind resource description.
325
+ base_aep:
326
+ Baseline AEP (Wh/yr) computed at zero yaw, for relative improvement reporting.
327
+ yaw_max_deg:
328
+ Symmetric yaw angle bound applied to both minimum and maximum.
329
+ """
330
+ fmodel = _get_fmodel_python()
331
+ fmodel.set(layout_x=lx.tolist(), layout_y=ly.tolist(), wind_data=wind_rose)
332
+
333
+ yaw_opt = YawOptimizationSR(
334
+ fmodel=fmodel,
335
+ minimum_yaw_angle=-yaw_max_deg,
336
+ maximum_yaw_angle=yaw_max_deg,
337
+ Ny_passes=[5, 4],
338
+ exclude_downstream_turbines=True,
339
+ )
340
+
341
+ print("Running Serial Refine yaw optimization...")
342
+ t0 = time.perf_counter()
343
+ df_opt = yaw_opt.optimize()
344
+ elapsed = time.perf_counter() - t0
345
+
346
+ # Apply optimal yaw angles to evaluate AEP over the full wind rose.
347
+ yaw_angles_opt = np.vstack(df_opt["yaw_angles_opt"]) # [n_findex, n_turbs]
348
+ fmodel_eval = _get_fmodel_python()
349
+ fmodel_eval.set(
350
+ layout_x=lx.tolist(),
351
+ layout_y=ly.tolist(),
352
+ wind_data=wind_rose,
353
+ yaw_angles=yaw_angles_opt,
354
+ )
355
+ fmodel_eval.run()
356
+ final_aep = fmodel_eval.get_farm_AEP()
357
+
358
+ print(f"SR opt finished in {elapsed:.1f} s")
359
+ print(
360
+ f"Final AEP (SR): {final_aep / 1e9:.4f} GWh/yr"
361
+ f" ({100 * (final_aep / base_aep - 1):+.3f}% vs zero-yaw)\n"
362
+ )
363
+
364
+ return dict(
365
+ base_aep=base_aep,
366
+ final_aep=final_aep,
367
+ elapsed=elapsed,
368
+ final_yaw=yaw_angles_opt,
369
+ n_findex=yaw_angles_opt.shape[0],
370
+ n_turbs=yaw_angles_opt.shape[1],
371
+ yaw_max_deg=yaw_max_deg,
372
+ )
373
+
374
+
375
+ # ---------------------------------------------------------------------------
376
+ # Comparison helpers
377
+ # ---------------------------------------------------------------------------
378
+
379
+ def _print_comparison_table(grad_res: dict, sr_res: dict) -> None:
380
+ """Print a formatted side-by-side results table."""
381
+ g = grad_res
382
+ s = sr_res
383
+
384
+ print("\n" + "=" * 62)
385
+ print(f"{'':30s} {'Gradient (Adam)':>15} {'SR (FLORIS)':>11}")
386
+ print("-" * 62)
387
+ print(f"{'Iterations / passes':30s} {g['n_iters']:>15d} {'–':>11}")
388
+ print(f"{'Wall time (s)':30s} {g['elapsed']:>15.1f} {s['elapsed']:>11.1f}")
389
+ print(f"{'Initial AEP (GWh/yr)':30s} {g['base_aep'] / 1e9:>15.4f} {'(same)':>11}")
390
+ print(f"{'Final AEP (GWh/yr)':30s} {g['final_aep'] / 1e9:>15.4f} {s['final_aep'] / 1e9:>11.4f}")
391
+ pct_g = 100 * (g['final_aep'] / g['base_aep'] - 1)
392
+ pct_s = 100 * (s['final_aep'] / s['base_aep'] - 1)
393
+ print(f"{'AEP improvement (%)':30s} {pct_g:>+15.3f} {pct_s:>+11.3f}")
394
+ print("=" * 62 + "\n")
395
+
396
+
397
+ def _plot_comparison(grad_res: dict, sr_res: dict) -> None:
398
+ """Plot AEP convergence (gradient) and final-AEP bar comparison side-by-side."""
399
+ fig, axes = plt.subplots(1, 2, figsize=(13, 5))
400
+ fig.suptitle(
401
+ "Yaw optimization comparison: autograd (Adam) vs Serial Refine (FLORIS)",
402
+ fontsize=13,
403
+ fontweight="bold",
404
+ )
405
+
406
+ colours = {"grad": "#2c7fb8", "sr": "#d7191c"}
407
+
408
+ # Left panel — gradient convergence curve
409
+ ax = axes[0]
410
+ hist = np.array(grad_res["aep_history"])
411
+ improvement = 100.0 * (hist / grad_res["base_aep"] - 1.0)
412
+ ax.plot(
413
+ np.arange(len(improvement)),
414
+ improvement,
415
+ "o-",
416
+ color=colours["grad"],
417
+ ms=3,
418
+ lw=1.5,
419
+ label=f"Gradient (Adam) final {improvement[-1]:+.3f}%",
420
+ )
421
+ pct_sr = 100.0 * (sr_res["final_aep"] / sr_res["base_aep"] - 1.0)
422
+ ax.axhline(pct_sr, color=colours["sr"], ls="--", lw=1.5, label=f"SR (FLORIS) {pct_sr:+.3f}%")
423
+ ax.axhline(0, color="grey", ls=":", lw=1)
424
+ ax.set_xlabel("Adam iteration", fontsize=11)
425
+ ax.set_ylabel("AEP improvement (%)", fontsize=11)
426
+ ax.set_title("Gradient convergence", fontsize=11)
427
+ ax.legend(fontsize=9)
428
+ ax.grid(True, alpha=0.4)
429
+
430
+ # Right panel — per-turbine yaw angle comparison for the highest-frequency condition
431
+ ax = axes[1]
432
+ # Find the wind condition with the highest frequency weight
433
+ freq_np = sr_res["final_yaw"].shape[0] # just n_findex; we pick peak condition
434
+ # Use argmax of absolute mean yaw as a representative active condition
435
+ mean_abs_yaw_grad = np.abs(grad_res["final_yaw"]).mean(axis=1)
436
+ peak_idx = int(np.argmax(mean_abs_yaw_grad))
437
+
438
+ n_turbs = grad_res["n_turbs"]
439
+ turb_ids = np.arange(n_turbs)
440
+ width = 0.35
441
+
442
+ ax.bar(
443
+ turb_ids - width / 2,
444
+ grad_res["final_yaw"][peak_idx],
445
+ width,
446
+ color=colours["grad"],
447
+ label="Gradient (Adam)",
448
+ alpha=0.85,
449
+ edgecolor="k",
450
+ linewidth=0.5,
451
+ )
452
+ sr_yaw_peak = sr_res["final_yaw"][peak_idx] if peak_idx < sr_res["final_yaw"].shape[0] else np.zeros(n_turbs)
453
+ ax.bar(
454
+ turb_ids + width / 2,
455
+ sr_yaw_peak,
456
+ width,
457
+ color=colours["sr"],
458
+ label="SR (FLORIS)",
459
+ alpha=0.85,
460
+ edgecolor="k",
461
+ linewidth=0.5,
462
+ )
463
+ ax.axhline(0, color="grey", ls=":", lw=1)
464
+ ax.set_xlabel("Turbine index", fontsize=11)
465
+ ax.set_ylabel("Yaw angle (°)", fontsize=11)
466
+ ax.set_title(f"Optimal yaw angles at peak condition (findex {peak_idx})", fontsize=11)
467
+ ax.set_xticks(turb_ids)
468
+ ax.legend(fontsize=9)
469
+ ax.grid(True, alpha=0.3, axis="y")
470
+
471
+ plt.tight_layout()
472
+ plt.show()
473
+
474
+
475
+ # ---------------------------------------------------------------------------
476
+ # Results summary
477
+ # ---------------------------------------------------------------------------
478
+
479
+ def _print_results(res: dict) -> None:
480
+ wd_idx_peak = int(np.argmax(res["final_yaw"].max(axis=1)))
481
+ print("Optimal yaw angles at peak-frequency wind condition "
482
+ f"(findex {wd_idx_peak}), degrees:")
483
+ print(" " + " ".join(
484
+ f"T{i}: {res['final_yaw'][wd_idx_peak, i]:+.1f}"
485
+ for i in range(res["n_turbs"])
486
+ ))
487
+
488
+
489
+ # ---------------------------------------------------------------------------
490
+ # Entry point
491
+ # ---------------------------------------------------------------------------
492
+
493
+ if __name__ == "__main__":
494
+ parser = argparse.ArgumentParser()
495
+ parser.add_argument("--iters", type=int, default=200, help="Adam steps (default: 200)")
496
+ parser.add_argument("--lr", type=float, default=0.5, help="Adam lr in degrees (default: 0.5)")
497
+ parser.add_argument("--n-turbs", type=int, default=6, help="Turbines in row (default: 6)")
498
+ parser.add_argument("--n-wdirs", type=int, default=36, help="Wind directions (default: 36)")
499
+ parser.add_argument("--n-wspeeds", type=int, default=5, help="Wind speed bins (default: 5)")
500
+ parser.add_argument("--yaw-max", type=float, default=25.0, help="Max |yaw| degrees (default: 30)")
501
+ parser.add_argument(
502
+ "--layout",
503
+ choices=["row", "grid"],
504
+ default="row",
505
+ help="Farm layout: 'row' (single row, default) or 'grid' (staggered multi-row)",
506
+ )
507
+ parser.add_argument("--compare", action="store_true", help="Run SR yaw optimization and compare results.")
508
+ parser.add_argument("--no-plot", dest="plot", action="store_false", help="Disable live plot")
509
+ args = parser.parse_args()
510
+
511
+ print("=" * 60)
512
+ print(" Gradient-based wind farm yaw optimization")
513
+ print("=" * 60)
514
+ print(f" Turbines : {args.n_turbs}")
515
+ print(f" Wind dirs : {args.n_wdirs}")
516
+ print(f" Wind speeds : {args.n_wspeeds}")
517
+ print(f" Adam steps : {args.iters}")
518
+ print(f" Adam lr : {args.lr} deg")
519
+ print(f" |yaw| max : {args.yaw_max} deg")
520
+ print(f" Layout : {args.layout}")
521
+ print(f" SR compare : {'yes' if args.compare else 'no'}")
522
+ print()
523
+
524
+ wind_rose = _wind_rose(args.n_wdirs, args.n_wspeeds)
525
+
526
+ results = run_yaw_optimization(
527
+ n_turbs=args.n_turbs,
528
+ wind_rose=wind_rose,
529
+ n_iters=args.iters,
530
+ lr=args.lr,
531
+ yaw_max_deg=args.yaw_max,
532
+ layout=args.layout,
533
+ live_plot=args.plot,
534
+ device="mps"
535
+ )
536
+
537
+ _print_results(results)
538
+
539
+ if args.compare:
540
+ # Reconstruct the layout arrays used by the gradient optimizer.
541
+ D = 126.0
542
+ if args.layout == "grid":
543
+ lx, ly = _grid_layout(args.n_turbs, D=D)
544
+ else:
545
+ lx, ly = _row_layout(args.n_turbs, spacing_D=5.0, D=D)
546
+ lx = lx[: results["n_turbs"]]
547
+ ly = ly[: results["n_turbs"]]
548
+
549
+ sr_results = run_sr_optimization(
550
+ lx=lx,
551
+ ly=ly,
552
+ wind_rose=wind_rose,
553
+ base_aep=results["base_aep"],
554
+ yaw_max_deg=args.yaw_max,
555
+ )
556
+ _print_comparison_table(results, sr_results)
557
+ if args.plot:
558
+ _plot_comparison(results, sr_results)
559
+
560
+ if args.plot:
561
+ plt.ioff()
562
+ plt.show()