API Reference

RiverGrid class

class fluvial_particle.RiverGrid.RiverGrid(track3d, filename2d, filename3d=None, field_map_2d=None, field_map_3d=None, min_depth=None, *, manning_n=None, chezy_c=None, darcy_f=None, water_density=None, ustar_method=None)

A class of hydrodynamic data and tools defined on VTK structured grids.

__init__(track3d, filename2d, filename3d=None, field_map_2d=None, field_map_3d=None, min_depth=None, *, manning_n=None, chezy_c=None, darcy_f=None, water_density=None, ustar_method=None)

Initialize instance of class RiverGrid.

Parameters:
  • track3d (int) – 1 if 3D model run, 0 else

  • filename2d (str) – path to the input 2D grid. Supported formats: - .vtk: VTK legacy structured grid format - .vts: VTK XML structured grid format (recommended for large files) - .npz: NumPy compressed archive format See the docstring of the read_2d_data() method for additional details.

  • filename3d (str, optional) – path to the input 3D grid. Required for 3D simulations. Supports the same formats as filename2d.

  • field_map_2d (dict) – Mapping from standard field names to model-specific names for the 2D grid. Required keys: bed_elevation, velocity, water_surface_elevation. Plus at least one u* source: ustar, shear_stress, manning_n, chezy_c, darcy_f, energy_slope, or tke. Optional key: wet_dry (computed from depth if not provided). Example: {“bed_elevation”: “Elevation”, “shear_stress”: “TauBed”, …}

  • field_map_3d (dict) – Mapping from standard field names to model-specific names for the 3D grid. Required keys: velocity. Example: {“velocity”: “Velocity”}

  • min_depth (float, optional) – Minimum depth threshold for computing wet_dry if not provided in field_map_2d. Cells with depth > min_depth are considered wet (1), and cells with depth <= min_depth are considered dry (0). Defaults to 0.02 meters.

  • manning_n (float, optional) – Scalar Manning’s n value for computing u*. Use when friction is uniform across the domain. Formula: u* = U*n*sqrt(g)/h^(1/6)

  • chezy_c (float, optional) – Scalar Chezy C value for computing u*. Use when friction is uniform across the domain. Formula: u* = U*sqrt(g)/C

  • darcy_f (float, optional) – Scalar Darcy-Weisbach f value for computing u*. Use when friction is uniform across the domain. Formula: u* = U*sqrt(f/8)

  • water_density (float, optional) – Water density in kg/m³ for shear stress conversion. Defaults to 1000.0 kg/m³.

  • ustar_method (str, optional) – Force a specific u* computation method. Options: ‘auto’ (default), ‘ustar’, ‘shear_stress’, ‘manning’, ‘chezy’, ‘darcy’, ‘energy_slope’, ‘tke’. If ‘auto’, uses the highest priority available method.

Raises:
  • ValueError – track3d is 1 but no filename provided for input 3D grid.

  • ValueError – field_map_2d is missing required core field names.

  • ValueError – field_map_3d is missing required standard field names.

  • ValueError – No method available to compute shear velocity (u*).

property boundarycells

the inflow/outflow 2D boundary cells.

A NumPy ndarray with ndims=1 that holds the indices of the upstream and downstream mesh boundary cells. As currently implemented, upstream is the i=0 row and downstream is the i=nsc-1 row.

Type:

ndarray

build_probe_filter(nparts, comm=None)

Build pipeline for probe filters (i.e. interpolation).

Parameters:
  • nparts (int) – the number of input points to be probed

  • comm (mpi4py object) – MPI communicator, for parallel runs only

create_hdf5(nprints, time, fname='cells.h5', **dset_kwargs)

Create HDF5 file for cell-centered results.

Parameters:
  • nprints (int) – number of printing time steps

  • time (NumPy ndarray) – array of print times

  • fname (str) – file name of output HDF5 file

  • **dset_kwargs (dict) – HDF5 dataset keyword arguments, e.g. compression filter # noqa: E501

Returns:

the newly created and open HDF5 file

Return type:

h5py file object

property fname2d

the filename of the 2d grid input.

Type:

str

property fname3d

the filename of the 3d grid input.

Type:

str

property nn

the number of stream-normal points that define the grids.

For file writing reasons, nn must be >= 1.

Type:

int

property nnc

the number of stream-normal cells defined by the grids.

For file writing reasons, nnc must be >= 1.

Type:

int

property ns

the number of stream-wise points that define the grids.

For file writing reasons, ns must be >= 1.

Type:

int

property nsc

the number of stream-wise cells defined by the grids.

For file writing reasons, nsc must be >= 1.

Type:

int

property nz

the number of vertical points that define the grids.

For file writing reasons, nz must be >= 1.

Type:

int

property nzc

the number of vertical cells defined by the grids.

For file writing reasons, nzc must be >= 1.

Type:

int

out_of_grid(px, py, idx=None)

Check if any points in the probe filter pipeline are out of the 2D domain.

Parameters:
  • px (NumPy ndarray) – x coordinates of new points

  • py (NumPy ndarray) – y coordinates of new points

  • idx (NumPy ndarray, optional) – active indices in px & py. Defaults to None.

Returns:

True for indices of points out of the domain, else False

Return type:

ndarray(bool)

postprocess(output_directory, n_prints, globalnparts, **dset_kwargs)

Write XDMF files and cumulative cell counters, must be executed in serial.

Parameters:
  • output_directory (str) – path to output directory

  • n_prints (int) – total number of printing time steps

  • globalnparts (int) – number of particles across all processors

  • **dset_kwargs (dict) – HDF5 dataset keyword arguments, e.g. compression filter # noqa: E501

process_arrays()

Add required / delete unneeded arrays from 2D and 3D structured grids.

read_2d_data()

Read 2D structured grid data file.

Loads 2D data onto a VTK structured grid. The structured grid can be directly supplied as a .vtk file, a .vts (VTK XML) file, or as a collection of 2D arrays in a NumPy .npz file. The filename is read from the self.fname2d variable, saved during class initialization via the filename2d argument.

