From c56fce33d3b9e4dde41f357185209252776a12a6 Mon Sep 17 00:00:00 2001 From: scottrp <45947939+scottrp@users.noreply.github.com> Date: Tue, 12 Sep 2023 09:44:56 -0700 Subject: [PATCH 1/2] fix(remove_model): remove_model method fix and tests Method remove_model removes all references to the model from the simulation namefile. Tests added to autotest. --- autotest/regression/test_mf6.py | 13 ++++++++++++- flopy/mf6/mfsimbase.py | 31 ++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/autotest/regression/test_mf6.py b/autotest/regression/test_mf6.py index 5479014475..408165187e 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") @@ -3989,6 +3989,17 @@ def test006_2models_different_dis(function_tmpdir, example_data_path): assert gnc_data[0][1] == (0, 0) assert gnc_data[0][2] == (0, 1, 1) + # test remove_model + sim2.remove_model(model_name_2) + sim2.write_simulation() + success, buff = sim2.run_simulation() + assert success + sim3 = MFSimulation.load(sim_ws=sim.sim_path) + assert sim3.get_model(model_name_1) is not None + assert sim3.get_model(model_name_2) is None + assert len(sim3.name_file.models.get_data()) == 1 + assert sim3.name_file.exchanges.get_data() is None + sim.delete_output_files() diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index 1c96c23b46..264f35fdbd 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -2183,11 +2183,36 @@ def remove_model(self, model_name): Model name to remove from simulation """ - # Remove model + # remove model del self._models[model_name] - # TODO: Fully implement this - # Update simulation name file + # remove from solution group block + self._remove_from_all_solution_groups(model_name) + + # remove from models block + models_recarray = self.name_file.models.get_data() + if models_recarray is not None: + new_records = [] + for record in models_recarray: + if len(record) <= 2 or record[2] != model_name: + new_records.append(tuple(record)) + self.name_file.models.set_data(new_records) + + # remove from exchanges block + exch_recarray = self.name_file.exchanges.get_data() + if exch_recarray is not None: + new_records = [] + for record in exch_recarray: + model_in_record = False + if len(record) > 2: + for item in list(record)[2:]: + if item == model_name: + model_in_record = True + if not model_in_record: + new_records.append(tuple(record)) + if len(new_records) == 0: + new_records = None + self.name_file.exchanges.set_data(new_records) def is_valid(self): """ From ed5e079badbb65e1327b9ac0c158b2683c6203ac Mon Sep 17 00:00:00 2001 From: Wes Bonelli Date: Thu, 14 Sep 2023 17:01:05 -0400 Subject: [PATCH 2/2] test(remove_model): add narrow-scoped test for remove_model --- autotest/test_mf6.py | 47 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/autotest/test_mf6.py b/autotest/test_mf6.py index 7bead499c9..71d231da40 100644 --- a/autotest/test_mf6.py +++ b/autotest/test_mf6.py @@ -2244,14 +2244,14 @@ def test_multi_model(function_tmpdir): @requires_exe("mf6") -def test_namefile_creation(tmpdir): +def test_namefile_creation(function_tmpdir): test_ex_name = "test_namefile" # build MODFLOW 6 files sim = MFSimulation( sim_name=test_ex_name, version="mf6", exe_name="mf6", - sim_ws=str(tmpdir), + sim_ws=str(function_tmpdir), ) tdis_rc = [(6.0, 2, 1.0), (6.0, 3, 1.0), (6.0, 3, 1.0), (6.0, 3, 1.0)] @@ -2293,3 +2293,46 @@ def test_namefile_creation(tmpdir): except flopy.mf6.mfbase.FlopyException: ex_happened = True assert ex_happened + + +def test_remove_model(function_tmpdir, example_data_path): + # load a multi-model simulation + sim_ws = str(example_data_path / "mf6" / "test006_2models_mvr") + sim = MFSimulation.load(sim_ws=sim_ws, exe_name="mf6") + + # original simulation should contain models: + # - 'parent', with files named 'model1.ext' + # - 'child', with files named 'model2.ext' + assert len(sim.model_names) == 2 + assert "parent" in sim.model_names + assert "child" in sim.model_names + + # remove the child model + sim.remove_model("child") + + # simulation should now only contain the parent model + assert len(sim.model_names) == 1 + assert "parent" in sim.model_names + + # write simulation input files + sim.set_sim_path(function_tmpdir) + sim.write_simulation() + + # there should be no input files for the child model + files = list(function_tmpdir.glob("*")) + assert not any("model2" in f.name for f in files) + + # there should be no model or solver entry for the child model in the simulation namefile + lines = open(function_tmpdir / "mfsim.nam").readlines() + lines = [l.lower().strip() for l in lines] + assert not any("model2" in l for l in lines) + assert not any("child" in l for l in lines) + + # there should be no exchanges either + exg_index = 0 + for i, l in enumerate(lines): + if "begin exchanges" in l: + exg_index = i + elif exg_index > 0: + assert "end exchanges" in l + break