NREL-reV 0.14.2__py3-none-any.whl → 0.14.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: NREL-reV
3
- Version: 0.14.2
3
+ Version: 0.14.4
4
4
  Summary: National Renewable Energy Laboratory's (NREL's) Renewable Energy Potential(V) Model: reV
5
5
  Author-email: Galen Maclaurin <galen.maclaurin@nrel.gov>
6
6
  Maintainer-email: Grant Buster <gbuster@nrel.gov>, Paul Pinchuk <ppinchuk@nrel.gov>
@@ -20,17 +20,17 @@ Classifier: Programming Language :: Python :: 3.13
20
20
  Requires-Python: >=3.9
21
21
  Description-Content-Type: text/x-rst
22
22
  License-File: LICENSE
23
- Requires-Dist: NREL-gaps<0.9,>=0.8.0
24
- Requires-Dist: NREL-NRWAL<0.1,>=0.0.11
23
+ Requires-Dist: NREL-gaps>=0.8.0
24
+ Requires-Dist: NREL-NRWAL>=0.0.11
25
25
  Requires-Dist: NREL-PySAM~=7.0.0
26
- Requires-Dist: NREL-rex<0.4,>=0.3.5
26
+ Requires-Dist: NREL-rex>=0.4.0
27
27
  Requires-Dist: numpy<3,>=2.0.2
28
28
  Requires-Dist: packaging<25,>=24.2
29
29
  Requires-Dist: plotly<7,>=6.0.1
30
30
  Requires-Dist: plotting<0.1,>=0.0.7
31
31
  Requires-Dist: shapely<3,>=2.0.7
32
32
  Provides-Extra: test
33
- Requires-Dist: pytest<9,>=8.3.3; extra == "test"
33
+ Requires-Dist: pytest<9,>=8.4.0; extra == "test"
34
34
  Provides-Extra: dev
35
35
  Requires-Dist: flake8; extra == "dev"
36
36
  Requires-Dist: pre-commit; extra == "dev"
@@ -1,7 +1,7 @@
1
- nrel_rev-0.14.2.dist-info/licenses/LICENSE,sha256=hDwoTANtan2ZpufBlXm5C3W_PJ-mCqItvlcobgjxL7k,1526
1
+ nrel_rev-0.14.4.dist-info/licenses/LICENSE,sha256=hDwoTANtan2ZpufBlXm5C3W_PJ-mCqItvlcobgjxL7k,1526
2
2
  reV/__init__.py,sha256=tXTpWu_qVo3uotfSw_TJ-gNbidGaIPPfUTwBlpCMJ-g,856
3
3
  reV/cli.py,sha256=u7G5M5moA7q8fCgC_1MB30Z7R14GNcngVf6eVNkfQU8,1682
4
- reV/version.py,sha256=iZ2NEm6j_ZMkwjscuehf0I9OUwsEHrSS3xbfjV9LCbM,51
4
+ reV/version.py,sha256=oIdidsSwDY_HSSZ-2OPfa9VlyBv1QAecZqvfdONcImU,51
5
5
  reV/SAM/SAM.py,sha256=3NK9rRaJzqH6wz7CU_5XguKCRhmoilOpDdFFsFgOaxQ,33163
6
6
  reV/SAM/__init__.py,sha256=LJqoncyKDY5ZP5WA4kboh561bce11F9Ge645Izah0EY,240
7
7
  reV/SAM/defaults.py,sha256=JQMJomX7wsbMzxKjx_IMnA_9QFsV2yWCyl_JToDVSJo,6703
@@ -16,18 +16,18 @@ reV/SAM/defaults/WY Southern-Flat Lands.srw,sha256=oSlFI7nnycW7SMnTXEXBXYkoh8rhV
16
16
  reV/SAM/defaults/geothermal.json,sha256=gnlxOBxxkbDDacIw6B9yP9iRkfmwj0WTWs8Zb71ytCo,7119
