pub struct External<E>(pub E);Expand description
Interactions between sites and external fields.
Given an inner type that implements SiteEnergy, External represents:
U_\mathrm{total} = \sum_{i=0}^{N-1} U\left( s_i \right)where $s_i$ is the full set of site properties for site i.
For the inner type, use one from external or your own custom type.
§Examples
A linear external potential:
use hoomd_interaction::{External, TotalEnergy, external::Linear};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 0.0])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let linear = External(Linear {
alpha: 1.0,
plane_origin: Cartesian::default(),
plane_normal: [0.0, 1.0].try_into()?,
});
let total_energy = linear.total_energy(µstate);
assert_eq!(total_energy, 2.0);Infinite interaction with a wall:
use hoomd_interaction::{External, SiteEnergy, TotalEnergy};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
struct Wall;
impl SiteEnergy<Point<Cartesian<2>>> for Wall {
fn site_energy(&self, site_properties: &Point<Cartesian<2>>) -> f64 {
if site_properties.position[1].abs() < 1.0 {
f64::INFINITY
} else {
0.0
}
}
fn is_only_infinite_or_zero() -> bool {
true
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 1.25])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let wall = External(Wall);
let total_energy = wall.total_energy(µstate);
assert_eq!(total_energy, 0.0);
Ok(())
}Tuple Fields§
§0: ETrait Implementations§
Source§impl<P, B, S, X, C, E> DeltaEnergyInsert<B, S, X, C> for External<E>
impl<P, B, S, X, C, E> DeltaEnergyInsert<B, S, X, C> for External<E>
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 External when a single body is inserted.
§Examples
A linear external potential:
use hoomd_interaction::{DeltaEnergyInsert, External, external::Linear};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.add_body(Body::point(Cartesian::from([0.0, 0.0])))?;
let linear = External(Linear {
alpha: 1.0,
plane_origin: Cartesian::default(),
plane_normal: [0.0, 1.0].try_into()?,
});
let delta_energy = linear
.delta_energy_insert(µstate, &Body::point([0.0, -1.0].into()));
assert_eq!(delta_energy, -1.0);Infinite interaction with a wall:
use hoomd_interaction::{DeltaEnergyInsert, External, SiteEnergy};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
struct Wall;
impl SiteEnergy<Point<Cartesian<2>>> for Wall {
fn site_energy(&self, site_properties: &Point<Cartesian<2>>) -> f64 {
if site_properties.position[1].abs() < 1.0 {
f64::INFINITY
} else {
0.0
}
}
fn is_only_infinite_or_zero() -> bool {
true
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 1.25])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let wall = External(Wall);
let delta_energy = wall
.delta_energy_insert(µstate, &Body::point([0.0, -0.5].into()));
assert_eq!(delta_energy, f64::INFINITY);
Ok(())
}Source§impl<P, B, S, X, C, E> DeltaEnergyOne<B, S, X, C> for External<E>
impl<P, B, S, X, C, E> DeltaEnergyOne<B, S, X, C> for External<E>
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 External when a single body is updated.
§Examples
A linear external potential:
use hoomd_interaction::{DeltaEnergyOne, External, external::Linear};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.add_body(Body::point(Cartesian::from([0.0, 0.0])))?;
let linear = External(Linear {
alpha: 1.0,
plane_origin: Cartesian::default(),
plane_normal: [0.0, 1.0].try_into()?,
});
let delta_energy = linear.delta_energy_one(
µstate,
0,
&Body::point([0.0, -1.0].into()),
);
assert_eq!(delta_energy, -1.0);Infinite interaction with a wall:
use hoomd_interaction::{DeltaEnergyOne, External, SiteEnergy};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
struct Wall;
impl SiteEnergy<Point<Cartesian<2>>> for Wall {
fn site_energy(&self, site_properties: &Point<Cartesian<2>>) -> f64 {
if site_properties.position[1].abs() < 1.0 {
f64::INFINITY
} else {
0.0
}
}
fn is_only_infinite_or_zero() -> bool {
true
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 1.25])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let wall = External(Wall);
let delta_energy = wall.delta_energy_one(
µstate,
0,
&Body::point([0.0, -0.5].into()),
);
assert_eq!(delta_energy, f64::INFINITY);
Ok(())
}Source§impl<B, S, X, C, E> DeltaEnergyRemove<B, S, X, C> for External<E>where
E: SiteEnergy<S>,
impl<B, S, X, C, E> DeltaEnergyRemove<B, S, X, C> for External<E>where
E: SiteEnergy<S>,
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 External when a single body is removed.
§Examples
A linear external potential:
use hoomd_interaction::{DeltaEnergyRemove, External, external::Linear};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.add_body(Body::point(Cartesian::from([0.0, 1.0])))?;
let linear = External(Linear {
alpha: 1.0,
plane_origin: Cartesian::default(),
plane_normal: [0.0, 1.0].try_into()?,
});
let delta_energy = linear.delta_energy_remove(µstate, 0);
assert_eq!(delta_energy, -1.0);Infinite interaction with a wall:
use hoomd_interaction::{DeltaEnergyRemove, External, SiteEnergy};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
struct Wall;
impl SiteEnergy<Point<Cartesian<2>>> for Wall {
fn site_energy(&self, site_properties: &Point<Cartesian<2>>) -> f64 {
if site_properties.position[1].abs() < 1.0 {
f64::INFINITY
} else {
0.0
}
}
fn is_only_infinite_or_zero() -> bool {
true
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 1.25])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let wall = External(Wall);
let delta_energy = wall.delta_energy_remove(µstate, 0);
assert_eq!(delta_energy, 0.0);
Ok(())
}Source§impl<'de, E> Deserialize<'de> for External<E>where
E: Deserialize<'de>,
impl<'de, E> Deserialize<'de> for External<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 External<E>
impl<E> MaximumInteractionRange for External<E>
Source§fn maximum_interaction_range(&self) -> f64
fn maximum_interaction_range(&self) -> f64
Source§impl<B, S, X, C, E> TotalEnergy<Microstate<B, S, X, C>> for External<E>where
E: SiteEnergy<S>,
impl<B, S, X, C, E> TotalEnergy<Microstate<B, S, X, C>> for External<E>where
E: SiteEnergy<S>,
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 of a single site.
The sum over sites differs from HOOMD-blue where external energies are evaluated only at the body centers. In general, hoomd-rs interactions apply to sites. Use a custom implementation to compute energies over body centers.
§Examples
A linear external potential:
use hoomd_interaction::{External, TotalEnergy, external::Linear};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 0.0])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let linear = External(Linear {
alpha: 1.0,
plane_origin: Cartesian::default(),
plane_normal: [0.0, 1.0].try_into()?,
});
let total_energy = linear.total_energy(µstate);
assert_eq!(total_energy, 2.0);Infinite interaction with a wall:
use hoomd_interaction::{External, SiteEnergy, TotalEnergy};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
struct Wall;
impl SiteEnergy<Point<Cartesian<2>>> for Wall {
fn site_energy(&self, site_properties: &Point<Cartesian<2>>) -> f64 {
if site_properties.position[1].abs() < 1.0 {
f64::INFINITY
} else {
0.0
}
}
fn is_only_infinite_or_zero() -> bool {
true
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::point(Cartesian::from([1.0, 1.25])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let wall = External(Wall);
let total_energy = wall.total_energy(µstate);
assert_eq!(total_energy, 0.0);
Ok(())
}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::{External, TotalEnergy, external::Linear};
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate_a = Microstate::new();
microstate_a.extend_bodies([
Body::point(Cartesian::from([1.0, 0.0])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let mut microstate_b = Microstate::new();
microstate_b.extend_bodies([
Body::point(Cartesian::from([1.0, 1.0])),
Body::point(Cartesian::from([-1.0, 2.0])),
])?;
let linear = External(Linear {
alpha: 1.0,
plane_origin: Cartesian::default(),
plane_normal: [0.0, 1.0].try_into()?,
});
let delta_energy_total =
linear.delta_energy_total(µstate_a, µstate_b);
assert_eq!(delta_energy_total, 1.0);impl<E> StructuralPartialEq for External<E>
Auto Trait Implementations§
impl<E> Freeze for External<E>where
E: Freeze,
impl<E> RefUnwindSafe for External<E>where
E: RefUnwindSafe,
impl<E> Send for External<E>where
E: Send,
impl<E> Sync for External<E>where
E: Sync,
impl<E> Unpin for External<E>where
E: Unpin,
impl<E> UnsafeUnpin for External<E>where
E: UnsafeUnpin,
impl<E> UnwindSafe for External<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