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 // Low x expansion for first few Ls. Accurate to ~ 10^9
21 if (std::abs(x) < 0.1) {
22 if (L == 0) {
23 const T x2 = x * x;
24 const T x4 = x2 * x2;
25 return 1.0 - 0.166666667 * x2 + 0.00833333333 * x4;
26 } else if (L == 1) {
27 const T x2 = x * x;
28 const T x3 = x2 * x;
29 const T x5 = x3 * x2;
30 return 0.333333333 * x - 0.0333333333 * x3 + 0.00119047619 * x5;
31 } else if (L == 2) {
32 const T x2 = x * x;
33 const T x4 = x2 * x2;
34 const T x6 = x4 * x2;
35 return 0.0666666667 * x2 - 0.00476190476 * x4 + 0.000132275132 * x6;
36 } else if (L == 3) {
37 const T x2 = x * x;
38 const T x3 = x2 * x;
39 const T x5 = x3 * x2;
40 const T x7 = x5 * x2;
41 return 0.00952380952 * x3 - 0.000529100529 * x5 + 0.000012025012 * x7;
42 } else if (L == 4) {
43 const T x2 = x * x;
44 const T x4 = x2 * x2;
45 const T x6 = x4 * x2;
46 const T x8 = x4 * x4;
47 return 0.00105820106 * x4 - 0.0000481000481 * x6 + 9.25000925e-7 * x8;
48 }
49 }
50
51 // If none of above apply, use GSL to calc. accurately
52 return (T)gsl_sf_bessel_jl(L, (double)x);
53}
54
55//==============================================================================
56template <typename T>
57T exactGSL_JL(int L, T x) {
58 return (T)gsl_sf_bessel_jl(L, (double)x);
59}
60
61//==============================================================================
63template <typename T>
64std::vector<T> fillBesselVec(const int l, const std::vector<T> &xvec) {
65 std::vector<T> Jl_vec;
66 Jl_vec.reserve(xvec.size());
67 for (const auto &x : xvec) {
68 Jl_vec.push_back(exactGSL_JL(l, x));
69 }
70 return Jl_vec;
71}
72
73template <typename T>
74std::vector<T> fillBesselVec_kr(const int l, const double k,
75 const std::vector<T> &rvec) {
76 std::vector<T> Jl_vec;
77 Jl_vec.reserve(rvec.size());
78 for (const auto &r : rvec) {
79 Jl_vec.push_back(JL(l, k * r));
80 }
81 return Jl_vec;
82}
83
84template <typename T>
85void fillBesselVec_kr(int l, double k, const std::vector<T> &r,
86 std::vector<T> *jl) {
87 jl->resize(r.size());
88 for (std::size_t i = 0; i < r.size(); ++i) {
89 (*jl)[i] = JL(l, k * r[i]);
90 }
91}
92
93} // 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:64