17
17
  reV/SAM/defaults/i_pvwattsv5.json,sha256=sF8rSe1bcqsKLXchvRxlp25dXOVe_q7rPJTf_vWR20Y,312
18
18
  reV/bespoke/__init__.py,sha256=vpXbyBUrUsTgK8UP_LafMjLiDg2CRG9WZLHPsOJoxek,109
19
- reV/bespoke/bespoke.py,sha256=ZMl4kz9oAaXpZaNa5EgiD43RvKiKl3xymRv-z4lDYmQ,113169
19
+ reV/bespoke/bespoke.py,sha256=PLs42cTGRrCihBZRO_6VR6eByGgTRBwLOEiXwPiz7dg,114863
20
20
  reV/bespoke/cli_bespoke.py,sha256=b6Xu0GKpXqPX3qVJ6-z0FrO97uCsH_1dVOa4r6IvesQ,2911
21
21
  reV/bespoke/gradient_free.py,sha256=URWV1yiO2jyWk3_GOpfpLV_wlgJhXXGmTUwCB3WTV0Y,12015
22
22
  reV/bespoke/pack_turbs.py,sha256=Dcd9F8obF8LPztzeycB5kxa5hXKSCiz3jC1WeAFUx28,3508
23
- reV/bespoke/place_turbines.py,sha256=NfAs0OMaXPmwHnz9sTAtntWjvwGwSE8SCQ8fGlGzNoQ,25543
23
+ reV/bespoke/place_turbines.py,sha256=f1Or9X1b2_XOkhUgRNXZwpF_xZQTw1LFL2O2SRe1p1E,25883
24
24
  reV/config/__init__.py,sha256=oqFNU4JESU_fPxFmPyQNFAXLDAdzmTlPuabXTe3Rf2Y,92
25
25
  reV/config/base_analysis_config.py,sha256=NvA3g5zQz8mIrV8ZSENLq0XBZGXa6RTGkwpZ76TVZj8,5615
26
26
  reV/config/base_config.py,sha256=a748VQ3CRs9RVi5sSEPcaWOyH6R3t5tssaFqZntHyaE,10075
27
27
  reV/config/cli_project_points.py,sha256=6edOlLNOG-ZEbcpNS2MPfu-DXjcOTEh_MEvKOvQSZj4,6010
28
28
  reV/config/curtailment.py,sha256=1bH7xzxOmD4PwLKcXFNotMAa9iCfGBUm2DKTOXViCJg,5548
29
29
  reV/config/execution.py,sha256=hyf8W7XYUXE6tXBXs-4En7h_aDTYu8FzbslgBsKLJkQ,5046
30
- reV/config/output_request.py,sha256=Sj3L5hcypLTCtLnKAqS7GSaI4_Hpb28QLuWT9IMCvrc,4520
30
+ reV/config/output_request.py,sha256=cww5MxOUnXE_HwwLYitsFSwwUT8mWkctSElq9-zUl_8,4725
31
31
  reV/config/project_points.py,sha256=CSq7lHgWfJ1pq1XlWJ5eykmGGhumkxVcg__Ln9RR4-Y,41886
32
32
  reV/config/sam_config.py,sha256=xvvx2FTuliq0Sk-BjRE3I9zdDmIdwHVBnWtXCcsoc40,7998
33
33
  reV/econ/__init__.py,sha256=UId1LNaAP9lErCEXVce6JZf0qVRUvwNFOPrajdRevGo,130
@@ -80,20 +80,20 @@ reV/supply_curve/cli_supply_curve.py,sha256=e-XrHQIe4OqWTL6u-TUAyHrw7Alk7vkXQ2Ho
80
80
  reV/supply_curve/cli_tech_mapping.py,sha256=Dirn4JOmu_3BIP7WgcRLAepsreKqmDhChHLPEUqcDAo,1735
