Skip to content

Commit b0b803c

Browse files
mjrenomjreno
authored andcommitted
remove second tutorial for now
1 parent 6998e38 commit b0b803c

File tree

3 files changed

+131
-457
lines changed

3 files changed

+131
-457
lines changed

.docs/Notebooks/netcdf01_tutorial.py

Lines changed: 129 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
# ---
2+
# jupyter:
3+
# jupytext:
4+
# cell_metadata_filter: -all
5+
# formats: ipynb,py:light
6+
# text_representation:
7+
# extension: .py
8+
# format_name: light
9+
# format_version: '1.5'
10+
# jupytext_version: 1.17.2
11+
# kernelspec:
12+
# display_name: Python 3
13+
# language: python
14+
# name: python3
15+
# metadata:
16+
# section: mf6
17+
# ---
18+
19+
# # MODFLOW 6: Generate MODFLOW 6 NetCDF input from existing FloPy sim
20+
#
21+
# ## NetCDF tutorial 1: MODFLOW 6 structured input file
22+
#
23+
# This tutorial demonstrates how to generate a MODFLOW 6 NetCDF file from
24+
# an existing FloPy simulation. In the tutorial, candidate array data is
25+
# added to an xarray dataset and annotated so that the generated NetCDF
26+
# file can be read by MODFLOW 6 as model input.
27+
#
28+
# This tutorial generates a structured NetCDF variant - for more information
29+
# on supported MODFLOW 6 NetCDF formats see:
30+
# [MODFLOW NetCDF Format](https://github.com/MODFLOW-ORG/modflow6/wiki/MODFLOW-NetCDF-Format).
31+
#
32+
# Note that NetCDF is only supported by the Extended version of MODFLOW 6.
33+
# A nightly windows build of Extended MODFLOW 6 is available from
34+
# [nightly build](https://github.com/MODFLOW-ORG/modflow6-nightly-build).
35+
36+
# package import
137
import sys
238
from pathlib import Path
339
from pprint import pformat, pprint
@@ -11,11 +47,29 @@
1147
print(sys.version)
1248
print(f"flopy version: {flopy.__version__}")
1349

50+
# ## Define DNODATA constant
51+
#
52+
# DNODATA is an important constant for MODFLOW 6 timeseries grid input
53+
# data. It signifies that the cell has no data defined for the time step
54+
# in question. These cell values are discared and have no impact on the
55+
# simulation.
56+
57+
# DNODATA constant
1458
DNODATA = 3.0e30
1559

60+
# ## Define ASCII input baseline simulation
61+
#
62+
# For the purposes of this tutorial, the specifics of this simulation
63+
# other than it is a candidate for NetCDF input are not a focus. It
64+
# is a NetCDF input candidate because it defines a candidate model type
65+
# (GWF6) with packages that support NetCDF input parameters.
66+
#
67+
# A NetCDF dataset will be created from array data in the DIS, NPF and
68+
# GHBG packages. Data will be copied from the package objects into dataset
69+
# arrays.
70+
1671

17-
# A FloPy simulation ASCII sim that will be updated
18-
# use netcdf inputs
72+
# A FloPy ASCII base simulation that will be updated use netcdf inputs
1973
def create_sim(ws):
2074
name = "uzf01"
2175
perlen = [500.0]
@@ -187,8 +241,16 @@ def create_sim(ws):
187241
return sim
188242

189243

190-
# A subroutine that can update an xarray dataset
191-
# with package netcdf information stored in a dict
244+
# ## Create helper function to update dataset
245+
#
246+
# This function updates an Xarray dataset to add variables described
247+
# in a FloPy provided dictionary.
248+
#
249+
# A dimension map variable relates FloPy and NetCDF dimensions names.
250+
251+
252+
# A subroutine that can update an xarray dataset with package
253+
# netcdf information stored in a dict
192254
def add_netcdf_vars(dataset, nc_info, dimmap):
193255
def _data_shape(shape):
194256
dims_l = []
@@ -223,14 +285,25 @@ def _data_shape(shape):
223285
assert success, pformat(buff)
224286

225287
# create directory for netcdf sim
288+
# set model name file nc_filerecord attribute to export name
226289
sim.set_sim_path(workspace / "netcdf")
227290
gwf = sim.get_model("uzf01")
228291
gwf.name_file.nc_filerecord = "uzf01.structured.nc"
229292
sim.write_simulation()
230293

231-
# create the netcdf dataset
294+
# create the dataset
232295
ds = xr.Dataset()
233296

297+
# ## Access model NetCDF attributes
298+
#
299+
# Access model scoped NetCDF details by storing the dictionary
300+
# returned from netcdf_info(). In particular, we need to set dataset
301+
# scoped attributes that are stored in the model netcdf info dict.
302+
#
303+
# First, retrieve and store the netcdf info dictionary and display
304+
# its contents. Then, in the following step, update the dataset with
305+
# the model scoped attributes defined in the dictionary.
306+
234307
# get model netcdf info
235308
nc_info = gwf.netcdf_info()
236309
pprint(nc_info)
@@ -239,7 +312,7 @@ def _data_shape(shape):
239312
for a in nc_info["attrs"]:
240313
ds.attrs[a] = nc_info["attrs"][a]
241314

242-
# set dimensional info
315+
# define dimensional info
243316
dis = gwf.modelgrid
244317
xoff = dis.xoffset
245318
yoff = dis.yoffset
@@ -253,26 +326,53 @@ def _data_shape(shape):
253326
ncol = dis.ncol
254327
dimmap = {"time": nstp, "z": nlay, "y": nrow, "x": ncol}
255328

