Skip to content

Commit 5248e32

Browse files
SAM-EM Project VIR NREL#390
1 parent f644fea commit 5248e32

File tree

8 files changed

+50
-32
lines changed

8 files changed

+50
-32
lines changed

docs/SAM-Economic-Models.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ The following table describes how GEOPHIRES parameters are transformed into SAM
5050
1. Only Electricity end-use is supported
5151
2. Only 1 construction year is supported
5252
3. The following economic outputs are not calculated:
53-
1. Project VIR=PI=PIR
54-
2. Project MOIC
55-
3. Project Payback Period
53+
1. Project Payback Period
5654

5755
## Using SAM Economic Models with Existing GEOPHIRES Inputs
5856

src/geophires_x/Economics.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from geophires_x import EconomicsSam
77
from geophires_x.EconomicsSam import calculate_sam_economics, SamEconomicsCalculations
88
from geophires_x.EconomicsUtils import BuildPricingModel, wacc_output_parameter, nominal_discount_rate_parameter, \
9-
real_discount_rate_parameter, after_tax_irr_parameter, moic_parameter
9+
real_discount_rate_parameter, after_tax_irr_parameter, moic_parameter, project_vir_parameter
1010
from geophires_x.OptionList import Configuration, WellDrillingCostCorrelation, EconomicModel, EndUseOptions, PlantType, \
1111
_WellDrillingCostCorrelationCitation
1212
from geophires_x.Parameter import intParameter, floatParameter, OutputParameter, ReadParameter, boolParameter, \
@@ -1839,13 +1839,7 @@ def __init__(self, model: Model):
18391839
CurrentUnits=PercentUnit.PERCENT,
18401840
PreferredUnits=PercentUnit.PERCENT,
18411841
)
1842-
self.ProjectVIR = self.OutputParameterDict[self.ProjectVIR.Name] = OutputParameter(
1843-
"Project Value Investment Ratio",
1844-
display_name='Project VIR=PI=PIR',
1845-
UnitType=Units.PERCENT,
1846-
PreferredUnits=PercentUnit.TENTH,
1847-
CurrentUnits=PercentUnit.TENTH
1848-
)
1842+
self.ProjectVIR = self.OutputParameterDict[self.ProjectVIR.Name] = project_vir_parameter()
18491843
self.ProjectMOIC = self.OutputParameterDict[self.ProjectMOIC.Name] = moic_parameter()
18501844
self.ProjectPaybackPeriod = self.OutputParameterDict[self.ProjectPaybackPeriod.Name] = OutputParameter(
18511845
"Project Payback Period",
@@ -2799,9 +2793,7 @@ def Calculate(self, model: Model) -> None:
27992793
convertible_unit(self.ProjectIRR.CurrentUnits)).magnitude
28002794

28012795
self.ProjectMOIC.value = self.sam_economics_calculations.moic.value
2802-
2803-
# TODO SAM economic models VIR https://github.com/NREL/GEOPHIRES-X/issues/390
2804-
# self.ProjectVIR.value = non_calculated_output_placeholder_val
2796+
self.ProjectVIR.value = self.sam_economics_calculations.project_vir.value
28052797

28062798
# Calculate the project payback period
28072799
if self.econmodel.value == EconomicModel.SAM_SINGLE_OWNER_PPA:

src/geophires_x/EconomicsSam.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
nominal_discount_rate_parameter,
3636
after_tax_irr_parameter,
3737
moic_parameter,
38+
project_vir_parameter,
3839
)
3940
from geophires_x.GeoPHIRESUtils import is_float, is_int
4041
from geophires_x.OptionList import EconomicModel, EndUseOptions
@@ -68,12 +69,10 @@ class SamEconomicsCalculations:
6869
)
6970

7071
after_tax_irr: OutputParameter = field(default_factory=after_tax_irr_parameter)
71-
7272
nominal_discount_rate: OutputParameter = field(default_factory=nominal_discount_rate_parameter)
73-
7473
wacc: OutputParameter = field(default_factory=wacc_output_parameter)
75-
7674
moic: OutputParameter = field(default_factory=moic_parameter)
75+
project_vir: OutputParameter = field(default_factory=project_vir_parameter)
7776

7877

7978
def validate_read_parameters(model: Model):
@@ -173,8 +172,8 @@ def sf(_v: float, num_sig_figs: int = 5) -> float:
173172
sam_economics.nominal_discount_rate.value, sam_economics.wacc.value = _calculate_nominal_discount_rate_and_wacc(
174173
model, single_owner
175174
)
176-
177175
sam_economics.moic.value = _calculate_moic(cash_flow, model)
176+
sam_economics.project_vir.value = _calculate_project_vir(cash_flow, model)
178177

179178
return sam_economics
180179

@@ -229,6 +228,25 @@ def _calculate_moic(cash_flow: list[list[Any]], model) -> float | None:
229228
return None
230229

231230

