FloPy is a Python package to create, run, and post-process MODFLOW-based models
66
This module provides comprehensive support for MODFLOW 6 models including groundwater flow (GWF), transport (GWT), energy transport (GWE), and particle tracking (PRT) models with all standard packages and advanced features. MODFLOW 6 represents the latest generation of the MODFLOW groundwater modeling software with enhanced capabilities and modern input/output structure.
The main container for MODFLOW 6 simulations that manages models, time discretization, and solution schemes.
class MFSimulation:
"""MODFLOW 6 simulation container and execution manager"""
def __init__(
self,
sim_name: str = 'modflowtest',
version: str = 'mf6',
exe_name: str = 'mf6',
sim_ws: str = '.',
verbosity_level: int = 1,
write_headers: bool = True,
lazy_io: bool = False,
use_pandas: bool = True,
**kwargs
): ...
def write_simulation(
self,
silent: bool = False,
ext_file_action: ExtFileAction = ExtFileAction.copy_relative_paths
) -> None:
"""Write all simulation files to the workspace"""
...
def run_simulation(
self,
silent: bool = False,
pause: bool = False,
report: bool = False,
normal_msg: str = 'normal termination'
) -> tuple[bool, list[str]]:
"""Run the MODFLOW 6 simulation and return success status and output"""
...
def load_package(
self,
ftype: str,
fname: str,
pname: str,
**kwargs
) -> object:
"""Load a package from file"""
...
def register_ims_package(
self,
solution: object,
model_list: list[str]
) -> None:
"""Register iterative model solution for models"""
...
def get_model(self, model_name: str = None) -> object:
"""Get model by name"""
...
def remove_model(self, model_name: str) -> None:
"""Remove model from simulation"""
...
@property
def simulation_data(self) -> object:
"""Access to simulation data container"""
...
@property
def name_file(self) -> object:
"""Simulation name file object"""
...Base class for all MODFLOW 6 models providing common functionality.
class MFModel:
"""Base class for MODFLOW 6 models"""
def __init__(
self,
simulation: MFSimulation,
model_type: str,
modelname: str,
**kwargs
): ...
def load_package(
self,
ftype: str,
fname: str,
pname: str = None,
**kwargs
) -> object:
"""Load package from file"""
...
def remove_package(self, package_name: str) -> bool:
"""Remove package from model"""
...
def get_package(self, name: str = None) -> object:
"""Get package by name or file type"""
...
def set_model_relative_path(self, path: str) -> None:
"""Set relative path for model files"""
...
@property
def modelgrid(self) -> object:
"""Model grid object"""
...
@property
def packages(self) -> list[object]:
"""List of model packages"""
...Groundwater flow model for simulating saturated groundwater flow.
class ModflowGwf(MFModel):
"""MODFLOW 6 groundwater flow model"""
def __init__(
self,
simulation: MFSimulation,
modelname: str = 'gwf',
model_nam_file: str = None,
version: str = 'mf6',
exe_name: str = 'mf6',
model_ws: str = None,
disfile: str = None,
grid_type: str = 'structured',
xll: float = None,
yll: float = None,
rotation: float = 0.0,
proj4_str: str = None,
**kwargs
): ...
def get_steadystate_list(self) -> list[bool]:
"""Get list of steady state periods"""
...
def get_package_list(self, ftype: str = None) -> list[str]:
"""Get list of packages by file type"""
...Groundwater transport model for simulating solute transport.
class ModflowGwt(MFModel):
"""MODFLOW 6 groundwater transport model"""
def __init__(
self,
simulation: MFSimulation,
modelname: str = 'gwt',
model_nam_file: str = None,
version: str = 'mf6',
exe_name: str = 'mf6',
model_ws: str = None,
disfile: str = None,
**kwargs
): ...Groundwater energy transport model for simulating heat transport.
class ModflowGwe(MFModel):
"""MODFLOW 6 groundwater energy transport model"""
def __init__(
self,
simulation: MFSimulation,
modelname: str = 'gwe',
model_nam_file: str = None,
version: str = 'mf6',
exe_name: str = 'mf6',
model_ws: str = None,
disfile: str = None,
**kwargs
): ...Particle tracking model for flow path analysis.
class ModflowPrt(MFModel):
"""MODFLOW 6 particle tracking model"""
def __init__(
self,
simulation: MFSimulation,
modelname: str = 'prt',
model_nam_file: str = None,
version: str = 'mf6',
exe_name: str = 'mf6',
model_ws: str = None,
**kwargs
): ...Temporal discretization package that defines stress periods and time stepping.
class ModflowTdis:
"""MODFLOW 6 time discretization package"""
def __init__(
self,
simulation: MFSimulation,
loading_package: bool = False,
time_units: str = 'DAYS',
start_date_time: str = None,
nper: int = 1,
perioddata: list[tuple] = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Parameters:
time_units (str): Time units ('DAYS', 'HOURS', 'MINUTES', 'SECONDS', 'YEARS')nper (int): Number of stress periodsperioddata (list[tuple]): List of (perlen, nstp, tsmult) tuples for each periodstart_date_time (str): Starting date and time in ISO formatIterative model solution package for solving linear equations.
class ModflowIms:
"""MODFLOW 6 iterative model solution package"""
def __init__(
self,
simulation: MFSimulation,
loading_package: bool = False,
print_option: str = None,
complexity: str = 'SIMPLE',
csv_output_filerecord: str = None,
csv_outer_output_filerecord: str = None,
no_ptcrecord: str = None,
outer_dvclose: float = 1e-4,
outer_maximum: int = 100,
under_relaxation: str = None,
inner_maximum: int = 100,
inner_dvclose: float = 1e-4,
rcloserecord: list = None,
linear_acceleration: str = 'BICGSTAB',
scaling_method: str = None,
reordering_method: str = None,
relaxation_factor: float = 0.97,
preconditioner_levels: int = 7,
preconditioner_drop_tolerance: float = 0.0001,
number_orthogonalizations: int = 0,
filename: str = None,
pname: str = None,
**kwargs
): ...Structured grid discretization package for regular rectangular grids.
class ModflowGwfdis:
"""MODFLOW 6 structured grid discretization"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
length_units: str = 'FEET',
nogrb: bool = None,
xorigin: float = None,
yorigin: float = None,
angrot: float = None,
nlay: int = 1,
nrow: int = 2,
ncol: int = 2,
delr: ArrayData = 1.0,
delc: ArrayData = 1.0,
top: ArrayData = 1.0,
botm: ArrayData = 0.0,
idomain: ArrayData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Unstructured grid discretization package for flexible mesh geometries.
class ModflowGwfdisu:
"""MODFLOW 6 unstructured grid discretization"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
length_units: str = 'FEET',
nogrb: bool = None,
xorigin: float = None,
yorigin: float = None,
angrot: float = None,
nodes: int = None,
nja: int = None,
nvert: int = None,
top: ArrayData = None,
bot: ArrayData = None,
area: ArrayData = None,
idomain: ArrayData = None,
iac: ArrayData = None,
ja: ArrayData = None,
ihc: ArrayData = None,
cl12: ArrayData = None,
hwva: ArrayData = None,
angldegx: ArrayData = None,
vertices: list[tuple] = None,
cell2d: list[tuple] = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Vertex grid discretization package for flexible layered grids.
class ModflowGwfdisv:
"""MODFLOW 6 vertex grid discretization"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
length_units: str = 'FEET',
nogrb: bool = None,
xorigin: float = None,
yorigin: float = None,
angrot: float = None,
nlay: int = 1,
ncpl: int = None,
nvert: int = None,
top: ArrayData = None,
botm: ArrayData = None,
idomain: ArrayData = None,
vertices: list[tuple] = None,
cell2d: list[tuple] = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Node property flow package that defines hydraulic properties.
class ModflowGwfnpf:
"""MODFLOW 6 node property flow package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
ipakcb: str = None,
cellavg: str = None,
thickstrt: bool = None,
cvoptions: str = None,
perched: bool = None,
rewet_record: str = None,
xt3doptions: str = None,
save_specific_discharge: bool = None,
save_saturation: bool = None,
k_filerecord: str = None,
k33_filerecord: str = None,
sat_filerecord: str = None,
icelltype: ArrayData = 0,
k: ArrayData = 1.0,
k22: ArrayData = None,
k33: ArrayData = None,
angle1: ArrayData = None,
angle2: ArrayData = None,
angle3: ArrayData = None,
wetdry: ArrayData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Initial conditions package that sets starting heads.
class ModflowGwfic:
"""MODFLOW 6 initial conditions package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
strt: ArrayData = 1.0,
filename: str = None,
pname: str = None,
**kwargs
): ...Storage package for transient simulations.
class ModflowGwfsto:
"""MODFLOW 6 storage package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
save_flows: bool = None,
ipakcb: str = None,
storagecoefficient: bool = None,
ss_confined_only: bool = None,
tvs_filerecord: str = None,
iconvert: ArrayData = 0,
ss: ArrayData = 1e-5,
sy: ArrayData = 0.15,
steady_state: list[bool] = None,
transient: list[bool] = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Constant head boundary package.
class ModflowGwfchd:
"""MODFLOW 6 constant head boundary package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
observations: dict = None,
maxbound: int = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Well package for pumping and injection wells.
class ModflowGwfwel:
"""MODFLOW 6 well package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
auto_flow_reduce: float = None,
observations: dict = None,
mover: bool = None,
maxbound: int = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Recharge package for distributed recharge.
class ModflowGwfrch:
"""MODFLOW 6 recharge package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
readasarrays: bool = None,
fixed_cell: bool = None,
observations: dict = None,
mover: bool = None,
maxbound: int = None,
recharge: ArrayData = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Evapotranspiration package.
class ModflowGwfevt:
"""MODFLOW 6 evapotranspiration package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
readasarrays: bool = None,
fixed_cell: bool = None,
observations: dict = None,
mover: bool = None,
maxbound: int = None,
surface: ArrayData = None,
rate: ArrayData = None,
depth: ArrayData = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...General head boundary package.
class ModflowGwfghb:
"""MODFLOW 6 general head boundary package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
observations: dict = None,
mover: bool = None,
maxbound: int = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...River package for river-aquifer interaction.
class ModflowGwfriv:
"""MODFLOW 6 river package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
observations: dict = None,
mover: bool = None,
maxbound: int = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Drain package for drainage features.
class ModflowGwfdrn:
"""MODFLOW 6 drain package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
observations: dict = None,
mover: bool = None,
maxbound: int = None,
stress_period_data: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Lake package for lake-aquifer interaction.
class ModflowGwflak:
"""MODFLOW 6 lake package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
boundnames: bool = None,
print_input: bool = None,
print_stage: bool = None,
print_flows: bool = None,
save_flows: bool = None,
stage_filerecord: str = None,
budget_filerecord: str = None,
budgetcsv_filerecord: str = None,
package_convergence_filerecord: str = None,
ts_filerecord: str = None,
observations: dict = None,
mover: bool = None,
surfdep: float = None,
time_conversion: float = None,
length_conversion: float = None,
nlakes: int = None,
noutlets: int = None,
ntables: int = None,
packagedata: list[tuple] = None,
connectiondata: list[tuple] = None,
tables: list[tuple] = None,
outlets: list[tuple] = None,
perioddata: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Streamflow routing package for stream networks.
class ModflowGwfsfr:
"""MODFLOW 6 streamflow routing package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
boundnames: bool = None,
print_input: bool = None,
print_stage: bool = None,
print_flows: bool = None,
save_flows: bool = None,
stage_filerecord: str = None,
budget_filerecord: str = None,
budgetcsv_filerecord: str = None,
package_convergence_filerecord: str = None,
ts_filerecord: str = None,
observations: dict = None,
mover: bool = None,
maximum_depth_change: float = None,
maximum_picard_iterations: int = None,
length_conversion: float = None,
time_conversion: float = None,
nreaches: int = None,
packagedata: list[tuple] = None,
connectiondata: list[tuple] = None,
diversions: list[tuple] = None,
perioddata: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Multi-aquifer well package for complex wells.
class ModflowGwfmaw:
"""MODFLOW 6 multi-aquifer well package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
boundnames: bool = None,
print_input: bool = None,
print_head: bool = None,
print_flows: bool = None,
save_flows: bool = None,
head_filerecord: str = None,
budget_filerecord: str = None,
budgetcsv_filerecord: str = None,
package_convergence_filerecord: str = None,
ts_filerecord: str = None,
observations: dict = None,
mover: bool = None,
flowing_wells: bool = None,
shutdown_theta: float = None,
shutdown_kappa: float = None,
nmawwells: int = None,
packagedata: list[tuple] = None,
connectiondata: list[tuple] = None,
perioddata: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Unsaturated zone flow package.
class ModflowGwfuzf:
"""MODFLOW 6 unsaturated zone flow package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
auxiliary: list[str] = None,
auxmultname: str = None,
boundnames: bool = None,
print_input: bool = None,
print_flows: bool = None,
save_flows: bool = None,
wc_filerecord: str = None,
budget_filerecord: str = None,
budgetcsv_filerecord: str = None,
package_convergence_filerecord: str = None,
ts_filerecord: str = None,
observations: dict = None,
mover: bool = None,
simulate_et: bool = None,
linear_gwet: bool = None,
square_gwet: bool = None,
simulate_gwseep: bool = None,
unsat_etwc: bool = None,
unsat_etae: bool = None,
nuzfcells: int = None,
ntrailwaves: int = None,
nwavesets: int = None,
packagedata: list[tuple] = None,
perioddata: StressPeriodData = None,
filename: str = None,
pname: str = None,
**kwargs
): ...Output control package for managing model output.
class ModflowGwfoc:
"""MODFLOW 6 output control package"""
def __init__(
self,
model: ModflowGwf,
loading_package: bool = False,
budget_filerecord: str = None,
head_filerecord: str = None,
headprintrecord: str = None,
saverecord: list[tuple] = None,
printrecord: list[tuple] = None,
filename: str = None,
pname: str = None,
**kwargs
): ...import flopy
import numpy as np
# Create simulation
sim = flopy.mf6.MFSimulation(sim_name='basic_gwf', version='mf6', exe_name='mf6')
# Add time discretization
tdis = flopy.mf6.ModflowTdis(
sim,
time_units='DAYS',
nper=2,
perioddata=[(1.0, 1, 1.0), (365.0, 12, 1.2)]
)
# Create groundwater flow model
gwf = flopy.mf6.ModflowGwf(sim, modelname='gwf', save_flows=True)
# Add discretization
dis = flopy.mf6.ModflowGwfdis(
gwf,
nlay=3, nrow=50, ncol=50,
delr=100.0, delc=100.0,
top=100.0,
botm=[50.0, 0.0, -50.0]
)
# Add initial conditions
ic = flopy.mf6.ModflowGwfic(gwf, strt=75.0)
# Add node property flow
npf = flopy.mf6.ModflowGwfnpf(
gwf,
k=[10.0, 5.0, 1.0], # Different K for each layer
icelltype=1 # Convertible layers
)
# Add storage for transient simulation
sto = flopy.mf6.ModflowGwfsto(
gwf,
ss=1e-5,
sy=0.2,
iconvert=1,
steady_state={0: True}, # First period steady state
transient={1: True} # Second period transient
)
# Add constant head boundaries
chd_period_data = {
0: [[(0, 0, 0), 100.0], [(0, 49, 49), 80.0]],
1: [[(0, 0, 0), 95.0], [(0, 49, 49), 75.0]]
}
chd = flopy.mf6.ModflowGwfchd(gwf, stress_period_data=chd_period_data)
# Add recharge
rch = flopy.mf6.ModflowGwfrch(gwf, recharge=0.001)
# Add output control
oc = flopy.mf6.ModflowGwfoc(
gwf,
head_filerecord='gwf.hds',
budget_filerecord='gwf.cbc',
saverecord=[('HEAD', 'ALL'), ('BUDGET', 'ALL')],
printrecord=[('HEAD', 'LAST'), ('BUDGET', 'ALL')]
)
# Add solver
ims = flopy.mf6.ModflowIms(sim, complexity='SIMPLE')
# Write and run
sim.write_simulation()
success, buff = sim.run_simulation()import flopy
# Create simulation with multiple models
sim = flopy.mf6.MFSimulation(sim_name='lake_stream', exe_name='mf6')
# Time discretization for seasonal analysis
tdis = flopy.mf6.ModflowTdis(
sim,
time_units='DAYS',
nper=4, # Four seasons
perioddata=[(90, 30, 1.1) for _ in range(4)]
)
# Groundwater flow model
gwf = flopy.mf6.ModflowGwf(sim, modelname='gwf')
# Structured grid
dis = flopy.mf6.ModflowGwfdis(
gwf,
nlay=5, nrow=100, ncol=100,
delr=50.0, delc=50.0,
top=50.0,
botm=[40.0, 30.0, 20.0, 10.0, -10.0]
)
# Initial conditions
ic = flopy.mf6.ModflowGwfic(gwf, strt=45.0)
# Node property flow with varying K
k_values = np.array([20.0, 15.0, 10.0, 5.0, 1.0])
npf = flopy.mf6.ModflowGwfnpf(gwf, k=k_values)
# Lake package
lake_packagedata = [
[0, 42.0, 10, 'lake1'], # Lake ID, stage, connections, name
]
lake_connectiondata = [
[0, 0, (0, 50, 50), 'horizontal', 1.0, 0.5, 0.0, 100.0, 100.0],
]
lak = flopy.mf6.ModflowGwflak(
gwf,
nlakes=1,
packagedata=lake_packagedata,
connectiondata=lake_connectiondata
)
# Stream package
sfr_packagedata = [
[0, (0, 25, 10), 100.0, 1.0, 0.001, 0.0, 1.0, 0.035, 'reach1'],
[1, (0, 25, 11), 100.0, 1.0, 0.001, 0.0, 1.0, 0.035, 'reach2'],
]
sfr_connectiondata = [
[0, -1], # Reach 0 has no upstream connection
[1, 0], # Reach 1 connects to reach 0
]
sfr = flopy.mf6.ModflowGwfsfr(
gwf,
nreaches=2,
packagedata=sfr_packagedata,
connectiondata=sfr_connectiondata
)
# Transport model
gwt = flopy.mf6.ModflowGwt(sim, modelname='gwt')
# Transport solver
ims_gwt = flopy.mf6.ModflowIms(
sim,
filename='gwt.ims',
linear_acceleration='BICGSTAB'
)
sim.register_ims_package(ims_gwt, [gwt.name])
# Write and run
sim.write_simulation()
success, buff = sim.run_simulation()# MODFLOW 6 specific types
ExtFileAction = Literal['copy_relative_paths', 'copy_all', 'copy_none']
ArrayData = Union[int, float, np.ndarray, list, str]
StressPeriodData = dict[int, list[list]]
PackageData = list[tuple]
ConnectionData = list[tuple]
ObservationData = dict[str, list[tuple]]
# Time discretization
PeriodData = list[tuple[float, int, float]] # (perlen, nstp, tsmult)
# Boundary condition data
BoundaryData = list[list] # [cellid, *values]
# File record types
FileRecord = str | list[str]This comprehensive documentation covers the complete MODFLOW 6 API including all major model types, packages, and their parameters. The examples demonstrate both basic and advanced usage patterns for groundwater flow, transport, and surface water interaction modeling.
Install with Tessl CLI
npx tessl i tessl/pypi-flopydocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10