|
7 | 7 | # extension: .py |
8 | 8 | # format_name: light |
9 | 9 | # format_version: '1.5' |
10 | | -# jupytext_version: 1.16.4 |
| 10 | +# jupytext_version: 1.17.2 |
11 | 11 | # kernelspec: |
12 | 12 | # display_name: Python 3 (ipykernel) |
13 | 13 | # language: python |
14 | 14 | # name: python3 |
15 | 15 | # --- |
16 | 16 |
|
17 | | -# # MODFLOW 6: Generate MODFLOW 6 NetCDF input from existing FloPy sim |
| 17 | +# # MODFLOW 6: MODFLOW 6 NetCDF inputs from FloPy simulation |
18 | 18 | # |
19 | | -# ## NetCDF tutorial 1: MODFLOW 6 structured input file |
| 19 | +# ## Write MODFLOW 6 NetCDF simulation |
20 | 20 | # |
21 | | -# This tutorial shows how to generate a MODFLOW 6 NetCDF file from |
22 | | -# an existing FloPy simulation. Two methods will be demonstrated that |
23 | | -# generate a simulation with package data stored in a model NetCDF |
24 | | -# file. The first method is non-interactive- FloPy will generate the |
25 | | -# file with a modified `write_simulation()` call. The second method |
26 | | -# is interactive, which provides an oppurtinity to modify the dataset |
27 | | -# before it is written to NetCDF. |
| 21 | +# This tutorial demonstrates how to generate a MODFLOW 6 NetCDF file |
| 22 | +# from an existing FloPy simulation. Two variations will be shown. |
| 23 | +# In the first, FloPy will generate the file with a modified |
| 24 | +# `write_simulation()` call. The second method is more interactive, |
| 25 | +# providing an opputinity to modify the dataset before it is written |
| 26 | +# to NetCDF. |
| 27 | +# |
| 28 | +# Support for generating a MODFLOW 6 NetCDF input without a defined |
| 29 | +# FloPy mf6 model or package instances is briefly discussed at the |
| 30 | +# end of the tutorial. |
28 | 31 | # |
29 | 32 | # For more information on supported MODFLOW 6 NetCDF formats see: |
30 | 33 | # [MODFLOW NetCDF Format](https://github.com/MODFLOW-ORG/modflow6/wiki/MODFLOW-NetCDF-Format). |
|
93 | 96 |
|
94 | 97 | # ## Load and run baseline simulation |
95 | 98 | # |
96 | | -# For the purposes of this tutorial, the specifics of this simulation |
| 99 | +# For the purposes of this tutorial, the specifics of the simulation |
97 | 100 | # other than it is a candidate for NetCDF input are not a focus. It |
98 | 101 | # is a NetCDF input candidate because it defines a supported model type |
99 | 102 | # (`GWF6`) with a structured discretization and packages that support |
100 | 103 | # NetCDF input parameters. |
| 104 | +# |
| 105 | +# More information about package NetCDF support in MODFLOW 6 can be |
| 106 | +# found in the `MODFLOW 6 - Description of Input and Output` (`mf6io.pdf`), |
| 107 | +# also available at the nightly build repository linked above. |
101 | 108 |
|
102 | 109 | # load and run the non-netcdf simulation |
103 | 110 | sim = flopy.mf6.MFSimulation.load(sim_ws=data_path / sim_name) |
|
108 | 115 |
|
109 | 116 | # ## Create NetCDF based simulation method 1 |
110 | 117 | # |
111 | | -# This is the most straightforward way to create a NetCDF simulation |
112 | | -# from the loaded ascii input simulation. Simply define the `netcdf` |
113 | | -# argument to `write_simulation()` to be either `structured` or |
114 | | -# `layered`, depending on the desired format of the generated NetCDF |
115 | | -# file. |
| 118 | +# The most straightforward way to create a NetCDF simulation |
| 119 | +# from the loaded simulation is to provide a `netcdf` argument |
| 120 | +# to `write_simulation()` and define it to be either `structured` |
| 121 | +# or `layered`, depending on the desired format of the generated |
| 122 | +# NetCDF file. |
116 | 123 | # |
117 | 124 | # The name of the created file can be specified by first setting the |
118 | 125 | # model `name_file.nc_filerecord` attribute to the desired name. If |
|
129 | 136 |
|
130 | 137 | # ## Run MODFLOW 6 simulation with NetCDF input |
131 | 138 | # |
132 | | -# The simulation generated by this tutorial should be runnable by |
133 | | -# Extended MODFLOW 6, available from the nightly-build repository |
134 | | -# (linked above). |
| 139 | +# The simulation generated by this tutorial should run with the |
| 140 | +# Extended MODFLOW 6 executable, available from the nightly-build |
| 141 | +# repository (linked above). |
135 | 142 |
|
136 | 143 | # success, buff = sim.run_simulation(silent=True, report=True) |
137 | 144 | # assert success, pformat(buff) |
|
148 | 155 |
|
149 | 156 | # ## Run MODFLOW 6 simulation with NetCDF input |
150 | 157 | # |
151 | | -# The simulation generated by this tutorial should be runnable by |
152 | | -# Extended MODFLOW 6, available from the nightly-build repository |
153 | | -# (linked above). |
| 158 | +# The simulation generated by this tutorial should run with the |
| 159 | +# Extended MODFLOW 6 executable, available from the nightly-build |
| 160 | +# repository (linked above). |
154 | 161 |
|
155 | 162 | # success, buff = sim.run_simulation(silent=True, report=True) |
156 | 163 | # assert success, pformat(buff) |
157 | 164 |
|
158 | 165 | # ## Create NetCDF based simulation method 2 |
159 | 166 | # |
| 167 | +# In this method we will set the FloPy `netcdf` argument to `nofile` |
| 168 | +# when `write_simulation()` is called. As such, FloPy will not generate |
| 169 | +# the NetCDF file automatically. We will manage the NetCDF file |
| 170 | +# generation ourselves in method 2. |
| 171 | +# |
160 | 172 | # Reset the simulation path and set the `GWF` name file `nc_filerecord` |
161 | 173 | # attribute to the name of the intended input NetCDF file. Display |
162 | 174 | # the resultant name file changes. |
163 | 175 | # |
164 | 176 | # When we write the updated simulation, all packages that support NetCDF |
165 | | -# input parameters will be converted. We will therefore need to create a |
| 177 | +# input parameters will be written such that NetCDF parameters expect the |
| 178 | +# data source to be a NetCDF file. We will therefore need to create a |
166 | 179 | # NetCDF input file containing arrays for the `DIS`, `NPF`, `IC`, `STO`, |
167 | | -# and `GHBG` packages. Data will be copied from the package objects into |
168 | | -# dataset arrays. |
169 | | -# |
170 | | -# Flopy will not generate the NetCDF input file when the `netcdf` argument |
171 | | -# to `write_simulation()` is set to `nofile`. This step is needed, however, |
172 | | -# to update ascii input with the keywords required to support the model |
173 | | -# NetCDF file that we will generate. |
| 180 | +# and `GHBG` packages. We will still use FloPy package objects to set the |
| 181 | +# parameter data in the dataset; however an `update_data=False` argument |
| 182 | +# could be passed to the `update_dataset()` call if this was not desired. |
174 | 183 |
|
175 | 184 | # create directory for netcdf sim |
176 | 185 | sim.set_sim_path(workspace / "netcdf3") |
|
205 | 214 |
|
206 | 215 | # ## Access model NetCDF attributes |
207 | 216 | # |
208 | | -# Access model scoped NetCDF details by storing the dictionary |
209 | | -# returned from `netcdf_info()`. In particular, we need to set dataset |
210 | | -# scoped attributes that are stored in the model netcdf info dict. |
| 217 | +# Internally, FloPy generates and uses NetCDF metadata dictionaries |
| 218 | +# to update datasets. Both model and package objects can generate |
| 219 | +# the dictionaries and they contain related but distinct NetCDF |
| 220 | +# details. Model object dictionaries contain file scoped attribute |
| 221 | +# information while package dictionaries are organized by NetCDF |
| 222 | +# variable and contain variable scoped attribute information and |
| 223 | +# details related to creating the variable, including dimensions, |
| 224 | +# shape and data type. |
211 | 225 | # |
212 | | -# First, retrieve and store the netcdf info dictionary and display |
| 226 | +# The dictionaries are available via the `netcdf_info()` call. Their |
| 227 | +# content also varies depending on the desired type of dataset (i.e. |
| 228 | +# `structured` or `layered`). In this step we will access the model |
| 229 | +# NetCDF metadata and use it to update dataset scoped attributes. |
| 230 | +# |
| 231 | +# First, retrieve and store the netcdf metadata dictionary and display |
213 | 232 | # its contents. Then, in the following step, update the dataset with |
214 | 233 | # the model scoped attributes defined in the dictionary. |
215 | 234 | # |
216 | | -# These 2 operations can also be accomplished by calling `update_dataset()` |
217 | | -# on the model object. Analogous functions for the package are shown |
218 | | -# below. |
| 235 | +# These operations can also both be accomplished by calling |
| 236 | +# `update_dataset()` on the model object, albeit without the |
| 237 | +# opportunity to modify the intermediate metadata dictionary. |
| 238 | +# Examples of this approach (with package objects) are shown below. |
219 | 239 |
|
220 | 240 | # get model netcdf info |
221 | 241 | nc_info = gwf.netcdf_info() |
|
227 | 247 |
|
228 | 248 | # ## Update the dataset with supported `DIS` arrays |
229 | 249 | # |
230 | | -# Add NetCDF supported data arrays in package to dataset. Internally, this call |
231 | | -# uses a `netcdf_info()` package dictionary to determine candidate variables |
232 | | -# and relevant information about them. Alternatively, this dictionary can |
233 | | -# be directly accessed, updated, and passed to the `update_dataset()` function. |
234 | | -# That workflow will be demonstrated in the `NPF` package update which follows. |
| 250 | +# First, we will show how package NetCDF parameters can be added to the |
| 251 | +# dataset without using the NetCDF metadata dictionary. We will use the |
| 252 | +# metadata dictionary when updating the dataset with NPF parameter data. |
| 253 | +# |
| 254 | +# Add NetCDF supported data arrays in package to dataset. |
235 | 255 |
|
236 | 256 | # update dataset with `DIS` arrays |
237 | 257 | dis = gwf.get_package("dis") |
|
240 | 260 | # ## Access `NPF` package NetCDF attributes |
241 | 261 | # |
242 | 262 | # Access package scoped NetCDF details by storing the dictionary returned |
243 | | -# from `netcdf_info()`. We need to set package variable attributes that are |
244 | | -# stored in the package netcdf info dict, but we also need other information |
245 | | -# that is relevant to creating the variables themselves. |
| 263 | +# from `netcdf_info()`. |
246 | 264 | # |
247 | 265 | # The contents of the info dictionary are shown and then, in the following |
248 | 266 | # step, the dictionary and the dataset are passed to a helper routine that |
|
253 | 271 | nc_info = npf.netcdf_info() |
254 | 272 | pprint(nc_info) |
255 | 273 |
|
256 | | -# ## Update package `netcdf_info` dictionary and dataset |
| 274 | +# ## Update package NetCDF metadata dictionary and dataset |
| 275 | +# |
| 276 | +# Here we update the metadata dictionary and then pass it directly to the |
| 277 | +# `update_dataset()` function which uses it when adding variables to the |
| 278 | +# dataset. |
257 | 279 | # |
258 | | -# Here we replace the default name for the `NPF K` input parameter and add |
259 | | -# the `standard_name` attribute to it's attribute dictionary. The dictionary |
260 | | -# is then passed to the `update_dataset()` function. Note the updated name |
261 | | -# is used in the subsequent block when updating the array values. |
| 280 | +# We replace the default name for the `NPF K` input parameter and add |
| 281 | +# the `standard_name` attribute to it's attribute dictionary. The |
| 282 | +# dictionary is then passed to the `update_dataset()` function. Note the |
| 283 | +# updated name is used in the subsequent block when updating the array |
| 284 | +# values. |
262 | 285 |
|
263 | 286 | # update dataset with `NPF` arrays |
264 | 287 | nc_info["k"]["varname"] = "npf_k_updated" |
|
302 | 325 |
|
303 | 326 | # ## Run MODFLOW 6 simulation with NetCDF input |
304 | 327 | # |
305 | | -# The simulation generated by this tutorial should be runnable by |
306 | | -# Extended MODFLOW 6, available from the nightly-build repository |
307 | | -# (linked above). |
| 328 | +# The simulation generated by this tutorial should run with the |
| 329 | +# Extended MODFLOW 6 executable, available from the nightly-build |
| 330 | +# repository (linked above). |
308 | 331 |
|
309 | 332 | # success, buff = sim.run_simulation(silent=True, report=True) |
310 | 333 | # assert success, pformat(buff) |
311 | 334 |
|
312 | | -# ## Method 4: DIY with xarray |
| 335 | +# ## Method 3: DIY with xarray |
313 | 336 | # |
314 | 337 | # The above method still uses FloPy objects to update the dataset arrays |
315 | 338 | # to values consistent with the state of the objects. The `netcdf_info` |
|
0 commit comments