Skip to content

Commit

Permalink
Merge pull request #1499 from dcdenu4/bugfix/1498-wind-energy-cast-nu…
Browse files Browse the repository at this point in the history
…mbers

Bugfix/1498 wind energy cast numbers
  • Loading branch information
davemfish authored Apr 1, 2024
2 parents da55458 + 1c158fc commit 8139d2b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
18 changes: 11 additions & 7 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ Unreleased Changes
versions of InVEST would skip these parameters' type-specific
validation. Now, these parameters will be validated with their
type-specific validation checks.

* Annual Water Yield
* Added the results_suffix to a few intermediate files where it was
missing. https://github.com/natcap/invest/issues/1517
Expand All @@ -71,6 +70,17 @@ Unreleased Changes
raster. ``nan`` pixels will now be propertly ignored before calculating
mean depths along fetch rays.
https://github.com/natcap/invest/issues/1528
* SDR
* Fixed an issue encountered in the sediment deposition function where
rasters with more than 2^32 pixels would raise a cryptic error relating
to negative dimensions. https://github.com/natcap/invest/issues/1431
* Optimized the creation of the summary vector by minimizing the number of
times the target vector needs to be rasterized.
* Wind Energy
* Fixed a bug where some number inputs were not being properly cast to
``float`` or ``int`` types. If the inputs happened to be passed as
a ``str`` this caused unintended side effects such as a concatenation
error. (https://github.com/natcap/invest/issues/1498)
* Urban Nature Access
* Fixed a ``NameError`` that occurred when running the model using
search radii defined per population group with an exponential search
Expand All @@ -94,12 +104,6 @@ Unreleased Changes
* Fixed an issue where an LULC raster without a nodata value would
always raise in exception during reclassification.
https://github.com/natcap/invest/issues/1539
* SDR
* Fixed an issue encountered in the sediment deposition function where
rasters with more than 2^32 pixels would raise a cryptic error relating
to negative dimensions. https://github.com/natcap/invest/issues/1431
* Optimized the creation of the summary vector by minimizing the number of
times the target vector needs to be rasterized.

3.14.1 (2023-12-18)
-------------------
Expand Down
25 changes: 13 additions & 12 deletions src/natcap/invest/wind_energy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1289,10 +1289,15 @@ def execute(args):
levelized_raster_path = os.path.join(
out_dir, 'levelized_cost_price_per_kWh%s.tif' % suffix)

# Include foundation_cost, discount_rate, number_of_turbines with
# parameters_dict to pass for NPV calculation
for key in ['foundation_cost', 'discount_rate', 'number_of_turbines']:
parameters_dict[key] = float(args[key])

task_graph.add_task(
func=_calculate_npv_levelized_rasters,
args=(harvested_masked_path, final_dist_raster_path, npv_raster_path,
levelized_raster_path, parameters_dict, args, price_list),
levelized_raster_path, parameters_dict, price_list),
target_path_list=[npv_raster_path, levelized_raster_path],
task_name='calculate_npv_levelized_rasters',
dependent_task_list=[final_dist_task])
Expand Down Expand Up @@ -1321,7 +1326,7 @@ def execute(args):
def _calculate_npv_levelized_rasters(
base_harvested_raster_path, base_dist_raster_path,
target_npv_raster_path, target_levelized_raster_path,
parameters_dict, args, price_list):
parameters_dict, price_list):
"""Calculate NPV and levelized rasters from harvested and dist rasters.
Args:
Expand All @@ -1341,9 +1346,6 @@ def _calculate_npv_levelized_rasters(
parameters_dict (dict): a dictionary of the turbine and biophysical
global parameters.
args (dict): a dictionary that contains information on
``foundation_cost``, ``discount_rate``, ``number_of_turbines``.
price_list (list): a list of wind energy prices for a period of time.
Expand Down Expand Up @@ -1375,7 +1377,7 @@ def _calculate_npv_levelized_rasters(
# The cost of infield cable in currency units per km
infield_cost = parameters_dict['infield_cable_cost']
# The cost of the foundation in currency units
foundation_cost = args['foundation_cost']
foundation_cost = parameters_dict['foundation_cost']
# The cost of each turbine unit in currency units
unit_cost = parameters_dict['turbine_cost']
# The installation cost as a decimal
Expand All @@ -1385,7 +1387,7 @@ def _calculate_npv_levelized_rasters(
# The operations and maintenance costs as a decimal factor of capex_arr
op_maint_cost = parameters_dict['operation_maintenance_cost']
# The discount rate as a decimal
discount_rate = args['discount_rate']
discount_rate = parameters_dict['discount_rate']
# The cost to decommission the farm as a decimal factor of capex_arr
decom = parameters_dict['decommission_cost']
# The mega watt value for the turbines in MW
Expand All @@ -1401,16 +1403,15 @@ def _calculate_npv_levelized_rasters(

# The total mega watt capacity of the wind farm where mega watt is the
# turbines rated power
total_mega_watt = mega_watt * int(args['number_of_turbines'])
number_of_turbines = int(parameters_dict['number_of_turbines'])
total_mega_watt = mega_watt * number_of_turbines

# Total infield cable cost
infield_cable_cost = infield_length * infield_cost * int(
args['number_of_turbines'])
infield_cable_cost = infield_length * infield_cost * number_of_turbines
LOGGER.debug('infield_cable_cost : %s', infield_cable_cost)

# Total foundation cost
total_foundation_cost = (foundation_cost + unit_cost) * int(
args['number_of_turbines'])
total_foundation_cost = (foundation_cost + unit_cost) * number_of_turbines
LOGGER.debug('total_foundation_cost : %s', total_foundation_cost)

# Nominal Capital Cost (CAP) minus the cost of cable which needs distances
Expand Down
15 changes: 7 additions & 8 deletions tests/test_wind_energy.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,12 @@ def test_calculate_npv_levelized_rasters(self):
'air_density_coefficient': 1.19E-04,
'loss_parameter': 0.05,
'turbine_cost': 10000,
'turbine_rated_pwr': 5
}
args = {
'turbine_rated_pwr': 5,
'foundation_cost': 1000000,
'discount_rate': 0.01,
'number_of_turbines': 10
}

price_list = [0.10, 0.10, 0.10, 0.10, 0.10]

srs = osr.SpatialReference()
Expand Down Expand Up @@ -381,7 +380,7 @@ def test_calculate_npv_levelized_rasters(self):
wind_energy._calculate_npv_levelized_rasters(
base_harvest_path, base_distance_path,
target_npv_raster_path, target_levelized_raster_path,
val_parameters_dict, args, price_list)
val_parameters_dict, price_list)

# Compare the results that were "eye" tested.
desired_npv_array = numpy.array(
Expand Down Expand Up @@ -428,8 +427,8 @@ def generate_base_args(workspace_dir):
SAMPLE_DATA, 'global_wind_energy_parameters.csv'),
'turbine_parameters_path': os.path.join(
SAMPLE_DATA, '3_6_turbine.csv'),
'number_of_turbines': 80,
'min_depth': 3,
'number_of_turbines': '80', # pass str to test casting
'min_depth': '3', # pass str to test casting
'max_depth': 180,
'n_workers': -1
}
Expand Down Expand Up @@ -534,13 +533,13 @@ def test_val_gridpts_windprice(self):
args['max_distance'] = 200000
args['valuation_container'] = True
args['foundation_cost'] = 2000000
args['discount_rate'] = 0.07
args['discount_rate'] = '0.07' # pass str to test casting
# Test that only grid points are provided in grid_points_path
args['grid_points_path'] = os.path.join(
SAMPLE_DATA, 'resampled_grid_pts.csv')
args['price_table'] = False
args['wind_price'] = 0.187
args['rate_change'] = 0.2
args['rate_change'] = '0.2' # pass str to test casting

wind_energy.execute(args)

Expand Down

0 comments on commit 8139d2b

Please sign in to comment.