pub struct QuickInsert<D> { /* private fields */ }Expand description
Quickly add bodies to the microstate with random configurations.
QuickInsert allows you to quickly insert many bodies into the microstate.
It does so by breaking detailed balance, so you should use it only during
the initialization phase of your simulation where you prepare a microstate
for later equilibration.
QuickInsert works best with the OverlapPenalty potential that
allows sites to overlap a small amount and for trial moves to partially
reduce that overlap.
As a algorithm, QuickInsert is more than just a trial move, it
stores internal state to track its progress. Therefore, you should only
use a given QuickInsert on one Microstate. After initialization,
a QuickInsert knows the target number of bodies it should add a
distribution that places those bodies in the simulation boundary. New
QuickInsert instances start in the running state.
When you apply a running QuickInsert to a microstate, it:
- Checks the total energy of the given Hamiltonian.
- If the total energy is less than or equal to zero and there are still bodies to insert, generate a random body and attempt to insert it into the microstate. Reject any insertion that would result in an infinite energy. Accept in all other cases.
- Repeat step 2 until inserted bodies overlap with others
allowed_overlapstimes, the target number of bodies have been inserted, or a total oftargetattempts have been made during this call, whichever comes first.
When both target bodies have been inserted and the energy is
0, QuickInsert transitions to the complete state. When complete,
is_complete returns true and apply returns immediately.
For spherical particles, QuickInsert combined with OverlapPenalty
can achieve a packing fraction of 56% in 3D and 72% in 2D. You might achieve
slightly higher densities if you are willing to run many steps, though
QuickCompress is a better solution.
The generic type names are:
D: The body distribution.
§Example
use hoomd_geometry::shape::Rectangle;
use hoomd_mc::{QuickInsert, UniformIn};
use hoomd_microstate::property::Point;
use hoomd_vector::Cartesian;
let rectangle = Rectangle::with_equal_edges(10.0.try_into()?);
let distribution = UniformIn {
boundary: rectangle,
template_sites: vec![Point::<Cartesian<2>>::default()],
};
let mut quick_insert = QuickInsert::new(distribution, 256);Implementations§
Source§impl<D> QuickInsert<D>
impl<D> QuickInsert<D>
Sourcepub fn new(distribution: D, target: usize) -> Self
pub fn new(distribution: D, target: usize) -> Self
Build a new quick insert algorithm.
After construction, the QuickInsert starts in a running state. On
successive calls to apply, it will attempt to insert target bodies into
the microstate randomly sampled from the given distribution. The default
number of allowed_overlaps is target/8.
§Example
use hoomd_geometry::shape::Rectangle;
use hoomd_mc::{QuickInsert, UniformIn};
use hoomd_microstate::property::Point;
use hoomd_vector::Cartesian;
let rectangle = Rectangle::with_equal_edges(10.0.try_into()?);
let distribution = UniformIn {
boundary: rectangle,
template_sites: vec![Point::<Cartesian<2>>::default()],
};
let quick_insert = QuickInsert::new(distribution, 256);Sourcepub fn is_complete(&self) -> bool
pub fn is_complete(&self) -> bool
Check if the quick insert algorithm is complete.
QuickInsert completes after it has inserted all target bodies and
the total energy of the system is less than or equal to 0. When using the
recommended OverlapPenalty potential, this means that that there are no
overlaps between any particles.
§Example
use hoomd_geometry::shape::Rectangle;
use hoomd_mc::{QuickInsert, UniformIn};
use hoomd_microstate::property::Point;
use hoomd_vector::Cartesian;
let rectangle = Rectangle::with_equal_edges(10.0.try_into()?);
let distribution = UniformIn {
boundary: rectangle,
template_sites: vec![Point::<Cartesian<2>>::default()],
};
let quick_insert = QuickInsert::new(distribution, 256);
let complete = quick_insert.is_complete();
assert!(!complete);Sourcepub fn target(&self) -> usize
pub fn target(&self) -> usize
The target number of bodies to insert.
§Example
use hoomd_geometry::shape::Rectangle;
use hoomd_mc::{QuickInsert, UniformIn};
use hoomd_microstate::property::Point;
use hoomd_vector::Cartesian;
let rectangle = Rectangle::with_equal_edges(10.0.try_into()?);
let distribution = UniformIn {
boundary: rectangle,
template_sites: vec![Point::<Cartesian<2>>::default()],
};
let quick_insert = QuickInsert::new(distribution, 256);
let target = quick_insert.target();
assert_eq!(target, 256);Sourcepub fn apply<P, B, S, X, C, H>(
&mut self,
microstate: &mut Microstate<B, S, X, C>,
hamiltonian: &H,
) -> Countwhere
P: Copy,
B: Position<Position = P> + Transform<S>,
S: Position<Position = P> + Default,
X: PointUpdate<P, SiteKey>,
D: BodyDistribution<Body<B, S>>,
H: DeltaEnergyInsert<B, S, X, C> + TotalEnergy<Microstate<B, S, X, C>>,
C: Wrap<B> + Wrap<S> + GenerateGhosts<S>,
pub fn apply<P, B, S, X, C, H>(
&mut self,
microstate: &mut Microstate<B, S, X, C>,
hamiltonian: &H,
) -> Countwhere
P: Copy,
B: Position<Position = P> + Transform<S>,
S: Position<Position = P> + Default,
X: PointUpdate<P, SiteKey>,
D: BodyDistribution<Body<B, S>>,
H: DeltaEnergyInsert<B, S, X, C> + TotalEnergy<Microstate<B, S, X, C>>,
C: Wrap<B> + Wrap<S> + GenerateGhosts<S>,
Apply the quick insert algorithm to a microstate.
Combine QuickInsert::apply with local trial moves that translate and/or
rotate bodies by small amounts to relieve the stress caused by inserting
overlapping sites.
§Example
Hard spheres
use hoomd_geometry::shape::Rectangle;
use hoomd_interaction::{
PairwiseCutoff,
pairwise::Isotropic,
univariate::{Expanded, OverlapPenalty},
};
use hoomd_mc::{QuickInsert, Sweep, Translate, Trial, UniformIn};
use hoomd_microstate::{
Body, Microstate, boundary::Periodic, property::Point,
};
use hoomd_simulation::macrostate::Isothermal;
use hoomd_vector::Cartesian;
let rectangle = Rectangle::with_equal_edges(10.0.try_into()?);
let distribution = UniformIn {
boundary: rectangle.clone(),
template_sites: vec![Point::default()],
};
let mut quick_insert = QuickInsert::new(distribution, 256);
let translate = Translate::with_maximum_distance(0.1.try_into()?);
let mut translate_sweep = Sweep(translate);
let pairwise_cutoff = PairwiseCutoff(Isotropic {
interaction: Expanded {
delta: 1.0,
f: OverlapPenalty::default(),
},
r_cut: 1.0,
});
let macrostate = Isothermal { temperature: 1.0 };
let mut microstate = Microstate::builder()
.boundary(Periodic::new(1.0, rectangle)?)
.bodies([Body::point(Cartesian::from([0.0, 0.0]))])
.try_build()?;
quick_insert.apply(&mut microstate, &pairwise_cutoff);
translate_sweep.apply(&mut microstate, &pairwise_cutoff, ¯ostate);
assert!(microstate.bodies().len() > 1);Trait Implementations§
Source§impl<D: Clone> Clone for QuickInsert<D>
impl<D: Clone> Clone for QuickInsert<D>
Source§fn clone(&self) -> QuickInsert<D>
fn clone(&self) -> QuickInsert<D>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<D: Debug> Debug for QuickInsert<D>
impl<D: Debug> Debug for QuickInsert<D>
Source§impl<'de, D> Deserialize<'de> for QuickInsert<D>where
D: Deserialize<'de>,
impl<'de, D> Deserialize<'de> for QuickInsert<D>where
D: 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<D: PartialEq> PartialEq for QuickInsert<D>
impl<D: PartialEq> PartialEq for QuickInsert<D>
Source§impl<D> Serialize for QuickInsert<D>where
D: Serialize,
impl<D> Serialize for QuickInsert<D>where
D: Serialize,
impl<D> StructuralPartialEq for QuickInsert<D>
Auto Trait Implementations§
impl<D> Freeze for QuickInsert<D>where
D: Freeze,
impl<D> RefUnwindSafe for QuickInsert<D>where
D: RefUnwindSafe,
impl<D> Send for QuickInsert<D>where
D: Send,
impl<D> Sync for QuickInsert<D>where
D: Sync,
impl<D> Unpin for QuickInsert<D>where
D: Unpin,
impl<D> UnwindSafe for QuickInsert<D>where
D: 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