-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add gridded layout optimizer #976
Conversation
After profiling, not surprisingly it appears that the slowest part of the code is that which checks, point by point, whether candidate locations are inside the boundary. This code relies on shapely's I tried a couple of quick things to speed this up, both of which failed:
Overall, I think we can treat the code as fast enough for now. When I run the new example 004_generate_gridded_layout.py with |
@paulf81 this is now ready for review |
floris/optimization/layout_optimization/layout_optimization_gridded.py
Outdated
Show resolved
Hide resolved
floris/optimization/layout_optimization/layout_optimization_gridded.py
Outdated
Show resolved
Hide resolved
# Create the default grid | ||
|
||
# use min_dist, hexagonal packing, and boundaries to create a grid. | ||
d = 1.1 * np.sqrt((self.xmax**2 - self.xmin**2) + (self.ymax**2 - self.ymin**2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious why 1.1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a little bit of over engineering to ensure that d
is sufficient to cover the boundary area, even after translations/rotations. May not be necessary, but I thought just easy to add a safety factor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks really great! All tests pass and examples run and produce clear results. Doc is also very clear. Approving and leave remaining minor comments up to you @misi9170
…ons, which are not relevant to this optimization procedure.
This pull requests adds a new "optimization" method that simply searches for the gridded layout (either a square grid or a hexagonal grid) that fits the most wind turbines into a specified boundary area. The spacing in the grid is fixed by the user, but the grid's rotation and translation is optimized (via a simple parameter sweep) to fit the most turbines into the boundary.
FlorisModel.run()
is not called, so there is no wake or AEP calculation---the optimizer simply chooses the grid that fits the most turbines. Where multiple rotations/translations result in the same number of turbines, the result returned is (arbitrarily) the first of those. @ejsimley has suggested we could consider a "tie-breaker" of running an AEP calculation for all layouts that have the maximum number of turbines and selecting that with the highest AEP; for now, this has been left as future work.There is no requirement that the boundary be a single area---users may specify a boundary with separate areas without issue.
The core code is complete. However, it currently runs somewhat slower than I'd hoped, and I intend to profile the code to see if there are any easy ways to speed it up.
To do:
Low-hanging fruit for speed-ups exploited