-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCylindricalBesselGenerator.cpp
185 lines (146 loc) · 4.24 KB
/
CylindricalBesselGenerator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <cassert>
#include "compat.h"
#ifndef NO_BESSEL_TABLE
#include <greens_functions/CylindricalBesselTable.hpp>
#endif
#include "CylindricalBesselGenerator.hpp"
namespace greens_functions{
#ifndef NO_BESSEL_TABLE
static inline double hermite_interp(double x,
double x0, double dx,
double const* y_array)
#else
static inline double hermite_interp(double x,
double x0, double dx,
std::vector<double> const& y_array)
#endif
{
const double hinv = 1.0 / dx;
const size_t i = static_cast<size_t>((x - x0 ) * hinv);
const size_t index = i * 2;
const double x_lo = (x - x0) * hinv - i;
const double x_hi = 1.0 - x_lo;
const double y_lo = y_array[index];
const double ydot_lo = y_array[index + 1] * dx;
const double y_hi = y_array[index + 2];
const double ydot_hi = y_array[index + 3] * dx;
return x_hi * x_hi * (y_lo + x_lo * (2 * y_lo + ydot_lo))
+ x_lo * x_lo * (y_hi + x_hi * (2 * y_hi - ydot_hi));
}
#ifndef NO_BESSEL_TABLE
inline static Real interp(Real x_start, Real delta_x,
Real const* yTable, Real x)
#else
inline static Real interp(Real x_start, Real delta_x,
std::vector<double> const& yTable, Real x)
#endif
{
return hermite_interp(x, x_start, delta_x, yTable);
}
static Real _J(UnsignedInteger n, Real z)
{
return gsl_sf_bessel_Jn(n, z);
}
static Real _Y(UnsignedInteger n, Real z)
{
return gsl_sf_bessel_Yn(n, z);
}
CylindricalBesselGenerator const& CylindricalBesselGenerator::instance()
{
static const CylindricalBesselGenerator cylindricalBesselGenerator;
return cylindricalBesselGenerator;
}
UnsignedInteger CylindricalBesselGenerator::getMinNJ()
{
return cb_table::cj_table_min;
}
UnsignedInteger CylindricalBesselGenerator::getMinNY()
{
return cb_table::cy_table_min;
}
UnsignedInteger CylindricalBesselGenerator::getMaxNJ()
{
return cb_table::cj_table_max;
}
UnsignedInteger CylindricalBesselGenerator::getMaxNY()
{
return cb_table::cy_table_max;
}
#ifndef NO_BESSEL_TABLE
static cb_table::Table const* getCJTable(UnsignedInteger n)
{
return cb_table::cj_table[n];
}
static cb_table::Table const* getCYTable(UnsignedInteger n)
{
return cb_table::cy_table[n];
}
static inline Real _J_table(UnsignedInteger n, Real z)
{
cb_table::Table const* tablen(getCJTable(n));
return interp(tablen->x_start, tablen->delta_x, tablen->y, z);
}
static inline Real _Y_table(UnsignedInteger n, Real z)
{
cb_table::Table const* tablen(getCYTable(n));
return interp(tablen->x_start, tablen->delta_x, tablen->y, z);
}
#else
cb_table::Table const* CylindricalBesselGenerator::getCJTable(UnsignedInteger n) const
{
return &cj_table_[n];
}
cb_table::Table const* CylindricalBesselGenerator::getCYTable(UnsignedInteger n) const
{
return &cy_table_[n];
}
Real CylindricalBesselGenerator::_J_table(UnsignedInteger n, Real z) const
{
cb_table::Table const* tablen(getCJTable(n));
return interp(tablen->x_start, tablen->delta_x, tablen->y, z);
}
Real CylindricalBesselGenerator::_Y_table(UnsignedInteger n, Real z) const
{
cb_table::Table const* tablen(getCYTable(n));
return interp(tablen->x_start, tablen->delta_x, tablen->y, z);
}
#endif
Real CylindricalBesselGenerator::J(UnsignedInteger n, Real z) const
{
if(n > getMaxNJ())
{
return _J(n, z);
}
const cb_table::Table* table(getCJTable(n));
assert(table != 0);
const Real minz(table->x_start + table->delta_x * 3);
const Real maxz(table->x_start + table->delta_x * (table->N-3));
if(z >= minz && z < maxz)
{
return _J_table(n, z);
}
else
{
return _J(n, z);
}
}
Real CylindricalBesselGenerator::Y(const UnsignedInteger n, const Real z) const
{
if(n > getMaxNY())
{
return _Y(n, z);
}
const cb_table::Table* table(getCYTable(n));
assert(table != 0);
const Real minz(table->x_start + table->delta_x * 3);
const Real maxz(table->x_start + table->delta_x * (table->N-3));
if(z >= minz && z < maxz)
{
return _Y_table(n, z);
}
else
{
return _Y(n, z);
}
}
}