The field_map_2d dict (provided at initialization) maps standard field names to model-specific names in the input file. After reading, arrays are renamed to standard names for internal use.

Supported formats:
  • .vtk: VTK legacy structured grid format

  • .vts: VTK XML structured grid format (recommended for large files)

  • .npz: NumPy compressed archive format

If a .npz file is supplied, then each expected field is a 2D array of the same shape. The (x, y) coordinates of every node that defines the grid are supplied via the x & y arguments. The remaining fields are all defined at the grid points. The npz file must have been saved using the following keyword arguments:

  • x: x coordinates of the grid

  • y: y coordinates of the grid

  • elev: topographic elevation

  • ibc: indicates whether node is wet (1) or dry (0), optional - computed from depth if missing

  • shear: shear stress magnitude

  • vx: x-component of fluid velocity

  • vy: y-component of fluid velocity

  • wse: water surface elevation

  • z (optional): z coordinates of the grid. Defaults to constant 0.

  • vz (optional): z-component of fluid velocity. Defaults to constant 0.

read_3d_data()

Read 3D structured grid data file.

Loads 3D data onto a VTK structured grid. The structured grid can be directly supplied as a .vtk file, a .vts (VTK XML) file, or as a collection of 3D arrays in a NumPy .npz file. The filename is read from the self.fname3d variable, saved during class initialization via the filename3d argument.

The field_map_3d dict (provided at initialization) maps standard field names to model-specific names in the input file. After reading, arrays are renamed to standard names for internal use.

Supported formats:
  • .vtk: VTK legacy structured grid format

  • .vts: VTK XML structured grid format (recommended for large files)

  • .npz: NumPy compressed archive format

If a .npz file is supplied, then each expected field is a 3D array of the same shape. The (x, y, z) coordinates of every node that defines the grid are supplied via the x, y, & z arguments. The 3D fluid velocity is the other expected field, and it is defined at the grid points. The npz file must have been saved using the following :keyword - x: x coordinates of the grid :keyword - y: y coordinates of the grid :keyword - z: z coordinates of the grid :keyword - vx: x-component of fluid velocity :keyword - vy: y-component of fluid velocity :keyword - vz: z-component of fluid velocity

reconstruct_filter_pipeline(nparts)

Reconstruct VTK probe filter pipeline objects.

Parameters:

nparts (int) – the number of input points to be probed

property required_keys2d

standard array names that will be present in the 2D grid.

Returns core required fields plus the u* source field being used, plus wet_dry.

Type:

tuple(str)

property required_keys3d

standard array names required in the input 3D grid.

Type:

tuple(str)

property track3d

flag that indicates the dimension of the simulation.

If 3D simulation, track3d=1. Else track3d=0.

Type:

int

update_2d_pipeline(px, py, idx=None)

Update the 2D VTK probe filter pipeline.

Parameters:
  • px (NumPy ndarray) – x coordinates of new points

  • py (NumPy ndarray) – y coordinates of new points

  • idx (NumPy ndarray, optional) – active indices in px & py. Defaults to None.

update_3d_pipeline(px, py, pz, idx=None)

Update the 3D VTK probe filter pipeline.

Parameters:
  • px (NumPy ndarray) – x coordinates of new points

  • py (NumPy ndarray) – y coordinates of new points

  • pz (NumPy ndarray) – z coordinates of new points

  • idx (NumPy ndarray, optional) – active indices in px, py & pz. Defaults to None.

write_hdf5(obj, name, data)

Write cell arrays to HDF5 object.

Parameters:
  • obj (h5py object) – opened HDF5 file to write data to

  • name (str) – key of the data to be written

  • data (NumPy ndarray) – data to be written

write_hdf5_xmf(filexmf, time, dims, names, attrnames, dtypes=None, center='Cell')

Body for cell-centered time series data.

Parameters:
  • filexmf (file) – open file to write

  • time (float) – current simulation time

  • dims (tuple) – integer values describing dimensions of the grid

  • names (list of str) – paths to datasets from the root directory in the HDF5 file

  • attrnames (list of str) – descriptive names corresponding to names

  • dtypes (list of str) – data types corresponding to names (either Float or Int)

  • center (str) – Node for node-centered data, Cell for cell-centered data

write_hdf5_xmf_attr(filexmf, dims, name, attrname, center, dtype='Float')

Write data sets as attributes to the XDMF file.

Parameters:
  • filexmf (file) – open file to write

  • dims (tuple) – integer values describing dimensions of the grid

  • name (str) – path to dataset from the root directory in the HDF5 file

  • attrname (str) – descriptive name of dataset

  • center (str) – Node for node-centered data, Cell for cell-centered data

  • dtype (str) – dataset type, defaults to Float

Footer for cell-centered time series data.

Parameters:

filexmf (file) – open file to write

write_hdf5_xmf_header1d(filexmf)

Header for cell-centered time series data.

Parameters:

filexmf (file) – open file to write

write_hdf5_xmf_header2d(filexmf)

Header for cell-centered time series data.

Parameters:

filexmf (file) – open file to write

write_hdf5_xmf_header3d(filexmf)

Header for cell-centered time series data.

Parameters:

filexmf (file) – open file to write

Particles class

class fluvial_particle.Particles.Particles(nparts, x, y, z, rng, mesh, **kwargs)

A class of particles, each with a velocity, size, and mass.

Models passive particles, i.e. no active drift component. A superclass for particles with active drift.

__init__(nparts, x, y, z, rng, mesh, **kwargs)

Initialize instance of class Particles.

Parameters:
  • nparts (int) – number of particles in this instance

  • x (float) – x-coordinate of each particle, numpy array of length nparts

  • y (float) – y-coordinate of each particle, numpy array of length nparts

  • z (float) – z-coordinate of each particle, numpy array of length nparts

  • rng (Numpy object) – random number generator

  • mesh (RiverGrid) – class instance of the river hydrodynamic data

  • **kwargs (dict) – additional keyword arguments # noqa: E501

