Skip to content

Commit 014245b

Browse files
committed
test(potentials): Add reflection parameters and enhance Buckingham potential tests
1 parent 4697107 commit 014245b

1 file changed

Lines changed: 118 additions & 12 deletions

File tree

  • src/potentials/nonbonded

src/potentials/nonbonded/vdw.rs

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,23 @@ mod tests {
513513
mod buckingham {
514514
use super::*;
515515

516-
fn params() -> (f64, f64, f64, f64) {
517-
(BUCK_A, BUCK_B, BUCK_C, BUCK_FUSION_SQ)
516+
/// Computes the local maximum of the Buckingham potential via Newton's method.
517+
fn reflection_params(a: f64, b: f64, c: f64) -> (f64, f64) {
518+
let mut r = 1.0_f64;
519+
for _ in 0..100 {
520+
let exp_term = (-b * r).exp();
521+
let r7 = r.powi(7);
522+
let g = a * b * exp_term * r7 - 6.0 * c;
523+
let gp = a * b * exp_term * r.powi(6) * (7.0 - b * r);
524+
r -= g / gp;
525+
}
526+
let e_max = a * (-b * r).exp() - c / r.powi(6);
527+
(r * r, 2.0 * e_max)
528+
}
529+
530+
fn params() -> (f64, f64, f64, f64, f64) {
531+
let (r_max_sq, two_e_max) = reflection_params(BUCK_A, BUCK_B, BUCK_C);
532+
(BUCK_A, BUCK_B, BUCK_C, r_max_sq, two_e_max)
518533
}
519534

520535
// --------------------------------------------------------------------
@@ -534,15 +549,30 @@ mod tests {
534549
assert_relative_eq!(result.diff, diff_only, epsilon = 1e-12);
535550
}
536551

552+
#[test]
553+
fn sanity_compute_equals_separate_reflected() {
554+
let p = params();
555+
let r_sq = 0.25_f64;
556+
557+
let result = Buckingham::compute(r_sq, p);
558+
let energy_only = Buckingham::energy(r_sq, p);
559+
let diff_only = Buckingham::diff(r_sq, p);
560+
561+
assert_relative_eq!(result.energy, energy_only, epsilon = 1e-12);
562+
assert_relative_eq!(result.diff, diff_only, epsilon = 1e-12);
563+
}
564+
537565
#[test]
538566
fn sanity_f32_f64_consistency() {
539567
let r_sq = 4.0;
540568
let p64 = params();
569+
let (r_max_sq_32, two_e_max_32) = reflection_params(BUCK_A, BUCK_B, BUCK_C);
541570
let p32 = (
542571
BUCK_A as f32,
543572
BUCK_B as f32,
544573
BUCK_C as f32,
545-
BUCK_FUSION_SQ as f32,
574+
r_max_sq_32 as f32,
575+
two_e_max_32 as f32,
546576
);
547577

548578
let e64 = Buckingham::energy(r_sq, p64);
@@ -556,13 +586,14 @@ mod tests {
556586
// --------------------------------------------------------------------
557587

558588
#[test]
559-
fn stability_fusion_region() {
589+
fn stability_reflected_region() {
560590
let r_sq = 0.1_f64;
561591
let result = Buckingham::compute(r_sq, params());
562592

563593
assert!(result.energy.is_finite());
564594
assert!(result.diff.is_finite());
565-
assert!(result.energy > 1e5);
595+
assert!(result.energy > 0.0);
596+
assert!(result.diff > 0.0);
566597
}
567598

568599
#[test]
@@ -574,6 +605,16 @@ mod tests {
574605
assert!(result.diff.is_finite());
575606
}
576607

608+
#[test]
609+
fn stability_near_zero() {
610+
let r_sq = 1e-20_f64;
611+
let p = params();
612+
let e = Buckingham::energy(r_sq, p);
613+
614+
assert!(e.is_finite());
615+
assert!(e > 0.0);
616+
}
617+
577618
// --------------------------------------------------------------------
578619
// 3. Finite Difference Verification
579620
// --------------------------------------------------------------------
@@ -595,7 +636,12 @@ mod tests {
595636
}
596637

597638
#[test]
598-
fn finite_diff_short_range() {
639+
fn finite_diff_reflected_region() {
640+
finite_diff_check(0.8);
641+
}
642+
643+
#[test]
644+
fn finite_diff_normal_short_range() {
599645
finite_diff_check(1.5);
600646
}
601647

@@ -610,15 +656,75 @@ mod tests {
610656
}
611657

612658
// --------------------------------------------------------------------
613-
// 4. Buckingham-Specific
659+
// 4. Buckingham-Specific: Reflection Properties
614660
// --------------------------------------------------------------------
615661

616662
#[test]
617-
fn specific_exponential_dominates_short_range() {
618-
let e1 = Buckingham::energy(0.81, params());
619-
let e2 = Buckingham::energy(1.0, params());
620-
assert!(e1.is_finite());
621-
assert!(e2.is_finite());
663+
fn specific_reflection_diverges() {
664+
let p = params();
665+
let e_close = Buckingham::energy(0.01, p);
666+
let e_far = Buckingham::energy(0.25, p);
667+
assert!(e_close > e_far);
668+
}
669+
670+
#[test]
671+
fn specific_diff_at_maximum_is_zero() {
672+
let p = params();
673+
let r_max_sq = p.3;
674+
let d = Buckingham::diff(r_max_sq, p);
675+
assert_relative_eq!(d, 0.0, epsilon = 1e-6);
676+
}
677+
678+
#[test]
679+
fn specific_c1_continuity_at_maximum() {
680+
let p = params();
681+
let r_max = p.3.sqrt();
682+
let eps = 1e-8;
683+
684+
let r_inside = r_max - eps;
685+
let r_outside = r_max + eps;
686+
687+
let d_inside = Buckingham::diff(r_inside * r_inside, p);
688+
let d_outside = Buckingham::diff(r_outside * r_outside, p);
689+
690+
let de_dr_inside = -d_inside * r_inside;
691+
let de_dr_outside = -d_outside * r_outside;
692+
693+
assert_relative_eq!(de_dr_inside, de_dr_outside, epsilon = 1e-3);
694+
}
695+
696+
#[test]
697+
fn specific_energy_continuity_at_maximum() {
698+
let p = params();
699+
let r_max = p.3.sqrt();
700+
let eps = 1e-8;
701+
702+
let e_inside = Buckingham::energy((r_max - eps).powi(2), p);
703+
let e_outside = Buckingham::energy((r_max + eps).powi(2), p);
704+
705+
assert_relative_eq!(e_inside, e_outside, epsilon = 1e-4);
706+
}
707+
708+
#[test]
709+
fn specific_finite_diff_across_boundary() {
710+
let p = params();
711+
let r_max = p.3.sqrt();
712+
713+
let h = 1e-6;
714+
715+
let r_out = r_max + 0.01;
716+
let e_p = Buckingham::energy((r_out + h).powi(2), p);
717+
let e_m = Buckingham::energy((r_out - h).powi(2), p);
718+
let de_dr_num_out = (e_p - e_m) / (2.0 * h);
719+
let de_dr_ana_out = -Buckingham::diff(r_out * r_out, p) * r_out;
720+
assert_relative_eq!(de_dr_num_out, de_dr_ana_out, epsilon = TOL_DIFF);
721+
722+
let r_in = r_max - 0.01;
723+
let e_p = Buckingham::energy((r_in + h).powi(2), p);
724+
let e_m = Buckingham::energy((r_in - h).powi(2), p);
725+
let de_dr_num_in = (e_p - e_m) / (2.0 * h);
726+
let de_dr_ana_in = -Buckingham::diff(r_in * r_in, p) * r_in;
727+
assert_relative_eq!(de_dr_num_in, de_dr_ana_in, epsilon = TOL_DIFF);
622728
}
623729
}
624730

0 commit comments

Comments
 (0)