rafmudaf-floris 4.6.4.post1.dev13__tar.gz → 4.6.4.post1.dev22__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.
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/PKG-INFO +1 -1
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/gradient_layout_optimization.py +10 -7
- rafmudaf_floris-4.6.4.post1.dev22/examples/gradient_yaw_optimization.py +562 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/cpp_core.py +77 -36
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/default_inputs.yaml +3 -3
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/floris_model.py +8 -7
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/pyproject.toml +1 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/rafmudaf_floris.egg-info/PKG-INFO +1 -1
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/rafmudaf_floris.egg-info/SOURCES.txt +1 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/gauss_regression_test.py +42 -157
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.codecov.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/dependabot.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/workflows/check-working-examples.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/workflows/continuous-integration-workflow.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/workflows/cpp-backend-tests.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/workflows/deploy-pages.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/workflows/python-publish.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.github/workflows/quality-metrics-workflow.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.gitignore +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/.pre-commit-config.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/CONTRIBUTING.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/LICENSE.txt +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/README.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/benchmarks/bench.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/.nojekyll +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/_config.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/_toc.yml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/advanced_concepts.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/api_docs.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/architecture.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/bibliography.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/cc.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/code_quality.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/dev_guide.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/docs_image.png +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/empirical_gauss_model.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/floating_wind_turbine.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/floris_models.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/gch.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/heterogeneous_map.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/index.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/input_reference_main.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/input_reference_turbine.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/installation.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/intro_concepts.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/jensen.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/layout_optimization.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/multidimensional_wind_turbine.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/nrel_5MW.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/operation_models_user.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/plot_complex_docs.png +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/powerthrust_helix.png +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/references.bib +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/turbine_library.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/turbine_models.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/v3_to_v4.md +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/wake_models.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/docs/wind_data_user.ipynb +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/001_opening_floris_computing_power.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/002_visualizations.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/003_wind_data_objects.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/004_set.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/005_getting_power.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/006_get_farm_aep.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/007_sweeping_variables.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/008_uncertain_models.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/009_parallel_models.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/010_compare_farm_power_with_neighbor.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/_convert_examples_to_notebooks.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/001_opt_yaw_single_ws.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/002_opt_yaw_single_ws_uncertain.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/003_opt_yaw_multiple_ws.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/004_optimize_yaw_aep.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/005_optimize_yaw_aep_parallel.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/006_compare_yaw_optimizers.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/007_optimize_yaw_with_neighbor_farms.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_optimization/008_optimize_yaw_with_disabled_turbines.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_types/001_derating_control.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_types/002_disable_turbines.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_types/003_setting_yaw_and_disabling.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_types/004_helix_active_wake_mixing.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_control_types/005_peak_shaving.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_emgauss/001_empirical_gauss_velocity_deficit_parameters.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_emgauss/002_empirical_gauss_deflection_parameters.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_floating/001_floating_turbine_models.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_floating/002_floating_vs_fixedbottom_farm.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_floating/003_tilt_driven_vertical_wake_deflection.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_get_flow/001_extract_wind_speed_at_turbines.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_get_flow/002_extract_wind_speed_at_points.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_get_flow/003_extract_turbulence_intensity_at_points.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_get_flow/004_plot_velocity_deficit_profiles.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_heterogeneous/001_heterogeneous_inflow_single.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_heterogeneous/002_heterogeneous_using_wind_data.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_heterogeneous/003_heterogeneous_speedup_by_wd_and_ws.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_heterogeneous/004_heterogeneous_2d_and_3d.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_layout_optimization/001_optimize_layout.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_layout_optimization/002_optimize_layout_with_heterogeneity.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_layout_optimization/003_genetic_random_search.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_layout_optimization/004_generate_gridded_layout.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_layout_optimization/005_layout_optimization_complex_boundary.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_load_optimization/001_lti_and_voc.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_load_optimization/002_row_opt_example.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_multidim/001_multi_dimensional_cp_ct.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_multidim/002_multi_dimensional_cp_ct_2Hs.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_multidim/003_multi_dimensional_cp_ct_TI.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_operation_models/001_compare_yaw_loss.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_turbine/001_reference_turbines.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_turbine/002_multiple_turbine_types.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_turbine/003_specify_turbine_power_curve.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_turbopark/001_compare_turbopark_implementations.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_turbopark/comparison_data/Rowpark_Orsted.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_turbopark/comparison_data/WindDirection_Sweep_Orsted.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_uncertain/001_uncertain_model_params.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_uncertain/002_approx_floris_model.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_uncertain/003_uncertain_model_with_parallelization.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_visualizations/001_layout_visualizations.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_visualizations/002_visualize_y_cut_plane.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_visualizations/003_visualize_cross_plane.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_visualizations/004_visualize_rotor_values.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_visualizations/005_visualize_flow_by_sweeping_turbines.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_data/001_wind_data_comparisons.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_data/002_generate_ti.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_data/003_generate_value.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_resource_grid/000_generate_example_wrg.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_resource_grid/001_wind_rose_wrg.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_resource_grid/002_set_floris_with_wrg.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_resource_grid/003_wrg_compar_layout_optimization.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/examples_wind_resource_grid/wrg_example.wrg +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/cc.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/emgauss.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/emgauss_helix.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/gch.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/gch_heterogeneous_inflow.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/gch_multi_dim_cp_ct.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/gch_multi_dim_cp_ct_TI.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/gch_multiple_turbine_types.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/jensen.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/turbine_files/iea_15MW_multi_dim_TI.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/turbine_files/iea_15MW_multi_dim_TI.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/turbopark.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/turbopark_cubature.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/turboparkgauss.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/turboparkgauss_cubature.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs/wind_rose.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/emgauss_fixed.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/emgauss_floating.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/emgauss_floating_fixedtilt15.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/emgauss_floating_fixedtilt5.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/gch_fixed.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/gch_floating.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/gch_floating_defined_floating.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/turbine_files/nrel_5MW_fixed.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/turbine_files/nrel_5MW_floating.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/turbine_files/nrel_5MW_floating_defined_floating.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/turbine_files/nrel_5MW_floating_fixedtilt15.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/examples/inputs_floating/turbine_files/nrel_5MW_floating_fixedtilt5.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/convert_floris_input_v3_to_v4.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/convert_turbine_v3_to_v4.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/base.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/core.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/farm.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/flow_field.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/grid.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/rotor_velocity.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/solver.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/turbine/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/turbine/controller_dependent_operation_model.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/turbine/operation_models.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/turbine/turbine.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/turbine/unified_momentum_model.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_combination/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_combination/fls.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_combination/max.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_combination/sosfs.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_deflection/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_deflection/empirical_gauss.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_deflection/gauss.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_deflection/jimenez.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_deflection/none.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_turbulence/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_turbulence/crespo_hernandez.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_turbulence/none.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_turbulence/wake_induced_mixing.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/cumulative_gauss_curl.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/empirical_gauss.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/gauss.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/jensen.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/none.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/turbopark.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/turbopark_lookup_table.mat +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/core/wake_velocity/turboparkgauss.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/cut_plane.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/flow_visualization.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/heterogeneous_map.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/layout_visualization.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/logging_manager.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_base.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_boundary_grid.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_gridded.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_pyoptsparse.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_pyoptsparse_spread.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_random_search.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/layout_optimization/layout_optimization_scipy.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/load_optimization/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/load_optimization/load_optimization.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/other/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/other/boundary_grid.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/yaw_optimization/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/yaw_optimization/yaw_optimization_base.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/yaw_optimization/yaw_optimization_tools.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/yaw_optimization/yaw_optimizer_geometric.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/yaw_optimization/yaw_optimizer_scipy.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/optimization/yaw_optimization/yaw_optimizer_sr.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/par_floris_model.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/parallel_floris_model.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/demo_cp_ct_surfaces/iea_10MW_demo_cp_ct_surface.npz +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/demo_cp_ct_surfaces/iea_15MW_demo_cp_ct_surface.npz +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/demo_cp_ct_surfaces/nrel_5MW_demo_cp_ct_surface.npz +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_10MW.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_15MW.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_15MW_floating_multi_dim_cp_ct.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_15MW_multi_dim_TI_u.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_15MW_multi_dim_Tp_Hs.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_15MW_multi_dim_cp_ct.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/iea_22MW.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/nrel_5MW.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/turbine_previewer.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/turbine_library/turbine_utilities.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/type_dec.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/uncertain_floris_model.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/utilities.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/floris/wind_data.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/profiling/conftest.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/profiling/linux_perf.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/profiling/profiling.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/profiling/quality_metrics.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/profiling/serial_vectorize.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/profiling/timing.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/rafmudaf_floris.egg-info/dependency_links.txt +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/rafmudaf_floris.egg-info/requires.txt +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/rafmudaf_floris.egg-info/top_level.txt +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/setup.cfg +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/base_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/conftest.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/controller_dependent_operation_model_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/convert_v3_to_v4_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/core_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/__init__.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/iea_15MW_multi_dim_TI.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/input_full.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/nrel_5MW.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/nrel_5MW_custom.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/wind_rose.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/wind_ti_rose.csv +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/data/wrg_test.wrg +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/farm_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/floris_model_integration_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/flow_field_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/geometric_yaw_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/heterogeneous_map_integration_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/layout_optimization_integration_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/layout_visualization_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/load_optimization_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/par_floris_model_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/parallel_floris_model_integration_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/cumulative_curl_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/empirical_gauss_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/jensen_jimenez_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/none_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/random_search_layout_opt_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/scipy_layout_opt_regression.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/turbopark_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/turboparkgauss_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/turbulence_models_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/reg_tests/yaw_optimization_regression_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/rotor_velocity_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/serial_refine_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/turbine_grid_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/turbine_multi_dim_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/turbine_operation_models_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/turbine_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/turbine_utilities_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/turboparkgauss_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/type_dec_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/uncertain_floris_model_integration_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/unified_momentum_operation_model_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/utilities_unit_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/v3_to_v4_convert_test/gch.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/v3_to_v4_convert_test/nrel_5MW_v3.yaml +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/wake_unit_tests.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/wind_data_integration_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/wind_rose_wrg_test.py +0 -0
- {rafmudaf_floris-4.6.4.post1.dev13 → rafmudaf_floris-4.6.4.post1.dev22}/tests/yaw_optimization_integration_test.py +0 -0
|
@@ -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=
|
|
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()
|