Keyword Arguments:
  • Track3D (int) – 1 if 3D model run, 0 else. Defaults to 1

  • lev (float) – lateral eddy viscosity, scalar. Defaults to 0.25

  • beta (float) – coefficients that scale diffusion, scalar or a tuple/list/numpy array of length 3. Defaults to 0.067

  • min_depth (float) – minimum allowed depth that particles may enter, scalar. Defaults to 0.02

  • vertbound (float) – bounds particle in fractional water column to [vertbound, 1-vertbound], scalar. Defaults to 0.01

  • comm (mpi4py object) – MPI communicator used in parallel execution. Defaults to None

  • PartStartTime (float) – variable particle start times. Defaults to the simulation start time

property active

Mask both in_bounds_mask and start_time_mask.

property bedelev

NumPy array of particles’ bed elevation.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property beta

diffusion scaling coefficient.

beta accepts input as either a scalar float/np.floating, or a tuple/list/ndarray of size 3. beta is saved as a 3D np.float64 ndarray corresponding to (x,y,z) components.

Type:

ndarray

calc_diffusion_coefs()

Calculate diffusion coefficients, McDonald & Nelson (2021).

calc_hdf5_chunksizes(nprints)

Calculate chunksizes for datasets in particles HDF5 output.

Designed to create chunks close to 1 MiB for 8 byte numbers. HDF5 org recommends chunks of size between 10 KiB - 1 MiB; Trials on Denali HPC show 1 MiB works better

Parameters:

nprints (int) – total number of printing time steps

Returns:

1st tuple is chunk size of datasets for 1D arrays (len=2), 2nd tuple is chunk size of datasets for 2D velocity arrays (len=3)

Return type:

tuple(tuple, tuple)

property cellindex2d

the index of the 2D cell that each particle is currently in.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property cellindex3d

the index of the 3D cell that each particle is currently in.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

create_hdf5(nprints, globalnparts, comm=None, fname='particles.h5', **dset_kwargs)

Create an HDF5 file to write incremental particles results.

Parameters:
  • nprints (int) – size of first dimension, indexes printing time slices

  • globalnparts (int) – global number of particles, distributed across processors

  • comm (MPI communicator) – only for parallel runs

  • fname (string) – name of the HDF5 file

  • **dset_kwargs (dict) – HDF5 dataset keyword arguments, e.g. compression filter # noqa: E501

Returns:

the newly created and open HDF5 file

Return type:

h5py file object

create_hdf5_xdmf(output_directory, n_prints, globalnparts)

Creates the particles XDMF file for visualizations in Paraview.

Note that this implementation assumes the HDF5 file will be in the same directory as filexmf with the name particles.h5.

Parameters:
  • output_directory (string) – path to output directory

  • n_prints (int) – total number of printing steps

  • globalnparts (int) – number of particles across all processors

deactivate_particles(idx)

Turn off particles that have left the river domain.

Parameters:

idx (int ndarray) – index or indices of particle(s) to turn off

property depth

the water-column depth that each particle is currently in.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property diffx

the diffusion coefficient in the x-direction of each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property diffy

the diffusion coefficient in the y-direction of each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property diffz

the diffusion coefficient in the z-direction of each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

gen_rands()

Generate random numbers drawn from standard normal distribution.

get_total_position()

Return complete position of particle.

handle_dry_parts(px, py, dt)

Adjust trajectories of dry particles.

Parameters:
  • px (float NumPy array) – new x coordinates of particles

  • py (float NumPy array) – new y coordinates of particles

  • dt (float) – time step

property htabvbed

the elevation of each particle above the channel bed.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property in_bounds_mask

masks particles that are not in the 2D grid.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)). Must have dtype=bool.

Type:

ndarray(bool)

initial_validation(starttime=0.0, frac=None)

Perform validation.

Perform validation of initial 2D positions, set vertical positions if provided, and interpolate mesh arrays for the simulation.

This method validates the initial particle positions in 2D space, ensures that the particles are within the boundaries of the 2D grid, interpolates the necessary mesh field values, and sets the vertical positions of the particles based on the frac parameter if provided. It also sets the simulation’s start time and handles the initial interpolation of the 3D velocity field.

Parameters:
  • starttime (float) – Initial time of the simulation in seconds. Defaults to 0.0.

  • frac (float or np.ndarray, optional) – Specifies the vertical starting position of the particles as a fraction of the water column depth. If provided, it can be a scalar or a NumPy array, with 0.0 representing the bed elevation and 1.0 representing the water surface. Defaults to None.

Raises:

ValueError – If none of the initial points are within the 2D grid, an exception is raised.

Notes

  • If frac is provided, the vertical positions (z) are calculated based on the

    bed elevation and water depth.

  • Mesh arrays and 2D and 3D field values are interpolated to ensure the simulation

    starts with valid data.

interp_3d_field(px=None, py=None, pz=None)

Interpolate 3D velocity field at current particle positions.

Parameters:
  • px (Numpy ndarray) – Particle position coordinates. Defaults to self.x.

  • py (Numpy ndarray) – Particle position coordinates. Defaults to self.y.

  • pz (Numpy ndarray) – Particle position coordinates. Defaults to self.z.

interp_fields(px=None, py=None, pz=None, twod=True, threed=True)

Interpolate mesh fields at current particle positions.

Parameters:
  • px (Numpy ndarray) – Particle position coordinates. Defaults to self.x.

  • py (Numpy ndarray) – Particle position coordinates. Defaults to self.y.

  • pz (Numpy ndarray) – Particle position coordinates. Defaults to self.z.

  • twod (bool, optional) – Flag to interpolate 2D field arrays. Defaults to True.

  • threed (bool, optional) – Flag to interpolate 3D field arrays. Defaults to True.

property lev

the constant lateral eddy viscosity.

Must be a scalar, and it will be converted to np.float64.

Type:

np.float64

property mesh

the mesh containing the VTK grids and hydrodynamic data.

Type:

RiverGrid

property min_depth

the minimum water-column depth that particles may enter.

Must be a scalar, and it will be converted to np.float64.

Type:

np.float64

move(time, dt)

Update particle positions.

Parameters:
  • time (float) – the new time at end of position update

  • dt (float) – time step

