Skip to content

Commit

Permalink
Add avg_sl_dist_to_center_m option for bespoke objective
Browse files Browse the repository at this point in the history
  • Loading branch information
ppinchuk committed Apr 29, 2024
1 parent e350725 commit cb995bd
Showing 1 changed file with 56 additions and 32 deletions.
88 changes: 56 additions & 32 deletions reV/bespoke/place_turbines.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,45 +55,53 @@ def __init__(self, wind_plant, objective_function,
Parameters
----------
wind_plant : WindPowerPD
wind plant object to analyze wind plant performance. This object
should have everything in the plant defined, such that only the
turbine coordinates and plant capacity need to be defined during
the optimization.
wind plant object to analyze wind plant performance. This
object should have everything in the plant defined, such
that only the turbine coordinates and plant capacity need to
be defined during the optimization.
objective_function : str
The objective function of the optimization as a string, should
return the objective to be minimized during layout optimization.
Variables available are:
The objective function of the optimization as a string,
should return the objective to be minimized during layout
optimization. Variables available are:
- n_turbines: the number of turbines
- system_capacity: wind plant capacity
- aep: annual energy production
- fixed_charge_rate: user input fixed_charge_rate if included
as part of the sam system config.
- avg_sl_dist_to_center_m: Average straight-line
distance to the supply curve point center from all
turbine locations (in m). Useful for computing plant
BOS costs.
- fixed_charge_rate: user input fixed_charge_rate if
included as part of the sam system config.
- capital_cost: plant capital cost as evaluated
by `capital_cost_function`
- fixed_operating_cost: plant fixed annual operating cost as
evaluated by `fixed_operating_cost_function`
- variable_operating_cost: plant variable annual operating cost
as evaluated by `variable_operating_cost_function`
- self.wind_plant: the SAM wind plant object, through which
all SAM variables can be accessed
- cost: the annual cost of the wind plant (from cost_function)
- fixed_operating_cost: plant fixed annual operating
cost as evaluated by `fixed_operating_cost_function`
- variable_operating_cost: plant variable annual
operating cost as evaluated by
`variable_operating_cost_function`
- self.wind_plant: the SAM wind plant object, through
which all SAM variables can be accessed
- cost: the annual cost of the wind plant (from
cost_function)
capital_cost_function : str
The plant capital cost function as a string, must return the total
capital cost in $. Has access to the same variables as the
objective_function.
The plant capital cost function as a string, must return the
total capital cost in $. Has access to the same variables as
the objective_function.
fixed_operating_cost_function : str
The plant annual fixed operating cost function as a string, must
return the fixed operating cost in $/year. Has access to the same
variables as the objective_function.
The plant annual fixed operating cost function as a string,
must return the fixed operating cost in $/year. Has access
to the same variables as the objective_function.
variable_operating_cost_function : str
The plant annual variable operating cost function as a string, must
return the variable operating cost in $/kWh. Has access to the same
variables as the objective_function.
exclusions : ExclusionMaskFromDict
The exclusions that define where turbines can be placed. Contains
exclusions.latitude, exclusions.longitude, and exclusions.mask
The plant annual variable operating cost function as a
string, must return the variable operating cost in $/kWh.
Has access to the same variables as the objective_function.
include_mask : np.ndarray
Supply curve point 2D inclusion mask where included pixels
are set to 1 and excluded pixels are set to 0.
pixel_side_length : int
Side length (m) of a single pixel of the `include_mask`.
min_spacing : float
The minimum spacing between turbines (in meters).
wake_loss_multiplier : float, optional
Expand Down Expand Up @@ -148,7 +156,7 @@ def define_exclusions(self):
"""From the exclusions data, create a shapely MultiPolygon as
self.safe_polygons that defines where turbines can be placed.
"""
nx, ny = np.shape(self.include_mask)
ny, nx = np.shape(self.include_mask)
self.safe_polygons = MultiPolygon()
side_x = np.arange(nx + 1) * self.pixel_side_length
side_y = np.arange(ny, -1, -1) * self.pixel_side_length
Expand Down Expand Up @@ -211,24 +219,33 @@ def initialize_packing(self):
self.x_locations = packing.turbine_x
self.y_locations = packing.turbine_y

def _avg_sl_dist_to_cent(self, x_locs, y_locs):
"""Average straight-line distance to center from turb locations. """
ny, nx = np.shape(self.include_mask)
cx = nx * self.pixel_side_length / 2
cy = ny * self.pixel_side_length / 2
return np.hypot(x_locs - cx, y_locs - cy).mean()

# pylint: disable=W0641,W0123
def optimization_objective(self, x):
"""The optimization objective used in the bespoke optimization
"""
x = [bool(y) for y in x]
if len(x) > 0:
n_turbines = np.sum(x)
self.wind_plant["wind_farm_xCoordinates"] = self.x_locations[x]
self.wind_plant["wind_farm_yCoordinates"] = self.y_locations[x]
x_locs, y_locs = self.x_locations[x], self.y_locations[x]
self.wind_plant["wind_farm_xCoordinates"] = x_locs
self.wind_plant["wind_farm_yCoordinates"] = y_locs

system_capacity = n_turbines * self.turbine_capacity
self.wind_plant["system_capacity"] = system_capacity

self.wind_plant.assign_inputs()
self.wind_plant.execute()
aep = self._aep_after_scaled_wake_losses()
avg_sl_dist_to_center_m = self._avg_sl_dist_to_cent(x_locs, y_locs)
else:
n_turbines = system_capacity = aep = 0
n_turbines = system_capacity = aep = avg_sl_dist_to_center_m = 0

fixed_charge_rate = self.fixed_charge_rate
capital_cost = eval(self.capital_cost_function,
Expand Down Expand Up @@ -378,6 +395,12 @@ def turbine_y(self):
"""This is the final optimized turbine y locations (m)"""
return self.y_locations[self.optimized_design_variables]

@property
@none_until_optimized
def avg_sl_dist_to_center_m(self):
"""This is the final avg straight line distance to center (m)"""
return self._avg_sl_dist_to_cent(self.turbine_x, self.turbine_y)

@property
@none_until_optimized
def nturbs(self):
Expand Down Expand Up @@ -522,4 +545,5 @@ def objective(self):
capital_cost = self.capital_cost
fixed_operating_cost = self.fixed_operating_cost
variable_operating_cost = self.variable_operating_cost
avg_sl_dist_to_center_m = self.avg_sl_dist_to_center_m
return eval(self.objective_function, globals(), locals())

0 comments on commit cb995bd

Please sign in to comment.