Skip to main content

VecCell

Struct VecCell 

Source
pub struct VecCell<K, const D: usize>
where K: Eq + Hash,
{ /* private fields */ }
Expand description

Bucket sort points into cubes with Vec-backed storage

VecCell is a spatial data structure that can efficiently update one point at a time (see PointUpdate) and find all points that are near a position in space (see PointsNearBall).

Points are stored in VecCell by key. The caller can choose a generic key type K appropriately. For example, K could be usize and map to an array index. Or it could be an enum that distinguishes between primary and ghost site positions.

Internally, VecCell stores a D-dimensional vector of cells that partition space. Each bucket is a hypercube with an edge length equal to the nominal search radius. When searching for points near a position in space, VecCell first determines which bucket that point is in. Then it iterates over all the keys in all the cells within the given search radius. To perform this iteration efficiently, VecCell pre-computes a set of stencils up to the given maximum search radius given at const

In systems with low density fluctuations, the time complexity of VecCell is O(1). More generally, and important when density fluctuations are present, the time complexity scales with the maximum number of points in any of the cells.

VecCell performs best when the search radius is equal to the nominal search radius. In that case, 2D searches loop over 9 cells and 3D searches loop over 27. The caller must filter the output of this iteration because the resulting hypercube covers more volume than the given hypersphere. When searching with a radius larger than the nominal, many more cells must be iterated leading to slower performance. At the same time, the stencil covers less excess volume and therefore fewer points must be filtered.

VecCell stores each cell at a unique index backed by storage in Vec. This performs very well in dense, compact systems. However, the memory utilization scales with the volume of the cube that spans from the most negative point to the most positive point. In dilute systems, VecCell can therefore waste a lot of memory storing empty cells. Use HashCell and occasionally call its shrink_to_fit method to limit the memory required to model dilute systems.

§Examples

The default VecCell set both the nominal and maximum search radii to 1.0.

use hoomd_spatial::VecCell;

let vec_cell = VecCell::<usize, 3>::default();

Use the builder API to set any or all parameters:

use hoomd_spatial::VecCell;

let vec_cell = VecCell::<usize, 3>::builder()
    .nominal_search_radius(2.5.try_into()?)
    .maximum_search_radius(7.5)
    .build();

Implementations§

Source§

impl<K, const D: usize> VecCell<K, D>
where K: Copy + Eq + Hash,

Source

pub fn builder() -> VecCellBuilder<K, D>

Construct a VecCell builder.

Use the builder to set any or all parameters and construct a VecCell.

§Example
use hoomd_spatial::VecCell;

let vec_cell = VecCell::<usize, 3>::builder()
    .nominal_search_radius(2.5.try_into()?)
    .maximum_search_radius(7.5)
    .build();
Source

pub fn shrink_to_fit(&mut self)

Remove excess capacity from dynamically allocated arrays.

At this time, shrink_to_fit only reduces the memory utilized by the cell contents. It does not shrink the D-dimensional storage to match the range spanned by points currently in the data structure.

Trait Implementations§

Source§

impl<K, const D: usize> Clone for VecCell<K, D>
where K: Eq + Hash + Clone,

Source§

fn clone(&self) -> VecCell<K, D>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<K, const D: usize> Debug for VecCell<K, D>
where K: Eq + Hash + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<K, const D: usize> Default for VecCell<K, D>
where K: Copy + Eq + Hash,

Source§

fn default() -> Self

Construct a default VecCell.

The default sets both the nominal and maximum search radii to 1.0.

§Example
use hoomd_spatial::VecCell;

let vec_cell = VecCell::<usize, 3>::default();
Source§

impl<'de, K, const D: usize> Deserialize<'de> for VecCell<K, D>
where K: Eq + Hash + Deserialize<'de>,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<K, const D: usize> Display for VecCell<K, D>
where K: Eq + Hash,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Summarize the contents of the cell list.

This is a slow operation. It is meant to be printed to logs only occasionally, such as at the end of a benchmark or simulation.

§Example
use hoomd_spatial::VecCell;
use log::info;

let vec_cell = VecCell::<usize, 3>::default();

info!("{vec_cell}");
Source§

impl<K, const D: usize> IndexFromPosition<Cartesian<D>> for VecCell<K, D>
where K: Eq + Hash,

Source§

type Location = [i64; D]

