From fbc83e9a65d4abe36fa3a41334f941fae05f2952 Mon Sep 17 00:00:00 2001 From: Bonelli Date: Sun, 15 Feb 2026 09:54:09 -0500 Subject: [PATCH 1/6] fix(mfdatascalar): skip fields with default values --- autotest/test_mf6_optional_default_value.py | 92 +++++++++++++++++++++ flopy/mf6/data/mfdatascalar.py | 16 ++++ flopy/mf6/data/mfstructure.py | 2 +- flopy/mf6/mfsimbase.py | 3 + flopy/mf6/modflow/mfsimulation.py | 8 ++ 5 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 autotest/test_mf6_optional_default_value.py diff --git a/autotest/test_mf6_optional_default_value.py b/autotest/test_mf6_optional_default_value.py new file mode 100644 index 0000000000..19f3b30261 --- /dev/null +++ b/autotest/test_mf6_optional_default_value.py @@ -0,0 +1,92 @@ +""" +Test that optional package variables with default values aren't +written to input files when the value is the default, unless an +explicit option `write_defaults` is set. + +Reproduce https://github.com/modflowpy/flopy/issues/2710: +ModflowPrtprp.coordinate_check_method was introduced in MF6.7.0 and +defaults to "eager". flopy 3.10.0 wrote COORDINATE_CHECK_METHOD EAGER +unconditionally, causing errors when used with older MF6 binaries. +""" + +from pathlib import Path + +import pytest + +import flopy + +pytestmark = pytest.mark.mf6 + + +def _build_prt_sim(ws, coordinate_check_method="eager", write_defaults=False): + sim = flopy.mf6.MFSimulation( + sim_name="prt", + sim_ws=str(ws), + write_defaults=write_defaults, + ) + flopy.mf6.ModflowTdis(sim, nper=1, perioddata=[(1.0, 1, 1.0)]) + ems = flopy.mf6.ModflowEms(sim) + prt = flopy.mf6.ModflowPrt(sim, modelname="prt") + flopy.mf6.ModflowPrtdis( + prt, + nlay=1, + nrow=1, + ncol=3, + delr=1.0, + delc=1.0, + top=1.0, + botm=0.0, + ) + flopy.mf6.ModflowPrtmip(prt, porosity=0.1) + flopy.mf6.ModflowPrtprp( + prt, + nreleasepts=1, + packagedata=[(0, (0, 0, 0), 0.5, 0.5, 0.5)], + perioddata={0: ["FIRST"]}, + coordinate_check_method=coordinate_check_method, + ) + flopy.mf6.ModflowPrtoc(prt, track_filerecord=[("prt.trk",)]) + sim.register_solution_package(ems, [prt.name]) + return sim + + +def _prp_text(ws): + prp_files = list(Path(ws).glob("*.prp")) + assert len(prp_files) == 1, f"expected one .prp file, found: {prp_files}" + return prp_files[0].read_text().upper() + + +def test_coordinate_check_method(function_tmpdir): + case = "none" + ws = Path(function_tmpdir) / case + ws.mkdir() + sim = _build_prt_sim(ws, coordinate_check_method=case) + sim.write_simulation() + text = _prp_text(ws) + assert "COORDINATE_CHECK_METHOD" in text + assert "NONE" in text + + case = "eager" + ws = Path(function_tmpdir) / case + ws.mkdir() + sim = _build_prt_sim(ws, coordinate_check_method=case) + sim.write_simulation() + text = _prp_text(ws) + assert "COORDINATE_CHECK_METHOD" not in text + + case = "toggle" + ws = Path(function_tmpdir) / case + ws.mkdir() + sim = _build_prt_sim(ws, write_defaults=True) + sim.write_simulation() + text = _prp_text(ws) + assert "COORDINATE_CHECK_METHOD" in text + assert "EAGER" in text + + case = "toggle_sim" + ws = Path(function_tmpdir) / case + ws.mkdir() + sim = _build_prt_sim(ws) + sim.simulation_data.write_defaults = True + sim.write_simulation() + assert "COORDINATE_CHECK_METHOD" in _prp_text(ws) diff --git a/flopy/mf6/data/mfdatascalar.py b/flopy/mf6/data/mfdatascalar.py index 94c4f1e3fd..9abab4e5a7 100644 --- a/flopy/mf6/data/mfdatascalar.py +++ b/flopy/mf6/data/mfdatascalar.py @@ -361,6 +361,22 @@ def get_file_entry( self._simulation_data.debug, ex, ) + if self.structure.optional: + data_item = self.structure.data_item_structures[0] + if data_item.default_value is not None: + current = storage.get_data() + try: + matches_default = float(str(current)) == float( + data_item.default_value + ) + except (ValueError, TypeError): + matches_default = str(current).lower().strip() == ( + data_item.default_value.lower().strip() + ) + if matches_default and not ( + self._simulation_data.write_defaults + ): + return "" if ( self.structure.type == DatumType.keyword or self.structure.type == DatumType.record diff --git a/flopy/mf6/data/mfstructure.py b/flopy/mf6/data/mfstructure.py index 3a44b4f9ab..649cfbcb90 100644 --- a/flopy/mf6/data/mfstructure.py +++ b/flopy/mf6/data/mfstructure.py @@ -614,7 +614,7 @@ def set_value(self, line, common): self.ucase = bool(arr_line[1]) elif arr_line[0] == "preserve_case": self.preserve_case = self._get_boolean_val(arr_line) - elif arr_line[0] == "default_value": + elif arr_line[0] in ("default_value", "default"): self.default_value = " ".join(arr_line[1:]) elif arr_line[0] == "numeric_index": self.numeric_index = self._get_boolean_val(arr_line) diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index 273970bb62..e72df881c6 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -259,6 +259,7 @@ def __init__(self, path: Union[str, PathLike], mfsim): self._verbosity_level = VerbosityLevel.normal self._max_columns_set_by = None # Can be None, 'user', or 'auto' self.use_pandas = True + self.write_defaults = False self._update_str_format() @@ -495,6 +496,7 @@ def __init__( write_headers=True, lazy_io=False, use_pandas=True, + write_defaults=False, ): self.name = sim_name self.simulation_data = MFSimulationData(sim_ws, self) @@ -503,6 +505,7 @@ def __init__( ) self.simulation_data.write_headers = write_headers self.simulation_data.use_pandas = use_pandas + self.simulation_data.write_defaults = write_defaults if lazy_io: self.simulation_data.lazy_io = True self._package_container = PackageContainer(self.simulation_data) diff --git a/flopy/mf6/modflow/mfsimulation.py b/flopy/mf6/modflow/mfsimulation.py index f618cc18c3..c2aa20450b 100644 --- a/flopy/mf6/modflow/mfsimulation.py +++ b/flopy/mf6/modflow/mfsimulation.py @@ -40,6 +40,12 @@ class MFSimulation(MFSimulationBase): both off. use_pandas: bool, default True Load/save data using pandas dataframes (for supported data). + write_defaults: bool, default False + When True, flopy writes optional input variables to package files even + when their value equals the declared DFN default. When False + (default), such variables are omitted because MF6 applies the same + default internally, keeping output files shorter and compatible with + older MF6 versions that may not recognise recently-added keywords. continue_ : keyword keyword flag to indicate that the simulation should continue even if one or more solutions do not converge. @@ -123,6 +129,7 @@ def __init__( write_headers: bool = True, use_pandas: bool = True, lazy_io: bool = False, + write_defaults: bool = False, continue_=None, nocheck=None, memory_print_option=None, @@ -141,6 +148,7 @@ def __init__( write_headers=write_headers, lazy_io=lazy_io, use_pandas=use_pandas, + write_defaults=write_defaults, ) self.name_file.continue_.set_data(continue_) From 3fd2d1110cb93aab0f151928201e4f3999aad51c Mon Sep 17 00:00:00 2001 From: Bonelli Date: Sun, 15 Feb 2026 11:54:59 -0500 Subject: [PATCH 2/6] remove from init --- autotest/test_mf6_optional_default_value.py | 7 ++----- flopy/mf6/mfsimbase.py | 2 -- flopy/mf6/modflow/mfsimulation.py | 8 -------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/autotest/test_mf6_optional_default_value.py b/autotest/test_mf6_optional_default_value.py index 19f3b30261..66f23a5058 100644 --- a/autotest/test_mf6_optional_default_value.py +++ b/autotest/test_mf6_optional_default_value.py @@ -19,11 +19,8 @@ def _build_prt_sim(ws, coordinate_check_method="eager", write_defaults=False): - sim = flopy.mf6.MFSimulation( - sim_name="prt", - sim_ws=str(ws), - write_defaults=write_defaults, - ) + sim = flopy.mf6.MFSimulation(sim_name="prt", sim_ws=str(ws)) + sim.simulation_data.write_defaults = write_defaults flopy.mf6.ModflowTdis(sim, nper=1, perioddata=[(1.0, 1, 1.0)]) ems = flopy.mf6.ModflowEms(sim) prt = flopy.mf6.ModflowPrt(sim, modelname="prt") diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index e72df881c6..def3a1803d 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -496,7 +496,6 @@ def __init__( write_headers=True, lazy_io=False, use_pandas=True, - write_defaults=False, ): self.name = sim_name self.simulation_data = MFSimulationData(sim_ws, self) @@ -505,7 +504,6 @@ def __init__( ) self.simulation_data.write_headers = write_headers self.simulation_data.use_pandas = use_pandas - self.simulation_data.write_defaults = write_defaults if lazy_io: self.simulation_data.lazy_io = True self._package_container = PackageContainer(self.simulation_data) diff --git a/flopy/mf6/modflow/mfsimulation.py b/flopy/mf6/modflow/mfsimulation.py index c2aa20450b..f618cc18c3 100644 --- a/flopy/mf6/modflow/mfsimulation.py +++ b/flopy/mf6/modflow/mfsimulation.py @@ -40,12 +40,6 @@ class MFSimulation(MFSimulationBase): both off. use_pandas: bool, default True Load/save data using pandas dataframes (for supported data). - write_defaults: bool, default False - When True, flopy writes optional input variables to package files even - when their value equals the declared DFN default. When False - (default), such variables are omitted because MF6 applies the same - default internally, keeping output files shorter and compatible with - older MF6 versions that may not recognise recently-added keywords. continue_ : keyword keyword flag to indicate that the simulation should continue even if one or more solutions do not converge. @@ -129,7 +123,6 @@ def __init__( write_headers: bool = True, use_pandas: bool = True, lazy_io: bool = False, - write_defaults: bool = False, continue_=None, nocheck=None, memory_print_option=None, @@ -148,7 +141,6 @@ def __init__( write_headers=write_headers, lazy_io=lazy_io, use_pandas=use_pandas, - write_defaults=write_defaults, ) self.name_file.continue_.set_data(continue_) From bb9e1cc162936a4ab3a451eff4e0824dc4922620 Mon Sep 17 00:00:00 2001 From: Bonelli Date: Sun, 15 Feb 2026 13:10:37 -0500 Subject: [PATCH 3/6] only non-numeric --- flopy/mf6/data/mfdatascalar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flopy/mf6/data/mfdatascalar.py b/flopy/mf6/data/mfdatascalar.py index 9abab4e5a7..4d4c059cd2 100644 --- a/flopy/mf6/data/mfdatascalar.py +++ b/flopy/mf6/data/mfdatascalar.py @@ -363,7 +363,7 @@ def get_file_entry( ) if self.structure.optional: data_item = self.structure.data_item_structures[0] - if data_item.default_value is not None: + if data_item.default_value is not None and data_item.valid_values: current = storage.get_data() try: matches_default = float(str(current)) == float( From 70177c70a9a82d363d385acc3b84ec6708cdba10 Mon Sep 17 00:00:00 2001 From: Bonelli Date: Tue, 17 Feb 2026 19:13:33 -0500 Subject: [PATCH 4/6] default optionals to None instead --- autotest/test_mf6_optional_default_value.py | 53 ++++++++++----------- flopy/mf6/data/mfdatascalar.py | 16 ------- flopy/mf6/mfsimbase.py | 1 - flopy/mf6/modflow/mfgwedis.py | 10 ++++ flopy/mf6/modflow/mfgwedisu.py | 12 ++++- flopy/mf6/modflow/mfgwedisv.py | 10 ++++ flopy/mf6/modflow/mfgweest.py | 6 +-- flopy/mf6/modflow/mfgwfbuy.py | 2 +- flopy/mf6/modflow/mfgwfchdg.py | 10 ++++ flopy/mf6/modflow/mfgwfcsub.py | 4 +- flopy/mf6/modflow/mfgwfdis.py | 10 ++++ flopy/mf6/modflow/mfgwfdisu.py | 12 ++++- flopy/mf6/modflow/mfgwfdisv.py | 10 ++++ flopy/mf6/modflow/mfgwfdrng.py | 9 ++++ flopy/mf6/modflow/mfgwfghbg.py | 10 ++++ flopy/mf6/modflow/mfgwfrivg.py | 9 ++++ flopy/mf6/modflow/mfgwfvsc.py | 8 ++-- flopy/mf6/modflow/mfgwfwelg.py | 10 ++++ flopy/mf6/modflow/mfgwtdis.py | 10 ++++ flopy/mf6/modflow/mfgwtdisu.py | 12 ++++- flopy/mf6/modflow/mfgwtdisv.py | 10 ++++ flopy/mf6/modflow/mfprtdis.py | 10 ++++ flopy/mf6/modflow/mfprtdisv.py | 10 ++++ flopy/mf6/modflow/mfprtprp.py | 4 +- flopy/mf6/utils/codegen/filters.py | 6 +++ 25 files changed, 204 insertions(+), 60 deletions(-) diff --git a/autotest/test_mf6_optional_default_value.py b/autotest/test_mf6_optional_default_value.py index 66f23a5058..35d37d8499 100644 --- a/autotest/test_mf6_optional_default_value.py +++ b/autotest/test_mf6_optional_default_value.py @@ -1,12 +1,17 @@ """ -Test that optional package variables with default values aren't -written to input files when the value is the default, unless an -explicit option `write_defaults` is set. +Test that optional package variables with default values aren't written to +input files when not explicitly set by the user. Reproduce https://github.com/modflowpy/flopy/issues/2710: -ModflowPrtprp.coordinate_check_method was introduced in MF6.7.0 and +ModflowPrtprp.coordinate_check_method was introduced in MF6 6.7.0 and defaults to "eager". flopy 3.10.0 wrote COORDINATE_CHECK_METHOD EAGER -unconditionally, causing errors when used with older MF6 binaries. +unconditionally (because the generated __init__ used the DFN default as the +Python default), causing errors when used with older MF6 binaries. + +The fix: optional scalar fields use None as their Python __init__ default. +The existing "if data is None, don't write" gate in get_file_entry() then +handles suppression naturally. If the user explicitly sets the value it is +always written, regardless of whether it matches MF6's internal default. """ from pathlib import Path @@ -18,9 +23,8 @@ pytestmark = pytest.mark.mf6 -def _build_prt_sim(ws, coordinate_check_method="eager", write_defaults=False): +def _build_prt_sim(ws, coordinate_check_method=None): sim = flopy.mf6.MFSimulation(sim_name="prt", sim_ws=str(ws)) - sim.simulation_data.write_defaults = write_defaults flopy.mf6.ModflowTdis(sim, nper=1, perioddata=[(1.0, 1, 1.0)]) ems = flopy.mf6.ModflowEms(sim) prt = flopy.mf6.ModflowPrt(sim, modelname="prt") @@ -54,36 +58,29 @@ def _prp_text(ws): def test_coordinate_check_method(function_tmpdir): - case = "none" - ws = Path(function_tmpdir) / case + # Not set (None default): should NOT appear in the input file. + # MF6 applies its own internal default (eager) when the keyword is absent. + ws = Path(function_tmpdir) / "default" ws.mkdir() - sim = _build_prt_sim(ws, coordinate_check_method=case) + sim = _build_prt_sim(ws) sim.write_simulation() - text = _prp_text(ws) - assert "COORDINATE_CHECK_METHOD" in text - assert "NONE" in text + assert "COORDINATE_CHECK_METHOD" not in _prp_text(ws) - case = "eager" - ws = Path(function_tmpdir) / case + # Explicitly set to "none": should be written. + ws = Path(function_tmpdir) / "none" ws.mkdir() - sim = _build_prt_sim(ws, coordinate_check_method=case) + sim = _build_prt_sim(ws, coordinate_check_method="none") sim.write_simulation() text = _prp_text(ws) - assert "COORDINATE_CHECK_METHOD" not in text + assert "COORDINATE_CHECK_METHOD" in text + assert "NONE" in text - case = "toggle" - ws = Path(function_tmpdir) / case + # Explicitly set to "eager": should also be written. + # Explicit values are always written regardless of MF6's internal default. + ws = Path(function_tmpdir) / "eager" ws.mkdir() - sim = _build_prt_sim(ws, write_defaults=True) + sim = _build_prt_sim(ws, coordinate_check_method="eager") sim.write_simulation() text = _prp_text(ws) assert "COORDINATE_CHECK_METHOD" in text assert "EAGER" in text - - case = "toggle_sim" - ws = Path(function_tmpdir) / case - ws.mkdir() - sim = _build_prt_sim(ws) - sim.simulation_data.write_defaults = True - sim.write_simulation() - assert "COORDINATE_CHECK_METHOD" in _prp_text(ws) diff --git a/flopy/mf6/data/mfdatascalar.py b/flopy/mf6/data/mfdatascalar.py index 4d4c059cd2..94c4f1e3fd 100644 --- a/flopy/mf6/data/mfdatascalar.py +++ b/flopy/mf6/data/mfdatascalar.py @@ -361,22 +361,6 @@ def get_file_entry( self._simulation_data.debug, ex, ) - if self.structure.optional: - data_item = self.structure.data_item_structures[0] - if data_item.default_value is not None and data_item.valid_values: - current = storage.get_data() - try: - matches_default = float(str(current)) == float( - data_item.default_value - ) - except (ValueError, TypeError): - matches_default = str(current).lower().strip() == ( - data_item.default_value.lower().strip() - ) - if matches_default and not ( - self._simulation_data.write_defaults - ): - return "" if ( self.structure.type == DatumType.keyword or self.structure.type == DatumType.record diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index def3a1803d..273970bb62 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -259,7 +259,6 @@ def __init__(self, path: Union[str, PathLike], mfsim): self._verbosity_level = VerbosityLevel.normal self._max_columns_set_by = None # Can be None, 'user', or 'auto' self.use_pandas = True - self.write_defaults = False self._update_str_format() diff --git a/flopy/mf6/modflow/mfgwedis.py b/flopy/mf6/modflow/mfgwedis.py index 304cc6e100..0a2a135331 100644 --- a/flopy/mf6/modflow/mfgwedis.py +++ b/flopy/mf6/modflow/mfgwedis.py @@ -54,6 +54,13 @@ class ModflowGwedis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -95,6 +102,7 @@ class ModflowGwedis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("gwe6", "dis", "options", "grb_filerecord")) + crs = ArrayTemplateGenerator(("gwe6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("gwe6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("gwe6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("gwe6", "dis", "griddata", "delc")) @@ -330,6 +338,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=1, nrow=2, @@ -365,6 +374,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwedisu.py b/flopy/mf6/modflow/mfgwedisu.py index 7339edf08f..a40532dabe 100644 --- a/flopy/mf6/modflow/mfgwedisu.py +++ b/flopy/mf6/modflow/mfgwedisu.py @@ -58,6 +58,13 @@ class ModflowGwedisu(MFPackage): export_array_ascii : keyword keyword that specifies input griddata arrays should be written to layered ascii output files. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. nodes : integer is the number of cells in the model grid. nja : integer @@ -177,6 +184,7 @@ class ModflowGwedisu(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwe6", "disu", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("gwe6", "disu", "options", "crs")) top = ArrayTemplateGenerator(("gwe6", "disu", "griddata", "top")) bot = ArrayTemplateGenerator(("gwe6", "disu", "griddata", "bot")) area = ArrayTemplateGenerator(("gwe6", "disu", "griddata", "area")) @@ -496,8 +504,9 @@ def __init__( xorigin=None, yorigin=None, angrot=None, - vertical_offset_tolerance=0.0, + vertical_offset_tolerance=None, export_array_ascii=None, + crs=None, nodes=None, nja=None, nvert=None, @@ -539,6 +548,7 @@ def __init__( self.export_array_ascii = self.build_mfdata( "export_array_ascii", export_array_ascii ) + self.crs = self.build_mfdata("crs", crs) self.nodes = self.build_mfdata("nodes", nodes) self.nja = self.build_mfdata("nja", nja) self.nvert = self.build_mfdata("nvert", nvert) diff --git a/flopy/mf6/modflow/mfgwedisv.py b/flopy/mf6/modflow/mfgwedisv.py index 389c20f60c..f3fb97bca1 100644 --- a/flopy/mf6/modflow/mfgwedisv.py +++ b/flopy/mf6/modflow/mfgwedisv.py @@ -57,6 +57,13 @@ class ModflowGwedisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -123,6 +130,7 @@ class ModflowGwedisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwe6", "disv", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("gwe6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("gwe6", "disv", "options", "ncf_filerecord") ) @@ -429,6 +437,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=None, ncpl=None, @@ -464,6 +473,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgweest.py b/flopy/mf6/modflow/mfgweest.py index b7e021a94c..5eb29753eb 100644 --- a/flopy/mf6/modflow/mfgweest.py +++ b/flopy/mf6/modflow/mfgweest.py @@ -205,9 +205,9 @@ def __init__( save_flows=None, zero_order_decay_water=None, zero_order_decay_solid=None, - density_water=1000.0, - heat_capacity_water=4184.0, - latent_heat_vaporization=2453500.0, + density_water=None, + heat_capacity_water=None, + latent_heat_vaporization=None, porosity=None, decay_water=None, decay_solid=None, diff --git a/flopy/mf6/modflow/mfgwfbuy.py b/flopy/mf6/modflow/mfgwfbuy.py index fd7e4d6824..8619a754fe 100644 --- a/flopy/mf6/modflow/mfgwfbuy.py +++ b/flopy/mf6/modflow/mfgwfbuy.py @@ -221,7 +221,7 @@ def __init__( model, loading_package=False, hhformulation_rhs=None, - denseref=1000.0, + denseref=None, density_filerecord=None, dev_efh_formulation=None, nrhospecies=None, diff --git a/flopy/mf6/modflow/mfgwfchdg.py b/flopy/mf6/modflow/mfgwfchdg.py index 8b6148cec0..61dae704c3 100644 --- a/flopy/mf6/modflow/mfgwfchdg.py +++ b/flopy/mf6/modflow/mfgwfchdg.py @@ -19,6 +19,14 @@ class ModflowGwfchdg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. + readarraygrid : keyword + indicates that array-based grid input will be used for the constant head + package. this keyword must be specified to use array-based grid input. when + readarraygrid is specified, values must be provided for every cell within a + model grid, even those cells that have an idomain value less than one. values + assigned to cells with idomain values less than one are not used and have no + effect on simulation results. no data cells should contain the value dnodata + (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -243,6 +251,7 @@ def __init__( self, model, loading_package=False, + readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -268,6 +277,7 @@ def __init__( **kwargs, ) + self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwfcsub.py b/flopy/mf6/modflow/mfgwfcsub.py index e59a3ac517..362f97b662 100644 --- a/flopy/mf6/modflow/mfgwfcsub.py +++ b/flopy/mf6/modflow/mfgwfcsub.py @@ -1024,8 +1024,8 @@ def __init__( boundnames=None, print_input=None, save_flows=None, - gammaw=9806.65, - beta=4.6512e-10, + gammaw=None, + beta=None, head_based=None, initial_preconsolidation_head=None, ndelaycells=None, diff --git a/flopy/mf6/modflow/mfgwfdis.py b/flopy/mf6/modflow/mfgwfdis.py index d28c91ea50..e761c2ce9e 100644 --- a/flopy/mf6/modflow/mfgwfdis.py +++ b/flopy/mf6/modflow/mfgwfdis.py @@ -54,6 +54,13 @@ class ModflowGwfdis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -95,6 +102,7 @@ class ModflowGwfdis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("gwf6", "dis", "options", "grb_filerecord")) + crs = ArrayTemplateGenerator(("gwf6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("gwf6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("gwf6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("gwf6", "dis", "griddata", "delc")) @@ -330,6 +338,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=1, nrow=2, @@ -365,6 +374,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwfdisu.py b/flopy/mf6/modflow/mfgwfdisu.py index e45634f643..8dea8e4a62 100644 --- a/flopy/mf6/modflow/mfgwfdisu.py +++ b/flopy/mf6/modflow/mfgwfdisu.py @@ -58,6 +58,13 @@ class ModflowGwfdisu(MFPackage): export_array_ascii : keyword keyword that specifies input griddata arrays should be written to layered ascii output files. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. nodes : integer is the number of cells in the model grid. nja : integer @@ -177,6 +184,7 @@ class ModflowGwfdisu(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwf6", "disu", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("gwf6", "disu", "options", "crs")) top = ArrayTemplateGenerator(("gwf6", "disu", "griddata", "top")) bot = ArrayTemplateGenerator(("gwf6", "disu", "griddata", "bot")) area = ArrayTemplateGenerator(("gwf6", "disu", "griddata", "area")) @@ -496,8 +504,9 @@ def __init__( xorigin=None, yorigin=None, angrot=None, - vertical_offset_tolerance=0.0, + vertical_offset_tolerance=None, export_array_ascii=None, + crs=None, nodes=None, nja=None, nvert=None, @@ -539,6 +548,7 @@ def __init__( self.export_array_ascii = self.build_mfdata( "export_array_ascii", export_array_ascii ) + self.crs = self.build_mfdata("crs", crs) self.nodes = self.build_mfdata("nodes", nodes) self.nja = self.build_mfdata("nja", nja) self.nvert = self.build_mfdata("nvert", nvert) diff --git a/flopy/mf6/modflow/mfgwfdisv.py b/flopy/mf6/modflow/mfgwfdisv.py index 457ba7c05c..9192cc04ef 100644 --- a/flopy/mf6/modflow/mfgwfdisv.py +++ b/flopy/mf6/modflow/mfgwfdisv.py @@ -57,6 +57,13 @@ class ModflowGwfdisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -123,6 +130,7 @@ class ModflowGwfdisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwf6", "disv", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("gwf6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("gwf6", "disv", "options", "ncf_filerecord") ) @@ -429,6 +437,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=None, ncpl=None, @@ -464,6 +473,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwfdrng.py b/flopy/mf6/modflow/mfgwfdrng.py index e1386a1118..3431d9d896 100644 --- a/flopy/mf6/modflow/mfgwfdrng.py +++ b/flopy/mf6/modflow/mfgwfdrng.py @@ -19,6 +19,13 @@ class ModflowGwfdrng(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. + readarraygrid : keyword + indicates that array-based grid input will be used for the drain package. this + keyword must be specified to use array-based grid input. when readarraygrid is + specified, values must be provided for every cell within a model grid, even + those cells that have an idomain value less than one. values assigned to cells + with idomain values less than one are not used and have no effect on simulation + results. no data cells should contain the value dnodata (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -290,6 +297,7 @@ def __init__( self, model, loading_package=False, + readarraygrid=True, auxiliary=None, auxmultname=None, auxdepthname=None, @@ -318,6 +326,7 @@ def __init__( **kwargs, ) + self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.auxdepthname = self.build_mfdata("auxdepthname", auxdepthname) diff --git a/flopy/mf6/modflow/mfgwfghbg.py b/flopy/mf6/modflow/mfgwfghbg.py index 415872ee4e..0adf8712c0 100644 --- a/flopy/mf6/modflow/mfgwfghbg.py +++ b/flopy/mf6/modflow/mfgwfghbg.py @@ -19,6 +19,14 @@ class ModflowGwfghbg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. + readarraygrid : keyword + indicates that array-based grid input will be used for the general-head + boundary package. this keyword must be specified to use array-based grid + input. when readarraygrid is specified, values must be provided for every cell + within a model grid, even those cells that have an idomain value less than one. + values assigned to cells with idomain values less than one are not used and + have no effect on simulation results. no data cells should contain the value + dnodata (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -261,6 +269,7 @@ def __init__( self, model, loading_package=False, + readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -287,6 +296,7 @@ def __init__( **kwargs, ) + self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwfrivg.py b/flopy/mf6/modflow/mfgwfrivg.py index 3472aef279..5b011325ea 100644 --- a/flopy/mf6/modflow/mfgwfrivg.py +++ b/flopy/mf6/modflow/mfgwfrivg.py @@ -19,6 +19,13 @@ class ModflowGwfrivg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. + readarraygrid : keyword + indicates that array-based grid input will be used for the river package. this + keyword must be specified to use array-based grid input. when readarraygrid is + specified, values must be provided for every cell within a model grid, even + those cells that have an idomain value less than one. values assigned to cells + with idomain values less than one are not used and have no effect on simulation + results. no data cells should contain the value dnodata (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -272,6 +279,7 @@ def __init__( self, model, loading_package=False, + readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -299,6 +307,7 @@ def __init__( **kwargs, ) + self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwfvsc.py b/flopy/mf6/modflow/mfgwfvsc.py index 6e6444ef50..67c1657ccb 100644 --- a/flopy/mf6/modflow/mfgwfvsc.py +++ b/flopy/mf6/modflow/mfgwfvsc.py @@ -271,12 +271,12 @@ def __init__( self, model, loading_package=False, - viscref=1.0, + viscref=None, temperature_species_name=None, thermal_formulation=None, - thermal_a2=10.0, - thermal_a3=248.37, - thermal_a4=133.15, + thermal_a2=None, + thermal_a3=None, + thermal_a4=None, viscosity_filerecord=None, nviscspecies=None, packagedata=None, diff --git a/flopy/mf6/modflow/mfgwfwelg.py b/flopy/mf6/modflow/mfgwfwelg.py index 5fec9ff505..f3ef6c8828 100644 --- a/flopy/mf6/modflow/mfgwfwelg.py +++ b/flopy/mf6/modflow/mfgwfwelg.py @@ -19,6 +19,14 @@ class ModflowGwfwelg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. + readarraygrid : keyword + indicates that array-based grid input will be used for the well boundary + package. this keyword must be specified to use array-based grid input. when + readarraygrid is specified, values must be provided for every cell within a + model grid, even those cells that have an idomain value less than one. values + assigned to cells with idomain values less than one are not used and have no + effect on simulation results. no data cells should contain the value dnodata + (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -333,6 +341,7 @@ def __init__( self, model, loading_package=False, + readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -361,6 +370,7 @@ def __init__( **kwargs, ) + self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwtdis.py b/flopy/mf6/modflow/mfgwtdis.py index a32722915f..c8d6df9fa8 100644 --- a/flopy/mf6/modflow/mfgwtdis.py +++ b/flopy/mf6/modflow/mfgwtdis.py @@ -54,6 +54,13 @@ class ModflowGwtdis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -95,6 +102,7 @@ class ModflowGwtdis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("gwt6", "dis", "options", "grb_filerecord")) + crs = ArrayTemplateGenerator(("gwt6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("gwt6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("gwt6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("gwt6", "dis", "griddata", "delc")) @@ -330,6 +338,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=1, nrow=2, @@ -365,6 +374,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwtdisu.py b/flopy/mf6/modflow/mfgwtdisu.py index df4674d08f..7336cd98a1 100644 --- a/flopy/mf6/modflow/mfgwtdisu.py +++ b/flopy/mf6/modflow/mfgwtdisu.py @@ -58,6 +58,13 @@ class ModflowGwtdisu(MFPackage): export_array_ascii : keyword keyword that specifies input griddata arrays should be written to layered ascii output files. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. nodes : integer is the number of cells in the model grid. nja : integer @@ -177,6 +184,7 @@ class ModflowGwtdisu(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwt6", "disu", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("gwt6", "disu", "options", "crs")) top = ArrayTemplateGenerator(("gwt6", "disu", "griddata", "top")) bot = ArrayTemplateGenerator(("gwt6", "disu", "griddata", "bot")) area = ArrayTemplateGenerator(("gwt6", "disu", "griddata", "area")) @@ -496,8 +504,9 @@ def __init__( xorigin=None, yorigin=None, angrot=None, - vertical_offset_tolerance=0.0, + vertical_offset_tolerance=None, export_array_ascii=None, + crs=None, nodes=None, nja=None, nvert=None, @@ -539,6 +548,7 @@ def __init__( self.export_array_ascii = self.build_mfdata( "export_array_ascii", export_array_ascii ) + self.crs = self.build_mfdata("crs", crs) self.nodes = self.build_mfdata("nodes", nodes) self.nja = self.build_mfdata("nja", nja) self.nvert = self.build_mfdata("nvert", nvert) diff --git a/flopy/mf6/modflow/mfgwtdisv.py b/flopy/mf6/modflow/mfgwtdisv.py index 469999a33e..4e85f286b7 100644 --- a/flopy/mf6/modflow/mfgwtdisv.py +++ b/flopy/mf6/modflow/mfgwtdisv.py @@ -57,6 +57,13 @@ class ModflowGwtdisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -123,6 +130,7 @@ class ModflowGwtdisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwt6", "disv", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("gwt6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("gwt6", "disv", "options", "ncf_filerecord") ) @@ -429,6 +437,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=None, ncpl=None, @@ -464,6 +473,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfprtdis.py b/flopy/mf6/modflow/mfprtdis.py index 89ea68f765..3e90366657 100644 --- a/flopy/mf6/modflow/mfprtdis.py +++ b/flopy/mf6/modflow/mfprtdis.py @@ -54,6 +54,13 @@ class ModflowPrtdis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -95,6 +102,7 @@ class ModflowPrtdis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("prt6", "dis", "options", "grb_filerecord")) + crs = ArrayTemplateGenerator(("prt6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("prt6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("prt6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("prt6", "dis", "griddata", "delc")) @@ -322,6 +330,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=1, nrow=2, @@ -357,6 +366,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfprtdisv.py b/flopy/mf6/modflow/mfprtdisv.py index 6c87de4e28..0d2bd85bc0 100644 --- a/flopy/mf6/modflow/mfprtdisv.py +++ b/flopy/mf6/modflow/mfprtdisv.py @@ -55,6 +55,13 @@ class ModflowPrtdisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. + crs : [string] + is a real-world coordinate reference system (crs) for the model, for example, + an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open + geospatial consortium well-known text (wkt) specification. limited to 5000 + characters. the entry for crs does not affect the model simulation, but it is + written to the binary grid file so that postprocessors can locate the grid in + space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -121,6 +128,7 @@ class ModflowPrtdisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("prt6", "disv", "options", "grb_filerecord") ) + crs = ArrayTemplateGenerator(("prt6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("prt6", "disv", "options", "ncf_filerecord") ) @@ -421,6 +429,7 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, + crs=None, packagedata=None, nlay=None, ncpl=None, @@ -456,6 +465,7 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) + self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfprtprp.py b/flopy/mf6/modflow/mfprtprp.py index 410b770025..7cafc642f7 100644 --- a/flopy/mf6/modflow/mfprtprp.py +++ b/flopy/mf6/modflow/mfprtprp.py @@ -711,7 +711,7 @@ def __init__( boundnames=None, print_input=None, dev_exit_solve_method=None, - exit_solve_tolerance=1e-05, + exit_solve_tolerance=None, local_z=None, extend_tracking=None, track_filerecord=None, @@ -727,7 +727,7 @@ def __init__( dev_forceternary=None, release_time_tolerance=None, release_time_frequency=None, - coordinate_check_method="eager", + coordinate_check_method=None, dev_cycle_detection_window=None, nreleasepts=None, nreleasetimes=None, diff --git a/flopy/mf6/utils/codegen/filters.py b/flopy/mf6/utils/codegen/filters.py index 3d4ee82a4c..9a274e5b4f 100644 --- a/flopy/mf6/utils/codegen/filters.py +++ b/flopy/mf6/utils/codegen/filters.py @@ -229,6 +229,12 @@ def children(var: dict) -> Optional[dict]: def default_value(var: dict) -> Any: + # For optional scalar (non-array) fields, use None as the Python __init__ + # default. The DFN 'default' reflects MF6's internal default; MF6 applies + # it when the keyword is absent, so flopy does not need to store or write + # the value on behalf of the user. + if var.get("optional") and not var.get("shape"): + return None _default = var.get("default", None) if _default is not None: return _default From 28b9663d18b92bc7331ecbef5f13b716b2d56364 Mon Sep 17 00:00:00 2001 From: Bonelli Date: Wed, 18 Feb 2026 06:42:31 -0500 Subject: [PATCH 5/6] fix generated files --- flopy/mf6/modflow/mfgwedis.py | 10 ---------- flopy/mf6/modflow/mfgwedisu.py | 10 ---------- flopy/mf6/modflow/mfgwedisv.py | 10 ---------- flopy/mf6/modflow/mfgwfchdg.py | 10 ---------- flopy/mf6/modflow/mfgwfdis.py | 10 ---------- flopy/mf6/modflow/mfgwfdisu.py | 10 ---------- flopy/mf6/modflow/mfgwfdisv.py | 10 ---------- flopy/mf6/modflow/mfgwfdrng.py | 9 --------- flopy/mf6/modflow/mfgwfghbg.py | 10 ---------- flopy/mf6/modflow/mfgwfrivg.py | 9 --------- flopy/mf6/modflow/mfgwfwelg.py | 10 ---------- flopy/mf6/modflow/mfgwtdis.py | 10 ---------- flopy/mf6/modflow/mfgwtdisu.py | 10 ---------- flopy/mf6/modflow/mfgwtdisv.py | 10 ---------- flopy/mf6/modflow/mfprtdis.py | 10 ---------- flopy/mf6/modflow/mfprtdisv.py | 10 ---------- 16 files changed, 158 deletions(-) diff --git a/flopy/mf6/modflow/mfgwedis.py b/flopy/mf6/modflow/mfgwedis.py index 0a2a135331..304cc6e100 100644 --- a/flopy/mf6/modflow/mfgwedis.py +++ b/flopy/mf6/modflow/mfgwedis.py @@ -54,13 +54,6 @@ class ModflowGwedis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -102,7 +95,6 @@ class ModflowGwedis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("gwe6", "dis", "options", "grb_filerecord")) - crs = ArrayTemplateGenerator(("gwe6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("gwe6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("gwe6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("gwe6", "dis", "griddata", "delc")) @@ -338,7 +330,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=1, nrow=2, @@ -374,7 +365,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwedisu.py b/flopy/mf6/modflow/mfgwedisu.py index a40532dabe..7fec4411ce 100644 --- a/flopy/mf6/modflow/mfgwedisu.py +++ b/flopy/mf6/modflow/mfgwedisu.py @@ -58,13 +58,6 @@ class ModflowGwedisu(MFPackage): export_array_ascii : keyword keyword that specifies input griddata arrays should be written to layered ascii output files. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. nodes : integer is the number of cells in the model grid. nja : integer @@ -184,7 +177,6 @@ class ModflowGwedisu(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwe6", "disu", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("gwe6", "disu", "options", "crs")) top = ArrayTemplateGenerator(("gwe6", "disu", "griddata", "top")) bot = ArrayTemplateGenerator(("gwe6", "disu", "griddata", "bot")) area = ArrayTemplateGenerator(("gwe6", "disu", "griddata", "area")) @@ -506,7 +498,6 @@ def __init__( angrot=None, vertical_offset_tolerance=None, export_array_ascii=None, - crs=None, nodes=None, nja=None, nvert=None, @@ -548,7 +539,6 @@ def __init__( self.export_array_ascii = self.build_mfdata( "export_array_ascii", export_array_ascii ) - self.crs = self.build_mfdata("crs", crs) self.nodes = self.build_mfdata("nodes", nodes) self.nja = self.build_mfdata("nja", nja) self.nvert = self.build_mfdata("nvert", nvert) diff --git a/flopy/mf6/modflow/mfgwedisv.py b/flopy/mf6/modflow/mfgwedisv.py index f3fb97bca1..389c20f60c 100644 --- a/flopy/mf6/modflow/mfgwedisv.py +++ b/flopy/mf6/modflow/mfgwedisv.py @@ -57,13 +57,6 @@ class ModflowGwedisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -130,7 +123,6 @@ class ModflowGwedisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwe6", "disv", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("gwe6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("gwe6", "disv", "options", "ncf_filerecord") ) @@ -437,7 +429,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=None, ncpl=None, @@ -473,7 +464,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwfchdg.py b/flopy/mf6/modflow/mfgwfchdg.py index 61dae704c3..8b6148cec0 100644 --- a/flopy/mf6/modflow/mfgwfchdg.py +++ b/flopy/mf6/modflow/mfgwfchdg.py @@ -19,14 +19,6 @@ class ModflowGwfchdg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. - readarraygrid : keyword - indicates that array-based grid input will be used for the constant head - package. this keyword must be specified to use array-based grid input. when - readarraygrid is specified, values must be provided for every cell within a - model grid, even those cells that have an idomain value less than one. values - assigned to cells with idomain values less than one are not used and have no - effect on simulation results. no data cells should contain the value dnodata - (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -251,7 +243,6 @@ def __init__( self, model, loading_package=False, - readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -277,7 +268,6 @@ def __init__( **kwargs, ) - self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwfdis.py b/flopy/mf6/modflow/mfgwfdis.py index e761c2ce9e..d28c91ea50 100644 --- a/flopy/mf6/modflow/mfgwfdis.py +++ b/flopy/mf6/modflow/mfgwfdis.py @@ -54,13 +54,6 @@ class ModflowGwfdis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -102,7 +95,6 @@ class ModflowGwfdis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("gwf6", "dis", "options", "grb_filerecord")) - crs = ArrayTemplateGenerator(("gwf6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("gwf6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("gwf6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("gwf6", "dis", "griddata", "delc")) @@ -338,7 +330,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=1, nrow=2, @@ -374,7 +365,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwfdisu.py b/flopy/mf6/modflow/mfgwfdisu.py index 8dea8e4a62..9d3e4a7f53 100644 --- a/flopy/mf6/modflow/mfgwfdisu.py +++ b/flopy/mf6/modflow/mfgwfdisu.py @@ -58,13 +58,6 @@ class ModflowGwfdisu(MFPackage): export_array_ascii : keyword keyword that specifies input griddata arrays should be written to layered ascii output files. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. nodes : integer is the number of cells in the model grid. nja : integer @@ -184,7 +177,6 @@ class ModflowGwfdisu(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwf6", "disu", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("gwf6", "disu", "options", "crs")) top = ArrayTemplateGenerator(("gwf6", "disu", "griddata", "top")) bot = ArrayTemplateGenerator(("gwf6", "disu", "griddata", "bot")) area = ArrayTemplateGenerator(("gwf6", "disu", "griddata", "area")) @@ -506,7 +498,6 @@ def __init__( angrot=None, vertical_offset_tolerance=None, export_array_ascii=None, - crs=None, nodes=None, nja=None, nvert=None, @@ -548,7 +539,6 @@ def __init__( self.export_array_ascii = self.build_mfdata( "export_array_ascii", export_array_ascii ) - self.crs = self.build_mfdata("crs", crs) self.nodes = self.build_mfdata("nodes", nodes) self.nja = self.build_mfdata("nja", nja) self.nvert = self.build_mfdata("nvert", nvert) diff --git a/flopy/mf6/modflow/mfgwfdisv.py b/flopy/mf6/modflow/mfgwfdisv.py index 9192cc04ef..457ba7c05c 100644 --- a/flopy/mf6/modflow/mfgwfdisv.py +++ b/flopy/mf6/modflow/mfgwfdisv.py @@ -57,13 +57,6 @@ class ModflowGwfdisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -130,7 +123,6 @@ class ModflowGwfdisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwf6", "disv", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("gwf6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("gwf6", "disv", "options", "ncf_filerecord") ) @@ -437,7 +429,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=None, ncpl=None, @@ -473,7 +464,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwfdrng.py b/flopy/mf6/modflow/mfgwfdrng.py index 3431d9d896..e1386a1118 100644 --- a/flopy/mf6/modflow/mfgwfdrng.py +++ b/flopy/mf6/modflow/mfgwfdrng.py @@ -19,13 +19,6 @@ class ModflowGwfdrng(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. - readarraygrid : keyword - indicates that array-based grid input will be used for the drain package. this - keyword must be specified to use array-based grid input. when readarraygrid is - specified, values must be provided for every cell within a model grid, even - those cells that have an idomain value less than one. values assigned to cells - with idomain values less than one are not used and have no effect on simulation - results. no data cells should contain the value dnodata (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -297,7 +290,6 @@ def __init__( self, model, loading_package=False, - readarraygrid=True, auxiliary=None, auxmultname=None, auxdepthname=None, @@ -326,7 +318,6 @@ def __init__( **kwargs, ) - self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.auxdepthname = self.build_mfdata("auxdepthname", auxdepthname) diff --git a/flopy/mf6/modflow/mfgwfghbg.py b/flopy/mf6/modflow/mfgwfghbg.py index 0adf8712c0..415872ee4e 100644 --- a/flopy/mf6/modflow/mfgwfghbg.py +++ b/flopy/mf6/modflow/mfgwfghbg.py @@ -19,14 +19,6 @@ class ModflowGwfghbg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. - readarraygrid : keyword - indicates that array-based grid input will be used for the general-head - boundary package. this keyword must be specified to use array-based grid - input. when readarraygrid is specified, values must be provided for every cell - within a model grid, even those cells that have an idomain value less than one. - values assigned to cells with idomain values less than one are not used and - have no effect on simulation results. no data cells should contain the value - dnodata (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -269,7 +261,6 @@ def __init__( self, model, loading_package=False, - readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -296,7 +287,6 @@ def __init__( **kwargs, ) - self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwfrivg.py b/flopy/mf6/modflow/mfgwfrivg.py index 5b011325ea..3472aef279 100644 --- a/flopy/mf6/modflow/mfgwfrivg.py +++ b/flopy/mf6/modflow/mfgwfrivg.py @@ -19,13 +19,6 @@ class ModflowGwfrivg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. - readarraygrid : keyword - indicates that array-based grid input will be used for the river package. this - keyword must be specified to use array-based grid input. when readarraygrid is - specified, values must be provided for every cell within a model grid, even - those cells that have an idomain value less than one. values assigned to cells - with idomain values less than one are not used and have no effect on simulation - results. no data cells should contain the value dnodata (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -279,7 +272,6 @@ def __init__( self, model, loading_package=False, - readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -307,7 +299,6 @@ def __init__( **kwargs, ) - self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwfwelg.py b/flopy/mf6/modflow/mfgwfwelg.py index f3ef6c8828..5fec9ff505 100644 --- a/flopy/mf6/modflow/mfgwfwelg.py +++ b/flopy/mf6/modflow/mfgwfwelg.py @@ -19,14 +19,6 @@ class ModflowGwfwelg(MFPackage): loading_package : bool, default False Do not set this parameter. It is intended for debugging and internal processing purposes only. - readarraygrid : keyword - indicates that array-based grid input will be used for the well boundary - package. this keyword must be specified to use array-based grid input. when - readarraygrid is specified, values must be provided for every cell within a - model grid, even those cells that have an idomain value less than one. values - assigned to cells with idomain values less than one are not used and have no - effect on simulation results. no data cells should contain the value dnodata - (3.0e+30). auxiliary : [string] defines an array of one or more auxiliary variable names. there is no limit on the number of auxiliary variables that can be provided on this line; however, @@ -341,7 +333,6 @@ def __init__( self, model, loading_package=False, - readarraygrid=True, auxiliary=None, auxmultname=None, print_input=None, @@ -370,7 +361,6 @@ def __init__( **kwargs, ) - self.readarraygrid = self.build_mfdata("readarraygrid", readarraygrid) self.auxiliary = self.build_mfdata("auxiliary", auxiliary) self.auxmultname = self.build_mfdata("auxmultname", auxmultname) self.print_input = self.build_mfdata("print_input", print_input) diff --git a/flopy/mf6/modflow/mfgwtdis.py b/flopy/mf6/modflow/mfgwtdis.py index c8d6df9fa8..a32722915f 100644 --- a/flopy/mf6/modflow/mfgwtdis.py +++ b/flopy/mf6/modflow/mfgwtdis.py @@ -54,13 +54,6 @@ class ModflowGwtdis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -102,7 +95,6 @@ class ModflowGwtdis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("gwt6", "dis", "options", "grb_filerecord")) - crs = ArrayTemplateGenerator(("gwt6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("gwt6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("gwt6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("gwt6", "dis", "griddata", "delc")) @@ -338,7 +330,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=1, nrow=2, @@ -374,7 +365,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfgwtdisu.py b/flopy/mf6/modflow/mfgwtdisu.py index 7336cd98a1..353b1339c4 100644 --- a/flopy/mf6/modflow/mfgwtdisu.py +++ b/flopy/mf6/modflow/mfgwtdisu.py @@ -58,13 +58,6 @@ class ModflowGwtdisu(MFPackage): export_array_ascii : keyword keyword that specifies input griddata arrays should be written to layered ascii output files. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. nodes : integer is the number of cells in the model grid. nja : integer @@ -184,7 +177,6 @@ class ModflowGwtdisu(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwt6", "disu", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("gwt6", "disu", "options", "crs")) top = ArrayTemplateGenerator(("gwt6", "disu", "griddata", "top")) bot = ArrayTemplateGenerator(("gwt6", "disu", "griddata", "bot")) area = ArrayTemplateGenerator(("gwt6", "disu", "griddata", "area")) @@ -506,7 +498,6 @@ def __init__( angrot=None, vertical_offset_tolerance=None, export_array_ascii=None, - crs=None, nodes=None, nja=None, nvert=None, @@ -548,7 +539,6 @@ def __init__( self.export_array_ascii = self.build_mfdata( "export_array_ascii", export_array_ascii ) - self.crs = self.build_mfdata("crs", crs) self.nodes = self.build_mfdata("nodes", nodes) self.nja = self.build_mfdata("nja", nja) self.nvert = self.build_mfdata("nvert", nvert) diff --git a/flopy/mf6/modflow/mfgwtdisv.py b/flopy/mf6/modflow/mfgwtdisv.py index 4e85f286b7..469999a33e 100644 --- a/flopy/mf6/modflow/mfgwtdisv.py +++ b/flopy/mf6/modflow/mfgwtdisv.py @@ -57,13 +57,6 @@ class ModflowGwtdisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -130,7 +123,6 @@ class ModflowGwtdisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("gwt6", "disv", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("gwt6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("gwt6", "disv", "options", "ncf_filerecord") ) @@ -437,7 +429,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=None, ncpl=None, @@ -473,7 +464,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfprtdis.py b/flopy/mf6/modflow/mfprtdis.py index 3e90366657..89ea68f765 100644 --- a/flopy/mf6/modflow/mfprtdis.py +++ b/flopy/mf6/modflow/mfprtdis.py @@ -54,13 +54,6 @@ class ModflowPrtdis(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -102,7 +95,6 @@ class ModflowPrtdis(MFPackage): """ grb_filerecord = ListTemplateGenerator(("prt6", "dis", "options", "grb_filerecord")) - crs = ArrayTemplateGenerator(("prt6", "dis", "options", "crs")) ncf_filerecord = ListTemplateGenerator(("prt6", "dis", "options", "ncf_filerecord")) delr = ArrayTemplateGenerator(("prt6", "dis", "griddata", "delr")) delc = ArrayTemplateGenerator(("prt6", "dis", "griddata", "delc")) @@ -330,7 +322,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=1, nrow=2, @@ -366,7 +357,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord diff --git a/flopy/mf6/modflow/mfprtdisv.py b/flopy/mf6/modflow/mfprtdisv.py index 0d2bd85bc0..6c87de4e28 100644 --- a/flopy/mf6/modflow/mfprtdisv.py +++ b/flopy/mf6/modflow/mfprtdisv.py @@ -55,13 +55,6 @@ class ModflowPrtdisv(MFPackage): modflow 6 simulation input. this option only has an effect when an output model netcdf file is configured and the simulation is run in validate mode, otherwise it is ignored. - crs : [string] - is a real-world coordinate reference system (crs) for the model, for example, - an epsg integer code (e.g. 26915), authority string (i.e. epsg:26915), or open - geospatial consortium well-known text (wkt) specification. limited to 5000 - characters. the entry for crs does not affect the model simulation, but it is - written to the binary grid file so that postprocessors can locate the grid in - space. packagedata : record ncf6 filein ncf6_filename Contains data for the ncf package. Data can be passed as a dictionary to the ncf package with variable names as keys and package data as values. Data for @@ -128,7 +121,6 @@ class ModflowPrtdisv(MFPackage): grb_filerecord = ListTemplateGenerator( ("prt6", "disv", "options", "grb_filerecord") ) - crs = ArrayTemplateGenerator(("prt6", "disv", "options", "crs")) ncf_filerecord = ListTemplateGenerator( ("prt6", "disv", "options", "ncf_filerecord") ) @@ -429,7 +421,6 @@ def __init__( angrot=None, export_array_ascii=None, export_array_netcdf=None, - crs=None, packagedata=None, nlay=None, ncpl=None, @@ -465,7 +456,6 @@ def __init__( self.export_array_netcdf = self.build_mfdata( "export_array_netcdf", export_array_netcdf ) - self.crs = self.build_mfdata("crs", crs) self._ncf_filerecord = self.build_mfdata("ncf_filerecord", None) self._ncf_package = self.build_child_package( "ncf", packagedata, "packagedata", self._ncf_filerecord From c5ba01ddce672d12fcaf402289f4f8ae82b44ba2 Mon Sep 17 00:00:00 2001 From: Bonelli Date: Wed, 18 Feb 2026 14:01:27 -0500 Subject: [PATCH 6/6] just kidding --- autotest/test_mf6_optional_default_value.py | 35 +++++++++++---------- flopy/mf6/data/mfdatascalar.py | 14 +++++++++ flopy/mf6/mfsimbase.py | 1 + flopy/mf6/modflow/mfgwedisu.py | 2 +- flopy/mf6/modflow/mfgweest.py | 6 ++-- flopy/mf6/modflow/mfgwfbuy.py | 2 +- flopy/mf6/modflow/mfgwfcsub.py | 4 +-- flopy/mf6/modflow/mfgwfdisu.py | 2 +- flopy/mf6/modflow/mfgwfvsc.py | 8 ++--- flopy/mf6/modflow/mfgwtdisu.py | 2 +- flopy/mf6/modflow/mfprtprp.py | 4 +-- flopy/mf6/utils/codegen/filters.py | 6 ---- 12 files changed, 49 insertions(+), 37 deletions(-) diff --git a/autotest/test_mf6_optional_default_value.py b/autotest/test_mf6_optional_default_value.py index 35d37d8499..b60840f928 100644 --- a/autotest/test_mf6_optional_default_value.py +++ b/autotest/test_mf6_optional_default_value.py @@ -1,17 +1,17 @@ """ Test that optional package variables with default values aren't written to -input files when not explicitly set by the user. +input files when the value matches the DFN-declared default, unless +write_defaults is set on the simulation data. Reproduce https://github.com/modflowpy/flopy/issues/2710: ModflowPrtprp.coordinate_check_method was introduced in MF6 6.7.0 and defaults to "eager". flopy 3.10.0 wrote COORDINATE_CHECK_METHOD EAGER -unconditionally (because the generated __init__ used the DFN default as the -Python default), causing errors when used with older MF6 binaries. +unconditionally, causing fatal errors when used with older MF6 binaries. -The fix: optional scalar fields use None as their Python __init__ default. -The existing "if data is None, don't write" gate in get_file_entry() then -handles suppression naturally. If the user explicitly sets the value it is -always written, regardless of whether it matches MF6's internal default. +The fix: get_file_entry() suppresses writing optional scalars whose current +value equals the DFN-declared default, unless simulation_data.write_defaults +is True. MF6 applies its own internal default when the keyword is absent, +so the simulation outcome is identical either way. """ from pathlib import Path @@ -23,7 +23,7 @@ pytestmark = pytest.mark.mf6 -def _build_prt_sim(ws, coordinate_check_method=None): +def _build_prt_sim(ws, coordinate_check_method="eager"): sim = flopy.mf6.MFSimulation(sim_name="prt", sim_ws=str(ws)) flopy.mf6.ModflowTdis(sim, nper=1, perioddata=[(1.0, 1, 1.0)]) ems = flopy.mf6.ModflowEms(sim) @@ -58,15 +58,16 @@ def _prp_text(ws): def test_coordinate_check_method(function_tmpdir): - # Not set (None default): should NOT appear in the input file. - # MF6 applies its own internal default (eager) when the keyword is absent. - ws = Path(function_tmpdir) / "default" + # Default value "eager": should NOT be written. + # MF6 applies its own internal default (eager) when the keyword is absent, + # so omitting it produces identical simulation behavior. + ws = Path(function_tmpdir) / "eager" ws.mkdir() - sim = _build_prt_sim(ws) + sim = _build_prt_sim(ws, coordinate_check_method="eager") sim.write_simulation() assert "COORDINATE_CHECK_METHOD" not in _prp_text(ws) - # Explicitly set to "none": should be written. + # Non-default value "none": should be written. ws = Path(function_tmpdir) / "none" ws.mkdir() sim = _build_prt_sim(ws, coordinate_check_method="none") @@ -75,11 +76,13 @@ def test_coordinate_check_method(function_tmpdir): assert "COORDINATE_CHECK_METHOD" in text assert "NONE" in text - # Explicitly set to "eager": should also be written. - # Explicit values are always written regardless of MF6's internal default. - ws = Path(function_tmpdir) / "eager" + # write_defaults=True: default value should be written explicitly. + # Useful for producing fully self-contained input files independent + # of MF6's internal defaults, e.g. for archival or sharing. + ws = Path(function_tmpdir) / "write_defaults" ws.mkdir() sim = _build_prt_sim(ws, coordinate_check_method="eager") + sim.simulation_data.write_defaults = True sim.write_simulation() text = _prp_text(ws) assert "COORDINATE_CHECK_METHOD" in text diff --git a/flopy/mf6/data/mfdatascalar.py b/flopy/mf6/data/mfdatascalar.py index 94c4f1e3fd..22fdc0cb98 100644 --- a/flopy/mf6/data/mfdatascalar.py +++ b/flopy/mf6/data/mfdatascalar.py @@ -361,6 +361,20 @@ def get_file_entry( self._simulation_data.debug, ex, ) + if self.structure.optional: + data_item = self.structure.data_item_structures[0] + if data_item.default_value is not None: + current = storage.get_data() + try: + matches_default = float(str(current)) == float( + data_item.default_value + ) + except (ValueError, TypeError): + matches_default = str(current).lower().strip() == ( + data_item.default_value.lower().strip() + ) + if matches_default and not self._simulation_data.write_defaults: + return "" if ( self.structure.type == DatumType.keyword or self.structure.type == DatumType.record diff --git a/flopy/mf6/mfsimbase.py b/flopy/mf6/mfsimbase.py index 273970bb62..def3a1803d 100644 --- a/flopy/mf6/mfsimbase.py +++ b/flopy/mf6/mfsimbase.py @@ -259,6 +259,7 @@ def __init__(self, path: Union[str, PathLike], mfsim): self._verbosity_level = VerbosityLevel.normal self._max_columns_set_by = None # Can be None, 'user', or 'auto' self.use_pandas = True + self.write_defaults = False self._update_str_format() diff --git a/flopy/mf6/modflow/mfgwedisu.py b/flopy/mf6/modflow/mfgwedisu.py index 7fec4411ce..7339edf08f 100644 --- a/flopy/mf6/modflow/mfgwedisu.py +++ b/flopy/mf6/modflow/mfgwedisu.py @@ -496,7 +496,7 @@ def __init__( xorigin=None, yorigin=None, angrot=None, - vertical_offset_tolerance=None, + vertical_offset_tolerance=0.0, export_array_ascii=None, nodes=None, nja=None, diff --git a/flopy/mf6/modflow/mfgweest.py b/flopy/mf6/modflow/mfgweest.py index 5eb29753eb..b7e021a94c 100644 --- a/flopy/mf6/modflow/mfgweest.py +++ b/flopy/mf6/modflow/mfgweest.py @@ -205,9 +205,9 @@ def __init__( save_flows=None, zero_order_decay_water=None, zero_order_decay_solid=None, - density_water=None, - heat_capacity_water=None, - latent_heat_vaporization=None, + density_water=1000.0, + heat_capacity_water=4184.0, + latent_heat_vaporization=2453500.0, porosity=None, decay_water=None, decay_solid=None, diff --git a/flopy/mf6/modflow/mfgwfbuy.py b/flopy/mf6/modflow/mfgwfbuy.py index 8619a754fe..fd7e4d6824 100644 --- a/flopy/mf6/modflow/mfgwfbuy.py +++ b/flopy/mf6/modflow/mfgwfbuy.py @@ -221,7 +221,7 @@ def __init__( model, loading_package=False, hhformulation_rhs=None, - denseref=None, + denseref=1000.0, density_filerecord=None, dev_efh_formulation=None, nrhospecies=None, diff --git a/flopy/mf6/modflow/mfgwfcsub.py b/flopy/mf6/modflow/mfgwfcsub.py index 362f97b662..e59a3ac517 100644 --- a/flopy/mf6/modflow/mfgwfcsub.py +++ b/flopy/mf6/modflow/mfgwfcsub.py @@ -1024,8 +1024,8 @@ def __init__( boundnames=None, print_input=None, save_flows=None, - gammaw=None, - beta=None, + gammaw=9806.65, + beta=4.6512e-10, head_based=None, initial_preconsolidation_head=None, ndelaycells=None, diff --git a/flopy/mf6/modflow/mfgwfdisu.py b/flopy/mf6/modflow/mfgwfdisu.py index 9d3e4a7f53..e45634f643 100644 --- a/flopy/mf6/modflow/mfgwfdisu.py +++ b/flopy/mf6/modflow/mfgwfdisu.py @@ -496,7 +496,7 @@ def __init__( xorigin=None, yorigin=None, angrot=None, - vertical_offset_tolerance=None, + vertical_offset_tolerance=0.0, export_array_ascii=None, nodes=None, nja=None, diff --git a/flopy/mf6/modflow/mfgwfvsc.py b/flopy/mf6/modflow/mfgwfvsc.py index 67c1657ccb..6e6444ef50 100644 --- a/flopy/mf6/modflow/mfgwfvsc.py +++ b/flopy/mf6/modflow/mfgwfvsc.py @@ -271,12 +271,12 @@ def __init__( self, model, loading_package=False, - viscref=None, + viscref=1.0, temperature_species_name=None, thermal_formulation=None, - thermal_a2=None, - thermal_a3=None, - thermal_a4=None, + thermal_a2=10.0, + thermal_a3=248.37, + thermal_a4=133.15, viscosity_filerecord=None, nviscspecies=None, packagedata=None, diff --git a/flopy/mf6/modflow/mfgwtdisu.py b/flopy/mf6/modflow/mfgwtdisu.py index 353b1339c4..df4674d08f 100644 --- a/flopy/mf6/modflow/mfgwtdisu.py +++ b/flopy/mf6/modflow/mfgwtdisu.py @@ -496,7 +496,7 @@ def __init__( xorigin=None, yorigin=None, angrot=None, - vertical_offset_tolerance=None, + vertical_offset_tolerance=0.0, export_array_ascii=None, nodes=None, nja=None, diff --git a/flopy/mf6/modflow/mfprtprp.py b/flopy/mf6/modflow/mfprtprp.py index 7cafc642f7..410b770025 100644 --- a/flopy/mf6/modflow/mfprtprp.py +++ b/flopy/mf6/modflow/mfprtprp.py @@ -711,7 +711,7 @@ def __init__( boundnames=None, print_input=None, dev_exit_solve_method=None, - exit_solve_tolerance=None, + exit_solve_tolerance=1e-05, local_z=None, extend_tracking=None, track_filerecord=None, @@ -727,7 +727,7 @@ def __init__( dev_forceternary=None, release_time_tolerance=None, release_time_frequency=None, - coordinate_check_method=None, + coordinate_check_method="eager", dev_cycle_detection_window=None, nreleasepts=None, nreleasetimes=None, diff --git a/flopy/mf6/utils/codegen/filters.py b/flopy/mf6/utils/codegen/filters.py index 9a274e5b4f..3d4ee82a4c 100644 --- a/flopy/mf6/utils/codegen/filters.py +++ b/flopy/mf6/utils/codegen/filters.py @@ -229,12 +229,6 @@ def children(var: dict) -> Optional[dict]: def default_value(var: dict) -> Any: - # For optional scalar (non-array) fields, use None as the Python __init__ - # default. The DFN 'default' reflects MF6's internal default; MF6 applies - # it when the keyword is absent, so flopy does not need to store or write - # the value on behalf of the user. - if var.get("optional") and not var.get("shape"): - return None _default = var.get("default", None) if _default is not None: return _default