property normdepth

the normalized depth of each particle.

In other words, the fraction of the way from the channel bed to the particle’s elevation. In the range of (0, 1). Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property nparts

the number of simulated particles.

In parallel execution mode, this is the number of particles per CPU. Must be a positive integer.

Type:

int

property part_start_time

the starting simulation time of the particles.

If a scalar, all particles will be activated when the simulation time exceeds part_start_time. If an ndarray, must be 1D and the same length as the number of simulated particles.

Type:

np.float64 or ndarray

perturb_2d(px, py, dt)

Project particles’ 2D trajectories based on starting interpolated quantities.

Parameters:
  • px (float NumPy array) – new x coordinates of particles

  • py (float NumPy array) – new y coordinates of particles

  • dt (float) – time step

perturb_2d_random_only(px, py, idx, dt)

Project new particle 2D positions based on random walk only.

Parameters:
  • px (float NumPy array) – new x coordinates of particles

  • py (float NumPy array) – new y coordinates of particles

  • idx (int NumPy array) – indices of dry particles

  • dt (float) – time step

perturb_z(dt)

Project particles’ vertical trajectories and validate.

Parameters:

dt (float) – time step

Returns:

new elevation array

Return type:

ndarray

prevent_mindepth(px, py)

Prevent particles from entering a position with depth < min_depth.

Parameters:
  • px (float NumPy array) – new x coordinates of particles

  • py (float NumPy array) – new y coordinates of particles

property rng

NumPy random number generator.

Generates random numbers for stochastic diffusion.

Type:

np.random.RandomState

property shearstress

the shear stress interpolated from the mesh to each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property start_time_mask

masks particles that are active by (part_start_time <= current simulation time).

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)). Must have dtype=bool.

Type:

ndarray(bool)

property time

the current simulation time.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property track3d

flag that indicates the dimension of the simulation.

If 3D simulation, track3d=1. Else track3d=0.

Type:

int

property ustar

the shear velocity at each particle.

Computed as the square root of shearstress / 1000 [kg/m^3]. Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

validate_2d_pos(px, py)

Check that positions are inside the 2D grid and deactivate particles leaving it.

Parameters:
  • px (float NumPy array) – new x coordinates of particles

  • py (float NumPy array) – new y coordinates of particles

validate_z(pz)

Check that new particle vertical position is within bounds.

Parameters:

pz (float NumPy array) – new elevation array

property velx

the fluid velocity x-component interpolated to each particle from the mesh.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property vely

the fluid velocity y-component interpolated to each particle from the mesh.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property velz

the fluid velocity z-component interpolated to each particle from the mesh.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property vertbound

the fraction of the water column that buffers particles from the channel bed and water surface.

Particles are bounded to [bedelev + vertbound * depth, wse - vertbound * depth]. Must be between 0.0 and 0.5.

Type:

np.float64

write_hdf5(obj, tidx, start, end, time, rank)

Write particle positions and interpolated quantities to file.

Parameters:
  • obj (h5py object) – open HDF5 file object created with self.create_hdf5()

  • tidx (int) – current time slice index

  • start (int) – starting index of this processor’s assigned write space

  • end (int) – ending write index (non-inclusive)

  • time (float) – current simulation time

  • rank (int) – processor rank if run in MPI (0 in serial)

write_hdf5_xmf(filexmf, time, nprints, nparts, tidx)

Write the body of the particles XDMF file for visualizations in Paraview.

Note that this implementation assumes the HDF5 file will be in the same directory as filexmf with the name particles.h5.

Parameters:
  • filexmf (file) – open file to write

  • time (float) – current simulation time

  • nprints (int) – total number of printing steps

  • nparts (int) – global number of particles summed across processors

  • tidx (int) – time slice index corresponding to time

Write final lines of XDMF file.

Parameters:

filexmf (file) – open file to write

write_hdf5_xmf_gridfooter(filexmf)

Write footer of the XDMF Uniform grid type.

Parameters:

filexmf (file) – open file to write

write_hdf5_xmf_gridheader(filexmf, time, nprints, nparts, tidx)

Write header of the XDMF Uniform grid type.

Parameters:
  • filexmf (file) – open file to write

  • time (float) – current simulation time

  • nprints (int) – total number of printing steps

  • nparts (int) – global number of particles summed across processors

  • tidx (int) – time slice index corresponding to time

write_hdf5_xmf_header(filexmf)

Write initial lines of XDMF file.

Parameters:

filexmf (file) – open file to write

write_hdf5_xmf_scalarattribute(filexmf, nprints, nparts, tidx, name, fname, path, number_type='Float', precision='8')

Write scalar attribute to XDMF file.

Parameters:
  • filexmf (file) – open file to write

  • nprints (int) – total number of printing steps

  • nparts (int) – global number of particles summed across processors

  • tidx (int) – time slice index corresponding to time

  • name (str) – name of the attribute

  • fname (str) – name of the HDF5 file holding the data

  • path (str) – path to the attribute data set

  • number_type (str) – XDMF NumberType - “Float” or “Int” (default: “Float”)

  • precision (str) – bytes per value - “4” or “8” (default: “8”)

write_hdf5_xmf_vectorattribute(filexmf, nprints, nparts, tidx, name, fname, path)

Write vector attribute to XDMF file.

Parameters:
  • filexmf (file) – open file to write

  • nprints (int) – total number of printing steps

  • nparts (int) – global number of particles summed across processors

  • tidx (int) – time slice index corresponding to time

  • name (str) – name of the attribute

  • fname (str) – name of the HDF5 file holding the data

  • path (str) – path to the attribute data set

property wse

the water surface elevation interpolated to each particle’s 2D position.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property x

the x-coordinate of each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property y

the y-coordinate of each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

property z

the z-coordinate of each particle.

Must be 1D, the same length as the number of particles (i.e. shape==(self.nparts,)).

Type:

ndarray

FallingParticles class

class fluvial_particle.FallingParticles.FallingParticles(nparts, x, y, z, rng, mesh, **kwargs)

