How to export MODFLOW head contours as Shapefiles with Flopy – Tutorial

Hydrate

The quality of a groundwater model as a tool for sustainable management of our groundwater resources doesn´t on the quality of the input data, the accuracy of the calibration but also on the visualization of the output data and analysis of the water budget. There are several options to export contours from MODFLOW GUIs as Model Muse, however when analyzing several stress periods the graphical steps could be time consuming therefore a Python script would be helpful to export heads or water table as shapefiles.

You will need a conda environment with geospatial tools for the tutorial. Create the environment following this link:

https://hatarilabs.com/ih-en/how-to-install-python-geopandas-in-windows-on-a-conda-environment-tutorial

Video

Code

#!pip install flopy
import os
import numpy as np
import matplotlib.pyplot as plt
import flopy
#import shapefile as sf #in case you dont have it, form anaconda prompt: pip install pyshp
from flopy.utils.gridgen import Gridgen
from flopy.utils.reference import SpatialReference
import pandas as pd
from scipy.interpolate import griddata
modelname='regionalModel1'
model_ws= '../Model/'
mf = flopy.modflow.Modflow.load(modelname+'.nam', version="mfnwt" ,model_ws=model_ws)
# Lower left corner: (611991.514073899, 8354016.396838)
# Grid angle (in degrees counterclockwise): -24
xll = 611991.514073899
yll = 8354016.396838
epsg = 32718
rotation = -24

mf.modelgrid.set_coord_info(xoff=xll, yoff=yll, angrot=rotation,epsg=2236)
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(1, 1, 1, aspect='equal')
modelmap = flopy.plot.PlotMapView(model=mf)
linecollection = modelmap.plot_grid(linewidth=0.5, color='royalblue')
#import head data
mfheads = flopy.utils.HeadFile('../Model/'+modelname+'.bhd',text='head')
mftimes = mfheads.get_times()
mftimes[:3]
[1.0]
# find shape
head = mfheads.get_data()
shape = head.shape
shape
(5, 138, 75)
#create a array an empty array
drnArray = np.zeros(shape[1:])
drnArray[:] = np.NaN

#fill the values for the water table
for row in range(shape[1]):
    for col in range(shape[2]):
        drnValues = head[:,row,col]
        for value in drnValues:
            if value > 0:
                drnArray[row,col]=value
                break
plt.imshow(drnArray)
<matplotlib.image.AxesImage at 0x1b54ae10970>
#get min and max head for contour levels
headMin = head[head>-1.e+20].min()
headMax = head[head>-1.e+20].max()
print(headMin,headMax)
3431.9033 4439.018
#define contours levels
levels = np.linspace(headMin,headMax,25)
levels
array([3431.90332031, 3473.86643473, 3515.82954915, 3557.79266357,
       3599.75577799, 3641.71889242, 3683.68200684, 3725.64512126,
       3767.60823568, 3809.5713501 , 3851.53446452, 3893.49757894,
       3935.46069336, 3977.42380778, 4019.3869222 , 4061.35003662,
       4103.31315104, 4145.27626546, 4187.23937988, 4229.2024943 ,
       4271.16560872, 4313.12872314, 4355.09183757, 4397.05495199,
       4439.01806641])
# Plot the heads for a defined layer and boundary conditions
fig = plt.figure(figsize=(36, 24))
ax = fig.add_subplot(1, 1, 1, aspect='equal')
modelmap = flopy.plot.PlotMapView(model=mf)
contour = modelmap.contour_array(drnArray,ax=ax, levels=levels)

cellhead = modelmap.plot_array(drnArray,ax=ax, cmap='Blues', alpha=0.2)
ax.clabel(contour)
ax.grid()

plt.tight_layout()
import fiona 

# define schema
schema = {
    'geometry':'LineString',
    'properties':[('waterTable','float')]
}
#open a fiona object
polyShp = fiona.open('../Shps/waterTable_v1.shp', mode='w', driver='ESRI Shapefile',
          schema = schema, crs = "EPSG:32718")

for index, c in enumerate(contour.allsegs):
    try:
    #save record and close shapefile
        tupleList = [(a[0],a[1]) for a in c[0]]
        #print(tupleList)
        rowDict = {
            'geometry' : {'type':'LineString',
                             'coordinates': tupleList}, #Here the xyList is in brackets
            'properties': {'waterTable' : contour.cvalues[index]},
            }
        polyShp.write(rowDict)
    except IndexError:
        pass

#close fiona object
polyShp.close()

Input data

You can download the input data from this link.

—————
TRANSCOM ISPFree Sigma HSE Email
Level 6 Domain Names are FREE – Register Now.

Related Posts

Hydrate

EGU2024

The mountain hydrology team will have full presence at EGU2024. Below you’ll find a list of the primary presentations by our team.

Full programme can be

Boost Inflight Internet- Business Hosting- Secure Email Account- Dropcatch Domain Names- Antisnoop Email- Free Secure Email- Cheap VOIP Calls- Free Hosting and Email- Aero Connectivity- Premium Domains for Sale- Transcom Telecom- Satphone Airtime- Mobile Plans- Free Domain Names- Organic Products- Aviation News
Transcom ISP - Transcom VOIP - Free Secure Email - Dropcatch Software - FastApn Inflight - Aero Connect - Premium Domains