81
81
  reV/supply_curve/competitive_wind_farms.py,sha256=eOjM72-4oWtsqxB7Wh2gnB2zVAt4LY3iPE_DqWdXbQ4,15795
82
82
  reV/supply_curve/exclusions.py,sha256=4-ZxTO5Vlu03vie0V_74uvdajQfCuC8FE96Pg8I4U_c,42950
83
- reV/supply_curve/extent.py,sha256=a31po753hXSxQ8lfcCvpE8hoKc4bY7MmYq0NO0jtdqA,17414
84
- reV/supply_curve/points.py,sha256=p9Kqzas1jX8uCXcvYX7o6mdUVsgeHCC_F9pjBaEypPI,93548
83
+ reV/supply_curve/extent.py,sha256=168Vcr2XQNkoLLn3xCLfvE3udi39wbtQ7GAbvw1yys0,17917
84
+ reV/supply_curve/points.py,sha256=d3dPZio1PAbc0qvLJ1CqzqbcUwqsKMQK2wxbek4_CJ8,93937
85
85
  reV/supply_curve/sc_aggregation.py,sha256=l7uXs-grLb0enblPNsEDKccSP11WZ2Pah5baWtgtvzE,68067
86
86
  reV/supply_curve/supply_curve.py,sha256=9zhAA_9XSxE18j1Z9FuC71Wr3I0VuakfR5mt1_gHYuU,69931
87
87
  reV/supply_curve/tech_mapping.py,sha256=WP-o5Sk5q1Jz_F9Rpe77_fvTYGH8R4GnYDfRMSTuHB8,17804
88
- reV/utilities/__init__.py,sha256=HVb1P-ee-z2P6UTjyc0s0gYFK7XYM71BQLEMxj26apA,10834
88
+ reV/utilities/__init__.py,sha256=ii0xiebw0PNg5Eq9kYcLrX9M3yVglyxnn9_fP_w4ILA,10871
89
89
  reV/utilities/_clean_readme.py,sha256=IFI9wGPX5nnLTNVLJzH8IOHq9unQlAlHRu4Namib0LA,709
90
90
  reV/utilities/cli_functions.py,sha256=1_T_sXz0Ct8lW-vOk3mMRcpD6NYsc9cGI7dEujIi9z4,3864
91
91
  reV/utilities/curtailment.py,sha256=As902-2aLGnCiVEutYfAFIOwuV--_rCQhxGNOY9RB-4,5241
92
92
  reV/utilities/exceptions.py,sha256=f7sRGsbFLpmL6Caq_H1cD4GfVhnLMyvYUsLPA1UVDDE,3974
93
93
  reV/utilities/pytest_utils.py,sha256=spCw9yQ8KEYOkQZpCi9IEmaWIvIqHqbUPDXXNQJJ68U,3241
94
94
  reV/utilities/slots.py,sha256=xsw-JuUVZ0YeoCNuwP_HxGNxFMA4xRs1tuImXHIJqaU,2618
95
- nrel_rev-0.14.2.dist-info/METADATA,sha256=lIgkZ3PQLu5YOtLYAP62nRtNVAhxkwRuHGqS_2mSwDY,10733
96
- nrel_rev-0.14.2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
97
- nrel_rev-0.14.2.dist-info/entry_points.txt,sha256=4IfJtZm2iMJwrbC8J0Or7VjZWnFpvCaHYVpvSWfIwDA,616
98
- nrel_rev-0.14.2.dist-info/top_level.txt,sha256=S6YF2ZYgXUB6n28SY0K2H8YB9tMJdXQ9CyQbo6VC89M,4
99
- nrel_rev-0.14.2.dist-info/RECORD,,
95
+ nrel_rev-0.14.4.dist-info/METADATA,sha256=3lCV-lrlcYrhrUEtJbAKsj5e8kTahxjDhLujt2-XXqQ,10718
96
+ nrel_rev-0.14.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
+ nrel_rev-0.14.4.dist-info/entry_points.txt,sha256=4IfJtZm2iMJwrbC8J0Or7VjZWnFpvCaHYVpvSWfIwDA,616
98
+ nrel_rev-0.14.4.dist-info/top_level.txt,sha256=S6YF2ZYgXUB6n28SY0K2H8YB9tMJdXQ9CyQbo6VC89M,4
99
+ nrel_rev-0.14.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
reV/bespoke/bespoke.py CHANGED
@@ -258,8 +258,9 @@ class BespokeSinglePlant:
258
258
  ws_bins=(0.0, 20.0, 5.0), wd_bins=(0.0, 360.0, 45.0),
