Skip to content

Conversation

@cfrontin
Copy link
Collaborator

@cfrontin cfrontin commented Jan 7, 2026

Depends on #167.

@cfrontin cfrontin self-assigned this Jan 7, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds eagle density function capabilities for eco-constrained wind farm design optimization. It introduces components for evaluating eagle presence density at turbine locations and computing distances to exclusion zones.

Key changes include:

  • New EagleDensityFunction component using bivariate spline interpolation to evaluate eagle presence density from SSRS-generated maps
  • New FarmExclusionDistancePolygon component for computing turbine distances to polygonal exclusion regions using JAX-based autodifferentiation
  • Enhanced visualization support for rendering exclusion zones on layout plots

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
ard/eco/eagle_density.py New OpenMDAO component implementing eagle presence density evaluation using scipy's RectBivariateSpline
ard/layout/exclusions.py New OpenMDAO component for calculating turbine-to-exclusion distances with JAX-based gradient computation
ard/viz/layout.py Added plotting functionality for polygonal exclusion zones with validation
test/ard/unit/eco/test_eagle_density.py Unit tests for eagle density function with value and gradient validation
test/ard/unit/eco/inputs/ard_system_eagle_density.yaml Test configuration with eagle density map and design variable definitions
test/ard/unit/layout/test_exclusion.py Comprehensive unit tests for exclusion distance calculations (single and multi-polygon)
test/ard/unit/layout/test_boundary.py Cleanup of unused imports and variables

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@jaredthomas68 jaredthomas68 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just a few minor things to get it ready for production

"""
OpenMDAO component to evaluate eagle presence density at turbine locations.
An Ard/OpenMDAO component that evaluates the SRSS-generated eagle presence
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is SRSS?

OpenMDAO component to evaluate eagle presence density at turbine locations.
An Ard/OpenMDAO component that evaluates the SRSS-generated eagle presence
density at turbine locations, nominally for analysis of and optimization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

punctuation: I think you need some parenthetical commas (maybe I used the right term?)

-------
eagle_normalized_density : np.ndarray
a 1-D numpy array that represents the normalized eagle presence density
at each of the turbine locations (unitless)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give a little more insight into what the eagle density means or how to interpret it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could go here or in the intro paragraph of the doc string


# evaluate the gradients for each variable
dfdx = self.eagle_density_function.ev(x_turbines, y_turbines, dx=1, dy=0)
dfdy = self.eagle_density_function.ev(x_turbines, y_turbines, dx=0, dy=1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

way to include derivatives!!!!! I do think we may get better computational efficiency if you create separate derivatives splines in setup, but I'm not sure what RectBivariateSpline is doing under the hood with the ev call and dx spec, maybe it has the derivatives splines already.

y_turbines = inputs["y_turbines"] # m

# evaluate the density function at each turbine point
outputs["eagle_normalized_density"] = self.eagle_density_function.ev(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so clean, I love it

# add four-parameter grid farm layout DVs
self.add_input("spacing_primary", spacing_primary, units="unitless")
self.add_input("spacing_secondary", spacing_secondary, units="unitless")
self.add_input("spacing_primary", spacing_primary, units=None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, why the switch to None?

windIO_plant:
layout:
N_turbines: 9
ssrs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name ssrs in the modeling options is not clear enough for novice users. Let's spell it out or pick a more human readable name for the input use where users will see it a lot

windIO_plant:
layout:
N_turbines: 9
ssrs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section should probably be in its own file

R = lambda x, y: np.sqrt(x * x + y * y)
# if we wanted to add another dimension here
# we could add `THETA = lambda x, y: np.atan2(x, y)`
self.F = lambda x, y: -R(x, y) * R(x, y) / (Rmax * Rmax) + 2 * R(x, y) / Rmax
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could use a little explanation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice way of testing though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants