hoomd_mc/rotate.rs
1// Copyright (c) 2024-2026 The Regents of the University of Michigan.
2// Part of hoomd-rs, released under the BSD 3-Clause License.
3
4//! Implement Rotate
5
6use serde::{Deserialize, Serialize};
7use std::{fmt, marker::PhantomData};
8
9use hoomd_utility::valid::PositiveReal;
10
11mod angle;
12mod versor;
13
14/// Change the orientation of a body by a small amount.
15///
16/// [`Rotate`] proposes local trial moves that rotate the orientation of a body
17/// by a small amount. The [`maximum_rotation`] parameter sets the largest possible
18/// rotation.
19///
20/// When proposing trial moves for [`Angle`], [`maximum_rotation`] is measured
21/// in radians and the rotation is uniformly chosen between `-maximum_rotation`
22/// and `maximum_rotation`.
23///
24/// When proposing trial moves for [`Versor`], [`maximum_rotation`] is measured
25/// in radians and the width of a Gaussian distribution centered on 0.
26///
27/// [`Angle`]: hoomd_vector::Angle
28/// [`Versor`]: hoomd_vector::Versor
29/// [`maximum_rotation`]: Self::maximum_rotation
30///
31/// The generic type names are:
32/// * `O`: The type of the orientation to rotate.
33///
34/// # Example
35///
36/// ```
37/// use hoomd_mc::Rotate;
38/// use hoomd_vector::Angle;
39///
40/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
41/// let a = 0.1;
42/// let rotate = Rotate::<Angle>::with_maximum_rotation(a.try_into()?);
43/// # Ok(())
44/// # }
45/// ```
46#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
47pub struct Rotate<O> {
48 /// Limit the maximum rotation applied during a single trial move.
49 maximum_rotation: PositiveReal,
50 /// Mark the type of the orientation to be rotated.
51 marker: PhantomData<O>,
52}
53
54impl<P> Rotate<P> {
55 /// Construct a [`Rotate`] move with the given maximum rotation.
56 ///
57 /// # Example
58 ///
59 /// ```
60 /// use hoomd_mc::Rotate;
61 /// use hoomd_vector::Angle;
62 ///
63 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
64 /// let a = 0.1;
65 /// let rotate = Rotate::<Angle>::with_maximum_rotation(a.try_into()?);
66 /// # Ok(())
67 /// # }
68 /// ```
69 #[must_use]
70 #[inline]
71 pub fn with_maximum_rotation(maximum_rotation: PositiveReal) -> Self {
72 Self {
73 maximum_rotation,
74 marker: PhantomData,
75 }
76 }
77
78 /// Get the maximum rotation.
79 #[must_use]
80 #[inline]
81 pub fn maximum_rotation(&self) -> &PositiveReal {
82 &self.maximum_rotation
83 }
84
85 /// Get the maximum rotation.
86 #[inline]
87 pub fn maximum_rotation_mut(&mut self) -> &mut PositiveReal {
88 &mut self.maximum_rotation
89 }
90}
91
92impl<P> fmt::Display for Rotate<P> {
93 /// Format a [`Rotate`] as `{maximum_rotation}`.
94 #[inline]
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 self.maximum_rotation.fmt(f)
97 }
98}