259
259
  excl_dict=None, inclusion_mask=None, data_layers=None,
260
260
  resolution=64, excl_area=None, exclusion_shape=None,
261
- eos_mult_baseline_cap_mw=200, prior_meta=None, gid_map=None,
262
- bias_correct=None, pre_loaded_data=None, close=True):
261
+ eos_mult_baseline_cap_mw=200, convex_hull_buffer=0,
262
+ prior_meta=None, gid_map=None, bias_correct=None,
263
+ pre_loaded_data=None, close=True):
263
264
  """
264
265
  Parameters
265
266
  ----------
@@ -387,6 +388,10 @@ class BespokeSinglePlant:
387
388
  divided by the $-per-kW of a plant with this baseline
388
389
  capacity. By default, `200` (MW), which aligns the baseline
389
390
  with ATB assumptions. See here: https://tinyurl.com/y85hnu6h.
391
+ convex_hull_buffer : float, default=0
392
+ Buffer (in m) to apply to turbine location convex hull
393
+ before computing the convex hull area and capacity density.
394
+ By default, ``0``.
390
395
  prior_meta : pd.DataFrame | None
391
396
  Optional meta dataframe belonging to a prior run. This will only
392
397
  run the timeseries power generation step and assume that all of the
@@ -443,6 +448,11 @@ class BespokeSinglePlant:
443
448
  eos_mult_baseline_cap_mw
444
449
  )
445
450
  )
451
+ logger.debug(
452
+ "Bespoke convex hull buffer: {:,} m".format(
453
+ convex_hull_buffer
454
+ )
455
+ )
446
456
 
447
457
  if isinstance(min_spacing, str) and min_spacing.endswith("x"):
448
458
  rotor_diameter = sam_sys_inputs["wind_turbine_rotor_diameter"]
@@ -475,6 +485,7 @@ class BespokeSinglePlant:
475
485
  self._ws_bins = ws_bins
476
486
  self._wd_bins = wd_bins
477
487
  self._baseline_cap_mw = eos_mult_baseline_cap_mw
488
+ self.convex_hull_buffer = convex_hull_buffer
478
489
 
479
490
  self._res_df = None
480
491
  self._prior_meta = prior_meta is not None
@@ -537,7 +548,8 @@ class BespokeSinglePlant:
537
548
  (ws_mean, *_mean) if requested.
538
549
  """
539
550
 
540
- required = ("cf_mean", "annual_energy")
551
+ required = ("cf_mean", "annual_energy",
552
+ "annual_wake_loss_internal_percent")
541
553
  for req in required:
542
554
  if req not in self._out_req:
543
555
  self._out_req.append(req)
@@ -829,8 +841,12 @@ class BespokeSinglePlant:
829
841
  # `wind_plant_pd` PC may have PC losses applied, so keep the
830
842
  # original PC as to not double count losses here
831
843
  layout_config.pop("wind_turbine_powercurve_powerout", None)
832
- config.update(layout_config)
833
844
 
845
+ # Don't bring over wind resource choice from `wind_plant_pd`
846
+ layout_config.pop("wind_resource_model_choice", None)
847
+ layout_config.pop("wind_resource_distribution", None)
848
+
849
+ config.update(layout_config)
834
850
  return config
835
851
 
836
852
  @property
