forked from ecell/epdp
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathCylindricalBesselGenerator.cpp
149 lines (113 loc) · 3.22 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
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <cassert>
#include "compat.h"
#include "CylindricalBesselTable.hpp"
#include "CylindricalBesselGenerator.hpp"
static inline double hermite_interp(double x,
double x0, double dx,
double const* y_array)
{
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));
}
inline static Real interp(Real x_start, Real delta_x,
Real const* yTable, Real x)
{
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;
}
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);
}
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);
}
}