Source code for ogs5py.fileclasses.gem.core

# -*- coding: utf-8 -*-
"""Class for the ogs GEOCHEMICAL THERMODYNAMIC MODELING COUPLING file."""
import os

from ogs5py.fileclasses.base import BlockFile, LineFile

# current working directory
CWD = os.getcwd()


[docs]class GEM(BlockFile): """ Class for the ogs GEOCHEMICAL THERMODYNAMIC MODELING COUPLING file. Parameters ---------- task_root : str, optional Path to the destiny model folder. Default: cwd+"ogs5model" task_id : str, optional Name for the ogs task. Default: "model" Notes ----- Main-Keywords (#): - GEM_PROPERTIES Sub-Keywords ($) per Main-Keyword: - GEM_PROPERTIES - CALCULATE_BOUNDARY_NODES - DISABLE_GEMS - FLAG_COUPLING_HYDROLOGY - FLAG_DISABLE_GEM - FLAG_POROSITY_CHANGE - GEM_CALCULATE_BOUNDARY_NODES - GEM_INIT_FILE - GEM_THREADS - ITERATIVE_SCHEME - KINETIC_GEM - MAX_FAILED_NODES - MAX_POROSITY - MIN_POROSITY - MY_SMART_GEMS - PRESSURE_GEM - TEMPERATURE_GEM - TRANSPORT_B Standard block: None Keyword documentation: https://ogs5-keywords.netlify.com/ogs/wiki/public/doc-auto/by_ext/gem Reading routines: https://github.com/ufz/ogs5/blob/master/FEM/rf_REACT_GEM.cpp#L2644 See Also -------- add_block """ MKEYS = ["GEM_PROPERTIES"] # sorted SKEYS = [ [ "GEM_INIT_FILE", "GEM_THREADS", "TRANSPORT_B", "FLAG_POROSITY_CHANGE", "MIN_POROSITY", "MAX_POROSITY", "FLAG_COUPLING_HYDROLOGY", "ITERATIVE_SCHEME", "CALCULATE_BOUNDARY_NODES", "TEMPERATURE_GEM", "PRESSURE_GEM", "MAX_FAILED_NODES", "MY_SMART_GEMS", "FLAG_DISABLE_GEM", "KINETIC_GEM", "DISABLE_GEMS", # really? "GEM_CALCULATE_BOUNDARY_NODES", # really? "GEM_SMART", # really? "FLAG_NODE_ELEMENT", # really? "FLAG_CALCULATE_BOUNDARY_NODE", # really? ] ] STD = {} def __init__(self, **OGS_Config): super().__init__(**OGS_Config) self.file_ext = ".gem"
[docs]class GEMinit: """ Class for GEMS3K input file. lst file that contains the names of * the GEMS data file (dch file), * the GEMS numerical settings (ipm file) * the example setup (dbr file) used to initialize the GEMS3K kernel. Parameters ---------- lst_name: :class:`str` or :class:`None`, optional name of the lst file dch: :any:`LineFile` or :class:`None` the GEMS data file ipm: :any:`LineFile` or :class:`None` the GEMS data file dbr: :any:`LineFile` or :class:`None` the GEMS data file task_root : str, optional Path to the destiny model folder. Default: cwd+"ogs5model" task_id : str, optional Name for the ogs task. Default: "model" Notes ----- http://gems.web.psi.ch/GEMS3/index.html http://gems.web.psi.ch/GEMS3K/ http://gems.web.psi.ch/GEMS3K/doc/html/gems3k-iofiles.html """ def __init__( self, lst_name="model-dat.lst", dch=None, ipm=None, dbr=None, task_root=None, task_id="model", ): if task_root is None: task_root = os.path.join(CWD, "ogs5model") self._task_root = task_root self.task_id = task_id self.lst_name = lst_name # add files if dch is not None: self.dch = dch else: self.dch = LineFile( name=self.task_id + "-dch", file_ext=".dat", task_root=self.task_root, ) if ipm is not None: self.ipm = ipm else: self.ipm = LineFile( name=self.task_id + "-ipm", file_ext=".dat", task_root=self.task_root, ) if dbr is not None: self.dbr = dbr else: self.dbr = LineFile( name=self.task_id + "-dbr", file_ext=".dat", task_root=self.task_root, )
[docs] def get_file_type(self): """Get the OGS file class name.""" return "lst"
@property def files(self): """List of the included files: dch, ipm, dbr.""" out_list = [] if self.dch is not None: out_list.append(self.dch) if self.ipm is not None: out_list.append(self.ipm) if self.dbr is not None: out_list.append(self.dbr) return out_list @property def name(self): """The name of the lst file.""" return os.path.splitext(self.lst_name)[0] @property def file_ext(self): """The extension of the lst file.""" return os.path.splitext(self.lst_name)[1] @property def file_names(self): """The names of the included files.""" out_list = [] for file in self.files: out_list.append(file.name + file.file_ext) return out_list def __bool__(self): """Bool.""" return not self.is_empty def __nonzero__(self): """Bool.""" return self.__bool__() @property def is_empty(self): """State if the file is empty.""" # check if the files are empty if self.check(False): return not any(self.files) # if check is not passed, handle it as empty file return True @property def task_root(self): """Get and set the task_root path of the ogs model.""" return self._task_root @task_root.setter def task_root(self, value): self._task_root = value self.dch.task_root = value self.ipm.task_root = value self.dbr.task_root = value
[docs] def reset(self): """Delete every content.""" self.dch = LineFile( name=self.task_id + "-dch", file_ext=".dat", task_root=self.task_root, ) self.ipm = LineFile( name=self.task_id + "-ipm", file_ext=".dat", task_root=self.task_root, ) self.dbr = LineFile( name=self.task_id + "-dbr", file_ext=".dat", task_root=self.task_root, )
[docs] def check(self, verbose=True): """ Check if the GEM external file is valid. Parameters ---------- verbose : bool, optional Print information for the executed checks. Default: True Returns ------- result : bool Validity. """ # no checks are performed out = True for file in self.files: out &= file.check(verbose) return out
[docs] def save(self, path): """ Save the actual GEM external file in the given path. lst file containing: dch, ipm, dbr Parameters ---------- path : str path to where to file should be saved """ for file in self.files: file.write_file() with open(path, "w") as fout: fout.write(str(self))
[docs] def read_file(self, path, encoding=None, verbose=False): """ Read a given GEM external input lst-file. Parameters ---------- path : str path to the file Notes ----- This also reads the given files in the lst-file. (dch, ipm, dbr) """ root = os.path.dirname(path) self.reset() try: with open(path, "r", encoding=encoding) as fin: for line in fin: if line.strip().startswith("-t"): file_names = [] # get rid of leading "-t" for file_name in line.split()[1:]: # get rid of " and ' around strings file_names.append(file_name.strip('"').strip("'")) break except IOError: if verbose: print( "ogs5py " + self.get_file_type() + ": could not read lst-file: " + path ) else: # hard coded order of files self.dch.name = os.path.splitext(file_names[0])[0] self.dch.file_ext = os.path.splitext(file_names[0])[1] self.dch.read_file( path=os.path.join(root, file_names[0]), encoding=encoding, verbose=verbose, ) self.ipm.name = os.path.splitext(file_names[1])[0] self.ipm.file_ext = os.path.splitext(file_names[1])[1] self.ipm.read_file( path=os.path.join(root, file_names[1]), encoding=encoding, verbose=verbose, ) self.dbr.name = os.path.splitext(file_names[2])[0] self.dbr.file_ext = os.path.splitext(file_names[2])[1] self.dbr.read_file( path=os.path.join(root, file_names[2]), encoding=encoding, verbose=verbose, )
[docs] def write_file(self): """ Write the actual OGS input file to the given folder. Its path is given by "task_root+task_id+file_ext". """ # create the file path if not os.path.exists(self.task_root): os.makedirs(self.task_root) f_path = os.path.join(self.task_root, self.lst_name) # save the data if not self.is_empty: self.save(f_path)
def __repr__(self): """Representation.""" out_str = "-t" for file_name in self.file_names: out_str += ' "' + file_name + '"' return out_str def __str__(self): """Representation.""" return self.__repr__()