Orderable type based on the site’s position.
Source§

fn location_from_position(&self, position: &Cartesian<D>) -> Self::Location

Determine the location of a site based on its position. Read more
Source§

impl<K, const D: usize> PointUpdate<Cartesian<D>, K> for VecCell<K, D>
where K: Copy + Eq + Hash,

Source§

fn insert(&mut self, key: K, position: Cartesian<D>)

Insert or update a point identified by a key.

§Example
use hoomd_spatial::{PointUpdate, VecCell};

let mut vec_cell = VecCell::default();

vec_cell.insert(0, [1.25, 2.5].into());
Source§

fn remove(&mut self, key: &K)

Remove the point with the given key.

§Example
use hoomd_spatial::{PointUpdate, VecCell};

let mut vec_cell = VecCell::default();
vec_cell.insert(0, [1.25, 2.5].into());

vec_cell.remove(&0)
Source§

fn len(&self) -> usize

Get the number of points in the spatial data structure.

§Example
use hoomd_spatial::{PointUpdate, VecCell};

let mut vec_cell = VecCell::default();
vec_cell.insert(0, [1.25, 2.5].into());

assert_eq!(vec_cell.len(), 1)
Source§

fn is_empty(&self) -> bool

Test if the spatial data structure is empty.

§Example
use hoomd_spatial::{PointUpdate, VecCell};

let mut vec_cell = VecCell::<usize, 2>::default();

assert!(vec_cell.is_empty());
Source§

fn contains_key(&self, key: &K) -> bool

Test if the spatial data structure contains a key.

use hoomd_spatial::{PointUpdate, VecCell};

let mut vec_cell = VecCell::default();
vec_cell.insert(0, [1.25, 2.5].into());

assert!(vec_cell.contains_key(&0));
Source§

fn clear(&mut self)

Remove all points.

§Example
use hoomd_spatial::{PointUpdate, VecCell};

let mut vec_cell = VecCell::default();
vec_cell.insert(0, [1.25, 2.5].into());

vec_cell.clear();
Source§

impl<const D: usize, K> PointsNearBall<Cartesian<D>, K> for VecCell<K, D>
where K: Copy + Eq + Hash,

Source§

fn points_near_ball( &self, position: &Cartesian<D>, radius: f64, ) -> impl Iterator<Item = K>

Find all the points that might be in the given ball.

points_near_ball will iterate over all points in the given ball and possibly others as well. VecCell may iterate over the points in any order.

§Example
use hoomd_spatial::{PointUpdate, PointsNearBall, VecCell};

let mut vec_cell = VecCell::default();
vec_cell.insert(0, [1.25, 0.0].into());
vec_cell.insert(1, [3.25, 0.75].into());
vec_cell.insert(2, [-10.0, 12.0].into());

for key in vec_cell.points_near_ball(&[2.0, 0.0].into(), 1.0) {
    println!("{key}");
}

Prints (in any order):

0
1
§Panics

Panics when radius is larger than the maximum search radius provided at construction, rounded up to the nearest integer multiple of the nominal search radius.

Source§

fn is_all_pairs() -> bool

Is this spatial data structures AllPairs?
Source§

impl<K, const D: usize> Serialize for VecCell<K, D>
where K: Eq + Hash + Serialize,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<K, const D: usize> WithSearchRadius for VecCell<K, D>
where K: Copy + Eq + Hash,

Source§

fn with_search_radius(radius: PositiveReal) -> Self

Construct a VecCell with the given search radius.

Set both the nominal and maximum search radii to radius.

§Example
use hoomd_spatial::{VecCell, WithSearchRadius};

let vec_cell = VecCell::<usize, 3>::with_search_radius(2.5.try_into()?);

Auto Trait Implementations§

§

impl<K, const D: usize> Freeze for VecCell<K, D>

§

impl<K, const D: usize> RefUnwindSafe for VecCell<K, D>
where K: RefUnwindSafe,

§

impl<K, const D: usize> Send for VecCell<K, D>
where K: Send,

§

impl<K, const D: usize> Sync for VecCell<K, D>
where K: Sync,

§

impl<K, const D: usize> Unpin for VecCell<K, D>
where K: Unpin,

§

impl<K, const D: usize> UnsafeUnpin for VecCell<K, D>

§

impl<K, const D: usize> UnwindSafe for VecCell<K, D>
where K: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,