NREL-reV 0.13.1__tar.gz → 0.14.1__tar.gz
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.13.1 → nrel_rev-0.14.1/NREL_reV.egg-info}/PKG-INFO +2 -5
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/NREL_reV.egg-info/SOURCES.txt +1 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/NREL_reV.egg-info/requires.txt +1 -1
- {nrel_rev-0.13.1/NREL_reV.egg-info → nrel_rev-0.14.1}/PKG-INFO +2 -5
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/README.rst +0 -3
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/pyproject.toml +2 -2
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/version_checker.py +3 -2
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/bespoke/bespoke.py +22 -15
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/cli.py +4 -2
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/project_points.py +8 -5
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/econ/economies_of_scale.py +160 -61
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/cli_gen.py +4 -2
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/losses/scheduled.py +18 -31
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/aggregation.py +15 -6
- nrel_rev-0.14.1/reV/supply_curve/cli_tech_mapping.py +66 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/points.py +118 -28
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/sc_aggregation.py +93 -23
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/tech_mapping.py +190 -245
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/__init__.py +9 -4
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/version.py +1 -1
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/LICENSE +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/MANIFEST.in +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/NREL_reV.egg-info/dependency_links.txt +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/NREL_reV.egg-info/entry_points.txt +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/NREL_reV.egg-info/top_level.txt +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/SAM.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults/USA AZ Phoenix Sky Harbor Intl Ap (TMY3).csv +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults/USA CA Daggett (TMY2).csv +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults/US_Wave.csv +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults/WY Southern-Flat Lands.srw +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults/geothermal.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults/i_pvwattsv5.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/defaults.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/econ.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/generation.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/SAM/windbos.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/bespoke/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/bespoke/cli_bespoke.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/bespoke/gradient_free.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/bespoke/pack_turbs.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/bespoke/place_turbines.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/base_analysis_config.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/base_config.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/cli_project_points.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/curtailment.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/execution.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/output_request.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/config/sam_config.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/econ/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/econ/cli_econ.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/econ/econ.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/econ/utilities.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/base.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/generation.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/generation.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/lcoe_fcr.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/lcoe_fcr_inputs.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/linear_fresnel.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/other.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/single_owner.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/solar_water_heat.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/trough_heat.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/generation/output_attributes/windbos.json +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/cli_collect.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/cli_multi_year.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/exclusions.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/multi_year.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/outputs.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/handlers/transmission.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/hybrids/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/hybrids/cli_hybrids.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/hybrids/hybrid_methods.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/hybrids/hybrids.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/losses/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/losses/power_curve.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/losses/utils.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/nrwal/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/nrwal/cli_nrwal.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/nrwal/nrwal.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/qa_qc/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/qa_qc/cli_qa_qc.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/qa_qc/qa_qc.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/qa_qc/summary.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/rep_profiles/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/rep_profiles/cli_rep_profiles.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/rep_profiles/rep_profiles.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/__init__.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/cli_sc_aggregation.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/cli_supply_curve.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/competitive_wind_farms.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/exclusions.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/extent.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/supply_curve/supply_curve.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/_clean_readme.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/cli_functions.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/curtailment.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/exceptions.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/pytest_utils.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/reV/utilities/slots.py +0 -0
- {nrel_rev-0.13.1 → nrel_rev-0.14.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: NREL-reV
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.14.1
|
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>
|
@@ -22,7 +22,7 @@ Description-Content-Type: text/x-rst
|
|
22
22
|
License-File: LICENSE
|
23
23
|
Requires-Dist: NREL-gaps<0.9,>=0.8.0
|
24
24
|
Requires-Dist: NREL-NRWAL<0.1,>=0.0.11
|
25
|
-
Requires-Dist: NREL-PySAM~=
|
25
|
+
Requires-Dist: NREL-PySAM~=7.0.0
|
26
26
|
Requires-Dist: NREL-rex<0.4,>=0.3.2
|
27
27
|
Requires-Dist: numpy<3,>=2.0.2
|
28
28
|
Requires-Dist: packaging<25,>=24.2
|
@@ -156,9 +156,6 @@ Option 1: Install from PIP (recommended for analysts):
|
|
156
156
|
3. Install reV:
|
157
157
|
1) ``pip install NREL-reV`` or
|
158
158
|
|
159
|
-
- NOTE: If you install using conda and want to run from files directly on S3 like in the `running reV locally example <https://nrel.github.io/reV/misc/examples.running_locally.html>`_
|
160
|
-
you will also need to install S3 filesystem dependencies: ``pip install NREL-reV[s3]``
|
161
|
-
|
162
159
|
- NOTE: If you install using conda and want to use `HSDS <https://github.com/NREL/hsds-examples>`_
|
163
160
|
you will also need to install HSDS dependencies: ``pip install NREL-reV[hsds]``
|
164
161
|
|
@@ -86,6 +86,7 @@ reV/supply_curve/__init__.py
|
|
86
86
|
reV/supply_curve/aggregation.py
|
87
87
|
reV/supply_curve/cli_sc_aggregation.py
|
88
88
|
reV/supply_curve/cli_supply_curve.py
|
89
|
+
reV/supply_curve/cli_tech_mapping.py
|
89
90
|
reV/supply_curve/competitive_wind_farms.py
|
90
91
|
reV/supply_curve/exclusions.py
|
91
92
|
reV/supply_curve/extent.py
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: NREL-reV
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.14.1
|
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>
|
@@ -22,7 +22,7 @@ Description-Content-Type: text/x-rst
|
|
22
22
|
License-File: LICENSE
|
23
23
|
Requires-Dist: NREL-gaps<0.9,>=0.8.0
|
24
24
|
Requires-Dist: NREL-NRWAL<0.1,>=0.0.11
|
25
|
-
Requires-Dist: NREL-PySAM~=
|
25
|
+
Requires-Dist: NREL-PySAM~=7.0.0
|
26
26
|
Requires-Dist: NREL-rex<0.4,>=0.3.2
|
27
27
|
Requires-Dist: numpy<3,>=2.0.2
|
28
28
|
Requires-Dist: packaging<25,>=24.2
|
@@ -156,9 +156,6 @@ Option 1: Install from PIP (recommended for analysts):
|
|
156
156
|
3. Install reV:
|
157
157
|
1) ``pip install NREL-reV`` or
|
158
158
|
|
159
|
-
- NOTE: If you install using conda and want to run from files directly on S3 like in the `running reV locally example <https://nrel.github.io/reV/misc/examples.running_locally.html>`_
|
160
|
-
you will also need to install S3 filesystem dependencies: ``pip install NREL-reV[s3]``
|
161
|
-
|
162
159
|
- NOTE: If you install using conda and want to use `HSDS <https://github.com/NREL/hsds-examples>`_
|
163
160
|
you will also need to install HSDS dependencies: ``pip install NREL-reV[hsds]``
|
164
161
|
|
@@ -111,9 +111,6 @@ Option 1: Install from PIP (recommended for analysts):
|
|
111
111
|
3. Install reV:
|
112
112
|
1) ``pip install NREL-reV`` or
|
113
113
|
|
114
|
-
- NOTE: If you install using conda and want to run from files directly on S3 like in the `running reV locally example <https://nrel.github.io/reV/misc/examples.running_locally.html>`_
|
115
|
-
you will also need to install S3 filesystem dependencies: ``pip install NREL-reV[s3]``
|
116
|
-
|
117
114
|
- NOTE: If you install using conda and want to use `HSDS <https://github.com/NREL/hsds-examples>`_
|
118
115
|
you will also need to install HSDS dependencies: ``pip install NREL-reV[hsds]``
|
119
116
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[build-system]
|
2
2
|
requires = [
|
3
|
-
"setuptools >=
|
3
|
+
"setuptools >= 80",
|
4
4
|
"setuptools_scm[toml] >= 8",
|
5
5
|
]
|
6
6
|
build-backend = 'setuptools.build_meta'
|
@@ -33,7 +33,7 @@ classifiers=[
|
|
33
33
|
dependencies = [
|
34
34
|
"NREL-gaps>=0.8.0,<0.9",
|
35
35
|
"NREL-NRWAL>=0.0.11,<0.1",
|
36
|
-
"NREL-PySAM~=
|
36
|
+
"NREL-PySAM~=7.0.0",
|
37
37
|
"NREL-rex>=0.3.2,<0.4",
|
38
38
|
"numpy>=2.0.2,<3",
|
39
39
|
"packaging>=24.2,<25",
|
@@ -6,8 +6,9 @@ Created on Mon Feb 3 14:40:42 2020
|
|
6
6
|
@author: gbuster
|
7
7
|
"""
|
8
8
|
import logging
|
9
|
+
import importlib
|
9
10
|
from warnings import warn
|
10
|
-
|
11
|
+
|
11
12
|
from packaging import version
|
12
13
|
from reV.utilities.exceptions import PySAMVersionError, PySAMVersionWarning
|
13
14
|
|
@@ -105,7 +106,7 @@ class PySamVersionChecker:
|
|
105
106
|
@property
|
106
107
|
def pysam_version(self):
|
107
108
|
"""Get the PySAM distribution version"""
|
108
|
-
return
|
109
|
+
return importlib.metadata.version("nrel-pysam")
|
109
110
|
|
110
111
|
@classmethod
|
111
112
|
def run(cls, tech, parameters):
|
@@ -23,7 +23,7 @@ from rex.multi_year_resource import MultiYearWindResource
|
|
23
23
|
from rex.utilities.bc_parse_table import parse_bc_table
|
24
24
|
from rex.utilities.execution import SpawnProcessPool
|
25
25
|
from rex.utilities.loggers import create_dirs, log_mem
|
26
|
-
from rex.utilities.utilities import parse_year
|
26
|
+
from rex.utilities.utilities import parse_year, check_res_file
|
27
27
|
|
28
28
|
from reV.config.output_request import SAMOutputRequest
|
29
29
|
from reV.econ.utilities import lcoe_fcr
|
@@ -80,7 +80,8 @@ class BespokeMultiPlantData:
|
|
80
80
|
Option to pre-load relative humidity data (useful for icing
|
81
81
|
runs). If ``False``, relative humidities are not loaded.
|
82
82
|
"""
|
83
|
-
self.res_fpath = res_fpath
|
83
|
+
self.res_fpath = ([res_fpath]
|
84
|
+
if isinstance(res_fpath, str) else res_fpath)
|
84
85
|
self.sc_gid_to_hh = sc_gid_to_hh
|
85
86
|
self.sc_gid_to_res_gid = sc_gid_to_res_gid
|
86
87
|
self.hh_to_res_gids = {}
|
@@ -104,8 +105,9 @@ class BespokeMultiPlantData:
|
|
104
105
|
hh: sorted(gids) for hh, gids in self.hh_to_res_gids.items()
|
105
106
|
}
|
106
107
|
|
108
|
+
hsds = all(check_res_file(fp)[1] for fp in self.res_fpath)
|
107
109
|
start_time = time.time()
|
108
|
-
with MultiYearWindResource(self.res_fpath) as res:
|
110
|
+
with MultiYearWindResource(self.res_fpath, hsds=hsds) as res:
|
109
111
|
self._wind_dirs = {
|
110
112
|
hh: res[f"winddirection_{hh}m", :, gids]
|
111
113
|
for hh, gids in self.hh_to_res_gids.items()
|
@@ -488,7 +490,9 @@ class BespokeSinglePlant:
|
|
488
490
|
self._pre_loaded_data = pre_loaded_data
|
489
491
|
self._outputs = {}
|
490
492
|
|
491
|
-
|
493
|
+
if isinstance(res, str):
|
494
|
+
__, hsds = check_res_file(res)
|
495
|
+
res = MultiYearWindResource(res, hsds=hsds)
|
492
496
|
|
493
497
|
self._sc_point = AggSCPoint(
|
494
498
|
gid,
|
@@ -1087,8 +1091,8 @@ class BespokeSinglePlant:
|
|
1087
1091
|
fcr = lcoe_kwargs['fixed_charge_rate']
|
1088
1092
|
cc = lcoe_kwargs['capital_cost']
|
1089
1093
|
foc = lcoe_kwargs['fixed_operating_cost']
|
1090
|
-
voc = lcoe_kwargs['variable_operating_cost']
|
1091
|
-
aep = self.outputs['annual_energy-means']
|
1094
|
+
voc = lcoe_kwargs['variable_operating_cost'] # $/kWh
|
1095
|
+
aep = self.outputs['annual_energy-means'] # kWh
|
1092
1096
|
|
1093
1097
|
my_mean_lcoe = lcoe_fcr(fcr, cc, foc, aep, voc)
|
1094
1098
|
|
@@ -1184,6 +1188,7 @@ class BespokeSinglePlant:
|
|
1184
1188
|
'wind_resource_data',
|
1185
1189
|
'wind_turbine_powercurve_powerout',
|
1186
1190
|
'adjust_hourly',
|
1191
|
+
'adjust_timeindex',
|
1187
1192
|
'capital_cost',
|
1188
1193
|
'fixed_operating_cost',
|
1189
1194
|
'variable_operating_cost',
|
@@ -1387,12 +1392,12 @@ class BespokeSinglePlant:
|
|
1387
1392
|
self._meta[SupplyCurveField.EOS_MULT] = eos_mult
|
1388
1393
|
self._meta[SupplyCurveField.REG_MULT] = reg_mult_cc
|
1389
1394
|
|
1390
|
-
self._meta[SupplyCurveField.
|
1395
|
+
self._meta[SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW] = (
|
1391
1396
|
(self.plant_optimizer.capital_cost
|
1392
1397
|
+ self.plant_optimizer.balance_of_system_cost)
|
1393
1398
|
/ capacity_ac_mw
|
1394
1399
|
)
|
1395
|
-
self._meta[SupplyCurveField.
|
1400
|
+
self._meta[SupplyCurveField.COST_BASE_CC_USD_PER_AC_MW] = (
|
1396
1401
|
(self.plant_optimizer.capital_cost / eos_mult / reg_mult_cc
|
1397
1402
|
+ self.plant_optimizer.balance_of_system_cost / reg_mult_bos)
|
1398
1403
|
/ capacity_ac_mw
|
@@ -1406,14 +1411,13 @@ class BespokeSinglePlant:
|
|
1406
1411
|
/ reg_mult_foc
|
1407
1412
|
/ capacity_ac_mw
|
1408
1413
|
)
|
1409
|
-
self._meta[SupplyCurveField.
|
1410
|
-
self.plant_optimizer.variable_operating_cost
|
1411
|
-
/ capacity_ac_mw
|
1414
|
+
self._meta[SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH] = (
|
1415
|
+
self.plant_optimizer.variable_operating_cost * 1000 # to $/MWh
|
1412
1416
|
)
|
1413
|
-
self._meta[SupplyCurveField.
|
1417
|
+
self._meta[SupplyCurveField.COST_BASE_VOC_USD_PER_AC_MWH] = (
|
1414
1418
|
self.plant_optimizer.variable_operating_cost
|
1415
1419
|
/ reg_mult_voc
|
1416
|
-
|
1420
|
+
* 1000 # to $/MWh
|
1417
1421
|
)
|
1418
1422
|
self._meta[SupplyCurveField.FIXED_CHARGE_RATE] = (
|
1419
1423
|
self.plant_optimizer.fixed_charge_rate
|
@@ -1972,7 +1976,8 @@ class BespokeWindPlants(BaseAggregation):
|
|
1972
1976
|
pre_extract_inclusions=pre_extract_inclusions,
|
1973
1977
|
)
|
1974
1978
|
|
1975
|
-
self._res_fpath = res_fpath
|
1979
|
+
self._res_fpath = ([res_fpath]
|
1980
|
+
if isinstance(res_fpath, str) else res_fpath)
|
1976
1981
|
self._obj_fun = objective_function
|
1977
1982
|
self._cap_cost_fun = capital_cost_function
|
1978
1983
|
self._foc_fun = fixed_operating_cost_function
|
@@ -2123,8 +2128,9 @@ class BespokeWindPlants(BaseAggregation):
|
|
2123
2128
|
)
|
2124
2129
|
)
|
2125
2130
|
|
2131
|
+
hsds = all(check_res_file(fp)[1] for fp in self._res_fpath)
|
2126
2132
|
# just check that this file exists, cannot check res_fpath if *glob
|
2127
|
-
with MultiYearWindResource(self._res_fpath) as f:
|
2133
|
+
with MultiYearWindResource(self._res_fpath, hsds=hsds) as f:
|
2128
2134
|
assert any(f.dsets)
|
2129
2135
|
|
2130
2136
|
def _pre_load_data(self, pre_load_data):
|
@@ -2494,6 +2500,7 @@ class BespokeWindPlants(BaseAggregation):
|
|
2494
2500
|
"area_filter_kernel": area_filter_kernel,
|
2495
2501
|
"min_area": min_area,
|
2496
2502
|
"h5_handler": MultiYearWindResource,
|
2503
|
+
"hsds": all(check_res_file(fp)[1] for fp in res_fpath),
|
2497
2504
|
}
|
2498
2505
|
|
2499
2506
|
with AggFileHandler(excl_fpath, res_fpath, **file_kwargs) as fh:
|
@@ -12,6 +12,7 @@ from reV.handlers.cli_collect import collect_command
|
|
12
12
|
from reV.handlers.cli_multi_year import my_command
|
13
13
|
from reV.supply_curve.cli_sc_aggregation import sc_agg_command
|
14
14
|
from reV.supply_curve.cli_supply_curve import sc_command
|
15
|
+
from reV.supply_curve.cli_tech_mapping import tm_command
|
15
16
|
from reV.rep_profiles.cli_rep_profiles import rep_profiles_command
|
16
17
|
from reV.hybrids.cli_hybrids import hybrids_command
|
17
18
|
from reV.nrwal.cli_nrwal import nrwal_command
|
@@ -24,8 +25,9 @@ logger = logging.getLogger(__name__)
|
|
24
25
|
|
25
26
|
|
26
27
|
commands = [bespoke_command, gen_command, econ_command, collect_command,
|
27
|
-
my_command, sc_agg_command, sc_command,
|
28
|
-
hybrids_command, nrwal_command,
|
28
|
+
my_command, tm_command, sc_agg_command, sc_command,
|
29
|
+
rep_profiles_command, hybrids_command, nrwal_command,
|
30
|
+
qa_qc_command]
|
29
31
|
main = make_cli(commands, info={"name": "reV", "version": __version__})
|
30
32
|
main.add_command(qa_qc_extra)
|
31
33
|
main.add_command(project_points)
|
@@ -464,8 +464,10 @@ class ProjectPoints:
|
|
464
464
|
h_var = "wind_turbine_hub_ht"
|
465
465
|
if self._h is None:
|
466
466
|
if "wind" in self.tech:
|
467
|
-
|
468
|
-
|
467
|
+
if h_var in self.df.columns:
|
468
|
+
self._h = self.df[h_var].values.tolist()
|
469
|
+
else:
|
470
|
+
self._h = [self[site][1][h_var] for site in self.sites]
|
469
471
|
|
470
472
|
return self._h
|
471
473
|
|
@@ -837,7 +839,6 @@ class ProjectPoints:
|
|
837
839
|
logger.error(msg)
|
838
840
|
raise ConfigError(msg)
|
839
841
|
|
840
|
-
|
841
842
|
unused_configs = set(curtail_configs) - set(df_configs)
|
842
843
|
if unused_configs:
|
843
844
|
msg = ("One or more curtailment configurations not found in "
|
@@ -1164,12 +1165,14 @@ class ProjectPoints:
|
|
1164
1165
|
multi_h5_res, hsds = check_res_file(res_file)
|
1165
1166
|
if multi_h5_res:
|
1166
1167
|
res_cls = MultiFileResourceX
|
1168
|
+
res_kwargs = {}
|
1167
1169
|
else:
|
1168
1170
|
res_cls = ResourceX
|
1171
|
+
res_kwargs = {"hsds": hsds}
|
1169
1172
|
|
1170
1173
|
logger.info("Extracting ProjectPoints for desired regions")
|
1171
1174
|
points = []
|
1172
|
-
with res_cls(res_file,
|
1175
|
+
with res_cls(res_file, **res_kwargs) as f:
|
1173
1176
|
meta = f.meta
|
1174
1177
|
for region, region_col in regions.items():
|
1175
1178
|
logger.debug("- {}: {}".format(region_col, region))
|
@@ -1181,7 +1184,7 @@ class ProjectPoints:
|
|
1181
1184
|
if duplicates:
|
1182
1185
|
msg = (
|
1183
1186
|
"reV Cannot currently handle duplicate "
|
1184
|
-
"Resource gids! The given regions
|
1187
|
+
"Resource gids! The given regions containing the "
|
1185
1188
|
"same gids:\n{}".format(duplicates)
|
1186
1189
|
)
|
1187
1190
|
logger.error(msg)
|
@@ -34,31 +34,54 @@ class EconomiesOfScale:
|
|
34
34
|
lcoe : $/MWh
|
35
35
|
"""
|
36
36
|
|
37
|
-
def __init__(self,
|
37
|
+
def __init__(self, data, cap_eqn=None, fixed_eqn=None, var_eqn=None):
|
38
38
|
"""
|
39
|
+
|
39
40
|
Parameters
|
40
41
|
----------
|
41
|
-
eqn : str
|
42
|
-
LCOE scaling equation to implement "economies of scale".
|
43
|
-
Equation must be in python string format and return a scalar
|
44
|
-
value to multiply the capital cost by. Independent variables in
|
45
|
-
the equation should match the keys in the data input arg. This
|
46
|
-
equation may use numpy functions with the package prefix "np".
|
47
42
|
data : dict | pd.DataFrame
|
48
43
|
Namespace of econ data to use to calculate economies of scale. Keys
|
49
44
|
in dict or column labels in dataframe should match the Independent
|
50
45
|
variables in the eqn input. Should also include variables required
|
51
46
|
to calculate LCOE.
|
47
|
+
cap_eqn : str, optional
|
48
|
+
LCOE scaling equation to implement "economies of scale".
|
49
|
+
Equation must be in python string format and return a scalar
|
50
|
+
value to multiply the capital cost by. Independent variables in
|
51
|
+
the equation should match the keys in the data input arg. This
|
52
|
+
equation may use numpy functions with the package prefix "np". If
|
53
|
+
``None``, no economies of scale are applied to the capital cost.
|
54
|
+
By default, ``None``.
|
55
|
+
fixed_eqn : str, optional
|
56
|
+
LCOE scaling equation to implement "economies of scale".
|
57
|
+
Equation must be in python string format and return a scalar
|
58
|
+
value to multiply the fixed operating cost by. Independent
|
59
|
+
variables in the equation should match the keys in the data input
|
60
|
+
arg. This equation may use numpy functions with the package prefix
|
61
|
+
"np". If ``None``, no economies of scale are applied to the
|
62
|
+
fixed operating cost. By default, ``None``.
|
63
|
+
var_eqn : str, optional
|
64
|
+
LCOE scaling equation to implement "economies of scale".
|
65
|
+
Equation must be in python string format and return a scalar
|
66
|
+
value to multiply the variable operating cost by. Independent
|
67
|
+
variables in the equation should match the keys in the data input
|
68
|
+
arg. This equation may use numpy functions with the package prefix
|
69
|
+
"np". If ``None``, no economies of scale are applied to the
|
70
|
+
variable operating cost. By default, ``None``.
|
52
71
|
"""
|
53
|
-
self._eqn = eqn
|
54
72
|
self._data = data
|
73
|
+
self._cap_eqn = cap_eqn
|
74
|
+
self._fixed_eqn = fixed_eqn
|
75
|
+
self._var_eqn = var_eqn
|
76
|
+
self._vars = None
|
55
77
|
self._preflight()
|
56
78
|
|
57
79
|
def _preflight(self):
|
58
80
|
"""Run checks to validate EconomiesOfScale equation and input data."""
|
59
81
|
|
60
|
-
|
61
|
-
|
82
|
+
for eq in self._all_equations:
|
83
|
+
if eq is not None:
|
84
|
+
check_eval_str(str(eq))
|
62
85
|
|
63
86
|
if isinstance(self._data, pd.DataFrame):
|
64
87
|
self._data = {
|
@@ -79,11 +102,16 @@ class EconomiesOfScale:
|
|
79
102
|
if any(missing):
|
80
103
|
e = (
|
81
104
|
"Cannot evaluate EconomiesOfScale, missing data for variables"
|
82
|
-
": {} for equation: {}".format(missing, self.
|
105
|
+
": {} for equation: {}".format(missing, self._cap_eqn)
|
83
106
|
)
|
84
107
|
logger.error(e)
|
85
108
|
raise KeyError(e)
|
86
109
|
|
110
|
+
@property
|
111
|
+
def _all_equations(self):
|
112
|
+
"""gen: All EOS equations"""
|
113
|
+
yield from (self._cap_eqn, self._fixed_eqn, self._var_eqn)
|
114
|
+
|
87
115
|
@staticmethod
|
88
116
|
def is_num(s):
|
89
117
|
"""Check if a string is a number"""
|
@@ -111,36 +139,51 @@ class EconomiesOfScale:
|
|
111
139
|
the equation string. This will return an empty list if the equation
|
112
140
|
has no variables.
|
113
141
|
"""
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
142
|
+
if self._vars is not None:
|
143
|
+
return self._vars
|
144
|
+
|
145
|
+
self._vars = []
|
146
|
+
for eq in self._all_equations:
|
147
|
+
if eq is None:
|
148
|
+
continue
|
149
|
+
|
150
|
+
delimiters = (">", "<", ">=", "<=", "==", ",", "*", "/", "+",
|
151
|
+
"-", " ", "(", ")", "[", "]")
|
118
152
|
regex_pattern = "|".join(map(re.escape, delimiters))
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
153
|
+
for sub_str in re.split(regex_pattern, str(eq)):
|
154
|
+
is_valid_var_name = (sub_str and not self.is_num(sub_str)
|
155
|
+
and not self.is_method(sub_str))
|
156
|
+
if is_valid_var_name:
|
157
|
+
self._vars.append(sub_str)
|
124
158
|
|
125
|
-
|
159
|
+
self._vars = sorted(set(self._vars))
|
160
|
+
return self._vars
|
126
161
|
|
127
|
-
def _evaluate(self):
|
162
|
+
def _evaluate(self, eqn):
|
128
163
|
"""Evaluate the EconomiesOfScale equation with Independent variables
|
129
164
|
parsed into a kwargs dictionary input.
|
130
165
|
|
166
|
+
Parameters
|
167
|
+
----------
|
168
|
+
eqn : str
|
169
|
+
LCOE scaling equation to implement "economies of scale".
|
170
|
+
Equation must be in python string format and return a scalar
|
171
|
+
multiplier. Independent variables in the equation should match the
|
172
|
+
keys in the data input arg. This equation may use numpy functions
|
173
|
+
with the package prefix "np". If ``None``, this function returns
|
174
|
+
``1``.
|
175
|
+
|
131
176
|
Returns
|
132
177
|
-------
|
133
178
|
out : float | np.ndarray
|
134
|
-
Evaluated output of the EconomiesOfScale equation.
|
135
|
-
numeric scalars to apply directly to the capital cost.
|
179
|
+
Evaluated output of the EconomiesOfScale equation.
|
136
180
|
"""
|
137
|
-
|
138
|
-
|
139
|
-
kwargs = {k: self._data[k] for k in self.vars}
|
140
|
-
# pylint: disable=eval-used
|
141
|
-
out = eval(str(self._eqn), globals(), kwargs)
|
181
|
+
if eqn is None:
|
182
|
+
return 1
|
142
183
|
|
143
|
-
|
184
|
+
kwargs = {k: self._data[k] for k in self.vars}
|
185
|
+
# pylint: disable=eval-used
|
186
|
+
return eval(str(eqn), globals(), kwargs)
|
144
187
|
|
145
188
|
@staticmethod
|
146
189
|
def _get_prioritized_keys(input_dict, key_list):
|
@@ -180,8 +223,8 @@ class EconomiesOfScale:
|
|
180
223
|
|
181
224
|
@property
|
182
225
|
def capital_cost_scalar(self):
|
183
|
-
"""Evaluated output of the EconomiesOfScale equation.
|
184
|
-
numeric scalars to apply directly to the capital cost.
|
226
|
+
"""Evaluated output of the EconomiesOfScale capital cost equation.
|
227
|
+
Should be numeric scalars to apply directly to the capital cost.
|
185
228
|
|
186
229
|
Returns
|
187
230
|
-------
|
@@ -189,7 +232,35 @@ class EconomiesOfScale:
|
|
189
232
|
Evaluated output of the EconomiesOfScale equation. Should be
|
190
233
|
numeric scalars to apply directly to the capital cost.
|
191
234
|
"""
|
192
|
-
return self._evaluate()
|
235
|
+
return self._evaluate(self._cap_eqn)
|
236
|
+
|
237
|
+
@property
|
238
|
+
def fixed_operating_cost_scalar(self):
|
239
|
+
"""Evaluated output of the EconomiesOfScale fixed operating cost
|
240
|
+
equation. Should be numeric scalars to apply directly to the fixed
|
241
|
+
operating cost.
|
242
|
+
|
243
|
+
Returns
|
244
|
+
-------
|
245
|
+
out : float | np.ndarray
|
246
|
+
Evaluated output of the EconomiesOfScale equation. Should be
|
247
|
+
numeric scalars to apply directly to the fixed operating cost.
|
248
|
+
"""
|
249
|
+
return self._evaluate(self._fixed_eqn)
|
250
|
+
|
251
|
+
@property
|
252
|
+
def variable_operating_cost_scalar(self):
|
253
|
+
"""Evaluated output of the EconomiesOfScale equation variable
|
254
|
+
operating cost. Should be numeric scalars to apply directly to the
|
255
|
+
variable operating cost.
|
256
|
+
|
257
|
+
Returns
|
258
|
+
-------
|
259
|
+
out : float | np.ndarray
|
260
|
+
Evaluated output of the EconomiesOfScale equation. Should be
|
261
|
+
numeric scalars to apply directly to the variable operating cost.
|
262
|
+
"""
|
263
|
+
return self._evaluate(self._var_eqn)
|
193
264
|
|
194
265
|
def _cost_from_cap(self, col_name):
|
195
266
|
"""Get full cost value from cost per mw in data.
|
@@ -221,10 +292,10 @@ class EconomiesOfScale:
|
|
221
292
|
Returns
|
222
293
|
-------
|
223
294
|
out : float | np.ndarray
|
224
|
-
Unscaled (raw) capital_cost found in the data input arg.
|
295
|
+
Unscaled (raw) capital_cost ($) found in the data input arg.
|
225
296
|
"""
|
226
297
|
raw_capital_cost_from_cap = self._cost_from_cap(
|
227
|
-
SupplyCurveField.
|
298
|
+
SupplyCurveField.COST_SITE_CC_USD_PER_AC_MW
|
228
299
|
)
|
229
300
|
if raw_capital_cost_from_cap is not None:
|
230
301
|
return raw_capital_cost_from_cap
|
@@ -240,8 +311,8 @@ class EconomiesOfScale:
|
|
240
311
|
Returns
|
241
312
|
-------
|
242
313
|
out : float | np.ndarray
|
243
|
-
Capital cost found in the data input arg scaled by the
|
244
|
-
EconomiesOfScale equation.
|
314
|
+
Capital cost ($) found in the data input arg scaled by the
|
315
|
+
evaluated EconomiesOfScale equation.
|
245
316
|
"""
|
246
317
|
cc = copy.deepcopy(self.raw_capital_cost)
|
247
318
|
cc *= self.capital_cost_scalar
|
@@ -265,13 +336,13 @@ class EconomiesOfScale:
|
|
265
336
|
return self._get_prioritized_keys(self._data, key_list)
|
266
337
|
|
267
338
|
@property
|
268
|
-
def
|
269
|
-
"""
|
339
|
+
def raw_fixed_operating_cost(self):
|
340
|
+
"""Unscaled (raw) fixed operating cost from input data arg
|
270
341
|
|
271
342
|
Returns
|
272
343
|
-------
|
273
344
|
out : float | np.ndarray
|
274
|
-
|
345
|
+
Unscaled (raw) fixed operating cost ($/year) from input data arg
|
275
346
|
"""
|
276
347
|
foc_from_cap = self._cost_from_cap(
|
277
348
|
SupplyCurveField.COST_SITE_FOC_USD_PER_AC_MW
|
@@ -284,42 +355,70 @@ class EconomiesOfScale:
|
|
284
355
|
return self._get_prioritized_keys(self._data, key_list)
|
285
356
|
|
286
357
|
@property
|
287
|
-
def
|
288
|
-
"""
|
358
|
+
def scaled_fixed_operating_cost(self):
|
359
|
+
"""Fixed operating cost found in the data input arg scaled by the
|
360
|
+
evaluated EconomiesOfScale input equation.
|
289
361
|
|
290
362
|
Returns
|
291
363
|
-------
|
292
364
|
out : float | np.ndarray
|
293
|
-
|
365
|
+
Fixed operating cost ($/year) found in the data input arg scaled
|
366
|
+
by the evaluated EconomiesOfScale equation.
|
294
367
|
"""
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
368
|
+
foc = copy.deepcopy(self.raw_fixed_operating_cost)
|
369
|
+
foc *= self.fixed_operating_cost_scalar
|
370
|
+
return foc
|
371
|
+
|
372
|
+
@property
|
373
|
+
def raw_variable_operating_cost(self):
|
374
|
+
"""Unscaled (raw) variable operating cost from input data arg
|
375
|
+
|
376
|
+
Returns
|
377
|
+
-------
|
378
|
+
out : float | np.ndarray
|
379
|
+
Unscaled (raw) variable operating cost ($/kWh) from input
|
380
|
+
data arg
|
381
|
+
"""
|
382
|
+
voc_mwh = self._data.get(SupplyCurveField.COST_SITE_VOC_USD_PER_AC_MWH)
|
383
|
+
if voc_mwh is not None:
|
384
|
+
return voc_mwh / 1000 # convert to $/kWh
|
300
385
|
|
301
386
|
key_list = ["variable_operating_cost", "mean_variable_operating_cost",
|
302
387
|
"voc", "mean_voc"]
|
303
388
|
return self._get_prioritized_keys(self._data, key_list)
|
304
389
|
|
390
|
+
@property
|
391
|
+
def scaled_variable_operating_cost(self):
|
392
|
+
"""Variable operating cost found in the data input arg scaled by the
|
393
|
+
evaluated EconomiesOfScale input equation.
|
394
|
+
|
395
|
+
Returns
|
396
|
+
-------
|
397
|
+
out : float | np.ndarray
|
398
|
+
Variable operating cost ($/kWh) found in the data input arg
|
399
|
+
scaled by the evaluated EconomiesOfScale equation.
|
400
|
+
"""
|
401
|
+
voc = copy.deepcopy(self.raw_variable_operating_cost)
|
402
|
+
voc *= self.variable_operating_cost_scalar
|
403
|
+
return voc
|
404
|
+
|
305
405
|
@property
|
306
406
|
def aep(self):
|
307
|
-
"""Annual energy production back-calculated from the raw LCOE:
|
407
|
+
"""Annual energy production (kWh) back-calculated from the raw LCOE:
|
308
408
|
|
309
|
-
AEP = (fcr * raw_cap_cost +
|
409
|
+
AEP = (fcr * raw_cap_cost + raw_foc) / (raw_lcoe - raw_voc)
|
310
410
|
|
311
411
|
Returns
|
312
412
|
-------
|
313
413
|
out : float | np.ndarray
|
314
414
|
"""
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
return aep
|
415
|
+
num = self.fcr * self.raw_capital_cost + self.raw_fixed_operating_cost
|
416
|
+
denom = self.raw_lcoe - (self.raw_variable_operating_cost * 1000)
|
417
|
+
return num / denom * 1000 # convert MWh to KWh
|
319
418
|
|
320
419
|
@property
|
321
420
|
def raw_lcoe(self):
|
322
|
-
"""Raw LCOE taken from the input data
|
421
|
+
"""Raw LCOE ($/MWh) taken from the input data
|
323
422
|
|
324
423
|
Returns
|
325
424
|
-------
|
@@ -330,17 +429,17 @@ class EconomiesOfScale:
|
|
330
429
|
|
331
430
|
@property
|
332
431
|
def scaled_lcoe(self):
|
333
|
-
"""LCOE calculated with the scaled
|
432
|
+
"""LCOE ($/MWh) calculated with the scaled costs based on the
|
334
433
|
EconomiesOfScale input equation.
|
335
434
|
|
336
|
-
LCOE = (FCR * scaled_capital_cost +
|
435
|
+
LCOE = (FCR * scaled_capital_cost + scaled_FOC) / AEP + scaled_VOC
|
337
436
|
|
338
437
|
Returns
|
339
438
|
-------
|
340
439
|
lcoe : float | np.ndarray
|
341
|
-
LCOE calculated with the scaled
|
440
|
+
LCOE calculated with the scaled costs based on the
|
342
441
|
EconomiesOfScale input equation.
|
343
442
|
"""
|
344
|
-
return lcoe_fcr(
|
345
|
-
|
346
|
-
|
443
|
+
return lcoe_fcr(self.fcr, self.scaled_capital_cost,
|
444
|
+
self.scaled_fixed_operating_cost, self.aep,
|
445
|
+
self.scaled_variable_operating_cost)
|