A subclass of Particles that accelerate due to gravity up to the Ferguson & Church (2004) settling velocity.

__init__(nparts, x, y, z, rng, mesh, **kwargs)

Initialize instance of class FallingParticles.

Parameters:
  • nparts (int) – number of particles in this instance

  • x (float) – x-coordinate of each particle, numpy array of length nparts

  • y (float) – y-coordinate of each particle, numpy array of length nparts

  • z (float) – z-coordinate of each particle, numpy array of length nparts

  • rng (Numpy object) – random number generator

  • mesh (RiverGrid) – class instance of the river hydrodynamic data

  • **kwargs (dict) – additional keyword arguments # noqa: E501

Keyword Arguments:
  • radius (float) – radius of the particles [m], scalar or NumPy array of length nparts. Defaults to 0.0005

  • rho (float) – density of the particles [kg/m^3], scalar or NumPy array of length nparts. Defaults to 2650.0

  • c1 (float) – viscous drag coefficient [-], scalar or NumPy array of length nparts. Defaults to 20.0

  • c2 (float) – turbulent wake drag coefficient [-], scalar or NumPy array of length nparts. Defaults to 1.1

property c1

np.float64 or ndarray.

Viscous drag coef. in Ferguson and Church (2004) terminal settling velocity equation.If an ndarray, must be 1D and the same length as the number of simulated particles.

property c2

np.float64 or ndarray.

Turbulent wake drag coef. in Ferguson and Church (2004) terminal settling velocity equation. If an ndarray, must be 1D and the same length as the number of simulated particles.

create_hdf5(nprints, globalnparts, comm=None, fname='particles.h5')

Create an HDF5 file to write incremental particles results.

Subclass override method creates additional datasets in the HDF5 file.

Parameters:
  • nprints (int) – size of first dimension, indexes printing time slices

  • globalnparts (int) – global number of particles, distributed across processors

  • comm (MPI communicator) – only for parallel runs. Defaults to None

  • fname (string) – name of the HDF5 file. Defaults to “particles.h5”

Returns:

the newly created and open HDF5 file

Return type:

h5py file object

deactivate_particles(idx)

Turn off particles that have left the river domain.

Parameters:

idx (int) – index of particle to turn off

perturb_z(dt)

Project particles’ vertical trajectories, random wiggle + gravitational acceleration.

Parameters:

dt (float) – time step

Returns:

new elevation array

Return type:

ndarray

property radius

np.float64 or ndarray.

Radius of the particles in Ferguson and Church (2004) terminal settling velocity equation. If an ndarray, must be 1D and the same length as the number of simulated particles. All radius values must be greater than 0.

property rho

np.float64 or ndarray.

Density of the particles in Ferguson and Church (2004) terminal settling velocity equation. If an ndarray, must be 1D and the same length as the number of simulated particles. All rho values must be greater than 0.

write_hdf5(obj, tidx, start, end, time, rank)

Write particle positions and interpolated quantities to file.

Subclass override method writes additional arrays to output HDF5 file.

Parameters:
  • obj (h5py object) – open HDF5 file object created with self.create_hdf5()

  • tidx (int) – current time slice index

  • start (int) – starting index of this processor’s assigned write space

  • end (int) – ending write index (non-inclusive)

  • time (float) – current simulation time

  • rank (int) – processor rank if run in MPI (0 in serial)

write_hdf5_xmf(filexmf, time, nprints, nparts, tidx)

Write the body of the particles XDMF file for visualizations in Paraview.

Note that this implementation assumes the HDF5 file will be in the same directory as filexmf with the name particles.h5.

Parameters:
  • filexmf (file) – open file to write

  • time (float) – current simulation time

  • nprints (int) – total number of printing steps

  • nparts (int) – global number of particles summed across processors

  • tidx (int) – time slice index corresponding to time

LarvalParticles class

class fluvial_particle.LarvalParticles.LarvalParticles(nparts, x, y, z, rng, mesh, **kwargs)

A larval fish subclass of Particles, a helper superclass for bottom- or top-swimmers.

On its own, the LarvalParticles class does not implement any special swimming behavior (i.e. active-drift). LarvalTopParticles will swim near the water surface. LarvalBotParticles will swim near the channel bed.

__init__(nparts, x, y, z, rng, mesh, **kwargs)

Initialize instance of class LarvalParticles.

Parameters:
  • nparts (int) – number of particles in this instance

  • x (float) – x-coordinate of each particle, numpy array of length nparts

  • y (float) – y-coordinate of each particle, numpy array of length nparts

  • z (float) – z-coordinate of each particle, numpy array of length nparts

  • rng (Numpy object) – random number generator

  • mesh (RiverGrid) – class instance of the river hydrodynamic data

  • **kwargs (dict) – additional keyword arguments # noqa: E501

Keyword Arguments:
  • amp (float) – amplitude of sinusoid as depth fraction, scalar or NumPy array of length nparts.

  • 0.2 (Defaults to)

  • period (float) – period of swimming to compute ttime, scalar or NumPy array of length nparts.

  • 60.0 (Defaluts to)

property amp

amplitude of sinusoid swimming behavior as depth fraction.

If an ndarray, must be 1D and the same length as the number of simulated particles.

Type:

np.float64 or ndarray

create_hdf5(nprints, globalnparts, comm=None, fname='particles.h5')

Create an HDF5 file to write incremental particles results.

Subclass override method creates additional datasets in the HDF5 file.

Parameters:
  • nprints (int) – size of first dimension, indexes printing time slices

  • globalnparts (int) – global number of particles, distributed across processors

  • comm (MPI communicator) – only for parallel runs. Defaults to None

  • fname (string) – name of the HDF5 file. Defaults to “particles.h5”

Returns:

the newly created and open HDF5 file

Return type:

h5py file object

deactivate_particles(idx)

Turn off particles that have left the river domain.

Parameters:

idx (int) – index of particle to turn off

property period

period of sinusoid swimming behavior.

If an ndarray, must be 1D and the same length as the number of simulated particles.

Type:

np.float64 or ndarray

property ttime

