Skip to content

Commit b782719

Browse files
Address NREL#141
1 parent 7d86cd7 commit b782719

File tree

5 files changed

+188
-31
lines changed

5 files changed

+188
-31
lines changed

src/geophires_x_client/geophires_x_result.py

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from io import StringIO
77
from pathlib import Path
88
from types import MappingProxyType
9+
from typing import ClassVar
910

1011
from .common import _get_logger
1112
from .geophires_input_parameters import EndUseOption
@@ -542,27 +543,29 @@ def _get_heat_electricity_extraction_generation_profile(self):
542543
profile_lines = self._get_profile_lines('HEAT AND/OR ELECTRICITY EXTRACTION AND GENERATION PROFILE')
543544
return self._get_data_from_profile_lines(profile_lines)
544545

546+
_REVENUE_AND_CASHFLOW_PROFILE_HEADERS: ClassVar[list[str]] = [
547+
'Year Since Start',
548+
'Electricity Price (cents/kWh)',
549+
'Electricity Ann. Rev. (MUSD/yr)',
550+
'Electricity Cumm. Rev. (MUSD)',
551+
'Heat Price (cents/kWh)',
552+
'Heat Ann. Rev. (MUSD/yr)',
553+
'Heat Cumm. Rev. (MUSD)',
554+
'Cooling Price (cents/kWh)',
555+
'Cooling Ann. Rev. (MUSD/yr)',
556+
'Cooling Cumm. Rev. (MUSD)',
557+
'Carbon Price (USD/tonne)',
558+
'Carbon Ann. Rev. (MUSD/yr)',
559+
'Carbon Cumm. Rev. (MUSD)',
560+
'Project OPEX (MUSD/yr)',
561+
'Project Net Rev. (MUSD/yr)',
562+
'Project Net Cashflow (MUSD)',
563+
]
564+
545565
def _get_revenue_and_cashflow_profile(self):
546566
def extract_table_header(lines: list) -> list:
547567
# Tried various regexy approaches to extract this programmatically but landed on hard-coding.
548-
return [
549-
'Year Since Start',
550-
'Electricity Price (cents/kWh)',
551-
'Electricity Ann. Rev. (MUSD/yr)',
552-
'Electricity Cumm. Rev. (MUSD)',
553-
'Heat Price (cents/kWh)',
554-
'Heat Ann. Rev. (MUSD/yr)',
555-
'Heat Cumm. Rev. (MUSD)',
556-
'Cooling Price (cents/kWh)',
557-
'Cooling Ann. Rev. (MUSD/yr)',
558-
'Cooling Cumm. Rev. (MUSD)',
559-
'Carbon Price (USD/tonne)',
560-
'Carbon Ann. Rev. (MUSD/yr)',
561-
'Carbon Cumm. Rev. (MUSD)',
562-
'Project OPEX (MUSD/yr)',
563-
'Project Net Rev. (MUSD/yr)',
564-
'Project Net Cashflow (MUSD)',
565-
]
568+
return GeophiresXResult._REVENUE_AND_CASHFLOW_PROFILE_HEADERS
566569

567570
try:
568571
lines = self._get_profile_lines('REVENUE & CASHFLOW PROFILE')
@@ -622,11 +625,57 @@ def extract_table_header(lines: list) -> list:
622625
return None
623626

