From b9d236eb58146ad9f1c78d6127a8bddde37852cb Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Sun, 12 Nov 2023 15:29:14 -0600 Subject: [PATCH 1/2] fix(model_splitter): check keys in mftransient array --- flopy/mf6/utils/model_splitter.py | 34 ++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/flopy/mf6/utils/model_splitter.py b/flopy/mf6/utils/model_splitter.py index 2cdd455d23..82a6d58a68 100644 --- a/flopy/mf6/utils/model_splitter.py +++ b/flopy/mf6/utils/model_splitter.py @@ -1076,20 +1076,30 @@ def _remap_transient_array(self, item, mftransient, mapped_data): d0 = {mkey: {} for mkey in self._model_dict.keys()} for per, array in enumerate(mftransient.array): - storage = mftransient._data_storage[per] - how = [ - i.data_storage_type.value - for i in storage.layer_storage.multi_dim_list - ] - binary = [i.binary for i in storage.layer_storage.multi_dim_list] - fnames = [i.fname for i in storage.layer_storage.multi_dim_list] + if per in mftransient._data_storage.keys(): + storage = mftransient._data_storage[per] + how = [ + i.data_storage_type.value + for i in storage.layer_storage.multi_dim_list + ] + binary = [ + i.binary for i in storage.layer_storage.multi_dim_list + ] + fnames = [ + i.fname for i in storage.layer_storage.multi_dim_list + ] - d = self._remap_array( - item, array, mapped_data, how=how, binary=binary, fnames=fnames - ) + d = self._remap_array( + item, + array, + mapped_data, + how=how, + binary=binary, + fnames=fnames, + ) - for mkey in d.keys(): - d0[mkey][per] = d[mkey][item] + for mkey in d.keys(): + d0[mkey][per] = d[mkey][item] for mkey, values in d0.items(): mapped_data[mkey][item] = values From cf66df0462dd91c3e9aa50a42f9cc4f47b4aa530 Mon Sep 17 00:00:00 2001 From: Joseph Hughes Date: Mon, 13 Nov 2023 15:24:18 -0600 Subject: [PATCH 2/2] * fix issue with MFScalarTransient data in splitter (storage package period data) * add test for MFScalarTransient issue --- autotest/test_model_splitter.py | 168 ++++++++++++++++++++++++------ flopy/mf6/utils/model_splitter.py | 3 + 2 files changed, 142 insertions(+), 29 deletions(-) diff --git a/autotest/test_model_splitter.py b/autotest/test_model_splitter.py index 467b53e590..f7dca705e5 100644 --- a/autotest/test_model_splitter.py +++ b/autotest/test_model_splitter.py @@ -356,7 +356,7 @@ def test_control_records(function_tmpdir): spd_ls1 = ml1.wel.stress_period_data.get_record(1) spd_ls2 = ml1.wel.stress_period_data.get_record(2) - + if spd_ls1["filename"] is None or spd_ls1["binary"]: raise AssertionError( "External ascii files not being preserved for MFList" @@ -379,41 +379,49 @@ def test_empty_packages(function_tmpdir): nrow, ncol = 1, 14 base_name = "sfr01gwfgwf" gwf = flopy.mf6.ModflowGwf(sim, modelname=base_name, save_flows=True) - dis = flopy.mf6.ModflowGwfdis(gwf, nrow=1, ncol=14, top=0., botm=-1.) + dis = flopy.mf6.ModflowGwfdis(gwf, nrow=1, ncol=14, top=0.0, botm=-1.0) npf = flopy.mf6.ModflowGwfnpf( gwf, save_flows=True, save_specific_discharge=True, icelltype=0, - k=20., - k33=20. + k=20.0, + k33=20.0, ) - ic = flopy.mf6.ModflowGwfic(gwf, strt=0.) + ic = flopy.mf6.ModflowGwfic(gwf, strt=0.0) chd = flopy.mf6.ModflowGwfchd( gwf, - stress_period_data={0: [((0, 0, 13), 0.0),]} + stress_period_data={ + 0: [ + ((0, 0, 13), 0.0), + ] + }, ) wel = flopy.mf6.ModflowGwfwel( gwf, - stress_period_data={0: [((0, 0, 0), 1.),]} + stress_period_data={ + 0: [ + ((0, 0, 0), 1.0), + ] + }, ) # Build SFR records packagedata = [ - (0, (0, 0, 0), 1., 1., 1., 0., 0.1, 0., 1., 1, 1., 0), - (1, (0, 0, 1), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (2, (0, 0, 2), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (3, (0, 0, 3), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (4, (0, 0, 4), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (5, (0, 0, 5), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (6, (0, 0, 6), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (7, (0, 0, 7), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (8, (0, 0, 8), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (9, (0, 0, 9), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (10, (0, 0, 10), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (11, (0, 0, 11), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (12, (0, 0, 12), 1., 1., 1., 0., 0.1, 0., 1., 2, 1., 0), - (13, (0, 0, 13), 1., 1., 1., 0., 0.1, 0., 1., 1, 1., 0), + (0, (0, 0, 0), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 1, 1.0, 0), + (1, (0, 0, 1), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (2, (0, 0, 2), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (3, (0, 0, 3), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (4, (0, 0, 4), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (5, (0, 0, 5), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (6, (0, 0, 6), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (7, (0, 0, 7), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (8, (0, 0, 8), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (9, (0, 0, 9), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (10, (0, 0, 10), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (11, (0, 0, 11), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (12, (0, 0, 12), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 2, 1.0, 0), + (13, (0, 0, 13), 1.0, 1.0, 1.0, 0.0, 0.1, 0.0, 1.0, 1, 1.0, 0), ] connectiondata = [ @@ -430,7 +438,7 @@ def test_empty_packages(function_tmpdir): (10, 9, -11), (11, 10, -12), (12, 11, -13), - (13, 12) + (13, 12), ] sfr = flopy.mf6.ModflowGwfsfr( @@ -444,7 +452,11 @@ def test_empty_packages(function_tmpdir): nreaches=14, packagedata=packagedata, connectiondata=connectiondata, - perioddata={0: [(0, "INFLOW", 1.),]} + perioddata={ + 0: [ + (0, "INFLOW", 1.0), + ] + }, ) array = np.zeros((nrow, ncol), dtype=int) @@ -456,14 +468,10 @@ def test_empty_packages(function_tmpdir): m1 = new_sim.get_model(f"{base_name}_1") if "chd_0" in m0.package_dict: - raise AssertionError( - f"Empty CHD file written to {base_name}_0 model" - ) + raise AssertionError(f"Empty CHD file written to {base_name}_0 model") if "wel_0" in m1.package_dict: - raise AssertionError( - f"Empty WEL file written to {base_name}_1 model" - ) + raise AssertionError(f"Empty WEL file written to {base_name}_1 model") mvr_status0 = m0.sfr.mover.array mvr_status1 = m0.sfr.mover.array @@ -472,3 +480,105 @@ def test_empty_packages(function_tmpdir): raise AssertionError( "Mover status being overwritten in options splitting" ) + + +@requires_exe("mf6") +def test_transient_array(function_tmpdir): + name = "tarr" + new_sim_path = function_tmpdir / f"{name}_split_model" + nper = 3 + tdis_data = [ + (300000.0, 1, 1.0), + (36500.0, 10, 1.5), + (300000, 1, 1.0), + ] + nlay, nrow, ncol = 3, 21, 20 + xlen, ylen = 10000.0, 10500.0 + delc = ylen / nrow + delr = xlen / ncol + steady = {0: True, 2: True} + transient = {1: True} + + sim = flopy.mf6.MFSimulation(sim_name=name, sim_ws=new_sim_path) + ims = flopy.mf6.ModflowIms(sim, complexity="simple") + tdis = flopy.mf6.ModflowTdis(sim, nper=nper, perioddata=tdis_data) + + gwf = flopy.mf6.ModflowGwf( + sim, + modelname=name, + save_flows=True, + ) + dis = flopy.mf6.ModflowGwfdis( + gwf, + nlay=nlay, + nrow=nrow, + ncol=ncol, + delr=delr, + delc=delc, + top=400, + botm=[220.0, 200.0, 0], + length_units="meters", + ) + npf = flopy.mf6.ModflowGwfnpf( + gwf, + icelltype=1, + k=[50.0, 0.01, 200.0], + k33=[10.0, 0.01, 20.0], + ) + sto = flopy.mf6.ModflowGwfsto( + gwf, + iconvert=1, + ss=0.0001, + sy=0.1, + steady_state=steady, + transient=transient, + ) + ic = flopy.mf6.ModflowGwfic(gwf, strt=400.0) + oc = flopy.mf6.ModflowGwfoc( + gwf, + head_filerecord=f"{name}.hds", + budget_filerecord=f"{name}.cbc", + saverecord={0: [("head", "all"), ("budget", "all")]}, + ) + + rch = flopy.mf6.ModflowGwfrcha(gwf, recharge=0.005) + + chd_spd = [(0, i, ncol - 1, 320) for i in range(nrow)] + chd = flopy.mf6.ModflowGwfchd( + gwf, + stress_period_data=chd_spd, + ) + + well_spd = { + 0: [(0, 10, 9, -75000.0)], + 2: [(0, 10, 9, -75000.0), (2, 12, 4, -100000.0)], + } + wel = flopy.mf6.ModflowGwfwel( + gwf, + stress_period_data=well_spd, + ) + + sarr = np.ones((nrow, ncol), dtype=int) + sarr[:, int(ncol / 2) :] = 2 + mfsplit = Mf6Splitter(sim) + new_sim = mfsplit.split_model(sarr) + + for name in new_sim.model_names: + g = new_sim.get_model(name) + d = {} + for key in ( + 0, + 2, + ): + d[key] = g.sto.steady_state.get_data(key).get_data() + assert d == steady, ( + "storage steady_state dictionary " + + f"does not match for model '{name}'" + ) + d = {} + for key in (1,): + d[key] = g.sto.transient.get_data(key).get_data() + assert d == transient, ( + "storage package transient dictionary " + + f"does not match for model '{name}'" + ) diff --git a/flopy/mf6/utils/model_splitter.py b/flopy/mf6/utils/model_splitter.py index 82a6d58a68..c5eafd46ae 100644 --- a/flopy/mf6/utils/model_splitter.py +++ b/flopy/mf6/utils/model_splitter.py @@ -2946,6 +2946,9 @@ def _remap_package(self, package, ismvr=False): value = list_data mapped_data = self._remap_mflist(item, value, mapped_data) + elif isinstance(value, mfdatascalar.MFScalarTransient): + for mkey in self._model_dict.keys(): + mapped_data[mkey][item] = value._data_storage elif isinstance(value, mfdatascalar.MFScalar): for mkey in self._model_dict.keys(): mapped_data[mkey][item] = value.data