Ejemplo Básico de Modelamiento con MODFLOW 6 y Visualización con Paraview y Flopy

MODFLOW6BasicExample_IsometricViewWaterTablewithEquipotentialSurfacesandBC.png

Tutorial básico para aprender el procedimiento de construcción, simulación y representación de un modelo hidrogeológico en MODFLOW 6. El tutorial muestra una introducción al sistema de ficheros de un modelo en condiciones de régimen uniforme. El modelo de este tutorial tiene implementado las siguientes condiciones de borde: Drenes, Recarga, y Carga Constante.  La grilla del modelo es regular con un ancho de 50 metros y tiene 30 filas con 24 columnas; el modelo consta de 4 capas y un espesor total de 130 metros.

El modelo es llamado "hatari01" y esta inspirado en el modelo "twri" de la documentación de MODFLOW 2005 adaptado a MODFLOW 6.  Dentro de la conceptualización hidrogeológica se especifica la conductividad hidráulica en el plano horizontal y vertical. Luego de la simulación se ejecuta un script de Python dentro de un Jupyter Notebook para crear archivos VTK de grilla no estructurada para las cargas hidráulicas, napa freática y condiciones de borde como objetos 3D en Paraview.

 

Galería de Fotos

 

Tutorial

 

Datos de Ingreso

Ustedes pueden descargar los datos de ingreso del siguiente enlace.

 

Código

Esta es una parte del código en Python para crear los archivos VTK, el resto de código lo puede ubica en la parte de datos de ingreso de este tutorial.

# # Import packages, read files and create empty dicts

# In[1]:


import os, re
import numpy as np
from workFunctions import workFunctions
from vtkFunctions import vtkFunctions  
from transFunctions import transFunctions
from listFunctions import listFunctions


# In[2]:


#open the DIS, BAS and FHD and DRN files
chdLines  = open('../model/hatari01.chd').readlines()
disLines  = open('../model/hatari01.dis').readlines()
drnLines  = open('../model/hatari01.drn').readlines() 
icLines   = open('../model/hatari01.ic').readlines()
npfLines  = open('../model/hatari01.npf').readlines()            
rchLines  = open('../model/hatari01.rch').readlines()         
welLines  = open('../model/hatari01.wel').readlines()             


# In[3]:


#create a empty dictionay to store the model features
modChd  = {}
modDis  = {}
modDrn  = {}
modIc   = {}
modNpf  = {}
modRch  = {}
modWel  = {}
modHds  = {}


# <br/>
# <br/>
# <br/>
# ___
# 
# # Working with the DIS (Discretization Data) data

# ### General model features as modDis dict

# In[4]:


########################
### General model features as modDis dict
#get the number of layers, rows, columns, cell and vertex numbers
for line in disLines:
    if 'NLAY' in line:
        modDis['cellLays'] = int(line.split()[1])
    elif 'NROW' in line:
        modDis['cellRows'] = int(line.split()[1])
    elif 'NCOL' in line:
        modDis['cellCols'] = int(line.split()[1])
        
modDis["vertexLays"] = modDis["cellLays"] + 1
modDis["vertexRows"] = modDis["cellRows"] + 1
modDis["vertexCols"] = modDis["cellCols"] + 1
modDis["vertexPerLay"] = modDis["vertexRows"] * modDis["vertexCols"]
modDis["cellsPerLay"] = modDis["cellRows"] * modDis["cellCols"]

########################
### Get the DIS Breakers
modDis['DELRArray1D'] = workFunctions.getListFromDel('DELR',modDis,disLines)
modDis['DELCArray1D'] = workFunctions.getListFromDel('DELC',modDis,disLines)

modDis['cellZVertexGrid']={}
modDis['cellZVertexGrid']['lay0']=workFunctions.getUniLayerListFromTerm(modDis,disLines,'TOP').reshape(modDis['cellRows'],modDis['cellCols'])

listFromBottom = workFunctions.getListinDictxLayFromGriddataLayered(modDis,disLines,'BOTM',modDis)
#i = 0
for lay in range(1,modDis['vertexLays']):
    modDis['cellZVertexGrid']['lay'+str(lay)]=np.asarray(listFromBottom['lay'+str(lay-1)]).reshape(modDis['cellRows'],modDis['cellCols'])
#    i+=1
    
########################
### Geolocation model data
modDis["vertexXmin"]=0
modDis["vertexYmin"]=0
modDis["vertexXmax"]=sum(modDis['DELRArray1D'])
modDis["vertexYmax"]=sum(modDis['DELCArray1D'])

########################
### List of arrays of cells and vertex coord
modDis['vertexEastingArray1D']  = np.array([modDis['vertexXmin']+np.sum(modDis['DELRArray1D'][:col]) for col in range(modDis['vertexCols'])])
modDis['vertexNorthingArray1D'] = np.array([modDis['vertexYmax']-np.sum(modDis['DELCArray1D'][:row]) for row in range(modDis['vertexRows'])])