624627
def _get_ccus_profile(self):
625-
"""
626-
FIXME TODO - transform from revenue & cashflow if present (CCUS profile replaced by revenue & cashflow
627-
profile in 49ff3a1213ac778ed53120626807e9a680d1ddcf)
628-
"""
628+
profile_legacy = self._get_ccus_profile_legacy()
629+
if profile_legacy is not None:
630+
return profile_legacy
631+
632+
revenue_and_cashflow_profile = self._get_revenue_and_cashflow_profile()
633+
if revenue_and_cashflow_profile is None:
634+
return None
635+
636+
carbon_price_field_name = 'Carbon Price (USD/tonne)'
637+
headers = [
638+
'Year Since Start',
639+
# 'Carbon Avoided (pound)', # Present in legacy CCUS profile but not in Revenue & Cashflow
640+
carbon_price_field_name, # Legacy field name: 'CCUS Price (USD/lb)'
641+
'Carbon Ann. Rev. (MUSD/yr)', # Legacy field name: 'CCUS Revenue (MUSD/yr)'
642+
# 'CCUS Annual Cash Flow (MUSD/yr)', # Present in legacy CCUS profile but not in Revenue & Cashflow
643+
'Carbon Cumm. Rev. (MUSD)', # # Legacy field name: 'CCUS Cumm. Cash Flow (MUSD)'
644+
# 'Project Annual Cash Flow (MUSD/yr)', # Present in legacy CCUS profile but not in Revenue & Cashflow
645+
# 'Project Cumm. Cash Flow (MUSD)', # Present in legacy CCUS profile but not in Revenue & Cashflow
646+
]
647+
648+
carbon_price_index = revenue_and_cashflow_profile[0].index(carbon_price_field_name)
649+
has_ccus_profile_in_revenue_and_cashflow = (
650+
len(revenue_and_cashflow_profile) > 1
651+
and carbon_price_field_name in revenue_and_cashflow_profile[0]
652+
# Treat all-zero values as not having CCUS profile
653+
and any(it != 0 for it in [x[carbon_price_index] for x in revenue_and_cashflow_profile[1:]])
654+
)
655+
656+
if not has_ccus_profile_in_revenue_and_cashflow:
657+
return None
629658

