Skip to content

Commit 02a2f91

Browse files
authored
feat(set all data external options): additional parameters added (#2041)
* feat(set all data external options): parameters added "binary" and "base_name" parameters added to set_all_data_external * feat(set all external binary): doc update * feat(set all ext options)
1 parent 37a5e6c commit 02a2f91

File tree

11 files changed

+212
-105
lines changed

11 files changed

+212
-105
lines changed

.docs/Notebooks/mf6_data_tutorial08.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
# ---
22
# jupyter:
33
# jupytext:
4+
# notebook_metadata_filter: metadata
45
# text_representation:
56
# extension: .py
67
# format_name: light
7-
# format_version: "1.5"
8-
# jupytext_version: 1.5.1
8+
# format_version: '1.5'
9+
# jupytext_version: 1.14.4
910
# kernelspec:
10-
# display_name: Python 3
11+
# display_name: Python 3 (ipykernel)
1112
# language: python
1213
# name: python3
1314
# metadata:
1415
# section: mf6
1516
# ---
1617

17-
# # MODFLOW 6: Data Storage Information and Performance Optimization
18+
# # MODFLOW 6: External Files, Binary Data, and Performance Optimization
1819
#
1920
# This tutorial shows the different options for storing MODFLOW data in FloPy.
2021
# Interaction with a FloPy MODFLOW 6 model is different from other models,
@@ -36,7 +37,7 @@
3637
# This tutorial focuses on the different storage options for MODFLOW data and
3738
# how to optimize data storage read/write speed.
3839

39-
# ## Introduction to Data Storage Information
40+
# ## Introduction to Data Storage Options
4041
# MODFLOW array and list data can either be stored internally or externally in
4142
# text or binary files. Additionally array data can have a factor applied to
4243
# them and can have a format flag/code to define how these data will be
@@ -215,6 +216,10 @@
215216
print(f"New binary flag for stress period 1: {spd_record[0]['binary']}")
216217
print(f"New filename for stress period 2: {spd_record[1]['filename']}")
217218

219+
# An alternative to individually setting each file to external is to call the set_all_files_external method (there is also a set_all_files_internal method to do the opposite). While this requires less code, it does not give you the ability to set the names of each individual external file. By setting the binary attribute to True, flopy will store data to binary files wherever possible.
220+
221+
sim.set_all_data_external(binary=True)
222+
218223
# ## Optimizing FloPy Performance
219224
#
220225
# By default FloPy will perform a number of verification checks on your data

autotest/regression/test_mf6.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4240,7 +4240,34 @@ def test045_lake1ss_table(function_tmpdir, example_data_path):
42404240
save_folder = function_tmpdir / "save"
42414241
save_folder.mkdir()
42424242
sim.set_sim_path(save_folder)
4243+
sim.set_all_data_external(
4244+
external_data_folder="test_folder",
4245+
base_name="ext_file",
4246+
binary=True,
4247+
)
42434248
sim.write_simulation()
4249+
# verify external files were written
4250+
ext_folder = os.path.join(save_folder, "test_folder")
4251+
files_to_check = [
4252+
"ext_file_lakeex1b.dis_botm_layer1.bin",
4253+
"ext_file_lakeex1b.dis_botm_layer2.bin",
4254+
"ext_file_lakeex1b.dis_botm_layer3.bin",
4255+
"ext_file_lakeex1b.dis_botm_layer4.bin",
4256+
"ext_file_lakeex1b.dis_botm_layer5.bin",
4257+
"ext_file_lakeex1b.npf_k_layer1.bin",
4258+
"ext_file_lakeex1b.npf_k_layer5.bin",
4259+
"ext_file_lakeex1b.chd_stress_period_data_1.bin",
4260+
"ext_file_lakeex1b.lak_connectiondata.txt",
4261+
"ext_file_lakeex1b.lak_packagedata.txt",
4262+
"ext_file_lakeex1b.lak_perioddata_1.txt",
4263+
"ext_file_lakeex1b_table.ref_table.txt",
4264+
"ext_file_lakeex1b.evt_depth_1.bin",
4265+
"ext_file_lakeex1b.evt_rate_1.bin",
4266+
"ext_file_lakeex1b.evt_surface_1.bin",
4267+
]
4268+
for file in files_to_check:
4269+
data_file_path = os.path.join(ext_folder, file)
4270+
assert os.path.exists(data_file_path)
42444271

42454272
# run simulation
42464273
success, buff = sim.run_simulation()

flopy/mf6/data/mfdata.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def __init__(
251251
self._data_type = structure.type
252252
self._keyword = ""
253253
if self._simulation_data is not None:
254-
self._data_dimensions = DataDimensions(dimensions, structure)
254+
self.data_dimensions = DataDimensions(dimensions, structure)
255255
# build a unique path in the simulation dictionary
256256
self._org_path = self._path
257257
index = 0
@@ -380,13 +380,13 @@ def layer_shape(self):
380380
layers = []
381381
layer_dims = self.structure.data_item_structures[0].layer_dims
382382
if len(layer_dims) == 1:
383-
layers.append(self._data_dimensions.get_model_grid().num_layers())
383+
layers.append(self.data_dimensions.get_model_grid().num_layers())
384384
else:
385385
for layer in layer_dims:
386386
if layer == "nlay":
387387
# get the layer size from the model grid
388388
try:
389-
model_grid = self._data_dimensions.get_model_grid()
389+
model_grid = self.data_dimensions.get_model_grid()
390390
except Exception as ex:
391391
type_, value_, traceback_ = sys.exc_info()
392392
raise MFDataException(
@@ -521,13 +521,13 @@ def _get_constant_formatting_string(
521521
const_val,
522522
data_type,
523523
self._simulation_data,
524-
self._data_dimensions,
524+
self.data_dimensions,
525525
verify_data=self._simulation_data.verify_data,
526526
)
527527
return f"{sim_data.indent_string.join(const_format)}{suffix}"
528528

529529
def _get_aux_var_name(self, aux_var_index):
530-
aux_var_names = self._data_dimensions.package_dim.get_aux_variables()
530+
aux_var_names = self.data_dimensions.package_dim.get_aux_variables()
531531
# TODO: Verify that this works for multi-dimensional layering
532532
return aux_var_names[0][aux_var_index[0] + 1]
533533

@@ -608,7 +608,7 @@ def _get_external_formatting_str(
608608
self, fname, factor, binary, iprn, data_type, ext_file_action
609609
):
610610
file_mgmt = self._simulation_data.mfpath
611-
model_name = self._data_dimensions.package_dim.model_dim[0].model_name
611+
model_name = self.data_dimensions.package_dim.model_dim[0].model_name
612612
ext_file_path = file_mgmt.get_updated_path(
613613
fname, model_name, ext_file_action
614614
)

flopy/mf6/data/mfdataarray.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def supports_layered(self):
348348
"""
349349

350350
try:
351-
model_grid = self._data_dimensions.get_model_grid()
351+
model_grid = self.data_dimensions.get_model_grid()
352352
except Exception as ex:
353353
type_, value_, traceback_ = sys.exc_info()
354354
raise MFDataException(
@@ -381,7 +381,7 @@ def set_layered_data(self, layered_data):
381381
"""
382382
if layered_data is True and self.structure.layered is False:
383383
if (
384-
self._data_dimensions.get_model_grid().grid_type()
384+
self.data_dimensions.get_model_grid().grid_type()
385385
== DiscretizationType.DISU
386386
):
387387
comment = f"Layered option not available for unstructured grid. {self._path}"
@@ -430,7 +430,7 @@ def make_layered(self):
430430
)
431431
else:
432432
if (
433-
self._data_dimensions.get_model_grid().grid_type()
433+
self.data_dimensions.get_model_grid().grid_type()
434434
== DiscretizationType.DISU
435435
):
436436
comment = f"Layered option not available for unstructured grid. {self._path}"
@@ -482,6 +482,7 @@ def store_as_external_file(
482482
Whether to replace an existing external file.
483483
check_data : bool
484484
Verify data prior to storing
485+
485486
"""
486487
storage = self._get_storage_obj()
487488
if storage is None:
@@ -861,11 +862,11 @@ def _set_record(self, data_record):
861862
)
862863
type_, value_, traceback_ = sys.exc_info()
863864
raise MFDataException(
864-
self._data_dimensions.structure.get_model(),
865-
self._data_dimensions.structure.get_package(),
866-
self._data_dimensions.structure.path,
865+
self.data_dimensions.structure.get_model(),
866+
self.data_dimensions.structure.get_package(),
867+
self.data_dimensions.structure.path,
867868
"setting record",
868-
self._data_dimensions.structure.name,
869+
self.data_dimensions.structure.name,
869870
inspect.stack()[0][3],
870871
type_,
871872
value_,
@@ -933,7 +934,7 @@ def _set_data(
933934
# handle special case of aux variables in an array
934935
self.layered = True
935936
aux_var_names = (
936-
self._data_dimensions.package_dim.get_aux_variables()
937+
self.data_dimensions.package_dim.get_aux_variables()
937938
)
938939
if len(aux_data) == len(aux_var_names[0]) - 1:
939940
for layer, aux_var_data in enumerate(aux_data):
@@ -980,11 +981,11 @@ def _set_data(
980981
)
981982
type_, value_, traceback_ = sys.exc_info()
982983
raise MFDataException(
983-
self._data_dimensions.structure.get_model(),
984-
self._data_dimensions.structure.get_package(),
985-
self._data_dimensions.structure.path,
984+
self.data_dimensions.structure.get_model(),
985+
self.data_dimensions.structure.get_package(),
986+
self.data_dimensions.structure.path,
986987
"setting aux variables",
987-
self._data_dimensions.structure.name,
988+
self.data_dimensions.structure.name,
988989
inspect.stack()[0][3],
989990
type_,
990991
value_,
@@ -1064,7 +1065,7 @@ def load(
10641065
self._resync()
10651066
if self.structure.layered:
10661067
try:
1067-
model_grid = self._data_dimensions.get_model_grid()
1068+
model_grid = self.data_dimensions.get_model_grid()
10681069
except Exception as ex:
10691070
type_, value_, traceback_ = sys.exc_info()
10701071
raise MFDataException(
@@ -1101,7 +1102,7 @@ def load(
11011102
else:
11021103
file_access = MFFileAccessArray(
11031104
self.structure,
1104-
self._data_dimensions,
1105+
self.data_dimensions,
11051106
self._simulation_data,
11061107
self._path,
11071108
self._current_key,
@@ -1272,7 +1273,7 @@ def _new_storage(
12721273
return DataStorage(
12731274
self._simulation_data,
12741275
self._model_or_sim,
1275-
self._data_dimensions,
1276+
self.data_dimensions,
12761277
self._get_file_entry,
12771278
DataStorageType.internal_array,
12781279
DataStructureType.ndarray,
@@ -1284,7 +1285,7 @@ def _new_storage(
12841285
return DataStorage(
12851286
self._simulation_data,
12861287
self._model_or_sim,
1287-
self._data_dimensions,
1288+
self.data_dimensions,
12881289
self._get_file_entry,
12891290
DataStorageType.internal_array,
12901291
DataStructureType.ndarray,
@@ -1402,7 +1403,7 @@ def _get_file_entry_layer(
14021403
self._simulation_data.debug,
14031404
ex,
14041405
)
1405-
package_dim = self._data_dimensions.package_dim
1406+
package_dim = self.data_dimensions.package_dim
14061407
model_name = package_dim.model_dim[0].model_name
14071408
self._simulation_data.mfpath.add_ext_file(file_path, model_name)
14081409
return file_entry
@@ -1430,7 +1431,7 @@ def _get_data_layer_string(self, layer, data_indent):
14301431
)
14311432
file_access = MFFileAccessArray(
14321433
self.structure,
1433-
self._data_dimensions,
1434+
self.data_dimensions,
14341435
self._simulation_data,
14351436
self._path,
14361437
self._current_key,
@@ -1683,6 +1684,7 @@ def store_as_external_file(
16831684
Whether to replace an existing external file.
16841685
check_data : bool
16851686
Verify data prior to storing
1687+
16861688
"""
16871689
# store each stress period in separate file(s)
16881690
for sp in self._data_storage.keys():
@@ -1803,7 +1805,7 @@ def get_record(self, key=None):
18031805
"""
18041806
if self._data_storage is not None and len(self._data_storage) > 0:
18051807
if key is None:
1806-
sim_time = self._data_dimensions.package_dim.model_dim[
1808+
sim_time = self.data_dimensions.package_dim.model_dim[
18071809
0
18081810
].simulation_time
18091811
num_sp = sim_time.get_num_stress_periods()
@@ -1825,7 +1827,7 @@ def get_data(self, key=None, apply_mult=True, **kwargs):
18251827
"""
18261828
if self._data_storage is not None and len(self._data_storage) > 0:
18271829
if key is None:
1828-
sim_time = self._data_dimensions.package_dim.model_dim[
1830+
sim_time = self.data_dimensions.package_dim.model_dim[
18291831
0
18301832
].simulation_time
18311833
num_sp = sim_time.get_num_stress_periods()

0 commit comments

Comments
 (0)