Interactive MODFLOW MT3D transport model visualization with Flopy, Ipywidgets and Voila - Tutorial

contaminantVisualization.jpg

Representation and analysis of flow and transport results is a challenge for groundwater modelers. Aspects such as speed, compatibility, data format and visualization options are key in the 2D/3D representation of head and concentration on model cells. Under the Jupyterlab framework new tools have been developed that can be useful to represent model results on a user friendly way.

This time we have done a tutorial for the interactive representation of a contaminant plume in Jupyterlab; modeling was done with Modflow Nwt and Mt3d, representation was done with Matplolib, Ipywidgets and Voila.

You have two ways to run this code:

  1. From the Hakuchik image for Docker: docker run -it -p 8888:8888 hatarilabs/hakuchik:74a2c9c18727 

  2. Using Anaconda with all the installed libraries

Files and scripts can be downloaded with:

git clone https://github.com/SaulMontoya/interactiveModflowTransportVisualization.git

Animation

contaminantVisualization.gif

Tutorial

Code

This is the complete Python code:

import flopy, os
import numpy as np
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
#get nam list
namList = [x[:-4] for x in os.listdir('../model') if x[-4:]=='.nam']

#get ucn list
ucnList = [x[:-4] for x in os.listdir('../model') if x[-4:]=='.ucn']
#nam dropdown widget
namDrop = widgets.Dropdown(
    options=namList,
    value=namList[0],
    description='Nam file:',
    disabled=False,
    layout=widgets.Layout(width='20%')
)

#nam dropdown widget
ucnDrop = widgets.Dropdown(
    options=ucnList,
    value=ucnList[0],
    description='Conc file:',
    disabled=False,
    layout=widgets.Layout(width='20%')
)

#times dropdown widget
timeBot = widgets.Button(
    description='Show times:',
    disabled=False,
    button_style='success', # 'success', 'info', 'warning', 'danger' or ''
    tooltip='Show available times',
)

#times dropdown widget
timeDrop = widgets.Dropdown(
    options=[0],
    value=0, #ucnList[0],
    description='Times:',
    disabled=False,
    layout=widgets.Layout(width='20%')
)

#plot widget
plotBot = widgets.Button(
    description='Plot conc.',
    disabled=True,
    button_style='success', # 'success', 'info', 'warning', 'danger' or ''
    tooltip='Plot concentrations at specified layer',
)

#plot function
def showLayConc(namFile,ucnFile,timeDrop):
    with out:
        out.clear_output()
        m = flopy.modflow.mf.Modflow.load('../model/'+namFile+'.nam',version='mfnwt')
        fig, ax = plt.subplots(figsize=(12,8))
        #modelmap = m.modelgrid.plot(ax=ax)
        modelmap = flopy.plot.PlotMapView(m,ax=ax)
        ucnFile = flopy.utils.binaryfile.UcnFile('../model/'+ucnFile+'.ucn')
        concArray = ucnFile.get_data(totim=timeDrop)
        concArray[concArray == -1.e+30] = np.nan
        modelmap.plot_array(concArray)
        plt.show()

def listTimes(ucnFile):
    ucnFile = flopy.utils.binaryfile.UcnFile('../model/'+ucnFile+'.ucn')
    return ucnFile.get_times()


#on click function
def plotButtonClicked(b):
    showLayConc(namDrop.value,ucnDrop.value,timeDrop.value)
    #plotBot.disabled = True

#on click function
def timesButtonClicked(b):
    timeDrop.options = listTimes(ucnDrop.value)
    plotBot.disabled = False
    timeBot.disabled = True
    timeBot.button_style = ''

plotBot.on_click(plotButtonClicked)

timeBot.on_click(timesButtonClicked)

display(widgets.HBox([namDrop, ucnDrop, timeBot, timeDrop, plotBot]))

out = widgets.Output()
display(out)
Comment

Saul Montoya

Saul Montoya es Ingeniero Civil graduado de la Pontificia Universidad Católica del Perú en Lima con estudios de postgrado en Manejo e Ingeniería de Recursos Hídricos (Programa WAREM) de la Universidad de Stuttgart con mención en Ingeniería de Aguas Subterráneas y Hidroinformática.

 

Suscribe to our online newsletter

Subscribe for free newsletter, receive news, interesting facts and dates of our courses in water resources.