@@ -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