Skip to content

carto_flow.flow_cartogram.velocity

Velocity field computation utilities for flow-based cartography.

This module provides functions and classes for computing velocity fields from density distributions using FFT-based methods with anisotropic diffusion. These velocity fields drive the deformation process in flow-based cartogram algorithms.

Functions:

Classes:

Examples:

>>> from carto_flow.flow_cartogram.velocity import VelocityComputerFFTW
>>> from carto_flow.flow_cartogram.grid import Grid
>>> grid = Grid.from_bounds((0, 0, 100, 80), size=100)
>>> computer = VelocityComputerFFTW(grid, Dx=1.0, Dy=1.0)
>>> vx, vy = computer.compute(density)

VelocityComputerFFTW

VelocityComputerFFTW(
    grid: Grid,
    Dx: float = 1.0,
    Dy: float = 1.0,
    threads: int | None = None,
)

Pre-allocate all arrays and FFTW plans for maximum performance. Use this when calling the function many times with same grid size.

Example: computer = VelocityComputerFFTW(grid, Dx=1.0, Dy=1.0) for i in range(n_steps): vx, vy = computer.compute(rho)

Parameters:

  • grid (Grid) –

    Grid information containing spatial discretization details

  • Dx (float, default: 1.0 ) –

    Flow amplification factors along x and y axes. Higher values produce stronger flow in the corresponding direction.

  • Dy (float, default: 1.0 ) –

    Flow amplification factors along x and y axes. Higher values produce stronger flow in the corresponding direction.

  • threads ((int, None), default: None ) –

    Number of threads for FFT computation

Methods:

  • compute

    Compute velocity field from density.

compute

compute(rho: ndarray) -> tuple[np.ndarray, np.ndarray]

Compute velocity field from density.

Parameters:

  • rho (2D array) –

    Density field

Returns:

  • vx, vy : 2D arrays

    Velocity components (views of internal buffers)

compute_velocity_anisotropic

compute_velocity_anisotropic(
    rho: ndarray,
    grid: Grid,
    Dx: float = 1.0,
    Dy: float = 1.0,
) -> tuple[np.ndarray, np.ndarray]

Compute anisotropic velocity field from density field using FFT-based method.

This function implements a fast Fourier transform (FFT) based approach to compute the velocity field for flow-based cartography. The method solves a Poisson-like equation using spectral methods with anisotropic diffusion coefficients.

The algorithm: 1. Computes FFT of normalized density field 2. Applies anisotropic diffusion operator in frequency domain 3. Computes velocity components using inverse FFT of frequency derivatives

Parameters:

  • rho (ndarray) –

    2D density field array with shape (ny, nx). Should represent population or mass density distribution.

  • grid (Grid) –

    Grid information containing spatial discretization details. Must provide dx and dy attributes for frequency computation.

  • Dx (float, default: 1.0 ) –

    Flow amplification factor in x-direction. Higher values produce stronger horizontal flow; lower values suppress it.

  • Dy (float, default: 1.0 ) –

    Flow amplification factor in y-direction. Higher values produce stronger vertical flow; lower values suppress it.

Returns:

  • vx ( ndarray ) –

    X-component of velocity field with same shape as rho. Represents horizontal flow velocities.

  • vy ( ndarray ) –

    Y-component of velocity field with same shape as rho. Represents vertical flow velocities.

Notes

The function uses spectral methods for computational efficiency:

  • FFT-based computation: O(n log n) complexity vs O(n²) for finite differences
  • Anisotropic diffusion: Different diffusion rates in x and y directions
  • Zero-mean normalization: Removes global mean to ensure convergence
  • Frequency domain filtering: Avoids division by zero at k=0

The velocity field satisfies a relationship derived from mass conservation and anisotropic diffusion principles commonly used in flow-based cartography.

Examples:

>>> import numpy as np
>>> from carto_flow.velocity import compute_velocity_anisotropic
>>> from carto_flow.grid import Grid
>>>
>>> # Create sample density field
>>> density = np.random.rand(50, 50)
>>> bounds = (0, 0, 10, 10)
>>> grid = Grid.from_bounds(bounds, size=50)
>>>
>>> # Compute isotropic velocity field
>>> vx, vy = compute_velocity_anisotropic(density, grid, Dx=1.0, Dy=1.0)
>>> print(f"Velocity field shape: {vx.shape}")
>>>
>>> # Compute anisotropic velocity field (stronger in x-direction)
>>> vx_aniso, vy_aniso = compute_velocity_anisotropic(density, grid, Dx=2.0, Dy=1.0)

compute_velocity_anisotropic_rfft

compute_velocity_anisotropic_rfft(
    rho: ndarray,
    grid: Grid,
    Dx: float = 1.0,
    Dy: float = 1.0,
) -> tuple[np.ndarray, np.ndarray]

Compute anisotropic velocity field using real FFTs and cached k-space arrays.

Parameters:

  • rho (2D array) –

    Density field.

  • grid (Grid) –

    Grid information containing spatial discretization details. Must provide dx and dy attributes for frequency computation.

  • Dx (float, default: 1.0 ) –

    Flow amplification factors along x and y axes. Higher values produce stronger flow in the corresponding direction.

  • Dy (float, default: 1.0 ) –

    Flow amplification factors along x and y axes. Higher values produce stronger flow in the corresponding direction.

Returns:

  • vx, vy : 2D arrays

    Velocity components in x and y directions.