#![allow(
clippy::approx_constant,
clippy::items_after_test_module,
clippy::type_complexity
)]
#[derive(Debug, Clone, Copy)]
pub struct BondEnergyParams {
pub kb: f64,
pub r0: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct AngleEnergyParams {
pub ka: f64,
pub theta0: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct TorsionEnergyParams {
pub v1: f64,
pub v2: f64,
pub v3: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct VdwEnergyParams {
pub alpha_i: f64,
pub n_i: f64,
pub a_i: f64,
pub g_i: f64,
pub da: u8,
}
mod angle;
mod bond;
mod oop_stbn;
mod torsion;
mod vdw;
pub use angle::{MMFF94_ANGLE_ENERGY, mmff94_angle_energy};
pub use bond::{MMFF94_BOND_ENERGY, mmff94_bond_energy};
pub use oop_stbn::{MMFF94_OOP, MMFF94_STBN, mmff94_oop, mmff94_stbn};
pub use torsion::{MMFF94_TORSION_ENERGY, mmff94_torsion_energy};
pub use vdw::{MMFF94_VDW_ENERGY, mmff94_vdw_combined, mmff94_vdw_energy};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn table_sizes() {
assert_eq!(MMFF94_BOND_ENERGY.len(), 493);
assert_eq!(MMFF94_ANGLE_ENERGY.len(), 2245);
assert_eq!(MMFF94_TORSION_ENERGY.len(), 926);
assert_eq!(MMFF94_VDW_ENERGY.len(), 95);
}
#[test]
fn bond_cc_sp3() {
let p = mmff94_bond_energy(0, 1, 1).expect("C-C sp3 bond");
assert!((p.r0 - 1.508).abs() < 0.001, "r0={}", p.r0);
assert!((p.kb - 4.258).abs() < 0.001, "kb={}", p.kb);
}
#[test]
fn bond_ch_sp3() {
let p = mmff94_bond_energy(0, 1, 5).expect("C-H sp3 bond");
assert!((p.r0 - 1.093).abs() < 0.001, "r0={}", p.r0);
assert!((p.kb - 4.766).abs() < 0.001, "kb={}", p.kb);
}
#[test]
fn bond_symmetric() {
assert_eq!(
mmff94_bond_energy(0, 1, 2).map(|p| p.r0),
mmff94_bond_energy(0, 2, 1).map(|p| p.r0),
);
}
#[test]
fn angle_ccc_sp3() {
let p = mmff94_angle_energy(0, 1, 1, 1).expect("C-C-C sp3 angle");
assert!((p.theta0 - 109.608).abs() < 0.1, "theta0={}", p.theta0);
assert!(p.ka > 0.5, "ka={}", p.ka);
}
#[test]
fn angle_symmetric() {
let a = mmff94_angle_energy(0, 1, 1, 2).map(|p| p.theta0);
let b = mmff94_angle_energy(0, 2, 1, 1).map(|p| p.theta0);
assert_eq!(a, b, "angle lookup not symmetric: {:?} vs {:?}", a, b);
}
#[test]
fn torsion_cccc() {
let p = mmff94_torsion_energy(0, 1, 1, 1, 1).expect("C-C-C-C torsion");
assert!((p.v1 - 0.103).abs() < 0.001, "v1={}", p.v1);
assert!((p.v2 - 0.681).abs() < 0.001, "v2={}", p.v2);
assert!((p.v3 - 0.332).abs() < 0.001, "v3={}", p.v3);
}
#[test]
fn torsion_hcch() {
let p = mmff94_torsion_energy(0, 5, 1, 1, 5);
assert!(p.is_some(), "H-C-C-H torsion should be found");
}
#[test]
fn torsion_wildcard_fallback() {
let _ = mmff94_torsion_energy(0, 99, 1, 1, 99);
}
#[test]
fn vdw_carbon_sp3() {
let p = mmff94_vdw_energy(1).expect("sp3 C vdW");
assert!(p.alpha_i > 0.0, "alpha_i={}", p.alpha_i);
assert!(p.n_i > 0.0, "n_i={}", p.n_i);
}
#[test]
fn vdw_combined_cc() {
let (r_star, eps) = mmff94_vdw_combined(1, 1).expect("C-C vdW combined");
assert!(r_star > 2.0 && r_star < 6.0, "r_star={}", r_star);
assert!(eps > 0.0, "eps={}", eps);
}
}