sutra2.ModPath_Well module
- class sutra2.ModPath_Well.ModPathWell(schematisation: HydroChemicalSchematisation, workspace: Optional[str] = None, modelname: Optional[str] = None, mf_exe='mf2005.exe', mp_exe='mpath7.exe', bound_left: str = 'xmin', bound_right: str = 'xmax', bound_top: str = 'top', bound_bot: str = 'bot', bound_north: str = 'ymin', bound_south: str = 'ymax', trackingdirection='forward')
Bases:
objectCompute travel time distribution using MODFLOW and MODPATH.
- MP7modelrun(mf_namfile=None, mp_exe=None)
Modpath model run.
- assign_material(schematisation: dict, dict_keys: Optional[dict] = None)
Assign grid material using subkeys in schematisation_dict.
- assign_wellloc(schematisation: dict, dict_key: str = 'well_parameters', well_names: list = 'None', discharge_parameter='well_discharge')
Determine the location of the pumping wells and the relative discharge per cell.
Boundaries of the well locations are to be included in the dictionaries with keys “dict_keys” [list], based on presence of “discharge_parameter” [str (default = “Q”)]:
bound_left: str = “xmin” bound_right: str = “xmax” bound_top: str = “top” bound_bot: str = “bot” bound_north: str = “ymin” bound_south: str = “ymax”
# Output: # Creates a dict with list of tuples representing the well locations well_loc = {“well1”: [(5,0,0),(6,0,0)], “well2”:}
# Calculate cumulative KD per well [m2/day] (to calculate relative discharge per cell) KD_well = {“well1”: 500., “well2”: 100.,…} # Create stress period data [list of lists per stress period]: # wel_spd = {0: [[lay,row,col,discharge1],[lay,row,col,discharge2]]
# Total discharge per day per well Qwell_day = = {“well1”: -1000.., “well2”: -1.,…}
- axisym_correction(grid: array, dtype: Optional[str] = None, theta=6.283185307179586)
Correct modflow parameters to correctly calculate axisymmetric flow. Adjust the array ‘grid’ if it already exists, using multiplier theta and xmid (nrow == 1 or nrow == 2) or ymid (ncol == 1 or ncol == 2).
- calc_flux_cell(frf, flf, fff, loc, flux_direction='total')
Calculate the total volume flux along the cell boundary, using frf, flf and fff.
- Parameters
frf (np.array) – flux right face (= positive to the right) [m^3 d-1]
flf (np.array) – flux lower face (= positive in downward direction) [m^3 d-1]
fff (np.array) – flux front face (= positive in ‘southward’ direction) [m^3 d-1]
loc (tuple) – cell location (lay,row,col)
flux_direction (str) – cell flux along boundary [‘total’,’west’,’east’,’north’,’south’,’top’,’bottom’, ‘vertical’, ‘horizontal’] (NB ‘total’: ‘magnitude’ of flow in cell) NB2: ‘vertical –> corrected for additional inflow horizontally NB3: ‘vertical –> corrected for additional inflow vertically
- calc_traveltime_vadose_analytical(vadose_parameters: dict = {}, dict_key='vadose_zone', distance=None, gw_level=None)
Inherit functionality from Analytical_Well module
- cell_bounds(schematisation: dict, dict_key: str = 'None', dict_subkey: str = 'None', model_type='axisymmetric')
Create cell boundaries of box created using following boundaries: self.bound_left: str = “xmin” self.bound_right: str = “xmax” self.bound_top: str = “top” self.bound_bot: str = “bot” self.bound_north: str = “ymin” # not required for axisymmetric or 2D model self.bound_south: str = “ymax” # not required for axisymmetric or 2D model # Return boundary indices of row and columns plus parameter value return layidx_min,layidx_max,rowidx_min,rowidx_max,colidx_min,colidx_max
- create_MNW(schematisation: dict, dict_key: str = 'well_parameters', well_names: Optional[list] = None, discharge_parameter='well_discharge')
Add multi nodal well Package to the MODFLOW model. # Function allows for a single row, col combination in current version per identified well. Documented in flopy docs - MNW2.
- Parameters
wellid (str or int) – name of the well
nnodes (int) – nr of filter screens per vertical well (if nnodes < 0). Allows for input of ztop and zbot per filter screen.
ztop (float) – top elevation of open intervals of vertical well. [m]
zbotm (float) – bottom elevation of open intervals of vertical well. [m]
rw (float) – well radius of the vertical well(s) [m]
- create_MP7object(mp_exe='mpath7', mf_model=None, headfilename=None, budgetfilename=None)
Load modpath7 model, using input from modflow model ‘mf_model’ (DIS), results from head calculations, and cell-by-cell data.
- create_bas()
Add basic Package to the MODFLOW model
- create_dis(per_nr=0)
Add dis Package to the MODFLOW model
- create_lpf()
Add lpf Package to the MODFLOW model
- create_mfobject(mf_exe='mf2005.exe', fname_nam=None)
create mf-object (if fname_nam equals None). Otherwise: load mf-model using nam-file ‘fname_nam’.
- create_modflow_input(**kwargs)
Generate flopy files.
- create_modflow_packages(**kwargs)
Create modflow packages used in the model run.
- create_modpath_packages(mp_exe='mpath7', **kwargs)
Create modpath packages used in the model run.
- create_mpbas()
Add BAS Package to the ModPath model
- create_oc(spd_oc={(0, 0): ['save head', 'save budget']}, per_nr=0)
Add output control Package to the MODFLOW model.
- create_pcg(hclose=0.0001, rclose=0.001)
Add PCG Package to the MODFLOW model
- create_rch(rech=None)
Add recharge Package to the MODFLOW model.
- create_wel(spd_wel=None)
Add well Package to the MODFLOW model.
- extract_vadose_zone_parameters(schematisation: dict, schematisation_type: str, dict_key='geo_parameters', parameter: str = 'vadose', remove_layer=None)
Extract vadose_zone interval from geo_parameters dictionary ‘dict_key’, if ‘parameter’ value in the ‘dict_key’ (e.g. “vadose”) is True. remove_layer: –> remove the key from schematisation[dict_key] if it is a vadose_zone (T/F).
- fill_df_flowline(df_particle, model_cbc)
Fill df_flowline dataframe
- Parameters
df_particle (pd.DataFrame) –
- Returns
df_flowline – Column ‘flowline_id’: Integer Column ‘flowline_type’: string Described the type of contamination associated with the flowline, either ‘diffuse_source’ or ‘point_source’. Column ‘flowline_discharge’: float. Discharge associated with the flowline, [m3/d]. Column ‘particle_release_day’: float Column ‘input_concentration’ Column ‘endpoint_id’: Integer ID of Well (or drain) where the flowline ends. Column ‘well_discharge’: float Column ‘substance’: string Column ‘removal_function’: string
- Return type
pandas.DataFrame
- fill_df_particle(particle_group, pg_nodes, parm_list: list = [], mppth=None)
Fill the df_particle, ordered by flowline_id and total_travel_time
- Parameters
particle_group (str) – particle group name of released particles
pg_nodes (list of tuple or list of list) – locations at which particles were started [(lay,row,col),(…)]
parm_list – list of columns to include in df_particle (to be returned)
mppth (str or Path) – ‘modpath_name.pth’ file location
- Returns
df_particle – Holder for df_particle, filled by the flowline_id
- flowline_id: int
ID of the flowline
- xcoord: float
x coordinate of particle
- ycoord: float
y coordinate of particle
- zcoord: float
z coordinate of particle
- total_travel_time:
travel time since start of model [days]
- material: str
identifier for geological layer or other material/object wherein particle resides
- redox: str
redox condition [‘suboxic’,’anoxic’,’deeply_anoxic’]
- temp_water: float
Water temperature [degrees celcius]
- porosity: float
effective porosity [-]
- dissolved_organic_carbon:
dissolved organic carbon (DOC) fraction [-]
- pH: float
pH of the water [-]
- fraction_organic_carbon
organic carbon fraction (foc) [-]
- solid_density: float
Bulk density of the material [kg / L]
- Return type
pandas.dataframe
- fill_grid(schematisation: dict, dict_keys: Optional[list] = None, parameter: str = 'None', grid: Optional[array] = None, dtype: str = 'float')
Assign values to ‘grid’ [np.array] for parameter name ‘parameter’ [str], using the keys dict_keys [list] in schematisation dictionary ‘self.schematisation’. ‘dtype’ [grid dtype] –> grid dtype [str] is obtained from grid if initial array is given. The schematisation type refers to the model_type[“axisymmetric”,”2D” or “3D”]
Boundaries of the parameter values are to be included in the dictionaries:
self.bound_left: str = “xmin” self.bound_right: str = “xmax” self.bound_top: str = “top” self.bound_bot: str = “bot” self.bound_north: str = “ymin” self.bound_south: str = “ymax”
The function returns: - grid # grid [np.array] filled with (numeric) values for parameter ‘parameter’.
- generate_modflow_files()
Write package data MODFLOW model.
- get_node_ID(locs)
Obtain/return model node index (int) belonging to layer ‘iLay’, row ‘iRow’ and column ‘iCol’. for point locations ‘locs’.
- get_node_indices(xyz_nodes, particle_list: Optional[list] = None)
Obtain/return layer,row,column idx (“node_indices”) as dict of np.arrays corresponding to xyz-coördinates of type dict per tracked particle (as key) with nodes “xyz_nodes” (np.array).
Method requires center points xmid, ymid, zmid to be predefined.
- make_discretisation(schematisation: dict, dict_keys=None, model_type='axisymmetric')
Generate spatial grid for model_type choices: ‘axisymmetric’, ‘2D’ or ‘3D’.
Parameter ‘schematisation’ is of type dict with (sub)dictionaries with keys ‘dict_keys’. The subdictionaries should contain specific keyword arguments to generate the grids. The function indirectly uses “_assign_cellboundaries” to obtain grid data outputs.
# Layer data assignment (model_type: axi-symmetric | 2D | 3D) Required keys: - “bot” # bottom of local grid refinement - “top” # top of local grid refinement Optional keyword argument(s): - “nlayers” # number of layers within local grid refinement
- self.delv: layer depths of the model layers [np.array]
rounded to two decimals [cm scale].
self.zmid: z-coordinates (middle) of the model layers [np.array]
self.nlay: number of model layers
self.top: model top [float or np.array]
self.bot: model bottoms per layer [1D | 2D | 3D np.array of floats]
# Column data assignment (model_type: axi-symmetric | 2D | 3D) Required keys: - “xmin” # left side of local grid refinement - “xmax” # right side of local grid refinement Optional keyword argument(s): - “ncols” # number of columns within local grid refinement
# Column data outputs: - self.delr: column widths of the model columns [np.array] rounded to three decimals [mm scale]. - self.xmid: x-coordinates (middle) of the model columns [np.array] - self.ncol: number of model columns
# Row data assignment (model_type: 3D) # N.B. for modeltype: (axisymmetric | 2D) the rows have a predefined width [2 rows, 1 m width]
Required keys: - “ymin” # ‘northern’ side of local grid refinement - “ymax” # ‘southern’ side of local grid refinement Optional keyword argument(s): - “nrows” # number of rows within local grid refinement
# Row data outputs: - self.delc: row widths of the model rows [np.array] - self.ymid: y-coordinates (middle) of the model rows [np.array] - self.nrow: number of model rows
- Returns
empty_grid (np.array) – Empty numpy array with size (self.nlay,nrow,ncol)
lay_bounds (np.array) – Upper and lower boundaries of the model grid cells [1D-array]
row_bounds (np.array) – Left and right boundaries of the model grid cells [1D-array]
col_bounds (np.array) – North-south boundaries of the grid-cells [1D-array]
- mfmodelrun()
Main model run code.
- model_cbc
Initialize the AnalyticalWell object by making the dictionaries and adding the schematisation (and therefore attributes of the schematisation) to the object.
- Return type
Dictionaries (Modflow) with all parameters as an attribute of the function.
- modpath_simulation(mp_model=None, trackingdirection='backward', simulationtype='combined', stoptimeoption='specified', particlegroups=None, stoptime=100000.0, zones=None)
input MODPATH Simulation File Package Class, see flopy docs.
- mpbas_input(prsity=0.3, defaultiface={'RECHARGE': 6})
Read model prsity and iface values into object.
- particle_data(partlocs=None, structured=True, particleids=[0], localx=None, localy=0.5, localz=None, timeoffset=0.0, drape=None, pgname='Recharge', pg_filename='Recharge.sloc', trackingdirection='forward', releasedata=0.0)
Class to create the most basic particle data type (starting location input style 1). Input style 1 is the most general input style and provides the highest flexibility in customizing starting locations, see flopy docs.
- plot_age_distribution(df_particle: DataFrame, vmin=0.0, vmax=1.0, orientation={'row': 0}, fpathfig=None, figtext=None, x_text=0, y_text=0, lognorm=True, xmin=0.0, xmax=None, ymin=None, ymax=None, line_dist=1, dpi=192, trackingdirection='forward', cmap='viridis_r', show_vadose=True)
Create pathline plots with residence times using colours as indicator. with: - df_particle: dataframe containing xyzt-points of the particle paths. - fpathfig = output location of plots figtext: figure text to show within plot starting at x-location ‘x_text’ and y-location ‘y_text’. lognorm: True/False (if vmin <= 0. –> vmin = 1.e-5) xmin: left boundary figure xmax: right boundary figure ymin: lower boundary figure ymax: upper boundary figure line_dist: min. distance between well pathlines at source (m) line_freq: show every ‘X’ pathlines dpi: pixel density trackingdirection: direction of calculating flow along pathlines” cmap: Uses colormap ‘viridis_r’ (viridis reversed as default) show_vadose: T/F (if True, include vadose zone flow lines; default = True)
- read_binarycbc_flow(fname=None)
Read binary cell budget file (fname). This is modflow output.
return frf, flf, fff.
- read_hdsobj(fname=None, time=None)
Return head data from file. If time = -1 –> return final time and head grid, elif time = ‘all’ –> return all time values and head grids, elif time = [1.,2.,time_n]–> Return head grids for prespecified times.
- read_pathlinedata(fpth, nodes)
Read pathlinedata from file fpth (extension: ‘.mppth’), given the particle release node index ‘nodes’ obtained from a tuple or list of tuples (iLay,iRow,iCol).
- Parameters
fpth (str) – filepath of pathline data
nodes – Cell node indices of starting locations. Can be obtained using the method get_node_ID((iLay,iRow,iCol))
- Returns
xyz_nodes – The xyz coördinates of each node per tracked particle
dist – The distance between each node per tracked particle [L]
tdiff – The travel time (difference) between each node per particle [T]
dist_tot – Total distance covered by each tracked particle [L]
time_tot – Total duration between release and ending of each particle [T]
pth_data (np.recarray) – Complete recarray is returned to see what is in the file fpth.
- run_ModPathmod()
Run ModPath model
- run_model(xll=0.0, yll=0.0, perlen: dict = 18250.0, nstp: dict = 1, nper: int = 1, steady: dict = True, run_mfmodel=True, run_mpmodel=True)
Run the combined modflow and modpath model using one of four possible schematisation types: - “Phreatic” - “Semi-confined” - “Recharge basin (BAR)” - “River bank filtration (RBF)” Currently (13-7-2021) only the Phreatic schematisation is supported.
- run_modflowmod()
Run modflow model
- write_input_mp()
Write package data ModPath model.
- xyz_to_layrowcol(xyz_point, decimals=3)
obtain lay, row, col index of an xyz_point list [x,y,z].