Skip to content

Commit 8f78111

Browse files
align inflation costs during construction with pre-existing convention as being incurred in Year 0 (WIP to likewise adjust accrued financing during construction)
1 parent 4c625e3 commit 8f78111

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

src/geophires_x/Economics.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,15 +1162,16 @@ def __init__(self, model: Model):
11621162
'The number of entries must equal Construction Years. e.g., for 3 years: 0.1,0.4,0.5'
11631163
)
11641164

1165+
pre_revenue_bond_interest_rate_unit = PercentUnit.PERCENT
11651166
self.pre_revenue_bond_interest_rate = self.ParameterDict[
11661167
self.pre_revenue_bond_interest_rate.Name] = floatParameter(
11671168
"Pre-Revenue Bond Interest Rate",
1168-
DefaultValue=self.BIR.DefaultValue,
1169+
DefaultValue=self.BIR.quantity().to(convertible_unit(pre_revenue_bond_interest_rate_unit)).magnitude,
11691170
Min=0.0,
11701171
Max=100.0,
11711172
UnitType=Units.PERCENT,
11721173
PreferredUnits=PercentUnit.PERCENT,
1173-
CurrentUnits=PercentUnit.PERCENT,
1174+
CurrentUnits=pre_revenue_bond_interest_rate_unit,
11741175
ToolTipText='Annual interest rate for the pre-revenue bond (such as for construction loan), '
11751176
'used to calculate capitalized interest for phased CAPEX.'
11761177
)

src/geophires_x/EconomicsSam.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,9 @@ class SamEconomicsCalculations:
8181

8282
@dataclass
8383
class PhasedPreRevenueCosts:
84-
"""Helper dataclass to return pre-processor results."""
85-
8684
total_installed_cost_usd: float
8785
construction_financing_cost_usd: float
86+
inflation_cost_usd: float = 0.0
8887

8988

9089
def validate_read_parameters(model: Model):
@@ -373,22 +372,31 @@ def _calculate_phased_capex_costs(
373372
pre_revenue_years_count: int,
374373
phased_capex_schedule: list[float],
375374
pre_revenue_bond_interest_rate: float,
375+
inflation_rate: float,
376376
debt_fraction: float,
377377
logger: logging.Logger,
378378
) -> PhasedPreRevenueCosts:
379379
"""
380380
Calculates the true capitalized cost and interest during pre-revenue years (exploration/permitting/appraisal,
381-
construction) by simulating a year-by-year phased expenditure.
381+
construction) by simulating a year-by-year phased expenditure with inflation.
382382
"""
383383

384384
logger.info(f"Using Phased CAPEX Schedule: {phased_capex_schedule}")
385385

386386
current_debt_balance_usd = 0.0
387387
total_capitalized_cost_usd = 0.0
388388
total_interest_accrued_usd = 0.0
389+
total_inflation_cost_usd = 0.0
389390

390391
for year_index in range(pre_revenue_years_count):
391-
capex_this_year_usd = total_overnight_capex_usd * phased_capex_schedule[year_index]
392+
# Calculate base (overnight) CAPEX for this year
393+
base_capex_this_year_usd = total_overnight_capex_usd * phased_capex_schedule[year_index]
394+
395+
inflation_factor = (1.0 + inflation_rate) ** (year_index + 1)
396+
inflation_cost_this_year_usd = base_capex_this_year_usd * (inflation_factor - 1.0)
397+
398+
# Total CAPEX spent this year (including inflation)
399+
capex_this_year_usd = base_capex_this_year_usd + inflation_cost_this_year_usd
392400

393401
# Interest is calculated on the opening balance (from previous years' draws)
394402
interest_this_year_usd = current_debt_balance_usd * pre_revenue_bond_interest_rate
@@ -398,6 +406,7 @@ def _calculate_phased_capex_costs(
398406
# Add this year's direct cost AND capitalized interest to the total project cost basis
399407
total_capitalized_cost_usd += capex_this_year_usd + interest_this_year_usd
400408
total_interest_accrued_usd += interest_this_year_usd
409+
total_inflation_cost_usd += inflation_cost_this_year_usd
401410

402411
# Update the loan balance for *next* year's interest calculation
403412
# New balance = Old Balance + New Debt + Capitalized Interest
@@ -406,11 +415,14 @@ def _calculate_phased_capex_costs(
406415
logger.info(
407416
f"Phased capex complete. "
408417
f"Total Installed Cost: ${total_capitalized_cost_usd:,.2f}, "
418+
f"Total Inflation Cost: ${total_inflation_cost_usd:,.2f}, "
409419
f"Total Capitalized Interest: ${total_interest_accrued_usd:,.2f}"
410420
)
411421

412422
return PhasedPreRevenueCosts(
413-
total_installed_cost_usd=total_capitalized_cost_usd, construction_financing_cost_usd=total_interest_accrued_usd
423+
total_installed_cost_usd=total_capitalized_cost_usd,
424+
construction_financing_cost_usd=total_interest_accrued_usd,
425+
inflation_cost_usd=total_inflation_cost_usd,
414426
)
415427

416428

@@ -453,12 +465,18 @@ def _get_single_owner_parameters(model: Model) -> dict[str, Any]:
453465
)
454466
raise RuntimeError(msg)
455467

468+
if econ.inflrateconstruction.Provided:
469+
pre_revenue_inflation_rate = econ.inflrateconstruction.quantity().to('dimensionless').magnitude
470+
else:
471+
pre_revenue_inflation_rate = econ.RINFL.quantity().to('dimensionless').magnitude
472+
456473
# Call the phased capex calculation function
457474
phased_costs = _calculate_phased_capex_costs(
458475
total_overnight_capex_usd=total_overnight_capex_usd,
459476
pre_revenue_years_count=pre_revenue_years,
460477
phased_capex_schedule=schedule_pct,
461478
pre_revenue_bond_interest_rate=econ.pre_revenue_bond_interest_rate.quantity().to('dimensionless').magnitude,
479+
inflation_rate=pre_revenue_inflation_rate,
462480
debt_fraction=econ.FIB.quantity().to('dimensionless').magnitude,
463481
logger=model.logger,
464482
)
@@ -474,7 +492,7 @@ def _get_single_owner_parameters(model: Model) -> dict[str, Any]:
474492

475493
# TODO/WIP align/adjust for all pre-revenue years (e.g. permitting/exploration, not just construction)
476494
econ.inflation_cost_during_construction.value = (
477-
quantity(construction_financing_cost_usd, 'USD')
495+
quantity(phased_costs.inflation_cost_usd, 'USD')
478496
.to(econ.inflation_cost_during_construction.CurrentUnits)
479497
.magnitude
480498
)

0 commit comments

Comments
 (0)