use crate::{
math::{Quantity, Scalar},
physics::molecular::potential::Potential,
units::{Energy, Force, ForcePerLength, Length, ReciprocalForcePerLength, Stress},
};
#[derive(Clone, Debug)]
pub struct Harmonic {
pub rest_length: Scalar,
pub stiffness: Scalar,
}
impl Potential for Harmonic {
fn energy(&self, length: Quantity<Length>) -> Quantity<Energy> {
let delta = length - self.rest_length();
0.5 * self.stiffness_quantity() * (delta * delta)
}
fn force(&self, length: Quantity<Length>) -> Quantity<Force> {
self.stiffness_quantity() * (length - self.rest_length())
}
fn forces_at_energy(&self, energy: Quantity<Energy>) -> [Quantity<Force>; 2] {
let force = Quantity::new((2.0 * self.stiffness * energy.value()).sqrt());
[force, -force]
}
fn stiffness(&self, _length: Quantity<Length>) -> Quantity<ForcePerLength> {
self.stiffness_quantity()
}
fn anharmonicity(&self, _length: Quantity<Length>) -> Quantity<Stress> {
Quantity::new(0.0)
}
fn extension(&self, force: Quantity<Force>) -> Quantity<Length> {
force / self.stiffness_quantity()
}
fn extensions_at_energy(&self, energy: Quantity<Energy>) -> [Quantity<Length>; 2] {
let extension = Quantity::new((2.0 * energy.value() / self.stiffness).sqrt());
[extension, -extension]
}
fn compliance(&self, _force: Quantity<Force>) -> Quantity<ReciprocalForcePerLength> {
1.0 / self.stiffness_quantity()
}
fn peak(&self) -> Quantity<Length> {
Quantity::new(Scalar::INFINITY)
}
fn peak_force(&self) -> Quantity<Force> {
Quantity::new(Scalar::INFINITY)
}
fn rest_length(&self) -> Quantity<Length> {
Quantity::new(self.rest_length)
}
}
impl Harmonic {
fn stiffness_quantity(&self) -> Quantity<ForcePerLength> {
Quantity::new(self.stiffness)
}
}