use serde::{Deserialize, Serialize};
use crate::{MaximumInteractionRange, SitePairEnergy};
use hoomd_geometry::{BoundingSphereRadius, IntersectsAtGlobal};
use hoomd_microstate::property::{Orientation, Position};
use hoomd_vector::Metric;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct HardShape<G>(pub G);
impl<G, S, R, P> SitePairEnergy<S> for HardShape<G>
where
S: Position<Position = P> + Orientation<Rotation = R>,
G: IntersectsAtGlobal<G, P, R>,
{
#[inline]
fn site_pair_energy(&self, site_properties_i: &S, site_properties_j: &S) -> f64 {
if self.0.intersects_at_global(
&self.0,
site_properties_i.position(),
site_properties_i.orientation(),
site_properties_j.position(),
site_properties_j.orientation(),
) {
f64::INFINITY
} else {
0.0
}
}
#[inline]
fn site_pair_energy_initial(&self, _site_properties_i: &S, _site_properties_j: &S) -> f64 {
0.0
}
#[inline]
fn is_only_infinite_or_zero() -> bool {
true
}
}
impl<G> MaximumInteractionRange for HardShape<G>
where
G: BoundingSphereRadius,
{
#[inline]
fn maximum_interaction_range(&self) -> f64 {
self.0.bounding_sphere_radius().get() * 2.0
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct HardSphere {
pub diameter: f64,
}
impl<S, P> SitePairEnergy<S> for HardSphere
where
S: Position<Position = P>,
P: Metric,
{
#[inline]
fn site_pair_energy(&self, site_properties_i: &S, site_properties_j: &S) -> f64 {
if site_properties_i
.position()
.distance_squared(site_properties_j.position())
< self.diameter.powi(2)
{
f64::INFINITY
} else {
0.0
}
}
#[inline]
fn site_pair_energy_initial(&self, _site_properties_i: &S, _site_properties_j: &S) -> f64 {
0.0
}
#[inline]
fn is_only_infinite_or_zero() -> bool {
true
}
}
impl MaximumInteractionRange for HardSphere {
#[inline]
fn maximum_interaction_range(&self) -> f64 {
self.diameter
}
}