use crate::pairwise::{MultipoleEnergy, MultipoleField, MultipolePotential};
use crate::units::*;
unit! {
system: uom::si;
quantity: uom::si::electric_charge_areal_density; @valence_per_angstrom_squared: 16.02176634; "e/Å2", "valence_per_angstrom_squared", "valence_per_angstrom_squared";
}
impl<T: MultipoleEnergy> MultipoleEnergySI for T {}
impl<T: MultipoleField> MultipoleFieldSI for T {}
impl<T: MultipolePotential> MultipolePotentialSI for T {}
pub trait MultipoleEnergySI: MultipolePotentialSI + MultipoleFieldSI {
fn ion_ion_energy(
&self,
charge1: crate::units::ElectricCharge,
charge2: crate::units::ElectricCharge,
distance: crate::units::Length,
) -> MolarEnergy {
use crate::units::*;
charge1 * MultipolePotentialSI::ion_potential(self, charge2, distance)
/ AmountOfSubstance::new::<mole>(1.0 / crate::AVOGADRO_CONSTANT)
}
}
pub trait MultipoleFieldSI: MultipoleField {
fn ion_field(
&self,
charge: crate::units::ElectricCharge,
distance: crate::units::Length,
) -> crate::units::ElectricField {
use crate::units::*;
use num_traits::Zero;
use uom::si::electric_charge_areal_density::ElectricChargeArealDensity;
let r = distance.get::<angstrom>();
if r >= self.cutoff() {
return ElectricField::zero();
}
let charge_areal_density = self.ion_field_scalar(charge.get::<elementary_charge>(), r);
ElectricChargeArealDensity::new::<valence_per_angstrom_squared>(charge_areal_density)
/ (4.0
* std::f64::consts::PI
* ElectricPermittivity::new::<farad_per_meter>(crate::VACUUM_ELECTRIC_PERMITTIVITY))
}
}
pub trait MultipolePotentialSI: MultipolePotential {
fn ion_potential(
&self,
charge: crate::units::ElectricCharge,
distance: crate::units::Length,
) -> crate::units::ElectricPotential {
use crate::units::*;
let z = charge.get::<elementary_charge>();
let r = distance.get::<angstrom>();
ElectricChargeLinearDensity::new::<valence_per_angstrom>(MultipolePotential::ion_potential(
self, z, r,
)) / (4.0
* std::f64::consts::PI
* ElectricPermittivity::new::<farad_per_meter>(crate::VACUUM_ELECTRIC_PERMITTIVITY))
}
}