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: EThe 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,
impl<E, V> AngularMask<E, V>where
V: Vector,
Sourcepub fn new<I>(isotropic: E, masks: I) -> Selfwhere
I: IntoIterator<Item = Patch<V>>,
pub fn new<I>(isotropic: E, masks: I) -> Selfwhere
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>
impl<E, V, R> AnisotropicEnergy<V, R> for AngularMask<E, V>
Source§impl<E: Clone, V: Clone> Clone for AngularMask<E, V>
impl<E: Clone, V: Clone> Clone for AngularMask<E, V>
Source§fn clone(&self) -> AngularMask<E, V>
fn clone(&self) -> AngularMask<E, V>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'de, E, V> Deserialize<'de> for AngularMask<E, V>where
E: Deserialize<'de>,
V: Deserialize<'de>,
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>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<E, V> Serialize for AngularMask<E, V>
impl<E, V> Serialize for AngularMask<E, V>
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>where
E: RefUnwindSafe,
V: RefUnwindSafe,
impl<E, V> Send for AngularMask<E, V>
impl<E, V> Sync for AngularMask<E, V>
impl<E, V> Unpin for AngularMask<E, V>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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