modDis['cellEastingArray1D']    = np.array([modDis['vertexXmin']+np.sum(modDis['DELRArray1D'][:col])+modDis['DELRArray1D'][col]/2 for col in range(modDis['cellCols'])])
modDis['cellNorthingArray1D']   = np.array([modDis['vertexYmax']-np.sum(modDis['DELCArray1D'][:row])-modDis['DELCArray1D'][row]/2 for row in range(modDis['cellRows'])])

########################
### Grid of XYZ Vertex Coordinates
modDis['vertexXGrid'] = np.repeat(modDis['vertexEastingArray1D'].reshape(modDis['vertexCols'],1),modDis['vertexRows'],axis=1).T
modDis['vertexYGrid'] = np.repeat(modDis['vertexNorthingArray1D'],modDis['vertexCols']).reshape(modDis['vertexRows'],modDis['vertexCols'])
modDis['vertexZGrid'] = transFunctions.interpolateCelltoVertex(modDis,'cellZVertexGrid')


# <br/>
# <br/>
# <br/>
# ___
# 
# # Get the Info for Boundary Conditions and Cell Heads

# In[5]:


# Get the NPF Info
modNpf['iCellTypeList'] = workFunctions.getListinDictxLayFromGriddataLayered(modNpf,npfLines,'ICELLTYPE',modDis)
modNpf['kList'] = workFunctions.getListinDictxLayFromGriddataLayered(modNpf,npfLines,'k LAYERED',modDis)
modNpf['K33List'] = workFunctions.getListinDictxLayFromGriddataLayered(modNpf,npfLines,'K33 LAYERED',modDis)

# Get the IC Info
modIc['strtList'] = workFunctions.getListinDictxLayFromGriddataLayered(modIc,icLines,'STRT',modDis)

# Get the DRN Info
modDrn['maxBound'] = workFunctions.getTermFromKeyword(drnLines,'MAXBOUND','DIMENSIONS')
modDrn['drnCells'] = workFunctions.getCellsforBoundary(drnLines,'drn',modDrn['maxBound'],1)

# Get the CHD Info
modChd['maxBound'] = workFunctions.getTermFromKeyword(chdLines,'MAXBOUND','DIMENSIONS')
modChd['chdCells'] = workFunctions.getCellsforBoundary(chdLines,'chd',modChd['maxBound'],1)

# Get the RCH Info
modRch['rchCellList'] = workFunctions.getUniLayerListFromTerm(modDis,rchLines,'RECHARGE')

# Get the WEL Info
modWel['maxBound'] = workFunctions.getTermFromKeyword(welLines,'MAXBOUND','DIMENSIONS')
modWel['welCells'] = workFunctions.getCellsforBoundary(welLines,'wel',modWel['maxBound'],1)

# Get the HDS info
### Store heads per lay
import flopy.utils.binaryfile as bf
modHds['cellHeadGrid'] = {}

headObject = bf.HeadFile('..\\model\\hatari01.hds', precision='double')
headObjectList = headObject.get_data()
headObject.close()

for lay in range(modDis['cellLays']):
    modHds['cellHeadGrid']['lay'+str(lay)] = headObjectList[lay]
    
vertexHeadGridCentroid = transFunctions.vertexHeadGridCentroidFunction(modDis,modHds)
modHds['vertexHeadGrid'] = transFunctions.vertexHeadGridFunction(vertexHeadGridCentroid,modDis,modHds)


# <br/>
# <br/>
# <br/>
# ___
# 
# # VTK file of Model Geometry, Model Results and Boundary Conditions
# 

# ## Point Data

# In[6]:


### Vertex Heads
listVertexHead = listFunctions.listCellHeadsFunction('vertexLays','vertexHeadGrid',modDis,modHds)

### Water Tables Vextex
listWaterTableVertex = listFunctions.listWaterTableVertexFunction(modDis,modHds)


# ## Point Definition

# In[7]:


### Definition of XYZ points for All Vertex
vertexXYZPoints = listFunctions.vertexXYZPointsFunction(modDis)

### Definition of XYZ points for Water Table
vertexWaterTableXYZPoints = listFunctions.vertexWaterTableXYZPointsFunction(listWaterTableVertex,modDis)


# ## Quad and Hexa Sequences

# In[8]:


### List of Layer Quad Sequences (Works only for a single layer)
listLayerQuadSequence = listFunctions.listLayerQuadSequenceFunction(modDis)

### List of Hexa Sequences for All Cells
listHexaSequence = listFunctions.listHexaSequenceFunction(modDis)

