static AranSphericalSeriesd *create_taylor (guint deg, VsgVector3d *center, VsgVector3d *p) { AranSphericalSeriesd *ass; gint l, m; const guint size = ((deg+1)*(deg+2))/2; gcomplex128 harmonics[size]; gdouble r, cost, sint, cosp, sinp; gcomplex128 expp; gdouble fact, inv_r; VsgVector3d tmp; ass = aran_spherical_seriesd_new (deg, 0); aran_spherical_seriesd_set_zero (ass); vsg_vector3d_sub (p, center, &tmp); vsg_vector3d_to_spherical_internal (&tmp, &r, &cost, &sint, &cosp, &sinp); expp = cosp + G_I * sinp; aran_spherical_harmonic_evaluate_multiple_internal (deg, cost, sint, expp, harmonics); *aran_spherical_seriesd_get_term (ass, 0, 0) = 0.; inv_r = 1./ r; fact = inv_r; for (l=0; l<=deg; l ++) { gcomplex128 term; term = fact * (4.*G_PI / (l+l+1.)) * *aran_spherical_harmonic_multiple_get_term (l, 0, harmonics); *aran_spherical_seriesd_get_term (ass, l, 0) = conj (term); for (m=1; m<=l; m ++) { term = fact * (4.*G_PI / (l+l+1.)) * *aran_spherical_harmonic_multiple_get_term (l, m, harmonics); *aran_spherical_seriesd_get_term (ass, l, m) = conj (term); } fact *= inv_r; } return ass; }
static void p2m (PointAccum *particle, const VsgVector3d *center, AranDevelopment3d *devel) { VsgVector3d tmp; guint deg = aran_spherical_seriesd_get_negdeg (devel->multipole); gint l, m; gcomplex128 harmonics[((deg+1)*(deg+2))/2]; gdouble r, cost, sint, cosp, sinp; gcomplex128 expp; gdouble fact; vsg_vector3d_sub (&particle->vector, center, &tmp); vsg_vector3d_to_spherical_internal (&tmp, &r, &cost, &sint, &cosp, &sinp); expp = cosp + G_I * sinp; aran_spherical_harmonic_evaluate_multiple_internal (deg, cost, sint, expp, harmonics); *aran_spherical_seriesd_get_term (devel->multipole, 0, 0) += 0.; fact = particle->density; for (l=0; l<deg; l ++) { gcomplex128 *ptr; gcomplex128 term; term = fact * (4.*G_PI / (l+l+1.)) * *aran_spherical_harmonic_multiple_get_term (l, 0, harmonics); ptr = aran_spherical_seriesd_get_term (devel->multipole, -l-1, 0); ptr[0] += conj (term); for (m=1; m<=l; m ++) { term = fact * (4.*G_PI / (l+l+1.)) * *aran_spherical_harmonic_multiple_get_term (l, m, harmonics); ptr[m] += conj (term); } fact *= r; } }
/** * aran_spherical_seriesd_to_local: * @src: source expansion series. * @xsrc: @src center. * @dst: destination expansion series. * @xdst: @dst center. * * Like aran_spherical_seriesd_translate() except the multipole part of * @src is transformed into a local expansion in @dst. */ void aran_spherical_seriesd_to_local (const AranSphericalSeriesd * src, const VsgVector3d * xsrc, AranSphericalSeriesd * dst, const VsgVector3d * xdst) { VsgVector3d tmp; gdouble r, cost, sint, cosp, sinp; vsg_vector3d_sub (xdst, xsrc, &tmp); vsg_vector3d_to_spherical_internal (&tmp, &r, &cost, &sint, &cosp, &sinp); aran_local_translate (src, dst, r, cost, sint, cosp, sinp); if (src->negdeg > 0) { aran_multipole_to_local (src, dst, r, cost, sint, cosp, sinp); } }
static AranSphericalSeriesd *create_newton (guint deg) { AranSphericalSeriesd *ass = aran_spherical_seriesd_new (0, deg); gint l, m; gcomplex128 harmonics[((deg+1)*(deg+2))/2]; gdouble r, cost, sint, cosp, sinp; gcomplex128 expp; gdouble fact; vsg_vector3d_to_spherical_internal (&p, &r, &cost, &sint, &cosp, &sinp); expp = cosp + G_I * sinp; aran_spherical_harmonic_evaluate_multiple_internal (deg, cost, sint, expp, harmonics); *aran_spherical_seriesd_get_term (ass, 0, 0) = 0.; fact = 1.; for (l=0; l<deg; l ++) { gcomplex128 term; term = fact * (4.*G_PI / (l+l+1.)) * *aran_spherical_harmonic_multiple_get_term (l, 0, harmonics); *aran_spherical_seriesd_get_term (ass, -l-1, 0) = conj (term); for (m=1; m<=l; m ++) { term = fact * (4.*G_PI / (l+l+1.)) * *aran_spherical_harmonic_multiple_get_term (l, m, harmonics); *aran_spherical_seriesd_get_term (ass, -l-1, m) = conj (term); } fact *= r; } return ass; }