pub struct External<E>(pub E);Expand description
Interactions between sites and external fields.
An External newtype wrapping a type that implements SiteEnergy 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.
An External newtype wrapping a type that implements SiteForceAndVirial and/or
SiteForceVirialAndTorque represents:
\vec{F}_i = \vec{F}\left(s_i\right)\vec{\tau}_i = \vec{\tau}\left(s_i\right)where $\vec{F}(s_i)$ is the force computed by SiteForceAndVirial
(or SiteForceVirialAndTorque) and $\vec{\tau}(s_i)$ is the torque computed by
SiteForceVirialAndTorque.
A type that implements both SiteEnergy and SiteForceAndVirial
(or SiteForceVirialAndTorque) must compute forces and torques that are
derivatives of the energy.
Use External with ConstantForce or your own custom type that
implements SiteEnergy, SiteForceAndVirial and/or
SiteForceVirialAndTorque.
§Examples
A linear external potential given by a constant force:
use hoomd_interaction::{External, TotalEnergy, external::ConstantForce};
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 constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let total_energy = constant_force.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 given by a constant force:
use hoomd_interaction::{
DeltaEnergyInsert, External, external::ConstantForce,
};
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 constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let delta_energy = constant_force
.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 given by a constant force:
use hoomd_interaction::{
DeltaEnergyOne, External, external::ConstantForce,
};
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 constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let delta_energy = constant_force.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 given by a constant force:
use hoomd_interaction::{
DeltaEnergyRemove, External, external::ConstantForce,
};
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 constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let delta_energy = constant_force.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<V, B, S, X, C, E> NetSiteForceAndVirial<B, S, X, C> for External<E>
impl<V, B, S, X, C, E> NetSiteForceAndVirial<B, S, X, C> for External<E>
Source§fn net_site_force_and_virial(
&self,
microstate: &Microstate<B, S, X, C>,
site_index: usize,
) -> (V, V::Tensor)
fn net_site_force_and_virial( &self, microstate: &Microstate<B, S, X, C>, site_index: usize, ) -> (V, V::Tensor)
Compute the net force and virial on a given site.
§Example
use hoomd_interaction::{
External, NetSiteForceAndVirial, external::ConstantForce,
};
use hoomd_linear_algebra::matrix::Matrix;
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.add_body(Body::point(Cartesian::from([2.0, 0.0])))?;
let constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let (force, virial) =
constant_force.net_site_force_and_virial(µstate, 0);
assert_eq!(force, [0.0, -1.0].into());
assert_eq!(
virial,
Matrix {
rows: [[0.0, 0.0], [-2.0, 0.0]]
}
);Source§impl<V, B, S, X, C, E> NetSiteForceVirialAndTorque<B, S, X, C> for External<E>
impl<V, B, S, X, C, E> NetSiteForceVirialAndTorque<B, S, X, C> for External<E>
Source§fn net_site_force_virial_and_torque(
&self,
microstate: &Microstate<B, S, X, C>,
site_index: usize,
) -> (V, V::Tensor, V::Bivector)
fn net_site_force_virial_and_torque( &self, microstate: &Microstate<B, S, X, C>, site_index: usize, ) -> (V, V::Tensor, V::Bivector)
Compute the net force, virial, and torque on a given site.
§Example
use hoomd_interaction::{
External, NetSiteForceVirialAndTorque, external::ConstantForce,
};
use hoomd_linear_algebra::matrix::Matrix;
use hoomd_microstate::{Body, Microstate, property::Point};
use hoomd_vector::Cartesian;
let mut microstate = Microstate::new();
microstate.add_body(Body::point(Cartesian::from([2.0, 0.0])))?;
let constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let (force, virial, torque) =
constant_force.net_site_force_virial_and_torque(µstate, 0);
assert_eq!(force, [0.0, -1.0].into());
assert_eq!(
virial,
Matrix {
rows: [[0.0, 0.0], [-2.0, 0.0]]
}
);
assert_eq!(torque, 0.0);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 given by a constant force:
use hoomd_interaction::{External, TotalEnergy, external::ConstantForce};
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 constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let total_energy = constant_force.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::ConstantForce};
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 constant_force = External(ConstantForce {
force: Cartesian::from([0.0, -1.0]),
r_0: Cartesian::default(),
});
let delta_energy_total =
constant_force.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