Skip to main content

conspire/physics/molecular/potential/harmonic/
mod.rs

1use crate::{
2    math::{Quantity, Scalar},
3    physics::molecular::potential::Potential,
4    units::{Energy, Force, ForcePerLength, Length, ReciprocalForcePerLength, Stress},
5};
6
7/// The harmonic potential.
8#[derive(Clone, Debug)]
9pub struct Harmonic {
10    /// The rest length $`x_0`$.
11    pub rest_length: Scalar,
12    /// The stiffness $`k`$.
13    pub stiffness: Scalar,
14}
15
16impl Potential for Harmonic {
17    /// ```math
18    /// u(x) = \frac{1}{2}\,k(x - x_0)^2
19    /// ```
20    fn energy(&self, length: Quantity<Length>) -> Quantity<Energy> {
21        let delta = length - self.rest_length();
22        0.5 * self.stiffness_quantity() * (delta * delta)
23    }
24    /// ```math
25    /// f(x) = k(x - x_0)
26    /// ```
27    fn force(&self, length: Quantity<Length>) -> Quantity<Force> {
28        self.stiffness_quantity() * (length - self.rest_length())
29    }
30    /// ```math
31    /// f = \pm\sqrt{2ku}
32    /// ```
33    fn forces_at_energy(&self, energy: Quantity<Energy>) -> [Quantity<Force>; 2] {
34        let force = Quantity::new((2.0 * self.stiffness * energy.value()).sqrt());
35        [force, -force]
36    }
37    /// ```math
38    /// k(x) = k
39    /// ```
40    fn stiffness(&self, _length: Quantity<Length>) -> Quantity<ForcePerLength> {
41        self.stiffness_quantity()
42    }
43    /// ```math
44    /// h(x) = 0.0
45    /// ```
46    fn anharmonicity(&self, _length: Quantity<Length>) -> Quantity<Stress> {
47        Quantity::new(0.0)
48    }
49    /// ```math
50    /// \Delta x(f) = \frac{f}{k}
51    /// ```
52    fn extension(&self, force: Quantity<Force>) -> Quantity<Length> {
53        force / self.stiffness_quantity()
54    }
55    /// ```math
56    /// \Delta x = \pm\sqrt{\frac{2u}{k}}
57    /// ```
58    fn extensions_at_energy(&self, energy: Quantity<Energy>) -> [Quantity<Length>; 2] {
59        let extension = Quantity::new((2.0 * energy.value() / self.stiffness).sqrt());
60        [extension, -extension]
61    }
62    /// ```math
63    /// c(f) = \frac{1}{k}
64    /// ```
65    fn compliance(&self, _force: Quantity<Force>) -> Quantity<ReciprocalForcePerLength> {
66        1.0 / self.stiffness_quantity()
67    }
68    /// ```math
69    /// \text{arg max }u(x) = \infty
70    /// ```
71    fn peak(&self) -> Quantity<Length> {
72        Quantity::new(Scalar::INFINITY)
73    }
74    /// ```math
75    /// f(x_\mathrm{peak}) = \infty
76    /// ```
77    fn peak_force(&self) -> Quantity<Force> {
78        Quantity::new(Scalar::INFINITY)
79    }
80    /// ```math
81    /// \text{arg min }u(x) = x_0
82    /// ```
83    fn rest_length(&self) -> Quantity<Length> {
84        Quantity::new(self.rest_length)
85    }
86}
87
88impl Harmonic {
89    /// Returns the stiffness.
90    fn stiffness_quantity(&self) -> Quantity<ForcePerLength> {
91        Quantity::new(self.stiffness)
92    }
93}