@@ -1072,7 +1088,8 @@ class BespokeSinglePlant:
1072
1088
  self.balance_of_system_cost_function,
1073
1089
  self.include_mask,
1074
1090
  self.pixel_side_length,
1075
- self.min_spacing)
1091
+ self.min_spacing,
1092
+ self.convex_hull_buffer)
1076
1093
 
1077
1094
  return self._plant_optm
1078
1095
 
@@ -1265,6 +1282,7 @@ class BespokeSinglePlant:
1265
1282
  self._meta[SupplyCurveField.MEAN_CF_AC] = np.nan
1266
1283
  self._meta[SupplyCurveField.MEAN_LCOE] = np.nan
1267
1284
  self._meta[SupplyCurveField.SC_POINT_ANNUAL_ENERGY_MWH] = np.nan
1285
+ self._meta[SupplyCurveField.WAKE_LOSSES] = np.nan
1268
1286
  # copy dataset outputs to meta data for supply curve table summary
1269
1287
  if "cf_mean-means" in self.outputs:
1270
1288
  self._meta.loc[:, SupplyCurveField.MEAN_CF_AC] = self.outputs[
@@ -1279,6 +1297,10 @@ class BespokeSinglePlant:
1279
1297
  self._meta[SupplyCurveField.SC_POINT_ANNUAL_ENERGY_MWH] = (
1280
1298
  self.outputs["annual_energy-means"] / 1000
1281
1299
  )
1300
+ if "annual_wake_loss_internal_percent-means" in self.outputs:
1301
+ self._meta[SupplyCurveField.WAKE_LOSSES] = (
1302
+ self.outputs["annual_wake_loss_internal_percent-means"]
1303
+ )
1282
1304
 
1283
1305
  logger.debug("Timeseries analysis complete!")
1284
1306
 
@@ -1314,10 +1336,14 @@ class BespokeSinglePlant:
1314
1336
  system_capacity_kw = self.plant_optimizer.capacity
1315
1337
  self._outputs["system_capacity"] = system_capacity_kw
1316
1338
 
1317
- txc = [int(np.round(c)) for c in self.plant_optimizer.turbine_x]
1318
- tyc = [int(np.round(c)) for c in self.plant_optimizer.turbine_y]
1319
- pxc = [int(np.round(c)) for c in self.plant_optimizer.x_locations]
1320
- pyc = [int(np.round(c)) for c in self.plant_optimizer.y_locations]
1339
+ txc = [float(np.round(c, decimals=2))
1340
+ for c in self.plant_optimizer.turbine_x]
1341
+ tyc = [float(np.round(c, decimals=2))
1342
+ for c in self.plant_optimizer.turbine_y]
1343
+ pxc = [float(np.round(c, decimals=2))
1344
+ for c in self.plant_optimizer.x_locations]
1345
+ pyc = [float(np.round(c, decimals=2))
1346
+ for c in self.plant_optimizer.y_locations]
1321
1347
 
1322
1348
  txc = json.dumps(txc)
1323
1349
  tyc = json.dumps(tyc)
@@ -1500,8 +1526,8 @@ class BespokeWindPlants(BaseAggregation):
1500
1526
  excl_dict=None, area_filter_kernel='queen', min_area=None,
1501
1527
  resolution=64, excl_area=None, data_layers=None,
1502
1528
  pre_extract_inclusions=False, eos_mult_baseline_cap_mw=200,
1503
- prior_run=None, gid_map=None, bias_correct=None,
1504
- pre_load_data=False):
1529
+ convex_hull_buffer=0, prior_run=None, gid_map=None,
1530
+ bias_correct=None, pre_load_data=False):
1505
1531
  """reV bespoke analysis class.
1506
1532
 
1507
1533
  Much like generation, ``reV`` bespoke analysis runs SAM
@@ -1866,6 +1892,10 @@ class BespokeWindPlants(BaseAggregation):
1866
1892
  divided by the $-per-kW of a plant with this baseline
1867
1893
  capacity. By default, `200` (MW), which aligns the baseline
1868
1894
  with ATB assumptions. See here: https://tinyurl.com/y85hnu6h.
1895
+ convex_hull_buffer : float, default=0
1896
+ Buffer (in m) to apply to turbine location convex hull
1897
+ before computing the convex hull area and capacity density.
1898
+ By default, ``0``.
1869
1899
  prior_run : str, optional
1870
1900
  Optional filepath to a bespoke output HDF5 file belonging to
1871
1901
  a prior run. If specified, this module will only run the
@@ -1990,6 +2020,7 @@ class BespokeWindPlants(BaseAggregation):
1990
2020
  self._wd_bins = wd_bins
1991
2021
  self._data_layers = data_layers
1992
2022
  self._eos_mult_baseline_cap_mw = eos_mult_baseline_cap_mw
2023
+ self._convex_hull_buffer = convex_hull_buffer
1993
2024
  self._prior_meta = self._parse_prior_run(prior_run)
1994
2025
  self._gid_map = BespokeSinglePlant._parse_gid_map(gid_map)
1995
2026
  self._bias_correct = Gen._parse_bc(bias_correct)
@@ -2466,8 +2497,9 @@ class BespokeWindPlants(BaseAggregation):
2466
2497
  area_filter_kernel='queen', min_area=None,
2467
2498
  resolution=64, excl_area=0.0081, data_layers=None,
2468
2499
  gids=None, exclusion_shape=None, slice_lookup=None,
2469
- eos_mult_baseline_cap_mw=200, prior_meta=None,
2470
- gid_map=None, bias_correct=None, pre_loaded_data=None):
2500
+ eos_mult_baseline_cap_mw=200, convex_hull_buffer=0,
2501
+ prior_meta=None, gid_map=None, bias_correct=None,
2502
+ pre_loaded_data=None):
2471
2503
  """
