Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pp/bespoke_bos_cost' into pp/ct_…
Browse files Browse the repository at this point in the history
…wakes
  • Loading branch information
ppinchuk committed May 13, 2024
2 parents 5010d40 + 42ce9f6 commit ced8709
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 63 deletions.
110 changes: 84 additions & 26 deletions reV/bespoke/bespoke.py
Expand Up @@ -197,8 +197,8 @@ def __init__(self, gid, excl, res, tm_dset, sam_sys_inputs,
objective_function, capital_cost_function,
fixed_operating_cost_function,
variable_operating_cost_function,
min_spacing='5x', ga_kwargs=None,
output_request=('system_capacity', 'cf_mean'),
balance_of_system_cost_function, min_spacing='5x',
ga_kwargs=None, output_request=('system_capacity', 'cf_mean'),
ws_bins=(0.0, 20.0, 5.0), wd_bins=(0.0, 360.0, 45.0),
excl_dict=None, inclusion_mask=None, data_layers=None,
resolution=64, excl_area=None, exclusion_shape=None,
Expand All @@ -225,19 +225,29 @@ def __init__(self, gid, excl, res, tm_dset, sam_sys_inputs,
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.
- self.wind_plant: the SAM wind plant object, through which
all SAM variables can be accessed
- capital_cost: plant capital cost as evaluated
- ``n_turbines``: the number of turbines
- ``system_capacity``: wind plant capacity
- ``aep``: annual energy production
- ``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.
- ``avg_sl_dist_to_medoid_m``: Average straight-line
distance to the medoid of 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`
- ``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`
- ``balance_of_system_cost``: plant balance of system
cost as evaluated by `balance_of_system_cost_function`
- ``self.wind_plant``: the SAM wind plant object,
through which all SAM variables can be accessed
capital_cost_function : str
The plant capital cost function as a string, must return the total
Expand All @@ -250,6 +260,16 @@ def __init__(self, gid, excl, res, tm_dset, sam_sys_inputs,
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. You can set this to "0"
to effectively ignore variable operating costs.
balance_of_system_cost_function : str
The plant balance-of-system cost function as a string, must
return the variable operating cost in $. Has access to the
same variables as the objective_function. You can set this
to "0" to effectively ignore balance-of-system costs.
balance_of_system_cost_function : str
The plant balance-of-system cost function as a string, must
return the variable operating cost in $. Has access to the same
variables as the objective_function.
min_spacing : float | int | str
Minimum spacing between turbines in meters. Can also be a string
Expand Down Expand Up @@ -375,6 +395,7 @@ def __init__(self, gid, excl, res, tm_dset, sam_sys_inputs,
self.fixed_operating_cost_function = fixed_operating_cost_function
self.variable_operating_cost_function = \
variable_operating_cost_function
self.balance_of_system_cost_function = balance_of_system_cost_function
self.min_spacing = min_spacing
self.ga_kwargs = ga_kwargs or {}

Expand Down Expand Up @@ -925,6 +946,7 @@ def plant_optimizer(self):
self.capital_cost_function,
self.fixed_operating_cost_function,
self.variable_operating_cost_function,
self.balance_of_system_cost_function,
self.include_mask,
self.pixel_side_length,
self.min_spacing)
Expand All @@ -942,10 +964,12 @@ def recalc_lcoe(self):
'multi-year mean AEP.')

fcr = lcoe_kwargs['fixed_charge_rate']
cap_cost = lcoe_kwargs['capital_cost']
cc = lcoe_kwargs['capital_cost']
foc = lcoe_kwargs['fixed_operating_cost']
voc = lcoe_kwargs['variable_operating_cost']
bos = lcoe_kwargs['balance_of_system_cost']
aep = self.outputs['annual_energy-means']
cap_cost = cc + bos

my_mean_lcoe = lcoe_fcr(fcr, cap_cost, foc, aep, voc)

Expand All @@ -963,13 +987,14 @@ def get_lcoe_kwargs(self):
sam_sys_inputs, normalized to the original system_capacity, and
updated based on the bespoke optimized system_capacity, includes
fixed_charge_rate, system_capacity (kW), capital_cost ($),
fixed_operating_cos ($), variable_operating_cost ($/kWh)
Data source priority: outputs, plant_optimizer,
original_sam_sys_inputs, meta
fixed_operating_cos ($), variable_operating_cost ($/kWh),
balance_of_system_cost ($). Data source priority: outputs,
plant_optimizer, original_sam_sys_inputs, meta
"""

kwargs_list = ['fixed_charge_rate', 'system_capacity', 'capital_cost',
'fixed_operating_cost', 'variable_operating_cost']
'fixed_operating_cost', 'variable_operating_cost',
'balance_of_system_cost']
lcoe_kwargs = {}

for kwarg in kwargs_list:
Expand Down Expand Up @@ -1045,7 +1070,8 @@ def _check_sys_inputs(plant1, plant2,
'hourly',
'capital_cost',
'fixed_operating_cost',
'variable_operating_cost')):
'variable_operating_cost',
'balance_of_system_cost')):
"""Check two reV-SAM models for matching system inputs.
Parameters
Expand Down Expand Up @@ -1162,6 +1188,10 @@ def run_plant_optimization(self):
self._outputs["system_capacity"] = self.plant_optimizer.capacity

self._meta["n_turbines"] = self.plant_optimizer.nturbs
self._meta["avg_sl_dist_to_center_m"] = \
self.plant_optimizer.avg_sl_dist_to_center_m
self._meta["avg_sl_dist_to_medoid_m"] = \
self.plant_optimizer.avg_sl_dist_to_medoid_m
self._meta["bespoke_aep"] = self.plant_optimizer.aep
self._meta["bespoke_objective"] = self.plant_optimizer.objective
self._meta["bespoke_capital_cost"] = \
Expand All @@ -1170,6 +1200,8 @@ def run_plant_optimization(self):
self.plant_optimizer.fixed_operating_cost
self._meta["bespoke_variable_operating_cost"] = \
self.plant_optimizer.variable_operating_cost
self._meta["bespoke_balance_of_system_cost"] = \
self.plant_optimizer.balance_of_system_cost
self._meta["included_area"] = self.plant_optimizer.area
self._meta["included_area_capacity_density"] = \
self.plant_optimizer.capacity_density
Expand Down Expand Up @@ -1258,7 +1290,8 @@ class BespokeWindPlants(BaseAggregation):

def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
capital_cost_function, fixed_operating_cost_function,
variable_operating_cost_function, project_points,
variable_operating_cost_function,
balance_of_system_cost_function, project_points,
sam_files, min_spacing='5x', ga_kwargs=None,
output_request=('system_capacity', 'cf_mean'),
ws_bins=(0.0, 20.0, 5.0), wd_bins=(0.0, 360.0, 45.0),
Expand Down Expand Up @@ -1338,17 +1371,26 @@ def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
- ``n_turbines``: the number of turbines
- ``system_capacity``: wind plant capacity
- ``aep``: annual energy production
- ``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.
- ``avg_sl_dist_to_medoid_m``: Average straight-line
distance to the medoid of 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.
- ``self.wind_plant``: the SAM wind plant object,
through which all SAM variables can be accessed
- ``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
operating cost as evaluated by
`variable_operating_cost_function`
- ``balance_of_system_cost``: plant balance of system
cost as evaluated by `balance_of_system_cost_function`
- ``self.wind_plant``: the SAM wind plant object,
through which all SAM variables can be accessed
capital_cost_function : str
The plant capital cost function written out as a string.
Expand All @@ -1365,6 +1407,13 @@ def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
out as a string. This expression must return the variable
operating cost in $/kWh. This expression has access to the
same variables as the `objective_function` argument above.
You can set this to "0" to effectively ignore variable
operating costs.
balance_of_system_cost_function : str
The plant balance-of-system cost function as a string, must
return the variable operating cost in $. Has access to the
same variables as the objective_function. You can set this
to "0" to effectively ignore balance-of-system costs.
project_points : int | list | tuple | str | dict | pd.DataFrame | slice
Input specifying which sites to process. A single integer
representing the supply curve GID of a site may be specified
Expand Down Expand Up @@ -1395,11 +1444,13 @@ def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
- ``capital_cost_multiplier``
- ``fixed_operating_cost_multiplier``
- ``variable_operating_cost_multiplier``
- ``balance_of_system_cost_multiplier``
These particular inputs are treated as multipliers to be
applied to the respective cost curves
(`capital_cost_function`, `fixed_operating_cost_function`,
and `variable_operating_cost_function`) both during and
`variable_operating_cost_function`, and
`balance_of_system_cost_function`) both during and
after the optimization. A DataFrame following the same
guidelines as the CSV input (or a dictionary that can be
used to initialize such a DataFrame) may be used for this
Expand Down Expand Up @@ -1676,6 +1727,8 @@ def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
.format(fixed_operating_cost_function))
logger.info('Bespoke variable operating cost function: {}'
.format(variable_operating_cost_function))
logger.info('Bespoke balance of system cost function: {}'
.format(balance_of_system_cost_function))
logger.info('Bespoke GA initialization kwargs: {}'.format(ga_kwargs))

