This page was generated from array_output_tutorial.py. It's also available as a notebook.

Formatting ASCII output arrays

Configuring numeric arrays written by FloPy

load and run the Freyberg model

[1]:
import os
import sys
from pathlib import Path
from pprint import pformat
from tempfile import TemporaryDirectory
[2]:
import git
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pooch
[3]:
import flopy
[4]:
# Set name of MODFLOW exe
#  assumes executable is in users path statement
version = "mf2005"
exe_name = "mf2005"
mfexe = exe_name

Check if we are in the repository and define the data path.

[5]:
try:
    root = Path(git.Repo(".", search_parent_directories=True).working_dir)
except:
    root = None
[6]:
data_path = root / "examples" / "data" if root else Path.cwd()
[7]:
sim_name = "freyberg"
[8]:
file_names = {
    "freyberg.bas": "63266024019fef07306b8b639c6c67d5e4b22f73e42dcaa9db18b5e0f692c097",
    "freyberg.dis": "62d0163bf36c7ee9f7ee3683263e08a0abcdedf267beedce6dd181600380b0a2",
    "freyberg.githds": "abe92497b55e6f6c73306e81399209e1cada34cf794a7867d776cfd18303673b",
    "freyberg.gitlist": "aef02c664344a288264d5f21e08a748150e43bb721a16b0e3f423e6e3e293056",
    "freyberg.lpf": "06500bff979424f58e5e4fbd07a7bdeb0c78f31bd08640196044b6ccefa7a1fe",
    "freyberg.nam": "e66321007bb603ef55ed2ba41f4035ba6891da704a4cbd3967f0c66ef1532c8f",
    "freyberg.oc": "532905839ccbfce01184980c230b6305812610b537520bf5a4abbcd3bd703ef4",
    "freyberg.pcg": "0d1686fac4680219fffdb56909296c5031029974171e25d4304e70fa96ebfc38",
    "freyberg.rch": "37a1e113a7ec16b61417d1fa9710dd111a595de738a367bd34fd4a359c480906",
    "freyberg.riv": "7492a1d5eb23d6812ec7c8227d0ad4d1e1b35631a765c71182b71e3bd6a6d31d",
    "freyberg.wel": "00aa55f59797c02f0be5318a523b36b168fc6651f238f34e8b0938c04292d3e7",
}
for fname, fhash in file_names.items():
    pooch.retrieve(
        url=f"https://github.com/modflowpy/flopy/raw/develop/examples/data/{sim_name}/{fname}",
        fname=fname,
        path=data_path / sim_name,
        known_hash=fhash,
    )
[9]:
# Set the paths
loadpth = data_path / sim_name
temp_dir = TemporaryDirectory()
modelpth = temp_dir.name
[10]:
# make sure modelpth directory exists
if not os.path.isdir(modelpth):
    os.makedirs(modelpth)
[11]:
print(sys.version)
print(f"numpy version: {np.__version__}")
print(f"matplotlib version: {mpl.__version__}")
print(f"flopy version: {flopy.__version__}")
3.12.10 | packaged by conda-forge | (main, Apr 10 2025, 22:21:13) [GCC 13.3.0]
numpy version: 2.2.5
matplotlib version: 3.10.3
flopy version: 3.9.3
[12]:
ml = flopy.modflow.Modflow.load(
    "freyberg.nam", model_ws=loadpth, exe_name=exe_name, version=version
)
ml.model_ws = modelpth
ml.write_input()
success, buff = ml.run_model(silent=True, report=True)
assert success, pformat(buff)

files = ["freyberg.hds", "freyberg.cbc"]
for f in files:
    if os.path.isfile(os.path.join(modelpth, f)):
        msg = f"Output file located: {f}"
        print(msg)
    else:
        errmsg = f"Error. Output file cannot be found: {f}"
        print(errmsg)

# Each ``Util2d`` instance now has a ```.format``` attribute, which is an ```ArrayFormat``` instance:

print(ml.lpf.hk[0].format)

