Skip to main content

hoomd_interaction/pairwise/
isotropic.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 Isotropic
5
6use serde::{Deserialize, Serialize};
7
8use crate::{MaximumInteractionRange, SitePairEnergy, univariate::UnivariateEnergy};
9use hoomd_microstate::property::Position;
10use hoomd_vector::Metric;
11
12/// Compute isotropic interactions between a pair of sites.
13///
14/// [`Isotropic`] provides a single implementation that computes pairwise
15/// interactions that are a function only of the distance between sites. It
16/// fills the gap between traits like [`SitePairEnergy`] which operates on
17/// site properties and [`UnivariateEnergy`] which is a function only of the
18/// separation distance.
19///
20/// Use [`Isotropic`] with [`PairwiseCutoff`] in MD and MC simulations.
21///
22/// [`PairwiseCutoff`]: crate::PairwiseCutoff
23/// # Example
24///
25/// ```
26/// use hoomd_interaction::{
27///     SitePairEnergy, pairwise::Isotropic, univariate::LennardJones,
28/// };
29/// use hoomd_microstate::property::Point;
30/// use hoomd_vector::Cartesian;
31///
32/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
33/// let a = Point {
34///     position: Cartesian::from([0.0, 0.0]),
35/// };
36/// let b = Point {
37///     position: Cartesian::from([0.0, 2.0 * 2.0_f64.powf(1.0 / 6.0)]),
38/// };
39///
40/// let lennard_jones: LennardJones = LennardJones {
41///     epsilon: 1.5,
42///     sigma: 2.0,
43/// };
44/// let lennard_jones = Isotropic {
45///     interaction: lennard_jones,
46///     r_cut: 2.5,
47/// };
48///
49/// let energy = lennard_jones.site_pair_energy(&a, &b);
50/// assert_eq!(energy, -1.5);
51/// # Ok(())
52/// # }
53/// ```
54#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
55pub struct Isotropic<E> {
56    /// The site-site interaction.
57    pub interaction: E,
58    /// Maximum distance between two interacting sites.
59    pub r_cut: f64,
60}
61
62impl<P, S, E> SitePairEnergy<S> for Isotropic<E>
63where
64    S: Position<Position = P>,
65    P: Metric,
66    E: UnivariateEnergy,
67{
68    #[inline]
69    fn site_pair_energy(&self, site_properties_i: &S, site_properties_j: &S) -> f64 {
70        let r = site_properties_i
71            .position()
72            .distance(site_properties_j.position());
73        if r >= self.r_cut {
74            return 0.0;
75        }
76
77        self.interaction.energy(r)
78    }
79}
80
81impl<E> MaximumInteractionRange for Isotropic<E> {
82    #[inline]
83    fn maximum_interaction_range(&self) -> f64 {
84        self.r_cut
85    }
86}