Skip to content

Commit af61f34

Browse files
Adjust royalty holder NPV for multiple construction years
1 parent 2616613 commit af61f34

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

src/geophires_x/EconomicsSam.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,11 @@ def sf(_v: float, num_sig_figs: int = 5) -> float:
301301
# Assumes that royalties opex is the only possible O&M production-based expense - this logic will need to be
302302
# updated if more O&M production-based expenses are added to SAM-EM
303303
sam_economics.royalties_opex.value = [
304-
quantity(it, 'USD / year').to(sam_economics.royalties_opex.CurrentUnits).magnitude
305-
for it in _cash_flow_profile_row(cash_flow, 'O&M production-based expense ($)')
304+
*_pre_revenue_years_vector(model),
305+
*[
306+
quantity(it, 'USD / year').to(sam_economics.royalties_opex.CurrentUnits).magnitude
307+
for it in _cash_flow_profile_row(cash_flow, 'O&M production-based expense ($)')
308+
],
306309
]
307310

308311
sam_economics.nominal_discount_rate.value, sam_economics.wacc.value = _calculate_nominal_discount_rate_and_wacc(
@@ -483,8 +486,7 @@ def _get_custom_gen_parameters(model: Model) -> dict[str, Any]:
483486

484487

485488
def _pre_revenue_years_count(model: Model) -> int:
486-
# return model.surfaceplant.construction_years.value
487-
return 0 # FIXME WIP (v3 impl)
489+
return model.surfaceplant.construction_years.value
488490

489491

490492
def _pre_revenue_years_vector(model: Model, v: float = 0.0) -> list[float]:
@@ -504,7 +506,7 @@ def _get_utility_rate_parameters(m: Model) -> dict[str, Any]:
504506
(max_total_kWh_produced - it) / max_total_kWh_produced * 100 for it in m.surfaceplant.NetkWhProduced.value
505507
]
506508

507-
ret['degradation'] = _pre_revenue_years_vector(m, v=100) + degradation_total
509+
ret['degradation'] = degradation_total
508510

509511
return ret
510512

tests/test_geophires_x.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,16 +1319,22 @@ def test_royalty_rate(self):
13191319
zero_royalty_npv = None
13201320
for royalty_rate in [0, 0.1]:
13211321
with self.subTest(msg=f'royalty_rate={royalty_rate}'):
1322-
result = GeophiresXClient().get_geophires_result(
1323-
ImmutableGeophiresInputParameters(
1324-
from_file_path=self._get_test_file_path(
1325-
'geophires_x_tests/generic-egs-case-2_sam-single-owner-ppa.txt'
1326-
),
1327-
params={
1328-
'Royalty Rate': royalty_rate,
1329-
},
1322+
1323+
def _get_result(
1324+
_royalty_rate: float, additional_params: dict[str, Any] | None = None
1325+
) -> GeophiresXResult:
1326+
if additional_params is None:
1327+
additional_params = {}
1328+
return GeophiresXClient().get_geophires_result(
1329+
ImmutableGeophiresInputParameters(
1330+
from_file_path=self._get_test_file_path(
1331+
'geophires_x_tests/generic-egs-case-2_sam-single-owner-ppa.txt'
1332+
),
1333+
params={'Royalty Rate': _royalty_rate, **additional_params},
1334+
)
13301335
)
1331-
)
1336+
1337+
result = _get_result(royalty_rate)
13321338
opex_result = result.result['OPERATING AND MAINTENANCE COSTS (M$/yr)']
13331339

13341340
self.assertIsNotNone(opex_result[royalties_output_name])
@@ -1347,8 +1353,14 @@ def test_royalty_rate(self):
13471353

13481354
self.assertEqual(opex_line_item_sum, total_opex_MUSD)
13491355

1350-
econ_result = result.result['EXTENDED ECONOMICS']
1351-
royalty_holder_npv_MUSD = econ_result['Royalty Holder NPV']['value']
1356+
def _royalty_holder_npv_MUSD(r: GeophiresXResult) -> float:
1357+
econ_result = r.result['EXTENDED ECONOMICS']
1358+
return econ_result['Royalty Holder NPV']['value']
1359+
1360+
# econ_result = result.result['EXTENDED ECONOMICS']
1361+
royalty_holder_npv_MUSD = _royalty_holder_npv_MUSD(
1362+
result
1363+
) # econ_result['Royalty Holder NPV']['value']
13521364

13531365
if royalty_rate > 0.0:
13541366
self.assertEqual(58.88, opex_result[royalties_output_name]['value'])
@@ -1369,7 +1381,14 @@ def test_royalty_rate(self):
13691381
)
13701382

13711383
if royalty_rate == 0.1:
1372-
self.assertAlmostEqual(708.07, royalty_holder_npv_MUSD, places=2)
1384+
base_expected_royalty_holder_npv_MUSD = 708.07
1385+
self.assertAlmostEqual(base_expected_royalty_holder_npv_MUSD, royalty_holder_npv_MUSD, places=2)
1386+
1387+
result_multiple_construction_years = _get_result(
1388+
royalty_rate, additional_params={'Construction Years': 5}
1389+
)
1390+
mcy_royalty_npv = _royalty_holder_npv_MUSD(result_multiple_construction_years)
1391+
self.assertLess(mcy_royalty_npv, base_expected_royalty_holder_npv_MUSD)
13731392

13741393
if royalty_rate == 0.0:
13751394
self.assertEqual(0, opex_result[royalties_output_name]['value'])

0 commit comments

Comments
 (0)