diff --git a/.bumpversion.cfg b/.bumpversion.cfg index d5e133ca4..c5be3fea6 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.8.10 +current_version = 3.8.13 commit = True tag = True diff --git a/.cookiecutterrc b/.cookiecutterrc index 4cd393a06..10a102210 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -54,7 +54,7 @@ default_context: sphinx_doctest: "no" sphinx_theme: "sphinx-py3doc-enhanced-theme" test_matrix_separate_coverage: "no" - version: 3.8.10 + version: 3.8.13 version_manager: "bump2version" website: "https://github.com/NREL" year_from: "2023" diff --git a/README.rst b/README.rst index a3ffca194..bbd1464e3 100644 --- a/README.rst +++ b/README.rst @@ -56,9 +56,9 @@ Free software: `MIT license `__ :alt: Supported implementations :target: https://pypi.org/project/geophires-x -.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.8.10.svg +.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.8.13.svg :alt: Commits since latest release - :target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.8.10...main + :target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.8.13...main .. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat :target: https://nrel.github.io/GEOPHIRES-X diff --git a/docs/conf.py b/docs/conf.py index 7917956f5..90c0231fe 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,7 @@ year = '2025' author = 'NREL' copyright = f'{year}, {author}' -version = release = '3.8.10' +version = release = '3.8.13' pygments_style = 'trac' templates_path = ['./templates'] diff --git a/setup.py b/setup.py index b1216a702..8566d5a60 100755 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def read(*names, **kwargs): setup( name='geophires-x', - version='3.8.10', + version='3.8.13', license='MIT', description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.', long_description='{}\n{}'.format( diff --git a/src/geophires_x/Economics.py b/src/geophires_x/Economics.py index 8cb6233df..20a5ab6df 100644 --- a/src/geophires_x/Economics.py +++ b/src/geophires_x/Economics.py @@ -479,7 +479,10 @@ def CalculateLCOELCOHLCOC(self, model: Model) -> tuple: NPVcap = np.sum((1 + self.inflrateconstruction.value) * self.CCap.value * CRF * discountvector) NPVfc = np.sum((1 + self.inflrateconstruction.value) * self.CCap.value * self.PTR.value * inflationvector * discountvector) NPVit = np.sum(self.CTR.value / (1 - self.CTR.value) * ((1 + self.inflrateconstruction.value) * self.CCap.value * CRF - self.CCap.value / model.surfaceplant.plant_lifetime.value) * discountvector) - NPVitc = (1 + self.inflrateconstruction.value) * self.CCap.value * self.RITC.value / (1 - self.CTR.value) + + npv_itc_discount_factor = discountvector[model.surfaceplant.construction_years.value] + NPVitc = ((1 + self.inflrateconstruction.value) * self.CCap.value * self.RITC.value / (1 - self.CTR.value) + * npv_itc_discount_factor) if model.surfaceplant.enduse_option.value == EndUseOptions.ELECTRICITY: NPVoandm = np.sum(self.Coam.value * inflationvector * discountvector) @@ -502,7 +505,8 @@ def CalculateLCOELCOHLCOC(self, model: Model) -> tuple: NPVcap_elec = np.sum((1 + self.inflrateconstruction.value) * CCap_elec * CRF * discountvector) NPVfc_elec = np.sum((1 + self.inflrateconstruction.value) * CCap_elec * self.PTR.value * inflationvector * discountvector) NPVit_elec = np.sum(self.CTR.value / (1 - self.CTR.value) * ((1 + self.inflrateconstruction.value) * CCap_elec * CRF - CCap_elec / model.surfaceplant.plant_lifetime.value) * discountvector) - NPVitc_elec = (1 + self.inflrateconstruction.value) * CCap_elec * self.RITC.value / (1 - self.CTR.value) + NPVitc_elec = ((1 + self.inflrateconstruction.value) * CCap_elec * self.RITC.value / (1 - self.CTR.value) + * npv_itc_discount_factor) NPVoandm_elec = np.sum(Coam_elec * inflationvector * discountvector) NPVgrt_elec = self.GTR.value / (1 - self.GTR.value) * (NPVcap_elec + NPVoandm_elec + NPVfc_elec + NPVit_elec - NPVitc_elec) @@ -512,7 +516,8 @@ def CalculateLCOELCOHLCOC(self, model: Model) -> tuple: NPVcap_heat = np.sum((1 + self.inflrateconstruction.value) * CCap_heat * CRF * discountvector) NPVfc_heat = np.sum((1 + self.inflrateconstruction.value) * (self.CCap.value * (1.0 - self.CAPEX_heat_electricity_plant_ratio.value)) * self.PTR.value * inflationvector * discountvector) NPVit_heat = np.sum(self.CTR.value / (1 - self.CTR.value) * ((1 + self.inflrateconstruction.value) * CCap_heat * CRF - CCap_heat / model.surfaceplant.plant_lifetime.value) * discountvector) - NPVitc_heat = (1 + self.inflrateconstruction.value) * CCap_heat * self.RITC.value / (1 - self.CTR.value) + NPVitc_heat = ((1 + self.inflrateconstruction.value) * CCap_heat * self.RITC.value / (1 - self.CTR.value) + * npv_itc_discount_factor) NPVoandm_heat = np.sum((self.Coam.value * (1.0 - self.CAPEX_heat_electricity_plant_ratio.value)) * inflationvector * discountvector) NPVgrt_heat = self.GTR.value / (1 - self.GTR.value) * (NPVcap_heat + NPVoandm_heat + NPVfc_heat + NPVit_heat - NPVitc_heat) @@ -974,7 +979,8 @@ def __init__(self, model: Model): PreferredUnits=PercentUnit.TENTH, CurrentUnits=PercentUnit.TENTH, ErrMessage="assume default investment tax credit rate (0)", - ToolTipText="Investment tax credit rate (see docs)" + ToolTipText="Investment tax credit rate " + "(see https://programs.dsireusa.org/system/program/detail/658)" ) self.PTR = self.ParameterDict[self.PTR.Name] = floatParameter( "Property Tax Rate", @@ -2701,11 +2707,6 @@ def Calculate(self, model: Model) -> None: else: self.CCap.value = self.totalcapcost.value - # update the capital costs, assuming the entire ITC is used to reduce the capital costs - if self.RITC.Provided: - self.RITCValue.value = self.RITC.value * self.CCap.value - self.CCap.value = self.CCap.value - self.RITCValue.value - # Add in the FlatLicenseEtc, OtherIncentives, & TotalGrant self.CCap.value = self.CCap.value + self.FlatLicenseEtc.value - self.OtherIncentives.value - self.TotalGrant.value @@ -2942,6 +2943,12 @@ def Calculate(self, model: Model) -> None: model.surfaceplant.plant_lifetime.value + model.surfaceplant.construction_years.value, 1): self.TotalRevenue.value[i] = self.TotalRevenue.value[i] - self.Coam.value + + if self.RITC.Provided: + self.RITCValue.value = self.RITC.value * self.CCap.value + # ITC is credited year after construction + self.TotalRevenue.value[model.surfaceplant.construction_years.value] += self.RITCValue.value + # Now do a one-time calculation that calculates the cumulative cash flow after everything else has been accounted for for i in range(1, model.surfaceplant.plant_lifetime.value + model.surfaceplant.construction_years.value, 1): self.TotalCummRevenue.value[i] = self.TotalCummRevenue.value[i-1] + self.TotalRevenue.value[i] diff --git a/src/geophires_x/__init__.py b/src/geophires_x/__init__.py index 33c7b81a0..1dd3ab6c5 100644 --- a/src/geophires_x/__init__.py +++ b/src/geophires_x/__init__.py @@ -1 +1 @@ -__version__ = '3.8.10' +__version__ = '3.8.13' diff --git a/src/geophires_x_schema_generator/geophires-request.json b/src/geophires_x_schema_generator/geophires-request.json index 9d91f4e9a..ea61258a6 100644 --- a/src/geophires_x_schema_generator/geophires-request.json +++ b/src/geophires_x_schema_generator/geophires-request.json @@ -1644,7 +1644,7 @@ "maximum": 1.0 }, "Investment Tax Credit Rate": { - "description": "Investment tax credit rate (see docs)", + "description": "Investment tax credit rate (see https://programs.dsireusa.org/system/program/detail/658)", "type": "number", "units": "", "category": "Economics", diff --git a/tests/examples/Fervo_Project_Cape-3.out b/tests/examples/Fervo_Project_Cape-3.out index 2d30aaaf7..b2e9faf4a 100644 --- a/tests/examples/Fervo_Project_Cape-3.out +++ b/tests/examples/Fervo_Project_Cape-3.out @@ -4,16 +4,16 @@ Simulation Metadata ---------------------- - GEOPHIRES Version: 3.7.23 - Simulation Date: 2025-03-10 - Simulation Time: 10:42 - Calculation Time: 0.871 sec + GEOPHIRES Version: 3.8.9 + Simulation Date: 2025-04-02 + Simulation Time: 12:41 + Calculation Time: 0.860 sec ***SUMMARY OF RESULTS*** End-Use Option: Electricity Average Net Electricity Production: 404.31 MW - Electricity breakeven price: 2.77 cents/kWh + Electricity breakeven price: 3.76 cents/kWh Number of production wells: 39 Number of injection wells: 39 Flowrate per production well: 120.0 kg/sec @@ -27,10 +27,10 @@ Simulation Metadata Accrued financing during construction: 5.00 Project lifetime: 20 yr Capacity factor: 90.0 % - Project NPV: 4580.36 MUSD - Project IRR: 43.75 % - Project VIR=PI=PIR: 5.27 - Project MOIC: 6.30 + Project NPV: 4550.28 MUSD + Project IRR: 39.26 % + Project VIR=PI=PIR: 3.97 + Project MOIC: 4.91 Project Payback Period: 3.38 yr Estimated Jobs Created: 976 @@ -102,7 +102,7 @@ Simulation Metadata Total surface equipment costs: 969.26 MUSD Exploration costs: 30.00 MUSD Investment Tax Credit: -459.83 MUSD - Total capital costs: 1072.95 MUSD + Total capital costs: 1532.78 MUSD ***OPERATING AND MAINTENANCE COSTS (M$/yr)*** @@ -193,8 +193,8 @@ Year Electricity | Heat | Since Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | OPEX Net Rev. Net Cashflow Start (cents/kWh)(MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(USD/lb) (MUSD/yr) (MUSD) |(MUSD/yr) (MUSD/yr) (MUSD) ________________________________________________________________________________________________________________________________________________________________________________________ - 0 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -1072.95 -1072.95 - 1 15.00 474.16 474.16 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 26.96 447.20 -625.75 + 0 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -1532.78 -1532.78 + 1 15.00 474.16 474.16 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 26.96 907.04 -625.75 2 15.00 476.35 950.51 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 26.96 449.39 -176.36 3 15.41 489.93 1440.44 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 26.96 462.97 286.61 4 15.81 503.25 1943.69 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 26.96 476.29 762.90 diff --git a/tests/examples/example_ITC.out b/tests/examples/example_ITC.out index 7c2e338e9..65bb8a792 100644 --- a/tests/examples/example_ITC.out +++ b/tests/examples/example_ITC.out @@ -4,16 +4,16 @@ Simulation Metadata ---------------------- - GEOPHIRES Version: 3.8.4 - Simulation Date: 2025-03-19 - Simulation Time: 10:30 - Calculation Time: 0.808 sec + GEOPHIRES Version: 3.8.9 + Simulation Date: 2025-04-02 + Simulation Time: 12:41 + Calculation Time: 0.777 sec ***SUMMARY OF RESULTS*** End-Use Option: Electricity Average Net Electricity Production: 18.84 MW - Electricity breakeven price: 3.21 cents/kWh + Electricity breakeven price: 4.89 cents/kWh Number of production wells: 2 Number of injection wells: 2 Flowrate per production well: 55.0 kg/sec @@ -27,10 +27,10 @@ Simulation Metadata Accrued financing during construction: 0.00 Project lifetime: 30 yr Capacity factor: 90.0 % - Project NPV: 10.31 MUSD - Project IRR: 8.82 % - Project VIR=PI=PIR: 1.19 - Project MOIC: 0.72 + Project NPV: 6.77 MUSD + Project IRR: 8.05 % + Project VIR=PI=PIR: 1.06 + Project MOIC: 0.52 Project Payback Period: 11.46 yr Estimated Jobs Created: 41 @@ -99,7 +99,7 @@ Simulation Metadata Total surface equipment costs: 62.40 MUSD Exploration costs: 8.24 MUSD Investment Tax Credit: -54.20 MUSD - Total capital costs: 54.20 MUSD + Total capital costs: 108.39 MUSD ***OPERATING AND MAINTENANCE COSTS (M$/yr)*** @@ -210,8 +210,8 @@ Year Electricity | Heat | Since Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | Price Ann. Rev. Cumm. Rev. | OPEX Net Rev. Net Cashflow Start (cents/kWh)(MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(cents/kWh) (MUSD/yr) (MUSD) |(USD/lb) (MUSD/yr) (MUSD) |(MUSD/yr) (MUSD/yr) (MUSD) ________________________________________________________________________________________________________________________________________________________________________________________ - 0 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -54.20 -54.20 - 1 5.50 8.02 8.02 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 2.95 5.07 -49.13 + 0 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 0.00 0.00 | 0.00 -108.39 -108.39 + 1 5.50 8.02 8.02 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 2.95 59.26 -49.13 2 5.50 8.09 16.11 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 2.95 5.14 -43.99 3 5.50 8.12 24.23 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 2.95 5.17 -38.82 4 5.50 8.13 32.36 | 2.50 0.00 0.00 | 2.50 0.00 0.00 | 0.00 0.00 0.00 | 2.95 5.18 -33.64 diff --git a/tests/test_geophires_x.py b/tests/test_geophires_x.py index c072c6cc4..bd953469e 100644 --- a/tests/test_geophires_x.py +++ b/tests/test_geophires_x.py @@ -610,8 +610,8 @@ def _get_result(base_example: str, do_discount: bool) -> GeophiresXResult: def _npv(r: GeophiresXResult) -> dict: return r.result['ECONOMIC PARAMETERS']['Project NPV']['value'] - self.assertEqual(4580.36, _npv(_get_result('Fervo_Project_Cape-3', False))) - self.assertEqual(4280.71, _npv(_get_result('Fervo_Project_Cape-3', True))) + self.assertEqual(4550.28, _npv(_get_result('Fervo_Project_Cape-3', False))) + self.assertEqual(4252.6, _npv(_get_result('Fervo_Project_Cape-3', True))) def _extended_economics_npv(r: GeophiresXResult) -> dict: return r.result['EXTENDED ECONOMICS']['Project NPV (including AddOns)']['value']