logger.info('Bespoke pre-extracting exclusions: {}'
Expand All @@ -1701,6 +1754,7 @@ def __init__(self, excl_fpath, res_fpath, tm_dset, objective_function,
self._cap_cost_fun = capital_cost_function
self._foc_fun = fixed_operating_cost_function
self._voc_fun = variable_operating_cost_function
self._bos_fun = balance_of_system_cost_function
self._min_spacing = min_spacing
self._ga_kwargs = ga_kwargs or {}
self._output_request = SAMOutputRequest(output_request)
Expand Down Expand Up @@ -2134,7 +2188,8 @@ def run_serial(cls, excl_fpath, res_fpath, tm_dset,
capital_cost_function,
fixed_operating_cost_function,
variable_operating_cost_function,
min_spacing='5x', ga_kwargs=None,
balance_of_system_cost_function, min_spacing='5x',
ga_kwargs=None,
output_request=('system_capacity', 'cf_mean'),
ws_bins=(0.0, 20.0, 5.0), wd_bins=(0.0, 360.0, 45.0),
excl_dict=None, inclusion_mask=None,
Expand Down Expand Up @@ -2194,6 +2249,7 @@ def run_serial(cls, excl_fpath, res_fpath, tm_dset,
capital_cost_function,
fixed_operating_cost_function,
variable_operating_cost_function,
balance_of_system_cost_function,
min_spacing=min_spacing,
ga_kwargs=ga_kwargs,
output_request=output_request,
Expand Down Expand Up @@ -2273,6 +2329,7 @@ def run_parallel(self, max_workers=None):
self._cap_cost_fun,
self._foc_fun,
self._voc_fun,
self._bos_fun,
self._min_spacing,
ga_kwargs=self._ga_kwargs,
output_request=self._output_request,
Expand Down Expand Up @@ -2355,6 +2412,7 @@ def run(self, out_fpath=None, max_workers=None):
self._cap_cost_fun,
self._foc_fun,
self._voc_fun,
self._bos_fun,
min_spacing=self._min_spacing,
ga_kwargs=self._ga_kwargs,
output_request=self._output_request,
Expand Down
2 changes: 2 additions & 0 deletions reV/bespoke/cli_bespoke.py
Expand Up @@ -54,6 +54,8 @@ def _log_bespoke_cli_inputs(config):
.format(config.get("fixed_operating_cost_function")))
logger.info('Bespoke variable operating cost function: "{}"'
.format(config.get("variable_operating_cost_function")))
logger.info('Bespoke balance of system cost function: "{}"'
.format(config.get("balance_of_system_cost_function")))
logger.info('The following project points were specified: "{}"'
.format(config.get('project_points', None)))
logger.info('The following SAM configs are available to this run:\n{}'
Expand Down

0 comments on commit ced8709

Please sign in to comment.