Skip to content

Commit 772a705

Browse files
committed
New rcpr - with f(x) returning a result instead of bare f64
1 parent 46dcf12 commit 772a705

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

src/bca.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -602,10 +602,12 @@ pub fn polynomial_rootfinder(Za: f64, Zb: f64, Ma: f64, Mb: f64, E0: f64, impact
602602
}
603603

604604
#[cfg(feature = "cpr_rootfinder")]
605-
fn transform(x: f64) -> f64 {
606-
L/(x*PI/2.).tan().powi(2)
605+
fn transform(x: f64, l: f64) -> f64 {
606+
l/(x*PI/2.).tan().powi(2)
607607
}
608608

609+
610+
609611
#[cfg(feature = "cpr_rootfinder")]
610612
/// Computes the distance of closest approach of two particles with atomic numbers `Za`, `Zb` and masses `Ma`, `Mb` for an arbitrary interaction potential (e.g., Morse) for a given impact parameter and incident energy `E0` using the Chebyshev-Proxy Root-Finder method.
611613
///
@@ -633,10 +635,13 @@ pub fn cpr_rootfinder(Za: f64, Zb: f64, Ma: f64, Mb: f64, E0: f64, impact_parame
633635
//Lindhard screening length and reduced energy
634636
let a = interactions::screening_length(Za, Zb, interaction_potential);
635637
let relative_energy = E0*Mb/(Ma + Mb);
638+
// Guess at scaling for rootfinder - enforce p -> 0.5 in transformed coords
639+
// If smaller than defined constant L, default to L (which was found empirically)
640+
let l: f64 = (impact_parameter*(PI/4.).tan().powi(2)/a).max(L);
636641

637-
let g = |r: f64| -> f64 {
638-
interactions::distance_of_closest_approach_function_singularity_free(transform(r)*a, a, Za, Zb, relative_energy, impact_parameter, interaction_potential)*
639-
interactions::scaling_function(transform(r)*a, a, interaction_potential)
642+
let g = |r: f64| -> Result<f64, std::convert::Infallible> {
643+
Ok(interactions::distance_of_closest_approach_function_singularity_free(transform(r, l)*a, a, Za, Zb, relative_energy, impact_parameter, interaction_potential)*
644+
interactions::scaling_function(transform(r, l)*a, a, interaction_potential))
640645
};
641646

642647
let lower_bound = CPR_ROOTFINDER_LOWER_BOUND;
@@ -658,12 +663,12 @@ pub fn cpr_rootfinder(Za: f64, Zb: f64, Ma: f64, Mb: f64, E0: f64, impact_parame
658663
// Since above the arg to doca is transform(r)*a, this is already scaled as output
659664
//let max_root = roots.iter().map(|&x| transform(x)).fold(f64::NAN, f64::max);
660665
let max_root = roots.iter()
661-
.map(|&x| transform(x))
666+
.map(|&x| transform(x, l))
662667
.max_by(f64::total_cmp)
663-
.ok_or_else(|| {anyhow!("Numerical error: failed to find maximum root. F(a): {}, F(b): {}", g(lower_bound), g(upper_bound))})?;
668+
.ok_or_else(|| {anyhow!("Numerical error: failed to find maximum root. F(a): {}, F(b): {}", g(lower_bound).unwrap(), g(upper_bound).unwrap())})?;
664669

665670
if roots.is_empty() || max_root.is_nan() {
666-
return Err(anyhow!("Numerical error: CPR rootfinder failed to find root. x0: {}, F(a): {}, F(b): {};", max_root, g(lower_bound), g(upper_bound)));
671+
return Err(anyhow!("Numerical error: CPR rootfinder failed to find root. x0: {}, F(a): {}, F(b): {};", max_root, g(lower_bound).unwrap(), g(upper_bound).unwrap()));
667672
} else {
668673
return Ok(max_root);
669674
}

0 commit comments

Comments
 (0)