static void aran_multipole_translate_vertical (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble cosp, gdouble sinp) { gint l, m; gint n; gdouble rpow[dst->negdeg]; gdouble pow; gcomplex128 *srcterm, *dstterm; gint d = MAX (src->negdeg, dst->negdeg) - 1; if (src->negdeg > dst->negdeg) g_warning ("could loose precision in \"%s\"\n", __PRETTY_FUNCTION__); aran_spherical_seriesd_alpha_require (d); aran_spherical_seriesd_beta_require (d); pow = 1.; for (l = 0; l < dst->negdeg; l++) { rpow[l] = pow; pow *= r; for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_neg_term (dst, l, m); for (n = m; n <= MIN (l, src->negdeg - 1); n++) { gdouble normaliz = aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gdouble factor; gdouble h; srcterm = _spherical_seriesd_get_neg_term (src, n, 0); /* m-o = 0 */ factor = aran_spherical_seriesd_alpha (l - n, 0) * aran_spherical_seriesd_alpha (n, m) / aran_spherical_seriesd_alpha (l, m); /* h= Y_(l-n)^(m-o) */ /* * in this case, h=Y_(l-n)^0, which simplifies with "normaliz" * removing beta(l-n) * and then becomes h = P_(l-n)^0 = (cost)^(l-n) */ h = ((l-n)%2 == 0)? 1. : cost; *dstterm += h * srcterm[m] * factor * normaliz * rpow[l - n]; } } } }
static gdouble _precomputed_translate_vertical_generator (guint l, guint m, guint n, AranTranslateBufferd * buf) { gdouble normaliz = _betal_over_betan (l, n); gdouble factor = aran_spherical_seriesd_alpha (l, m) * aran_spherical_seriesd_alpha (n, m); return normaliz * factor / aran_spherical_seriesd_alpha (l + n, 0); }
static void aran_local_translate (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble sint, gdouble cosp, gdouble sinp) { gint l, m; gint n, o; gdouble rpow[src->posdeg + 1]; gdouble pow; gcomplex128 *srcterm, *dstterm, *hterm; gint d = MAX (src->posdeg, dst->posdeg); gcomplex128 harmonics[((d + 1) * (d + 2)) / 2]; gcomplex128 expp = cosp + G_I * sinp; if (src->posdeg > dst->posdeg) g_warning ("could loose precision in \"%s\"\n", __PRETTY_FUNCTION__); aran_spherical_seriesd_beta_require (d); aran_spherical_seriesd_alpha_require (d); aran_spherical_harmonic_evaluate_multiple_internal (src->posdeg, cost, sint, expp, harmonics); pow = 1.; for (l = 0; l <= src->posdeg; l++) { rpow[l] = pow; pow *= r; } for (l = 0; l <= dst->posdeg; l++) { for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_pos_term (dst, l, m); for (n = l; n <= src->posdeg; n++) { gdouble normaliz = aran_spherical_seriesd_beta (n - l) * aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gcomplex128 sum = 0.; srcterm = _spherical_seriesd_get_pos_term (src, n, 0); hterm = aran_spherical_harmonic_multiple_get_term (n - l, 0, harmonics); for (o = l + m - n; o <= m + n - l; o++) { gint o_m_m = o - m; guint abs_o_m_m = ABS (o_m_m); gdouble factor = aran_spherical_seriesd_alpha (n - l, abs_o_m_m) * aran_spherical_seriesd_alpha (l, ABS (m)) / aran_spherical_seriesd_alpha (n, ABS (o)); gcomplex128 h = hterm[abs_o_m_m]; /* h = Y_(n-l)^(o-m) */ if (o_m_m < 0) h = _sph_sym (h, abs_o_m_m); if (o >= 0) h *= srcterm[o]; else h *= _sph_sym (srcterm[-o], -o); sum += h * factor; } *dstterm += sum * (normaliz * rpow[n - l]); } } } }
static void aran_multipole_to_local (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble sint, gdouble cosp, gdouble sinp) { gint l, m; gint n, o; gint d = dst->posdeg + src->negdeg; gdouble rpow[d + 1]; gdouble pow, inv_r; gcomplex128 *srcterm, *dstterm, *hterm; gcomplex128 harmonics[((d + 1) * (d + 2)) / 2]; gcomplex128 expp = cosp + G_I * sinp; gdouble sign; /* if ((src->negdeg-1) > dst->posdeg) */ /* g_warning ("could loose precision in \"%s\"\n", __PRETTY_FUNCTION__); */ /* vertical translation */ if (ABS (sint) < 1.e-5) /* sint in m2l translation is zero or high values */ { aran_spherical_seriesd_multipole_to_local_vertical (src, dst, r, cost, cosp, sinp); return; } aran_spherical_seriesd_alpha_require (d); aran_spherical_seriesd_beta_require (d); aran_spherical_harmonic_evaluate_multiple_internal (d, cost, sint, expp, harmonics); inv_r = 1. / r; pow = 1.; for (l = 0; l <= d; l++) { rpow[l] = pow; pow *= inv_r; } sign = 1.; for (l = 0; l <= dst->posdeg; l++) { for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_pos_term (dst, l, m); for (n = 0; n < src->negdeg; n++) { gdouble normaliz = aran_spherical_seriesd_beta (l + n) * aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gcomplex128 sum = 0.; srcterm = _spherical_seriesd_get_neg_term (src, n, 0); hterm = aran_spherical_harmonic_multiple_get_term (l + n, 0, harmonics); sum = aran_spherical_seriesd_alpha (l, m) * aran_spherical_seriesd_alpha (n, 0) / aran_spherical_seriesd_alpha (l + n, m) * hterm[m] * srcterm[0]; for (o = 1; o <= n; o++) { guint m_p_o = m + o; gdouble factor = aran_spherical_seriesd_alpha (l, m) * aran_spherical_seriesd_alpha (n, o); /* h= Y_(l+n)^(m+o) */ gcomplex128 h = hterm[m_p_o]; sum += h * srcterm[o] * factor / aran_spherical_seriesd_alpha (l + n, m_p_o); m_p_o = ABS (m - o); /* h= Y_(l+n)^(m-o) */ h = hterm[m_p_o]; if ((m - o) < 0) h = _sph_sym (h, m_p_o); sum += h * _sph_sym (srcterm[o], o) * factor / aran_spherical_seriesd_alpha (l + n, m_p_o); } *dstterm += conj (sum) * sign * normaliz * rpow[l + n + 1]; } } sign = -sign; } }
void aran_spherical_seriesd_multipole_to_local_vertical (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble cosp, gdouble sinp) { gint l, m; gint n; gint d = dst->posdeg + src->negdeg; gdouble rpow[d + 1]; gdouble pow, inv_r; gcomplex128 *srcterm, *dstterm, *hterm; gcomplex128 harmonics[((d + 1) * (d + 2)) / 2]; gcomplex128 expp = cosp + G_I * sinp; gdouble sign; aran_spherical_seriesd_alpha_require (d); aran_spherical_seriesd_beta_require (d); aran_spherical_harmonic_evaluate_multiple_internal (d, cost, 0, expp, harmonics); inv_r = 1. / r; pow = 1.; for (l = 0; l <= d; l++) { rpow[l] = pow; pow *= inv_r; } sign = 1.; for (l = 0; l <= dst->posdeg; l++) { for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_pos_term (dst, l, m); for (n = m; n < src->negdeg; n++) { gdouble normaliz = aran_spherical_seriesd_beta (l + n) * aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gcomplex128 sum; gdouble factor; gcomplex128 h; srcterm = _spherical_seriesd_get_neg_term (src, n, 0); hterm = aran_spherical_harmonic_multiple_get_term (l + n, 0, harmonics); /* o == -m */ factor = aran_spherical_seriesd_alpha (l, m) * aran_spherical_seriesd_alpha (n, m); /* h= Y_(l+n)^(m+o) */ h = hterm[0]; sum = h * _sph_sym (srcterm[m], m) * factor / aran_spherical_seriesd_alpha (l + n, 0); *dstterm += conj (sum) * sign * normaliz * rpow[l + n + 1]; } } sign = -sign; } }
static void aran_multipole_translate (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble sint, gdouble cosp, gdouble sinp) { gint l, m; gint n, o; gdouble rpow[dst->negdeg]; gdouble pow; gcomplex128 *srcterm, *dstterm, *hterm; gint d = MAX (src->negdeg, dst->negdeg) - 1; gcomplex128 harmonics[((d + 1) * (d + 2)) / 2]; gcomplex128 expp = cosp + G_I * sinp; if (src->negdeg > dst->negdeg) g_warning ("could loose precision in \"%s\"\n", __PRETTY_FUNCTION__); aran_spherical_seriesd_alpha_require (d); aran_spherical_seriesd_beta_require (d); aran_spherical_harmonic_evaluate_multiple_internal (dst->negdeg - 1, cost, sint, expp, harmonics); pow = 1.; for (l = 0; l < dst->negdeg; l++) { rpow[l] = pow; pow *= r; for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_neg_term (dst, l, m); for (n = 0; n <= MIN (l, src->negdeg - 1); n++) { gdouble normaliz = aran_spherical_seriesd_beta (l - n) * aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gcomplex128 sum = 0.; srcterm = _spherical_seriesd_get_neg_term (src, n, 0); hterm = aran_spherical_harmonic_multiple_get_term (l - n, 0, harmonics); for (o = MAX (-n, m + n - l); o <= MIN (n, l + m - n); o++) { guint abs_m_m_o = ABS (m - o); gdouble factor = aran_spherical_seriesd_alpha (l - n, abs_m_m_o) * aran_spherical_seriesd_alpha (n, ABS (o)) / aran_spherical_seriesd_alpha (l, ABS (m)); gcomplex128 h = conj (hterm[abs_m_m_o]); /* h=conj ( Y_(l-n)^(m-o) ) */ if ((m - o) < 0) h = _sph_sym (h, abs_m_m_o); if (o >= 0) h *= srcterm[o]; else h *= _sph_sym (srcterm[-o], -o); sum += h * factor; } *dstterm += sum * normaliz * rpow[l - n]; } } } }
void aran_spherical_seriesd_multipole_to_local_vertical (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble cosp, gdouble sinp) { gint l, m; gint n; gint d = dst->posdeg + src->negdeg; gdouble rpow[d + 1]; gdouble pow, inv_r; gcomplex128 *srcterm, *dstterm; gdouble sign; aran_spherical_seriesd_alpha_require (d); aran_spherical_seriesd_beta_require (d); inv_r = 1. / r; pow = 1.; for (l = 0; l <= d; l++) { rpow[l] = pow; pow *= inv_r; } sign = 1.; for (l = 0; l <= dst->posdeg; l++) { for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_pos_term (dst, l, m); for (n = m; n < src->negdeg; n++) { gdouble normaliz = aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gcomplex128 sum; gdouble factor; gcomplex128 h; srcterm = _spherical_seriesd_get_neg_term (src, n, 0); /* o == -m */ factor = aran_spherical_seriesd_alpha (l, m) * aran_spherical_seriesd_alpha (n, m); /* h= Y_(l+n)^(m+o) */ /* * in this case, h=Y_(l+n)^0, which simplifies with "normaliz" * removing beta(l+n) * and then becomes h = P_(l+n)^0 = (cost)^(l+n) */ h = ((l+n)%2 == 0)? 1. : cost; sum = h * _sph_sym (srcterm[m], m) * factor / aran_spherical_seriesd_alpha (l + n, 0); *dstterm += conj (sum) * sign * normaliz * rpow[l + n + 1]; } } sign = -sign; } }
static void aran_local_translate_vertical (const AranSphericalSeriesd * src, AranSphericalSeriesd * dst, gdouble r, gdouble cost, gdouble cosp, gdouble sinp) { gint l, m; gint n; gdouble rpow[src->posdeg + 1]; gdouble pow; gcomplex128 *srcterm, *dstterm; gint d = MAX (src->posdeg, dst->posdeg); if (src->posdeg > dst->posdeg) g_warning ("could loose precision in \"%s\"\n", __PRETTY_FUNCTION__); aran_spherical_seriesd_beta_require (d); aran_spherical_seriesd_alpha_require (d); pow = 1.; for (l = 0; l <= src->posdeg; l++) { rpow[l] = pow; pow *= r; } for (l = 0; l <= dst->posdeg; l++) { for (m = 0; m <= l; m++) { dstterm = _spherical_seriesd_get_pos_term (dst, l, m); for (n = l; n <= src->posdeg; n++) { gdouble normaliz = aran_spherical_seriesd_beta (l) / aran_spherical_seriesd_beta (n); gdouble factor; gdouble h; srcterm = _spherical_seriesd_get_pos_term (src, n, 0); /* o-m = 0 */ factor = aran_spherical_seriesd_alpha (n - l, 0) * aran_spherical_seriesd_alpha (l, m) / aran_spherical_seriesd_alpha (n, m); /* h= Y_(n-l)^(o-m) */ /* * in this case, h=Y_(n-l)^0, which simplifies with "normaliz" * removing beta(n-l) * and then becomes h = P_(n-l)^0 = (cost)^(n-l) */ h = ((n-l)%2 == 0)? 1. : cost; *dstterm += h * srcterm[m] * factor * normaliz * rpow[n - l]; } } } }