-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6aea45f
commit adb6d21
Showing
5 changed files
with
644 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
from __future__ import annotations | ||
|
||
import ctypes | ||
import re | ||
from datetime import datetime | ||
from enum import Enum, auto | ||
from fnmatch import fnmatch | ||
from typing import TYPE_CHECKING | ||
|
||
import numpy as np | ||
from ecl.summary import EclSum | ||
from pydantic import PositiveInt | ||
from typing_extensions import Self | ||
|
||
if TYPE_CHECKING: | ||
from typing import Any, List, Optional, Sequence, Tuple | ||
|
||
SPECIAL_KEYWORDS = [ | ||
"NEWTON", | ||
"NAIMFRAC", | ||
"NLINEARS", | ||
"NLINSMIN", | ||
"NLINSMAX", | ||
"ELAPSED", | ||
"MAXDPR", | ||
"MAXDSO", | ||
"MAXDSG", | ||
"MAXDSW", | ||
"STEPTYPE", | ||
"WNEWTON", | ||
] | ||
|
||
|
||
class _SummaryType(Enum): | ||
AQUIFER = auto() | ||
BLOCK = auto() | ||
COMPLETION = auto() | ||
FIELD = auto() | ||
GROUP = auto() | ||
LOCAL_BLOCK = auto() | ||
LOCAL_COMPLETION = auto() | ||
LOCAL_WELL = auto() | ||
NETWORK = auto() | ||
SEGMENT = auto() | ||
WELL = auto() | ||
REGION = auto() | ||
INTER_REGION = auto() | ||
OTHER = auto() | ||
|
||
@classmethod | ||
def from_keyword(cls, summary_keyword: str) -> Self: | ||
KEYWORD_TYPE_MAPPING = { | ||
"A": cls.AQUIFER, | ||
"B": cls.BLOCK, | ||
"C": cls.COMPLETION, | ||
"F": cls.FIELD, | ||
"G": cls.GROUP, | ||
"LB": cls.LOCAL_BLOCK, | ||
"LC": cls.LOCAL_COMPLETION, | ||
"LW": cls.LOCAL_WELL, | ||
"N": cls.NETWORK, | ||
"S": cls.SEGMENT, | ||
"W": cls.WELL, | ||
} | ||
if summary_keyword == "": | ||
raise ValueError("Got empty summary_keyword") | ||
if any(special in summary_keyword for special in SPECIAL_KEYWORDS): | ||
return cls.OTHER | ||
if summary_keyword[0] in KEYWORD_TYPE_MAPPING: | ||
return KEYWORD_TYPE_MAPPING[summary_keyword[0]] | ||
if summary_keyword[0:2] in KEYWORD_TYPE_MAPPING: | ||
return KEYWORD_TYPE_MAPPING[summary_keyword[0:2]] | ||
if summary_keyword == "RORFR": | ||
return cls.REGION | ||
|
||
if any( | ||
re.match(pattern, summary_keyword) | ||
for pattern in [r"R.FT.*", r"R..FT.*", r"R.FR.*", r"R..FR.*", r"R.F"] | ||
): | ||
return cls.INTER_REGION | ||
if summary_keyword[0] == "R": | ||
return cls.REGION | ||
|
||
return cls.OTHER | ||
|
||
|
||
def _cell_index( | ||
array_index: int, nx: PositiveInt, ny: PositiveInt | ||
) -> Tuple[int, int, int]: | ||
k = array_index // (nx * ny) | ||
array_index -= k * (nx * ny) | ||
j = array_index // nx | ||
array_index -= j * nx | ||
|
||
return array_index + 1, j + 1, k + 1 | ||
|
||
|
||
def make_summary_key( | ||
keyword: str, | ||
number: int, | ||
name: str, | ||
nx: int, | ||
ny: int, | ||
lgr_name: Optional[str] = None, | ||
li: Optional[int] = None, | ||
lj: Optional[int] = None, | ||
lk: Optional[int] = None, | ||
) -> List[str]: | ||
sum_type = _SummaryType.from_keyword(keyword) | ||
if sum_type in [ | ||
_SummaryType.FIELD, | ||
_SummaryType.OTHER, | ||
]: | ||
return [f"{keyword}"] | ||
if sum_type in [ | ||
_SummaryType.REGION, | ||
_SummaryType.AQUIFER, | ||
]: | ||
return [f"{keyword}:{number}"] | ||
if sum_type == _SummaryType.BLOCK: | ||
i, j, k = _cell_index(number - 1, nx, ny) | ||
return [f"{keyword}:{number}", f"{keyword}:{i},{j},{k}"] | ||
if sum_type in [ | ||
_SummaryType.GROUP, | ||
_SummaryType.WELL, | ||
]: | ||
return [f"{keyword}:{name}"] | ||
if sum_type == _SummaryType.SEGMENT: | ||
return [f"{keyword}:{name}:{number}"] | ||
if sum_type == _SummaryType.COMPLETION: | ||
i, j, k = _cell_index(number - 1, nx, ny) | ||
return [f"{keyword}:{name}:{number}", f"{keyword}:{name}:{i},{j},{k}"] | ||
if sum_type == _SummaryType.INTER_REGION: | ||
r1 = number % 32768 | ||
r2 = ((number - r1) // 32768) - 10 | ||
return [f"{keyword}:{number}", f"{keyword}:{r1}-{r2}"] | ||
if sum_type == _SummaryType.LOCAL_WELL: | ||
return [f"{keyword}:{lgr_name}:{name}"] | ||
if sum_type == _SummaryType.LOCAL_BLOCK: | ||
return [f"{keyword}:{lgr_name}:{li},{lj},{lk}"] | ||
if sum_type == _SummaryType.LOCAL_COMPLETION: | ||
i, j, k = _cell_index(number - 1, nx, ny) | ||
return [f"{keyword}:{lgr_name}:{name}:{li},{lj},{lk}"] | ||
if sum_type == _SummaryType.NETWORK: | ||
return [] | ||
raise ValueError(f"Unexpected keyword type: {sum_type}") | ||
|
||
|
||
def read_summary( | ||
filepath: str, fetch_keys: Sequence[str] | ||
) -> Tuple[List[str], Sequence[datetime], Any]: | ||
try: | ||
summary = EclSum( | ||
filepath, | ||
include_restart=False, | ||
lazy_load=False, | ||
) | ||
except IOError as e: | ||
raise ValueError( | ||
"Could not find SUMMARY file or using non unified SUMMARY " | ||
f"file from: {filepath}.UNSMRY", | ||
) from e | ||
|
||
data = [] | ||
keys = [] | ||
c_time = summary.alloc_time_vector(True) | ||
time_map = [t.datetime() for t in c_time] | ||
|
||
user_summary_keys = set(fetch_keys) | ||
for key in summary: | ||
if not _should_load_summary_key(key, user_summary_keys): | ||
continue | ||
keys.append(key) | ||
data.append(summary.numpy_vector(key)) | ||
return (keys, time_map, data) | ||
|
||
|
||
def _should_load_summary_key(data_key: Any, user_set_keys: set[str]) -> bool: | ||
return any(fnmatch(data_key, key) for key in user_set_keys) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.