Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4401592
WIP - LCOH calculation in SAM cash flow profile
softwareengineerprogrammer Mar 30, 2026
994b85c
working-ish impl of LCOH insertion into SAM cash flow profile - WIP o…
softwareengineerprogrammer Mar 30, 2026
460f7dc
set CAPEX_heat_electricity_plant_ratio for end use options
softwareengineerprogrammer Mar 31, 2026
d4c76d4
break out EconomicsSamCalculations.py
softwareengineerprogrammer Mar 31, 2026
bae714d
WIP - Present value of annual heat costs ($) line item
softwareengineerprogrammer Mar 31, 2026
329f28a
WIP - Present value of annual heat provided (kWh) line item
softwareengineerprogrammer Mar 31, 2026
8ade446
regen example_SAM-single-owner-PPA-7/8
softwareengineerprogrammer Mar 31, 2026
62a3728
LCOH line items in MMBTU
softwareengineerprogrammer Mar 31, 2026
2195473
populate case report LCOH
softwareengineerprogrammer Mar 31, 2026
9b2e018
increase test_hip_ra_monte_carlo threshold
softwareengineerprogrammer Apr 1, 2026
c9216a5
remove redundant _get_ret_row_index
softwareengineerprogrammer Apr 1, 2026
3fdb895
minor code reorganization/cleanup
softwareengineerprogrammer Apr 1, 2026
91f678b
WIP - add PV of annual energy (electricity costs), pivoting to using …
softwareengineerprogrammer Apr 1, 2026
c812574
calculate LCOE based on PV of annual energy (electricity only) costs
softwareengineerprogrammer Apr 1, 2026
a2d0b74
minor - rounding
softwareengineerprogrammer Apr 1, 2026
136f5b5
regen non-Fervo SAM-EM examples
softwareengineerprogrammer Apr 1, 2026
251324b
code cleanup
softwareengineerprogrammer Apr 1, 2026
acd8e51
WIP - parameterizing backfill_lcoh_nominal for re-use with LCOC
softwareengineerprogrammer Apr 1, 2026
df5531a
insert_non_electricity_levelized_metrics parameterized & genericized …
softwareengineerprogrammer Apr 1, 2026
631adb3
insert_lcoc_metrics
softwareengineerprogrammer Apr 1, 2026
0548958
insert LCOC metrics in cash flow and include in case report
softwareengineerprogrammer Apr 1, 2026
9e1b451
regen Fervo_Project_Cape-{4,5,6}
softwareengineerprogrammer Apr 1, 2026
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 .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# pre-commit install --install-hooks
# To update the versions:
# pre-commit autoupdate
exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg|src/geophires_x(?!/(GEOPHIRESv3|EconomicsSam|EconomicsSamCashFlow|EconomicsUtils|EconomicsSamPreRevenue|SurfacePlantUtils|NumpyUtils|UPPReservoir)\.py))(/|$)'
exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg|src/geophires_x(?!/(GEOPHIRESv3|EconomicsSam|EconomicsSamCashFlow|EconomicsUtils|EconomicsSamPreRevenue|EconomicsSamCalculations|SurfacePlantUtils|NumpyUtils|UPPReservoir)\.py))(/|$)'
# Note the order is intentional to avoid multiple passes of the hooks
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
Expand Down
50 changes: 31 additions & 19 deletions src/geophires_x/Economics.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@

import geophires_x.Model as Model
from geophires_x import EconomicsSam
from geophires_x.EconomicsSam import calculate_sam_economics, SamEconomicsCalculations
from geophires_x.EconomicsSam import calculate_sam_economics
from geophires_x.EconomicsSamCalculations import SamEconomicsCalculations
from geophires_x.EconomicsUtils import BuildPricingModel, wacc_output_parameter, nominal_discount_rate_parameter, \
real_discount_rate_parameter, after_tax_irr_parameter, moic_parameter, project_vir_parameter, \
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, investment_tax_credit_output_parameter, expand_schedule_dsl
_YEAR_INDEX_VALUE_EXPLANATION_SNIPPET, investment_tax_credit_output_parameter, expand_schedule_dsl, \
lcoh_output_parameter, lcoc_output_parameter
from geophires_x.GeoPHIRESUtils import quantity
from geophires_x.OptionList import Configuration, WellDrillingCostCorrelation, EconomicModel, EndUseOptions, PlantType, \
_WellDrillingCostCorrelationCitation
Expand Down Expand Up @@ -488,9 +490,21 @@ def _construction_inflation_cost_elec_heat() -> tuple[float, float]:
# Designated as nominal (as opposed to real) in parameter tooltip text
LCOE = econ.sam_economics_calculations.lcoe_nominal.quantity().to(
convertible_unit(econ.LCOE.CurrentUnits.value)).magnitude
else:
# FIXME WIP calculate LCOH/LCOC as applicable
pass