256-
# create coordinate vars
329+
# create dataset coordinate vars
257330
var_d = {"time": (["time"], time), "z": (["z"], z), "y": (["y"], y), "x": (["x"], x)}
258331
ds = ds.assign(var_d)
259332

260-
# dis
333+
# ## Access package NetCDF attributes
334+
#
335+
# Access package scoped NetCDF details by storing the dictionary returned
336+
# from netcdf_info(). We need to set package variable attributes that are
337+
# stored in the package netcdf info dict, but we also need other information
338+
# that is relevant to creating the variables themselves.
339+
#
340+
# The contents of the info dictionary are shown and then, in the following
341+
# step, the dictionary and the dataset are passed to a helper routine that
342+
# create the intended array variables.
343+
344+
# get dis package netcdf info
261345
dis = gwf.get_package("dis")
262346
nc_info = dis.netcdf_info()
263347
pprint(nc_info)
264348

265349
# create dis dataset variables
266350
ds = add_netcdf_vars(ds, nc_info, dimmap)
267351

268-
# update data
352+
# ## Update array data
353+
#
354+
# We have created dataset array variables for the package but they do not yet
355+
# define the expected input data for MODFLOW 6. We will take advantage of the
356+
# existing simulation objects and update the dataset.
357+
358+
# update dataset from dis arrays
269359
ds["dis_delr"].values = dis.delr.get_data()
270360
ds["dis_delc"].values = dis.delc.get_data()
271361
ds["dis_top"].values = dis.top.get_data()
272362
ds["dis_botm"].values = dis.botm.get_data()
273363
ds["dis_idomain"].values = dis.idomain.get_data()
274364

275-
# update dis to read from netcdf
365+
# ## Update MODFLOW 6 package input file
366+
#
367+
# MODFLOW 6 input data for the package is now in the dataset. Once the NetCDF
368+
# file is generated, we need to configure MODFLOW 6 so that it looks to that
369+
# file for the package array input. The ASCII will no longer defined the arrays-
370+
# instead the array names will be followed by the NETCDF keyword.
371+
#
372+
# We will simply overwrite the entire MODFLOW 6 DIS package input file with the
373+
# following code block.
374+
375+
# rewrite mf6 dis input to read from netcdf
276376
with open(workspace / "netcdf" / "uzf01.dis", "w") as f:
277377
f.write("BEGIN options\n")
278378
f.write(" crs EPSG:26916\n")
@@ -290,19 +390,23 @@ def _data_shape(shape):
290390
f.write(" idomain NETCDF\n")
291391
f.write("END griddata\n")
292392

293-
# npf
393+
# ## Update MODFLOW 6 package input file
394+
#
395+
# Follow the same process as above for the NPF package.
396+
397+
# get npf package netcdf info
294398
npf = gwf.get_package("npf")
295399
nc_info = npf.netcdf_info()
296400
pprint(nc_info)
297401

298402
# create npf dataset variables
299403
ds = add_netcdf_vars(ds, nc_info, dimmap)
300404

301-
# update data
405+
# update dataset from npf arrays
302406
ds["npf_icelltype"].values = npf.icelltype.get_data()
303407
ds["npf_k"].values = npf.k.get_data()
304408

305-
# update npf to read from netcdf
409+
# rewrite mf6 npf input to read from netcdf
306410
with open(workspace / "netcdf" / "uzf01.npf", "w") as f:
307411
f.write("BEGIN options\n")
308412
f.write("END options\n\n")
@@ -311,6 +415,14 @@ def _data_shape(shape):
311415
f.write(" k NETCDF\n")
312416
f.write("END griddata\n")
313417

418+
# ## Update MODFLOW 6 package input file
419+
#
420+
# Follow the same process as above for the GHBG package. The difference is
421+
# that this is PERIOD input and therefore stored as timeseries data in the
422+
# NetCDF file. As NETCDF timeseries and defined in terms of total number of
423+
# simulation steps, care must be taken in the translation of FloPy period
424+
# data to the timeseries.
425+
314426
# get ghbg package netcdf info
315427
ghbg = gwf.get_package("ghbg_0")
316428
nc_info = ghbg.netcdf_info()
@@ -320,24 +432,26 @@ def _data_shape(shape):
320432
ds = add_netcdf_vars(ds, nc_info, dimmap)
321433

322434
# update bhead netcdf array from flopy perioddata
435+
# timeseries step index is first of stress period
323436
for p in ghbg.bhead.get_data():
324437
istp = sum(gwf.modeltime.nstp[0:p])
325438
ds["ghbg_0_bhead"].values[istp] = ghbg.bhead.get_data()[p]
326439

327440
# update cond netcdf array from flopy perioddata
441+
# timeseries step index is first of stress period
328442
for p in ghbg.cond.get_data():
329443
istp = sum(gwf.modeltime.nstp[0:p])
330444
ds["ghbg_0_cond"].values[istp] = ghbg.cond.get_data()[p]
331445

332446
# show the dataset
333447
print(ds)
334448

335-
# write the netcdf
449+
# write dataset to netcdf
336450
ds.to_netcdf(
337451
workspace / "netcdf/uzf01.structured.nc", format="NETCDF4", engine="netcdf4"
338452
)
339453

340-
# update ghbg to read from netcdf
454+
# rewrite mf6 ghbg input to read from netcdf
341455
with open(workspace / "netcdf/uzf01.ghbg", "w") as f:
342456
f.write("BEGIN options\n")
343457
f.write(" READARRAYGRID\n")

0 commit comments

Comments
 (0)