2472
2504
  Standalone serial method to run bespoke optimization.
2473
2505
  See BespokeWindPlants docstring for parameter description.
@@ -2533,6 +2565,7 @@ class BespokeWindPlants(BaseAggregation):
2533
2565
  data_layers=data_layers,
2534
2566
  exclusion_shape=exclusion_shape,
2535
2567
  eos_mult_baseline_cap_mw=eos_mult_baseline_cap_mw,
2568
+ convex_hull_buffer=convex_hull_buffer,
2536
2569
  prior_meta=prior_meta,
2537
2570
  gid_map=gid_map,
2538
2571
  bias_correct=bias_correct,
@@ -2625,6 +2658,7 @@ class BespokeWindPlants(BaseAggregation):
2625
2658
  exclusion_shape=self.shape,
2626
2659
  slice_lookup=copy.deepcopy(self.slice_lookup),
2627
2660
  eos_mult_baseline_cap_mw=self._eos_mult_baseline_cap_mw,
2661
+ convex_hull_buffer=self._convex_hull_buffer,
2628
2662
  prior_meta=self._get_prior_meta(gid),
2629
2663
  gid_map=self._gid_map,
2630
2664
  bias_correct=self._get_bc_for_gid(gid),
@@ -2689,6 +2723,7 @@ class BespokeWindPlants(BaseAggregation):
2689
2723
  afk = self._area_filter_kernel
2690
2724
  i_bc = self._get_bc_for_gid(gid)
2691
2725
  ebc = self._eos_mult_baseline_cap_mw
2726
+ chb = self._convex_hull_buffer
2692
2727
 
