Note
MODFLOW 6: Working with MODFLOW Grid Array Data
This tutorial shows how to view, access, and change the underlying data variables for MODFLOW 6 objects in FloPy. Interaction with a FloPy MODFLOW 6 model is different from other models, such as MODFLOW-2005, MT3D, and SEAWAT, for example.
FloPy stores model data in data objects (MFDataArray
, MFDataList
, MFDataScalar
objects) that are accessible from packages. Data can be added to a package by using the appropriate parameters when the package is constructed and through package attributes.
The MODFLOW 6 simulation structure is arranged in the following generalized way:
Simulation --> Package --> DATA Simulation --> Model --> Package (--> Package) --> DATA
This tutorial focuses on MODFLOW grid array data from the GridData
and other similar blocks. These blocks contain data in a one or more dimensional array format organized by dimensions, which can include layer, row, column, and stress period. These data are stored by FloPy in a MFArray
or MFTransientArray
object and a referred to as array data.
Introduction to MODFLOW Array Data
MODFLOW array data use the MFArray
or MFTransientArray
FloPy classes and are stored in numpy ndarrays. Most MODFLOW array data are two (row, column) or three (layer, row, column) dimensional and represent data on the model grid. Other MODFLOW array data contain data by stress period. The following list summarizes the different types of MODFLOW array data.
Time-invariant multi-dimensional array data. This includes:
One and two dimensional arrays that do not have a layer dimension. Examples include
top
,delc
, anddelr
.Three dimensional arrays that can contain a layer dimension. Examples include
botm
,idomain
, andk
.
Transient arrays that can change with time and therefore contain arrays of data for one or more stress periods. Examples include
irch
andrecharge
in theRCHA
package.
In the example below a three dimensional ndarray is constructed for the DIS
package’s botm
array. First, the a simulation and groundwater-flow model are set up.
[1]:
# package import
import os
from pathlib import Path
from tempfile import TemporaryDirectory
[2]:
import numpy as np
[3]:
import flopy
[4]:
# set up where simulation workspace will be stored
temp_dir = TemporaryDirectory()
workspace = temp_dir.name
name = "tutorial07_mf6_data"
[5]:
# create the FloPy simulation and tdis objects
sim = flopy.mf6.MFSimulation(
sim_name=name, exe_name="mf6", version="mf6", sim_ws=workspace
)
tdis = flopy.mf6.modflow.mftdis.ModflowTdis(
sim,
pname="tdis",
time_units="DAYS",
nper=2,
perioddata=[(1.0, 1, 1.0), (1.0, 1, 1.0)],
)
# create the Flopy groundwater flow (gwf) model object
model_nam_file = f"{name}.nam"
gwf = flopy.mf6.ModflowGwf(sim, modelname=name, model_nam_file=model_nam_file)
# create the flopy iterative model solver (ims) package object
ims = flopy.mf6.modflow.mfims.ModflowIms(sim, pname="ims", complexity="SIMPLE")
Then a three-dimensional ndarray of floating point values is created using numpy’s linspace
method.
[6]:
bot = np.linspace(-50.0 / 3.0, -3.0, 3)
delrow = delcol = 4.0
The DIS
package is then created passing the three-dimensional array to the botm
parameter. The botm
array defines the model’s cell bottom elevations.
[7]:
dis = flopy.mf6.modflow.mfgwfdis.ModflowGwfdis(
gwf,
pname="dis",
nogrb=True,
nlay=3,
nrow=10,
ncol=10,
delr=delrow,
delc=delcol,
top=0.0,
botm=bot,
)
Adding MODFLOW Grid Array Data
MODFLOW grid array data, like the data found in the NPF
package’s GridData
block, can be specified as:
A constant value
A n-dimensional list
A numpy ndarray
Additionally, layered grid data (generally arrays with a layer dimension) can be specified by layer.
In the example below icelltype
is specified as constants by layer, k
is specified as a numpy ndarray, k22
is specified as an array by layer, and k33
is specified as a constant.
First k
is set up as a 3 layer, by 10 row, by 10 column array with all values set to 10.0 using numpy’s full method.
[8]:
k = np.full((3, 10, 10), 10.0)
Next k22
is set up as a three dimensional list of nested lists. This option can be useful for those that are familiar with python lists but are not familiar with the numpy library.
[9]:
k22_row = []
for row in range(0, 10):
k22_row.append(8.0)
k22_layer = []
for col in range(0, 10):
k22_layer.append(k22_row)
k22 = [k22_layer, k22_layer, k22_layer]
K33
is set up as a single constant value. Whenever an array has all the same values the easiest and most efficient way to set it up is as a constant value. Constant values also take less space to store.
[10]:
k33 = 1.0
The k
, k22
, and k33
values defined above are then passed in on construction of the npf package.
[11]:
npf = flopy.mf6.ModflowGwfnpf(
gwf,
pname="npf",
save_flows=True,
icelltype=[1, 1, 1],
k=k,
k22=k22,
k33=k33,
xt3doptions="xt3d rhs",
rewet_record="REWET WETFCT 1.0 IWETIT 1 IHDWET 0",
)
<flopy.mf6.data.mfstructure.MFDataItemStructure object at 0x7f780a30b190>
<flopy.mf6.data.mfstructure.MFDataItemStructure object at 0x7f780a30b1c0>
Layered Data
When we look at what will be written to the npf input file, we see that the entire npf.k22
array is written as one long array with the number of values equal to nlay
* nrow
* ncol
. And this whole-array specification may be of use in some cases. Often times, however, it is easier to work with each layer separately. An MFArray
object, such as npf.k22
can be converted to a layered array as follows.
[12]:
npf.k22.make_layered()
By changing npf.k22
to layered, we are then able to manage each layer separately. Before doing so, however, we need to pass in data that can be separated into three layers. An array of the correct size is one option.
[13]:
shp = npf.k22.array.shape
a = np.arange(shp[0] * shp[1] * shp[2]).reshape(shp)
npf.k22.set_data(a)
Now that npf.k22
has been set to be layered, if we print information about it, we see that each layer is stored separately, however, npf.k22.array
will still return a full three-dimensional array.
[14]:
print(type(npf.k22))
print(npf.k22)
<class 'flopy.mf6.data.mfdataarray.MFArray'>
Layer_1{internal}
([[ 0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[50 51 52 53 54 55 56 57 58 59]
[60 61 62 63 64 65 66 67 68 69]
[70 71 72 73 74 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]])
Layer_2{internal}
([[100 101 102 103 104 105 106 107 108 109]
[110 111 112 113 114 115 116 117 118 119]
[120 121 122 123 124 125 126 127 128 129]
[130 131 132 133 134 135 136 137 138 139]
[140 141 142 143 144 145 146 147 148 149]
[150 151 152 153 154 155 156 157 158 159]
[160 161 162 163 164 165 166 167 168 169]
[170 171 172 173 174 175 176 177 178 179]
[180 181 182 183 184 185 186 187 188 189]
[190 191 192 193 194 195 196 197 198 199]])
Layer_3{internal}
([[200 201 202 203 204 205 206 207 208 209]
[210 211 212 213 214 215 216 217 218 219]
[220 221 222 223 224 225 226 227 228 229]
[230 231 232 233 234 235 236 237 238 239]
[240 241 242 243 244 245 246 247 248 249]
[250 251 252 253 254 255 256 257 258 259]
[260 261 262 263 264 265 266 267 268 269]
[270 271 272 273 274 275 276 277 278 279]
[280 281 282 283 284 285 286 287 288 289]
[290 291 292 293 294 295 296 297 298 299]])
We also see that each layer is printed separately to the npf Package input file, and that the LAYERED keyword is activated:
[15]:
print(npf.k22.get_file_entry())
k22 LAYERED
INTERNAL FACTOR 1.0
0.00000000 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000 6.00000000 7.00000000 8.00000000 9.00000000
10.00000000 11.00000000 12.00000000 13.00000000 14.00000000 15.00000000 16.00000000 17.00000000 18.00000000 19.00000000
20.00000000 21.00000000 22.00000000 23.00000000 24.00000000 25.00000000 26.00000000 27.00000000 28.00000000 29.00000000
30.00000000 31.00000000 32.00000000 33.00000000 34.00000000 35.00000000 36.00000000 37.00000000 38.00000000 39.00000000
40.00000000 41.00000000 42.00000000 43.00000000 44.00000000 45.00000000 46.00000000 47.00000000 48.00000000 49.00000000
50.00000000 51.00000000 52.00000000 53.00000000 54.00000000 55.00000000 56.00000000 57.00000000 58.00000000 59.00000000
60.00000000 61.00000000 62.00000000 63.00000000 64.00000000 65.00000000 66.00000000 67.00000000 68.00000000 69.00000000
70.00000000 71.00000000 72.00000000 73.00000000 74.00000000 75.00000000 76.00000000 77.00000000 78.00000000 79.00000000
80.00000000 81.00000000 82.00000000 83.00000000 84.00000000 85.00000000 86.00000000 87.00000000 88.00000000 89.00000000
90.00000000 91.00000000 92.00000000 93.00000000 94.00000000 95.00000000 96.00000000 97.00000000 98.00000000 99.00000000
INTERNAL FACTOR 1.0
100.00000000 101.00000000 102.00000000 103.00000000 104.00000000 105.00000000 106.00000000 107.00000000 108.00000000 109.00000000
110.00000000 111.00000000 112.00000000 113.00000000 114.00000000 115.00000000 116.00000000 117.00000000 118.00000000 119.00000000
120.00000000 121.00000000 122.00000000 123.00000000 124.00000000 125.00000000 126.00000000 127.00000000 128.00000000 129.00000000
130.00000000 131.00000000 132.00000000 133.00000000 134.00000000 135.00000000 136.00000000 137.00000000 138.00000000 139.00000000
140.00000000 141.00000000 142.00000000 143.00000000 144.00000000 145.00000000 146.00000000 147.00000000 148.00000000 149.00000000
150.00000000 151.00000000 152.00000000 153.00000000 154.00000000 155.00000000 156.00000000 157.00000000 158.00000000 159.00000000
160.00000000 161.00000000 162.00000000 163.00000000 164.00000000 165.00000000 166.00000000 167.00000000 168.00000000 169.00000000
170.00000000 171.00000000 172.00000000 173.00000000 174.00000000 175.00000000 176.00000000 177.00000000 178.00000000 179.00000000
180.00000000 181.00000000 182.00000000 183.00000000 184.00000000 185.00000000 186.00000000 187.00000000 188.00000000 189.00000000
190.00000000 191.00000000 192.00000000 193.00000000 194.00000000 195.00000000 196.00000000 197.00000000 198.00000000 199.00000000
INTERNAL FACTOR 1.0
200.00000000 201.00000000 202.00000000 203.00000000 204.00000000 205.00000000 206.00000000 207.00000000 208.00000000 209.00000000
210.00000000 211.00000000 212.00000000 213.00000000 214.00000000 215.00000000 216.00000000 217.00000000 218.00000000 219.00000000
220.00000000 221.00000000 222.00000000 223.00000000 224.00000000 225.00000000 226.00000000 227.00000000 228.00000000 229.00000000
230.00000000 231.00000000 232.00000000 233.00000000 234.00000000 235.00000000 236.00000000 237.00000000 238.00000000 239.00000000
240.00000000 241.00000000 242.00000000 243.00000000 244.00000000 245.00000000 246.00000000 247.00000000 248.00000000 249.00000000
250.00000000 251.00000000 252.00000000 253.00000000 254.00000000 255.00000000 256.00000000 257.00000000 258.00000000 259.00000000
260.00000000 261.00000000 262.00000000 263.00000000 264.00000000 265.00000000 266.00000000 267.00000000 268.00000000 269.00000000
270.00000000 271.00000000 272.00000000 273.00000000 274.00000000 275.00000000 276.00000000 277.00000000 278.00000000 279.00000000
280.00000000 281.00000000 282.00000000 283.00000000 284.00000000 285.00000000 286.00000000 287.00000000 288.00000000 289.00000000
290.00000000 291.00000000 292.00000000 293.00000000 294.00000000 295.00000000 296.00000000 297.00000000 298.00000000 299.00000000
Working with a layered array provides lots of flexibility. For example, constants can be set for some layers, but arrays for others:
[16]:
npf.k22.set_data([1, a[2], 200])
print(npf.k22.get_file_entry())
k22 LAYERED
CONSTANT 1.00000000
INTERNAL FACTOR 1.0
200.00000000 201.00000000 202.00000000 203.00000000 204.00000000 205.00000000 206.00000000 207.00000000 208.00000000 209.00000000
210.00000000 211.00000000 212.00000000 213.00000000 214.00000000 215.00000000 216.00000000 217.00000000 218.00000000 219.00000000
220.00000000 221.00000000 222.00000000 223.00000000 224.00000000 225.00000000 226.00000000 227.00000000 228.00000000 229.00000000
230.00000000 231.00000000 232.00000000 233.00000000 234.00000000 235.00000000 236.00000000 237.00000000 238.00000000 239.00000000
240.00000000 241.00000000 242.00000000 243.00000000 244.00000000 245.00000000 246.00000000 247.00000000 248.00000000 249.00000000
250.00000000 251.00000000 252.00000000 253.00000000 254.00000000 255.00000000 256.00000000 257.00000000 258.00000000 259.00000000
260.00000000 261.00000000 262.00000000 263.00000000 264.00000000 265.00000000 266.00000000 267.00000000 268.00000000 269.00000000
270.00000000 271.00000000 272.00000000 273.00000000 274.00000000 275.00000000 276.00000000 277.00000000 278.00000000 279.00000000
280.00000000 281.00000000 282.00000000 283.00000000 284.00000000 285.00000000 286.00000000 287.00000000 288.00000000 289.00000000
290.00000000 291.00000000 292.00000000 293.00000000 294.00000000 295.00000000 296.00000000 297.00000000 298.00000000 299.00000000
CONSTANT 200.00000000
To gain full control over an individual layers, layer information can be provided as a dictionary:
[17]:
a0 = {"factor": 0.5, "iprn": 1, "data": 100 * np.ones((10, 10))}
a1 = 50
a2 = {"factor": 1.0, "iprn": 14, "data": 30 * np.ones((10, 10))}
npf.k22.set_data([a0, a1, a2])
print(npf.k22.get_file_entry())
k22 LAYERED
INTERNAL FACTOR 0.5 IPRN 1
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000 100.00000000
CONSTANT 50.00000000
INTERNAL FACTOR 1.0 IPRN 14
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000 30.00000000
Here we say that the FACTOR has been set to 0.5 for the first layer and an alternative print flag is set for the last layer.
Because we are specifying a factor for the top layer, we can also see that the get_data()
method returns the array without the factor applied
[18]:
print(npf.k22.get_data())
[[[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]
[100. 100. 100. 100. 100. 100. 100. 100. 100. 100.]]
[[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[ 50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]]
[[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[ 30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]]]
whereas the array
property returns the array with the factor applied
[19]:
print(npf.k22.array)
[[[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]]
[[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]
[50. 50. 50. 50. 50. 50. 50. 50. 50. 50.]]
[[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]
[30. 30. 30. 30. 30. 30. 30. 30. 30. 30.]]]
Adding MODFLOW Stress Period Array Data
Transient array data spanning multiple stress periods must be specified as a dictionary of arrays, where the dictionary key is the stress period, expressed as a zero-based integer, and the dictionary value is the grid data for that stress period.
In the following example a RCHA
package is created. First a dictionary is created that contains recharge for the model’s two stress periods. Recharge is specified as a constant value in this example, though it could also be specified as a 3-dimensional ndarray or list of lists.
[20]:
rch_sp1 = 0.01
rch_sp2 = 0.03
rch_spd = {0: rch_sp1, 1: rch_sp2}
The RCHA
package is created and the dictionary constructed above is passed in as the recharge
parameter.
[21]:
rch = flopy.mf6.ModflowGwfrcha(
gwf, readasarrays=True, pname="rch", print_input=True, recharge=rch_spd
)
Retrieving Grid Array Data
Grid data can be retrieved with get_data
, array
, []
, repr
/str
, or get_file_entry
.
Retrieval Method |
Description |
---|---|
get_data |
Returns ndarray of data without multiplier applied, unless the apply_mult parameter is set to True |
array |
Returns ndarray of data with multiplier applied |
[] |
Returns a particular layer of data if data is layered, otherwise is an array index |
repr/str |
Returns string with storage information followed by ndarray repr/str |
get_file_entry(layer) |
Returns string containing data formatted for the MODFLOW-6 package file. If layer is not specified returns all layers, otherwise returns just the layer specified. |
Below the NPF
k
array is retrieved using the various methods highlighted above.
First, we use the get_data
method to get k as an ndarray.
[22]:
print(npf.k.get_data())
[[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]
[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]
[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]]
Next, we use the array
attribute which also gets k as an ndarray.
[23]:
print(npf.k.array)
[[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]
[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]
[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]]
We can also use the []
to get a single layer of data as an ndarray.
[24]:
print(npf.k[0])
[[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]]
repr gives a string representation of the data.
[25]:
print(repr(npf.k))
Layer_1{internal}
(array([[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.]]))
Layer_2{internal}
(array([[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.]]))
Layer_3{internal}
(array([[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.],
[10., 10., 10., 10., 10., 10., 10., 10., 10., 10.]]))
str gives a similar string representation of the data.
[26]:
print(str(npf.k))
Layer_1{internal}
([[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]])
Layer_2{internal}
([[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]])
Layer_3{internal}
([[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10. 10. 10. 10. 10. 10.]])
The method get_file_entry
prints the data as it would appear in a MODFLOW 6 file.
[27]:
print(npf.k.get_file_entry())
k LAYERED
INTERNAL FACTOR 1.0
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
INTERNAL FACTOR 1.0
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
INTERNAL FACTOR 1.0
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000 10.00000000
Retrieving MODFLOW Stress Period Array Data
Transient array data can be retrieved with get_data
, array
, repr
/str
, or get_file_entry
.
Retrieval Method |
Description |
---|---|
get_data |
Returns dictionary of ndarrays without multiplier applied. The dictionary key is the stress period as a zero-based integer. |
array |
Returns ndarray of data for all stress periods (stress period is an added dimension) |
repr/str |
Returns string with storage information followed by ndarray repr/str for all stress periods |
get_file_entry(layer) |
Returns string containing data formatted for the MODFLOW-6 package file. Use to specify a stress period (zero-based integer). |
Below the RCHA
recharge
array is retrieved using the various methods highlighted above.
First, we use the get_data
method to get the recharge data as a dictionary of ndarrays. The dictionary key is a the stress period (zero based).
[28]:
print(rch.recharge.get_data())
{0: array([[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01],
[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]]), 1: array([[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03],
[0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03]])}
Next, we use the array
attribute to get the data as an 4-dimensional ndarray.
[29]:
print(rch.recharge.array)
[[[[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]
[0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]]]
[[[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]
[0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03 0.03]]]]
repr gives a string representation of the data.
[30]:
print(repr(rch.recharge))
{constant 0.03}
str gives a similar representation of the data.
[31]:
print(str(rch.recharge))
{constant 0.03}
We can use the get_file_entry
method to get the data as it would appear in a MODFLOW 6 file for a specific stress period. In this case we are getting the data for stress period 2 (stress periods are treated as 0-based in FloPy).
[32]:
print(rch.recharge.get_file_entry(1))
recharge
CONSTANT 0.03000000
[33]:
try:
temp_dir.cleanup()
except PermissionError:
# can occur on windows: https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryDirectory
pass