phase of swimmers, must be same length as the number of simulated particles.

Type:

ndarray

write_hdf5(obj, tidx, start, end, time, rank)

Write particle positions and interpolated quantities to file.

Subclass override method writes additional arrays to output HDF5 file.

Parameters:
  • obj (h5py object) – open HDF5 file object created with self.create_hdf5()

  • tidx (int) – current time slice index

  • start (int) – starting index of this processor’s assigned write space

  • end (int) – ending write index (non-inclusive)

  • time (float) – current simulation time

  • rank (int) – processor rank if run in MPI (0 in serial)

write_hdf5_xmf(filexmf, time, nprints, nparts, tidx)

Write the body of the particles XDMF file for visualizations in Paraview.

Note that this implementation assumes the HDF5 file will be in the same directory as filexmf with the name particles.h5.

Parameters:
  • filexmf (file) – open file to write

  • time (float) – current simulation time

  • nprints (int) – total number of printing steps

  • nparts (int) – global number of particles summed across processors

  • tidx (int) – time slice index corresponding to time

LarvalBotParticles class

class fluvial_particle.LarvalParticles.LarvalBotParticles(nparts, x, y, z, rng, mesh, **kwargs)

A subclass of LarvalParticles for larvae that swim in the bottom of water column.

__init__(nparts, x, y, z, rng, mesh, **kwargs)

Initialize instance of class LarvalParticles.

Parameters:
  • nparts (int) – number of particles in this instance

  • x (float) – x-coordinate of each particle, numpy array of length nparts

  • y (float) – y-coordinate of each particle, numpy array of length nparts

  • z (float) – z-coordinate of each particle, numpy array of length nparts

  • rng (Numpy object) – random number generator

  • mesh (RiverGrid) – class instance of the river hydrodynamic data

  • **kwargs (dict) – additional keyword arguments # noqa: E501

Keyword Arguments:
  • amp (float) – amplitude of sinusoid as depth fraction, scalar or NumPy array of length nparts.

  • 0.2 (Defaults to)

  • period (float) – period of swimming to compute ttime, scalar or NumPy array of length nparts.

  • 60.0 (Defaluts to)

perturb_z(dt)

Project particles vertical trajectory, sinusoidal bed-swimmer.

Parameters:

dt (float) – time step

Returns:

new elevation array

Return type:

ndarray

LarvalTopParticles class

class fluvial_particle.LarvalParticles.LarvalTopParticles(nparts, x, y, z, rng, mesh, **kwargs)

A subclass of LarvalParticles for larvae that swim in the top of water column.

__init__(nparts, x, y, z, rng, mesh, **kwargs)

Initialize instance of class LarvalParticles.

Parameters:
  • nparts (int) – number of particles in this instance

  • x (float) – x-coordinate of each particle, numpy array of length nparts

  • y (float) – y-coordinate of each particle, numpy array of length nparts

  • z (float) – z-coordinate of each particle, numpy array of length nparts

  • rng (Numpy object) – random number generator

  • mesh (RiverGrid) – class instance of the river hydrodynamic data

  • **kwargs (dict) – additional keyword arguments # noqa: E501

Keyword Arguments:
  • amp (float) – amplitude of sinusoid as depth fraction, scalar or NumPy array of length nparts.

  • 0.2 (Defaults to)

  • period (float) – period of swimming to compute ttime, scalar or NumPy array of length nparts.

  • 60.0 (Defaluts to)

perturb_z(dt)

Project particles vertical trajectory, sinusoidal top-swimmer.

Parameters:

dt (float) – time step

Returns:

new elevation array

Return type:

ndarray

Helpers

General helper functions.

fluvial_particle.Helpers.checkcommandarguments()

Check the user’s command line arguments.

Returns:

Parsed command-line arguments as a dictionary.

Return type:

dict

Raises:
  • SystemExit – If –init flag is provided (after generating template).

  • FileNotFoundError – If settings_file does not exist.

  • NotADirectoryError – If output_directory does not exist.

fluvial_particle.Helpers.convert_grid_hdf5tovtk(h5fname, output_dir, output_prefix='cells', output_threed=True)

Convert an HDF5 RiverGrid mesh output file into a time series of VTKStructuredGrid files.

This function reads a specified HDF5 file containing grid data and converts it into multiple VTK files, either in 2D or 3D format, based on the user’s preference. The output files are named using a specified prefix and are saved in the designated output directory.

Parameters:
  • h5fname (str) – Path to the RiverGrid HDF5 output file.

  • output_dir (str) – Directory to write output VTK files.

  • output_prefix (str, optional) – Shared name of the output VTK files. A suffix like 00.vtk will be appended to each one. Defaults to cells.

  • output_threed (bool, optional) – If True, output files will be on 3D grids. If False, output will be 2D. Defaults to True.

Raises:

NotADirectoryError – If the output directory output_dir does not exist.

fluvial_particle.Helpers.convert_particles_hdf5tocsv(h5fname, output_dir, output_prefix='particles')

Convert an HDF5 Particles output file into a time series of csv files.

Parameters:
  • h5fname (str) – path to the Particles HDF5 output file

  • output_dir (str) – directory to write output csv files

  • output_prefix (str, optional) – shared name of the output csv files, a suffix like “00.csv” will be appended to each one. Defaults to “particles”.

Raises:

NotADirectoryError – if the output directory output_dir does not exist

fluvial_particle.Helpers.create_parser()

Factory method to create an argument parser for command-line arguments.

Returns:

the container for command line argument specifications

Return type:

argparse.ArgumentParser

fluvial_particle.Helpers.generate_settings_template(output_path='user_options.py')

Generate a template settings file for the user.

Parameters:

output_path (str) – Path where the template file will be written. Defaults to ‘user_options.py’ in the current directory.

Return type:

None

fluvial_particle.Helpers.get_prng(timer, comm=None, seed=None)

Generate a random seed using time and the process id, then create and return the random number generator.

Parameters:
  • timer (time.time or MPI.Wtime) – object that controls the timing; time.time for serial execution, MPI.Wtime for parallel

  • comm (MPI.Intracomm) – MPI communicator for parallel execution. Defaults to None

  • seed (int) – random seed