2693
2728
  si = self.run_serial(self._excl_fpath,
2694
2729
  self._res_fpath,
@@ -2713,6 +2748,7 @@ class BespokeWindPlants(BaseAggregation):
2713
2748
  data_layers=self._data_layers,
2714
2749
  slice_lookup=slice_lookup,
2715
2750
  eos_mult_baseline_cap_mw=ebc,
2751
+ convex_hull_buffer=chb,
2716
2752
  prior_meta=prior_meta,
2717
2753
  gid_map=self._gid_map,
2718
2754
  bias_correct=i_bc,
@@ -53,7 +53,8 @@ class PlaceTurbines:
53
53
  fixed_operating_cost_function,
54
54
  variable_operating_cost_function,
55
55
  balance_of_system_cost_function,
56
- include_mask, pixel_side_length, min_spacing):
56
+ include_mask, pixel_side_length, min_spacing,
57
+ convex_hull_buffer=0):
57
58
  """
58
59
  Parameters
59
60
  ----------
@@ -123,6 +124,10 @@ class PlaceTurbines:
123
124
  Side length (m) of a single pixel of the `include_mask`.
124
125
  min_spacing : float
125
126
  The minimum spacing between turbines (in meters).
127
+ convex_hull_buffer : float, default=0
128
+ Buffer (in m) to apply to turbine location convex hull
129
+ before computing the convex hull area and capacity density.
130
+ By default, ``0``.
126
131
  """
127
132
 
128
133
  # inputs
@@ -138,6 +143,7 @@ class PlaceTurbines:
138
143
  self.include_mask = include_mask
139
144
  self.pixel_side_length = pixel_side_length
140
145
  self.min_spacing = min_spacing
146
+ self.convex_hull_buffer = convex_hull_buffer
141
147
 
142
148
  # internal variables
143
149
  self.nrows, self.ncols = np.shape(include_mask)
@@ -455,7 +461,7 @@ class PlaceTurbines:
455
461
  turbines = MultiPoint([Point(x, y)
456
462
  for x, y in zip(self.turbine_x,
457
463
  self.turbine_y)])
458
- return turbines.convex_hull
464
+ return turbines.convex_hull.buffer(self.convex_hull_buffer)
459
465
 
460
466
  @property
461
467
  @none_until_optimized
@@ -107,6 +107,9 @@ class SAMOutputRequest(OutputRequest):
107
107
  'wind_direction': 'winddirection',
108
108
  'wind-direction': 'winddirection',
109
109
  'wl': 'annual_wake_loss_internal_percent',
110
+ 'wakes': 'annual_wake_loss_internal_percent',
111
+ 'wake_loss': 'annual_wake_loss_internal_percent',
112
+ 'wake_losses': 'annual_wake_loss_internal_percent',
110
113
  'wl_kwh': 'annual_wake_loss_internal_kWh',
111
114
  'wl_pct': 'annual_wake_loss_total_percent',
112
115
  'wl_ts': 'wake_loss_internal_percent',
@@ -10,7 +10,6 @@ import pandas as pd
10
10
  from rex.utilities.utilities import get_chunk_ranges
11
11
 
12
12
  from reV.handlers.exclusions import LATITUDE, LONGITUDE, ExclusionLayers
13
- from reV.utilities import SupplyCurveField
14
13
  from reV.utilities.exceptions import SupplyCurveError, SupplyCurveInputError
15
14
 
16
15
  logger = logging.getLogger(__name__)
@@ -297,14 +296,19 @@ class SupplyCurveExtent:
297
296
  lats = []
298
297
  lons = []
299
298
 
299
+ max_center = self.resolution // 2 + 1
300
+ min_center = max_center - 2 + self.resolution % 2
301
+
300
302
  sc_cols, sc_rows = np.meshgrid(
301
303
  np.arange(self.n_cols), np.arange(self.n_rows)
302
304
  )
303
305
  for r, c in zip(sc_rows.flatten(), sc_cols.flatten()):
304
- r = self.excl_row_slices[r]
305
- c = self.excl_col_slices[c]
306
- lats.append(self.exclusions[LATITUDE, r, c].mean())
307
- lons.append(self.exclusions[LONGITUDE, r, c].mean())
306
+ r = slice(r * self.resolution + min_center,
307
+ r * self.resolution + max_center)
308
+ c = slice(c * self.resolution + min_center,
309
+ c * self.resolution + max_center)
310
+ lats.append(np.median(self.exclusions[LATITUDE, r, c]))
311
+ lons.append(np.median(self.exclusions[LONGITUDE, r, c]))
308
312
 
