Skip to content

Commit 7b7294d

Browse files
Unit test to ensure difference between correlation values and GEOPHIRES-calculated drilling cost per well is due to 5% indirect cost factor
1 parent d14517d commit 7b7294d

File tree

2 files changed

+60
-13
lines changed

2 files changed

+60
-13
lines changed

tests/geophires_x_tests/test_options_list.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import ClassVar
2+
13
from base_test_case import BaseTestCase
24
from geophires_x.OptionList import EndUseOptions
35
from geophires_x.OptionList import PlantType
@@ -33,23 +35,33 @@ def test_equality(self):
3335

3436

3537
class WellDrillingCostCorrelationTestCase(BaseTestCase):
38+
3639
def test_equality(self):
3740
self.assertFalse(WellDrillingCostCorrelation.VERTICAL_SMALL == WellDrillingCostCorrelation.DEVIATED_SMALL)
3841
self.assertTrue(WellDrillingCostCorrelation.VERTICAL_SMALL == WellDrillingCostCorrelation.VERTICAL_SMALL)
3942

40-
def test_baseline_curve_costs(self):
41-
# Sanity-check calibration with NREL 2025 Cost Curve Update
42-
# https://pangea.stanford.edu/ERE/db/GeoConf/papers/SGW/2025/Akindipe.pdf?t=1740084555
43-
44-
self.assertAlmostEqual(5.1, WellDrillingCostCorrelation.VERTICAL_SMALL.calculate_cost_MUSD(3500), delta=0.1)
45-
self.assertAlmostEqual(13.9, WellDrillingCostCorrelation.VERTICAL_SMALL.calculate_cost_MUSD(6500), delta=0.1)
46-
self.assertAlmostEqual(15.9, WellDrillingCostCorrelation.VERTICAL_SMALL.calculate_cost_MUSD(7000), delta=0.1)
47-
48-
self.assertAlmostEqual(17.2, WellDrillingCostCorrelation.VERTICAL_LARGE.calculate_cost_MUSD(6500), delta=0.1)
49-
50-
self.assertAlmostEqual(14.9, WellDrillingCostCorrelation.DEVIATED_SMALL.calculate_cost_MUSD(6500), delta=0.1)
51-
52-
self.assertAlmostEqual(18.3, WellDrillingCostCorrelation.DEVIATED_LARGE.calculate_cost_MUSD(6500), delta=0.1)
43+
COST_CORRELATION_TEST_CASES: ClassVar[list[tuple[WellDrillingCostCorrelation, int, float]]] = [
44+
(WellDrillingCostCorrelation.VERTICAL_SMALL, 3500, 5.1),
45+
(WellDrillingCostCorrelation.VERTICAL_SMALL, 6500, 13.9),
46+
(WellDrillingCostCorrelation.VERTICAL_SMALL, 7000, 15.9),
47+
(WellDrillingCostCorrelation.VERTICAL_LARGE, 6500, 17.2),
48+
(WellDrillingCostCorrelation.DEVIATED_SMALL, 6500, 14.9),
49+
(WellDrillingCostCorrelation.DEVIATED_LARGE, 6500, 18.3),
50+
]
51+
52+
def test_drilling_cost_curve_correlations(self):
53+
"""
54+
Check calibration with NREL 2025 Cost Curve Update.
55+
Values in COST_CORRELATION_TEST_CASES derived from graphs on p. 8 of
56+
https://pangea.stanford.edu/ERE/db/GeoConf/papers/SGW/2025/Akindipe.pdf?t=1740084555
57+
"""
58+
59+
for test_case in WellDrillingCostCorrelationTestCase.COST_CORRELATION_TEST_CASES:
60+
correlation: WellDrillingCostCorrelation = test_case[0]
61+
depth_m = test_case[1]
62+
expected_cost_musd = test_case[2]
63+
with self.subTest(msg=str(f'{correlation.name}, {depth_m}m')):
64+
self.assertAlmostEqual(expected_cost_musd, correlation.calculate_cost_MUSD(depth_m), delta=0.1)
5365

5466

5567
class PlantTypeTestCase(BaseTestCase):

tests/test_geophires_x.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
from typing import Optional
66

77
from geophires_x.OptionList import PlantType
8+
from geophires_x.OptionList import WellDrillingCostCorrelation
89
from geophires_x_client import GeophiresXClient
910
from geophires_x_client import GeophiresXResult
1011
from geophires_x_client import _get_logger
1112
from geophires_x_client.geophires_input_parameters import EndUseOption
1213
from geophires_x_client.geophires_input_parameters import GeophiresInputParameters
14+
from geophires_x_tests.test_options_list import WellDrillingCostCorrelationTestCase
1315
from tests.base_test_case import BaseTestCase
1416

1517

@@ -784,3 +786,36 @@ def test_multiple_construction_years(self):
784786
pre_rev_idx = min(net_rev_idx, net_cashflow_idx)
785787
self.assertListEqual([0] * pre_rev_idx, rcp[1][:pre_rev_idx])
786788
self.assertListEqual([1] + [0] * (pre_rev_idx - 1), rcp[2][:pre_rev_idx])
789+
790+
def test_drilling_cost_curves(self):
791+
"""
792+
Note this is similar to
793+
geophires_x_tests.test_options_list.WellDrillingCostCorrelationTestCase.test_drilling_cost_curve_correlations;
794+
this test ensures that the indirect cost factor is responsible for the discrepancy between GEOPHIRES-calculated
795+
drilling cost per well and the raw value calculated by the curve.
796+
"""
797+
798+
indirect_cost_factor = 1.05 # See TODO re:parameterizing at src/geophires_x/Economics.py:652
799+
800+
for test_case in WellDrillingCostCorrelationTestCase.COST_CORRELATION_TEST_CASES:
801+
correlation: WellDrillingCostCorrelation = test_case[0]
802+
depth_m = test_case[1]
803+
expected_cost_musd = test_case[2]
804+
with self.subTest(msg=str(f'{correlation.name}, {depth_m}m')):
805+
result = GeophiresXClient().get_geophires_result(
806+
GeophiresInputParameters(
807+
from_file_path=self._get_test_file_path('geophires_x_tests/generic-egs-case.txt'),
808+
params={
809+
'Well Drilling Cost Correlation': correlation.int_value,
810+
'Reservoir Depth': f'{depth_m} meter',
811+
'Number of Production Wells': 1,
812+
'Number of Injection Wells': 1,
813+
'Well Drilling and Completion Capital Cost Adjustment Factor': 1,
814+
},
815+
)
816+
)
817+
818+
cost_per_well_val = result.result['CAPITAL COSTS (M$)']['Drilling and completion costs per well'][
819+
'value'
820+
]
821+
self.assertAlmostEqual(indirect_cost_factor * expected_cost_musd, cost_per_well_val, delta=0.1)

0 commit comments

Comments
 (0)