659+
try:
660+
profile = [headers]
661+
662+
headers_with_rcp_index = [
663+
(header, GeophiresXResult._REVENUE_AND_CASHFLOW_PROFILE_HEADERS.index(header)) for header in headers
664+
]
665+
666+
for i in range(1, len(revenue_and_cashflow_profile)):
667+
ccus_entry = []
668+
for j in range(len(headers_with_rcp_index)):
669+
rcp_index = headers_with_rcp_index[j][1]
670+
ccus_entry.append(revenue_and_cashflow_profile[i][rcp_index])
671+
profile.append(ccus_entry)
672+
673+
return profile
674+
except BaseException as e:
675+
self._logger.debug(f'Failed to get CCUS profile: {e}')
676+
return None
677+
678+
def _get_ccus_profile_legacy(self):
630679
def extract_table_header(lines: list) -> list:
631680
# Tried various regexy approaches to extract this programmatically but landed on hard-coding.
632681
return [
@@ -646,7 +695,7 @@ def extract_table_header(lines: list) -> list:
646695
profile.extend(self._extract_addons_style_table_data(lines))
647696
return profile
648697
except BaseException as e:
649-
self._logger.debug(f'Failed to get CCUS profile: {e}')
698+
self._logger.debug(f'Failed to get legacy CCUS profile: {e}')
650699
return None
651700

652701
def _extract_addons_style_table_data(self, lines: list):

tests/example1_addons.csv

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ SURFACE EQUIPMENT SIMULATION RESULTS,Average Annual Net Electricity Generation,,
9999
SURFACE EQUIPMENT SIMULATION RESULTS,Average Pumping Power,,0.2,MW
100100
SURFACE EQUIPMENT SIMULATION RESULTS,Initial pumping power/net installed power,,3.82,%
101101
SURFACE EQUIPMENT SIMULATION RESULTS,Heat to Power Conversion Efficiency,,10.07,%
102-
Simulation Metadata,GEOPHIRES Version,,3.7.1,
102+
Simulation Metadata,GEOPHIRES Version,,3.7.16,
103103
POWER GENERATION PROFILE,THERMAL DRAWDOWN,1,1.0,
104104
POWER GENERATION PROFILE,THERMAL DRAWDOWN,2,1.0056,
105105
POWER GENERATION PROFILE,THERMAL DRAWDOWN,3,1.0073,
@@ -1090,3 +1090,93 @@ REVENUE & CASHFLOW PROFILE,Project Net Cashflow,27,197.51,MUSD
10901090
REVENUE & CASHFLOW PROFILE,Project Net Cashflow,28,208.24,MUSD
10911091
REVENUE & CASHFLOW PROFILE,Project Net Cashflow,29,218.97,MUSD
10921092
REVENUE & CASHFLOW PROFILE,Project Net Cashflow,30,229.7,MUSD
1093+
CCUS PROFILE,Carbon Price,1,0.0,USD/tonne
1094+
CCUS PROFILE,Carbon Price,2,0.01,USD/tonne
1095+
CCUS PROFILE,Carbon Price,3,0.01,USD/tonne
1096+
CCUS PROFILE,Carbon Price,4,0.01,USD/tonne
1097+
CCUS PROFILE,Carbon Price,5,0.01,USD/tonne
1098+
CCUS PROFILE,Carbon Price,6,0.01,USD/tonne
1099+
CCUS PROFILE,Carbon Price,7,0.01,USD/tonne
1100+
CCUS PROFILE,Carbon Price,8,0.03,USD/tonne
1101+
CCUS PROFILE,Carbon Price,9,0.04,USD/tonne
1102+
CCUS PROFILE,Carbon Price,10,0.04,USD/tonne
1103+
CCUS PROFILE,Carbon Price,11,0.06,USD/tonne
1104+
CCUS PROFILE,Carbon Price,12,0.07,USD/tonne
1105+
CCUS PROFILE,Carbon Price,13,0.07,USD/tonne
1106+
CCUS PROFILE,Carbon Price,14,0.09,USD/tonne
1107+
CCUS PROFILE,Carbon Price,15,0.1,USD/tonne
1108+
CCUS PROFILE,Carbon Price,16,0.1,USD/tonne
1109+
CCUS PROFILE,Carbon Price,17,0.1,USD/tonne
1110+
CCUS PROFILE,Carbon Price,18,0.1,USD/tonne
1111+
CCUS PROFILE,Carbon Price,19,0.1,USD/tonne
1112+
CCUS PROFILE,Carbon Price,20,0.1,USD/tonne
1113+
CCUS PROFILE,Carbon Price,21,0.1,USD/tonne
1114+
CCUS PROFILE,Carbon Price,22,0.1,USD/tonne
1115+
CCUS PROFILE,Carbon Price,23,0.1,USD/tonne
1116+
CCUS PROFILE,Carbon Price,24,0.1,USD/tonne
1117+
CCUS PROFILE,Carbon Price,25,0.1,USD/tonne
1118+
CCUS PROFILE,Carbon Price,26,0.1,USD/tonne
1119+
CCUS PROFILE,Carbon Price,27,0.1,USD/tonne
1120+
CCUS PROFILE,Carbon Price,28,0.1,USD/tonne
1121+
CCUS PROFILE,Carbon Price,29,0.1,USD/tonne
1122+
CCUS PROFILE,Carbon Price,30,0.1,USD/tonne
1123+
CCUS PROFILE,Carbon Ann. Rev.,1,0.0,MUSD/yr
1124+
CCUS PROFILE,Carbon Ann. Rev.,2,0.51,MUSD/yr
1125+
CCUS PROFILE,Carbon Ann. Rev.,3,0.52,MUSD/yr
1126+
CCUS PROFILE,Carbon Ann. Rev.,4,0.52,MUSD/yr
1127+
CCUS PROFILE,Carbon Ann. Rev.,5,0.52,MUSD/yr
1128+
CCUS PROFILE,Carbon Ann. Rev.,6,0.52,MUSD/yr
1129+
CCUS PROFILE,Carbon Ann. Rev.,7,0.52,MUSD/yr
1130+
CCUS PROFILE,Carbon Ann. Rev.,8,0.87,MUSD/yr
1131+
CCUS PROFILE,Carbon Ann. Rev.,9,1.22,MUSD/yr
1132+
CCUS PROFILE,Carbon Ann. Rev.,10,1.57,MUSD/yr
1133+
CCUS PROFILE,Carbon Ann. Rev.,11,1.92,MUSD/yr
1134+
CCUS PROFILE,Carbon Ann. Rev.,12,2.27,MUSD/yr
1135+
CCUS PROFILE,Carbon Ann. Rev.,13,2.62,MUSD/yr
1136+
CCUS PROFILE,Carbon Ann. Rev.,14,2.97,MUSD/yr
1137+
CCUS PROFILE,Carbon Ann. Rev.,15,3.32,MUSD/yr
1138+
CCUS PROFILE,Carbon Ann. Rev.,16,3.49,MUSD/yr
1139+
CCUS PROFILE,Carbon Ann. Rev.,17,3.5,MUSD/yr
1140+
CCUS PROFILE,Carbon Ann. Rev.,18,3.5,MUSD/yr
1141+
CCUS PROFILE,Carbon Ann. Rev.,19,3.5,MUSD/yr
1142+
CCUS PROFILE,Carbon Ann. Rev.,20,3.5,MUSD/yr
1143+
CCUS PROFILE,Carbon Ann. Rev.,21,3.5,MUSD/yr
1144+
CCUS PROFILE,Carbon Ann. Rev.,22,3.5,MUSD/yr
1145+
CCUS PROFILE,Carbon Ann. Rev.,23,3.5,MUSD/yr
1146+
CCUS PROFILE,Carbon Ann. Rev.,24,3.5,MUSD/yr
1147+
CCUS PROFILE,Carbon Ann. Rev.,25,3.5,MUSD/yr
1148+
CCUS PROFILE,Carbon Ann. Rev.,26,3.5,MUSD/yr
1149+
CCUS PROFILE,Carbon Ann. Rev.,27,3.5,MUSD/yr
1150+
CCUS PROFILE,Carbon Ann. Rev.,28,3.5,MUSD/yr
1151+
CCUS PROFILE,Carbon Ann. Rev.,29,3.5,MUSD/yr
1152+
CCUS PROFILE,Carbon Ann. Rev.,30,3.5,MUSD/yr
1153+
CCUS PROFILE,Carbon Cumm. Rev.,1,0.0,MUSD
1154+
CCUS PROFILE,Carbon Cumm. Rev.,2,0.51,MUSD
1155+
CCUS PROFILE,Carbon Cumm. Rev.,3,1.03,MUSD
1156+
CCUS PROFILE,Carbon Cumm. Rev.,4,1.55,MUSD
1157+
CCUS PROFILE,Carbon Cumm. Rev.,5,2.07,MUSD
1158+
CCUS PROFILE,Carbon Cumm. Rev.,6,2.59,MUSD
1159+
CCUS PROFILE,Carbon Cumm. Rev.,7,3.11,MUSD
1160+
CCUS PROFILE,Carbon Cumm. Rev.,8,3.98,MUSD
1161+
CCUS PROFILE,Carbon Cumm. Rev.,9,5.2,MUSD
1162+
CCUS PROFILE,Carbon Cumm. Rev.,10,6.77,MUSD
1163+
CCUS PROFILE,Carbon Cumm. Rev.,11,8.69,MUSD
1164+
CCUS PROFILE,Carbon Cumm. Rev.,12,10.95,MUSD
1165+
CCUS PROFILE,Carbon Cumm. Rev.,13,13.57,MUSD
1166+
CCUS PROFILE,Carbon Cumm. Rev.,14,16.54,MUSD
1167+
CCUS PROFILE,Carbon Cumm. Rev.,15,19.86,MUSD
1168+
CCUS PROFILE,Carbon Cumm. Rev.,16,23.35,MUSD
1169+
CCUS PROFILE,Carbon Cumm. Rev.,17,26.85,MUSD
1170+
CCUS PROFILE,Carbon Cumm. Rev.,18,30.34,MUSD
1171+
CCUS PROFILE,Carbon Cumm. Rev.,19,33.84,MUSD
1172+
CCUS PROFILE,Carbon Cumm. Rev.,20,37.34,MUSD
1173+
CCUS PROFILE,Carbon Cumm. Rev.,21,40.84,MUSD
1174+
CCUS PROFILE,Carbon Cumm. Rev.,22,44.34,MUSD
1175+
CCUS PROFILE,Carbon Cumm. Rev.,23,47.84,MUSD
1176+
CCUS PROFILE,Carbon Cumm. Rev.,24,51.34,MUSD
1177+
CCUS PROFILE,Carbon Cumm. Rev.,25,54.84,MUSD
1178+
CCUS PROFILE,Carbon Cumm. Rev.,26,58.34,MUSD
1179+
CCUS PROFILE,Carbon Cumm. Rev.,27,61.85,MUSD
1180+
CCUS PROFILE,Carbon Cumm. Rev.,28,65.35,MUSD
1181+
CCUS PROFILE,Carbon Cumm. Rev.,29,68.85,MUSD
1182+
CCUS PROFILE,Carbon Cumm. Rev.,30,72.36,MUSD

tests/examples/example1_addons.out

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

55
Simulation Metadata
66
----------------------
7-
GEOPHIRES Version: 3.7.1
8-
Simulation Date: 2025-01-22
9-
Simulation Time: 10:47
10-
Calculation Time: 0.779 sec
7+
GEOPHIRES Version: 3.7.16
8+
Simulation Date: 2025-02-27
9+
Simulation Time: 11:53
10+
Calculation Time: 0.786 sec
1111

1212
***SUMMARY OF RESULTS***
1313

File renamed without changes.

tests/test_geophires_x_client.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,27 @@ def test_revenue_and_cashflow_profile(self):
346346
)
347347