Returns:

the random number generator

Return type:

np.random.RandomState

fluvial_particle.Helpers.load_checkpoint(fname, tidx, start, end, comm=None)

Load initial positions from a checkpoint HDF5 file.

This function retrieves the starting positions of particles from a specified checkpoint file in HDF5 format. It supports parallel execution using MPI, allowing for efficient data loading across multiple processors.

Parameters:
  • fname (str) – Path to the checkpoint HDF5 file.

  • tidx (int) – Outer index of HDF5 datasets, indicating the specific time step to load.

  • start (int) – Starting index of this processor’s assigned space.

  • end (int) – Ending index (non-inclusive) for the data slice.

  • comm (mpi4py communicator, optional) – MPI communicator for parallel runs. If None, the function runs in a single process.

Returns:

A tuple containing the (x, y, z) starting positions of the

particles and the simulation start time.

Return type:

Tuple(ndarray, ndarray, ndarray, int)

Raises:

FileNotFoundError – If the specified HDF5 file does not exist.

fluvial_particle.Helpers.load_variable_source(fname)

Load variable source data.

Input file must be a comma separated values file with 5 columns:

  1. start_time (float): the time at which to activate the particles

  2. x(float): the starting x-coordinate of the particles

  3. y(float): the starting y-coordinate of the particles

  4. z(float): the starting z-coordinate of the particles

  5. numpart (int): the number of particles to activate

Each row will add additional particles to the simulation. For example, if a given row in the CSV file is “10.0, 6.14, 9.09, 10.3, 100”, then 100 particles will be initiated from the point (6.14, 9.09, 10.3) starting at a simulation time of 10.0 seconds.

Parameters:

fname (str) – path to CSV file containing the variable source data

Raises:
  • FileNotFoundError – the path to the input CSV given in fname is not valid

  • ValueError – the input did not contain 5 columns per row

Returns:

each output ndarray is 1D and has length equal to the summed numpart column

Return type:

Tuple(ndarray, ndarray, ndarray, ndarray)

Settings

Settings file, subclass of dictionary.

class fluvial_particle.Settings.Settings(**kwargs)

Handler class to user defined parameters. Allows us to check a users input parameters in the backend.

classmethod read(filename)

Load user parameters from options file.

Parameters:

filename (str) – path to the options file

Returns:

dict-like object with user parameters stored as key: value pairs

Return type:

Settings

property required_keys

Attributes required in the options file.

Returns:

list of the required keys: SimTime, dt, Track3D, PrintAtTick, file_name_2d, file_name_3d, NumPart, StartLoc, field_map_2d, field_map_3d

Return type:

list(str)

Core API

Fluvial Particle - Lagrangian particle tracking for fluvial environments.

class fluvial_particle.SimulationResults(output_dir)

High-level interface for accessing simulation output.

This class provides convenient methods for loading and analyzing particle tracking results stored in HDF5 format.

Parameters:

output_dir (str | pathlib.Path)

output_dir

Path to the output directory.

num_timesteps

Number of output timesteps in the simulation.

num_particles

Number of particles in the simulation.

times

Array of simulation times for each output timestep.

close()

Close the HDF5 file.

Return type:

None

property coordinate_names: list[str]

Available coordinate fields.

get_depths(timestep=None)

Get water depths at particle locations.

Parameters:

timestep (int | None) – Specific timestep index. If None, returns all timesteps.

Returns:

Depth values of shape (n_particles,) or (n_timesteps, n_particles).

Return type:

NDArray[np.floating]

get_positions(timestep=None, flatten_z=False)

Get particle positions.

Parameters:
  • timestep (int | None) – Specific timestep index to retrieve. If None, returns all timesteps. Supports negative indexing (-1 for last).

  • flatten_z (bool) – If True, set z coordinates to 0 (useful for 2D visualization).

Returns:

array of shape (n_particles, 3) If timestep is None: array of shape (n_timesteps, n_particles, 3)

Return type:

If timestep is specified

get_positions_2d(timestep=None)

Get particle positions as 2D (x, y) coordinates.

Convenience method for 2D visualizations and analysis where the z coordinate is not needed.

Parameters:

timestep (int | None) – Specific timestep index to retrieve. If None, returns all timesteps. Supports negative indexing (-1 for last).

Returns:

array of shape (n_particles, 2) If timestep is None: array of shape (n_timesteps, n_particles, 2)

Return type:

If timestep is specified

get_property(name, timestep=None)

Get a particle property.

Parameters:
  • name (str) – Property name. Use property_names to see available options. Common properties: ‘depth’, ‘wse’, ‘bedelev’, ‘velvec’, ‘htabvbed’, ‘cellidx2d’, ‘cellidx3d’.

  • timestep (int | None) – Specific timestep index. If None, returns all timesteps.

Returns:

Property values. Shape depends on property and timestep selection.

Raises:

KeyError – If property name doesn’t exist.

Return type:

NDArray

get_velocities(timestep=None)

Get particle velocities.

Convenience method for accessing the velocity vector property.

Parameters:

timestep (int | None) – Specific timestep index. If None, returns all timesteps.

Returns:

Velocity vectors of shape (n_particles, 3) or (n_timesteps, n_particles, 3).

Return type:

NDArray[np.floating]

property num_particles: int

Number of particles.

property num_timesteps: int

Number of output timesteps.

property property_names: list[str]

Available property fields.

summary()

Return a summary of the simulation results.

Returns:

Multi-line string with simulation statistics.

Return type:

str

property times: NDArray[np.floating]

Simulation times for each output timestep.

to_dataframe(timestep=None)

Convert results to a pandas DataFrame.

Parameters:

timestep (int | None) – Specific timestep to convert. If None, includes all timesteps.

Returns:

pandas.DataFrame with columns for coordinates, time, and properties.

Raises:

ImportError – If pandas is not installed.

to_pyvista(timestep=-1, include_inactive=False)

Convert particle positions to a PyVista PolyData object.

