Skip to content

Commit ebee67b

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

1 file changed

Lines changed: 119 additions & 14 deletions

File tree

  • src/potentials/nonbonded

src/potentials/nonbonded/vdw.rs

Lines changed: 119 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,10 @@ mod tests {
359359
const R0: f64 = 3.5;
360360
const R0_SQ: f64 = R0 * R0;
361361

362-
// Buckingham parameters: A, B, C, r_fusion_sq
362+
// Buckingham parameters: A, B, C
363363
const BUCK_A: f64 = 1000.0;
364364
const BUCK_B: f64 = 3.0;
365365
const BUCK_C: f64 = 50.0;
366-
const BUCK_FUSION_SQ: f64 = 0.5;
367366

368367
// ========================================================================
369368
// Lennard-Jones Tests
@@ -513,8 +512,23 @@ mod tests {
513512
mod buckingham {
514513
use super::*;
515514

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

520534
// --------------------------------------------------------------------
@@ -534,15 +548,30 @@ mod tests {
534548
assert_relative_eq!(result.diff, diff_only, epsilon = 1e-12);
535549
}
536550

551+
#[test]
552+
fn sanity_compute_equals_separate_reflected() {
553+
let p = params();
554+
let r_sq = 0.25_f64;
555+
556+
let result = Buckingham::compute(r_sq, p);
557+
let energy_only = Buckingham::energy(r_sq, p);
558+
let diff_only = Buckingham::diff(r_sq, p);
559+
560+
assert_relative_eq!(result.energy, energy_only, epsilon = 1e-12);
561+
assert_relative_eq!(result.diff, diff_only, epsilon = 1e-12);
562+
}
563+
537564
#[test]
538565
fn sanity_f32_f64_consistency() {
539566
let r_sq = 4.0;
540567
let p64 = params();
568+
let (r_max_sq_32, two_e_max_32) = reflection_params(BUCK_A, BUCK_B, BUCK_C);
541569
let p32 = (
542570
BUCK_A as f32,
543571
BUCK_B as f32,
544572
BUCK_C as f32,
545-
BUCK_FUSION_SQ as f32,
573+
r_max_sq_32 as f32,
574+
two_e_max_32 as f32,
546575
);
547576

548577
let e64 = Buckingham::energy(r_sq, p64);
@@ -556,13 +585,14 @@ mod tests {
556585
// --------------------------------------------------------------------
557586

558587
#[test]
559-
fn stability_fusion_region() {
588+
fn stability_reflected_region() {
560589
let r_sq = 0.1_f64;
561590
let result = Buckingham::compute(r_sq, params());
562591

563592
assert!(result.energy.is_finite());
564593
assert!(result.diff.is_finite());
565-
assert!(result.energy > 1e5);
594+
assert!(result.energy > 0.0);
595+
assert!(result.diff > 0.0);
566596
}
567597

568598
#[test]
@@ -574,6 +604,16 @@ mod tests {
574604
assert!(result.diff.is_finite());
575605
}
576606

607+
#[test]
608+
fn stability_near_zero() {
609+
let r_sq = 1e-20_f64;
610+
let p = params();
611+
let e = Buckingham::energy(r_sq, p);
612+
613+
assert!(e.is_finite());
614+
assert!(e > 0.0);
615+
}
616+
577617
// --------------------------------------------------------------------
578618
// 3. Finite Difference Verification
579619
// --------------------------------------------------------------------
@@ -595,7 +635,12 @@ mod tests {
595635
}
596636

597637
#[test]
598-
fn finite_diff_short_range() {
638+
fn finite_diff_reflected_region() {
639+
finite_diff_check(0.8);
640+
}
641+
642+
#[test]
643+
fn finite_diff_normal_short_range() {
599644
finite_diff_check(1.5);
600645
}
601646

@@ -610,15 +655,75 @@ mod tests {
610655
}
611656

612657
// --------------------------------------------------------------------
613-
// 4. Buckingham-Specific
658+
// 4. Buckingham-Specific: Reflection Properties
614659
// --------------------------------------------------------------------
615660

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

0 commit comments

Comments
 (0)