Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.11.1
current_version = 3.11.2
commit = True
tag = True

Expand Down
2 changes: 1 addition & 1 deletion .cookiecutterrc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ default_context:
sphinx_doctest: "no"
sphinx_theme: "sphinx-py3doc-enhanced-theme"
test_matrix_separate_coverage: "no"
version: 3.11.1
version: 3.11.2
version_manager: "bump2version"
website: "https://github.com/NREL"
year_from: "2023"
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ GEOPHIRES v3 (2023-2025)
3.11
^^^^

3.11.2: `SAM Economic Models ITC result output <https://github.com/softwareengineerprogrammer/GEOPHIRES/pull/124>`__ | `release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.11.2>`__

3.11: `SAM Economic Models Project Payback Period fix <https://github.com/softwareengineerprogrammer/GEOPHIRES/pull/123>`__ | `release <https://github.com/NREL/GEOPHIRES-X/releases/tag/v3.11.1>`__


Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Free software: `MIT license <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.11.1.svg
.. |commits-since| image:: https://img.shields.io/github/commits-since/softwareengineerprogrammer/GEOPHIRES-X/v3.11.2.svg
:alt: Commits since latest release
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.11.1...main
:target: https://github.com/softwareengineerprogrammer/GEOPHIRES-X/compare/v3.11.2...main

.. |docs| image:: https://readthedocs.org/projects/GEOPHIRES-X/badge/?style=flat
:target: https://nrel.github.io/GEOPHIRES-X
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
year = '2025'
author = 'NREL'
copyright = f'{year}, {author}'
version = release = '3.11.1'
version = release = '3.11.2'

pygments_style = 'trac'
templates_path = ['./templates']
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def read(*names, **kwargs):

setup(
name='geophires-x',
version='3.11.1',
version='3.11.2',
license='MIT',
description='GEOPHIRES is a free and open-source geothermal techno-economic simulator.',
long_description='{}\n{}'.format(
Expand Down
13 changes: 5 additions & 8 deletions src/geophires_x/Economics.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
project_payback_period_parameter, inflation_cost_during_construction_output_parameter, \
interest_during_construction_output_parameter, total_capex_parameter_output_parameter, \
overnight_capital_cost_output_parameter, CONSTRUCTION_CAPEX_SCHEDULE_PARAMETER_NAME, \
_YEAR_INDEX_VALUE_EXPLANATION_SNIPPET
_YEAR_INDEX_VALUE_EXPLANATION_SNIPPET, investment_tax_credit_output_parameter
from geophires_x.GeoPHIRESUtils import quantity
from geophires_x.OptionList import Configuration, WellDrillingCostCorrelation, EconomicModel, EndUseOptions, PlantType, \
_WellDrillingCostCorrelationCitation
Expand Down Expand Up @@ -2302,13 +2302,7 @@ def __init__(self, model: Model):
self.ProjectMOIC = self.OutputParameterDict[self.ProjectMOIC.Name] = moic_parameter()
self.ProjectPaybackPeriod = self.OutputParameterDict[self.ProjectPaybackPeriod.Name] = (
project_payback_period_parameter())
self.RITCValue = self.OutputParameterDict[self.RITCValue.Name] = OutputParameter(
Name="Investment Tax Credit Value",
display_name='Investment Tax Credit',
UnitType=Units.CURRENCY,
PreferredUnits=CurrencyUnit.MDOLLARS,
CurrentUnits=CurrencyUnit.MDOLLARS
)
self.RITCValue = self.OutputParameterDict[self.RITCValue.Name] = investment_tax_credit_output_parameter()
self.cost_one_production_well = self.OutputParameterDict[self.cost_one_production_well.Name] = OutputParameter(
Name="Cost of One Production Well",
UnitType=Units.CURRENCY,
Expand Down Expand Up @@ -3587,6 +3581,9 @@ def _calculate_sam_economics(self, model: Model) -> None:

self.ProjectPaybackPeriod.value = self.sam_economics_calculations.project_payback_period.value

self.RITCValue.value = self.sam_economics_calculations.investment_tax_credit.quantity().to(
self.RITCValue.CurrentUnits).magnitude

# noinspection SpellCheckingInspection
def _calculate_derived_outputs(self, model: Model) -> None:
"""
Expand Down
22 changes: 22 additions & 0 deletions src/geophires_x/EconomicsSam.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

# noinspection PyPackageRequirements
import PySAM.Utilityrate5 as UtilityRate
from pint.facets.plain import PlainQuantity
from tabulate import tabulate

from geophires_x import Model as Model
Expand All @@ -43,6 +44,7 @@
royalty_cost_output_parameter,
overnight_capital_cost_output_parameter,
_SAM_EM_MOIC_RETURNS_TAX_QUALIFIER,
investment_tax_credit_output_parameter,
)
from geophires_x.EconomicsSamPreRevenue import (
_AFTER_TAX_NET_CASH_FLOW_ROW_NAME,
Expand Down Expand Up @@ -97,6 +99,8 @@ class SamEconomicsCalculations:

project_payback_period: OutputParameter = field(default_factory=project_payback_period_parameter)

investment_tax_credit: OutputParameter = field(default_factory=investment_tax_credit_output_parameter)

@property
def _pre_revenue_years_count(self) -> int:
return len(
Expand Down Expand Up @@ -367,6 +371,11 @@ def sf(_v: float, num_sig_figs: int = 5) -> float:
sam_economics.project_payback_period.value = _calculate_project_payback_period(
sam_economics.sam_cash_flow_profile, model
)
sam_economics.investment_tax_credit.value = (
_calculate_investment_tax_credit_value(sam_economics.sam_cash_flow_profile)
.to(sam_economics.investment_tax_credit.CurrentUnits.value)
.magnitude
)

return sam_economics

Expand Down Expand Up @@ -567,6 +576,19 @@ def _calculate_project_payback_period(cash_flow: list[list[Any]], model) -> floa
return None


def _calculate_investment_tax_credit_value(sam_cash_flow_profile) -> PlainQuantity:
total_itc_sum_q: PlainQuantity = quantity(0, 'USD')

for itc_line_item in ['Federal ITC total income ($)', 'State ITC total income ($)']:
itc_numeric_entries = [
float(it) for it in _cash_flow_profile_row(sam_cash_flow_profile, itc_line_item) if is_float(it)
]
itc_sum_q = quantity(sum(itc_numeric_entries), 'USD')
total_itc_sum_q += itc_sum_q

return total_itc_sum_q


def get_sam_cash_flow_profile_tabulated_output(model: Model, **tabulate_kw_args) -> str:
"""
Note model must have already calculated economics for this to work (used in Outputs)
Expand Down
13 changes: 13 additions & 0 deletions src/geophires_x/EconomicsUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,16 @@ def royalty_cost_output_parameter() -> OutputParameter:
ToolTipText='The annual costs paid to a royalty holder, calculated as a percentage of the '
'project\'s gross annual revenue. This is modeled as a variable operating expense.',
)


def investment_tax_credit_output_parameter() -> OutputParameter:
return OutputParameter(
Name="Investment Tax Credit Value",
display_name='Investment Tax Credit',
UnitType=Units.CURRENCY,
PreferredUnits=CurrencyUnit.MDOLLARS,
CurrentUnits=CurrencyUnit.MDOLLARS,
ToolTipText='Represents the total undiscounted ITC sum. '
'For SAM Economic Models, this accounts for the standard Year 1 Federal ITC as well as any '
'applicable State ITCs or multi-year credit schedules.',
)
20 changes: 9 additions & 11 deletions src/geophires_x/Outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ def PrintOutputs(self, model: Model):
label = Outputs._field_label(field.Name, 49)
f.write(f' {label}{field.value:10.2f} {field.CurrentUnits.value}\n')

if econ.RITCValue.value and is_sam_econ_model:
# Non-SAM-EMs (inaccurately) treat ITC as a capital cost and thus are displayed in the capital
# costs category rather than here.
f.write(
f' {econ.RITCValue.display_name}: {abs(econ.RITCValue.value):10.2f} {econ.RITCValue.CurrentUnits.value}\n')

if not is_sam_econ_model: # (parameter is ambiguous to the point of meaninglessness for SAM-EM)
acf: OutputParameter = econ.accrued_financing_during_construction_percentage
acf_label = Outputs._field_label(acf.display_name, 49)
Expand Down Expand Up @@ -495,17 +501,9 @@ def PrintOutputs(self, model: Model):
f.write(f' Drilling and completion costs per redrilled well: {(econ.Cwell.value/(model.wellbores.nprod.value+model.wellbores.ninj.value)):10.2f} {econ.Cwell.CurrentUnits.value}\n')
f.write(f' Stimulation costs (for redrilling): {econ.Cstim.value:10.2f} {econ.Cstim.CurrentUnits.value}\n')

if model.economics.RITCValue.value:
if not is_sam_econ_model:
f.write(f' {model.economics.RITCValue.display_name}: {-1*model.economics.RITCValue.value:10.2f} {model.economics.RITCValue.CurrentUnits.value}\n')
else:
# TODO Extract value from SAM Cash Flow Profile per
# https://github.com/NREL/GEOPHIRES-X/issues/404.
# For now we skip displaying the value because it can be/probably is usually mathematically
# inaccurate, and even if it's not, it's redundant with the cash flow profile and also
# misleading/confusing/wrong to display it as a capital cost since it is not a capital
# expenditure.
pass
if model.economics.RITCValue.value and not is_sam_econ_model:
# Note ITC is in ECONOMIC PARAMETERS category for SAM-EM (not capital costs)
f.write(f' {econ.RITCValue.display_name}: {-1 * econ.RITCValue.value:10.2f} {econ.RITCValue.CurrentUnits.value}\n')

display_occ_and_inflation_during_construction_in_capital_costs = is_sam_econ_model
if display_occ_and_inflation_during_construction_in_capital_costs:
Expand Down
2 changes: 1 addition & 1 deletion src/geophires_x/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '3.11.1'
__version__ = '3.11.2'
2 changes: 1 addition & 1 deletion src/geophires_x_schema_generator/geophires-result.json
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@
},
"Investment Tax Credit": {
"type": "number",
"description": "Investment Tax Credit Value",
"description": "Investment Tax Credit Value. Represents the total undiscounted ITC sum. For SAM Economic Models, this accounts for the standard Year 1 Federal ITC as well as any applicable State ITCs or multi-year credit schedules.",
"units": "MUSD"
},
"Overnight Capital Cost": {
Expand Down
7 changes: 4 additions & 3 deletions tests/examples/Fervo_Project_Cape-5.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

Simulation Metadata
----------------------
GEOPHIRES Version: 3.11.0
GEOPHIRES Version: 3.11.1
Simulation Date: 2026-01-16
Simulation Time: 11:42
Calculation Time: 1.791 sec
Simulation Time: 12:50
Calculation Time: 1.783 sec

***SUMMARY OF RESULTS***

Expand All @@ -32,6 +32,7 @@ Simulation Metadata
Real Discount Rate: 12.00 %
Nominal Discount Rate: 15.02 %
WACC: 8.31 %
Investment Tax Credit: 857.78 MUSD
Project lifetime: 30 yr
Capacity factor: 90.0 %
Project NPV: 268.60 MUSD
Expand Down