diff --git a/autotest/t015_test.py b/autotest/t015_test.py index 09bed0f128..3164b5e36d 100644 --- a/autotest/t015_test.py +++ b/autotest/t015_test.py @@ -32,7 +32,54 @@ else: path = os.path.join("..", "examples", "data", "mf2005_test") -str_items = {0: {"mfnam": "str.nam", "sfrfile": "str.str"}} +str_items = { + 0: { + "mfnam": "str.nam", + "sfrfile": "str.str", + "lstfile": "str.lst", + } +} + + +def test_str_issue1164(): + m = flopy.modflow.Modflow.load( + str_items[0]["mfnam"], + exe_name=mfexe, + model_ws=path, + verbose=False, + check=False, + ) + + ws = os.path.join(tpth, "issue-1164") + m.change_model_ws(ws) + + # adjust stress period data + spd0 = m.str.stress_period_data[0] + spd0["flow"][0] = 2.1149856e6 # 450000000000000000.0000e-17 + m.str.stress_period_data[0] = spd0 + + # write model datasets and run fixed + m.write_input() + success = m.run_model() + assert success, "could not run base model" + + # get the budget + lst_pth = os.path.join(ws, str_items[0]["lstfile"]) + base_wb = flopy.utils.MfListBudget(lst_pth).get_dataframes()[0] + + # set the model to free format + m.set_ifrefm() + + # write model datasets and run revised + m.write_input() + success = m.run_model() + assert success, "could not run revised model" + + # get the revised budget + revised_wb = flopy.utils.MfListBudget(lst_pth).get_dataframes()[0] + + # test if the budgets are the same + assert revised_wb.equals(base_wb), "water budgets do not match" def test_str_free(): @@ -43,7 +90,7 @@ def test_str_free(): verbose=False, check=False, ) - ws = tpth + ws = os.path.join(tpth, "fixed") m.change_model_ws(ws) # get pointer to str package @@ -116,7 +163,7 @@ def test_str_free(): msg = "could not load the fixed format model with aux variables" assert m2 is not None, msg - ws = os.path.join(tpth, "mf2005") + ws = os.path.join(tpth, "free") m.change_model_ws(ws) m.set_ifrefm() m.write_input() @@ -145,7 +192,7 @@ def test_str_free(): # compare the fixed and free format head files if run: if pymake is not None: - fn1 = os.path.join(tpth, "str.nam") + fn1 = os.path.join(tpth, "fixed", "str.nam") fn2 = os.path.join(ws, "str.nam") success = pymake.compare_heads(fn1, fn2, verbose=True) msg = "fixed and free format input output head files are different" @@ -162,5 +209,6 @@ def test_str_plot(): if __name__ == "__main__": + test_str_issue1164() test_str_free() test_str_plot() diff --git a/flopy/utils/flopy_io.py b/flopy/utils/flopy_io.py index 4cb074392c..8fd8fdd793 100755 --- a/flopy/utils/flopy_io.py +++ b/flopy/utils/flopy_io.py @@ -185,18 +185,25 @@ def write_fixed_var(v, length=10, ipos=None, free=False, comment=None): if free: write_fmt = "{} " else: + width = ipos[n] if isinstance(v[n], (float, np.float32, np.float64)): - width = ipos[n] - 6 - vmin, vmax = 10 ** -width, 10 ** width + decimal = width - 6 + vmin, vmax = 10 ** -decimal, 10 ** decimal if abs(v[n]) < vmin or abs(v[n]) > vmax: - ctype = "g" + ctype = "g" # default precision is 6 if not specified else: - ctype = ".{}f".format(width) + ctype = ".{}f".format(decimal) + # evaluate if the fixed format value will exceed width + if ( + len("{{:>{}{}}}".format(width, ctype).format(v[n])) + > width + ): + ctype = ".{}g".format(decimal) # preserve precision elif isinstance(v[n], (int, np.int32, np.int64)): ctype = "d" else: ctype = "" - write_fmt = "{{:>{}{}}}".format(ipos[n], ctype) + write_fmt = "{{:>{}{}}}".format(width, ctype) out += write_fmt.format(v[n]) if comment is not None: out += " # {}".format(comment)