### List of Hexa Sequences for DRN Cells
listDrnCellsHexaSecuence = listFunctions.bcCellsListFunction(modDrn,'drnCells',listHexaSequence,modDis)[1]

### List of Hexa Sequences for CHD Cells
listChdCellsHexaSecuence = listFunctions.bcCellsListFunction(modChd,'chdCells',listHexaSequence,modDis)[1]

### List of Hexa Sequences for wEL Cells
listWelCellsHexaSecuence = listFunctions.bcCellsListFunction(modWel,'welCells',listHexaSequence,modDis)[1]


# ## Cell Data

# In[9]:


### Definition of cellHead
listCellHead = listFunctions.listCellHeadsFunction('cellLays','cellHeadGrid',modDis,modHds)

### Definition of DRN cells values '1' as List
listDrnCellsIO = listFunctions.bcCellsListFunction(modDrn,'drnCells',listHexaSequence,modDis)[0]

### Definition of CHD cells values '1' as List
listChdCellsIO = listFunctions.bcCellsListFunction(modChd,'chdCells',listHexaSequence,modDis)[0]

### Definition of WEL cells values '1' as List
listWelCellsIO = listFunctions.bcCellsListFunction(modWel,'welCells',listHexaSequence,modDis)[0]

### Water Tables on Cell
listWaterTableCell = listFunctions.listWaterTableCellFunction(modDis,modHds)


# <br/>
# <br/>
# <br/>
# ___
# 
# # VTK Creation

# ## Heads on Vertex and Cells VTK

# In[10]:


vtkText = open('../vtuFiles/hatari01_Heads.vtu','w')

vtkFunctions.printHeader(vtkText,len(vertexXYZPoints),len(listHexaSequence))

vtkFunctions.printPointData(vtkText,'VertexHeads',listVertexHead)

vtkFunctions.printCellData(vtkText,'CellHeads',listCellHead)

vtkFunctions.printPointDefinition(vtkText,vertexXYZPoints)

vtkFunctions.printCellHexaConnectivityOffsetType(vtkText,listHexaSequence)

vtkFunctions.printFooter(vtkText)

vtkText.close()


# ## Water Table VTK

# In[11]:


vtkText = open('../vtuFiles/hatari01_WaterTable.vtu','w')

vtkFunctions.printHeader(vtkText,len(vertexWaterTableXYZPoints),len(listWaterTableCell))

vtkFunctions.printCellData(vtkText,'WaterTableElev',listWaterTableCell)

vtkFunctions.printPointDefinition(vtkText,vertexWaterTableXYZPoints)

vtkFunctions.printCellQuadConnectivityOffsetType(vtkText,listLayerQuadSequence)

vtkFunctions.printFooter(vtkText)

vtkText.close()


# ## DRN Package VTK

# In[12]:


vtkText = open('../vtuFiles/hatari01_DRNCells.vtu','w')

vtkFunctions.printHeader(vtkText,len(vertexXYZPoints),len(listDrnCellsHexaSecuence))

vtkFunctions.printCellData(vtkText,'DRNCells',listDrnCellsIO)

vtkFunctions.printPointDefinition(vtkText,vertexXYZPoints)

vtkFunctions.printCellHexaConnectivityOffsetType(vtkText,listDrnCellsHexaSecuence)

vtkFunctions.printFooter(vtkText)

vtkText.close()


# ## CHD Package VTK

# In[13]:


vtkText = open('../vtuFiles/hatari01_CHDCells.vtu','w')

vtkFunctions.printHeader(vtkText,len(vertexXYZPoints),len(listChdCellsHexaSecuence))

vtkFunctions.printCellData(vtkText,'CHDCells',listChdCellsIO)

vtkFunctions.printPointDefinition(vtkText,vertexXYZPoints)

vtkFunctions.printCellHexaConnectivityOffsetType(vtkText,listChdCellsHexaSecuence)

vtkFunctions.printFooter(vtkText)

vtkText.close()


# ## WEL Package VTK

# In[14]:


vtkText = open('../vtuFiles/hatari01_WELCells.vtu','w')

vtkFunctions.printHeader(vtkText,len(vertexXYZPoints),len(listWelCellsHexaSecuence))

vtkFunctions.printCellData(vtkText,'WELCells',listWelCellsIO)

vtkFunctions.printPointDefinition(vtkText,vertexXYZPoints)

vtkFunctions.printCellHexaConnectivityOffsetType(vtkText,listWelCellsHexaSecuence)

vtkFunctions.printFooter(vtkText)

vtkText.close()
Smiley face

Suscríbase a nuestro boletín gratuito para recibir noticias, datos interesantes y fechas de nuestros cursos en recursos hídricos.

Posted on February 1, 2018 and filed under TutorialModflow, TutorialPython.