348348
def test_ccus_profile(self):
349-
test_result_path = self._get_test_file_path('result_with_ccus_profile.out')
349+
result_example1 = GeophiresXResult(self._get_test_file_path('examples/example1.out'))
350+
self.assertTrue('CCUS PROFILE' not in result_example1.result)
351+
352+
result_addons = GeophiresXResult(self._get_test_file_path('examples/example1_addons.out'))
353+
ccus_profile = result_addons.result['CCUS PROFILE']
354+
self.assertIsNotNone(ccus_profile)
355+
self.assertListEqual(
356+
ccus_profile[0],
357+
['Year Since Start', 'Carbon Price (USD/tonne)', 'Carbon Ann. Rev. (MUSD/yr)', 'Carbon Cumm. Rev. (MUSD)'],
358+
)
359+
360+
self.assertListEqual(ccus_profile[1], [1, 0.0, 0.0, 0.0])
361+
362+
self.assertListEqual(ccus_profile[2], [2, 0.01, 0.51, 0.51])
363+
364+
self.assertListEqual(ccus_profile[30], [30, 0.1, 3.5, 72.36])
365+
366+
def test_ccus_profile_legacy(self):
367+
test_result_path = self._get_test_file_path('result_with_ccus_profile_legacy.out')
350368
result = GeophiresXResult(test_result_path)
351-
ccus_profile = result.result['CCUS PROFILE']
369+
ccus_profile_legacy = result.result['CCUS PROFILE']
352370

353371
self.assertListEqual(
354372
[
@@ -394,7 +412,7 @@ def test_ccus_profile(self):
394412
[30, 8035085.158, 0.1, 0.8, 0.8, 16.45, 3.07, 44.31],
395413
[31, 6703146.945, 0.1, 0.67, 0.67, 17.12, 2.7, 47.01],
396414
],
397-
ccus_profile,
415+
ccus_profile_legacy,
398416
)
399417

400418
def test_non_vertical_section_cost(self):

0 commit comments

Comments
 (0)