Skip to main content

AngularMask

Struct AngularMask 

Source
pub struct AngularMask<E, V> {
    pub isotropic: E,
    pub masks_i: Vec<Patch<V>>,
    pub masks_j: Vec<Patch<V>>,
}
Expand description

Evaluate an isotropic pairwise energy masked by angular patches (not differentiable).

U(\vec{r}_{ij}, \mathbf{o}_{ij}) = f(|\vec{r}_{ij}|) \cdot \max
\left(1,
\sum_{m=1}^{N_{\mathrm{masks},i}}
\sum_{n=1}^{N_{\mathrm{masks},j}}
s(\vec{d}_{m,i},
\mathbf{o}_{ij} \vec{d}_{n,j} \mathbf{o}_{ij}^*,
\delta_{m,i},
\delta_{n,j}) \right)

where

s(\vec{a}, \vec{b}, \delta_a, \delta_b) =
\begin{cases}
1 & \hat{a} \cdot \hat{r}_{ij} \ge \cos \delta_{a} \land
\hat{b} \cdot \hat{r}_{ji} \ge \cos \delta_{b} \\
0 & \text{otherwise} \\
\end{cases}

Implement the Kern-Frenkel potential with the Boxcar isotropic potential and single patch in both masks_i and masks_j.

§Examples

Construction:

use hoomd_interaction::{
    pairwise::{AngularMask, angular_mask::Patch},
    univariate::Boxcar,
};
use hoomd_vector::Angle;
use std::f64::consts::PI;

let boxcar = Boxcar {
    epsilon: -1.0,
    left: 1.0,
    right: 1.5,
};
let masks = [Patch {
    director: [1.0, 0.0].try_into()?,
    cos_delta: (PI / 8.0).cos(),
}];
let angular_mask = AngularMask::new(boxcar, masks);

All fields are public and can be directly manipulated:

use hoomd_interaction::{
    pairwise::{AngularMask, angular_mask::Patch},
    univariate::Boxcar,
};
use hoomd_vector::Angle;
use std::f64::consts::PI;

let boxcar = Boxcar {
    epsilon: -1.0,
    left: 1.0,
    right: 1.5,
};
let masks = [Patch {
    director: [1.0, 0.0].try_into()?,
    cos_delta: (PI / 8.0).cos(),
}];
let mut angular_mask = AngularMask::new(boxcar, masks);

angular_mask.masks_i[0].cos_delta = (PI / 4.0).cos();
angular_mask.isotropic.epsilon = -2.0;

Evaluate energy between particles:

use hoomd_interaction::{
    pairwise::{AngularMask, AnisotropicEnergy, angular_mask::Patch},
    univariate::Boxcar,
};
use hoomd_vector::Angle;
use std::f64::consts::PI;

let boxcar = Boxcar {
    epsilon: -1.0,
    left: 1.0,
    right: 1.5,
};
let masks = [Patch {
    director: [1.0, 0.0].try_into()?,
    cos_delta: (PI / 8.0).cos(),
}];
let angular_mask = AngularMask::new(boxcar, masks);

let energy = angular_mask.energy(&[1.0, 0.0].into(), &Angle::from(0.0));
assert_eq!(energy, 0.0);

let energy = angular_mask.energy(&[1.0, 0.0].into(), &Angle::from(PI));
assert_eq!(energy, -1.0);

Apply different patches to the i and j particles:

use hoomd_interaction::{
    pairwise::{AngularMask, AnisotropicEnergy, angular_mask::Patch},
    univariate::Boxcar,
};
use hoomd_vector::Angle;
use std::f64::consts::PI;

let boxcar = Boxcar {
    epsilon: -1.0,
    left: 1.0,
    right: 1.5,
};
let masks_i = vec![
    Patch {
        director: [1.0, 0.0].try_into()?,
        cos_delta: (PI / 8.0).cos(),
    },
    Patch {
        director: [-1.0, 0.0].try_into()?,
        cos_delta: (PI / 8.0).cos(),
    },
];
let masks_j = vec![Patch {
    director: [0.0, 1.0].try_into()?,
    cos_delta: (PI / 8.0).cos(),
}];
let angular_mask = AngularMask {
    isotropic: boxcar,
    masks_i,
    masks_j,
};

let energy = angular_mask.energy(&[-1.0, 0.0].into(), &Angle::from(0.0));
assert_eq!(energy, 0.0);

