pub struct PairwiseCutoff<E>(pub E);Expand description
Short-ranged pairwise interactions between sites.
A PairwiseCutoff newtype wrapped around a type that implements
SitePairEnergy represents:
U_\mathrm{total} = \sum_{i=0}^{N-1}\sum_{j=i+1}^{N-1} U\left(s_i, s_j \right) \left[ \left|\vec{r}_j - \vec{r}_i\right| \lt r_\mathrm{cut} \right]\left[b_i \ne b_j\right]where $U(s_i, s_j)$ is the potential computed by SitePairEnergy,
$s_i$ is the full set of site properties for site i, $\vec{r}_i$ is
the position of site i, $b_i$ is the body tag that holds site i, and
$\left[ \ \right]$ denotes the Iverson bracket.
In other words, PairwiseCutoff sums the energy for all pairs that are
separated by a distance less than the maximum interaction range r_cut and
belong to different bodies.
Use PairwiseCutoff with Anisotropic, Isotropic, HardShape, or
your own custom type.
TODO: Reword this when PairwiseCutoff also implements SitePairForce.
§Example
Basic usage:
use hoomd_interaction::{
PairwiseCutoff, pairwise::Isotropic, univariate::LennardJones,
};
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.5,
sigma: 2.0,
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: lennard_jones,
r_cut: 5.0,
});Set a custom potential using a closure:
use hoomd_interaction::{PairwiseCutoff, pairwise::Isotropic};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: |r: f64| 1.0 / (r.powi(12)),
r_cut: 3.0,
});Implement a custom potential via a type:
use hoomd_interaction::{
PairwiseCutoff, pairwise::Isotropic, univariate::UnivariateEnergy,
};
struct Custom {
a: f64,
}
impl UnivariateEnergy for Custom {
fn energy(&self, r: f64) -> f64 {
self.a / r.powi(12)
}
}
let custom = Custom { a: 2.0 };
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: custom,
r_cut: 2.0,
});Hard sphere:
use hoomd_interaction::{PairwiseCutoff, pairwise::HardSphere};
use hoomd_microstate::property::Point;
use hoomd_vector::Cartesian;
let hard_sphere = PairwiseCutoff(HardSphere { diameter: 1.0 });Hard ellipse:
use hoomd_geometry::shape::Ellipse;
use hoomd_interaction::{PairwiseCutoff, pairwise::HardShape};
use hoomd_microstate::property::Point;
use hoomd_vector::Cartesian;
let ellipse = Ellipse::with_semi_axes([4.0.try_into()?, 1.0.try_into()?]);
let hard_ellipse = PairwiseCutoff(HardShape(ellipse));Tuple Fields§
§0: EImplementations§
Source§impl<E> PairwiseCutoff<E>
impl<E> PairwiseCutoff<E>
Sourcepub fn site_pair_energy<S>(&self, site_i: &Site<S>, site_j: &Site<S>) -> f64where
E: SitePairEnergy<S>,
pub fn site_pair_energy<S>(&self, site_i: &Site<S>, site_j: &Site<S>) -> f64where
E: SitePairEnergy<S>,
Compute the pair energy between two sites.
Use this method to compute an individual term in the total pair energy,
subject to the the maximum interaction range r_cut and inter-body checks:
U\left(s_i, s_j \right) \left[ \left|\vec{r}_j - \vec{r}_i\right| \lt r_\mathrm{cut} \right]\left[b_i \ne b_j\right]§Example
use approxim::assert_relative_eq;
use hoomd_interaction::{
PairwiseCutoff, pairwise::Isotropic, univariate::LennardJones,
};
use hoomd_microstate::{Body, Microstate, Site};
use hoomd_vector::Cartesian;
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.0,
sigma: 1.0,
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: lennard_jones,
r_cut: 2.5,
});
let body_a = Body::point(Cartesian::from([0.0, 0.0]));
let body_b = Body::point(Cartesian::from([0.0, 3.0]));
let body_c = Body::point(Cartesian::from([0.0, -2.0_f64.powf(1.0 / 6.0)]));
let microstate = Microstate::builder()
.bodies([body_a, body_b, body_c])
.try_build()?;
let sites = microstate.sites();
let energy_ab = pairwise_cutoff.site_pair_energy(&sites[0], &sites[1]);
let energy_ac = pairwise_cutoff.site_pair_energy(&sites[0], &sites[2]);
assert_eq!(energy_ab, 0.0);
assert_relative_eq!(energy_ac, -1.0);Trait Implementations§
Source§impl<E: Clone> Clone for PairwiseCutoff<E>
impl<E: Clone> Clone for PairwiseCutoff<E>
Source§fn clone(&self) -> PairwiseCutoff<E>
fn clone(&self) -> PairwiseCutoff<E>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<E: Debug> Debug for PairwiseCutoff<E>
impl<E: Debug> Debug for PairwiseCutoff<E>
Source§impl<P, B, S, X, C, E> DeltaEnergyInsert<B, S, X, C> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
B: Transform<S>,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
C: Wrap<B> + Wrap<S>,
impl<P, B, S, X, C, E> DeltaEnergyInsert<B, S, X, C> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
B: Transform<S>,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
C: Wrap<B> + Wrap<S>,
Source§fn delta_energy_insert(
&self,
initial_microstate: &Microstate<B, S, X, C>,
new_body: &Body<B, S>,
) -> f64
fn delta_energy_insert( &self, initial_microstate: &Microstate<B, S, X, C>, new_body: &Body<B, S>, ) -> f64
Evaluate the change in energy contributed by PairwiseCutoff when one body is inserted.
§Example
Boxcar:
use hoomd_interaction::{
DeltaEnergyInsert, PairwiseCutoff, pairwise::Isotropic,
univariate::Boxcar,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([1.0, 0.0])),
])?;
let epsilon = 2.0;
let (left, right) = (0.0, 1.5);
let boxcar = Boxcar {
epsilon,
left,
right,
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: boxcar,
r_cut: 1.5,
});
let delta_energy = pairwise_cutoff
.delta_energy_insert(µstate, &Body::point([-1.0, 0.0].into()));
assert_eq!(delta_energy, 2.0);Hard circle:
use hoomd_geometry::shape::Circle;
use hoomd_interaction::{
DeltaEnergyInsert, PairwiseCutoff, pairwise::HardSphere,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::{Angle, Cartesian};
let mut microstate = Microstate::new();
microstate.extend_bodies([Body::point(Cartesian::from([0.0, 0.0]))])?;
let hard_circle = PairwiseCutoff(HardSphere { diameter: 1.0 });
let delta_energy = hard_circle
.delta_energy_insert(µstate, &Body::point([0.4, 0.0].into()));
assert_eq!(delta_energy, f64::INFINITY);
let delta_energy = hard_circle
.delta_energy_insert(µstate, &Body::point([1.5, 0.0].into()));
assert_eq!(delta_energy, 0.0);Source§impl<P, B, S, X, C, E> DeltaEnergyOne<B, S, X, C> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
B: Transform<S>,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
C: Wrap<B> + Wrap<S>,
impl<P, B, S, X, C, E> DeltaEnergyOne<B, S, X, C> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
B: Transform<S>,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
C: Wrap<B> + Wrap<S>,
Source§fn delta_energy_one(
&self,
initial_microstate: &Microstate<B, S, X, C>,
body_index: usize,
final_body: &Body<B, S>,
) -> f64
fn delta_energy_one( &self, initial_microstate: &Microstate<B, S, X, C>, body_index: usize, final_body: &Body<B, S>, ) -> f64
Evaluate the change in energy contributed by PairwiseCutoff when one body is updated.
§Examples
Boxcar:
use hoomd_interaction::{
DeltaEnergyOne, PairwiseCutoff, pairwise::Isotropic, univariate::Boxcar,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([1.0, 0.0])),
])?;
let epsilon = 2.0;
let (left, right) = (0.0, 1.5);
let boxcar = Boxcar {
epsilon,
left,
right,
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: boxcar,
r_cut: 1.5,
});
let delta_energy = pairwise_cutoff.delta_energy_one(
µstate,
0,
&Body::point([-1.0, 0.0].into()),
);
assert_eq!(delta_energy, -2.0);Hard circle:
use hoomd_geometry::shape::Circle;
use hoomd_interaction::{
DeltaEnergyOne, PairwiseCutoff, pairwise::HardSphere,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::{Angle, Cartesian};
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([2.0, 0.0])),
])?;
let hard_circle = PairwiseCutoff(HardSphere { diameter: 1.0 });
let delta_energy = hard_circle.delta_energy_one(
µstate,
1,
&Body::point([0.4, 0.0].into()),
);
assert_eq!(delta_energy, f64::INFINITY);
let delta_energy = hard_circle.delta_energy_one(
µstate,
1,
&Body::point([1.5, 0.0].into()),
);
assert_eq!(delta_energy, 0.0);Source§impl<P, B, S, X, C, E> DeltaEnergyRemove<B, S, X, C> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
impl<P, B, S, X, C, E> DeltaEnergyRemove<B, S, X, C> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
Source§fn delta_energy_remove(
&self,
initial_microstate: &Microstate<B, S, X, C>,
body_index: usize,
) -> f64
fn delta_energy_remove( &self, initial_microstate: &Microstate<B, S, X, C>, body_index: usize, ) -> f64
Evaluate the change in energy contributed by PairwiseCutoff when one body is removed.
§Example
Boxcar:
use hoomd_interaction::{
DeltaEnergyRemove, PairwiseCutoff, pairwise::Isotropic,
univariate::Boxcar,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([1.0, 0.0])),
])?;
let epsilon = 2.0;
let (left, right) = (0.0, 1.5);
let boxcar = Boxcar {
epsilon,
left,
right,
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: boxcar,
r_cut: 1.5,
});
let delta_energy = pairwise_cutoff.delta_energy_remove(µstate, 0);
assert_eq!(delta_energy, -2.0);Hard circle:
use hoomd_geometry::shape::Circle;
use hoomd_interaction::{
DeltaEnergyRemove, PairwiseCutoff, pairwise::HardSphere,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::{Angle, Cartesian};
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([2.0, 0.0])),
])?;
let hard_circle = PairwiseCutoff(HardSphere { diameter: 1.0 });
let delta_energy = hard_circle.delta_energy_remove(µstate, 1);
assert_eq!(delta_energy, 0.0);Source§impl<'de, E> Deserialize<'de> for PairwiseCutoff<E>where
E: Deserialize<'de>,
impl<'de, E> Deserialize<'de> for PairwiseCutoff<E>where
E: 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> MaximumInteractionRange for PairwiseCutoff<E>where
E: MaximumInteractionRange,
impl<E> MaximumInteractionRange for PairwiseCutoff<E>where
E: MaximumInteractionRange,
Source§fn maximum_interaction_range(&self) -> f64
fn maximum_interaction_range(&self) -> f64
Source§impl<E: PartialEq> PartialEq for PairwiseCutoff<E>
impl<E: PartialEq> PartialEq for PairwiseCutoff<E>
Source§impl<E> Serialize for PairwiseCutoff<E>where
E: Serialize,
impl<E> Serialize for PairwiseCutoff<E>where
E: Serialize,
Source§impl<P, B, S, X, C, E> TotalEnergy<Microstate<B, S, X, C>> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
impl<P, B, S, X, C, E> TotalEnergy<Microstate<B, S, X, C>> for PairwiseCutoff<E>where
E: SitePairEnergy<S> + MaximumInteractionRange,
S: Position<Position = P>,
X: PointsNearBall<P, SiteKey>,
Source§fn total_energy(&self, microstate: &Microstate<B, S, X, C>) -> f64
fn total_energy(&self, microstate: &Microstate<B, S, X, C>) -> f64
Compute the total energy of the microstate contributed by functions on pairs of sites.
§Examples
Lennard-Jones:
use hoomd_interaction::{
PairwiseCutoff, SitePairEnergy, TotalEnergy, pairwise::Isotropic,
univariate::LennardJones,
};
use hoomd_microstate::{
Body, Microstate,
property::{Point, Position},
};
use hoomd_vector::{Cartesian, InnerProduct};
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([1.0, 0.0])),
Body::point(Cartesian::from([0.0, 5.0])),
Body::point(Cartesian::from([-1.0, 5.0])),
])?;
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.5,
sigma: 1.0 / 2.0_f64.powf(1.0 / 6.0),
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: lennard_jones,
r_cut: 2.5,
});
let total_energy = pairwise_cutoff.total_energy(µstate);
assert_eq!(total_energy, -3.0);Hard circle:
use hoomd_geometry::shape::Circle;
use hoomd_interaction::{
PairwiseCutoff, TotalEnergy, pairwise::HardSphere,
};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::{Angle, Cartesian};
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([0.4, 0.0])),
])?;
let hard_circle = PairwiseCutoff(HardSphere { diameter: 1.0 });
let total_energy = hard_circle.total_energy(µstate);
assert_eq!(total_energy, f64::INFINITY);
microstate.update_body_properties(0, Point::new([0.0, -2.0].into()));
let total_energy = hard_circle.total_energy(µstate);
assert_eq!(total_energy, 0.0);Source§fn delta_energy_total(
&self,
initial_microstate: &Microstate<B, S, X, C>,
final_microstate: &Microstate<B, S, X, C>,
) -> f64
fn delta_energy_total( &self, initial_microstate: &Microstate<B, S, X, C>, final_microstate: &Microstate<B, S, X, C>, ) -> f64
Compute the difference in energy between two microstates.
Returns $ E_\mathrm{final} - E_\mathrm{initial} $.
§Example
use hoomd_interaction::{
PairwiseCutoff, SitePairEnergy, TotalEnergy, pairwise::Isotropic,
univariate::LennardJones,
};
use hoomd_microstate::{
Body, Microstate,
property::{Point, Position},
};
use hoomd_vector::{Cartesian, InnerProduct};
let mut microstate_a = Microstate::new();
microstate_a.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([1.0, 0.0])),
])?;
let mut microstate_b = Microstate::new();
microstate_b.extend_bodies([
Body::point(Cartesian::from([0.0, 0.0])),
Body::point(Cartesian::from([5.0, 0.0])),
])?;
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.5,
sigma: 1.0 / 2.0_f64.powf(1.0 / 6.0),
};
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: lennard_jones,
r_cut: 2.5,
});
let delta_energy_total =
pairwise_cutoff.delta_energy_total(µstate_a, µstate_b);
assert_eq!(delta_energy_total, 1.5);impl<E> StructuralPartialEq for PairwiseCutoff<E>
Auto Trait Implementations§
impl<E> Freeze for PairwiseCutoff<E>where
E: Freeze,
impl<E> RefUnwindSafe for PairwiseCutoff<E>where
E: RefUnwindSafe,
impl<E> Send for PairwiseCutoff<E>where
E: Send,
impl<E> Sync for PairwiseCutoff<E>where
E: Sync,
impl<E> Unpin for PairwiseCutoff<E>where
E: Unpin,
impl<E> UnsafeUnpin for PairwiseCutoff<E>where
E: UnsafeUnpin,
impl<E> UnwindSafe for PairwiseCutoff<E>where
E: 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