# The ```ArrayFormat``` class exposes each of the attributes seen in the ```ArrayFormat.___str___()``` call. ```ArrayFormat``` also exposes ``.fortran``, ``.py`` and ``.numpy`` atrributes, which are the respective format descriptors:

print(ml.dis.botm[0].format.fortran)
print(ml.dis.botm[0].format.py)
print(ml.dis.botm[0].format.numpy)

# #### (re)-setting ```.format```
#
# We can reset the format using a standard fortran type format descriptor

ml.dis.botm[0].format.free = False
ml.dis.botm[0].format.fortran = "(20f10.4)"
print(ml.dis.botm[0].format.fortran)
print(ml.dis.botm[0].format.py)
print(ml.dis.botm[0].format.numpy)
print(ml.dis.botm[0].format)
Output file located: freyberg.hds
Output file located: freyberg.cbc
ArrayFormat: npl:20,format:E,width:15,decimal6,isfree:True,isbinary:False
(FREE)
(20, '{0:15.6E}')
%15E.6
(20F10.4)
(20, '{0:10.4F}')
%10F.4
ArrayFormat: npl:20,format:F,width:10,decimal4,isfree:False,isbinary:False
[13]:
ml.write_input()
success, buff = ml.run_model(silent=True, report=True)
if success:
    for line in buff:
        print(line)
else:
    raise ValueError("Failed to run.")

                                  MODFLOW-2005
    U.S. GEOLOGICAL SURVEY MODULAR FINITE-DIFFERENCE GROUND-WATER FLOW MODEL
                             Version 1.12.00 2/3/2017

 Using NAME file: freyberg.nam
 Run start date and time (yyyy/mm/dd hh:mm:ss): 2025/05/13  1:46:21

 Solving:  Stress period:     1    Time step:     1    Ground-Water Flow Eqn.
 Run end date and time (yyyy/mm/dd hh:mm:ss): 2025/05/13  1:46:21
 Elapsed run time:  0.005 Seconds

  Normal termination of simulation

Let’s load the model we just wrote and check that the desired botm[0].format was used:

[14]:
ml1 = flopy.modflow.Modflow.load("freyberg.nam", model_ws=modelpth)
print(ml1.dis.botm[0].format)
ArrayFormat: npl:20,format:E,width:15,decimal6,isfree:True,isbinary:False

We can also reset individual format components (we can also generate some warnings):

[15]:
ml.dis.botm[0].format.width = 9
ml.dis.botm[0].format.decimal = 1
print(ml1.dis.botm[0].format)
ArrayFormat warning:setting width less than default of 15
ArrayFormat warning: setting decimal less than default of 6
ArrayFormat warning: setting decimal less than current value of 6
ArrayFormat: npl:20,format:E,width:15,decimal6,isfree:True,isbinary:False

We can also select free format. Note that setting to free format resets the format attributes to the default, max precision:

[16]:
ml.dis.botm[0].format.free = True
print(ml1.dis.botm[0].format)
# -
ArrayFormat: npl:20,format:E,width:15,decimal6,isfree:True,isbinary:False
[17]:
ml.write_input()
success, buff = ml.run_model(silent=True, report=True)
if success:
    for line in buff:
        print(line)
else:
    raise ValueError("Failed to run.")

                                  MODFLOW-2005
    U.S. GEOLOGICAL SURVEY MODULAR FINITE-DIFFERENCE GROUND-WATER FLOW MODEL
                             Version 1.12.00 2/3/2017

 Using NAME file: freyberg.nam
 Run start date and time (yyyy/mm/dd hh:mm:ss): 2025/05/13  1:46:21

 Solving:  Stress period:     1    Time step:     1    Ground-Water Flow Eqn.
 Run end date and time (yyyy/mm/dd hh:mm:ss): 2025/05/13  1:46:21
 Elapsed run time:  0.006 Seconds

  Normal termination of simulation
[18]:
ml1 = flopy.modflow.Modflow.load("freyberg.nam", model_ws=modelpth)
print(ml1.dis.botm[0].format)
ArrayFormat: npl:20,format:E,width:15,decimal6,isfree:True,isbinary:False