23#include <gsl/gsl_errno.h>
24#include <gsl/gsl_integration.h>
25#include <gsl/gsl_sf_bessel.h>
26#include <gsl/gsl_sf_expint.h>
30#define M_EULER_MASCHERONI 0.5772156649015328606065120
64static const double tol = 1e-7;
65static double zero = 1e-100;
67static double f(
double w,
void *p) {
68 struct parameters *params = (
struct parameters *)p;
69 const double kx = (params->kx);
70 double kr = (params->kr);
71 double x0 = (params->x0);
72 double r0 = (params->r0);
73 int index = (params->index);
79 if (
fabs(kx - w) > tol) {
80 result =
sin((kx - w) * x0) / (kx - w) *
82 (kr * kr + w * w) * gsl_sf_bessel_Kn(
index, r0 *
fabs(w));
84 result = x0 *
sqrt(
pow(w, 2.0 *
index)) / (kr * kr + w * w) *
90static double f_kx_zero(
double w,
void *p) {
91 struct parameters *params = (
struct parameters *)p;
92 double kr = (params->kr);
93 double x0 = (params->x0);
99 result = 2.0 * M_PI * w * gsl_sf_bessel_J0(kr * w) *
100 (
log(x0 +
sqrt(w * w + x0 * x0)) -
log(-x0 +
sqrt(w * w + x0 * x0)));
104static double f_kr_zero(
double w,
void *p) {
105 struct parameters *params = (
struct parameters *)p;
106 double kx = (params->kx);
107 double r0 = (params->r0);
110 result = 4.0 * M_PI *
cos(kx * w) * (
sqrt(r0 * r0 + w * w) -
fabs(w));
114static double int_aux(
int index,
double kx,
double kr,
double x0,
double r0,
117 double result, error;
118 double xinf = 100.0 / r0;
119 struct parameters params;
122 const size_t wrk_size = 5000;
127 const double epsilon_abs = 1e-3;
128 const double epsilon_rel = 1e-3;
131 gsl_integration_workspace *ws = gsl_integration_workspace_alloc(wrk_size);
136 assert(which_int == PFC_F_0 || which_int == PFC_F_KR ||
137 which_int == PFC_F_KX);
143 params.index =
index;
151 gsl_integration_qag(&F, -xinf, xinf, epsilon_abs, epsilon_rel, wrk_size, 3,
152 ws, &result, &error);
155 F.function = &f_kx_zero;
156 gsl_integration_qag(&F, 0.0, r0, epsilon_abs, epsilon_rel, wrk_size, 3, ws,
160 F.function = &f_kr_zero;
161 gsl_integration_qag(&F, 0.0, x0, epsilon_abs, epsilon_rel, wrk_size, 3, ws,
167 gsl_integration_workspace_free(ws);
173double poisson_finite_cylinder(
double kx,
double kr,
double x0,
double r0) {
176 if ((kx >= tol) & (kr >= tol)) {
178 4.0 * kr * r0 * gsl_sf_bessel_Jn(1, kr * r0) *
179 int_aux(0, kx, kr, x0, r0, PFC_F_0) -
180 4.0 * gsl_sf_bessel_Jn(0, kr * r0) *
181 int_aux(1, kx, kr, x0, r0, PFC_F_0) +
182 4.0 * M_PI / (kx * kx + kr * kr) *
183 (1.0 +
exp(-kr * x0) * (kx / kr *
sin(kx * x0) -
cos(kx * x0)));
184 }
else if ((kx < tol) & (kr >= tol)) {
185 result = int_aux(0, kx, kr, x0, r0, PFC_F_KX);
186 }
else if ((kx >= tol) & (kr < tol)) {
187 result = int_aux(0, kx, kr, x0, r0, PFC_F_KR);
189 result = -2.0 * M_PI *
190 (
log(r0 / (x0 +
sqrt(r0 * r0 + x0 * x0))) * r0 * r0 +
191 x0 * (x0 -
sqrt(r0 * r0 + x0 * x0)));
194 return result / (4.0 * M_PI);
198double FC_FUNC_(c_poisson_cutoff_3d_1d_finite,
199 C_POISSON_CUTOFF_3D_1D_FINITE)(
double *gx,
double *gperp,
200 double *xsize,
double *rsize) {
201 return poisson_finite_cylinder(*gx, *gperp, *xsize, *rsize);
209static double bessel_J0(
double w,
void *p) {
return gsl_sf_bessel_J0(w); }
212double FC_FUNC_(c_poisson_cutoff_2d_0d, C_POISSON_CUTOFF_2D_0D)(
double *x,
214 double result, error;
215 const size_t wrk_size = 500;
216 const double epsilon_abs = 1e-3;
217 const double epsilon_rel = 1e-3;
219 gsl_integration_workspace *ws = gsl_integration_workspace_alloc(wrk_size);
222 F.function = &bessel_J0;
223 gsl_integration_qag(&F, *x, *y, epsilon_abs, epsilon_rel, wrk_size, 3, ws,
225 gsl_integration_workspace_free(ws);
237double FC_FUNC(intcoslog, INTCOSLOG)(
double *mu,
double *a,
double *b) {
238 if (
fabs(*a) > 0.0) {
239 return (1.0 / (*a)) *
240 (
log((*b) * (*mu)) *
sin((*a) * (*mu)) - gsl_sf_Si((*a) * (*mu)));
242 return (*mu) * (
log((*mu) * (*b)) - 1.0);
251struct parameters_2d_1d {
257static double cutoff_2d_1d(
double w,
void *p) {
259 struct parameters_2d_1d *params = (
struct parameters_2d_1d *)p;
260 double gx = (params->gx);
261 double gy = (params->gy);
263 k0arg =
fabs(w * gx);
265 k0 = -(
log(k0arg / 2) + M_EULER_MASCHERONI);
266 }
else if (k0arg < 50.0) {
267 k0 = gsl_sf_bessel_K0(k0arg);
269 k0 =
sqrt(2.0 * M_PI / k0arg) *
exp(-k0arg);
271 return 4.0 *
cos(w * gy) * k0;
275double FC_FUNC_(c_poisson_cutoff_2d_1d,
276 C_POISSON_CUTOFF_2D_1D)(
double *gy,
double *gx,
double *rc) {
277 double result, error, res, b;
278 struct parameters_2d_1d params;
279 const size_t wrk_size = 5000;
280 const double epsilon_abs = 1e-3;
281 const double epsilon_rel = 1e-3;
284 gsl_integration_workspace *ws = gsl_integration_workspace_alloc(wrk_size);
288 b =
fabs((*gx)) / 2.0;
294 F.function = &cutoff_2d_1d;
297 res = -4.0 * FC_FUNC(intcoslog, INTCOSLOG)(&mu, gy, &b);
299 if (
fabs(*gy) > 0.0) {
300 res = res - (4.0 * M_EULER_MASCHERONI / (*gy)) *
sin((*gy) * mu);
302 res = res - 4.0 * M_EULER_MASCHERONI * mu;
305 gsl_integration_qag(&F, mu, (*rc), epsilon_abs, epsilon_rel, wrk_size, 3, ws,
309 gsl_integration_workspace_free(ws);
319struct parameters_1d_0d {
324static double cutoff_1d_0d(
double w,
void *p) {
325 struct parameters_1d_0d *params = (
struct parameters_1d_0d *)p;
326 double g = (params->g);
327 double a = (params->a);
328 return 2.0 * (
cos(w) /
sqrt(w * w + a * a * g * g));
332double FC_FUNC_(c_poisson_cutoff_1d_0d,
333 C_POISSON_CUTOFF_1D_0D)(
double *g,
double *a,
double *rc) {
334 double result, error;
335 struct parameters_1d_0d params;
336 const size_t wrk_size = 5000;
337 const double epsilon_abs = 1e-3;
338 const double epsilon_rel = 1e-3;
340 gsl_integration_workspace *ws;
344 return 2.0 *
asinh((*rc) / (*a));
349 if ((*g) * (*rc) > 100.1 * M_PI) {
350 return 2.0 * gsl_sf_bessel_K0((*a) * (*g));
353 gsl_set_error_handler_off();
355 ws = gsl_integration_workspace_alloc(wrk_size);
360 F.function = &cutoff_1d_0d;
363 status = gsl_integration_qag(&F, 0.0, (*rc) * (*g), epsilon_abs, epsilon_rel,
364 wrk_size, 3, ws, &result, &error);
366 gsl_integration_workspace_free(ws);
double pow(double __x, double __y) __attribute__((__nothrow__
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double fabs(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double asinh(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
const int *restrict index