hoomd-spatial 1.0.0

Infrastructure for efficient computation of neighbors using spatial data structures.
Documentation
// Copyright (c) 2024-2026 The Regents of the University of Michigan.
// Part of hoomd-rs, released under the BSD 3-Clause License.

//! Implement `AllPairs`

use rustc_hash::FxHashSet;
use serde::{Deserialize, Serialize};
use std::{fmt, hash::Hash};

use hoomd_utility::valid::PositiveReal;

use super::{PointUpdate, PointsNearBall, WithSearchRadius};

/// Check all pairs.
///
/// Prefer [`VecCell`] or [`HashCell`] when possible. In typical benchmarks,
/// [`AllPairs`] outperforms [`VecCell`] only when the system size is less
/// than 32 sites.
///
/// [`VecCell`]: crate::VecCell
/// [`HashCell`]: crate::HashCell
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct AllPairs<K>
where
    K: Eq + Hash,
{
    /// Store all keys currently in the spatial data.
    keys: FxHashSet<K>,
}

impl<K> Default for AllPairs<K>
where
    K: Copy + Eq + Hash,
{
    #[inline]
    fn default() -> Self {
        Self {
            keys: FxHashSet::default(),
        }
    }
}

impl<K> WithSearchRadius for AllPairs<K>
where
    K: Copy + Eq + Hash,
{
    #[inline]
    fn with_search_radius(_radius: PositiveReal) -> Self {
        Self::default()
    }
}

impl<P, K> PointUpdate<P, K> for AllPairs<K>
where
    K: Copy + Eq + Hash,
{
    #[inline]
    fn insert(&mut self, key: K, _position: P) {
        self.keys.insert(key);
    }

    #[inline]
    fn remove(&mut self, key: &K) {
        self.keys.remove(key);
    }

    #[inline]
    fn len(&self) -> usize {
        self.keys.len()
    }

    #[inline]
    fn is_empty(&self) -> bool {
        self.keys.is_empty()
    }

    #[inline]
    fn contains_key(&self, key: &K) -> bool {
        self.keys.contains(key)
    }

    #[inline]
    fn clear(&mut self) {
        self.keys.clear();
    }
}

impl<P, K> PointsNearBall<P, K> for AllPairs<K>
where
    K: Copy + Eq + Hash,
{
    #[inline]
    fn points_near_ball(&self, _position: &P, _radius: f64) -> impl Iterator<Item = K> {
        self.keys.iter().copied()
    }

    #[inline]
    fn is_all_pairs() -> bool {
        true
    }
}

impl<K> fmt::Display for AllPairs<K>
where
    K: Eq + Hash,
{
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "AllPairs")
    }
}