Source code for flopy.pest.tplarray

import numpy as np

from ..utils.util_array import Transient2d as Transient2d
from ..utils.util_array import Util3d as Util3d


[docs]def get_template_array(pakarray): """ Convert the package array into the appropriate template array """ tpla = pakarray if isinstance(pakarray, Util3d): tpla = Util3dTpl(pakarray) elif isinstance(pakarray, Transient2d): tpla = Transient2dTpl(pakarray) return tpla
[docs]class Transient2dTpl: def __init__(self, transient2d): self.transient2d = transient2d self.params = {} self.multipliers = {} return
[docs] def add_parameter(self, p): """ Store the parameters in a list for later substitution """ # Verify parameter span contents if "kpers" not in p.span: raise Exception(f"Parameter {p.name} span does not contain kper.") if "idx" not in p.span: raise Exception(f"Parameter {p.name} span does not contain idx.") if p.span["idx"] is None: # Multiplier parameter is when p.span['idx'] is None for kper in p.span["kpers"]: self.multipliers[kper] = f"~ {p.name:^13s} ~" else: # Index parameter otherwise for kper in p.span["kpers"]: if kper not in self.params: self.params[kper] = [] self.params[kper].append(p) return
[docs] def get_kper_entry(self, kper): # Set defaults parameterized = False multiplier = None indexed_param = False # Check to see if a multiplier applies if kper in self.multipliers: multiplier = self.multipliers[kper] parameterized = True # Check to see if there are any array index parameters. if kper in self.params: parameterized = True indexed_param = True # If parameterized return the parameter array, otherwise return # regular transient2d array if parameterized: u2d = self.transient2d[kper] chararray = np.array(u2d.array, dtype="str") if kper in self.params: for p in self.params[kper]: idx = p.span["idx"] chararray[idx] = f"~{p.name:^13s}~" u2dtpl = Util2dTpl(chararray, u2d.name, multiplier, indexed_param) return (1, u2dtpl.get_file_entry()) else: return self.transient2d.get_kper_entry(kper)
[docs]class Util3dTpl: """ Class to define a three-dimensional template array for use with parameter estimation. Parameters ---------- u3d : Util3d object """ def __init__(self, u3d): self.u3d = u3d self.chararray = np.array(u3d.array, dtype="str") self.multipliers = {} self.indexed_params = False if self.chararray.ndim == 3: # Then multi layer array, so set all multipliers to None for k in range(self.chararray.shape[0]): self.multipliers[k] = None return def __getitem__(self, k): return Util2dTpl( self.chararray[k], self.u3d.name_base[k] + str(k + 1), self.multipliers[k], self.indexed_params, )
[docs] def add_parameter(self, p): """ Fill the chararray with the parameter name. Parameters ---------- p : flopy.pest.params.Params Parameter. Must have .idx and .name attributes """ if "layers" in p.span and "idx" in p.span: if p.span["idx"] is not None: raise Exception( "For a Util3d object, cannot have layers and " "idx in parameter.span" ) if "layers" in p.span: for l in p.span["layers"]: self.multipliers[l] = f"~ {p.name:^13s} ~" if "idx" in p.span and p.span["idx"] is not None: idx = p.span["idx"] self.chararray[idx] = f"~{p.name:^13s}~" self.indexed_params = True return
[docs]class Util2dTpl: """ Class to define a two-dimensional template array for use with parameter estimation. Parameters ---------- chararray : A Numpy ndarray of dtype 'str'. name : The parameter type. This will be written to the control record as a comment. indexed_param : bool A flag to indicated whether or not the array contains parameter names within the array itself. """ def __init__(self, chararray, name, multiplier, indexed_param): self.chararray = chararray self.name = name self.multiplier = multiplier self.indexed_param = indexed_param return
[docs] def get_file_entry(self): """ Convert the array into a string. Returns ------- file_entry : str """ ncol = self.chararray.shape[-1] au = np.unique(self.chararray) if au.shape[0] == 1 and self.multiplier is None: file_entry = f"CONSTANT {au[0]} #{self.name}\n" else: mult = 1.0 if self.multiplier is not None: mult = self.multiplier cr = f"INTERNAL {mult} (FREE) -1 #{self.name}\n" astring = "" icount = 0 for i in range(self.chararray.shape[0]): for j in range(self.chararray.shape[1]): icount += 1 astring += f" {self.chararray[i, j]:>15s}" if icount == 10 or j == ncol - 1: astring += "\n" icount = 0 file_entry = cr + astring return file_entry