309
313
  self._latitude = np.array(lats, dtype="float32")
310
314
  self._longitude = np.array(lons, dtype="float32")
@@ -324,14 +328,19 @@ class SupplyCurveExtent:
324
328
  lats = []
325
329
  lons = []
326
330
 
331
+ max_center = self.resolution // 2 + 1
332
+ min_center = max_center - 2 + self.resolution % 2
333
+
327
334
  sc_cols, sc_rows = np.meshgrid(
328
335
  np.arange(self.n_cols), np.arange(self.n_rows)
329
336
  )
330
337
  for r, c in zip(sc_rows.flatten(), sc_cols.flatten()):
331
- r = self.excl_row_slices[r]
332
- c = self.excl_col_slices[c]
333
- lats.append(self.exclusions[LATITUDE, r, c].mean())
334
- lons.append(self.exclusions[LONGITUDE, r, c].mean())
338
+ r = slice(r * self.resolution + min_center,
339
+ r * self.resolution + max_center)
340
+ c = slice(c * self.resolution + min_center,
341
+ c * self.resolution + max_center)
342
+ lats.append(np.median(self.exclusions[LATITUDE, r, c]))
343
+ lons.append(np.median(self.exclusions[LONGITUDE, r, c]))
335
344
 
336
345
  self._latitude = np.array(lats, dtype="float32")
337
346
  self._longitude = np.array(lons, dtype="float32")
@@ -1856,6 +1856,15 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
1856
1856
 
1857
1857
  return None
1858
1858
 
1859
+ @property
1860
+ def mean_wake_losses(self):
1861
+ """float: Mean wake losses, if applicable."""
1862
+ if "annual_wake_loss_internal_percent-means" not in self.gen.datasets:
1863
+ return None
1864
+
1865
+ wakes = self.gen["annual_wake_loss_internal_percent-means"]
1866
+ return self.exclusion_weighted_mean(wakes)
1867
+
1859
1868
  @property
1860
1869
  def mean_lcoe(self):
1861
1870
  """Get the mean LCOE for the non-excluded data.
@@ -2368,6 +2377,7 @@ class GenerationSupplyCurvePoint(AggregationSupplyCurvePoint):
2368
2377
  SupplyCurveField.MEAN_CF_DC: self.mean_cf_dc,
2369
2378
  SupplyCurveField.MEAN_LCOE: self.mean_lcoe,
2370
2379
  SupplyCurveField.MEAN_RES: self.mean_res,
2380
+ SupplyCurveField.WAKE_LOSSES: self.mean_wake_losses,
2371
2381
  SupplyCurveField.AREA_SQ_KM: self.area,
2372
2382
  SupplyCurveField.CAPACITY_AC_MW: (
2373
2383
  self.capacity if self.capacity_ac is None else self.capacity_ac
reV/utilities/__init__.py CHANGED
@@ -140,6 +140,7 @@ class SupplyCurveField(FieldEnum):
140
140
  MEAN_RES = "resource"
141
141
  MEAN_CF_AC = "capacity_factor_ac"
142
142
  MEAN_CF_DC = "capacity_factor_dc"
143
+ WAKE_LOSSES = "losses_wakes_pct"
143
144
  MEAN_LCOE = "lcoe_site_usd_per_mwh"
144
145
  CAPACITY_AC_MW = "capacity_ac_mw"
145
146
  CAPACITY_DC_MW = "capacity_dc_mw"
reV/version.py CHANGED
@@ -2,4 +2,4 @@
2
2
  reV Version number
3
3
  """
4
4
 
5
- __version__ = "0.14.2"
5
+ __version__ = "0.14.4"