NREL-reV 0.9.2__py3-none-any.whl → 0.9.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.
- {NREL_reV-0.9.2.dist-info → NREL_reV-0.9.4.dist-info}/METADATA +14 -14
- {NREL_reV-0.9.2.dist-info → NREL_reV-0.9.4.dist-info}/RECORD +15 -15
- {NREL_reV-0.9.2.dist-info → NREL_reV-0.9.4.dist-info}/WHEEL +1 -1
- reV/SAM/SAM.py +10 -0
- reV/SAM/generation.py +1 -1
- reV/bespoke/bespoke.py +63 -63
- reV/generation/generation.py +12 -6
- reV/handlers/multi_year.py +2 -6
- reV/supply_curve/cli_sc_aggregation.py +19 -6
- reV/supply_curve/sc_aggregation.py +1 -2
- reV/supply_curve/tech_mapping.py +1 -1
- reV/version.py +1 -1
- {NREL_reV-0.9.2.dist-info → NREL_reV-0.9.4.dist-info}/LICENSE +0 -0
- {NREL_reV-0.9.2.dist-info → NREL_reV-0.9.4.dist-info}/entry_points.txt +0 -0
- {NREL_reV-0.9.2.dist-info → NREL_reV-0.9.4.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: NREL-reV
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.4
|
4
4
|
Summary: National Renewable Energy Laboratory's (NREL's) Renewable Energy Potential(V) Model: reV
|
5
5
|
Home-page: https://nrel.github.io/reV/
|
6
6
|
Author: Galen Maclaurin
|
@@ -17,22 +17,22 @@ Classifier: Programming Language :: Python :: 3.9
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
19
19
|
Requires-Python: >=3.8
|
20
|
-
Requires-Dist: NREL-gaps
|
21
|
-
Requires-Dist: NREL-NRWAL
|
22
|
-
Requires-Dist: NREL-PySAM
|
23
|
-
Requires-Dist: NREL-rex
|
24
|
-
Requires-Dist: numpy
|
25
|
-
Requires-Dist: packaging
|
26
|
-
Requires-Dist: plotly
|
27
|
-
Requires-Dist: plotting
|
20
|
+
Requires-Dist: NREL-gaps>=0.6.11
|
21
|
+
Requires-Dist: NREL-NRWAL>=0.0.7
|
22
|
+
Requires-Dist: NREL-PySAM~=4.1.0
|
23
|
+
Requires-Dist: NREL-rex>=0.2.89
|
24
|
+
Requires-Dist: numpy~=1.24.4
|
25
|
+
Requires-Dist: packaging>=20.3
|
26
|
+
Requires-Dist: plotly>=4.7.1
|
27
|
+
Requires-Dist: plotting>=0.0.6
|
28
28
|
Requires-Dist: shapely
|
29
29
|
Provides-Extra: dev
|
30
|
-
Requires-Dist: pytest
|
31
|
-
Requires-Dist: flake8
|
32
|
-
Requires-Dist: pre-commit
|
33
|
-
Requires-Dist: pylint
|
30
|
+
Requires-Dist: pytest>=5.2; extra == "dev"
|
31
|
+
Requires-Dist: flake8; extra == "dev"
|
32
|
+
Requires-Dist: pre-commit; extra == "dev"
|
33
|
+
Requires-Dist: pylint; extra == "dev"
|
34
34
|
Provides-Extra: test
|
35
|
-
Requires-Dist: pytest
|
35
|
+
Requires-Dist: pytest>=5.2; extra == "test"
|
36
36
|
|
37
37
|
|
38
38
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
reV/__init__.py,sha256=tXTpWu_qVo3uotfSw_TJ-gNbidGaIPPfUTwBlpCMJ-g,856
|
2
2
|
reV/cli.py,sha256=jfGGOr6QlLz8ghA7vBgx5-VgNsy4bBQo5DdHk42-q9A,1601
|
3
|
-
reV/version.py,sha256=
|
4
|
-
reV/SAM/SAM.py,sha256=
|
3
|
+
reV/version.py,sha256=yGiTX3S7R3_KR7tg1ywY2A7vCKmVDUNzRXtyt803-Ds,50
|
4
|
+
reV/SAM/SAM.py,sha256=wdrL7EAbn6246_3NP6EIksLM2yIg4IKK4taaTA7oj5o,32130
|
5
5
|
reV/SAM/__init__.py,sha256=LJqoncyKDY5ZP5WA4kboh561bce11F9Ge645Izah0EY,240
|
6
6
|
reV/SAM/defaults.py,sha256=2zqT_mfrVtbvU7Pe6H4anNtiVkIyQbuJcGIOARzEsbM,7193
|
7
7
|
reV/SAM/econ.py,sha256=dFhtUXp5eozSsPyk0XXji0HGexKJnxoct8cwE1ApHVg,20704
|
8
|
-
reV/SAM/generation.py,sha256=
|
8
|
+
reV/SAM/generation.py,sha256=WYFXb39v7gJp1xxyLtsMLrP8Ze9dB15cxqxRoeNdZyk,89144
|
9
9
|
reV/SAM/version_checker.py,sha256=q-eXsmSB08A5hSelNH7uAe_bqPpqjsxaiS3OBjXBs-0,3997
|
10
10
|
reV/SAM/windbos.py,sha256=fnq1uxtSl-vtJth0gTlHkCSsmvDbRROCo9RGdqA7hK4,7504
|
11
11
|
reV/SAM/defaults/USA AZ Phoenix Sky Harbor Intl Ap (TMY3).csv,sha256=8QorTX0ACjgPgNV7kLSpTHOqfY4E17gkkpKB-qseiFk,406896
|
@@ -14,7 +14,7 @@ reV/SAM/defaults/US_Wave.csv,sha256=wvn9vGl9ZGKVHbCyq4muhMI6x1-nAaQfDS3hC4ftwBA,
|
|
14
14
|
reV/SAM/defaults/geothermal.json,sha256=ivxnpxkfBrEl1MwLKXClLJfTfvF5UrbN87wpC_BFLck,2598
|
15
15
|
reV/SAM/defaults/i_pvwattsv5.json,sha256=pZpNlK5MiowZmNwY7i9XRWp9G8pPLirwdBWCMVJVuKE,312
|
16
16
|
reV/bespoke/__init__.py,sha256=vpXbyBUrUsTgK8UP_LafMjLiDg2CRG9WZLHPsOJoxek,109
|
17
|
-
reV/bespoke/bespoke.py,sha256=
|
17
|
+
reV/bespoke/bespoke.py,sha256=vvCyCaJc333yifTqQvGb-nV7OPen3fhpUE6vecelU78,111283
|
18
18
|
reV/bespoke/cli_bespoke.py,sha256=nZc6rJlfxH2IXUz9bym4EO-C1k6VvulgweWoRrMg_cE,3028
|
19
19
|
reV/bespoke/gradient_free.py,sha256=URWV1yiO2jyWk3_GOpfpLV_wlgJhXXGmTUwCB3WTV0Y,12015
|
20
20
|
reV/bespoke/pack_turbs.py,sha256=l4btC2dPZkLvDgAAGVhAYgAZDbvwimGYRdrQDq0xT68,3740
|
@@ -37,7 +37,7 @@ reV/econ/utilities.py,sha256=ZOA49S1jfsvdenvlL7m-BAJIrAvpAHSix5-wrSW0uLc,1232
|
|
37
37
|
reV/generation/__init__.py,sha256=LBecrbpL69tROol_OwVHTKBrTqgSSxJW59fs0k3o0jQ,75
|
38
38
|
reV/generation/base.py,sha256=p6g8Bj8T98OfKu44LTocGtEozstbUvti6wSi3oroS5U,48758
|
39
39
|
reV/generation/cli_gen.py,sha256=5RSlr8yO9zlB-1FzFZGClqsxqsrbr9rcS_8PlOjVx2s,4435
|
40
|
-
reV/generation/generation.py,sha256=
|
40
|
+
reV/generation/generation.py,sha256=o6nJlEcgs-QQ_fdqva-7jOhWl1wj-J7CIrRR5qNJyEQ,47434
|
41
41
|
reV/generation/output_attributes/generation.json,sha256=cy8efVCJgNSYCsR3x3_VpMCtynYS3oaQG4M2MwcdzFY,4954
|
42
42
|
reV/generation/output_attributes/lcoe_fcr.json,sha256=d_TGMkZsmsfDXQiWfhYjFkmwqi-wKF8JdHmiMCj2h38,136
|
43
43
|
reV/generation/output_attributes/lcoe_fcr_inputs.json,sha256=Yb-WTXt9YD4wE4Uu315W2uLFH6g3fT40YY83mxS-aWE,1289
|
@@ -51,7 +51,7 @@ reV/handlers/__init__.py,sha256=N7KfWbXfHLizMpoUw6yo0egbyq3jb9QL4YouBLUf4mI,130
|
|
51
51
|
reV/handlers/cli_collect.py,sha256=QRjhuJ1lV4BwGoguu0m4etrNRPMXGIZlijNyYsb7_5U,799
|
52
52
|
reV/handlers/cli_multi_year.py,sha256=xMAQ70lVUMAPM10EkZwc_FreQLjnzQ9VmKl48MS1SO0,660
|
53
53
|
reV/handlers/exclusions.py,sha256=_s-LHbjHAAHSIM6tFXCoJlLKcv0FBxbm6JAmuE_X_-I,12266
|
54
|
-
reV/handlers/multi_year.py,sha256=
|
54
|
+
reV/handlers/multi_year.py,sha256=4U-9nMVeKs03jIKdyeLq5FM9uQqAuYcgheAyMyWa5tg,30825
|
55
55
|
reV/handlers/outputs.py,sha256=VbSPFwA0ZH-oWUCCtef7zGyPbWXKY07ilPzpZIOMmuc,6034
|
56
56
|
reV/handlers/transmission.py,sha256=JzpmiweCez7vzGSutO21XIbG9czY_H6ysg_R7z290w0,25610
|
57
57
|
reV/hybrids/__init__.py,sha256=oBrJSt9WeBlER7GVd-NEJgVqFlasl0WuyHJRMgLgpAY,133
|
@@ -74,24 +74,24 @@ reV/rep_profiles/cli_rep_profiles.py,sha256=i3fRolT7HTzTQePXpNLDyxwgpRa7FEfHO1mO
|
|
74
74
|
reV/rep_profiles/rep_profiles.py,sha256=oqmtU9FbUlKurkglmZLyDBNH8VRKv8fgdSuvtYWLm04,48271
|
75
75
|
reV/supply_curve/__init__.py,sha256=dbf0cO0qmt1VhV8dnDddztrcpnwua9T2HBhM6tLKaP8,274
|
76
76
|
reV/supply_curve/aggregation.py,sha256=fv4FTdRUQWZ_1Ds84ubgJdrf5lR1xb3luhAnibe3Y3Q,38752
|
77
|
-
reV/supply_curve/cli_sc_aggregation.py,sha256=
|
77
|
+
reV/supply_curve/cli_sc_aggregation.py,sha256=qGfJyZjg4tFARG2dl-wAlHv9KjEp2u4wg1Boxz18Gf0,3347
|
78
78
|
reV/supply_curve/cli_supply_curve.py,sha256=e-XrHQIe4OqWTL6u-TUAyHrw7Alk7vkXQ2HoLbE3zTM,2163
|
79
79
|
reV/supply_curve/competitive_wind_farms.py,sha256=eOjM72-4oWtsqxB7Wh2gnB2zVAt4LY3iPE_DqWdXbQ4,15795
|
80
80
|
reV/supply_curve/exclusions.py,sha256=4-ZxTO5Vlu03vie0V_74uvdajQfCuC8FE96Pg8I4U_c,42950
|
81
81
|
reV/supply_curve/extent.py,sha256=a31po753hXSxQ8lfcCvpE8hoKc4bY7MmYq0NO0jtdqA,17414
|
82
82
|
reV/supply_curve/points.py,sha256=YEYHpn3KlBbGqpxywrfbrUrlhL3BndgX7cVQerdB6zg,86107
|
83
|
-
reV/supply_curve/sc_aggregation.py,sha256=
|
83
|
+
reV/supply_curve/sc_aggregation.py,sha256=R_h3xXKum4JTYMuq2us0rWhW0t2wm-G9Wj2on1d8FeY,61604
|
84
84
|
reV/supply_curve/supply_curve.py,sha256=igbloCkvYQwaH4zjbrYO17J7TtCTX5dKkk-TnlGJJeY,69931
|
85
|
-
reV/supply_curve/tech_mapping.py,sha256=
|
85
|
+
reV/supply_curve/tech_mapping.py,sha256=nfqPIj9o1pllX3aRC1Hi2KGXYJOYy68Vbvr_1asNmFk,18573
|
86
86
|
reV/utilities/__init__.py,sha256=iOvOuqcXv_WaSP627z2i2wF5820DbUSGRa7lSj23diQ,10534
|
87
87
|
reV/utilities/cli_functions.py,sha256=1_T_sXz0Ct8lW-vOk3mMRcpD6NYsc9cGI7dEujIi9z4,3864
|
88
88
|
reV/utilities/curtailment.py,sha256=fu48Lje-iyd2Awfe-6jFebvgcKSeJ3daNNTqjFI2GvM,4963
|
89
89
|
reV/utilities/exceptions.py,sha256=f7sRGsbFLpmL6Caq_H1cD4GfVhnLMyvYUsLPA1UVDDE,3974
|
90
90
|
reV/utilities/pytest_utils.py,sha256=T22NFEGxPOc9wRwgy0Pt2cHvw3Vam9cKwUj4AkzI7bU,3244
|
91
91
|
reV/utilities/slots.py,sha256=xsw-JuUVZ0YeoCNuwP_HxGNxFMA4xRs1tuImXHIJqaU,2618
|
92
|
-
NREL_reV-0.9.
|
93
|
-
NREL_reV-0.9.
|
94
|
-
NREL_reV-0.9.
|
95
|
-
NREL_reV-0.9.
|
96
|
-
NREL_reV-0.9.
|
97
|
-
NREL_reV-0.9.
|
92
|
+
NREL_reV-0.9.4.dist-info/LICENSE,sha256=hDwoTANtan2ZpufBlXm5C3W_PJ-mCqItvlcobgjxL7k,1526
|
93
|
+
NREL_reV-0.9.4.dist-info/METADATA,sha256=IN6FHUL4PezUaGzk6bmUM-0fF1Ux2HGNQoXumrFo4Lg,10279
|
94
|
+
NREL_reV-0.9.4.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
95
|
+
NREL_reV-0.9.4.dist-info/entry_points.txt,sha256=KGtPEOQRZMSqKXjjv5jt_T4e4HQN0fHiaGdAWwTtuW4,617
|
96
|
+
NREL_reV-0.9.4.dist-info/top_level.txt,sha256=S6YF2ZYgXUB6n28SY0K2H8YB9tMJdXQ9CyQbo6VC89M,4
|
97
|
+
NREL_reV-0.9.4.dist-info/RECORD,,
|
reV/SAM/SAM.py
CHANGED
@@ -195,6 +195,11 @@ class SamResourceRetriever:
|
|
195
195
|
# make precip rate available for curtailment analysis
|
196
196
|
kwargs["precip_rate"] = True
|
197
197
|
|
198
|
+
sam_configs = project_points.sam_inputs.values()
|
199
|
+
needs_wd = any(_sam_config_contains_turbine_layout(sam_config)
|
200
|
+
for sam_config in sam_configs)
|
201
|
+
kwargs["require_wind_dir"] = needs_wd
|
202
|
+
|
198
203
|
elif res_handler == GeothermalResource:
|
199
204
|
args += (project_points.d,)
|
200
205
|
|
@@ -954,3 +959,8 @@ def _add_sys_capacity(sam_inputs):
|
|
954
959
|
cap = sam_inputs.get("nameplate")
|
955
960
|
|
956
961
|
sam_inputs["system_capacity"] = cap
|
962
|
+
|
963
|
+
|
964
|
+
def _sam_config_contains_turbine_layout(sam_config):
|
965
|
+
"""Detect wether SAM config contains multiple turbines in layout. """
|
966
|
+
return len(sam_config.get("wind_farm_xCoordinates", ())) > 1
|
reV/SAM/generation.py
CHANGED
@@ -1548,7 +1548,7 @@ class Geothermal(AbstractSamGenerationFromWeatherFile):
|
|
1548
1548
|
or 1 allowed.
|
1549
1549
|
- ``design_temp`` : EGS plant design temperature (in C). Only
|
1550
1550
|
affects EGS runs. This value may be adjusted internally by
|
1551
|
-
``reV under the following conditions:
|
1551
|
+
``reV`` under the following conditions:
|
1552
1552
|
|
1553
1553
|
- The design temperature is larger than the resource
|
1554
1554
|
temperature
|
reV/bespoke/bespoke.py
CHANGED
@@ -20,7 +20,6 @@ import pandas as pd
|
|
20
20
|
import psutil
|
21
21
|
from rex.joint_pd.joint_pd import JointPD
|
22
22
|
from rex.multi_year_resource import MultiYearWindResource
|
23
|
-
from rex.renewable_resource import WindResource
|
24
23
|
from rex.utilities.bc_parse_table import parse_bc_table
|
25
24
|
from rex.utilities.execution import SpawnProcessPool
|
26
25
|
from rex.utilities.loggers import create_dirs, log_mem
|
@@ -60,8 +59,13 @@ class BespokeMultiPlantData:
|
|
60
59
|
|
61
60
|
Parameters
|
62
61
|
----------
|
63
|
-
res_fpath : str
|
64
|
-
|
62
|
+
res_fpath : str | list
|
63
|
+
Unix shell style path (potentially containing wildcard (*)
|
64
|
+
patterns) to a single or multi-file resource file set(s).
|
65
|
+
Can also be an explicit list of resource file paths, which
|
66
|
+
themselves can contain wildcards. This input must be
|
67
|
+
readable by
|
68
|
+
:py:class:`rex.multi_year_resource.MultiYearWindResource`.
|
65
69
|
sc_gid_to_hh : dict
|
66
70
|
Dictionary mapping SC GID values to hub-heights. Data for
|
67
71
|
each SC GID will be pulled for the corresponding hub-height
|
@@ -69,7 +73,7 @@ class BespokeMultiPlantData:
|
|
69
73
|
sc_gid_to_res_gid : dict
|
70
74
|
Dictionary mapping SC GID values to an iterable oif resource
|
71
75
|
GID values. Resource GID values should correspond to GID
|
72
|
-
values in
|
76
|
+
values in the HDF5 file, so any GID map must be applied
|
73
77
|
before initializing :class`BespokeMultiPlantData`.
|
74
78
|
"""
|
75
79
|
self.res_fpath = res_fpath
|
@@ -95,12 +99,7 @@ class BespokeMultiPlantData:
|
|
95
99
|
}
|
96
100
|
|
97
101
|
start_time = time.time()
|
98
|
-
|
99
|
-
handler = MultiYearWindResource
|
100
|
-
else:
|
101
|
-
handler = WindResource
|
102
|
-
|
103
|
-
with handler(self.res_fpath) as res:
|
102
|
+
with MultiYearWindResource(self.res_fpath) as res:
|
104
103
|
self._wind_dirs = {
|
105
104
|
hh: res[f"winddirection_{hh}m", :, gids]
|
106
105
|
for hh, gids in self.hh_to_res_gids.items()
|
@@ -481,8 +480,7 @@ class BespokeSinglePlant:
|
|
481
480
|
self._pre_loaded_data = pre_loaded_data
|
482
481
|
self._outputs = {}
|
483
482
|
|
484
|
-
|
485
|
-
res = res if not isinstance(res, str) else Handler(res)
|
483
|
+
res = res if not isinstance(res, str) else MultiYearWindResource(res)
|
486
484
|
|
487
485
|
self._sc_point = AggSCPoint(
|
488
486
|
gid,
|
@@ -1142,29 +1140,6 @@ class BespokeSinglePlant:
|
|
1142
1140
|
lcoe_kwargs["capital_cost"] = lcoe_kwargs["capital_cost"] + bos
|
1143
1141
|
return lcoe_kwargs
|
1144
1142
|
|
1145
|
-
@staticmethod
|
1146
|
-
def get_wind_handler(res):
|
1147
|
-
"""Get a wind resource handler for a resource filepath.
|
1148
|
-
|
1149
|
-
Parameters
|
1150
|
-
----------
|
1151
|
-
res : str
|
1152
|
-
Resource filepath to wtk .h5 file. Can include * wildcards
|
1153
|
-
for multi year resource.
|
1154
|
-
|
1155
|
-
Returns
|
1156
|
-
-------
|
1157
|
-
handler : WindResource | MultiYearWindResource
|
1158
|
-
Wind resource handler or multi year handler
|
1159
|
-
"""
|
1160
|
-
handler = res
|
1161
|
-
if isinstance(res, str):
|
1162
|
-
if "*" in res:
|
1163
|
-
handler = MultiYearWindResource
|
1164
|
-
else:
|
1165
|
-
handler = WindResource
|
1166
|
-
return handler
|
1167
|
-
|
1168
1143
|
@classmethod
|
1169
1144
|
def check_dependencies(cls):
|
1170
1145
|
"""Check special dependencies for bespoke"""
|
@@ -1382,32 +1357,45 @@ class BespokeSinglePlant:
|
|
1382
1357
|
eos_mult = (self.plant_optimizer.capital_cost
|
1383
1358
|
/ self.plant_optimizer.capacity
|
1384
1359
|
/ baseline_cost)
|
1385
|
-
|
1360
|
+
reg_mult_cc = self.sam_sys_inputs.get(
|
1361
|
+
"capital_cost_multiplier", 1)
|
1362
|
+
reg_mult_foc = self.sam_sys_inputs.get(
|
1363
|
+
"fixed_operating_cost_multiplier", 1)
|
1364
|
+
reg_mult_voc = self.sam_sys_inputs.get(
|
1365
|
+
"variable_operating_cost_multiplier", 1)
|
1366
|
+
reg_mult_bos = self.sam_sys_inputs.get(
|
1367
|
+
"balance_of_system_cost_multiplier", 1)
|
1386
1368
|
|
1387
1369
|
self._meta[SupplyCurveField.EOS_MULT] = eos_mult
|
1388
|
-
self._meta[SupplyCurveField.REG_MULT] =
|
1370
|
+
self._meta[SupplyCurveField.REG_MULT] = reg_mult_cc
|
1389
1371
|
|
1390
|
-
cap_cost = (
|
1391
|
-
self.plant_optimizer.capital_cost
|
1392
|
-
+ self.plant_optimizer.balance_of_system_cost
|
1393
|
-
)
|
1394
1372
|
self._meta[SupplyCurveField.COST_SITE_OCC_USD_PER_AC_MW] = (
|
1395
|
-
|
1373
|
+
(self.plant_optimizer.capital_cost
|
1374
|
+
+ self.plant_optimizer.balance_of_system_cost)
|
1375
|
+
/ capacity_ac_mw
|
1396
1376
|
)
|
1397
1377
|
self._meta[SupplyCurveField.COST_BASE_OCC_USD_PER_AC_MW] = (
|
1398
|
-
|
1378
|
+
(self.plant_optimizer.capital_cost / eos_mult / reg_mult_cc
|
1379
|
+
+ self.plant_optimizer.balance_of_system_cost / reg_mult_bos)
|
1380
|
+
/ capacity_ac_mw
|
1399
1381
|
)
|
1400
1382
|
self._meta[SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW] = (
|
1401
|
-
self.plant_optimizer.fixed_operating_cost
|
1383
|
+
self.plant_optimizer.fixed_operating_cost
|
1384
|
+
/ capacity_ac_mw
|
1402
1385
|
)
|
1403
1386
|
self._meta[SupplyCurveField.COST_BASE_FOC_USD_PER_AC_MW] = (
|
1404
|
-
self.plant_optimizer.fixed_operating_cost
|
1387
|
+
self.plant_optimizer.fixed_operating_cost
|
1388
|
+
/ reg_mult_foc
|
1389
|
+
/ capacity_ac_mw
|
1405
1390
|
)
|
1406
1391
|
self._meta[SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MW] = (
|
1407
|
-
self.plant_optimizer.variable_operating_cost
|
1392
|
+
self.plant_optimizer.variable_operating_cost
|
1393
|
+
/ capacity_ac_mw
|
1408
1394
|
)
|
1409
1395
|
self._meta[SupplyCurveField.COST_BASE_VOC_USD_PER_AC_MW] = (
|
1410
|
-
self.plant_optimizer.variable_operating_cost
|
1396
|
+
self.plant_optimizer.variable_operating_cost
|
1397
|
+
/ reg_mult_voc
|
1398
|
+
/ capacity_ac_mw
|
1411
1399
|
)
|
1412
1400
|
self._meta[SupplyCurveField.FIXED_CHARGE_RATE] = (
|
1413
1401
|
self.plant_optimizer.fixed_charge_rate
|
@@ -1489,8 +1477,9 @@ class BespokeWindPlants(BaseAggregation):
|
|
1489
1477
|
ws_bins=(0.0, 20.0, 5.0), wd_bins=(0.0, 360.0, 45.0),
|
1490
1478
|
excl_dict=None, area_filter_kernel='queen', min_area=None,
|
1491
1479
|
resolution=64, excl_area=None, data_layers=None,
|
1492
|
-
pre_extract_inclusions=False,
|
1493
|
-
|
1480
|
+
pre_extract_inclusions=False, eos_mult_baseline_cap_mw=200,
|
1481
|
+
prior_run=None, gid_map=None, bias_correct=None,
|
1482
|
+
pre_load_data=False):
|
1494
1483
|
"""reV bespoke analysis class.
|
1495
1484
|
|
1496
1485
|
Much like generation, ``reV`` bespoke analysis runs SAM
|
@@ -1521,14 +1510,15 @@ class BespokeWindPlants(BaseAggregation):
|
|
1521
1510
|
uniquely defined (i.e.only appear once and in a single
|
1522
1511
|
input file).
|
1523
1512
|
res_fpath : str
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1513
|
+
Unix shell style path to wind resource HDF5 file in NREL WTK
|
1514
|
+
format. Can also be a path including a wildcard input like
|
1515
|
+
``/h5_dir/prefix*suffix`` to run bespoke on multiple years
|
1516
|
+
of resource data. Can also be an explicit list of resource
|
1517
|
+
HDF5 file paths, which themselves can contain wildcards. If
|
1518
|
+
multiple files are specified in this way, they must have the
|
1519
|
+
same coordinates but can have different time indices (i.e.
|
1520
|
+
different years). This input must be readable by
|
1521
|
+
:py:class:`rex.multi_year_resource.MultiYearWindResource`
|
1532
1522
|
(i.e. the resource data conform to the
|
1533
1523
|
`rex data format <https://tinyurl.com/3fy7v5kx>`_). This
|
1534
1524
|
means the data file(s) must contain a 1D ``time_index``
|
@@ -1855,6 +1845,13 @@ class BespokeWindPlants(BaseAggregation):
|
|
1855
1845
|
the `excl_dict` input. It is typically faster to compute
|
1856
1846
|
the inclusion mask on the fly with parallel workers.
|
1857
1847
|
By default, ``False``.
|
1848
|
+
eos_mult_baseline_cap_mw : int | float, optional
|
1849
|
+
Baseline plant capacity (MW) used to calculate economies of
|
1850
|
+
scale (EOS) multiplier from the `capital_cost_function`. EOS
|
1851
|
+
multiplier is calculated as the $-per-kW of the wind plant
|
1852
|
+
divided by the $-per-kW of a plant with this baseline
|
1853
|
+
capacity. By default, `200` (MW), which aligns the baseline
|
1854
|
+
with ATB assumptions. See here: https://tinyurl.com/y85hnu6h.
|
1858
1855
|
prior_run : str, optional
|
1859
1856
|
Optional filepath to a bespoke output HDF5 file belonging to
|
1860
1857
|
a prior run. If specified, this module will only run the
|
@@ -1980,6 +1977,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
1980
1977
|
self._ws_bins = ws_bins
|
1981
1978
|
self._wd_bins = wd_bins
|
1982
1979
|
self._data_layers = data_layers
|
1980
|
+
self._eos_mult_baseline_cap_mw = eos_mult_baseline_cap_mw
|
1983
1981
|
self._prior_meta = self._parse_prior_run(prior_run)
|
1984
1982
|
self._gid_map = BespokeSinglePlant._parse_gid_map(gid_map)
|
1985
1983
|
self._bias_correct = Gen._parse_bc(bias_correct)
|
@@ -2119,8 +2117,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
2119
2117
|
)
|
2120
2118
|
|
2121
2119
|
# just check that this file exists, cannot check res_fpath if *glob
|
2122
|
-
|
2123
|
-
with Handler(self._res_fpath) as f:
|
2120
|
+
with MultiYearWindResource(self._res_fpath) as f:
|
2124
2121
|
assert any(f.dsets)
|
2125
2122
|
|
2126
2123
|
def _pre_load_data(self, pre_load_data):
|
@@ -2453,8 +2450,8 @@ class BespokeWindPlants(BaseAggregation):
|
|
2453
2450
|
area_filter_kernel='queen', min_area=None,
|
2454
2451
|
resolution=64, excl_area=0.0081, data_layers=None,
|
2455
2452
|
gids=None, exclusion_shape=None, slice_lookup=None,
|
2456
|
-
|
2457
|
-
pre_loaded_data=None):
|
2453
|
+
eos_mult_baseline_cap_mw=200, prior_meta=None,
|
2454
|
+
gid_map=None, bias_correct=None, pre_loaded_data=None):
|
2458
2455
|
"""
|
2459
2456
|
Standalone serial method to run bespoke optimization.
|
2460
2457
|
See BespokeWindPlants docstring for parameter description.
|
@@ -2480,14 +2477,13 @@ class BespokeWindPlants(BaseAggregation):
|
|
2480
2477
|
exclusion_shape = sc.exclusions.shape
|
2481
2478
|
|
2482
2479
|
cls._check_inclusion_mask(inclusion_mask, gids, exclusion_shape)
|
2483
|
-
Handler = BespokeSinglePlant.get_wind_handler(res_fpath)
|
2484
2480
|
|
2485
2481
|
# pre-extract handlers so they are not repeatedly initialized
|
2486
2482
|
file_kwargs = {
|
2487
2483
|
"excl_dict": excl_dict,
|
2488
2484
|
"area_filter_kernel": area_filter_kernel,
|
2489
2485
|
"min_area": min_area,
|
2490
|
-
"h5_handler":
|
2486
|
+
"h5_handler": MultiYearWindResource,
|
2491
2487
|
}
|
2492
2488
|
|
2493
2489
|
with AggFileHandler(excl_fpath, res_fpath, **file_kwargs) as fh:
|
@@ -2520,6 +2516,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
2520
2516
|
excl_area=excl_area,
|
2521
2517
|
data_layers=data_layers,
|
2522
2518
|
exclusion_shape=exclusion_shape,
|
2519
|
+
eos_mult_baseline_cap_mw=eos_mult_baseline_cap_mw,
|
2523
2520
|
prior_meta=prior_meta,
|
2524
2521
|
gid_map=gid_map,
|
2525
2522
|
bias_correct=bias_correct,
|
@@ -2612,6 +2609,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
2612
2609
|
gids=gid,
|
2613
2610
|
exclusion_shape=self.shape,
|
2614
2611
|
slice_lookup=copy.deepcopy(self.slice_lookup),
|
2612
|
+
eos_mult_baseline_cap_mw=self._eos_mult_baseline_cap_mw,
|
2615
2613
|
prior_meta=self._get_prior_meta(gid),
|
2616
2614
|
gid_map=self._gid_map,
|
2617
2615
|
bias_correct=self._get_bc_for_gid(gid),
|
@@ -2676,6 +2674,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
2676
2674
|
afk = self._area_filter_kernel
|
2677
2675
|
wlm = self._wake_loss_multiplier
|
2678
2676
|
i_bc = self._get_bc_for_gid(gid)
|
2677
|
+
ebc = self._eos_mult_baseline_cap_mw
|
2679
2678
|
|
2680
2679
|
si = self.run_serial(self._excl_fpath,
|
2681
2680
|
self._res_fpath,
|
@@ -2700,6 +2699,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
2700
2699
|
excl_area=self._excl_area,
|
2701
2700
|
data_layers=self._data_layers,
|
2702
2701
|
slice_lookup=slice_lookup,
|
2702
|
+
eos_mult_baseline_cap_mw=ebc,
|
2703
2703
|
prior_meta=prior_meta,
|
2704
2704
|
gid_map=self._gid_map,
|
2705
2705
|
bias_correct=i_bc,
|
reV/generation/generation.py
CHANGED
@@ -236,10 +236,10 @@ class Gen(BaseGen):
|
|
236
236
|
info on the allowed and/or required SAM config file inputs.
|
237
237
|
resource_file : str
|
238
238
|
Filepath to resource data. This input can be path to a
|
239
|
-
single resource HDF5 file
|
240
|
-
|
241
|
-
a
|
242
|
-
cases, the resource data must be readable by
|
239
|
+
single resource HDF5 file or a path including a wildcard
|
240
|
+
input like ``/h5_dir/prefix*suffix`` (i.e. if your datasets
|
241
|
+
for a single year are spread out over multiple files). In
|
242
|
+
all cases, the resource data must be readable by
|
243
243
|
:py:class:`rex.resource.Resource`
|
244
244
|
or :py:class:`rex.multi_file_resource.MultiFileResource`.
|
245
245
|
(i.e. the resource data conform to the
|
@@ -253,8 +253,14 @@ class Gen(BaseGen):
|
|
253
253
|
consideration, and its shape must be a multiple of 8760.
|
254
254
|
|
255
255
|
.. Note:: If executing ``reV`` from the command line, this
|
256
|
-
|
257
|
-
the `analysis_years` input.
|
256
|
+
input string can contain brackets ``{}`` that will be
|
257
|
+
filled in by the `analysis_years` input. Alternatively,
|
258
|
+
this input can be a list of explicit files to process. In
|
259
|
+
this case, the length of the list must match the length of
|
260
|
+
the `analysis_years` input exactly, and the path are
|
261
|
+
assumed to align with the `analysis_years` (i.e. the first
|
262
|
+
path corresponds to the first analysis year, the second
|
263
|
+
path corresponds to the second analysis year, and so on).
|
258
264
|
|
259
265
|
.. Important:: If you are using custom resource data (i.e.
|
260
266
|
not NSRDB/WTK/Sup3rCC, etc.), ensure the following:
|
reV/handlers/multi_year.py
CHANGED
@@ -103,8 +103,9 @@ class MultiYearGroup:
|
|
103
103
|
|
104
104
|
if "lcoe_fcr" in dsets:
|
105
105
|
for dset in LCOE_REQUIRED_OUTPUTS:
|
106
|
-
if dset not in pass_through_dsets:
|
106
|
+
if dset not in pass_through_dsets and dset in dsets:
|
107
107
|
pass_through_dsets.append(dset)
|
108
|
+
|
108
109
|
if "dc_ac_ratio" in dsets:
|
109
110
|
if "dc_ac_ratio" not in pass_through_dsets:
|
110
111
|
pass_through_dsets.append("dc_ac_ratio")
|
@@ -839,11 +840,6 @@ def my_collect_groups(out_fpath, groups, clobber=True):
|
|
839
840
|
dset, group=group['group'])
|
840
841
|
|
841
842
|
pass_through_dsets = group.get('pass_through_dsets') or []
|
842
|
-
if "lcoe_fcr" in group['dsets']:
|
843
|
-
for dset in LCOE_REQUIRED_OUTPUTS:
|
844
|
-
if dset not in pass_through_dsets:
|
845
|
-
pass_through_dsets.append(dset)
|
846
|
-
|
847
843
|
for dset in pass_through_dsets:
|
848
844
|
MultiYear.pass_through(out_fpath, group['source_files'],
|
849
845
|
dset, group=group['group'])
|
@@ -50,12 +50,25 @@ def _preprocessor(config, out_dir):
|
|
50
50
|
def _format_res_fpath(config):
|
51
51
|
"""Format res_fpath with year, if need be. """
|
52
52
|
res_fpath = config.setdefault("res_fpath", None)
|
53
|
-
if isinstance(res_fpath, str)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
if isinstance(res_fpath, str):
|
54
|
+
if '{}' in res_fpath:
|
55
|
+
for year in range(1950, 2100):
|
56
|
+
if os.path.exists(res_fpath.format(year)):
|
57
|
+
break
|
58
|
+
else:
|
59
|
+
msg = ("Could not find any files that match the pattern"
|
60
|
+
"{!r}".format(res_fpath.format("<year>")))
|
61
|
+
logger.error(msg)
|
62
|
+
raise FileNotFoundError(msg)
|
63
|
+
|
64
|
+
res_fpath = res_fpath.format(year)
|
65
|
+
|
66
|
+
elif not os.path.exists(res_fpath):
|
67
|
+
msg = "Could not find resource file: {!r}".format(res_fpath)
|
68
|
+
logger.error(msg)
|
69
|
+
raise FileNotFoundError(msg)
|
70
|
+
|
71
|
+
config["res_fpath"] = res_fpath
|
59
72
|
|
60
73
|
return config
|
61
74
|
|
@@ -18,7 +18,6 @@ from rex.multi_file_resource import MultiFileResource
|
|
18
18
|
from rex.resource import Resource
|
19
19
|
from rex.utilities.execution import SpawnProcessPool
|
20
20
|
|
21
|
-
from reV.generation.base import BaseGen
|
22
21
|
from reV.handlers.exclusions import ExclusionLayers
|
23
22
|
from reV.supply_curve.aggregation import (
|
24
23
|
AbstractAggFileHandler,
|
@@ -1410,7 +1409,7 @@ class SupplyCurveAggregation(BaseAggregation):
|
|
1410
1409
|
``multi-year``, ``collect``, or ``econ``. However, note
|
1411
1410
|
that duplicate executions of any of these commands within
|
1412
1411
|
the pipeline may invalidate this parsing, meaning the
|
1413
|
-
`
|
1412
|
+
`gen_fpath` input will have to be specified manually.
|
1414
1413
|
|
1415
1414
|
By default, ``None``.
|
1416
1415
|
args : tuple | list, optional
|
reV/supply_curve/tech_mapping.py
CHANGED
@@ -185,7 +185,7 @@ class TechMapping:
|
|
185
185
|
excl_row_slices, excl_col_slices,
|
186
186
|
coord_labels=(LATITUDE, LONGITUDE)):
|
187
187
|
"""
|
188
|
-
Extract the exclusion coordinates for
|
188
|
+
Extract the exclusion coordinates for the desired gids for TechMapping.
|
189
189
|
|
190
190
|
Parameters
|
191
191
|
----------
|
reV/version.py
CHANGED
File without changes
|
File without changes
|
File without changes
|