let energy =
    angular_mask.energy(&[-1.0, 0.0].into(), &Angle::from(-PI / 2.0));
assert_eq!(energy, -1.0);

Evaluate the angular mask potential on 3D particles:

use hoomd_interaction::{
    pairwise::{AngularMask, AnisotropicEnergy, angular_mask::Patch},
    univariate::Boxcar,
};
use hoomd_vector::{Cartesian, InnerProduct, Versor};
use std::f64::consts::PI;

let boxcar = Boxcar {
    epsilon: -1.0,
    left: 1.0,
    right: 1.5,
};

let mask = [Patch {
    director: [0.0, 0.0, 1.0].try_into()?,
    cos_delta: (PI / 8.0).cos(),
}];
let (x_axis, _) = Cartesian::from([1.0, 0.0, 0.0]).to_unit_unchecked();

let angular_mask = AngularMask::new(boxcar, mask);

assert_eq!(
    angular_mask.energy(
        &Cartesian::from([0.0, 0.0, 1.0]),
        &Versor::from_axis_angle(x_axis, 0.0)
    ),
    0.0
);
assert_eq!(
    angular_mask.energy(
        &Cartesian::from([0.0, 0.0, 1.0]),
        &Versor::from_axis_angle(x_axis, PI)
    ),
    -1.0
);

Fields§

§isotropic: E

The original potential.

§masks_i: Vec<Patch<V>>

Masks on the i particle.

§masks_j: Vec<Patch<V>>

Masks on the j particle.

Implementations§

Source§

impl<E, V> AngularMask<E, V>
where V: Vector,

Source

pub fn new<I>(isotropic: E, masks: I) -> Self
where I: IntoIterator<Item = Patch<V>>,

Construct a AngularMask with the given function and masks.

To obtain the best performance, construct AngularMask once and call use it many times. new dynamically allocates Vec types and is therefore not suitable to be called per particle, unlike other potentials such as LennardJones or Boxcar.

new sets both masks_i and masks_j to masks. Use struct initialization syntax to set these separately.

§Example
use hoomd_interaction::{
    pairwise::{AngularMask, angular_mask::Patch},
    univariate::Boxcar,
};
use std::f64::consts::PI;

let boxcar = Boxcar {
    epsilon: -1.0,
    left: 1.0,
    right: 1.5,
};
let masks = [Patch {
    director: [1.0, 0.0].try_into()?,
    cos_delta: (PI / 8.0).cos(),
}];
let angular_mask = AngularMask::new(boxcar, masks);

Trait Implementations§

Source§

impl<E, V, R> AnisotropicEnergy<V, R> for AngularMask<E, V>
where E: UnivariateEnergy, V: InnerProduct, R: Rotate<V> + Into<R::Matrix> + Copy,

Source§

fn energy(&self, r_ij: &V, o_ij: &R) -> f64

Compute the pairwise energy between two oriented particles. Read more
Source§

impl<E: Clone, V: Clone> Clone for AngularMask<E, V>

Source§

fn clone(&self) -> AngularMask<E, V>

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<E: Debug, V: Debug> Debug for AngularMask<E, V>

Source§

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

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

impl<'de, E, V> Deserialize<'de> for AngularMask<E, V>
where E: Deserialize<'de>, V: 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<E: PartialEq, V: PartialEq> PartialEq for AngularMask<E, V>

Source§

fn eq(&self, other: &AngularMask<E, V>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<E, V> Serialize for AngularMask<E, V>
where E: Serialize, V: 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<E, V> StructuralPartialEq for AngularMask<E, V>

Auto Trait Implementations§

§

impl<E, V> Freeze for AngularMask<E, V>
where E: Freeze,

§

impl<E, V> RefUnwindSafe for AngularMask<E, V>

§

impl<E, V> Send for AngularMask<E, V>
where E: Send, V: Send,

§

impl<E, V> Sync for AngularMask<E, V>
where E: Sync, V: Sync,

§

impl<E, V> Unpin for AngularMask<E, V>
where E: Unpin, V: Unpin,

§

impl<E, V> UnsafeUnpin for AngularMask<E, V>
where E: UnsafeUnpin,

§

impl<E, V> UnwindSafe for AngularMask<E, V>
where E: UnwindSafe, V: 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
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, 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>,