231+
def _calculate_project_vir(cash_flow: list[list[Any]], model) -> float | None:
232+
"""
233+
VIR = PV(Future Cash Flows) / |CF_0|
234+
Where CF_0 is the cash flow at Year 0 (the initial investment).
235+
NPV = CF_0 + PV(Future Cash Flows)
236+
PV(Future Cash Flows) = NPV - CF_0
237+
"""
238+
try:
239+
npv_USD = Decimal(_cash_flow_profile_row(cash_flow, 'After-tax cumulative NPV ($)')[-1])
240+
cf_0_USD = Decimal(_cash_flow_profile_row(cash_flow, 'Total after-tax returns ($)')[0])
241+
pv_of_future_cash_flows_USD = npv_USD - cf_0_USD
242+
vir = pv_of_future_cash_flows_USD / abs(cf_0_USD)
243+
244+
return float(vir)
245+
except Exception as e:
246+
model.logger.error(f'Encountered exception calculating Project VIR: {e}')
247+
return None
248+
249+
232250
def get_sam_cash_flow_profile_tabulated_output(model: Model, **tabulate_kw_args) -> str:
233251
"""
234252
Note model must have already calculated economics for this to work (used in Outputs)

src/geophires_x/EconomicsUtils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ def moic_parameter() -> OutputParameter:
4949
)
5050

5151

52+
def project_vir_parameter() -> OutputParameter:
53+
return OutputParameter(
54+
"Project Value Investment Ratio",
55+
display_name='Project VIR=PI=PIR',
56+
UnitType=Units.PERCENT,
57+
PreferredUnits=PercentUnit.TENTH,
58+
CurrentUnits=PercentUnit.TENTH
59+
)
60+
61+
5262
def after_tax_irr_parameter() -> OutputParameter:
5363
return OutputParameter(
5464
Name='After-tax IRR',

src/geophires_x/Outputs.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,7 @@ def PrintOutputs(self, model: Model):
285285
if not math.isnan(irr_output_param.value) else 'NaN'
286286
f.write(f' {irr_field_label}{irr_display_value} {irr_output_param.CurrentUnits.value}\n')
287287

288-
if econ.econmodel.value != EconomicModel.SAM_SINGLE_OWNER_PPA:
289-
# TODO SAM economic models VIR https://github.com/NREL/GEOPHIRES-X/issues/390
290-
f.write(f' {econ.ProjectVIR.display_name}: {econ.ProjectVIR.value:10.2f}\n')
291-
288+
f.write(f' {econ.ProjectVIR.display_name}: {econ.ProjectVIR.value:10.2f}\n')
292289
f.write(f' {econ.ProjectMOIC.display_name}: {econ.ProjectMOIC.value:10.2f}\n')
293290

294291
if econ.econmodel.value != EconomicModel.SAM_SINGLE_OWNER_PPA:

tests/examples/Fervo_Project_Cape-4.out

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Simulation Metadata
66
----------------------
77
GEOPHIRES Version: 3.9.15
88
Simulation Date: 2025-06-04
9-
Simulation Time: 08:45
10-
Calculation Time: 1.041 sec
9+
Simulation Time: 11:49
10+
Calculation Time: 1.057 sec
1111

1212
***SUMMARY OF RESULTS***
1313

@@ -33,6 +33,7 @@ Simulation Metadata
3333
Capacity factor: 90.0 %
3434
Project NPV: 428.92 MUSD
3535
After-tax IRR: 25.85 %
36+
Project VIR=PI=PIR: 1.39
3637
Project MOIC: 2.98
3738
Estimated Jobs Created: 1299
3839

tests/examples/example_SAM-single-owner-PPA-2.out

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
Simulation Metadata
66
----------------------
7-
GEOPHIRES Version: 3.9.14
8-
Simulation Date: 2025-06-03
9-
Simulation Time: 08:48
10-
Calculation Time: 0.875 sec
7+
GEOPHIRES Version: 3.9.15
8+
Simulation Date: 2025-06-04
9+
Simulation Time: 11:49
10+
Calculation Time: 0.878 sec
1111

1212
***SUMMARY OF RESULTS***
1313

@@ -33,6 +33,7 @@ Simulation Metadata
3333
Capacity factor: 90.0 %
3434
Project NPV: 2877.00 MUSD
3535
After-tax IRR: 59.73 %
36+
Project VIR=PI=PIR: 4.58
3637
Project MOIC: 12.36
3738
Estimated Jobs Created: 976
3839

tests/examples/example_SAM-single-owner-PPA.out

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
Simulation Metadata
66
----------------------
7-
GEOPHIRES Version: 3.9.14
8-
Simulation Date: 2025-06-03
9-
Simulation Time: 08:48
10-
Calculation Time: 1.039 sec
7+
GEOPHIRES Version: 3.9.15
8+
Simulation Date: 2025-06-04
9+
Simulation Time: 11:49
10+
Calculation Time: 1.042 sec
1111

1212
***SUMMARY OF RESULTS***
1313

@@ -33,6 +33,7 @@ Simulation Metadata
3333
Capacity factor: 90.0 %
3434
Project NPV: 124.91 MUSD
3535
After-tax IRR: 22.33 %
36+
Project VIR=PI=PIR: 1.79
3637
Project MOIC: 4.15
3738
Estimated Jobs Created: 125
3839

0 commit comments

Comments
 (0)