Utils

Utility functions for SPH operations.

smudgy.utils.build_kdtree(points: ArrayLike, boxsize: float | Sequence[float] | ArrayLike | None = None) cKDTree[source]

Construct a cKDTree with optional periodic box sizes.

If boxsize is provided, the tree will use periodic boundary conditions.

Parameters:
  • points – Array of shape (N, D) with particle coordinates, where N is the number of particles and D the dimension.

  • boxsize – Scalar or (D,) array defining periodic box lengths, or None.

Returns:

Tree built from points.

Return type:

scipy.spatial.cKDTree

smudgy.utils.query_kdtree(tree: cKDTree, points: ArrayLike, k: int) tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[int64]]][source]

Query a cKDTree for the k nearest neighbors of given points.

Parameters:
  • tree – cKDTree instance to query.

  • points – Array of shape (M, D) with query coordinates, where M is the number of query positions.

  • k – Number of nearest neighbors to return.

Returns:

Tuple of (distances, indices) from cKDTree.query.

Return type:

Tuple[numpy.ndarray, numpy.ndarray]

smudgy.utils.shift_coordinates(coordinates: ArrayLike) ndarray[tuple[Any, ...], dtype[floating]][source]

Shift coordinates so the minimum per-axis value is at zero.

Parameters:

coordinates – Array of shape (N, D) with particle coordinates.

Returns:

Shifted coordinates with the same shape as coordinates.

Return type:

numpy.ndarray

Raises:

AssertionError – If the input array is not 2D.

smudgy.utils.coordinate_difference_with_pbc(x: ArrayLike, y: ArrayLike, boxsize: float | Sequence[float] | ArrayLike) ndarray[tuple[Any, ...], dtype[floating]][source]

Compute coordinate differences with periodic boundary conditions.

Parameters:
  • x – Array-like coordinates.

  • y – Array-like coordinates to subtract from x.

  • boxsize – Scalar or (D,) array defining periodic box lengths.

Returns:

Coordinate differences wrapped into the range $[-0.5 * boxsize, 0.5 * boxsize)$ per dimension.

Return type:

numpy.ndarray

Raises:

AssertionError – If the input coordinate arrays do not have the same spatial dimension. If boxsize is an array, if it is not 1D or if its length does not match the coordinate dimension.

smudgy.utils.compute_smoLens(tree: cKDTree, num_neighbors: int, query_positions: ArrayLike | None = None) tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[int64]], ndarray[tuple[Any, ...], dtype[floating]]][source]

Estimate smoothing length as half the distance to the Nth neighbor.

Parameters:
  • tree – cKDTree built from particle positions.

  • num_neighbors – Number of neighbors used for the estimate.

  • query_positions – Array of shape (M, D) with positions where smoothing length is evaluated. If None, uses particle positions from the tree.

Returns:

Tuple of (hsm, nn_inds, nn_dists) where hsm has shape (M,), nn_dists has shape (M, num_neighbors), and nn_inds has shape (M, num_neighbors).

Return type:

Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

smudgy.utils.compute_smoTens(tree: cKDTree, weights: ArrayLike, num_neighbors: int, query_positions: ArrayLike | None = None) tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[int64]], ndarray[tuple[Any, ...], dtype[floating]]][source]

Compute anisotropic smoothing tensor using a covariance-based method.

Implements the method from Marinho (2021), generalized for 2D and 3D.

Parameters:
  • tree – cKDTree built from particle positions.

  • weights – Array of shape (N,) with particle weights.

  • num_neighbors – Number of neighbors used for covariance estimation.

  • query_positions – Array of shape (M, D) where the tensor is evaluated. If None, uses particle positions from the tree.

Returns:

Tuple (H, eigvals, eigvecs, nn_inds, nn_dists, rel_coords) where H has shape (M, D, D), eigvals has shape (M, D), eigvecs has shape (M, D, D), nn_inds has shape (M, num_neighbors), nn_dists has shape (M, num_neighbors), and rel_coords has shape (M, num_neighbors, D).

Return type:

Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray]

smudgy.utils.project_smoTens_to_2d(h_tensor: ArrayLike, plane: list[int] | None = None, basis: list[Sequence[float], Sequence[float]] | None = None) tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]][source]

Project 3D smoothing tensors onto a 2D plane.

Parameters:
  • h_tensor – Array of shape (N, 3, 3) with 3D smoothing tensors.

  • plane – Indices of the axes to project onto for 3D to 2D deposition. Mutually exclusive with basis.

  • basis – List of basis vectors (e1, e2) spanning the projection plane. Each vector should be array-like of length 3. Mutually exclusive with plane.

Returns:

Tuple (h_tensor_2d, eigvals, eigvecs) where h_tensor_2d has shape (N, 2, 2), eigvals has shape (N, 2), and eigvecs has shape (N, 2, 2).

Return type:

Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

Raises:

ValueError – If neither or both of plane and basis are provided. If plane is not one of the allowed values or types or does not have length 2. If basis is not a 2-tuple of 3D vectors.