#[cfg(test)]
mod test;
mod harmonic;
mod morse;
pub use harmonic::Harmonic;
pub use morse::Morse;
use crate::{math::Scalar, physics::BOLTZMANN_CONSTANT};
use std::fmt::Debug;
pub trait Potential
where
Self: Clone + Debug,
{
fn energy(&self, length: Scalar) -> Scalar;
fn nondimensional_energy(&self, nondimensional_length: Scalar, temperature: Scalar) -> Scalar {
let length = self.rest_length() * nondimensional_length;
self.energy(length) / BOLTZMANN_CONSTANT / temperature
}
fn force(&self, length: Scalar) -> Scalar;
fn nondimensional_force(&self, nondimensional_length: Scalar, temperature: Scalar) -> Scalar {
let length = self.rest_length() * nondimensional_length;
self.force(length) * self.rest_length() / BOLTZMANN_CONSTANT / temperature
}
fn stiffness(&self, length: Scalar) -> Scalar;
fn nondimensional_stiffness(
&self,
nondimensional_length: Scalar,
temperature: Scalar,
) -> Scalar {
let length = self.rest_length() * nondimensional_length;
self.stiffness(length) * self.rest_length().powi(2) / BOLTZMANN_CONSTANT / temperature
}
fn anharmonicity(&self, length: Scalar) -> Scalar;
fn nondimensional_anharmonicity(
&self,
nondimensional_length: Scalar,
temperature: Scalar,
) -> Scalar {
let length = self.rest_length() * nondimensional_length;
self.anharmonicity(length) * self.rest_length().powi(3) / BOLTZMANN_CONSTANT / temperature
}
fn legendre(&self, force: Scalar) -> Scalar {
let extension = self.extension(force);
let length = self.rest_length() + extension;
self.energy(length) - force * extension
}
fn nondimensional_legendre(&self, nondimensional_force: Scalar, temperature: Scalar) -> Scalar {
let force = nondimensional_force / self.rest_length() * BOLTZMANN_CONSTANT * temperature;
self.legendre(force) / BOLTZMANN_CONSTANT / temperature
}
fn extension(&self, force: Scalar) -> Scalar;
fn nondimensional_extension(
&self,
nondimensional_force: Scalar,
temperature: Scalar,
) -> Scalar {
let force = nondimensional_force / self.rest_length() * BOLTZMANN_CONSTANT * temperature;
self.extension(force) / self.rest_length()
}
fn compliance(&self, force: Scalar) -> Scalar;
fn nondimensional_compliance(
&self,
nondimensional_force: Scalar,
temperature: Scalar,
) -> Scalar {
let force = nondimensional_force / self.rest_length() * BOLTZMANN_CONSTANT * temperature;
self.compliance(force) / self.rest_length().powi(2) * BOLTZMANN_CONSTANT * temperature
}
fn peak(&self) -> Scalar;
fn peak_force(&self) -> Scalar;
fn rest_length(&self) -> Scalar;
}