Ejemplo n.º 1
0
int
mfield_green_ext(const double r, const double theta, const double phi,
                 mfield_green_workspace *w)
{
  int s = 0;
  size_t n;
  int m;
  const double sint = sin(theta);
  const double cost = cos(theta);
  double ratio = r / w->R;
  double term = 1.0;     /* (r/a)^{n-1} */

  /* precompute cos(m phi) and sin(m phi) */
  for (n = 0; n <= w->nmax; ++n)
    {
      w->cosmphi[n] = cos(n * phi);
      w->sinmphi[n] = sin(n * phi);
    }

  /* compute associated legendres */
  gsl_sf_legendre_deriv_alt_array(GSL_SF_LEGENDRE_SCHMIDT, w->nmax, cost,
                                  w->Plm, w->dPlm);

  for (n = 1; n <= w->nmax; ++n)
    {
      int ni = (int) n;

      for (m = -ni; m <= ni; ++m)
        {
          int mabs = abs(m);
          size_t cidx = mfield_green_nmidx(n, m);
          size_t pidx = gsl_sf_legendre_array_index(n, mabs);

          if (m < 0)
            {
              /* h_{nm} */
              w->dX_ext[cidx] = term * w->sinmphi[mabs] * w->dPlm[pidx];
              w->dY_ext[cidx] = -term / sint * mabs * w->cosmphi[mabs] * w->Plm[pidx];
              w->dZ_ext[cidx] = (double) n * term * w->sinmphi[mabs] * w->Plm[pidx];
            }
          else
            {
              /* g_{nm} */
              w->dX_ext[cidx] = term * w->cosmphi[mabs] * w->dPlm[pidx];
              w->dY_ext[cidx] = term / sint * mabs * w->sinmphi[mabs] * w->Plm[pidx];
              w->dZ_ext[cidx] = (double) n * term * w->cosmphi[mabs] * w->Plm[pidx];
            }
        }

      /* (r/a)^{n-1} */
      term *= ratio;
    }

  return s;
} /* mfield_green_ext() */
Ejemplo n.º 2
0
Archivo: green.c Proyecto: pa345/lib
int
green_calc(const double r, const double theta, const double phi,
           const double R, green_workspace *w)
{
  int s = 0;
  size_t n;
  int m;
  const double sint = sin(theta);
  const double cost = cos(theta);
  double ratio = R / r;
  double term = ratio * ratio;     /* (R/r)^{n+2} */

  /* precompute cos(m phi) and sin(m phi) */
  for (n = 0; n <= w->nmax; ++n)
    {
      w->cosmphi[n] = cos(n * phi);
      w->sinmphi[n] = sin(n * phi);
    }

  /* compute associated legendres */
  gsl_sf_legendre_deriv_alt_array(GSL_SF_LEGENDRE_SCHMIDT, w->nmax, cost,
                                  w->Plm, w->dPlm);

  for (n = 1; n <= w->nmax; ++n)
    {
      int ni = (int) n;

      /* (a/r)^{n+2} */
      term *= ratio;

      for (m = -ni; m <= ni; ++m)
        {
          int mabs = abs(m);
          size_t cidx = green_nmidx(n, m);
          size_t pidx = gsl_sf_legendre_array_index(n, mabs);

          if (m < 0)
            {
              /* h_{nm} */
              w->dX[cidx] = term * w->sinmphi[mabs] * w->dPlm[pidx];
              w->dY[cidx] = -term / sint * mabs * w->cosmphi[mabs] * w->Plm[pidx];
              w->dZ[cidx] = -(n + 1.0) * term * w->sinmphi[mabs] * w->Plm[pidx];
            }
          else
            {
              /* g_{nm} */
              w->dX[cidx] = term * w->cosmphi[mabs] * w->dPlm[pidx];
              w->dY[cidx] = term / sint * mabs * w->sinmphi[mabs] * w->Plm[pidx];
              w->dZ[cidx] = -(n + 1.0) * term * w->cosmphi[mabs] * w->Plm[pidx];
            }
        }
    }

  return s;
} /* green_calc() */
Ejemplo n.º 3
0
Archivo: stage3b.c Proyecto: pa345/lib
static double
chi_ext(const double b, const double phi, const gsl_vector *k,
        const green_workspace *green_p)
{
  const double mu0 = 400.0 * M_PI; /* units of nT / (kA km^{-1}) */
  const size_t nmax = green_p->nmax;
  const double *Plm = green_p->Plm;
  const double ratio = b / R_EARTH_KM;
  size_t n;
  double chi = 0.0;
  double rfac = 1.0;

  for (n = 1; n <= nmax; ++n)
    {
      int M = (int) GSL_MIN(n, green_p->mmax);
      int m;
      double nfac = (2.0 * n + 1.0) / (n + 1.0);

      for (m = -M; m <= M; ++m)
        {
          int mabs = abs(m);
          size_t cidx = green_nmidx(n, m, green_p);
          double knm = gsl_vector_get(k, cidx);
          double qnm = nfac * rfac * knm;
          size_t pidx = gsl_sf_legendre_array_index(n, mabs);
          double Snm = Plm[pidx];

          if (m < 0)
            Snm *= sin(mabs * phi);
          else
            Snm *= cos(mabs * phi);

          chi += qnm * Snm;
        }

      /* (b/R)^{n-2} */
      rfac *= ratio;
    }

  /* units of kA */
  chi *= -(b / mu0);

  return chi;
}
Ejemplo n.º 4
0
int
FUNCTION (gsl_sf_legendre, array_e)
(const gsl_sf_legendre_t norm, const size_t lmax, const double x,
 const double csphase, OUTPUT_ARG)
{
  int s;
  const size_t nlm = gsl_sf_legendre_nlm(lmax);
#if !defined(LEGENDRE_DERIV_ALT)
  size_t i;
#if defined(LEGENDRE_DERIV) || defined(LEGENDRE_DERIV2)
  const double u = sqrt((1.0 - x) * (1.0 + x));
  const double uinv = 1.0 / u;
#endif
#if defined(LEGENDRE_DERIV2)
  const double uinv2 = uinv * uinv;
#endif
#endif
  double fac1 = 0.0, fac2 = 0.0; /* normalization factors */

  if (norm == GSL_SF_LEGENDRE_NONE)
    {
      /* compute P_{lm}(x) */
      s = FUNCTION(legendre,array_none_e)(lmax, x, csphase, OUTPUT);
    }
  else
    {
      /* compute S_{lm}(x) */
      s = FUNCTION(legendre,array_schmidt_e)(lmax, x, csphase, OUTPUT);
    }

#if !defined(LEGENDRE_DERIV_ALT)
  /* scale derivative arrays to recover P'(x) and P''(x) */
  for (i = 0; i < nlm; ++i)
    {
#if defined(LEGENDRE_DERIV2)
      double dp = result_deriv_array[i];
      double d2p = result_deriv2_array[i];

      result_deriv2_array[i] = (d2p - x * uinv * dp) * uinv2;
#endif
#if defined(LEGENDRE_DERIV)
      result_deriv_array[i] *= -uinv;
#endif
    }
#endif

  /* apply scaling for requested normalization */
  if (norm == GSL_SF_LEGENDRE_SCHMIDT || norm == GSL_SF_LEGENDRE_NONE)
    {
      return s;
    }
  else if (norm == GSL_SF_LEGENDRE_SPHARM)
    {
      fac1 = 1.0 / sqrt(4.0 * M_PI);
      fac2 = 1.0 / sqrt(8.0 * M_PI);
    }
  else if (norm == GSL_SF_LEGENDRE_FULL)
    {
      fac1 = 1.0 / sqrt(2.0);
      fac2 = 1.0 / sqrt(4.0);
    }

  /*
   * common code for different normalizations
   * P_{l0} = fac1 * sqrt(2l + 1) * S_{l0}
   * P_{lm} = fac2 * sqrt(2l + 1) * S_{lm}, m > 0
   */
  {
    size_t l, m;
    size_t twoellp1 = 1; /* 2l + 1 */
    double *sqrts = &(result_array[nlm]);

    for (l = 0; l <= lmax; ++l)
      {
        result_array[gsl_sf_legendre_array_index(l, 0)] *=
          sqrts[twoellp1] * fac1;
#if defined(LEGENDRE_DERIV)
        result_deriv_array[gsl_sf_legendre_array_index(l, 0)] *=
          sqrts[twoellp1] * fac1;
#endif
#if defined(LEGENDRE_DERIV2)
        result_deriv2_array[gsl_sf_legendre_array_index(l, 0)] *=
          sqrts[twoellp1] * fac1;
#endif

        for (m = 1; m <= l; ++m)
          {
            result_array[gsl_sf_legendre_array_index(l, m)] *=
              sqrts[twoellp1] * fac2;
#if defined(LEGENDRE_DERIV)
            result_deriv_array[gsl_sf_legendre_array_index(l, m)] *=
              sqrts[twoellp1] * fac2;
#endif
#if defined(LEGENDRE_DERIV2)
            result_deriv2_array[gsl_sf_legendre_array_index(l, m)] *=
              sqrts[twoellp1] * fac2;
#endif
          }

        twoellp1 += 2;
      }
  }

  return s;
}