From c7a9dfeb7b17124a185779f516031fb347433ac1 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:27:07 -0700 Subject: [PATCH 1/7] fix(check): Updated check to work with cellid -1 values --- autotest/regression/test_mf6.py | 2 ++ flopy/discretization/grid.py | 2 ++ flopy/discretization/vertexgrid.py | 3 --- flopy/mf6/data/mfdatalist.py | 32 +++++++++++++++++++++++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/autotest/regression/test_mf6.py b/autotest/regression/test_mf6.py index 6b8b8d207..6d49da744 100644 --- a/autotest/regression/test_mf6.py +++ b/autotest/regression/test_mf6.py @@ -677,6 +677,7 @@ def test_np001(function_tmpdir, example_data_path): sim.delete_output_files() # test error checking + sim.simulation_data.verify_data = False drn_package = ModflowGwfdrn( model, print_input=True, @@ -697,6 +698,7 @@ def test_np001(function_tmpdir, example_data_path): k=100001.0, k33=1e-12, ) + sim.simulation_data.verify_data = True chk = sim.check() summary = ".".join(chk[0].summary_array.desc) assert "drn_1 package: invalid BC index" in summary diff --git a/flopy/discretization/grid.py b/flopy/discretization/grid.py index cfa72af05..097d6c1ee 100644 --- a/flopy/discretization/grid.py +++ b/flopy/discretization/grid.py @@ -183,6 +183,8 @@ def __init__( self._top = top if botm is not None: botm = botm.astype(float) + if idomain is None: + idomain = np.ones_like(botm) self._botm = botm self._idomain = idomain diff --git a/flopy/discretization/vertexgrid.py b/flopy/discretization/vertexgrid.py index 9679b4a33..c235134e4 100644 --- a/flopy/discretization/vertexgrid.py +++ b/flopy/discretization/vertexgrid.py @@ -102,9 +102,6 @@ def __init__( self._vertices = vertices self._cell1d = cell1d self._cell2d = cell2d - self._top = top - self._botm = botm - self._idomain = idomain if botm is None: self._nlay = nlay self._ncpl = ncpl diff --git a/flopy/mf6/data/mfdatalist.py b/flopy/mf6/data/mfdatalist.py index 7cffa30bc..d622a2500 100644 --- a/flopy/mf6/data/mfdatalist.py +++ b/flopy/mf6/data/mfdatalist.py @@ -505,6 +505,36 @@ def _check_valid_cellids(self): idomain_val = idomain # cellid should be within the model grid for idx, cellid_part in enumerate(record[index]): + if cellid_part == -1: + # cellid not defined, all values should + # be -1 + match = all( + elem == record[index][0] + for elem in record[index] + ) + if not match: + message = ( + f"Invalid cellid {record[index]}" + ) + ( + type_, + value_, + traceback_, + ) = sys.exc_info() + raise MFDataException( + self.structure.get_model(), + self.structure.get_package(), + self.structure.path, + "storing data", + self.structure.name, + inspect.stack()[0][3], + type_, + value_, + traceback_, + message, + self._simulation_data.debug, + ) + continue if ( model_shape[idx] <= cellid_part or cellid_part < 0 @@ -530,7 +560,7 @@ def _check_valid_cellids(self): ) idomain_val = idomain_val[cellid_part] # cellid should be at an active cell - if idomain_val < 1: + if record[index][0] != -1 and idomain_val < 1: message = ( "Cellid {} is outside of the " "active model grid" From dd5b7ac2fcc896df431c164dee000f9053e99523 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:38:03 -0700 Subject: [PATCH 2/7] fix(test): should be a complete grid --- autotest/test_grid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autotest/test_grid.py b/autotest/test_grid.py index 246f9e48b..4cd16c5cb 100644 --- a/autotest/test_grid.py +++ b/autotest/test_grid.py @@ -983,7 +983,7 @@ def test_unstructured_complete_grid_ctor(minimal_unstructured_grid_info): assert g.nlay == 2 assert g.nnodes == 2 assert g.is_valid - assert not g.is_complete + assert g.is_complete assert g.grid_varies_by_layer assert g._vertices == d["vertices"] assert g._iverts == d["iverts"] From bced4eb613d179122ca1d0cd22289f1ee02eb668 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Thu, 27 Jul 2023 16:03:13 -0700 Subject: [PATCH 3/7] fix(model grid): Always resync mf2005 grids --- flopy/modflow/mf.py | 4 ---- flopy/mt3d/mt.py | 4 ---- flopy/seawat/swt.py | 4 ---- 3 files changed, 12 deletions(-) diff --git a/flopy/modflow/mf.py b/flopy/modflow/mf.py index ea1ec9974..96d872d78 100644 --- a/flopy/modflow/mf.py +++ b/flopy/modflow/mf.py @@ -271,9 +271,6 @@ def modeltime(self): @property def modelgrid(self): - if not self._mg_resync: - return self._modelgrid - if self.has_package("bas6"): ibound = self.bas6.ibound.array else: @@ -339,7 +336,6 @@ def modelgrid(self): self._modelgrid.angrot, self._modelgrid.crs or self._modelgrid.epsg, ) - self._mg_resync = not self._modelgrid.is_complete return self._modelgrid @modelgrid.setter diff --git a/flopy/mt3d/mt.py b/flopy/mt3d/mt.py index c3d82cdda..dc0476543 100644 --- a/flopy/mt3d/mt.py +++ b/flopy/mt3d/mt.py @@ -253,9 +253,6 @@ def modeltime(self): @property def modelgrid(self): - if not self._mg_resync: - return self._modelgrid - if self.btn is not None: ibound = self.btn.icbund.array delc = self.btn.delc.array @@ -323,7 +320,6 @@ def modelgrid(self): angrot = 0.0 self._modelgrid.set_coord_info(xoff, yoff, angrot, crs=crs) - self._mg_resync = not self._modelgrid.is_complete return self._modelgrid @property diff --git a/flopy/seawat/swt.py b/flopy/seawat/swt.py index 689ff5af0..babda8a17 100644 --- a/flopy/seawat/swt.py +++ b/flopy/seawat/swt.py @@ -186,9 +186,6 @@ def modeltime(self): @property def modelgrid(self): - if not self._mg_resync: - return self._modelgrid - if self.has_package("bas6"): ibound = self.bas6.ibound.array else: @@ -228,7 +225,6 @@ def modelgrid(self): self._modelgrid.angrot, self._modelgrid.crs, ) - self._mg_resync = not self._modelgrid.is_complete return self._modelgrid @property From 80067bf3d70ffbbd5f85cadfd7afa929a33e55ed Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Thu, 27 Jul 2023 16:09:21 -0700 Subject: [PATCH 4/7] Revert "fix(model grid): Always resync mf2005 grids" This reverts commit bced4eb613d179122ca1d0cd22289f1ee02eb668. --- flopy/modflow/mf.py | 4 ++++ flopy/mt3d/mt.py | 4 ++++ flopy/seawat/swt.py | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/flopy/modflow/mf.py b/flopy/modflow/mf.py index 96d872d78..ea1ec9974 100644 --- a/flopy/modflow/mf.py +++ b/flopy/modflow/mf.py @@ -271,6 +271,9 @@ def modeltime(self): @property def modelgrid(self): + if not self._mg_resync: + return self._modelgrid + if self.has_package("bas6"): ibound = self.bas6.ibound.array else: @@ -336,6 +339,7 @@ def modelgrid(self): self._modelgrid.angrot, self._modelgrid.crs or self._modelgrid.epsg, ) + self._mg_resync = not self._modelgrid.is_complete return self._modelgrid @modelgrid.setter diff --git a/flopy/mt3d/mt.py b/flopy/mt3d/mt.py index dc0476543..c3d82cdda 100644 --- a/flopy/mt3d/mt.py +++ b/flopy/mt3d/mt.py @@ -253,6 +253,9 @@ def modeltime(self): @property def modelgrid(self): + if not self._mg_resync: + return self._modelgrid + if self.btn is not None: ibound = self.btn.icbund.array delc = self.btn.delc.array @@ -320,6 +323,7 @@ def modelgrid(self): angrot = 0.0 self._modelgrid.set_coord_info(xoff, yoff, angrot, crs=crs) + self._mg_resync = not self._modelgrid.is_complete return self._modelgrid @property diff --git a/flopy/seawat/swt.py b/flopy/seawat/swt.py index babda8a17..689ff5af0 100644 --- a/flopy/seawat/swt.py +++ b/flopy/seawat/swt.py @@ -186,6 +186,9 @@ def modeltime(self): @property def modelgrid(self): + if not self._mg_resync: + return self._modelgrid + if self.has_package("bas6"): ibound = self.bas6.ibound.array else: @@ -225,6 +228,7 @@ def modelgrid(self): self._modelgrid.angrot, self._modelgrid.crs, ) + self._mg_resync = not self._modelgrid.is_complete return self._modelgrid @property From dcc62e61944e397d9345d2c3228acf6657cd66ae Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Fri, 28 Jul 2023 08:42:06 -0700 Subject: [PATCH 5/7] fix(grid idomain): grid idomain now defaults to all 1's for MF6 only --- autotest/test_grid.py | 2 +- flopy/discretization/grid.py | 2 -- flopy/mf6/mfmodel.py | 27 +++++++++++++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/autotest/test_grid.py b/autotest/test_grid.py index 4cd16c5cb..246f9e48b 100644 --- a/autotest/test_grid.py +++ b/autotest/test_grid.py @@ -983,7 +983,7 @@ def test_unstructured_complete_grid_ctor(minimal_unstructured_grid_info): assert g.nlay == 2 assert g.nnodes == 2 assert g.is_valid - assert g.is_complete + assert not g.is_complete assert g.grid_varies_by_layer assert g._vertices == d["vertices"] assert g._iverts == d["iverts"] diff --git a/flopy/discretization/grid.py b/flopy/discretization/grid.py index 097d6c1ee..cfa72af05 100644 --- a/flopy/discretization/grid.py +++ b/flopy/discretization/grid.py @@ -183,8 +183,6 @@ def __init__( self._top = top if botm is not None: botm = botm.astype(float) - if idomain is None: - idomain = np.ones_like(botm) self._botm = botm self._idomain = idomain diff --git a/flopy/mf6/mfmodel.py b/flopy/mf6/mfmodel.py index dcab7fdea..079a721e0 100644 --- a/flopy/mf6/mfmodel.py +++ b/flopy/mf6/mfmodel.py @@ -370,12 +370,14 @@ def modelgrid(self): angrot=self._modelgrid.angrot, ) else: + botm = dis.botm.array + idomain = self._resolve_idomain(dis.idomain.array, botm) self._modelgrid = StructuredGrid( delc=dis.delc.array, delr=dis.delr.array, top=dis.top.array, - botm=dis.botm.array, - idomain=dis.idomain.array, + botm=botm, + idomain=idomain, lenuni=dis.length_units.array, crs=self._modelgrid.crs, xoff=self._modelgrid.xoffset, @@ -403,12 +405,14 @@ def modelgrid(self): angrot=self._modelgrid.angrot, ) else: + botm = dis.botm.array + idomain = self._resolve_idomain(dis.idomain.array, botm) self._modelgrid = VertexGrid( vertices=dis.vertices.array, cell2d=dis.cell2d.array, top=dis.top.array, - botm=dis.botm.array, - idomain=dis.idomain.array, + botm=botm, + idomain=idomain, lenuni=dis.length_units.array, crs=self._modelgrid.crs, xoff=self._modelgrid.xoffset, @@ -498,12 +502,14 @@ def modelgrid(self): angrot=self._modelgrid.angrot, ) else: + botm = dis.botm.array + idomain = self._resolve_idomain(dis.idomain.array, botm) self._modelgrid = VertexGrid( vertices=dis.vertices.array, cell1d=dis.cell1d.array, top=dis.top.array, - botm=dis.botm.array, - idomain=dis.idomain.array, + botm=botm, + idomain=idomain, lenuni=dis.length_units.array, crs=self._modelgrid.crs, xoff=self._modelgrid.xoffset, @@ -1937,3 +1943,12 @@ def plot(self, SelPackList=None, **kwargs): ) return axes + + @staticmethod + def _resolve_idomain(idomain, botm): + if idomain is None: + if botm is None: + return idomain + else: + return np.ones_like(botm) + return idomain From 12cfa825078a20783c0ffbdcd0a252cab57bfae6 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Fri, 28 Jul 2023 09:25:14 -0700 Subject: [PATCH 6/7] fix(notebook): notebook contained out of bounds cellid --- .docs/Notebooks/mf6_data_tutorial06.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.docs/Notebooks/mf6_data_tutorial06.py b/.docs/Notebooks/mf6_data_tutorial06.py index 92e7aa48c..9fd43753a 100644 --- a/.docs/Notebooks/mf6_data_tutorial06.py +++ b/.docs/Notebooks/mf6_data_tutorial06.py @@ -1,13 +1,14 @@ # --- # jupyter: # jupytext: +# notebook_metadata_filter: metadata # text_representation: # extension: .py # format_name: light -# format_version: "1.5" -# jupytext_version: 1.5.1 +# format_version: '1.5' +# jupytext_version: 1.14.4 # kernelspec: -# display_name: Python 3 +# display_name: Python 3 (ipykernel) # language: python # name: python3 # metadata: @@ -159,7 +160,7 @@ # Note that the cellid information (layer, row, column) is encapsulated in # a tuple. -stress_period_data = [((1, 10, 10), 100.0), ((1, 10, 11), 105.0)] +stress_period_data = [((1, 8, 8), 100.0), ((1, 9, 9), 105.0)] # build chd package chd = flopy.mf6.modflow.mfgwfchd.ModflowGwfchd( gwf, From a9abc351c743a9def09efbe095748a3a1fbee79b Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Fri, 28 Jul 2023 13:19:34 -0700 Subject: [PATCH 7/7] fix(modelgrid): always force modelgrid to resync until an idomain array is provided --- autotest/regression/test_mf6.py | 2 +- flopy/mf6/mfmodel.py | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/autotest/regression/test_mf6.py b/autotest/regression/test_mf6.py index 6d49da744..547901447 100644 --- a/autotest/regression/test_mf6.py +++ b/autotest/regression/test_mf6.py @@ -3085,7 +3085,7 @@ def test028_create_tests_sfr(function_tmpdir, example_data_path): delc=5000.0, top=top, botm=botm, - idomain=idomain, + #idomain=idomain, filename=f"{model_name}.dis", ) strt = testutils.read_std_array(os.path.join(pth, "strt.txt"), "float") diff --git a/flopy/mf6/mfmodel.py b/flopy/mf6/mfmodel.py index 079a721e0..b76bb2e71 100644 --- a/flopy/mf6/mfmodel.py +++ b/flopy/mf6/mfmodel.py @@ -346,7 +346,7 @@ def modelgrid(self): model. """ - + force_resync = False if not self._mg_resync: return self._modelgrid if self.get_grid_type() == DiscretizationType.DIS: @@ -371,7 +371,10 @@ def modelgrid(self): ) else: botm = dis.botm.array - idomain = self._resolve_idomain(dis.idomain.array, botm) + idomain = dis.idomain.array + if idomain is None: + force_resync = True + idomain = self._resolve_idomain(idomain, botm) self._modelgrid = StructuredGrid( delc=dis.delc.array, delr=dis.delr.array, @@ -406,7 +409,10 @@ def modelgrid(self): ) else: botm = dis.botm.array - idomain = self._resolve_idomain(dis.idomain.array, botm) + idomain = dis.idomain.array + if idomain is None: + force_resync = True + idomain = self._resolve_idomain(idomain, botm) self._modelgrid = VertexGrid( vertices=dis.vertices.array, cell2d=dis.cell2d.array, @@ -503,7 +509,10 @@ def modelgrid(self): ) else: botm = dis.botm.array - idomain = self._resolve_idomain(dis.idomain.array, botm) + idomain = dis.idomain.array + if idomain is None: + force_resync = True + idomain = self._resolve_idomain(idomain, botm) self._modelgrid = VertexGrid( vertices=dis.vertices.array, cell1d=dis.cell1d.array, @@ -552,7 +561,7 @@ def modelgrid(self): angrot, self._modelgrid.crs, ) - self._mg_resync = not self._modelgrid.is_complete + self._mg_resync = not self._modelgrid.is_complete or force_resync return self._modelgrid @property