Skip to main content

hoomd_microstate/
property.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//! Traits that describe body and/or site properties a a selection types that implement them.
5//!
6//! See the [crate-level documentation](crate) for an overview of how body and site
7//! properties interact with [`Microstate`](crate::Microstate) and model methods.
8//!
9//! # Provided types
10//!
11//! The structs provided in `property` may be used as [`Body`](crate::Body) and/or
12//! [`Site`](crate::Site) properties.
13//!
14//! [`Point`] represents a position in space:
15//! ```
16//! use hoomd_microstate::property::Point;
17//! use hoomd_vector::Cartesian;
18//!
19//! let point = Point::new(Cartesian::from([1.0, -3.0]));
20//! ```
21//!
22//! [`OrientedPoint`] contains both the position and orientation of an extended body:
23//! ```
24//! use hoomd_microstate::property::OrientedPoint;
25//! use hoomd_vector::{Angle, Cartesian};
26//!
27//! let point = OrientedPoint {
28//!     position: Cartesian::from([1.0, -3.0]),
29//!     orientation: Angle::from(1.2),
30//! };
31//! ```
32//!
33//! # Custom property types
34//!
35//! When none of the provided types meets your needs, you can define a custom type.
36//! You must implement [`Position`] for your type and may implement other
37//! property traits as needed by your model.
38//!
39//! For example, this `Custom` type implements [`Position`], [`Orientation`],
40//! and has a `custom` field. The full site properties type is available when
41//! hoomd-rs computes interactions on sites, so you can use the custom fields
42//! in your own custom interaction potentials.
43//!
44//! ```
45//! use hoomd_microstate::property::{Orientation, Position};
46//! use hoomd_vector::{Cartesian, Versor};
47//!
48//! #[derive(Position, Orientation)]
49//! struct Custom {
50//!     position: Cartesian<3>,
51//!     orientation: Versor,
52//!     custom: f64,
53//! }
54//! ```
55//!
56//! ## Transformations
57//!
58//! Implement `Transform` to take sites from the body frame to the system frame.
59//! Typically, this involves transforming position and orientation while leaving
60//! all other fields unchanged. The three most common implementations of `Transform`
61//! follow. All these examples are in 3D. To convert to 2D, replace `Cartesian<3>`
62//! with `Cartesian<2>` and `Versor` with `Angle`.
63//!
64//! Non-oriented bodies and sites (i.e. point particles or non-rotating rigid bodies):
65//! ```
66//! use hoomd_microstate::{
67//!     Transform,
68//!     property::{Point, Position},
69//! };
70//! use hoomd_vector::Cartesian;
71//!
72//! #[derive(Position)]
73//! struct Custom {
74//!     position: Cartesian<3>,
75//!     custom: f64,
76//! }
77//!
78//! impl Transform<Custom> for Point<Cartesian<3>> {
79//!     fn transform(&self, site_properties: &Custom) -> Custom {
80//!         Custom {
81//!             position: self.position + site_properties.position,
82//!             ..*site_properties
83//!         }
84//!     }
85//! }
86//! ```
87//!
88//! Oriented bodies and non-oriented sites (i.e. rotating rigid bodies with
89//! isotropic site-site interactions):
90//! ```
91//! use hoomd_microstate::{
92//!     Transform,
93//!     property::{OrientedPoint, Position},
94//! };
95//! use hoomd_vector::{Cartesian, Rotate, Rotation, Versor};
96//!
97//! #[derive(Position)]
98//! struct Custom {
99//!     position: Cartesian<3>,
100//!     custom: f64,
101//! }
102//!
103//! impl Transform<Custom> for OrientedPoint<Cartesian<3>, Versor> {
104//!     fn transform(&self, site_properties: &Custom) -> Custom {
105//!         Custom {
106//!             position: self.position
107//!                 + self.orientation.rotate(&site_properties.position),
108//!             ..*site_properties
109//!         }
110//!     }
111//! }
112//! ```
113//!
114//! Oriented bodies and oriented sites (i.e. rotating rigid bodies with
115//! anisotropic site-site interactions):
116//! ```
117//! use hoomd_microstate::{
118//!     Transform,
119//!     property::{Orientation, OrientedPoint, Position},
120//! };
121//! use hoomd_vector::{Cartesian, Rotate, Rotation, Versor};
122//!
123//! #[derive(Position, Orientation)]
124//! struct Custom {
125//!     position: Cartesian<3>,
126//!     orientation: Versor,
127//!     custom: f64,
128//! }
129//!
130//! impl Transform<Custom> for OrientedPoint<Cartesian<3>, Versor> {
131//!     fn transform(&self, site_properties: &Custom) -> Custom {
132//!         Custom {
133//!             position: self.position
134//!                 + self.orientation.rotate(&site_properties.position),
135//!             orientation: self
136//!                 .orientation
137//!                 .combine(&site_properties.orientation),
138//!             ..*site_properties
139//!         }
140//!     }
141//! }
142//! ```
143
144mod point;
145pub use point::Point;
146
147mod oriented_point;
148pub use oriented_point::OrientedPoint;
149
150mod oriented_hyperbolic_point;
151pub use oriented_hyperbolic_point::OrientedHyperbolicPoint;
152
153pub use hoomd_derive::{Orientation, Position};
154
155/// Locate sites and bodies.
156///
157/// When applied to site properties, [`Position`] describes the location of the site
158/// relative to the origin of the body. In other words, it is the position of the
159/// site in the body reference frame.
160///
161/// When applied to body properties [`Position`] describes the location of the body
162/// relative to the origin of the system coordinate system. In other words, it is
163/// the position of the body's origin in the system reference frame.
164///
165/// # Units
166///
167/// Position vectors have units of *\[length\]*.
168///
169/// # Derive macro
170///
171/// Use the [`Position`](macro@Position) derive macro to automatically implement
172/// the `Position` trait on a type. The type **must** have a field named `position`.
173/// ```
174/// use hoomd_microstate::property::Position;
175/// use hoomd_vector::Cartesian;
176///
177/// #[derive(Position)]
178/// struct Custom {
179///     position: Cartesian<3>,
180/// }
181/// ```
182pub trait Position {
183    /// Every position is located in this vector space.
184    type Position;
185
186    /// The position of this body or site *\[length\]*.
187    fn position(&self) -> &Self::Position;
188
189    /// The mutable position of this body or site *\[length\]*.
190    fn position_mut(&mut self) -> &mut Self::Position;
191}
192
193/// Rotate sites and bodies.
194///
195/// When applied to site properties, [`Orientation`] describes the rotation from the
196/// site's local coordinates to the body frame.
197///
198/// When applied to body properties, [`Orientation`] describes the rotation from the
199/// body frame to the system.
200///
201/// # Units
202///
203/// The units of [`Orientation`] depend on the representation chosen for `R`.
204/// For example, [`hoomd_vector::Angle`] has units of radians while
205/// [`hoomd_vector::Versor`] is unitless.
206///
207/// # Derive macro
208///
209/// Use the [`Orientation`](macro@Orientation) derive macro to automatically implement
210/// the `Orientation` trait on a type. The type **must** have a field named `orientation`.
211/// ```
212/// use hoomd_microstate::property::Orientation;
213/// use hoomd_vector::Versor;
214///
215/// #[derive(Orientation)]
216/// struct Custom {
217///     orientation: Versor,
218/// }
219/// ```
220pub trait Orientation {
221    /// Type that can express the orientation of a body or site.
222    type Rotation;
223
224    /// The orientation of this body or site.
225    fn orientation(&self) -> &Self::Rotation;
226
227    /// The orientation of this body or site (mutable).
228    fn orientation_mut(&mut self) -> &mut Self::Rotation;
229}