Skip to content

fix(mf6): opt into writing optional default values#2712

Open
wpbonelli wants to merge 6 commits intomodflowpy:developfrom
wpbonelli:fix-2710
Open

fix(mf6): opt into writing optional default values#2712
wpbonelli wants to merge 6 commits intomodflowpy:developfrom
wpbonelli:fix-2710

Conversation

@wpbonelli
Copy link
Member

@wpbonelli wpbonelli commented Feb 15, 2026

Add an option write_defaults to the simulation, determining whether optional variables with default values are written to input files. Default to false to keep new/breaking options from being written to input files when they are not explicitly used. This gives new versions of flopy, aimed at new versions of MF6, better odds of remaining compatible with older versions of MF6. This is safe assuming MF6 consistently implements defaults as declared in DFN files. It will change the contents of input files, but in a way that prevents breakage, so seems better to consider a fix than a breaking change.

take 2

Initialize optional variables to None rather than a default value, for variables with a DFN-specified default value. This is a backwards-compatibility fix meant to keep new/breaking options from being written to input files when they are not explicitly used, to give new versions of flopy, aimed at new versions of MF6, better odds of remaining compatible with older versions of MF6.

This could be considered a breaking change, in that it will change the behavior of MF6 classes, and the contents of input files. IMO it is unintuitive for an optional variable to silently take the default value when left unspecified in package init. So I think it can be considered a fix on grounds that it prevents breakage on new versions of flopy/MF6 as described above

first pass

When writing MF6 input files, don't write optional multiple choice variables (i.e. string variables with a specified set of valid_values) if the value is equal to the default as specified in the DFN.

I think it's only safe to do this to multiple-choice string variables, rather than for all optional variables specifying a default, at least at the moment. We can assume MF6 reliably implements the default specified in the DFN for multiple choice strings. These are "mode selection" options; since MF6 must always run in one or another mode, we can expect it to default to the one specified in the DFN.

For numeric parameters on the other hand, MF6 does not always implement the default internally. E.g., density_water in GWEEST defines a default of 1000.0, but that seems to just be a "hint" to flopy. I think this needs fixing upstream, so MF6 will always implement specified defaults internally. Then flopy could simply default to None for all optionals..

This PR also introduces an option write_defaults on the simulation, to allow opting into the old behavior. I figure it can still be useful as a kind of 'strict' mode.

Fix #2710

@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.4%. Comparing base (556c088) to head (c5ba01d).
⚠️ Report is 130 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #2712      +/-   ##
===========================================
+ Coverage     55.5%    72.4%   +16.9%     
===========================================
  Files          644      674      +30     
  Lines       124135   130572    +6437     
===========================================
+ Hits         68947    94635   +25688     
+ Misses       55188    35937   -19251     
Files with missing lines Coverage Δ
flopy/mf6/data/mfdatascalar.py 60.4% <100.0%> (+1.0%) ⬆️
flopy/mf6/data/mfstructure.py 74.2% <100.0%> (+0.4%) ⬆️
flopy/mf6/mfsimbase.py 62.7% <100.0%> (-12.8%) ⬇️

... and 567 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wpbonelli wpbonelli marked this pull request as ready for review February 16, 2026 13:17
@wpbonelli wpbonelli added this to the 3.10.1 milestone Feb 16, 2026
@wpbonelli wpbonelli changed the title fix(mfdatascalar): skip fields with default values fix(mfdatascalar): skip multiple choice fields with default values Feb 16, 2026
@wpbonelli wpbonelli marked this pull request as draft February 17, 2026 19:36
@wpbonelli
Copy link
Member Author

wpbonelli commented Feb 17, 2026

After a closer look, I think the best way forward here is

  1. fix GWEEST upstream in MF6 to implement the default values (spoke to @emorway-usgs, he plans to do this)
  2. update flopy to set all optional variables not specified by the user to None

With the former, MF6 will consistently implement all defaults defined in DFNs.

The latter could be considered a breaking change, but it is unlikely anybody is a) electing not to specify a variable, then b) expecting in subsequent flopy code for that variable to have the default value. I think it is more intuitive for unspecified optional variables to be None, instead of taking the default specified in the DFN. This also reduces coupling between flopy and MF6: after this, DFN defaults would only mean "MF6 will use this value if you don't provide one", where now the default means that, plus "flopy will write this value to MF6 input files even though it's not required". Tighter scoping of DFN files, cleaner semantics, IMO.

@wpbonelli
Copy link
Member Author

GWE-EST issue fixed in MODFLOW-ORG/modflow6#2702

@wpbonelli wpbonelli changed the title fix(mfdatascalar): skip multiple choice fields with default values fix(mf6): initialize optional variables to None, not default Feb 18, 2026
@wpbonelli wpbonelli marked this pull request as ready for review February 18, 2026 12:36
@wpbonelli wpbonelli changed the title fix(mf6): initialize optional variables to None, not default fix(mf6): don't write optional default values by default Feb 18, 2026
@wpbonelli wpbonelli changed the title fix(mf6): don't write optional default values by default fix(mf6): opt into writing optional default values Feb 18, 2026
@wpbonelli
Copy link
Member Author

I think it is more intuitive for unspecified optional variables to be None, instead of taking the default specified in the DFN.

After thinking about this more I think it is a hard question. None makes instances accurate records of the user's intent. But I can also see a case for flopy to know the defaults MF6 will use and inform the user of that.

I reverted the switch to None. I think for consistency's sake it makes sense to stay with the defaults as currently, and just fix the MF6 version compatibility bug with an option, off by default, deciding whether to write optionals taking default values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: the default value for coordinate_check_method in ModflowPrtprp of 'eager' errors in latest MODFLOW (6.6.3)

1 participant

Comments