Source code for ResSimpy.Nexus.structured_grid_operations

from __future__ import annotations
from typing import Optional, TYPE_CHECKING
from ResSimpy.Grid import VariableEntry
import ResSimpy.Nexus.nexus_file_operations as nfo

if TYPE_CHECKING:
    from ResSimpy.Nexus.NexusSimulator import NexusSimulator


[docs]class StructuredGridOperations:
[docs] def __init__(self, model: NexusSimulator) -> None: self.__model: NexusSimulator = model
[docs] @staticmethod def load_token_value_if_present(token: str, modifier: str, token_property: VariableEntry, line: str, file_as_list: list[str], ignore_values: Optional[list[str]] = None) -> None: """Gets a token's value if there is one and loads it into the token_property. Args: ---- token (str): the token being searched for. e.g. 'PERMX' modifier (str): any modifiers applied to the token e.g. 'MULT' token_property (VariableEntry): VariableEntry object to store the modifier and value pair into line (str): line to search for the token in ignore_values (Optional[list[str]], optional): values to be ignored. Defaults to None. Raises: ------ ValueError: raises an error if no numerical value can be found after the supplied token modifier pair Returns: None: stores the value into token_property supplied instead """ if ignore_values is None: ignore_values = [] token_modifier = f"{token} {modifier}" if nfo.check_token(token, line) and nfo.get_token_value(token, line, file_as_list) == modifier: # If we are loading a multiple, load the two relevant values, otherwise just the next value if modifier == 'MULT': numerical_value = nfo.get_expected_token_value(token_modifier, line, file_as_list, ignore_values=None) if numerical_value is None: raise ValueError( f'No numerical value found after {token_modifier} keyword in line: {line}') value_to_multiply = nfo.get_token_value(token_modifier, line, file_as_list, ignore_values=[numerical_value]) if numerical_value is not None and value_to_multiply is not None: token_property.modifier = 'MULT' token_property.value = f"{numerical_value} {value_to_multiply}" else: value = nfo.get_token_value(token_modifier, line, file_as_list, ignore_values=ignore_values) if value is None: # Could be 'cut short' by us excluding the rest of a file token_property.value = None token_property.modifier = modifier token_property.value = value token_property.modifier = modifier
[docs] @staticmethod def replace_value(file_as_list: list[str], old_property: VariableEntry, new_property: VariableEntry, token_name: str) -> None: """Replace the value and token + modifier with the new values. Args: ---- file_as_list (list[str]): a list of strings containing each line of the file as a new entry old_property (VariableEntry): property found in the original file to be replaced new_property (VariableEntry): new property to replace the old property with token_name (str): name of the token being replaced Returns: None: modifies the file_as_list with the new property """ for line in file_as_list: old_token_modifier = f"{token_name} {old_property.modifier}" new_token_modifier = f"{token_name} {new_property.modifier}" ignore_values = ['INCLUDE'] if old_property.modifier == 'VALUE' else [] if nfo.check_token(old_token_modifier, line): # If we are replacing a mult, replace the first value with a blank if old_property.modifier == 'MULT': dummy_value = VariableEntry('MULT', '') nfo.get_token_value(old_token_modifier, line, file_as_list, ignore_values=ignore_values, replace_with=dummy_value) nfo.get_token_value(old_token_modifier, line, file_as_list, ignore_values=ignore_values, replace_with=new_property) new_line = line.replace(old_token_modifier, new_token_modifier, 1) line_index = file_as_list.index(line) file_as_list[line_index] = new_line
[docs] @staticmethod def append_include_to_grid_file(include_file_location: str, structured_grid_file_path: str) -> None: # TODO: change append to be an optional parameter """Appends an include file to the end of a grid for adding LGRs. Args: ---- include_file_location (str): path to a file to include in the grid structured_grid_file_path (str): file path to the structured grid. Raises: ------ ValueError: if no structured grid file path is specified in the class instance """ # Get the existing file as a list if structured_grid_file_path is None: raise ValueError("No file path given or found for structured grid file path. \ Please update structured grid file path") file = nfo.load_file_as_list(structured_grid_file_path) file.append(f"\nINCLUDE {include_file_location}\n") file.append("TOLPV LGR1 0\n") # Save the new file contents new_file_str = "".join(file) with open(structured_grid_file_path, "w") as text_file: text_file.write(new_file_str)
[docs] @staticmethod def get_grid_file_as_3d_list(path: str) -> Optional[list]: """Converts a grid file to a 3D list. Args: ---- path (str): path to a grid file Returns: ------- Optional[list[str]]: Returns None if no file is found, returns the grid as a 3d array otherwise """ try: with open(path) as f: grid_file_list = list(f) except FileNotFoundError: return None sub_lists = [] new_list_str = "" for sub_list in grid_file_list[4:]: if sub_list == '\n': new_list_split = [x.split("\t") for x in new_list_str.split("\n")] new_list_split_cleaned = [] for x_list in new_list_split: float_list_split = [float(x) for x in x_list if x != ""] new_list_split_cleaned.append(float_list_split) sub_lists.append(new_list_split_cleaned) new_list_str = "" else: new_list_str = new_list_str + sub_list return sub_lists
[docs] def view_command(self, field: str, previous_lines: int = 3, following_lines: int = 3) -> Optional[str]: """Displays how the property is declared in the structured grid file. Args: ---- field (str): property as written in the structured grid (e.g. KX) previous_lines (int, optional): how many lines to look back from the field searched for. Defaults to 3. following_lines (int, optional): how many lines to look forward from the field searched for. Defaults to 3. Raises: ------ ValueError: if no structured grid file path is specified in the class instance Returns: ------- Optional[str]: the string associated with the supplied property from within the structured grid. \ If the field is not found in the structured grid returns None. """ structured_grid_dict = self.__model.get_structured_grid_dict() structured_grid_path = self.__model.structured_grid_path command_token = f"{field.upper()} {structured_grid_dict[field.lower()].modifier}" if structured_grid_path is None: raise ValueError("No path found for structured grid file path. \ Please provide a path to the structured grid") file_as_list = nfo.load_file_as_list(structured_grid_path) for line in file_as_list: if nfo.check_token(command_token, line): start_index = file_as_list.index(line) - previous_lines \ if file_as_list.index(line) - previous_lines > 0 else 0 end_index = file_as_list.index(line) + following_lines \ if file_as_list.index(line) + following_lines < len(file_as_list) else len(file_as_list) - 1 new_array = file_as_list[start_index: end_index] new_array = [x.strip("'") for x in new_array] value = "".join(new_array) return value return None