@@ -1309,6 +1309,7 @@ def test_redrilling_costs(self):
1309
1309
def test_royalty_rate (self ):
1310
1310
royalties_output_name = 'Average Annual Royalty Cost'
1311
1311
1312
+ zero_royalty_npv = None
1312
1313
for royalty_rate in [0 , 0.1 ]:
1313
1314
result = GeophiresXClient ().get_geophires_result (
1314
1315
ImmutableGeophiresInputParameters (
@@ -1345,6 +1346,9 @@ def test_royalty_rate(self):
1345
1346
self .assertEqual (58.88 , opex_result [royalties_output_name ]['value' ])
1346
1347
self .assertGreater (royalty_holder_npv_MUSD , 0 )
1347
1348
1349
+ # Owner NPV is lower when royalty rate is non-zero
1350
+ self .assertGreater (zero_royalty_npv , result .result ['ECONOMIC PARAMETERS' ]['Project NPV' ]['value' ])
1351
+
1348
1352
royalties_cash_flow_MUSD = [
1349
1353
it * 1e-6
1350
1354
for it in _cash_flow_profile_row (
@@ -1362,3 +1366,65 @@ def test_royalty_rate(self):
1362
1366
if royalty_rate == 0.0 :
1363
1367
self .assertEqual (0 , opex_result [royalties_output_name ]['value' ])
1364
1368
self .assertEqual (0 , royalty_holder_npv_MUSD )
1369
+ zero_royalty_npv = result .result ['ECONOMIC PARAMETERS' ]['Project NPV' ]['value' ]
1370
+
1371
+ def test_royalty_rate_escalation (self ):
1372
+ royalties_output_name = 'Average Annual Royalty Cost'
1373
+
1374
+ base_royalty_rate = 0.05
1375
+ escalation_rate = 0.01
1376
+
1377
+ for max_rate in [0.08 , 1.0 ]:
1378
+ result = GeophiresXClient ().get_geophires_result (
1379
+ ImmutableGeophiresInputParameters (
1380
+ from_file_path = self ._get_test_file_path (
1381
+ 'geophires_x_tests/generic-egs-case-2_sam-single-owner-ppa.txt'
1382
+ ),
1383
+ params = {
1384
+ 'Royalty Rate' : base_royalty_rate ,
1385
+ 'Royalty Rate Escalation' : escalation_rate ,
1386
+ 'Royalty Rate Maximum' : max_rate ,
1387
+ },
1388
+ )
1389
+ )
1390
+ opex_result = result .result ['OPERATING AND MAINTENANCE COSTS (M$/yr)' ]
1391
+
1392
+ self .assertIsNotNone (opex_result [royalties_output_name ])
1393
+ self .assertEqual ('MUSD/yr' , opex_result [royalties_output_name ]['unit' ])
1394
+
1395
+ total_opex_MUSD = opex_result ['Total operating and maintenance costs' ]['value' ]
1396
+
1397
+ opex_line_item_sum = 0
1398
+ for line_item_names in [
1399
+ 'Wellfield maintenance costs' ,
1400
+ 'Power plant maintenance costs' ,
1401
+ 'Water costs' ,
1402
+ royalties_output_name ,
1403
+ ]:
1404
+ opex_line_item_sum += opex_result [line_item_names ]['value' ]
1405
+
1406
+ self .assertAlmostEqual (opex_line_item_sum , total_opex_MUSD , places = 4 )
1407
+
1408
+ project_lifetime_yrs = result .result ['ECONOMIC PARAMETERS' ]['Project lifetime' ]['value' ]
1409
+
1410
+ royalties_cash_flow_MUSD = [
1411
+ it * 1e-6
1412
+ for it in _cash_flow_profile_row (
1413
+ result .result ['SAM CASH FLOW PROFILE' ], 'O&M production-based expense ($)'
1414
+ )
1415
+ ][1 :]
1416
+
1417
+ ppa_revenue_MUSD = [
1418
+ it * 1e-6 for it in _cash_flow_profile_row (result .result ['SAM CASH FLOW PROFILE' ], 'PPA revenue ($)' )
1419
+ ][1 :]
1420
+
1421
+ actual_royalty_rate = [None ] * len (ppa_revenue_MUSD )
1422
+ for i in range (len (ppa_revenue_MUSD )):
1423
+ actual_royalty_rate [i ] = royalties_cash_flow_MUSD [i ] / ppa_revenue_MUSD [i ]
1424
+
1425
+ max_expected_rate = (
1426
+ max_rate if max_rate < 1.0 else base_royalty_rate + escalation_rate * (project_lifetime_yrs - 1 )
1427
+ )
1428
+
1429
+ expected_last_year_revenue = ppa_revenue_MUSD [- 1 ] * max_expected_rate
1430
+ self .assertAlmostEqual (expected_last_year_revenue , royalties_cash_flow_MUSD [- 1 ], places = 3 )
0 commit comments