if model.surfaceplant.enduse_option.value.has_direct_use_heat_component:
if econ.sam_economics_calculations.lcoh_nominal.value is not None:
# Designated as nominal (as opposed to real) in parameter tooltip text
LCOH = econ.sam_economics_calculations.lcoh_nominal.quantity().to(
convertible_unit(econ.LCOH.CurrentUnits.value)).magnitude
else:
# FIXME TODO probably should not happen; relevant to
# https://github.com/NatLabRockies/GEOPHIRES-X/issues/452?title=Deduplicate+calls+to+calculate_pre_revenue_costs_and_cashflow
pass

if econ.sam_economics_calculations.lcoc_nominal.value is not None:
# Designated as nominal (as opposed to real) in parameter tooltip text
LCOC = econ.sam_economics_calculations.lcoc_nominal.quantity().to(
convertible_unit(econ.LCOC.CurrentUnits.value)).magnitude

else:
if econ.econmodel.value != EconomicModel.BICYCLE:
Expand Down Expand Up @@ -1917,13 +1931,7 @@ def __init__(self, model: Model):
CurrentUnits=CostPerMassUnit.DOLLARSPERLB
)

self.LCOC = self.OutputParameterDict[self.LCOC.Name] = OutputParameter(
Name="LCOC",
display_name='Direct-Use Cooling Breakeven Price (LCOC)',
UnitType=Units.ENERGYCOST,
PreferredUnits=EnergyCostUnit.DOLLARSPERMMBTU,
CurrentUnits=EnergyCostUnit.DOLLARSPERMMBTU
)
self.LCOC = self.OutputParameterDict[self.LCOC.Name] = lcoc_output_parameter()

self.LCOE = self.OutputParameterDict[self.LCOE.Name] = OutputParameter(
Name="LCOE",
Expand All @@ -1933,13 +1941,7 @@ def __init__(self, model: Model):
CurrentUnits=EnergyCostUnit.CENTSSPERKWH,
ToolTipText="For SAM economic models, this is the nominal LCOE value (as opposed to real)."
)
self.LCOH = self.OutputParameterDict[self.LCOH.Name] = OutputParameter(
Name="LCOH",
display_name='Direct-Use heat breakeven price (LCOH)',
UnitType=Units.ENERGYCOST,
PreferredUnits=EnergyCostUnit.DOLLARSPERMMBTU, # $/MMBTU
CurrentUnits=EnergyCostUnit.DOLLARSPERMMBTU
)
self.LCOH = self.OutputParameterDict[self.LCOH.Name] = lcoh_output_parameter()

stimulation_contingency_and_indirect_costs_tooltip = (
f'plus {self.contingency_percentage.quantity().to(convertible_unit("%")).magnitude:g}% contingency '
Expand Down Expand Up @@ -2753,6 +2755,16 @@ def _warn(_msg: str) -> None:
convertible_unit(self.accrued_financing_during_construction_percentage.CurrentUnits)
).magnitude

if not self.CAPEX_heat_electricity_plant_ratio.Provided:
def _set_ratio(frac: float) -> None:
self.CAPEX_heat_electricity_plant_ratio.value = quantity(frac, 'dimensionless').to(
convertible_unit(self.CAPEX_heat_electricity_plant_ratio.CurrentUnits)).magnitude

if model.surfaceplant.enduse_option.value == EndUseOptions.ELECTRICITY:
_set_ratio(1.0)
elif model.surfaceplant.enduse_option.value == EndUseOptions.HEAT:
_set_ratio(0.0)

model.logger.info(f'complete {__class__!s}: {sys._getframe().f_code.co_name}')

def sync_interest_rate(self, model):
Expand Down
Loading