pyftle package¶
Submodules¶
pyftle.api module¶
- class pyftle.api.AnalyticalSolver[source]¶
Bases:
objectA notebook-friendly FTLE manager for in-memory analytical velocity fields.
This class provides a high-level interface to compute Finite-Time Lyapunov Exponents (FTLE) from an analytical velocity field. It generates time batches, integrates particle trajectories, and computes flow maps entirely in memory, with optional parallelization and output writing.
The solver is particularly suited for analytical or synthetic flow fields defined as Python functions rather than on a discrete spatial grid.
- Parameters:
velocity_fn (Callable[[np.ndarray, float], np.ndarray]) –
A user-defined function that returns the velocity field at a given time. The callable must have the signature:
velocity_fn(positions: ArrayNx2 | ArrayNx3, t: float) -> ArrayNx2 | ArrayNx3where
positionsare the spatial coordinates of the particles andtis the time.particles (NeighboringParticles) – Initial particle positions and neighbor information used for computing local flow map Jacobians.
timestep (float) – Time step size used for particle integration. Positive values correspond to forward-time integration, and negative values to backward-time.
flow_map_period (float) – Total duration over which each flow map is integrated (in the same units as timestep).
num_ftles (int) – Number of FTLE fields to compute. Each FTLE field corresponds to a distinct start time separated by timestep.
integrator_name (str) – Name of the time integrator to use. Must be one of the registered integrators available in
pyftle.integrate(e.g., “rk4”, “euler”).num_processes (int, default=1) – Number of parallel processes used for computing FTLE fields.
save_output (bool, default=False) – If True, the computed FTLE fields will be written to disk instead of being returned as NumPy arrays.
output_format (str, default="vtk") – File format used for writing the output (e.g., “vtk” or “npy”).
output_dir_name (Optional[str], default=None) – Output directory name. If not provided and save_output=True, a timestamped directory name (e.g., “run-2025-11-07-18h-42m-00s”) will be automatically created.
- velocity_fn¶
Analytical velocity function used for interpolation.
- Type:
Callable
- particles¶
Initial and neighboring particle configuration.
- Type:
NeighboringParticles
- num_snapshots¶
Number of snapshots per flow map integration (derived from flow_map_period / |timestep| + 1).
- Type:
- writer¶
Writer object for saving output (if enabled).
- Type:
Optional[BaseWriter]
- executor¶
Manager for executing FTLE computations in parallel.
- Type:
- integrator¶
Time integrator created via
create_integrator().- Type:
BaseIntegrator
- run()[source]¶
Execute all FTLE computations, either sequentially or in parallel.
This method orchestrates the full FTLE workflow: batch generation → particle integration → flow map computation → FTLE evaluation → optional output writing.
- Returns:
If save_output is False, returns an array of shape
(num_ftles, n_points)containing the computed FTLE fields.If save_output is True, returns None (fields are written to disk).
- Return type:
np.ndarray or None
- Raises:
RuntimeError – If no FTLE fields are returned due to worker failure.
pyftle.cauchy_green module¶
- pyftle.cauchy_green.compute_flow_map_jacobian_2x2(particles)[source]¶
Wrapper to compute the 2D flow map Jacobian (deformation gradient) from a NeighboringParticles instance.
- Parameters:
particles (NeighboringParticles) – Dataclass containing particle positions and their corresponding neighbor displacements (current and initial) in 2D.
- Returns:
jacobian – The 2D flow map Jacobian for each particle group.
- Return type:
ArrayNx2x2
- pyftle.cauchy_green.compute_flow_map_jacobian_3x3(particles)[source]¶
Wrapper to compute the 3D flow map Jacobian (deformation gradient) from a NeighboringParticles instance.
- Parameters:
particles (NeighboringParticles) – Dataclass containing particle positions and their corresponding neighbor displacements (current and initial) in 3D.
- Returns:
jacobian – The 3D flow map Jacobian for each particle group.
- Return type:
ArrayNx3x3
pyftle.core module¶
pyftle.data_source module¶
Batch data sources for FTLE computation.
This module defines the BatchSource protocol and concrete implementations (FileBatchSource and AnalyticalBatchSource) for providing particle and velocity field data during flow map integration.
Two main use cases are supported: 1. File-based data: reading velocity and coordinate snapshots from disk. 2. Analytical data: using a user-defined velocity function evaluated at runtime.
All sources expose a consistent interface defined by the BatchSource protocol, so they can be used interchangeably in higher-level FTLE computation routines.
- class pyftle.data_source.AnalyticalBatchSource[source]¶
Bases:
BatchSourceBatch source for analytical velocity fields.
This implementation allows using a user-defined velocity function instead of reading data from files. It provides access to precomputed particle positions and a sequence of time values.
- Parameters:
velocity_fn (Callable) – Analytical function that returns the velocity field given space and time. Expected signature: velocity_fn(x: Array2xN | Array3xN, t: float) -> Array2xN | Array3xN
particles (NeighboringParticles) – Particle data used for initialization.
timestep (float) – Time step between consecutive evaluations.
times (array-like of float) – Sequence of time values at which the velocity function is evaluated.
- get_particles()[source]¶
Return the particle data associated with this analytical source.
- Returns:
Dataclass containing particle positions and neighbor offsets.
- Return type:
NeighboringParticles
- update_interpolator(interpolator, step_index)[source]¶
No-op method: analytical velocity fields do not require data updates.
- Parameters:
interpolator (Interpolator) – The interpolator instance (unused).
step_index (int) – Index of the current step (unused).
- class pyftle.data_source.BatchSource[source]¶
Bases:
ProtocolProtocol defining the interface for batch data sources used in FTLE computation.
Any concrete implementation must provide methods and properties to: - Access the time-step information. - Retrieve initial particle positions. - Update the velocity interpolator for a given snapshot.
This abstraction allows using either numerical data (from files) or analytical functions for flow map integration.
- get_particles()[source]¶
Retrieve the set of neighboring particles used for flow map computation.
- Returns:
Dataclass containing particle positions and their initial displacements.
- Return type:
NeighboringParticles
- update_interpolator(interpolator, step_index)[source]¶
Update the velocity interpolator with the data for the given time step.
- Parameters:
interpolator (Interpolator) – The interpolator instance to update with velocity (and optionally coordinate) data.
step_index (int) – Index of the current time step (0-based).
- class pyftle.data_source.FileBatchSource[source]¶
Bases:
BatchSourceBatch source that loads velocity and coordinate data from files.
This implementation supports both static and time-varying coordinate grids. It reads the velocity and coordinate snapshots corresponding to each time step, as well as the seed particle positions for flow map initialization.
- Parameters:
snapshot_files (list of str) – List of file paths containing velocity field data for each time step.
coordinate_files (list of str) – List of file paths containing the spatial grid coordinates. Can be identical for all time steps if the grid is stationary.
particle_file (str) – Path to the file containing seed particle positions.
snapshot_timestep (float) – Time step between consecutive velocity snapshots.
flow_map_period (int or float) – Number of time steps or total time duration between flow map evaluations.
- get_data_for_step(step_index)[source]¶
Load velocity and coordinate data for a specific time step.
- Parameters:
step_index (int) – Index of the time step to read (0-based).
- Returns:
velocities (Array2xN or Array3xN) – Velocity field data at the current time step.
coordinates (Array2xN or Array3xN or None) – Coordinate grid corresponding to the current time step. Returns None if the grid is reused and unchanged.
- Return type:
Tuple[NDArray[Shape[2, *], float64] | NDArray[Shape[3, *], float64], NDArray[Shape[2, *], float64] | NDArray[Shape[3, *], float64] | None]
- get_particles()[source]¶
Load and return the seed particles used to initialize the flow map.
- Returns:
Dataclass containing particle positions and neighbor offsets.
- Return type:
NeighboringParticles
- update_interpolator(interpolator, step_index)[source]¶
Update the velocity interpolator with the data for the specified time step.
- Parameters:
interpolator (Interpolator) – Interpolator instance to update.
step_index (int) – Index of the time step to load.
pyftle.decorators module¶
- pyftle.decorators.date_diff_in_seconds(dt2, dt1)[source]¶
Compute the time difference between two datetime objects in seconds.
- Parameters:
dt2 (datetime) – The later datetime.
dt1 (datetime) – The earlier datetime.
- Returns:
The total time difference in seconds between dt2 and dt1.
- Return type:
Examples
>>> from datetime import datetime >>> t1 = datetime(2024, 1, 1, 12, 0, 0) >>> t2 = datetime(2024, 1, 1, 12, 30, 0) >>> date_diff_in_seconds(t2, t1) 1800
- pyftle.decorators.dhms_from_seconds(seconds)[source]¶
Convert a time duration in seconds into days, hours, minutes, and seconds.
- Parameters:
seconds (int) – Duration in seconds.
- Returns:
A tuple (days, hours, minutes, seconds) representing the same duration.
- Return type:
Examples
>>> dhms_from_seconds(90061) (1, 1, 1, 1)
- pyftle.decorators.time_it(func)[source]¶
Decorator that measures and prints the execution time of a function.
The execution time is displayed in days, hours, minutes, and seconds.
- Parameters:
func (Callable) – The function to be wrapped and timed.
- Returns:
The wrapped function that prints execution duration upon completion.
- Return type:
Callable
Examples
>>> @time_it ... def slow_function(): ... import time; time.sleep(2) ... >>> slow_function() Execution complete in 0 days, 0 hours, 0 minutes, 2 seconds
pyftle.file_readers module¶
File readers for velocity, coordinate, and seed particle data.
This module provides utilities for loading MATLAB .mat files containing velocity fields, spatial coordinates, and seed particle positions used in FTLE (Finite-Time Lyapunov Exponent) computations.
Supported data layouts¶
Each .mat file must contain specific variable names:
Velocity data: - 2D: velocity_x, velocity_y - 3D: velocity_x, velocity_y, velocity_z (optional)
Coordinate data: - 2D: coordinate_x, coordinate_y - 3D: coordinate_x, coordinate_y, coordinate_z (optional)
Seed particle data: - 2D: left, right, top, bottom - 3D: left, right, top, bottom, front, back
All arrays are automatically flattened and stacked in column-major order to produce consistent NumPy arrays compatible with pyftle’s internal types.
- pyftle.file_readers.read_coordinate(file_path)[source]¶
Read coordinate grid data from a MATLAB .mat file.
The file must contain at least the keys ‘coordinate_x’ and ‘coordinate_y’. If ‘coordinate_z’ is present, the coordinates are treated as 3D.
- Parameters:
file_path (str) – Path to the MATLAB file containing coordinate data.
- Returns:
coordinates – A 2xN or 3xN array where each row corresponds to one spatial component (x, y, and optionally z), and N is the number of grid points.
- Return type:
Array2xN or Array3xN
- Raises:
ValueError – If the required coordinate keys are missing from the file.
- pyftle.file_readers.read_seed_particles_coordinates(file_path)[source]¶
Read seed particle coordinates from a MATLAB .mat file and return a NeighboringParticles dataclass instance.
The MATLAB file must contain at least the 2D neighbor keys: ‘left’, ‘right’, ‘top’, ‘bottom’.
If ‘front’ and ‘back’ are also present, the dataset is interpreted as 3D.
- Parameters:
file_path (str) – Path to the MATLAB file containing seed particle data.
- Returns:
particles – Dataclass representing the grouped particle positions. The total shape is: - (4xN, 2) for 2D datasets (left, right, top, bottom) - (6xN, 3) for 3D datasets (left, right, top, bottom, front, back)
- Return type:
NeighboringParticles
- Raises:
ValueError – If the required neighbor keys are missing from the .mat file.
Notes
The returned NeighboringParticles object contains the concatenated coordinates of all neighboring particles used to compute flow map Jacobians and FTLE fields.
- pyftle.file_readers.read_velocity(file_path)[source]¶
Read velocity components from a MATLAB .mat file.
The file must contain at least the keys ‘velocity_x’ and ‘velocity_y’. If ‘velocity_z’ is also present, the velocity is treated as 3D.
- Parameters:
file_path (str) – Path to the MATLAB file containing the velocity data.
- Returns:
velocities – A 2xN or 3xN array where each row corresponds to one velocity component (x, y, and optionally z), and N is the number of spatial grid points.
- Return type:
Array2xN or Array3xN
- Raises:
ValueError – If the required keys (velocity_x, velocity_y) are not present in the .mat file.
pyftle.file_utils module¶
- pyftle.file_utils.find_files_with_pattern(root_dir, pattern)[source]¶
Recursively search for files matching a given substring pattern.
This function traverses the specified root directory and all of its subdirectories, returning all files whose names contain the given pattern.
- Parameters:
- Returns:
Sorted list of full file paths that contain the given pattern.
- Return type:
Examples
>>> find_files_with_pattern("/data", "velocity") ['/data/run1/velocity_001.csv', '/data/run2/velocity_002.csv']
- pyftle.file_utils.get_files_list(file_path)[source]¶
Read a text file containing a list of file paths.
This function expects a plain text file (e.g., generated by
write_list_to_txt()) where each line contains a file path. It returns the list of paths as strings.- Parameters:
file_path (str) – Path to the text file containing the list of file paths.
- Returns:
List of file paths read from the file.
- Return type:
- Raises:
FileNotFoundError – If the specified file does not exist.
Examples
>>> get_files_list("files.txt") ['a.txt', 'b.txt']
- pyftle.file_utils.write_list_to_txt(file_list, output_file)[source]¶
Write a list of file paths to a text file, one path per line.
- Parameters:
Notes
The output file is overwritten if it already exists.
Examples
>>> write_list_to_txt(["a.txt", "b.txt"], "files.txt") # Creates a file 'files.txt' with: # a.txt # b.txt
pyftle.file_writers module¶
- class pyftle.file_writers.FTLEWriter[source]¶
Bases:
ABCAbstract base class for writing Finite-Time Lyapunov Exponent (FTLE) fields to different file formats.
This class defines a unified interface for exporting computed FTLE data along with particle centroid coordinates, either as structured or unstructured datasets.
- Parameters:
directory_path (str or os.PathLike) – Directory where output files will be saved. The folder will be created automatically if it does not exist.
grid_shape (tuple of int, optional) – Shape of the underlying grid (e.g.,
(nx, ny)or(nx, ny, nz)). If omitted, the data are assumed to represent an unstructured point cloud.
- abstract write(filename, ftle_field, particles_centroid)[source]¶
Write the FTLE field to a file.
- Parameters:
filename (str) – File name (without extension) or full file path for the output.
ftle_field (ArrayN) – Array containing FTLE scalar values for all particle centroids.
particles_centroid (ArrayNx2 or ArrayNx3) – Coordinates of particle centroids in 2D or 3D space.
- class pyftle.file_writers.MatWriter[source]¶
Bases:
FTLEWriterWriter class to export FTLE fields to MATLAB
.matfiles.The writer supports both structured and unstructured datasets. Structured grids are reshaped according to the specified
grid_shapeand saved as multidimensional arrays. Unstructured data are saved as flattened arrays.- Parameters:
directory_path (str or os.PathLike) – Directory where the
.matfiles will be stored.grid_shape (tuple of int, optional) – Shape of the computational grid (
(nx, ny)or(nx, ny, nz)). If not provided, data are assumed to be unstructured.
- write(filename, ftle_field, particles_centroid)[source]¶
Save the FTLE field and particle centroid coordinates in a MATLAB
.matfile.- Parameters:
filename (str) – Base name (without extension) for the output file.
ftle_field (ArrayN) – Flattened FTLE values corresponding to each particle centroid.
particles_centroid (ArrayNx2 or ArrayNx3) – Array of centroid coordinates in 2D or 3D space.
- Raises:
ValueError – If
grid_shapeis provided but its length is not 2 or 3.
- class pyftle.file_writers.VTKWriter[source]¶
Bases:
FTLEWriterWriter class to export FTLE fields to VTK files for visualization with ParaView or other visualization tools.
Structured grids are written as
.vtsfiles (VTK StructuredGrid), whereas unstructured data are written as.vtpfiles (VTK PolyData).- Parameters:
directory_path (str or os.PathLike) – Directory where the VTK files will be saved.
grid_shape (tuple of int, optional) – Shape of the computational grid (
(nx, ny)or(nx, ny, nz)). If omitted, data are treated as an unstructured cloud of points.
- write(filename, ftle_field, particles_centroid)[source]¶
Save the FTLE field and particle centroid coordinates as a VTK file.
- Parameters:
filename (str) – Base name (without extension) for the output file.
ftle_field (ArrayN) – Flattened FTLE values corresponding to each particle centroid.
particles_centroid (ArrayNx2 or ArrayNx3) – Array of centroid coordinates in 2D or 3D space.
- Raises:
ValueError – If
grid_shapeis provided but its length is not 2 or 3.
- pyftle.file_writers.create_writer(output_format, directory_path, grid_shape=None)[source]¶
Factory function to create an FTLE writer for the desired output format.
- Parameters:
output_format (str) – Output format for the FTLE data. Must be either
"mat"or"vtk".directory_path (str) – Directory path where the output files will be stored.
grid_shape (tuple of int, optional) – Shape of the structured grid (
(nx, ny)or(nx, ny, nz)). If omitted, the writer assumes an unstructured dataset.
- Returns:
- Return type:
- Raises:
ValueError – If
output_formatis not recognized.
pyftle.ftle module¶
- pyftle.ftle.compute_cauchy_green_2x2(flow_map_jacobian)[source]¶
Compute the 2D right Cauchy-Green deformation tensor for each flow map Jacobian.
The right Cauchy-Green tensor is defined as:
\[\mathbf{C} = \mathbf{F}^\mathsf{T} \mathbf{F},\]where \(\mathbf{F}\) is the deformation gradient (flow map Jacobian).
This Numba-optimized implementation explicitly expands the matrix product for performance in 2D.
- Parameters:
flow_map_jacobian (ArrayNx2x2) – Deformation gradient tensors (Jacobian matrices) for all particle groups. Shape
(N, 2, 2).- Returns:
cauchy_green_tensor – The right Cauchy-Green deformation tensors. Shape
(N, 2, 2).- Return type:
ArrayNx2x2
Notes
For each tensor \(\mathbf{F}\), defined as
\[\begin{split}\mathbf{F} = \begin{bmatrix} F_{11} & F_{12} \\ F_{21} & F_{22} \end{bmatrix},\end{split}\]the resulting \(\mathbf{C}\) is:
\[\begin{split}\mathbf{C} = \begin{bmatrix} F_{11}^2 + F_{21}^2 & F_{11} F_{12} + F_{21} F_{22} \\ F_{12} F_{11} + F_{22} F_{21} & F_{12}^2 + F_{22}^2 \end{bmatrix}.\end{split}\]
- pyftle.ftle.compute_cauchy_green_3x3(flow_map_jacobian)[source]¶
Compute the 3D right Cauchy-Green deformation tensor for each flow map Jacobian.
The tensor is given by:
\[\mathbf{C} = \mathbf{F}^\mathsf{T} \mathbf{F},\]where \(\mathbf{F}\) is the deformation gradient.
- Parameters:
flow_map_jacobian (ArrayNx3x3) – Deformation gradient tensors (Jacobian matrices) for all particle groups. Shape
(N, 3, 3).- Returns:
cauchy_green_tensor – The right Cauchy-Green deformation tensors. Shape
(N, 3, 3).- Return type:
ArrayNx3x3
- pyftle.ftle.compute_ftle_2x2(flow_map_jacobian, map_period)[source]¶
Compute the Finite-Time Lyapunov Exponent (FTLE) field in 2D.
The FTLE quantifies the rate of separation between neighboring trajectories over a finite time interval and is given by:
\[\sigma = \frac{1}{|T|} \ln \sqrt{\lambda_{\max}(\mathbf{C})},\]where \(\lambda_{\max}\) is the maximum eigenvalue of the right Cauchy-Green tensor \(\mathbf{C} = \mathbf{F}^\mathsf{T} \mathbf{F}\).
- Parameters:
flow_map_jacobian (ArrayNx2x2) – Deformation gradient (flow map Jacobian) for each particle group. Shape
(N, 2, 2).map_period (float) – Finite integration time \(T\) (positive for forward time, negative for backward time).
- Returns:
ftle – Finite-Time Lyapunov Exponent for each particle. Shape
(N,).- Return type:
ArrayN
- pyftle.ftle.compute_ftle_3x3(flow_map_jacobian, map_period)[source]¶
Compute the Finite-Time Lyapunov Exponent (FTLE) field in 3D.
The FTLE quantifies the rate of exponential separation of trajectories over a finite time interval, based on the largest eigenvalue of the Cauchy-Green deformation tensor.
\[\sigma = \frac{1}{|T|} \ln \sqrt{\lambda_{\max}(\mathbf{C})},\]where \(\mathbf{C} = \mathbf{F}^\mathsf{T} \mathbf{F}\).
- Parameters:
flow_map_jacobian (ArrayNx3x3) – Deformation gradient (flow map Jacobian) for each particle group. Shape
(N, 3, 3).map_period (float) – Finite integration time \(T\) (positive for forward time, negative for backward time).
- Returns:
ftle – Finite-Time Lyapunov Exponent for each particle. Shape
(N,).- Return type:
ArrayN
- pyftle.ftle.max_eigenvalue_2x2(cauchy_green_tensor)[source]¶
Compute the maximum eigenvalue of each 2D right Cauchy-Green deformation tensor.
- Parameters:
cauchy_green_tensor (ArrayNx2x2) – Right Cauchy-Green deformation tensors. Shape
(N, 2, 2).- Returns:
max_eigvals – Maximum eigenvalue of each tensor. Shape
(N,).- Return type:
ArrayN
Notes
The eigenvalues are computed analytically from the characteristic equation:
\[\lambda = \frac{\operatorname{tr}(\mathbf{C}) \pm \sqrt{\operatorname{tr}(\mathbf{C})^2 - 4 \det(\mathbf{C})}}{2}.\]
- pyftle.ftle.max_eigenvalue_3x3(cauchy_green_tensor)[source]¶
Compute the maximum eigenvalue of the 3D right Cauchy-Green deformation tensor.
- Parameters:
cauchy_green_tensor (ArrayNx3x3) – Right Cauchy-Green deformation tensors. Shape
(N, 3, 3).- Returns:
max_eigvals – Maximum eigenvalue of each tensor. Shape
(N,).- Return type:
ArrayN
Notes
The eigenvalues correspond to the squared principal stretch ratios.
pyftle.ftle_solver module¶
- class pyftle.ftle_solver.FTLESolver[source]¶
Bases:
objectCompute the Finite-Time Lyapunov Exponent (FTLE) field from a sequence of velocity data files.
The solver integrates particle trajectories over a given flow map period, computes the flow map Jacobian, and evaluates the FTLE field either in 2D or 3D. Data are processed sequentially from a
BatchSource, using anIntegratorfor time integration, and optionally writing results through aFTLEWriter.- Parameters:
source (BatchSource) – Source of velocity field data and particle initialization. Must provide velocity data, interpolation updates, and particle positions for each time step.
integrator (Integrator) – Object responsible for advancing particle positions in time using the current velocity interpolator.
progress_queue (Optional[Queue], default=None) – Optional multiprocessing queue for publishing progress updates during FTLE computation. Each iteration sends a tuple
(id, i)and a final(id, "done")message when completed.output_writer (Optional[FTLEWriter], default=None) – Writer used to save the computed FTLE field to disk. If not provided, the computed field is returned instead of written.
Notes
The FTLESolver assumes that the sequence of velocity field files in source is ordered correctly for either forward or backward FTLE mapping. It is the user’s responsibility to ensure temporal consistency in the input data.
Examples
>>> solver = FTLESolver(source, integrator, output_writer=writer) >>> solver.run() # Computes and writes FTLE field
- run()[source]¶
Run the FTLE computation for the current flow map period.
This method performs the full FTLE workflow: 1. Loads particle positions from the data source. 2. Sequentially integrates all time steps in the dataset. 3. Publishes progress updates to the queue (if provided). 4. Computes the FTLE field using the final particle configuration. 5. Writes or returns the FTLE field.
- Returns:
The computed FTLE field if output_writer is not provided; otherwise, returns
Noneafter writing the results to disk.- Return type:
Optional[ArrayN]
Notes
The time integration is performed in-place using the provided
Integrator, which updates particle positions overnum_stepsiterations. After all steps, the flow map Jacobian is evaluated to compute the FTLE.
pyftle.ginterp module¶
pyftle.hyperparameters module¶
- pyftle.hyperparameters.parse_args()[source]¶
Parse command-line arguments and return a MyProgramArgs dataclass instance. This function should be called explicitly by the main entry point, so that importing this module does not trigger parsing automatically.
- pyftle.hyperparameters.parse_tuple(value)[source]¶
Convert a comma-separated string into a tuple of positive integers.
This function is used to parse command-line arguments representing grid shapes (e.g., –grid_shape 10,20,30). It validates that the input contains either two or three positive integers. If the last integer equals 1, it is automatically removed to handle degenerate dimensions.
- Parameters:
value (str) – A string of comma-separated integers, such as “10,20,30” or “32,32”.
- Returns:
A tuple of two or three positive integers. If the last element is 1, it is omitted.
- Return type:
- Raises:
ValueError – If the input does not contain exactly 2 or 3 integers, or if any integer is non-positive.
Examples
>>> parse_tuple("10,20,30") (10, 20, 30)
>>> parse_tuple("10,20,1") (10, 20)
pyftle.integrate module¶
- class pyftle.integrate.AdamsBashforth2Integrator[source]¶
Bases:
IntegratorSecond-order explicit Adams-Bashforth (AB2) integrator.
Uses a linear combination of the current and previous velocities to achieve second-order accuracy:
\[x_{n+1} = x_n + h \left( \frac{3}{2} v_n - \frac{1}{2} v_{n-1} \right)\]On the first iteration (when no previous velocity is available), it defaults to a single Euler step.
- integrate(h, particles)[source]¶
Perform a single AB2 integration step in-place.
- Parameters:
h (float) – Time step size.
particles (NeighboringParticles) – Particle data with current positions to be updated.
Notes
Uses Euler integration for the first step, when no previous velocity field is available.
- class pyftle.integrate.EulerIntegrator[source]¶
Bases:
IntegratorFirst-order explicit Euler integrator.
The Euler method approximates the solution of an ODE by advancing the state using the current derivative (velocity):
\[x_{n+1} = x_n + h \, v_n\]
- class pyftle.integrate.Integrator[source]¶
Bases:
ABCAbstract base class for numerical ODE integrators.
All specific integrator implementations (Euler, AB2, RK4) must derive from this class and implement the
integrate()method.- Parameters:
interpolator (Interpolator) – Interpolator used to evaluate velocity from particle positions.
**kwargs – Optional extra arguments specific to the integrator implementation.
- abstract integrate(h, particles)[source]¶
Perform a single integration step.
- Parameters:
h (float) – Time step size.
particles (NeighboringParticles) – Dataclass containing particle positions and neighboring data.
Notes
This method must mutate
particles.positionsin-place. Implementations should use Numba-accelerated kernels for efficiency.
- class pyftle.integrate.RungeKutta4Integrator[source]¶
Bases:
IntegratorFourth-order explicit Runge-Kutta (RK4) integrator.
Uses four slope evaluations per step to achieve fourth-order accuracy:
\[x_{n+1} = x_n + \frac{h}{6} (k_1 + 2k_2 + 2k_3 + k_4)\]- where:
k₁ = f(t, x) k₂ = f(t + h/2, x + h k₁/2) k₃ = f(t + h/2, x + h k₂/2) k₄ = f(t + h, x + h k₃)
- integrate(h, particles)[source]¶
Perform a single RK4 integration step in-place.
- Parameters:
h (float) – Time step size.
particles (NeighboringParticles) – Particle data with current positions to be updated.
Notes
This method allocates intermediate buffers lazily and reuses them between calls to minimize memory allocations.
- pyftle.integrate.adams_bashforth_2_step_inplace(positions, h, v_current, v_prev)[source]¶
Perform an in-place second-order Adams–Bashforth (AB2) integration step.
Updates particle positions according to:
\[x_{n+1} = x_n + h \left( \tfrac{3}{2} v_n - \tfrac{1}{2} v_{n-1} \right)\]- Parameters:
positions (ArrayNx2 or ArrayNx3) – Particle positions at the current time. Updated in-place.
h (float) – Time step size.
v_current (Array2xN or Array3xN) – Velocity field evaluated at the current positions.
v_prev (Array2xN or Array3xN) – Velocity field evaluated at the previous positions.
- pyftle.integrate.create_integrator(integrator_name, interpolator)[source]¶
Factory function to instantiate a numerical integrator.
- Parameters:
integrator_name (str) – Name of the integrator to create. Supported values:
"euler","ab2","rk4".interpolator (Interpolator) – Interpolator used to compute velocity from particle positions.
- Returns:
An instance of the requested integrator type.
- Return type:
- Raises:
ValueError – If the provided
integrator_nameis not recognized.
- pyftle.integrate.euler_step_inplace(positions, h, velocity)[source]¶
Perform an in-place Euler integration step.
Updates particle positions according to:
\[x_{n+1} = x_n + h \, v_n\]- Parameters:
positions (ArrayNx2 | ArrayNx3) – Particle positions at the current time. Updated in-place.
h (float) – Time step size.
velocity (Array2xN | Array3xN) – Velocity field evaluated at the current positions.
Notes
This is a low-level kernel designed for performance with Numba. It does not allocate memory or perform error checking.
- pyftle.integrate.runge_kutta_4_step_inplace(positions, h, k1, k2, k3, k4)[source]¶
Perform an in-place fourth-order Runge-Kutta (RK4) integration step.
Updates particle positions according to:
\[x_{n+1} = x_n + \frac{h}{6}(k_1 + 2k_2 + 2k_3 + k_4)\]- Parameters:
positions (ArrayNx2 | ArrayNx3) – Particle positions at the current time. Updated in-place.
h (float) – Time step size.
k1 (ArrayNx2 | ArrayNx3) – Intermediate slope (velocity) evaluations for RK4.
k2 (ArrayNx2 | ArrayNx3) – Intermediate slope (velocity) evaluations for RK4.
k3 (ArrayNx2 | ArrayNx3) – Intermediate slope (velocity) evaluations for RK4.
k4 (ArrayNx2 | ArrayNx3) – Intermediate slope (velocity) evaluations for RK4.
pyftle.interpolate module¶
- class pyftle.interpolate.AnalyticalInterpolator[source]¶
Bases:
InterpolatorInterpolator that evaluates an analytical velocity field function.
Useful for synthetic or theoretical flow fields where velocity values are defined by an analytical expression rather than discrete data.
- Parameters:
velocity_fn (Callable) – A function of the form velocity_fn(t: float, points: np.ndarray) -> np.ndarray returning velocity vectors for given time t and coordinates.
- velocity_fn¶
User-defined analytical velocity function.
- Type:
Callable
- interpolate(new_points)[source]¶
Evaluate the analytical velocity field at the given points.
- Parameters:
new_points (Array2xN or Array3xN) – Cartesian coordinates where the velocity is to be evaluated.
- Returns:
velocities – Velocity vectors computed from the analytical function.
- Return type:
Array2xN or Array3xN
- Raises:
ExecutableNotFoundError – If velocity_fn has not been properly initialized.
- update(velocities, points=None)[source]¶
Do nothing (analytical interpolators have no internal state).
- Parameters:
velocities (Array2xN or Array3xN) – Ignored. Present to satisfy the interpolator interface.
points (Array2xN or Array3xN, optional) – Ignored. Present to satisfy the interpolator interface.
- class pyftle.interpolate.CubicInterpolator[source]¶
Bases:
InterpolatorClough-Tocher piecewise cubic interpolator for 2D velocity fields.
Provides C¹-smooth, curvature-minimizing interpolation using Delaunay triangulation of the input points.
Pros¶
Produces smooth, high-quality interpolation.
Suitable for smoothly varying velocity fields.
Cons¶
Computationally expensive (requires triangulation).
Limited to 2D domains.
- class pyftle.interpolate.GridInterpolator[source]¶
Bases:
InterpolatorGrid-based interpolator using SciPy’s RegularGridInterpolator.
This interpolator is designed for structured (rectangular) grids and supports linear, nearest, cubic, and higher-order methods. It is slower than HighPerfInterpolator but more flexible for prototyping or when C++ bindings are not available.
Pros¶
Fast for structured, regular data.
Lower memory usage compared to unstructured methods.
Cons¶
Requires structured grid coordinates.
Not suited for scattered data.
- param grid_shape:
Number of grid points along each spatial dimension.
- type grid_shape:
tuple[int, …]
- param method:
Interpolation scheme to use. Default is ‘linear’.
- type method:
{‘linear’, ‘nearest’, ‘slinear’, ‘cubic’, ‘quintic’}, optional
- interpolator_x, interpolator_y, interpolator_z
Interpolator objects for each velocity component.
- Type:
RegularGridInterpolator, optional
- VALID_METHODS = {'cubic', 'linear', 'nearest', 'quintic', 'slinear'}¶
- interpolate(new_points)[source]¶
Interpolate the velocity field at given Cartesian coordinates.
- Parameters:
new_points (Array2xN or Array3xN) – Target coordinates for interpolation.
- Returns:
velocities – Interpolated velocity components at new_points.
- Return type:
Array2xN or Array3xN
- Raises:
ValueError – If the interpolator has not been initialized.
- update(velocities, points=None)[source]¶
Update the internal velocity field or reinitialize the interpolator.
- Parameters:
velocities (Array2xN or Array3xN) – Updated velocity components in flattened order.
points (Array2xN or Array3xN, optional) – Optional grid coordinates. If provided, reinitializes the interpolator; otherwise, only updates the values.
Notes
Efficiently updates preinitialized interpolators by replacing .values.
Calls super().update() if reinitialization is required.
- class pyftle.interpolate.HighPerfInterpolator[source]¶
Bases:
InterpolatorHigh-performance grid-based interpolator using C++/Eigen backends.
Supports both 2D (bilinear) and 3D (trilinear) interpolation on structured, rectangular grids. This class dispatches automatically to Interp2D or Interp3D implementations depending on the dimensionality of grid_shape.
It is optimized for speed and suitable for large-scale flow field interpolation, such as FTLE or particle advection computations.
- Parameters:
grid_shape (tuple[int, ...]) – The number of grid points along each spatial axis, e.g. (nx, ny) for 2D or (nx, ny, nz) for 3D grids.
- interpolator_x, interpolator_y, interpolator_z
C++-based interpolator instances for each velocity component.
- Type:
Interp2D or Interp3D, optional
- velocities¶
Flattened velocity components used to initialize the interpolators.
- Type:
np.ndarray or None
- points¶
Flattened coordinate array corresponding to the velocity data.
- Type:
np.ndarray or None
- interpolate(new_points, out=None)[source]¶
Interpolate the velocity field at arbitrary Cartesian coordinates.
- Parameters:
new_points (Array2xN or Array3xN) – Coordinates where the velocity field should be interpolated.
out (np.ndarray, optional) – Optional preallocated output array for efficiency.
- Returns:
out – Interpolated velocity vectors at the requested points.
- Return type:
Array2xN or Array3xN
- Raises:
ValueError – If the dimensionality of new_points is not supported.
AssertionError – If the internal interpolators were not properly initialized.
Notes
Uses preallocated NumPy buffers for minimal memory overhead.
Supports both 2D and 3D velocity fields.
- update(velocities, points=None)[source]¶
Update the interpolator with new velocity and coordinate data.
- Parameters:
velocities (Array2xN or Array3xN) – Velocity components at each grid or sample point.
points (Array2xN or Array3xN, optional) – Spatial coordinates corresponding to each velocity sample. If omitted, previously stored points are reused.
- class pyftle.interpolate.Interpolator[source]¶
Bases:
ABCAbstract base class for velocity field interpolation strategies.
This class defines a common interface for interpolators used to estimate velocities at arbitrary spatial points, either from discrete samples or analytical expressions.
Subclasses must implement the
interpolate()method and may override the_initialize_interpolator()method to define their specific behavior.- __init__()[source]¶
Initialize an uninitialized interpolator instance.
This class uses lazy initialization: the actual interpolation object is created only when
update()is called with velocity and coordinate data.
- abstract interpolate(new_points)[source]¶
Interpolate the velocity field at given spatial coordinates.
- Parameters:
new_points (Array2xN or Array3xN) – Coordinates where the velocity should be interpolated.
- Returns:
Interpolated velocity components at the queried points.
- Return type:
Array2xN or Array3xN
- update(velocities, points=None)[source]¶
Update the interpolator with new velocity and coordinate data.
- Parameters:
velocities (Array2xN or Array3xN) – Velocity components at each grid or sample point.
points (Array2xN or Array3xN, optional) – Spatial coordinates corresponding to each velocity sample. If omitted, previously stored points are reused.
- class pyftle.interpolate.LinearInterpolator[source]¶
Bases:
InterpolatorPiecewise linear interpolator for 2D or 3D velocity fields.
Uses Delaunay triangulation for unstructured grids. Faster than Clough-Tocher but less smooth.
Pros¶
Computationally efficient.
Handles scattered (unstructured) points.
Cons¶
Discontinuous derivatives.
Less accurate for smooth fields.
- class pyftle.interpolate.NearestNeighborInterpolator[source]¶
Bases:
InterpolatorNearest-neighbor interpolation for discrete velocity data.
Assigns each query point the velocity of its nearest known sample.
Pros¶
Extremely fast.
No triangulation or precomputation required.
Cons¶
Produces blocky, discontinuous velocity fields.
Not suitable for smooth physical flows.
- pyftle.interpolate.create_interpolator(interpolation_type, grid_shape=None, velocity_fn=None)[source]¶
Factory function to construct an interpolator instance.
- Parameters:
interpolation_type (str) – Type of interpolation to perform. Supported options: - “cubic”: Clough-Tocher cubic interpolation (smooth but slower). - “linear”: Linear interpolation (fast, moderately smooth). - “nearest”: Nearest-neighbor interpolation (very fast, discontinuous). - “grid”: Grid-based C++/Eigen interpolation (HighPerfInterpolator). - “analytical”: Analytical function-based interpolation.
grid_shape (tuple[int, ...], optional) – Shape of the structured grid, required for “grid” or “linear” types.
velocity_fn (Callable, optional) – Analytical velocity function, required for “analytical” type.
- Returns:
interpolator – An initialized interpolator matching the requested configuration.
- Return type:
- Raises:
ValueError – If an unsupported interpolation type is requested.
ExecutableNotFoundError – If velocity_fn is not provided for analytical interpolation.
Examples
>>> interp = create_interpolator("grid", grid_shape=(64, 64)) >>> interp.update(velocities, points) >>> v_interp = interp.interpolate(new_points)
pyftle.my_types module¶
Type aliases for NumPy arrays used throughout the pyftle package.
These aliases are defined using nptyping to make array shapes and
element types explicit in function signatures. They serve as lightweight,
readable type hints for scientific arrays representing physical fields,
particle positions, and tensors.
All arrays use numpy.float64 as the element type.
Examples
>>> from pyftle.my_types import ArrayNx2
>>> import numpy as np
>>> a: ArrayNx2 = np.zeros((100, 2), dtype=np.float64)
Notes
These aliases are not runtime checks; they are primarily for static type
checking (e.g., with pyright, mypy, or IDEs with type support).
Shapes follow the convention:
N: number of particles, points, or samples.Dimensions such as
2,3,2x2, and3x3indicate spatial or tensor components.
Aliases¶
ArrayN(N,) array of float641D array of scalar values.
Array2xN(2, N) array of float642D array representing two components across N samples.
Array3xN(3, N) array of float643D array representing three components across N samples.
Array4Nx2(N, 2) array of float642D array for four groups of 2D particle positions (e.g., right, left, top, bottom).
Array6Nx3(N, 3) array of float643D array for six groups of 3D particle positions (e.g., right, left, top, bottom, front, back).
ArrayNx2(N, 2) array of float642D array with N vectors in 2D space.
ArrayNx3(N, 3) array of float642D array with N vectors in 3D space.
ArrayNx2x2(N, 2, 2) array of float64Stack of N 2×2 tensors (e.g., Jacobians in 2D).
ArrayNx3x3(N, 3, 3) array of float64Stack of N 3×3 tensors (e.g., Jacobians in 3D).
pyftle.parallel module¶
Infrastructure Layer
This module provides utilities for parallel task execution, real-time progress monitoring, and robust error handling in multiprocessing contexts. It is designed for scientific computations (e.g., FTLE batch processing) where multiple independent tasks need to be executed concurrently with visual feedback through progress bars.
Features¶
Seamless integration with both terminal and Jupyter environments via tqdm.
Graceful handling of errors during multiprocessing (with traceback display).
Live monitoring of per-task and global progress using multiple progress bars.
Clean shutdown and interruption handling across processes.
Classes¶
- ParallelExecutor
Handles parallel task execution, progress tracking, and error reporting.
Functions¶
- get_tqdm()
Detects environment and returns the appropriate tqdm class (terminal or notebook).
- class pyftle.parallel.ParallelExecutor[source]¶
Bases:
objectManage multiprocessing execution with live progress monitoring.
The ParallelExecutor is responsible for executing multiple independent tasks in parallel using concurrent.futures.ProcessPoolExecutor, while providing live progress visualization and robust error handling.
- Parameters:
n_processes (int, optional) – Number of parallel worker processes to launch (default is 4).
- progress_queue¶
Shared queue used to communicate task progress between worker processes and the monitor process.
- Type:
- _stop_event¶
Event flag used to signal the monitor process to terminate.
- Type:
- run(tasks, worker_fn)[source]¶
Execute multiple tasks in parallel and collect results.
Each task is executed in a separate process via the provided worker_fn. Progress updates are collected asynchronously and displayed via tqdm bars.
- Parameters:
tasks (list of BatchSource) – List of task objects to process. Each BatchSource must contain attributes such as id and num_steps, representing the task’s identity and number of progress steps, respectively.
worker_fn (callable) –
Function with signature worker_fn(task, queue) that performs the actual work for each task.
The function must:
Report progress by placing (task.id, step) or (task.id, “done”) messages into the shared queue.
Return a result (e.g., NumPy array) or raise an exception on failure.
- Returns:
results – List of task results in the same order as the input tasks.
- Return type:
list of np.ndarray or None
- Raises:
RuntimeError – If one or more tasks fail during execution. Errors are printed with traceback details, and all remaining tasks are immediately canceled.
Notes
Progress is displayed live for all tasks.
If an error occurs in any task, all ongoing computations are stopped.
The method ensures that monitor processes and worker pools terminate cleanly even in error conditions.
- pyftle.parallel.get_tqdm()[source]¶
Return a tqdm-compatible progress bar for the current environment.
This function automatically detects whether the code is running inside a Jupyter/IPython environment or a standard terminal, and imports the appropriate tqdm variant accordingly.
- Returns:
tqdm_class – The appropriate tqdm class: - tqdm.notebook.tqdm if running in Jupyter/IPython. - tqdm.tqdm for standard terminal environments.
- Return type:
Notes
This ensures consistent progress bar rendering across environments.
pyftle.particles module¶
- pyftle.particles.compute_centroid(positions, num_neighbors)[source]¶
Compute the centroid (mean position) of each neighbor group.
- Parameters:
positions (Array4Nx2 | Array6Nx3) – Particle positions grouped in sets of num_neighbors.
num_neighbors (int) – Number of neighbors per group (4 in 2D, 6 in 3D).
- Returns:
Centroid coordinates, \(\bar{\mathbf{x}} = \frac{1}{n}\sum_i \mathbf{x}_i\).
- Return type:
ArrayNx2 | ArrayNx3
- pyftle.particles.compute_delta_front_back(positions, num_neighbors)[source]¶
Compute the vector difference between front and back neighbors (3D only).
- Parameters:
positions (Array6Nx3) – Particle positions grouped in sets of 6 neighbors.
num_neighbors (int) – Number of neighbors (must be 6 in 3D).
- Returns:
The vector difference \(\Delta \mathbf{x}_{FB} = \mathbf{x}_F - \mathbf{x}_B\). Returns an empty array in 2D cases.
- Return type:
ArrayNx3
- pyftle.particles.compute_delta_right_left(positions, num_neighbors)[source]¶
Compute the vector difference between right and left neighbors.
- Parameters:
positions (Array4Nx2 | Array6Nx3) – Particle positions grouped in sets of num_neighbors.
num_neighbors (int) – Number of neighbors per group (4 in 2D, 6 in 3D).
- Returns:
The vector difference \(\Delta \mathbf{x}_{RL} = \mathbf{x}_R - \mathbf{x}_L\).
- Return type:
ArrayNx2 | ArrayNx3
- pyftle.particles.compute_delta_top_bottom(positions, num_neighbors)[source]¶
Compute the vector difference between top and bottom neighbors.
- Parameters:
positions (Array4Nx2 | Array6Nx3) – Particle positions grouped in sets of num_neighbors.
num_neighbors (int) – Number of neighbors per group (4 in 2D, 6 in 3D).
- Returns:
The vector difference \(\Delta \mathbf{x}_{TB} = \mathbf{x}_T - \mathbf{x}_B\).
- Return type:
ArrayNx2 | ArrayNx3
Module contents¶
- class pyftle.AnalyticalSolver[source]¶
Bases:
objectA notebook-friendly FTLE manager for in-memory analytical velocity fields.
This class provides a high-level interface to compute Finite-Time Lyapunov Exponents (FTLE) from an analytical velocity field. It generates time batches, integrates particle trajectories, and computes flow maps entirely in memory, with optional parallelization and output writing.
The solver is particularly suited for analytical or synthetic flow fields defined as Python functions rather than on a discrete spatial grid.
- Parameters:
velocity_fn (Callable[[np.ndarray, float], np.ndarray]) –
A user-defined function that returns the velocity field at a given time. The callable must have the signature:
velocity_fn(positions: ArrayNx2 | ArrayNx3, t: float) -> ArrayNx2 | ArrayNx3where
positionsare the spatial coordinates of the particles andtis the time.particles (NeighboringParticles) – Initial particle positions and neighbor information used for computing local flow map Jacobians.
timestep (float) – Time step size used for particle integration. Positive values correspond to forward-time integration, and negative values to backward-time.
flow_map_period (float) – Total duration over which each flow map is integrated (in the same units as timestep).
num_ftles (int) – Number of FTLE fields to compute. Each FTLE field corresponds to a distinct start time separated by timestep.
integrator_name (str) – Name of the time integrator to use. Must be one of the registered integrators available in
pyftle.integrate(e.g., “rk4”, “euler”).num_processes (int, default=1) – Number of parallel processes used for computing FTLE fields.
save_output (bool, default=False) – If True, the computed FTLE fields will be written to disk instead of being returned as NumPy arrays.
output_format (str, default="vtk") – File format used for writing the output (e.g., “vtk” or “npy”).
output_dir_name (Optional[str], default=None) – Output directory name. If not provided and save_output=True, a timestamped directory name (e.g., “run-2025-11-07-18h-42m-00s”) will be automatically created.
- velocity_fn¶
Analytical velocity function used for interpolation.
- Type:
Callable
- particles¶
Initial and neighboring particle configuration.
- Type:
NeighboringParticles
- num_snapshots¶
Number of snapshots per flow map integration (derived from flow_map_period / |timestep| + 1).
- Type:
- writer¶
Writer object for saving output (if enabled).
- Type:
Optional[BaseWriter]
- executor¶
Manager for executing FTLE computations in parallel.
- Type:
- integrator¶
Time integrator created via
create_integrator().- Type:
BaseIntegrator
- run()[source]¶
Execute all FTLE computations, either sequentially or in parallel.
This method orchestrates the full FTLE workflow: batch generation → particle integration → flow map computation → FTLE evaluation → optional output writing.
- Returns:
If save_output is False, returns an array of shape
(num_ftles, n_points)containing the computed FTLE fields.If save_output is True, returns None (fields are written to disk).
- Return type:
np.ndarray or None
- Raises:
RuntimeError – If no FTLE fields are returned due to worker failure.