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}