ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Loading...
Searching...
No Matches
SphericalBessel.hpp
1#pragma once
2#include "qip/Maths.hpp"
3#include <cmath>
4#include <gsl/gsl_sf_bessel.h>
5#include <vector>
6//
7#include <gsl/gsl_errno.h>
8#include <iostream>
9
14namespace SphericalBessel {
15
16//==============================================================================
17template <typename T>
18T JL(const int L, const T x) {
19
20 // Very low x expansion
21 if (std::abs(x) < (T)1.0e-8) {
22 if (L == 0)
23 return 1.0;
24 else
25 return 0.0;
26 }
27
28 // Low x expansion for first few Ls. Accurate to ~ 10^9
29 if (std::fabs(x) < 0.1) {
30 if (L == 0)
31 return 1.0 - 0.166666667 * (x * x) + 0.00833333333 * qip::pow<4>(x);
32 if (L == 1)
33 return 0.333333333 * x - 0.0333333333 * (x * x * x) +
34 0.00119047619 * qip::pow<5>(x);
35 if (L == 2)
36 return 0.0666666667 * (x * x) - 0.00476190476 * qip::pow<4>(x) +
37 0.000132275132 * qip::pow<6>(x);
38 if (L == 3)
39 return 0.00952380952 * (x * x * x) - 0.000529100529 * qip::pow<5>(x) +
40 0.000012025012 * qip::pow<7>(x);
41 if (L == 4)
42 return 0.00105820106 * qip::pow<4>(x) - 0.0000481000481 * qip::pow<6>(x) +
43 9.25000925e-7 * qip::pow<8>(x);
44 }
45
46 // Explicit formalas for first few L's
47 if (L == 0)
48 return std::sin(x) / x;
49 if (L == 1)
50 return std::sin(x) / (x * x) - std::cos(x) / x;
51 if (L == 2)
52 return (3.0 / (x * x) - 1.0) * std::sin(x) / x -
53 3.0 * std::cos(x) / (x * x);
54 if (L == 3)
55 return (15.0 / (x * x * x) - 6.0 / x) * std::sin(x) / x -
56 (15.0 / (x * x) - 1.0) * std::cos(x) / x;
57 if (L == 4)
58 return 5.0 * (-21.0 + 2.0 * x * x) * std::cos(x) / qip::pow<4>(x) +
59 (105.0 - 45.0 * x * x + qip::pow<4>(x)) * std::sin(x) /
60 (qip::pow<5>(x));
61
62 // If none of above apply, use GSL to calc. accurately
63 return (T)gsl_sf_bessel_jl(L, (double)x);
64}
65
66//==============================================================================
67template <typename T>
68T exactGSL_JL(int L, T x) {
69 return (T)gsl_sf_bessel_jl(L, (double)x);
70}
71
72//==============================================================================
74template <typename T>
75std::vector<T> fillBesselVec(const int l, const std::vector<T> &xvec) {
76 std::vector<T> Jl_vec;
77 Jl_vec.reserve(xvec.size());
78 for (const auto &x : xvec) {
79 Jl_vec.push_back(exactGSL_JL(l, x));
80 }
81 return Jl_vec;
82}
83
84template <typename T>
85std::vector<T> fillBesselVec_kr(const int l, const double k,
86 const std::vector<T> &rvec) {
87 std::vector<T> Jl_vec;
88 Jl_vec.reserve(rvec.size());
89 for (const auto &r : rvec) {
90 Jl_vec.push_back(exactGSL_JL(l, k * r));
91 }
92 return Jl_vec;
93}
94
95} // namespace SphericalBessel
Wrappers for returning Spherical Bessel functions.
Definition SphericalBessel.hpp:14
std::vector< T > fillBesselVec(const int l, const std::vector< T > &xvec)
Creates a vector of Jl(r) for given r.
Definition SphericalBessel.hpp:75