Creates a point cloud with particle positions and all available scalar properties attached as point data arrays.

Parameters:
  • timestep (int) – Timestep index to convert. Supports negative indexing (-1 for last timestep). Default is -1.

  • include_inactive (bool) – If True, include inactive particles (NaN positions). If False (default), only include active particles.

Returns:

pyvista.PolyData with particle positions as points and properties as point data arrays.

Raises:

ImportError – If pyvista is not installed.

Example:

import pyvista as pv

results = SimulationResults("./output")
particles = results.to_pyvista(timestep=-1)

# Plot with PyVista
particles.plot(scalars="depth", cmap="viridis")

# Or add to a plotter with the grid
grid = pv.read("grid.vts")
plotter = pv.Plotter()
plotter.add_mesh(grid, opacity=0.5)
plotter.add_points(particles, scalars="depth", point_size=10)
plotter.show()
to_pyvista_sequence()

Get all timesteps as a list of PyVista PolyData objects.

Useful for creating animations or iterating through timesteps.

Returns:

List of pyvista.PolyData objects, one per timestep.

Note

Requires pyvista to be installed.

Example:

results = SimulationResults("./output")
timesteps = results.to_pyvista_sequence()

# Create animation
plotter = pv.Plotter(off_screen=True)
plotter.open_gif("particles.gif")
for particles in timesteps:
    plotter.clear_actors()
    plotter.add_points(particles, color="red")
    plotter.write_frame()
plotter.close()
trajectories_to_pyvista(particle_ids=None)

Convert particle trajectories to PyVista polylines.

Creates a PolyData object with particle trajectories as connected line segments, useful for visualizing particle paths over time.

Parameters:

particle_ids (list[int] | None) – List of particle indices to include. If None, includes all particles.

Returns:

pyvista.PolyData with trajectories as polylines. Each trajectory is a separate line, with time stored as point data.

Raises:

ImportError – If pyvista is not installed.

Example:

import pyvista as pv

results = SimulationResults("./output")

# Get all trajectories
trajectories = results.trajectories_to_pyvista()

# Or specific particles
trajectories = results.trajectories_to_pyvista(particle_ids=[0, 1, 2])

# Plot colored by time
trajectories.plot(scalars="time", cmap="viridis", line_width=2)
fluvial_particle.inspect_grid(settings_file, *, timestep=None, quiet=False)

Inspect grid data from a user options file.

Loads the grid(s) specified in the options file and returns a summary of dimensions, extents, available fields, and reach-averaged hydraulic statistics.

Parameters:
  • settings_file (str | Path) – Path to the user settings file (Python script).

  • timestep (int | None) – For time-dependent grids, which timestep index to inspect (0-indexed). Defaults to 0 (first timestep). Negative values supported (-1 = last).

  • quiet (bool) – If True, suppress printed summary. Default False.

Returns:

  • grid_2d: 2D grid info (file, dimensions, extents, scalars, vectors)

  • grid_3d: 3D grid info (only if Track3D=1)

  • hydraulics: Reach-averaged statistics (depth, velocity, shear_stress, ustar)

  • time_dependent: Boolean or timestep info dict

  • ustar_method: The method used to compute shear velocity

Return type:

Dictionary containing grid information with keys

Raises:

FileNotFoundError – If settings file or grid files don’t exist.

Example:

from fluvial_particle import inspect_grid

info = inspect_grid("settings.py")
print(f"Grid dimensions: {info['grid_2d']['dimensions']}")
print(f"Mean depth: {info['hydraulics']['depth']['mean']:.2f} m")
fluvial_particle.run_simulation(settings_file, output_dir, *, seed=None, postprocess=True, quiet=False)

Run a particle tracking simulation and return results.

This is a convenience function that wraps the standard simulation workflow into a single call, useful for notebooks and scripts.

Parameters:
  • settings_file (str | Path) – Path to the user settings file (Python script).

  • output_dir (str | Path) – Directory where output files will be written. Will be created if it doesn’t exist.

  • seed (int | None) – Random seed for reproducible simulations. If None, a seed is generated from current time and process ID.

  • postprocess (bool) – If True (default), run post-processing to generate XDMF files and cell counters.

  • quiet (bool) – If True, suppress simulation output. Default False.

Returns:

SimulationResults object for accessing the output.

Raises:

FileNotFoundError – If settings_file doesn’t exist.

Return type:

SimulationResults

Example:

from fluvial_particle.results import run_simulation

# Run simulation and get results
results = run_simulation("my_settings.py", "./output", seed=42)

# Access results
print(results.summary())
positions = results.get_positions(timestep=-1)
fluvial_particle.simulate(settings, argvars, timer, comm=None)

Run the fluvial particle simulation.

Parameters:
  • settings (dict subclass) – parameter settings for the simulation

  • argvars (dict) – dictionary holding command line argument variables

  • timer (time object) – does timing

  • comm (MPI intracomm object) – for parallel runs only, MPI communicator

Raises:
  • FileNotFoundError – The StartLoc file does not exist

  • ValueError – StartLoc must be tuple or HDF5 checkpoint file path

  • ValueError – Simulation start time must be less than end time

fluvial_particle.track_mpi()

Run fluvial particle in parallel.

fluvial_particle.track_serial()

Run fluvial particle in serial.

Simulation

Core simulation functionality for fluvial particle tracking.

fluvial_particle.simulation.simulate(settings, argvars, timer, comm=None)

Run the fluvial particle simulation.

Parameters:
  • settings (dict subclass) – parameter settings for the simulation

  • argvars (dict) – dictionary holding command line argument variables

  • timer (time object) – does timing

  • comm (MPI intracomm object) – for parallel runs only, MPI communicator

Raises:
  • FileNotFoundError – The StartLoc file does not exist

  • ValueError – StartLoc must be tuple or HDF5 checkpoint file path

  • ValueError – Simulation start time must be less than end time

Command Line Interface

Command-line interface entry points for fluvial particle tracking.

fluvial_particle.cli.track_mpi()

Run fluvial particle in parallel.

fluvial_particle.cli.track_serial()

Run fluvial particle in serial.