foxes 0.6.1__tar.gz → 0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of foxes might be problematic. Click here for more details.
- {foxes-0.6.1/foxes.egg-info → foxes-0.7}/PKG-INFO +13 -7
- {foxes-0.6.1 → foxes-0.7}/README.md +11 -6
- foxes-0.7/foxes/VERSION +1 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/downwind/downwind.py +131 -65
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/downwind/models/__init__.py +2 -1
- foxes-0.7/foxes/algorithms/downwind/models/farm_wakes_calc.py +152 -0
- foxes-0.7/foxes/algorithms/downwind/models/init_farm_data.py +134 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/downwind/models/point_wakes_calc.py +54 -65
- foxes-0.6.1/foxes/algorithms/downwind/models/calc_order.py → foxes-0.7/foxes/algorithms/downwind/models/reorder_farm_output.py +28 -26
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/iterative/iterative.py +100 -51
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/iterative/models/convergence.py +3 -3
- foxes-0.7/foxes/algorithms/iterative/models/farm_wakes_calc.py +141 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/sequential/models/seq_state.py +7 -6
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/sequential/sequential.py +81 -44
- {foxes-0.6.1 → foxes-0.7}/foxes/constants.py +33 -18
- {foxes-0.6.1 → foxes-0.7}/foxes/core/__init__.py +2 -2
- {foxes-0.6.1 → foxes-0.7}/foxes/core/algorithm.py +31 -12
- foxes-0.7/foxes/core/data.py +517 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/data_calc_model.py +27 -23
- {foxes-0.6.1 → foxes-0.7}/foxes/core/farm_controller.py +27 -28
- {foxes-0.6.1 → foxes-0.7}/foxes/core/farm_data_model.py +26 -4
- {foxes-0.6.1 → foxes-0.7}/foxes/core/model.py +186 -129
- foxes-0.7/foxes/core/partial_wakes_model.py +202 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/point_data_model.py +51 -18
- {foxes-0.6.1 → foxes-0.7}/foxes/core/rotor_model.py +59 -77
- {foxes-0.6.1 → foxes-0.7}/foxes/core/states.py +6 -6
- {foxes-0.6.1 → foxes-0.7}/foxes/core/turbine_model.py +4 -4
- {foxes-0.6.1 → foxes-0.7}/foxes/core/turbine_type.py +24 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/vertical_profile.py +3 -3
- {foxes-0.6.1 → foxes-0.7}/foxes/core/wake_frame.py +91 -50
- {foxes-0.6.1 → foxes-0.7}/foxes/core/wake_model.py +74 -43
- {foxes-0.6.1 → foxes-0.7}/foxes/core/wake_superposition.py +29 -26
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/__init__.py +1 -0
- foxes-0.7/foxes/input/farm_layout/from_random.py +49 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/__init__.py +1 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/create/__init__.py +1 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/create/random_abl_states.py +6 -2
- foxes-0.7/foxes/input/states/create/random_timeseries.py +56 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/field_data_nc.py +12 -8
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/multi_height.py +24 -14
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/scan_ws.py +13 -17
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/single.py +28 -20
- {foxes-0.6.1 → foxes-0.7}/foxes/input/states/states_table.py +22 -18
- {foxes-0.6.1 → foxes-0.7}/foxes/models/axial_induction_models/betz.py +1 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/models/farm_models/turbine2farm.py +2 -2
- {foxes-0.6.1 → foxes-0.7}/foxes/models/model_book.py +40 -14
- {foxes-0.6.1 → foxes-0.7}/foxes/models/partial_wakes/__init__.py +2 -2
- foxes-0.7/foxes/models/partial_wakes/axiwake.py +198 -0
- foxes-0.7/foxes/models/partial_wakes/centre.py +40 -0
- foxes-0.7/foxes/models/partial_wakes/grid.py +26 -0
- foxes-0.7/foxes/models/partial_wakes/rotor_points.py +98 -0
- foxes-0.7/foxes/models/partial_wakes/segregated.py +158 -0
- foxes-0.7/foxes/models/partial_wakes/top_hat.py +181 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/point_models/set_uniform_data.py +4 -4
- {foxes-0.6.1 → foxes-0.7}/foxes/models/point_models/tke2ti.py +4 -4
- {foxes-0.6.1 → foxes-0.7}/foxes/models/point_models/wake_deltas.py +4 -4
- {foxes-0.6.1 → foxes-0.7}/foxes/models/rotor_models/centre.py +15 -19
- {foxes-0.6.1 → foxes-0.7}/foxes/models/rotor_models/grid.py +2 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/models/rotor_models/levels.py +2 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/__init__.py +0 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/calculator.py +11 -7
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/kTI_model.py +13 -11
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/lookup_table.py +22 -9
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/power_mask.py +81 -51
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/rotor_centre_calc.py +17 -20
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/sector_management.py +5 -6
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/set_farm_vars.py +49 -20
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/table_factors.py +5 -5
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/thrust2ct.py +9 -5
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/yaw2yawm.py +7 -13
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_models/yawm2yaw.py +7 -11
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/PCt_file.py +84 -3
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/PCt_from_two.py +7 -3
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/null_type.py +2 -2
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -2
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/wsti2PCt_from_two.py +6 -2
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/farm_order.py +26 -22
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/rotor_wd.py +32 -31
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/seq_dynamic_wakes.py +112 -64
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/streamlines.py +51 -47
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/timelines.py +59 -47
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/yawed_wakes.py +63 -40
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/axisymmetric.py +31 -35
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/dist_sliced.py +50 -56
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/gaussian.py +33 -35
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/induction/rankine_half_body.py +79 -87
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/induction/rathmann.py +56 -63
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/induction/self_similar.py +59 -62
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/ti/crespo_hernandez.py +83 -74
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/ti/iec_ti.py +65 -75
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/top_hat.py +60 -69
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/wake_mirror.py +49 -54
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/wind/bastankhah14.py +44 -66
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/wind/bastankhah16.py +84 -111
- foxes-0.7/foxes/models/wake_models/wind/jensen.py +182 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/wind/turbopark.py +93 -133
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ti_linear.py +33 -27
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ti_max.py +33 -27
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ti_pow.py +35 -27
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ti_quadratic.py +33 -27
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ws_linear.py +39 -32
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ws_max.py +40 -33
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ws_pow.py +39 -32
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ws_product.py +35 -28
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/ws_quadratic.py +39 -32
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/constraints/min_dist.py +1 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/objectives/farm_vars.py +1 -1
- foxes-0.7/foxes/opt/problems/layout/farm_layout.py +137 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/__init__.py +1 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/farm_results_eval.py +1 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/output/flow_plots_2d/flow_plots.py +2 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/flow_plots_2d/get_fig.py +2 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/grids.py +1 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/output/rose_plot.py +3 -3
- foxes-0.7/foxes/output/rotor_point_plots.py +117 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/turbine_type_curves.py +2 -2
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/__init__.py +2 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/load.py +29 -0
- foxes-0.7/foxes/utils/random_xy.py +56 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/runners/runners.py +13 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/variables.py +10 -0
- {foxes-0.6.1 → foxes-0.7/foxes.egg-info}/PKG-INFO +13 -7
- {foxes-0.6.1 → foxes-0.7}/foxes.egg-info/SOURCES.txt +8 -4
- {foxes-0.6.1 → foxes-0.7}/foxes.egg-info/requires.txt +1 -0
- {foxes-0.6.1 → foxes-0.7}/setup.cfg +1 -0
- foxes-0.6.1/foxes/VERSION +0 -1
- foxes-0.6.1/foxes/algorithms/downwind/models/farm_wakes_calc.py +0 -120
- foxes-0.6.1/foxes/algorithms/iterative/models/farm_wakes_calc.py +0 -134
- foxes-0.6.1/foxes/core/data.py +0 -223
- foxes-0.6.1/foxes/core/partial_wakes_model.py +0 -199
- foxes-0.6.1/foxes/models/partial_wakes/axiwake.py +0 -325
- foxes-0.6.1/foxes/models/partial_wakes/distsliced.py +0 -322
- foxes-0.6.1/foxes/models/partial_wakes/grid.py +0 -82
- foxes-0.6.1/foxes/models/partial_wakes/mapped.py +0 -252
- foxes-0.6.1/foxes/models/partial_wakes/rotor_points.py +0 -192
- foxes-0.6.1/foxes/models/partial_wakes/top_hat.py +0 -289
- foxes-0.6.1/foxes/models/turbine_models/set_XYHD.py +0 -130
- foxes-0.6.1/foxes/models/wake_models/wind/jensen.py +0 -204
- foxes-0.6.1/foxes/opt/problems/layout/farm_layout.py +0 -196
- {foxes-0.6.1 → foxes-0.7}/LICENSE +0 -0
- {foxes-0.6.1 → foxes-0.7}/Logo_FOXES.svg +0 -0
- {foxes-0.6.1 → foxes-0.7}/MANIFEST.in +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/downwind/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/downwind/models/set_amb_farm_results.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/downwind/models/set_amb_point_results.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/iterative/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/iterative/models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/iterative/models/urelax.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/sequential/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/sequential/models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/algorithms/sequential/models/plugin.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/axial_induction_model.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/farm_model.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/turbine.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/core/wind_farm.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/farms/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/farms/test_farm_67.csv +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/parse.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/power_ct_curves/DTU-10MW-D178d3-H119.csv +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/power_ct_curves/IEA-15MW-D240-H150.csv +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/power_ct_curves/IWT-7d5MW-D164-H100.csv +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/power_ct_curves/NREL-5MW-D126-H90.csv +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/power_ct_curves/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/WRF-Timeseries-4464.csv.gz +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/abl_states_6000.csv.gz +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/timeseries_100.csv.gz +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/timeseries_3000.csv.gz +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/timeseries_8000.csv.gz +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/wind_rose_bremen.csv +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/wind_rotation.nc +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/states/winds100.tab +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/data/static_data.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/from_csv.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/from_df.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/from_file.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/from_json.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/grid.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/farm_layout/row.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/windio/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/input/windio/windio.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/axial_induction_models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/axial_induction_models/madsen.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/farm_controllers/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/farm_controllers/basic.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/farm_models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/point_models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/rotor_models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/CpCt_file.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/CpCt_from_two.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/turbine_types/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/abl_log_neutral_ws.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/abl_log_stable_ws.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/abl_log_unstable_ws.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/abl_log_ws.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/data_profile.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/sheared_ws.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/vertical_profiles/uniform.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_frames/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/induction/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/induction/self_similar2020.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/ti/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_models/wind/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/models/wake_superpositions/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/constraints/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/constraints/area_geometry.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/core/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/core/farm_constraint.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/core/farm_objective.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/core/farm_opt_problem.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/core/farm_vars_problem.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/core/pop_states.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/objectives/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/objectives/max_n_turbines.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/constraints.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/geom_layout.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/geom_layout_gridded.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/geom_reggrid.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/geom_reggrids.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/geom_layouts/objectives.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/reggrids_layout.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/layout/regular_layout.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/opt/problems/opt_farm_vars.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/animation.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/calc_points.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/farm_layout.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/flow_plots_2d/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/flow_plots_2d/seq_flow_ani_plugin.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/flow_plots_2d.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/output.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/results_writer.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/round.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/slice_data.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/output/state_turbine_map.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/abl/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/abl/neutral.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/abl/sheared.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/abl/stable.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/abl/unstable.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/cubic_roots.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/data_book.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/dict.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/exec_python.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/area_geometry.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/circle.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/example_intersection.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/example_union.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/half_plane.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geom2d/polygon.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geopandas_helpers.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/geopandas_utils.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/pandas_helpers.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/pandas_utils.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/plotly_helpers.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/regularize.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/runners/__init__.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/subclasses.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/tab_files.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/two_circles.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/wind_dir.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/windrose_plot.py +1 -1
- {foxes-0.6.1 → foxes-0.7}/foxes/utils/xarray_utils.py +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes.egg-info/dependency_links.txt +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes.egg-info/top_level.txt +0 -0
- {foxes-0.6.1 → foxes-0.7}/foxes.egg-info/zip-safe +0 -0
- {foxes-0.6.1 → foxes-0.7}/pyproject.toml +0 -0
- {foxes-0.6.1 → foxes-0.7}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: foxes
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7
|
|
4
4
|
Summary: Farm Optimization and eXtended yield Evaluation Software
|
|
5
5
|
Author: Fraunhofer IWES
|
|
6
6
|
Author-email: jonas.schmidt@iwes.fraunhofer.de
|
|
@@ -38,6 +38,7 @@ Requires-Dist: nbsphinx; extra == "doc"
|
|
|
38
38
|
Requires-Dist: ipykernel; extra == "doc"
|
|
39
39
|
Requires-Dist: ipywidgets; extra == "doc"
|
|
40
40
|
Requires-Dist: m2r2; extra == "doc"
|
|
41
|
+
Requires-Dist: lxml_html_clean; extra == "doc"
|
|
41
42
|
Provides-Extra: all
|
|
42
43
|
Requires-Dist: windio>=1.0; extra == "all"
|
|
43
44
|
Requires-Dist: flake8; extra == "all"
|
|
@@ -102,7 +103,7 @@ Evaluation Software"`
|
|
|
102
103
|
}
|
|
103
104
|
```
|
|
104
105
|
|
|
105
|
-
##
|
|
106
|
+
## Installation via pip
|
|
106
107
|
|
|
107
108
|
The supported Python versions are:
|
|
108
109
|
|
|
@@ -110,8 +111,7 @@ The supported Python versions are:
|
|
|
110
111
|
- `Python 3.9`
|
|
111
112
|
- `Python 3.10`
|
|
112
113
|
- `Python 3.11`
|
|
113
|
-
|
|
114
|
-
## Installation via pip
|
|
114
|
+
- `Python 3.12`
|
|
115
115
|
|
|
116
116
|
### Virtual Python environment
|
|
117
117
|
|
|
@@ -162,6 +162,14 @@ The last line makes sure that all your code changes are included whenever import
|
|
|
162
162
|
|
|
163
163
|
## Installation via conda
|
|
164
164
|
|
|
165
|
+
The supported Python versions are:
|
|
166
|
+
|
|
167
|
+
- `Python 3.8`
|
|
168
|
+
- `Python 3.9`
|
|
169
|
+
- `Python 3.10`
|
|
170
|
+
- `Python 3.11`
|
|
171
|
+
- `Python 3.12`
|
|
172
|
+
|
|
165
173
|
### Preparation
|
|
166
174
|
|
|
167
175
|
It is strongly recommend to use the `libmamba` dependency solver instead of the default solver. Install it once by
|
|
@@ -233,12 +241,10 @@ import foxes
|
|
|
233
241
|
|
|
234
242
|
states = foxes.input.states.Timeseries("timeseries_3000.csv.gz", ["WS", "WD","TI","RHO"])
|
|
235
243
|
|
|
236
|
-
mbook = foxes.ModelBook()
|
|
237
|
-
|
|
238
244
|
farm = foxes.WindFarm()
|
|
239
245
|
foxes.input.farm_layout.add_from_file(farm, "test_farm_67.csv", turbine_models=["NREL5MW"])
|
|
240
246
|
|
|
241
|
-
algo = foxes.algorithms.Downwind(
|
|
247
|
+
algo = foxes.algorithms.Downwind(farm, states, ["Jensen_linear_k007"])
|
|
242
248
|
farm_results = algo.calc_farm()
|
|
243
249
|
|
|
244
250
|
print(farm_results)
|
|
@@ -49,7 +49,7 @@ Evaluation Software"`
|
|
|
49
49
|
}
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
##
|
|
52
|
+
## Installation via pip
|
|
53
53
|
|
|
54
54
|
The supported Python versions are:
|
|
55
55
|
|
|
@@ -57,8 +57,7 @@ The supported Python versions are:
|
|
|
57
57
|
- `Python 3.9`
|
|
58
58
|
- `Python 3.10`
|
|
59
59
|
- `Python 3.11`
|
|
60
|
-
|
|
61
|
-
## Installation via pip
|
|
60
|
+
- `Python 3.12`
|
|
62
61
|
|
|
63
62
|
### Virtual Python environment
|
|
64
63
|
|
|
@@ -109,6 +108,14 @@ The last line makes sure that all your code changes are included whenever import
|
|
|
109
108
|
|
|
110
109
|
## Installation via conda
|
|
111
110
|
|
|
111
|
+
The supported Python versions are:
|
|
112
|
+
|
|
113
|
+
- `Python 3.8`
|
|
114
|
+
- `Python 3.9`
|
|
115
|
+
- `Python 3.10`
|
|
116
|
+
- `Python 3.11`
|
|
117
|
+
- `Python 3.12`
|
|
118
|
+
|
|
112
119
|
### Preparation
|
|
113
120
|
|
|
114
121
|
It is strongly recommend to use the `libmamba` dependency solver instead of the default solver. Install it once by
|
|
@@ -180,12 +187,10 @@ import foxes
|
|
|
180
187
|
|
|
181
188
|
states = foxes.input.states.Timeseries("timeseries_3000.csv.gz", ["WS", "WD","TI","RHO"])
|
|
182
189
|
|
|
183
|
-
mbook = foxes.ModelBook()
|
|
184
|
-
|
|
185
190
|
farm = foxes.WindFarm()
|
|
186
191
|
foxes.input.farm_layout.add_from_file(farm, "test_farm_67.csv", turbine_models=["NREL5MW"])
|
|
187
192
|
|
|
188
|
-
algo = foxes.algorithms.Downwind(
|
|
193
|
+
algo = foxes.algorithms.Downwind(farm, states, ["Jensen_linear_k007"])
|
|
189
194
|
farm_results = algo.calc_farm()
|
|
190
195
|
|
|
191
196
|
print(farm_results)
|
foxes-0.7/foxes/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.7
|
|
@@ -18,14 +18,16 @@ class Downwind(Algorithm):
|
|
|
18
18
|
----------
|
|
19
19
|
states: foxes.core.States
|
|
20
20
|
The ambient states
|
|
21
|
-
wake_models:
|
|
22
|
-
The wake models
|
|
21
|
+
wake_models: dict
|
|
22
|
+
The wake models. Key: wake model name,
|
|
23
|
+
value: foxes.core.WakeModel
|
|
23
24
|
rotor_model: foxes.core.RotorModel
|
|
24
25
|
The rotor model, for all turbines
|
|
25
26
|
wake_frame: foxes.core.WakeFrame
|
|
26
27
|
The wake frame
|
|
27
|
-
|
|
28
|
-
The partial wakes model
|
|
28
|
+
partial_wakes: dict
|
|
29
|
+
The partial wakes mapping. Key: wake model name,
|
|
30
|
+
value: foxes.core.PartialWakesModel
|
|
29
31
|
farm_controller: foxes.core.FarmController
|
|
30
32
|
The farm controller
|
|
31
33
|
n_states: int
|
|
@@ -35,36 +37,38 @@ class Downwind(Algorithm):
|
|
|
35
37
|
|
|
36
38
|
"""
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
DEFAULT_FARM_OUTPUTS = [
|
|
41
|
+
FV.X,
|
|
42
|
+
FV.Y,
|
|
43
|
+
FV.H,
|
|
44
|
+
FV.D,
|
|
45
|
+
FV.AMB_WD,
|
|
46
|
+
FV.AMB_REWS,
|
|
47
|
+
FV.AMB_TI,
|
|
48
|
+
FV.AMB_RHO,
|
|
49
|
+
FV.AMB_P,
|
|
50
|
+
FV.WD,
|
|
51
|
+
FV.REWS,
|
|
52
|
+
FV.YAW,
|
|
53
|
+
FV.TI,
|
|
54
|
+
FV.CT,
|
|
55
|
+
FV.P,
|
|
56
|
+
FV.ORDER,
|
|
57
|
+
FV.WEIGHT,
|
|
58
|
+
]
|
|
55
59
|
|
|
56
60
|
def __init__(
|
|
57
61
|
self,
|
|
58
|
-
mbook,
|
|
59
62
|
farm,
|
|
60
63
|
states,
|
|
61
64
|
wake_models,
|
|
62
65
|
rotor_model="centre",
|
|
63
66
|
wake_frame="rotor_wd",
|
|
64
|
-
|
|
67
|
+
partial_wakes=None,
|
|
65
68
|
farm_controller="basic_ctrl",
|
|
66
|
-
chunks={FC.STATE: 1000, FC.POINT:
|
|
69
|
+
chunks={FC.STATE: 1000, FC.POINT: 4000},
|
|
67
70
|
wake_mirrors={},
|
|
71
|
+
mbook=None,
|
|
68
72
|
dbook=None,
|
|
69
73
|
verbosity=1,
|
|
70
74
|
):
|
|
@@ -73,8 +77,6 @@ class Downwind(Algorithm):
|
|
|
73
77
|
|
|
74
78
|
Parameters
|
|
75
79
|
----------
|
|
76
|
-
mbook: foxes.ModelBook
|
|
77
|
-
The model book
|
|
78
80
|
farm: foxes.WindFarm
|
|
79
81
|
The wind farm
|
|
80
82
|
states: foxes.core.States
|
|
@@ -88,9 +90,9 @@ class Downwind(Algorithm):
|
|
|
88
90
|
wake_frame: str
|
|
89
91
|
The wake frame. Will be looked up in the
|
|
90
92
|
model book
|
|
91
|
-
|
|
92
|
-
The partial wakes
|
|
93
|
-
|
|
93
|
+
partial_wakes: dict, list or str, optional
|
|
94
|
+
The partial wakes mapping. Key: wake model name,
|
|
95
|
+
value: partial wake model name
|
|
94
96
|
farm_controller: str
|
|
95
97
|
The farm controller. Will be
|
|
96
98
|
looked up in the model book
|
|
@@ -100,12 +102,17 @@ class Downwind(Algorithm):
|
|
|
100
102
|
wake_mirrors: dict
|
|
101
103
|
Switch on wake mirrors for wake models.
|
|
102
104
|
Key: wake model name, value: list of heights
|
|
105
|
+
mbook: foxes.ModelBook, optional
|
|
106
|
+
The model book
|
|
103
107
|
dbook: foxes.DataBook, optional
|
|
104
108
|
The data book, or None for default
|
|
105
109
|
verbosity: int
|
|
106
110
|
The verbosity level, 0 means silent
|
|
107
111
|
|
|
108
112
|
"""
|
|
113
|
+
if mbook is None:
|
|
114
|
+
mbook = fm.ModelBook()
|
|
115
|
+
|
|
109
116
|
super().__init__(mbook, farm, chunks, verbosity, dbook)
|
|
110
117
|
|
|
111
118
|
self.states = states
|
|
@@ -115,13 +122,10 @@ class Downwind(Algorithm):
|
|
|
115
122
|
self.rotor_model = self.mbook.rotor_models[rotor_model]
|
|
116
123
|
self.rotor_model.name = rotor_model
|
|
117
124
|
|
|
118
|
-
self.partial_wakes_model = self.mbook.partial_wakes[partial_wakes_model]
|
|
119
|
-
self.partial_wakes_model.name = partial_wakes_model
|
|
120
|
-
|
|
121
125
|
self.wake_frame = self.mbook.wake_frames[wake_frame]
|
|
122
126
|
self.wake_frame.name = wake_frame
|
|
123
127
|
|
|
124
|
-
self.wake_models =
|
|
128
|
+
self.wake_models = {}
|
|
125
129
|
for w in wake_models:
|
|
126
130
|
m = self.mbook.wake_models[w]
|
|
127
131
|
m.name = w
|
|
@@ -135,14 +139,63 @@ class Downwind(Algorithm):
|
|
|
135
139
|
f"Wake model '{w}' is mirrored with heights {m.heights}, cannot apply WakeMirror with heights {hts}"
|
|
136
140
|
)
|
|
137
141
|
else:
|
|
138
|
-
self.wake_models
|
|
142
|
+
self.wake_models[w] = fm.wake_models.WakeMirror(m, heights=hts)
|
|
139
143
|
|
|
140
144
|
else:
|
|
141
|
-
self.wake_models
|
|
145
|
+
self.wake_models[w] = m
|
|
146
|
+
|
|
147
|
+
self.partial_wakes = {}
|
|
148
|
+
if partial_wakes is None:
|
|
149
|
+
partial_wakes = {}
|
|
150
|
+
if isinstance(partial_wakes, list) and len(partial_wakes) == 1:
|
|
151
|
+
partial_wakes = partial_wakes[0]
|
|
152
|
+
if isinstance(partial_wakes, str):
|
|
153
|
+
for w in wake_models:
|
|
154
|
+
try:
|
|
155
|
+
pw = partial_wakes
|
|
156
|
+
except TypeError:
|
|
157
|
+
pw = mbook.default_partial_wakes(self.wake_models[w])
|
|
158
|
+
self.partial_wakes[w] = self.mbook.partial_wakes[pw]
|
|
159
|
+
self.partial_wakes[w].name = pw
|
|
160
|
+
elif isinstance(partial_wakes, list):
|
|
161
|
+
for i, w in enumerate(wake_models):
|
|
162
|
+
if i >= len(partial_wakes):
|
|
163
|
+
raise IndexError(
|
|
164
|
+
f"Not enough partial wakes in list {partial_wakes}, expecting {len(wake_models)}"
|
|
165
|
+
)
|
|
166
|
+
pw = partial_wakes[i]
|
|
167
|
+
self.partial_wakes[w] = self.mbook.partial_wakes[pw]
|
|
168
|
+
self.partial_wakes[w].name = pw
|
|
169
|
+
else:
|
|
170
|
+
for w in wake_models:
|
|
171
|
+
if w in partial_wakes:
|
|
172
|
+
pw = partial_wakes[w]
|
|
173
|
+
else:
|
|
174
|
+
pw = mbook.default_partial_wakes(self.wake_models[w])
|
|
175
|
+
self.partial_wakes[w] = self.mbook.partial_wakes[pw]
|
|
176
|
+
self.partial_wakes[w].name = pw
|
|
142
177
|
|
|
143
178
|
self.farm_controller = self.mbook.farm_controllers[farm_controller]
|
|
144
179
|
self.farm_controller.name = farm_controller
|
|
145
180
|
|
|
181
|
+
@classmethod
|
|
182
|
+
def get_model(cls, name):
|
|
183
|
+
"""
|
|
184
|
+
Get the algorithm specific model
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
name: str
|
|
189
|
+
The model name
|
|
190
|
+
|
|
191
|
+
Returns
|
|
192
|
+
-------
|
|
193
|
+
model: foxes.core.model
|
|
194
|
+
The model
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
return getattr(mdls, name)
|
|
198
|
+
|
|
146
199
|
def _print_deco(self, func_name, n_points=None):
|
|
147
200
|
"""
|
|
148
201
|
Helper function for printing model names
|
|
@@ -160,13 +213,16 @@ class Downwind(Algorithm):
|
|
|
160
213
|
print(f" states : {self.states}")
|
|
161
214
|
print(f" rotor : {self.rotor_model}")
|
|
162
215
|
print(f" controller: {self.farm_controller}")
|
|
163
|
-
print(f" partialwks: {self.partial_wakes_model}")
|
|
164
216
|
print(f" wake frame: {self.wake_frame}")
|
|
165
217
|
print(deco)
|
|
166
218
|
print(f" wakes:")
|
|
167
|
-
for i, w in enumerate(self.wake_models):
|
|
219
|
+
for i, w in enumerate(self.wake_models.values()):
|
|
168
220
|
print(f" {i}) {w}")
|
|
169
221
|
print(deco)
|
|
222
|
+
print(f" partial wakes:")
|
|
223
|
+
for i, (w, p) in enumerate(self.partial_wakes.items()):
|
|
224
|
+
print(f" {i}) {w}: {p}")
|
|
225
|
+
print(deco)
|
|
170
226
|
print(f" turbine models:")
|
|
171
227
|
for i, m in enumerate(self.farm_controller.pre_rotor_models.models):
|
|
172
228
|
print(f" {i}) {m} [pre-rotor]")
|
|
@@ -226,8 +282,9 @@ class Downwind(Algorithm):
|
|
|
226
282
|
self.rotor_model,
|
|
227
283
|
self.farm_controller,
|
|
228
284
|
self.wake_frame,
|
|
229
|
-
|
|
230
|
-
|
|
285
|
+
]
|
|
286
|
+
mdls += list(self.wake_models.values())
|
|
287
|
+
mdls += list(self.partial_wakes.values())
|
|
231
288
|
|
|
232
289
|
return mdls
|
|
233
290
|
|
|
@@ -245,6 +302,7 @@ class Downwind(Algorithm):
|
|
|
245
302
|
|
|
246
303
|
def _collect_farm_models(
|
|
247
304
|
self,
|
|
305
|
+
outputs,
|
|
248
306
|
calc_parameters,
|
|
249
307
|
ambient,
|
|
250
308
|
):
|
|
@@ -253,73 +311,68 @@ class Downwind(Algorithm):
|
|
|
253
311
|
"""
|
|
254
312
|
# prepare:
|
|
255
313
|
calc_pars = []
|
|
256
|
-
t2f = fm.farm_models.Turbine2FarmModel
|
|
257
314
|
mlist = FarmDataModelList(models=[])
|
|
258
315
|
mlist.name = f"{self.name}_calc"
|
|
259
316
|
|
|
260
|
-
# 0)
|
|
261
|
-
m = fm.turbine_models.SetXYHD()
|
|
262
|
-
mlist.models.append(t2f(m))
|
|
263
|
-
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
264
|
-
|
|
265
|
-
# 1) run pre-rotor turbine models via farm controller:
|
|
317
|
+
# 0) run pre-rotor turbine models via farm controller:
|
|
266
318
|
mlist.models.append(self.farm_controller)
|
|
267
319
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
268
320
|
calc_pars[-1]["pre_rotor"] = True
|
|
269
321
|
|
|
270
|
-
#
|
|
271
|
-
mlist.models.append(
|
|
272
|
-
mlist.models[-1].name = "calc_yaw_" + mlist.models[-1].name
|
|
322
|
+
# 1) set initial data:
|
|
323
|
+
mlist.models.append(self.get_model("InitFarmData")())
|
|
273
324
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
274
325
|
|
|
275
|
-
#
|
|
326
|
+
# 2) calculate ambient rotor results:
|
|
276
327
|
mlist.models.append(self.rotor_model)
|
|
277
328
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
278
329
|
calc_pars[-1].update(
|
|
279
330
|
{"store_rpoints": True, "store_rweights": True, "store_amb_res": True}
|
|
280
331
|
)
|
|
281
332
|
|
|
282
|
-
#
|
|
283
|
-
mlist.models.append(self.get_model("CalcOrder")())
|
|
284
|
-
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
285
|
-
|
|
286
|
-
# 5) run post-rotor turbine models via farm controller:
|
|
333
|
+
# 3) run post-rotor turbine models via farm controller:
|
|
287
334
|
mlist.models.append(self.farm_controller)
|
|
288
335
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
289
336
|
calc_pars[-1]["pre_rotor"] = False
|
|
290
337
|
|
|
291
|
-
#
|
|
338
|
+
# 4) copy results to ambient, requires self.farm_vars:
|
|
292
339
|
self.farm_vars = mlist.output_farm_vars(self)
|
|
293
340
|
mlist.models.append(self.get_model("SetAmbFarmResults")())
|
|
294
341
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
295
342
|
|
|
296
|
-
#
|
|
343
|
+
# 5) calculate wake effects:
|
|
297
344
|
if not ambient:
|
|
298
345
|
mlist.models.append(self.get_model("FarmWakesCalculation")())
|
|
299
346
|
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
300
347
|
|
|
348
|
+
# 6) reorder back to state-turbine dimensions:
|
|
349
|
+
if outputs != False:
|
|
350
|
+
mlist.models.append(self.get_model("ReorderFarmOutput")(outputs))
|
|
351
|
+
calc_pars.append(calc_parameters.get(mlist.models[-1].name, {}))
|
|
352
|
+
|
|
301
353
|
return mlist, calc_pars
|
|
302
354
|
|
|
303
355
|
def _calc_farm_vars(self, mlist):
|
|
304
356
|
"""Helper function that gathers the farm variables"""
|
|
305
357
|
self.farm_vars = sorted(list(set([FV.WEIGHT] + mlist.output_farm_vars(self))))
|
|
306
358
|
|
|
307
|
-
def _run_farm_calc(self, mlist, *data, **kwargs):
|
|
359
|
+
def _run_farm_calc(self, mlist, *data, outputs=None, **kwargs):
|
|
308
360
|
"""Helper function for running the main farm calculation"""
|
|
309
361
|
self.print(
|
|
310
362
|
f"\nCalculating {self.n_states} states for {self.n_turbines} turbines"
|
|
311
363
|
)
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
)
|
|
364
|
+
out_vars = self.farm_vars if outputs is None else outputs
|
|
365
|
+
farm_results = mlist.run_calculation(self, *data, out_vars=out_vars, **kwargs)
|
|
315
366
|
farm_results[FC.TNAME] = ((FC.TURBINE,), self.farm.turbine_names)
|
|
316
|
-
|
|
317
|
-
|
|
367
|
+
for v in [FV.ORDER, FV.ORDER_SSEL, FV.ORDER_INV]:
|
|
368
|
+
if v in farm_results:
|
|
369
|
+
farm_results[v] = farm_results[v].astype(FC.ITYPE)
|
|
318
370
|
|
|
319
371
|
return farm_results
|
|
320
372
|
|
|
321
373
|
def calc_farm(
|
|
322
374
|
self,
|
|
375
|
+
outputs=None,
|
|
323
376
|
calc_parameters={},
|
|
324
377
|
persist=True,
|
|
325
378
|
finalize=True,
|
|
@@ -335,6 +388,8 @@ class Downwind(Algorithm):
|
|
|
335
388
|
calc_parameters: dict
|
|
336
389
|
Parameters for model calculation.
|
|
337
390
|
Key: model name str, value: parameter dict
|
|
391
|
+
outputs: list of str, optional
|
|
392
|
+
The output variables, or None for defaults
|
|
338
393
|
persist: bool
|
|
339
394
|
Switch for forcing dask to load all model data
|
|
340
395
|
into memory
|
|
@@ -362,7 +417,9 @@ class Downwind(Algorithm):
|
|
|
362
417
|
self._print_deco("calc_farm")
|
|
363
418
|
|
|
364
419
|
# collect models:
|
|
365
|
-
|
|
420
|
+
if outputs == "default":
|
|
421
|
+
outputs = self.DEFAULT_FARM_OUTPUTS
|
|
422
|
+
mlist, calc_pars = self._collect_farm_models(outputs, calc_parameters, ambient)
|
|
366
423
|
|
|
367
424
|
# initialize models:
|
|
368
425
|
if not mlist.initialized:
|
|
@@ -370,12 +427,19 @@ class Downwind(Algorithm):
|
|
|
370
427
|
self._calc_farm_vars(mlist)
|
|
371
428
|
self._print_model_oder(mlist, calc_pars)
|
|
372
429
|
|
|
430
|
+
# update outputs:
|
|
431
|
+
if outputs is None:
|
|
432
|
+
outputs = self.farm_vars
|
|
433
|
+
else:
|
|
434
|
+
outputs = sorted(list(set(outputs).intersection(self.farm_vars)))
|
|
435
|
+
|
|
373
436
|
# get input model data:
|
|
374
437
|
models_data = self.get_models_data()
|
|
375
438
|
if persist:
|
|
376
439
|
models_data = models_data.persist()
|
|
377
440
|
self.print("\nInput data:\n\n", models_data, "\n")
|
|
378
|
-
self.print(f"\
|
|
441
|
+
self.print(f"\nFarm variables:", ", ".join(self.farm_vars))
|
|
442
|
+
self.print(f"\nOutput variables:", ", ".join(outputs))
|
|
379
443
|
self.print(f"\nChunks: {self.chunks}\n")
|
|
380
444
|
|
|
381
445
|
# run main calculation:
|
|
@@ -383,6 +447,7 @@ class Downwind(Algorithm):
|
|
|
383
447
|
mlist,
|
|
384
448
|
models_data,
|
|
385
449
|
parameters=calc_pars,
|
|
450
|
+
outputs=outputs,
|
|
386
451
|
**kwargs,
|
|
387
452
|
)
|
|
388
453
|
del models_data
|
|
@@ -559,6 +624,7 @@ class Downwind(Algorithm):
|
|
|
559
624
|
self.print(
|
|
560
625
|
f"Calculating {len(ovars)} variables at {points.shape[1]} points in {self.n_states} states"
|
|
561
626
|
)
|
|
627
|
+
|
|
562
628
|
point_results = mlist.run_calculation(
|
|
563
629
|
self,
|
|
564
630
|
models_data,
|
|
@@ -2,4 +2,5 @@ from .set_amb_farm_results import SetAmbFarmResults
|
|
|
2
2
|
from .set_amb_point_results import SetAmbPointResults
|
|
3
3
|
from .farm_wakes_calc import FarmWakesCalculation
|
|
4
4
|
from .point_wakes_calc import PointWakesCalculation
|
|
5
|
-
from .
|
|
5
|
+
from .init_farm_data import InitFarmData
|
|
6
|
+
from .reorder_farm_output import ReorderFarmOutput
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
|
|
4
|
+
from foxes.core import FarmDataModel, TData
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FarmWakesCalculation(FarmDataModel):
|
|
8
|
+
"""
|
|
9
|
+
This model calculates wakes effects on farm data.
|
|
10
|
+
|
|
11
|
+
:group: algorithms.downwind.models
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def output_farm_vars(self, algo):
|
|
16
|
+
"""
|
|
17
|
+
The variables which are being modified by the model.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
algo: foxes.core.Algorithm
|
|
22
|
+
The calculation algorithm
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
output_vars: list of str
|
|
27
|
+
The output variable names
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
ovars = algo.rotor_model.output_farm_vars(
|
|
31
|
+
algo
|
|
32
|
+
) + algo.farm_controller.output_farm_vars(algo)
|
|
33
|
+
return list(dict.fromkeys(ovars))
|
|
34
|
+
|
|
35
|
+
def calculate(self, algo, mdata, fdata):
|
|
36
|
+
""" "
|
|
37
|
+
The main model calculation.
|
|
38
|
+
|
|
39
|
+
This function is executed on a single chunk of data,
|
|
40
|
+
all computations should be based on numpy arrays.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
algo: foxes.core.Algorithm
|
|
45
|
+
The calculation algorithm
|
|
46
|
+
mdata: foxes.core.Data
|
|
47
|
+
The model data
|
|
48
|
+
fdata: foxes.core.Data
|
|
49
|
+
The farm data
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
results: dict
|
|
54
|
+
The resulting data, keys: output variable str.
|
|
55
|
+
Values: numpy.ndarray with shape (n_states, n_turbines)
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
# collect ambient rotor results and weights:
|
|
59
|
+
rotor = algo.rotor_model
|
|
60
|
+
weights = rotor.from_data_or_store(rotor.RWEIGHTS, algo, mdata)
|
|
61
|
+
amb_res = rotor.from_data_or_store(rotor.AMBRES, algo, mdata)
|
|
62
|
+
|
|
63
|
+
# generate all wake evaluation points
|
|
64
|
+
# (n_states, n_order, n_rpoints)
|
|
65
|
+
pwake2tdata = {}
|
|
66
|
+
for wname, wmodel in algo.wake_models.items():
|
|
67
|
+
pwake = algo.partial_wakes[wname]
|
|
68
|
+
if pwake.name not in pwake2tdata:
|
|
69
|
+
tpoints, tweights = pwake.get_wake_points(algo, mdata, fdata)
|
|
70
|
+
pwake2tdata[pwake.name] = TData.from_tpoints(tpoints, tweights)
|
|
71
|
+
|
|
72
|
+
def _get_wdata(tdatap, wdeltas, s):
|
|
73
|
+
"""Helper function for wake data extraction"""
|
|
74
|
+
tdata = tdatap.get_slice(s, keep=True)
|
|
75
|
+
wdelta = {v: d[s] for v, d in wdeltas.items()}
|
|
76
|
+
return tdata, wdelta
|
|
77
|
+
|
|
78
|
+
def _evaluate(tdata, amb_res, weights, wake_res, wdeltas, oi, wmodel, pwake):
|
|
79
|
+
"""Helper function for data evaluation at turbines"""
|
|
80
|
+
wres = pwake.finalize_wakes(
|
|
81
|
+
algo, mdata, fdata, tdata, amb_res, weights, wdeltas, wmodel, oi
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
hres = {v: d[:, oi, None] for v, d in wake_res.items()}
|
|
85
|
+
for v, d in wres.items():
|
|
86
|
+
if v in wake_res:
|
|
87
|
+
hres[v] += d[:, None]
|
|
88
|
+
|
|
89
|
+
rotor.eval_rpoint_results(
|
|
90
|
+
algo, mdata, fdata, hres, weights, downwind_index=oi
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
res = algo.farm_controller.calculate(
|
|
94
|
+
algo, mdata, fdata, pre_rotor=False, downwind_index=oi
|
|
95
|
+
)
|
|
96
|
+
fdata.update(res)
|
|
97
|
+
|
|
98
|
+
wake_res = deepcopy(amb_res)
|
|
99
|
+
n_turbines = mdata.n_turbines
|
|
100
|
+
run_up = None
|
|
101
|
+
run_down = None
|
|
102
|
+
for wname, wmodel in algo.wake_models.items():
|
|
103
|
+
pwake = algo.partial_wakes[wname]
|
|
104
|
+
tdatap = pwake2tdata[pwake.name]
|
|
105
|
+
wdeltas = pwake.new_wake_deltas(algo, mdata, fdata, tdatap, wmodel)
|
|
106
|
+
|
|
107
|
+
# downwind:
|
|
108
|
+
if wmodel.affects_downwind:
|
|
109
|
+
run_up = wname
|
|
110
|
+
for oi in range(n_turbines):
|
|
111
|
+
if oi > 0:
|
|
112
|
+
_evaluate(
|
|
113
|
+
tdatap,
|
|
114
|
+
amb_res,
|
|
115
|
+
weights,
|
|
116
|
+
wake_res,
|
|
117
|
+
wdeltas,
|
|
118
|
+
oi,
|
|
119
|
+
wmodel,
|
|
120
|
+
pwake,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if oi < n_turbines - 1:
|
|
124
|
+
tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, oi + 1 :])
|
|
125
|
+
pwake.contribute(algo, mdata, fdata, tdata, oi, wdelta, wmodel)
|
|
126
|
+
|
|
127
|
+
# upwind:
|
|
128
|
+
else:
|
|
129
|
+
run_down = wname
|
|
130
|
+
for oi in range(n_turbines - 1, -1, -1):
|
|
131
|
+
if oi < n_turbines - 1:
|
|
132
|
+
_evaluate(
|
|
133
|
+
tdatap,
|
|
134
|
+
amb_res,
|
|
135
|
+
weights,
|
|
136
|
+
wake_res,
|
|
137
|
+
wdeltas,
|
|
138
|
+
oi,
|
|
139
|
+
wmodel,
|
|
140
|
+
pwake,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if oi > 0:
|
|
144
|
+
tdata, wdelta = _get_wdata(tdatap, wdeltas, np.s_[:, :oi])
|
|
145
|
+
pwake.contribute(algo, mdata, fdata, tdata, oi, wdelta, wmodel)
|
|
146
|
+
|
|
147
|
+
if run_up is not None and run_down is not None:
|
|
148
|
+
raise KeyError(
|
|
149
|
+
f"Wake model '{run_up}' is an upwind model, wake model '{run_down}' is a downwind model: Require iterative algorithm"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
return {v: fdata[v] for v in self.output_farm_vars(algo)}
|