hoomd_interaction/
univariate.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//! Interactions as a function of one variable.
5
6mod boxcar;
7mod expanded;
8mod harmonic;
9mod harmonic_repulsion;
10mod lennard_jones;
11mod lennard_jones_gauss;
12mod overlap_penalty;
13mod shifted;
14mod weeks_chandler_anderson;
15mod xplor;
16
17pub use boxcar::Boxcar;
18pub use expanded::Expanded;
19pub use harmonic::Harmonic;
20pub use harmonic_repulsion::HarmonicRepulsion;
21pub use lennard_jones::LennardJones;
22pub use lennard_jones_gauss::LennardJonesGauss;
23pub use overlap_penalty::OverlapPenalty;
24pub use shifted::Shifted;
25pub use weeks_chandler_anderson::WeeksChandlerAnderson;
26pub use xplor::Xplor;
27
28/// Computes energy as a function of one variable.
29///
30/// A univariate energy is function only of one variable. Often, this is
31/// distance between two points: $`U(r)`$, but it could be a distance from a
32/// point to a surface, or any other single variable.
33///
34/// Implement [`UnivariateEnergy`] on a custom type or use one of the provided
35/// potentials in [`univariate`] in MD or MC simulations.
36///
37/// * Use [`UnivariateEnergy`] in combination with [`Isotropic`] and
38///   [`PairwiseCutoff`] to model pairwise interactions between sites.
39///
40/// [`univariate`]: crate::univariate
41/// [`Isotropic`]: crate::pairwise::Isotropic
42/// [`PairwiseCutoff`]: crate::PairwiseCutoff
43///
44/// # Examples
45///
46/// Set a custom potential using a closure:
47/// ```
48/// use hoomd_interaction::univariate::UnivariateEnergy;
49///
50/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
51/// let a = 2.0;
52/// let custom = |r: f64| a / (r.powi(12));
53///
54/// let energy = custom.energy(1.0);
55/// assert_eq!(energy, 2.0);
56/// # Ok(())
57/// # }
58/// ```
59///
60/// Implement a custom potential via a type:
61/// ```
62/// use hoomd_interaction::univariate::UnivariateEnergy;
63///
64/// struct Custom {
65///     a: f64,
66/// }
67///
68/// impl UnivariateEnergy for Custom {
69///     fn energy(&self, r: f64) -> f64 {
70///         self.a / r.powi(12)
71///     }
72/// }
73///
74/// let custom = Custom { a: 2.0 };
75///
76/// let energy = custom.energy(1.0);
77/// assert_eq!(energy, 2.0);
78/// ```
79pub trait UnivariateEnergy {
80    /// Compute the energy as a function of one variable.
81    /// ```math
82    /// U(r)
83    /// ```
84    #[must_use]
85    fn energy(&self, r: f64) -> f64;
86}
87
88impl<F> UnivariateEnergy for F
89where
90    F: Fn(f64) -> f64,
91{
92    #[inline]
93    fn energy(&self, r: f64) -> f64 {
94        self(r)
95    }
96}
97
98/// Computes force as a function of one variable.
99///
100/// An univariate force is a function only one variable. Often, this is
101/// distance between two points: $`f(r)`$, but it could be a distance from a
102/// point to a surface, or any other single variable. The direction of the
103/// resulting force vector depends on how the [`UnivariateForce`] is applied.
104///
105/// Implement [`UnivariateForce`] on a custom type or use one of the provided
106/// forces in [`univariate`] in MD simulations.
107///
108/// [`univariate`]: crate::univariate
109pub trait UnivariateForce {
110    /// Compute force as a function of one variable.
111    ///
112    /// When the force is associated with a potential energy [`UnivariateEnergy`],
113    /// it must follow:
114    /// ```math
115    /// -\frac{\mathrm{d} U}{\mathrm{d} r}
116    /// ```
117    #[must_use]
118    fn force(&self, r: f64) -> f64;
119}