pub trait SitePairEnergy<S> {
// Required method
fn site_pair_energy(
&self,
site_properties_i: &S,
site_properties_j: &S,
) -> f64;
// Provided methods
fn site_pair_energy_initial(
&self,
site_properties_i: &S,
site_properties_j: &S,
) -> f64 { ... }
fn is_only_infinite_or_zero() -> bool { ... }
}Expand description
Compute the energy contribution from a pair of sites.
The SitePairEnergy trait describes a type that can compute the energy
contribution from a pair of sites to the system’s total energy as a function
only of those site’s properties.
The pairwise module provides a number of commonly used implementations,
such as Isotropic, Anisotropic, and HardShape. Combine any
of them with the PairwiseCutoff for use with MC and MD simulations or to
compute system-wide properties.
The generic type names are:
S: TheSite::propertiestype.
§Examples
Implement a custom site energy method:
use hoomd_interaction::{
MaximumInteractionRange, PairwiseCutoff, SitePairEnergy, TotalEnergy,
};
use hoomd_microstate::{
Body, Microstate,
property::{Point, Position},
};
use hoomd_vector::{Cartesian, InnerProduct};
#[derive(MaximumInteractionRange)]
struct Custom {
epsilon: f64,
maximum_interaction_range: f64,
}
impl<S> SitePairEnergy<S> for Custom
where
S: Position<Position = Cartesian<2>>,
{
fn site_pair_energy(
&self,
site_properties_i: &S,
site_properties_j: &S,
) -> f64 {
self.epsilon
* site_properties_i
.position()
.dot(&site_properties_j.position())
}
}
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 0.0])),
Body::point(Cartesian::from([0.0, 1.0])),
])?;
let custom = Custom {
epsilon: 1.0,
maximum_interaction_range: 2.5,
};
let site_pair_energy = custom.site_pair_energy(
µstate.sites()[0].properties,
µstate.sites()[1].properties,
);
let custom = PairwiseCutoff(custom);
let total_energy = custom.total_energy(µstate);Implement a custom site overlap method:
use hoomd_interaction::{
MaximumInteractionRange, PairwiseCutoff, SitePairEnergy, TotalEnergy,
};
use hoomd_microstate::{
Body, Microstate, Transform,
property::{Point, Position},
};
use hoomd_utility::valid::PositiveReal;
use hoomd_vector::{Cartesian, Metric};
#[derive(Default, Position)]
struct CircleSiteProperties {
position: Cartesian<2>,
radius: PositiveReal,
}
impl Transform<CircleSiteProperties> for Point<Cartesian<2>> {
fn transform(
&self,
site_properties: &CircleSiteProperties,
) -> CircleSiteProperties {
CircleSiteProperties {
position: self.position + site_properties.position,
..*site_properties
}
}
}
#[derive(MaximumInteractionRange)]
struct PolydisperseCircleOverlap {
maximum_interaction_range: f64,
}
impl SitePairEnergy<CircleSiteProperties> for PolydisperseCircleOverlap {
fn site_pair_energy(
&self,
a: &CircleSiteProperties,
b: &CircleSiteProperties,
) -> f64 {
let r = a.position().distance(b.position());
if r < a.radius.get() + b.radius.get() {
f64::INFINITY
} else {
0.0
}
}
fn is_only_infinite_or_zero() -> bool {
true
}
fn site_pair_energy_initial(
&self,
_a: &CircleSiteProperties,
_b: &CircleSiteProperties,
) -> f64 {
0.0
}
}
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body {
properties: Point::new(Cartesian::from([0.0, 0.0])),
sites: vec![CircleSiteProperties {
position: Cartesian::from([0.0, 0.0]),
radius: 0.5.try_into()?,
}],
},
Body {
properties: Point::new(Cartesian::from([1.4, 0.0])),
sites: vec![CircleSiteProperties {
position: Cartesian::from([0.0, 0.0]),
radius: 1.0.try_into()?,
}],
},
])?;
let overlap = PolydisperseCircleOverlap {
maximum_interaction_range: 1.5,
};
let site_pair_energy = overlap.site_pair_energy(
µstate.sites()[0].properties,
µstate.sites()[1].properties,
);
assert_eq!(site_pair_energy, f64::INFINITY);
let pairwise_cutoff = PairwiseCutoff(overlap);
let total_energy = pairwise_cutoff.total_energy(µstate);
assert_eq!(total_energy, f64::INFINITY);§Derive macro
Use the SitePairEnergy derive macro to
automatically implement the SitePairEnergy trait on a type.
The implemented site_pair_energy sums the result of site_pair_energy
over all fields. The implementation returns early when any one field returns
infinity. The implemented site_pair_energy_initial behaves similarly.
The derived is_only_infinite_or_zero returns true only when all fields
also return true for the same method.
use hoomd_interaction::{
MaximumInteractionRange, SitePairEnergy,
pairwise::{AngularMask, Anisotropic, HardSphere},
univariate::Boxcar,
};
use hoomd_vector::Cartesian;
#[derive(MaximumInteractionRange, SitePairEnergy)]
struct SitePairInteraction {
hard_disk: HardSphere,
angular_mask: Anisotropic<AngularMask<Boxcar, Cartesian<2>>>,
}Required Methods§
Sourcefn site_pair_energy(&self, site_properties_i: &S, site_properties_j: &S) -> f64
fn site_pair_energy(&self, site_properties_i: &S, site_properties_j: &S) -> f64
Evaluate the energy contribution from a pair of sites.
Provided Methods§
Sourcefn site_pair_energy_initial(
&self,
site_properties_i: &S,
site_properties_j: &S,
) -> f64
fn site_pair_energy_initial( &self, site_properties_i: &S, site_properties_j: &S, ) -> f64
Evaluate the energy contribution from a pair of sites in the initial state.
Override this method in potentials that have both infinite or zero terms
and finite terms, such as the sum of a hard site-wall interaction plus
an attractive well. site_pair_energy should compute both terms and
site_pair_energy_initial should compute only the finite terms.
PairwiseCutoff calls site_pair_energy_initial when evaluating the
energy of the initial state in a trial move. The infinite interaction
term can be assumed 0 in the initial state because no site will ever be
placed in an infinite energy configuration.
Sourcefn is_only_infinite_or_zero() -> bool
fn is_only_infinite_or_zero() -> bool
Does this potential only ever return infinity or zero?
Override this method and return true for e.g. hard particle
interactions that always return infinity or zero and never any other
value. When this method returns true, PairwiseCutoff skips the
initial energy computation and assumes it is zero.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.