pub struct Rigid<F>(pub F);Expand description
Rigid body interactions.
The Rigid newtype implements NetBodyForceAndVirial for wrapped force
interaction model types that implement NetSiteForceAndVirial. It also implements
NetBodyForceVirialAndTorque for interaction model types that implement
NetSiteForceVirialAndTorque.
Rigid computes the net force and torque on a rigid body that results
from the forces/torques on all of its sites:
\vec{F}_\mathrm{body} = \sum_{i \in \mathrm{body}} \vec{F}_{i}\vec{\tau}_\mathrm{body} = \sum_{i \in \mathrm{body}} (\mathbf{q}_\mathrm{body} \cdot \vec{r}_{\mathrm{body},i} \cdot \mathbf{q}_\mathrm{body}^*) \wedge \vec{F}_i + \vec{\tau}_{i}The generic type names are:
F: The evaluator that implementsNetSiteForceAndVirialand/orNetSiteForceVirialAndTorque.
§Example
use hoomd_interaction::{
PairwiseCutoff, Rigid, pairwise::Isotropic, univariate::LennardJones,
};
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.0,
sigma: 1.0,
};
let evaluator = Isotropic {
interaction: lennard_jones,
r_cut: 2.5,
};
let rigid = Rigid(PairwiseCutoff(evaluator));Tuple Fields§
§0: FTrait Implementations§
Source§impl<B, S, X, C, F> DeltaEnergyInsert<B, S, X, C> for Rigid<F>where
F: DeltaEnergyInsert<B, S, X, C>,
impl<B, S, X, C, F> DeltaEnergyInsert<B, S, X, C> for Rigid<F>where
F: DeltaEnergyInsert<B, S, X, C>,
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
Source§impl<B, S, X, C, F> DeltaEnergyOne<B, S, X, C> for Rigid<F>where
F: DeltaEnergyOne<B, S, X, C>,
impl<B, S, X, C, F> DeltaEnergyOne<B, S, X, C> for Rigid<F>where
F: DeltaEnergyOne<B, S, X, C>,
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
Source§impl<B, S, X, C, F> DeltaEnergyRemove<B, S, X, C> for Rigid<F>where
F: DeltaEnergyRemove<B, S, X, C>,
impl<B, S, X, C, F> DeltaEnergyRemove<B, S, X, C> for Rigid<F>where
F: DeltaEnergyRemove<B, S, X, C>,
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
Source§impl<'de, F> Deserialize<'de> for Rigid<F>where
F: Deserialize<'de>,
impl<'de, F> Deserialize<'de> for Rigid<F>where
F: 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<F> MaximumInteractionRange for Rigid<F>where
F: MaximumInteractionRange,
impl<F> MaximumInteractionRange for Rigid<F>where
F: MaximumInteractionRange,
Source§fn maximum_interaction_range(&self) -> f64
fn maximum_interaction_range(&self) -> f64
Source§impl<V, B, S, X, C, F> NetBodyForceAndVirial<B, S, X, C> for Rigid<F>
impl<V, B, S, X, C, F> NetBodyForceAndVirial<B, S, X, C> for Rigid<F>
Source§fn net_body_force_and_virial(
&self,
microstate: &Microstate<B, S, X, C>,
body_index: usize,
) -> (V, V::Tensor)
fn net_body_force_and_virial( &self, microstate: &Microstate<B, S, X, C>, body_index: usize, ) -> (V, V::Tensor)
Compute the net force and virial on a body in the microstate.
The net force and virial on a body are the sums of the net forces and virials on all sites in the body:
\begin{align*}
\vec{F}_\mathrm{body} &= \sum_{\mathrm{site} \in \mathrm{body}} \vec{F}_\mathrm{site} \\
\mathbf{W}_\mathrm{body} &= \sum_{\mathrm{site} \in \mathrm{body}} \mathbf{W}_\mathrm{site} - \mathbf{F}_\mathrm{site} \otimes \left( \vec{r}_\mathrm{site}^\mathrm{global} - \vec{r}_{body}^\mathrm{global} \right) \\
\end{align*}where the net site forces and virials are given by F’s implementation of
NetSiteForceAndVirial, and $\vec{r}_\mathrm{site}^\mathrm{global}$ and $\vec{r}_\mathrm{body}^\mathrm{global}$
are the positions in the global frame of the site and body, respectively.
The second term in the virial summation is required to correct for the centripetal forces implicit in the rigid body constraint. For more information, see Glaser et al. 2020, especially equations 23 and 24 and algorithm 2.
§Example
use approxim::assert_relative_eq;
use hoomd_interaction::{
NetBodyForceAndVirial, PairwiseCutoff, Rigid, pairwise::Isotropic,
univariate::LennardJones,
};
use hoomd_linear_algebra::matrix::Matrix;
use hoomd_microstate::{
Body, Microstate,
boundary::Open,
property::{OrientedPoint, Point},
};
use hoomd_vector::{Cartesian, Versor};
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::single_site(
OrientedPoint {
position: Cartesian::from([0.0, 0.0, 0.0]),
orientation: Versor::default(),
},
Point::new(Cartesian::<3>::default()),
),
Body::single_site(
OrientedPoint {
position: Cartesian::from([1.0, 0.0, 0.0]),
orientation: Versor::default(),
},
Point::new(Cartesian::<3>::default()),
),
])?;
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.0,
sigma: 1.0,
};
let force_interaction_model = PairwiseCutoff(Isotropic {
interaction: lennard_jones,
r_cut: 2.5,
});
let rigid = Rigid(force_interaction_model);
let (body_force_0, body_virial_0) =
rigid.net_body_force_and_virial(µstate, 0);
let (body_force_1, body_virial_1) =
rigid.net_body_force_and_virial(µstate, 1);
assert_relative_eq!(body_force_0, Cartesian::from([-24.0, 0.0, 0.0]));
assert_eq!(
body_virial_0,
Matrix {
rows: [[12.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
}
);
assert_relative_eq!(body_force_1, Cartesian::from([24.0, 0.0, 0.0]));
assert_eq!(
body_virial_1,
Matrix {
rows: [[12.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
}
);Source§impl<V, B, S, X, C, F, R> NetBodyForceVirialAndTorque<B, S, X, C> for Rigid<F>where
V: Vector + Wedge + Default + Outer,
B: Transform<S> + Orientation<Rotation = R> + Position<Position = V>,
S: Position<Position = V>,
F: NetSiteForceVirialAndTorque<B, S, X, C, Force = V>,
R: Rotate<V>,
V::Bivector: Default + Add<Output = V::Bivector> + AddAssign,
V::Tensor: Default + AddAssign + Sub<Output = V::Tensor>,
impl<V, B, S, X, C, F, R> NetBodyForceVirialAndTorque<B, S, X, C> for Rigid<F>where
V: Vector + Wedge + Default + Outer,
B: Transform<S> + Orientation<Rotation = R> + Position<Position = V>,
S: Position<Position = V>,
F: NetSiteForceVirialAndTorque<B, S, X, C, Force = V>,
R: Rotate<V>,
V::Bivector: Default + Add<Output = V::Bivector> + AddAssign,
V::Tensor: Default + AddAssign + Sub<Output = V::Tensor>,
Source§fn net_body_force_virial_and_torque(
&self,
microstate: &Microstate<B, S, X, C>,
body_index: usize,
) -> (V, V::Tensor, V::Bivector)
fn net_body_force_virial_and_torque( &self, microstate: &Microstate<B, S, X, C>, body_index: usize, ) -> (V, V::Tensor, V::Bivector)
Compute the net force, virial, and torque on a body in the microstate.
The net force and virial on a body are the sums of the net forces and virials on all sites in the body, and the net torque is the sum of the torques resulting from those forces and intrinsic torques applied to the sites:
\begin{align*}
\vec{F}_\mathrm{body} &= \sum_{\mathrm{site} \in \mathrm{body}} \vec{F}_\mathrm{site} \\
\mathbf{W}_\mathrm{body} &= \sum_{\mathrm{site} \in \mathrm{body}} \mathbf{W}_\mathrm{site} - \mathbf{F}_\mathrm{site} \otimes \left( \vec{r}_\mathrm{site}^\mathrm{global} - \vec{r}_\mathrm{body}^\mathrm{global} \right) \\
\vec{\tau}_\mathrm{body} &= \sum_{\mathrm{site} \in \mathrm{body}} (\mathbf{q}_{body} \cdot \vec{r}_{body,site} \cdot \mathbf{q}_{body}^*) \wedge \vec{F}_\mathrm{site} + \vec{\tau}_\mathrm{site} \\
\end{align*}where $\mathbf{q}_{body}$ is the body’s orientation,
$\vec{r}_{body,site}$ is the position of site i in the body
frame, and the net site forces, virials, and torques are given by F’s
implementation of NetSiteForceVirialAndTorque.
The symbol $\wedge$ denotes the Wedge product. The resulting torque
$\vec{\tau}_{body}$ is in the system frame.
The second term in the virial summation is required to correct for the centripetal forces implicit in the rigid body constraint. For more information, see Glaser et al. 2020, especially equations 23 and 24 and algorithm 2.
§Example
use hoomd_interaction::{
NetBodyForceVirialAndTorque, PairwiseCutoff, Rigid,
pairwise::Isotropic, univariate::LennardJones,
};
use hoomd_linear_algebra::matrix::Matrix;
use hoomd_microstate::{
Body, Microstate,
boundary::Open,
property::{OrientedPoint, Point},
};
use hoomd_vector::{Cartesian, Versor};
use approxim::assert_relative_eq;
let mut microstate = Microstate::new();
microstate.extend_bodies([
Body::single_site(
OrientedPoint {
position: Cartesian::from([0.0, 2.0, 0.0]),
orientation: Versor::default(),
},
Point::new(Cartesian::from([0.0, -2.0, 0.0])),
),
Body::single_site(
OrientedPoint {
position: Cartesian::from([1.0, 0.0, 0.0]),
orientation: Versor::default(),
},
Point::new(Cartesian::<3>::default()),
),
])?;
let lennard_jones: LennardJones = LennardJones {
epsilon: 1.0,
sigma: 1.0,
};
let force_interaction_model = PairwiseCutoff(Isotropic {
interaction: lennard_jones,
r_cut: 2.5,
});
let rigid = Rigid(force_interaction_model);
let (body_force, body_virial, body_torque) =
rigid.net_body_force_virial_and_torque(µstate, 0);
assert_relative_eq!(body_force, Cartesian::from([-24.0, 0.0, 0.0]));
assert_relative_eq!(body_torque, Cartesian::from([0.0, 0.0, -48.0]));
assert_eq!(
body_virial,
Matrix {
rows: [[12.0, -48.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
}
);
let (body_force, body_virial, body_torque) =
rigid.net_body_force_virial_and_torque(µstate, 1);
assert_relative_eq!(body_force, Cartesian::from([24.0, 0.0, 0.0]));
assert_relative_eq!(body_torque, Cartesian::from([0.0, 0.0, 0.0]));
assert_eq!(
body_virial,
Matrix {
rows: [[12.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
}
);Source§impl<M, F> TotalEnergy<M> for Rigid<F>where
F: TotalEnergy<M>,
impl<M, F> TotalEnergy<M> for Rigid<F>where
F: TotalEnergy<M>,
impl<F> StructuralPartialEq for Rigid<F>
Auto Trait Implementations§
impl<F> Freeze for Rigid<F>where
F: Freeze,
impl<F> RefUnwindSafe for Rigid<F>where
F: RefUnwindSafe,
impl<F> Send for Rigid<F>where
F: Send,
impl<F> Sync for Rigid<F>where
F: Sync,
impl<F> Unpin for Rigid<F>where
F: Unpin,
impl<F> UnsafeUnpin for Rigid<F>where
F: UnsafeUnpin,
impl<F> UnwindSafe for Rigid<F>where
F: 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