示例#1
0
int getLoc(GEOLOCATE_REC *g,double range,double dop,  /*  Inputs.*/
           double *latitude,double *phi,double *earthRadius) /*Outputs.*/
{
        int err;
	double yaw=0,look=0;
	vector target;
	err = getLookYaw(g,range,dop,&look,&yaw);
        if (err) return err;
	getDoppler(g,look,yaw,NULL,NULL,&target,NULL);
	cart2sph(target,earthRadius,latitude,phi);
        return 0;
}
示例#2
0
文件: exafmm.cpp 项目: dmarce1/fmmx
void exafmm_kernel::M2M(std::vector<real>& CiM, const std::vector<real>& CjM, const std::array<real, NDIM>& dist,
		const integer N) {
	std::vector<real> Ynm(FMM_P * FMM_P);
	std::vector<real> M_r(N), M_i(N);
	real rho, theta, phi;
	cart2sph(rho, theta, phi, dist);
	evalMultipole(rho, theta, -phi, Ynm);
	for (integer j = 0; j != FMM_P; ++j) {
		for (integer k = 0; k <= j; ++k) {
			const integer jkp = j * j + j + k;
			const integer jkm = j * j + j - k;
#pragma vector aligned
#pragma simd
			for (integer i = 0; i != N; ++i) {
				M_r[i] = M_i[i] = real(0.0);
			}
			for (integer n = 0; n <= j; ++n) {
				for (integer m = std::max(n - j + k, -n); m <= std::min(j - n + k, +n); ++m) {
					const integer nn = n * n + n;
					const integer nj = (j - n) * (j - n) + j - n;
					const integer jnkm = nj + k - m;
					const integer jnpkm = nj + std::abs(k - m);
					const integer jnmkm = nj - std::abs(k - m);
					const integer nmp = nn + std::abs(m);
					const integer nmm = nn - std::abs(m);
					const auto Mj_r = CjM.data() + N * jnpkm;
					const auto Mj_i = CjM.data() + N * jnmkm;
					const real tmp = Anm[nmp] * Anm[jnkm]
							/ Anm[jkp]* ODDEVEN((std::abs(k) - std::abs(m) - std::abs(k - m)) / 2 + n);
					const real sgn_km = SGN(k-m);
					const real Y_r = tmp * Ynm[nmp];
					const real Y_i = SGN(m) * tmp * Ynm[nmm];
#pragma vector aligned
#pragma simd
					for (integer i = 0; i != N; ++i) {
						COMPLEX_MULT_ADD(M_r[i], M_i[i], Y_r, Y_i, Mj_r[i], sgn_km * Mj_i[i]);
					}
				}
			}
			auto Mi_r = CiM.data() + N * jkp;
			auto Mi_i = CiM.data() + N * jkm;
#pragma vector aligned
#pragma simd
			for (integer i = 0; i != N; ++i) {
				Mi_r[i] += M_r[i];
				Mi_i[i] += (jkm == jkp) ? 0.0 : M_i[i];
			}
		}
	}
}
示例#3
0
文件: exafmm.cpp 项目: dmarce1/fmmx
void exafmm_kernel::L2L(std::vector<real>& CiL, const std::vector<real>& CjL, const std::array<real, NDIM>& dist,
		const integer N) {
	std::vector<real> Ynm(FMM_P * FMM_P);
	real rho, theta, phi;
	std::vector<real> L_r(N), L_i(N);
	cart2sph(rho, theta, phi, dist);
	evalMultipole(rho, theta, phi, Ynm);
	for (integer j = 0; j != FMM_P; ++j) {
		for (integer k = 0; k <= j; ++k) {
			integer jkp = j * j + j + k;
			integer jkm = j * j + j - k;
#pragma vector aligned
#pragma simd
			for (integer i = 0; i != N; ++i) {
				L_r[i] = L_i[i] = 0.0;
			}
			for (integer n = j; n != FMM_P; ++n) {
				for (integer m = j - n + k; m <= n - j + k; ++m) {
					const integer nn = n * n + n;
					const integer nj = (n - j) * ((n - j) + 1);
					const integer npm = nn + std::abs(m);
					const integer nmm = nn - std::abs(m);
					const integer jnpkm = nj + std::abs(m - k);
					const integer jnmkm = nj - std::abs(m - k);
					const auto Lj_r = CjL.data() + N * npm;
					const auto Lj_i = CjL.data() + N * nmm;
					const real sgn = SGN(m);
					real tmp = std::pow(-real(1.0), real(std::abs(m) - std::abs(k) - std::abs(m - k)) / 2) * Anm[jnpkm] * Anm[jkp]
							/ Anm[npm];
					const real Y_r = Ynm[jnpkm] * tmp;
					const real Y_i = SGN(m-k) * Ynm[jnmkm] * tmp;
#pragma vector aligned
#pragma simd
					for (integer i = 0; i != N; ++i) {
						COMPLEX_MULT_ADD(L_r[i], L_i[i], Y_r, Y_i, Lj_r[i], sgn * Lj_i[i]);
					}
				}
			}
			auto Li_r = CiL.data() + N * jkp;
			auto Li_i = CiL.data() + N * jkm;
#pragma vector aligned
#pragma simd
			for (integer i = 0; i != N; ++i) {
				Li_r[i] = L_r[i];
				Li_i[i] = (k == 0) ? L_r[i] : L_i[i];
			}
		}
	}
}
示例#4
0
void scan_to_latlon(meta_parameters *meta,
        double x, double y, double z,
        double *lat_d, double *lon, double *height)
{
  double qlat, qlon;
  double lat,radius;
  vector pos;
  meta_projection *proj = meta->projection;

  if (z != 0.0) {
    // height correction applies directly to y (range direction)
    double line, samp;
    line = (y-proj->startY)/proj->perY - meta->general->start_line;
    samp = (x-proj->startX)/proj->perX - meta->general->start_sample;
    double sr = meta_get_slant(meta,line,samp);
    double er = proj->param.atct.rlocal;
    double ht = meta_get_sat_height(meta,line,samp);
    double cos_ang = (sr*sr + er*er - ht*ht)/(2.0*sr*er);
    if (cos_ang > 1) cos_ang = 1;
    if (cos_ang < -1) cos_ang = -1;
    double incid = PI-acos(cos_ang);
    x += z*tan(PI/2-incid);
  }

  if (meta->sar->look_direction=='R')
    qlat = -x/proj->param.atct.rlocal; /* Right looking sar */
  else
    qlat =  x/proj->param.atct.rlocal; /* Left looking sar */
  qlon = y/(proj->param.atct.rlocal*cos(qlat));

  sph2cart(proj->param.atct.rlocal, qlat, qlon, &pos);

  rotate_z(&pos,-proj->param.atct.alpha3);
  rotate_y(&pos,-proj->param.atct.alpha2);
  rotate_z(&pos,-proj->param.atct.alpha1);

  cart2sph(pos,&radius,&lat,lon);
  *lon *= R2D;
  lat *= R2D;
  *lat_d = atand(tand(lat) / (1-ecc2(proj->re_minor,proj->re_major)));
  *height = z;  // FIXME: Do we need to correct the height at all?
}
示例#5
0
static void ll_ac(meta_projection *proj, char look_dir, double lat_r, double lon, double *c1, double *c2)
{
  double qlat, qlon;
  double lat,radius;
  vector pos;

  lat = atan(tan(lat_r)*(1 - ecc2(proj->re_minor,proj->re_major)));
  sph2cart(proj->param.atct.rlocal,lat,lon,&pos);

  rotate_z(&pos,proj->param.atct.alpha1);
  rotate_y(&pos,proj->param.atct.alpha2);
  rotate_z(&pos,proj->param.atct.alpha3);

  cart2sph(pos,&radius,&qlat,&qlon);

  *c1 = qlon*proj->param.atct.rlocal*cos(qlat);
  if (look_dir=='R')
    *c2 = -1.0*qlat*proj->param.atct.rlocal;  /* right looking */
  else
    *c2 = qlat * proj->param.atct.rlocal;   /* left looking */
}
  /**
   * Create expansions for D_ij / G_i (Tornberg & Greengard
   */
  void P2M(const source_type& source, const charge_type& charge,
           const point_type& center, multipole_type& M) const {
    complex Ynm[4*P*P], YnmTheta[4*P*P];
    // modifications needed here
    point_type dist = static_cast<point_type>(source) - center;
    real rho, alpha, beta;
    cart2sph(rho,alpha,beta,dist);
    evalMultipole(rho,alpha,-beta,Ynm,YnmTheta);

    real g0 = charge[0], g1 = charge[1], g2 = charge[2];
    real n0 = charge[3], n1 = charge[4], n2 = charge[5];

    for (int n=0; n!=P; ++n) {
      for (int m=0; m<=n; ++m) {
        const int nm  = n * (n + 1) + m;
        const int nms = n * (n + 1) / 2 + m;

        complex brh = (double)n/rho*Ynm[nm]; // d(rho)
        complex bal = YnmTheta[nm];          // d(alpha)
        complex bbe = -complex(0,1.)*(double)m*Ynm[nm]; // d(beta)

        complex bxd = sin(alpha)*cos(beta)*brh + cos(alpha)*cos(beta)/rho*bal - sin(beta)/rho/sin(alpha)*bbe; // dx
        complex byd = sin(alpha)*sin(beta)*brh + cos(alpha)*sin(beta)/rho*bal + cos(beta)/rho/sin(alpha)*bbe; // dy
        complex bzd = cos(alpha)*brh - sin(alpha)/rho*bal; // dz

        // which order should these be in?
        real rdotn = bxd*n0 + byd*n1 + bzd*n2;
        real rdotg = bxd*g0 + byd*g1 + bzd*g2;
        M[0][nms] += (rdotn * g0 + rdotg * n0);
        M[1][nms] += (rdotn * g1 + rdotg * n1);
        M[2][nms] += (rdotn * g2 + rdotg * n2);

        real xdotg = source[0]*g0 + source[1]*g1 + source[2]*g2;
        real ndotx = n0*source[0] + n1*source[1] + n2*source[2];
        M[3][nms] += rdotn * xdotg + rdotg * ndotx;
      }
    }
  }
示例#7
0
static int
get_target_latlon(stateVector *st, double look, double *tlat, double *tlon)
{
  // satellite height, from the state vector
  double ht = vecMagnitude(st->pos);

  // earth radius, calculate from WGS84 values, and approx latitude
  double re = 6378137.0;
  double rp = 6356752.31414;
  double lat = asin(st->pos.z/ht);
  double er = re*rp/sqrt(rp*rp*cos(lat)*cos(lat)+re*re*sin(lat)*sin(lat));

  // calculate slant range by law of cosines
  // (where we know two sides, but not the angle between them)
  double D = er*er - ht*ht*sin(look)*sin(look);
  if (D < 0) 
    return 0; // can't see the Earth from here
  double sr1 = ht*cos(look) + sqrt(D);
  double sr2 = ht*cos(look) - sqrt(D);
  double sr = sr1>sr2 ? sr2 : sr1;

  // target position, first in inertial coords, then convert to lat/lon
  vector target;
  get_target_position(st, look, 0, sr, &target);

  double glat; // geocentric
  cart2sph(target,&er,&glat,tlon);
  
  // tlon should be -180,180
  // tlat needs to be geodetic
  // both should be degrees
  *tlon *= R2D;
  if (*tlon < -180.) *tlon += 360.;

  *tlat = R2D*atan(tan(glat)*re*re/(rp*rp));

  return 1;
}
  /**
   * Create expansions for S_ij / F_i (Tornberg & Greengard
   */
  void P2M(const source_type& source, const charge_type& charge,
           const point_type& center, multipole_type& M) const {
    complex Ynm[4*P*P], YnmTheta[4*P*P];
    // modifications needed here
    point_type dist = static_cast<point_type>(source) - center;
    real rho, alpha, beta;
    cart2sph(rho,alpha,beta,dist);
    evalMultipole(rho,alpha,-beta,Ynm,YnmTheta);

    real f0 = charge[0], f1 = charge[1], f2 = charge[2];
    real fdotx = f0*source[0] + f1*source[1] + f2*source[2];

    for (int n=0; n!=P; ++n) {
      for (int m=0; m<=n; ++m) {
        const int nm  = n * (n + 1) + m;
        const int nms = n * (n + 1) / 2 + m;

        M[0][nms] += f0 * Ynm[nm];
        M[1][nms] += f1 * Ynm[nm];
        M[2][nms] += f2 * Ynm[nm];
        M[3][nms] += fdotx * Ynm[nm];
      }
    }
  }
 /** Kernel L2P operation
   * r += Op(L, t) where L is the local expansion and r is the result
   *
   * @param[in] L The local expansion
   * @param[in] center The center of the box with the local expansion
   * @param[in] target The target of this L2P operation
   * @param[in] result The result to accumulate into
   * @pre L includes the influence of all sources outside its box
   */
  void L2P(const local_type& L, const point_type& center,
           const target_type& target, result_type& result) const {
    complex Ynm[4*P*P], YnmTheta[4*P*P];
    point_type dist = target - center;
    point_type gradient[4]; //   = {0.,0.,0.,0.};
    gradient[0] = point_type(0.);
    gradient[1] = point_type(0.);
    gradient[2] = point_type(0.);
    gradient[3] = point_type(0.);
    point_type cartesian(0);

    real r, theta, phi;
    cart2sph(r,theta,phi,dist);
    evalMultipole(r,theta,phi,Ynm,YnmTheta);

#ifdef STRESSLET
    double scale = 1./6;
#else
    double scale = 1.;
#endif

    for( int n=0; n!=P; ++n ) {
      int nm  = n * n + n;
      int nms = n * (n + 1) / 2;
      result[0] += scale*std::real(L[0][nms] * Ynm[nm]);
      result[1] += scale*std::real(L[1][nms] * Ynm[nm]);
      result[2] += scale*std::real(L[2][nms] * Ynm[nm]);

      real factor = 1. / r * n;
      gradient[0][0] += std::real(L[0][nms] * Ynm[nm]) * factor;
      gradient[0][1] += std::real(L[0][nms] * YnmTheta[nm]);

      gradient[1][0] += std::real(L[1][nms] * Ynm[nm]) * factor;
      gradient[1][1] += std::real(L[1][nms] * YnmTheta[nm]);

      gradient[2][0] += std::real(L[2][nms] * Ynm[nm]) * factor;
      gradient[2][1] += std::real(L[2][nms] * YnmTheta[nm]);

      gradient[3][0] += std::real(L[3][nms] * Ynm[nm]) * factor;
      gradient[3][1] += std::real(L[3][nms] * YnmTheta[nm]);

      for( int m=1; m<=n; ++m ) {
        nm  = n * n + n + m;
        nms = n * (n + 1) / 2 + m;
        result[0] += scale * 2 * std::real(L[0][nms] * Ynm[nm]);
        result[1] += scale * 2 * std::real(L[1][nms] * Ynm[nm]);
        result[2] += scale * 2 * std::real(L[2][nms] * Ynm[nm]);

        gradient[0][0] += 2 * std::real(L[0][nms] * Ynm[nm]) * factor;
        gradient[0][1] += 2 * std::real(L[0][nms] * YnmTheta[nm]);
        gradient[0][2] += 2 * std::real(L[0][nms] * Ynm[nm] * CI) * m;

        gradient[1][0] += 2 * std::real(L[1][nms] * Ynm[nm]) * factor;
        gradient[1][1] += 2 * std::real(L[1][nms] * YnmTheta[nm]);
        gradient[1][2] += 2 * std::real(L[1][nms] * Ynm[nm] * CI) * m;

        gradient[2][0] += 2 * std::real(L[2][nms] * Ynm[nm]) * factor;
        gradient[2][1] += 2 * std::real(L[2][nms] * YnmTheta[nm]);
        gradient[2][2] += 2 * std::real(L[2][nms] * Ynm[nm] * CI) * m;

        gradient[3][0] += 2 * std::real(L[3][nms] * Ynm[nm]) * factor;
        gradient[3][1] += 2 * std::real(L[3][nms] * YnmTheta[nm]);
        gradient[3][2] += 2 * std::real(L[3][nms] * Ynm[nm] * CI) * m;
      }
    }
    sph2cart(r,theta,phi,gradient[0],cartesian);
    cartesian *= -target[0];
    gradient[0] = cartesian;

    sph2cart(r,theta,phi,gradient[1],cartesian);
    cartesian *= -target[1];
    gradient[1] = cartesian;

    sph2cart(r,theta,phi,gradient[2],cartesian);
    cartesian *= -target[2];
    gradient[2] = cartesian;

    sph2cart(r,theta,phi,gradient[3],cartesian);
    gradient[3] = cartesian;

    result[0] += scale*(gradient[0][0]+gradient[1][0]+gradient[2][0]+gradient[3][0]);
    result[1] += scale*(gradient[0][1]+gradient[1][1]+gradient[2][1]+gradient[3][1]);
    result[2] += scale*(gradient[0][2]+gradient[1][2]+gradient[2][2]+gradient[3][2]);
  }
示例#10
0
// m2p
void FmmKernel::m2p(int numBoxIndex, int numLevel) {
  int ii,i,ij,jj,jb,j,n,nm,nms,m;
  vec3<int> boxIndex3D;
  vec3<float> boxCenter;
  vec3<double> accel,dist;
  double boxSize,r,theta,phi,rn,accelR,accelTheta,accelPhi;
  double xx,yy,s2,fact,pn,p,p1,p2;
  double YnmReal[numExpansion2],YnmRealTheta[numExpansion2];
  std::complex<double> MnmVector[numCoefficients];
  std::complex<double> rr,rtheta,rphi,I(0.0,1.0),eim;

  boxSize = rootBoxSize/(1 << numLevel);
  for( ii=0; ii<numBoxIndex; ii++ ) {
    for( i=particleOffset[0][ii]; i<=particleOffset[1][ii]; i++ ) {
      for( ij=0; ij<numInteraction[ii]; ij++ ) {
        jj = interactionList[ii][ij];
        jb = jj+levelOffset[numLevel-1];
        for( j=0; j<numCoefficients; j++ ) MnmVector[j] = Mnm[jb][j];
        tree.unmorton(boxIndexFull[jb],boxIndex3D);
        boxCenter.x = boxMin.x+(boxIndex3D.x+0.5)*boxSize;
        boxCenter.y = boxMin.y+(boxIndex3D.y+0.5)*boxSize;
        boxCenter.z = boxMin.z+(boxIndex3D.z+0.5)*boxSize;
        dist.x = bodyPos[i].x-boxCenter.x;
        dist.y = bodyPos[i].y-boxCenter.y;
        dist.z = bodyPos[i].z-boxCenter.z;
        cart2sph(r,theta,phi,dist.x,dist.y,dist.z);
        xx = cos(theta);
        yy = sin(theta);
        s2 = sqrt((1-xx)*(1+xx));
        fact = 1;
        pn = 1;
        for( m=0; m<numExpansions; m++ ) {
          p = pn;
          nm = m*m+2*m;
          YnmReal[nm] = factorial[nm]*p;
          p1 = p;
          p = xx*(2*m+1)*p;
          YnmRealTheta[nm] = factorial[nm]*(p-(m+1)*xx*p1)/yy;
          for( n=m+1; n<numExpansions; n++ ) {
            nm = n*n+n+m;
            YnmReal[nm] = factorial[nm]*p;
            p2 = p1;
            p1 = p;
            p = (xx*(2*n+1)*p1-(n+m)*p2)/(n-m+1);
            YnmRealTheta[nm] = factorial[nm]*((n-m+1)*p-(n+1)*xx*p1)/yy;
          }
          pn = -pn*fact*s2;
          fact += 2;
        }
        accelR = 0;
        accelTheta = 0;
        accelPhi = 0;
        rn = 1/r;
        for( n=0; n<numExpansions; n++ ) {
          rn /= r;
          nm = n*n+n;
          nms = n*(n+1)/2;
          rr = -(n+1)*rn*YnmReal[nm];
          rtheta = rn*r*YnmRealTheta[nm];
          accelR += real(rr*MnmVector[nms]);
          accelTheta += real(rtheta*MnmVector[nms]);
          for( m=1; m<=n; m++ ) {
            nm = n*n+n+m;
            nms = n*(n+1)/2+m;
            eim = exp(m*phi*I);
            rr = -(n+1)*rn*YnmReal[nm]*eim;
            rtheta = rn*r*YnmRealTheta[nm]*eim;
            rphi = m*rn*r*YnmReal[nm]*eim*I;
            accelR += 2*real(rr*MnmVector[nms]);
            accelTheta += 2*real(rtheta*MnmVector[nms]);
            accelPhi += 2*real(rphi*MnmVector[nms]);
          }
        }
        accel.x = sin(theta)*cos(phi)*accelR+cos(theta)*cos(phi)/r*accelTheta-sin(phi)/r/sin(theta)*accelPhi;
        accel.y = sin(theta)*sin(phi)*accelR+cos(theta)*sin(phi)/r*accelTheta+cos(phi)/r/sin(theta)*accelPhi;
        accel.z = cos(theta)*accelR-sin(theta)/r*accelTheta;
        bodyAccel[i].x += inv4PI*accel.x;
        bodyAccel[i].y += inv4PI*accel.y;
        bodyAccel[i].z += inv4PI*accel.z;
      }
    }
  }
}
示例#11
0
// precalculate M2L translation matrix and Wigner rotation matrix
void FmmKernel::precalc() {
  int n,m,nm,nabsm,j,k,nk,npn,nmn,npm,nmm,nmk,i,nmk1,nm1k,nmk2;
  vec3<int> boxIndex3D;
  vec3<double> dist;
  double anmk[2][numExpansion4];
  double Dnmd[numExpansion4];
  double fnma,fnpa,pn,p,p1,p2,anmd,anmkd,rho,alpha,beta,sc,ank,ek;
  std::complex<double> expBeta[numExpansion2],I(0.0,1.0);

  int jk,jkn,jnk;
  double fnmm,fnpm,fad;

  for( n=0; n<2*numExpansions; n++ ) {
    for( m=-n; m<=n; m++ ) {
      nm = n*n+n+m;
      nabsm = abs(m);
      fnmm = 1.0;
      for( i=1; i<=n-m; i++ ) fnmm *= i;
      fnpm = 1.0;
      for( i=1; i<=n+m; i++ ) fnpm *= i;
      fnma = 1.0;
      for( i=1; i<=n-nabsm; i++ ) fnma *= i;
      fnpa = 1.0;
      for( i=1; i<=n+nabsm; i++ ) fnpa *= i;
      factorial[nm] = sqrt(fnma/fnpa);
      fad = sqrt(fnmm*fnpm);
      anm[nm] = pow(-1.0,n)/fad;
    }
  }

  for( j=0; j<numExpansions; j++) {
    for( k=-j; k<=j; k++ ){
      jk = j*j+j+k;
      for( n=abs(k); n<numExpansions; n++ ) {
        nk = n*n+n+k;
        jkn = jk*numExpansion2+nk;
        jnk = (j+n)*(j+n)+j+n;
        Anm[jkn] = pow(-1.0,j+k)*anm[nk]*anm[jk]/anm[jnk];
      }
    }
  }

  pn = 1;
  for( m=0; m<2*numExpansions; m++ ) {
    p = pn;
    npn = m*m+2*m;
    nmn = m*m;
    Ynm[npn] = factorial[npn]*p;
    Ynm[nmn] = conj(Ynm[npn]);
    p1 = p;
    p = (2*m+1)*p;
    for( n=m+1; n<2*numExpansions; n++ ) {
      npm = n*n+n+m;
      nmm = n*n+n-m;
      Ynm[npm] = factorial[npm]*p;
      Ynm[nmm] = conj(Ynm[npm]);
      p2 = p1;
      p1 = p;
      p = ((2*n+1)*p1-(n+m)*p2)/(n-m+1);
    }
    pn = 0;
  }

  for( n=0; n<numExpansions; n++ ) {
    for( m=1; m<=n; m++ ) {
      anmd = n*(n+1)-m*(m-1);
      for( k=1-m; k<m; k++ ) {
        nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
        anmkd = ((double) (n*(n+1)-k*(k+1)))/(n*(n+1)-m*(m-1));
        anmk[0][nmk] = -(m+k)/sqrt(anmd);
        anmk[1][nmk] = sqrt(anmkd);
      }
    }
  }

  for( i=0; i<numRelativeBox; i++ ) {
    tree.unmorton(i,boxIndex3D);
    dist.x = boxIndex3D.x-3;
    dist.y = boxIndex3D.y-3;
    dist.z = boxIndex3D.z-3;
    cart2sph(rho,alpha,beta,dist.x,dist.y,dist.z);

    sc = sin(alpha)/(1+cos(alpha));
    for( n=0; n<4*numExpansions-3; n++ ) {
      expBeta[n] = exp((n-2*numExpansions+2)*beta*I);
    }

    for( n=0; n<numExpansions; n++ )  {
      nmk = (4*n*n*n+6*n*n+5*n)/3+n*(2*n+1)+n;
      Dnmd[nmk] = pow(cos(alpha*0.5),2*n);
      for( k=n; k>=1-n; k-- ) {
        nmk = (4*n*n*n+6*n*n+5*n)/3+n*(2*n+1)+k;
        nmk1 = (4*n*n*n+6*n*n+5*n)/3+n*(2*n+1)+k-1;
        ank = ((double) n+k)/(n-k+1);
        Dnmd[nmk1] = sqrt(ank)*tan(alpha*0.5)*Dnmd[nmk];
      }
      for( m=n; m>=1; m-- ) {
        for( k=m-1; k>=1-m; k-- ){
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nmk1 = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k+1;
          nm1k = (4*n*n*n+6*n*n+5*n)/3+(m-1)*(2*n+1)+k;
          Dnmd[nm1k] = anmk[1][nmk]*Dnmd[nmk1]+anmk[0][nmk]*sc*Dnmd[nmk];
        }
      }
    }

    for( n=1; n<numExpansions; n++ ) {
      for( m=0; m<=n; m++ ) {
        for( k=-m; k<=-1; k++ ) {
          ek = pow(-1.0,k);
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nmk1 = (4*n*n*n+6*n*n+5*n)/3-k*(2*n+1)-m;
          Dnmd[nmk] = ek*Dnmd[nmk];
          Dnmd[nmk1] = pow(-1.0,m+k)*Dnmd[nmk];
        }
        for( k=0; k<=m; k++ ) {
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nmk1 = (4*n*n*n+6*n*n+5*n)/3+k*(2*n+1)+m;
          nmk2 = (4*n*n*n+6*n*n+5*n)/3-k*(2*n+1)-m;
          Dnmd[nmk1] = pow(-1.0,m+k)*Dnmd[nmk];
          Dnmd[nmk2] = Dnmd[nmk1];
        }
      }
    }

    for( n=0; n<numExpansions; n++ ) {
      for( m=0; m<=n; m++ ) {
        for( k=-n; k<=n; k++ ) {
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nk = n*(n+1)+k;
          Dnm[i][m][nk] = Dnmd[nmk]*expBeta[k+m+2*numExpansions-2];
        }
      }
    }

    alpha = -alpha;
    beta = -beta;

    sc = sin(alpha)/(1+cos(alpha));
    for( n=0; n<4*numExpansions-3; n++ ) {
      expBeta[n] = exp((n-2*numExpansions+2)*beta*I);
    }

    for( n=0; n<numExpansions; n++ ) {
      nmk = (4*n*n*n+6*n*n+5*n)/3+n*(2*n+1)+n;
      Dnmd[nmk] = pow(cos(alpha*0.5),2*n);
      for( k=n; k>=1-n; k-- ) {
        nmk = (4*n*n*n+6*n*n+5*n)/3+n*(2*n+1)+k;
        nmk1 = (4*n*n*n+6*n*n+5*n)/3+n*(2*n+1)+k-1;
        ank = ((double) n+k)/(n-k+1);
        Dnmd[nmk1] = sqrt(ank)*tan(alpha*0.5)*Dnmd[nmk];
      }
      for( m=n; m>=1; m-- ) {
        for( k=m-1; k>=1-m; k-- ) {
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nmk1 = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k+1;
          nm1k = (4*n*n*n+6*n*n+5*n)/3+(m-1)*(2*n+1)+k;
          Dnmd[nm1k] = anmk[1][nmk]*Dnmd[nmk1]+anmk[0][nmk]*sc*Dnmd[nmk];
        }
      }
    }

    for( n=1; n<numExpansions; n++ ) {
      for( m=0; m<=n; m++ ) {
        for( k=-m; k<=-1; k++ ) {
          ek = pow(-1.0,k);
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nmk1 = (4*n*n*n+6*n*n+5*n)/3-k*(2*n+1)-m;
          Dnmd[nmk] = ek*Dnmd[nmk];
          Dnmd[nmk1] = pow(-1.0,m+k)*Dnmd[nmk];
        }
        for( k=0; k<=m; k++ ) {
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nmk1 = (4*n*n*n+6*n*n+5*n)/3+k*(2*n+1)+m;
          nmk2 = (4*n*n*n+6*n*n+5*n)/3-k*(2*n+1)-m;
          Dnmd[nmk1] = pow(-1.0,m+k)*Dnmd[nmk];
          Dnmd[nmk2] = Dnmd[nmk1];
        }
      }
    }

    for( n=0; n<numExpansions; n++ ) {
      for( m=0; m<=n; m++ ) {
        for( k=-n; k<=n; k++ ) {
          nmk = (4*n*n*n+6*n*n+5*n)/3+m*(2*n+1)+k;
          nk = n*(n+1)+k;
          Dnm[i+numRelativeBox][m][nk] = Dnmd[nmk]*expBeta[k+m+2*numExpansions-2];
        }
      }
    }
  }

  for( j=0; j<numBoxIndexTotal; j++ ) {
    for( i=0; i<numCoefficients; i++ ) {
      Mnm[j][i] = 0;
    }
  }
}
示例#12
0
// p2m
void FmmKernel::p2m(int numBoxIndex) {
  int jj,j,n,m,nm,nms;
  vec3<int> boxIndex3D;
  vec3<float> boxCenter;
  vec3<double> dist;
  double boxSize,rho,alpha,beta;
  double xx,s2,fact,pn,p,p1,p2,rhom,rhon;
  double YnmReal[numExpansion2];
  std::complex<double> MnmVector[numCoefficients],I(0.0,1.0),eim;

  boxSize = rootBoxSize/(1 << maxLevel);
  for( jj=0; jj<numBoxIndex; jj++ ) {
    tree.unmorton(boxIndexFull[jj],boxIndex3D);
    boxCenter.x = boxMin.x+(boxIndex3D.x+0.5)*boxSize;
    boxCenter.y = boxMin.y+(boxIndex3D.y+0.5)*boxSize;
    boxCenter.z = boxMin.z+(boxIndex3D.z+0.5)*boxSize;
    for( j=0; j<numCoefficients; j++ ) {
      MnmVector[j] = 0;
    }
    for( j=particleOffset[0][jj]; j<=particleOffset[1][jj]; j++ ) {
      dist.x = bodyPos[j].x-boxCenter.x;
      dist.y = bodyPos[j].y-boxCenter.y;
      dist.z = bodyPos[j].z-boxCenter.z;
      cart2sph(rho,alpha,beta,dist.x,dist.y,dist.z);
      xx = cos(alpha);
      s2 = sqrt((1-xx)*(1+xx));
      fact = 1;
      pn = 1;
      rhom = 1;
      for( m=0; m<numExpansions; m++ ) {
        p = pn;
        nm = m*m+2*m;
        YnmReal[nm] = rhom*factorial[nm]*p;
        p1 = p;
        p = xx*(2*m+1)*p;
        rhom *= rho;
        rhon = rhom;
        for( n=m+1; n<numExpansions; n++ ) {
          nm = n*n+n+m;
          YnmReal[nm] = rhon*factorial[nm]*p;
          p2 = p1;
          p1 = p;
          p = (xx*(2*n+1)*p1-(n+m)*p2)/(n-m+1);
          rhon *=rho;
        }
        pn = -pn*fact*s2;
        fact += 2;
      }
      for( n=0; n<numExpansions; n++ ) {
        for( m=0; m<=n; m++ ) {
          nm = n*n+n+m;
          nms = n*(n+1)/2+m;
          eim = exp(-m*beta*I);
          MnmVector[nms] += ((std::complex<double>) bodyPos[j].w)*YnmReal[nm]*eim;
        }
      }
    }
    for( j=0; j<numCoefficients; j++ ) {
      Mnm[jj][j] = MnmVector[j];
    }
  }
}
FE_TMPL std::complex<float> FE_SYS::_I(int n,int m,glm::vec3 x){
	glm::vec3 s = cart2sph(x);
	return std::pow(std::complex<float>(0,-1),-std::abs(m)) * _A(n,m) * std::pow(s.x,n) * _Y(n,m,s.y,s.z);
}
示例#14
0
void get_sources(ParamCoLoRe *par)
{
  //////
  // Uses the gaussian matter density field to obtain a
  // poisson sampling of point sources (returns an integer array
  // with the number of sources in each cell).
  int ii,nthr;
  lint *np_tot_thr;
#ifdef _HAVE_OMP
  nthr=omp_get_max_threads();
#else //_HAVE_OMP
  nthr=1;
#endif //_HAVE_OMP
  np_tot_thr=my_calloc(nthr,sizeof(lint));

  print_info("*** Getting point sources\n");
  if(NodeThis==0) timer(0);
  print_info("Poisson-sampling\n");
#ifdef _HAVE_OMP
#pragma omp parallel default(none)		\
  shared(par,np_tot_thr,IThread0)
#endif //_HAVE_OMP
  {
    lint iz;
#ifdef _HAVE_OMP
    int ithr=omp_get_thread_num();
#else //_HAVE_OMP
    int ithr=0;
#endif //_HAVE_OMP
    double dx=par->l_box/par->n_grid;
    double cell_vol=dx*dx*dx;
    int ngx=2*(par->n_grid/2+1);
    unsigned int seed_thr=par->seed_rng+IThread0+ithr;
    gsl_rng *rng_thr=init_rng(seed_thr);

#ifdef _HAVE_OMP
#pragma omp for schedule(static)
#endif //_HAVE_OMP
    for(iz=0;iz<par->nz_here;iz++) {
      int iy;
      lint indexz=iz*((lint)(ngx*par->n_grid));
      double z0=(iz+par->iz0_here+0.5)*dx-par->pos_obs[2];
      for(iy=0;iy<par->n_grid;iy++) {
	int ix;
	lint indexy=iy*ngx;
	double y0=(iy+0.5)*dx-par->pos_obs[1];
	for(ix=0;ix<par->n_grid;ix++) {
	  int npp=0;
	  double dz_rsd=0;
	  lint index=ix+indexy+indexz;
	  double x0=(ix+0.5)*dx-par->pos_obs[1];
	  double r=sqrt(x0*x0+y0*y0+z0*z0);
	  double redshift=z_of_r(par,r);
	  double ndens=ndens_of_z(par,redshift);
	  if(ndens>0) {
	    double bias=bias_of_z(par,redshift);
	    double gfb=dgrowth_of_r(par,r)*bias;
	    double lambda=ndens*cell_vol*
	      exp(gfb*(par->grid_dens[index]-0.5*gfb*par->sigma2_gauss));
	    npp=rng_poisson(lambda,rng_thr);
	    dz_rsd=par->grid_rvel[index]*vgrowth_of_r(par,r);
	  }

	  par->grid_rvel[index]=dz_rsd;
	  par->nsources[index]=npp;
	  np_tot_thr[ithr]+=npp;
	}
      }
    }//end omp for

    end_rng(rng_thr);
  }//end omp parallel
  if(NodeThis==0) timer(2);

  par->nsources_this=0;
  for(ii=0;ii<nthr;ii++)
    par->nsources_this+=np_tot_thr[ii];

  par->nsources_total=0;
#ifdef _HAVE_MPI
  MPI_Allreduce(&(par->nsources_this),&(par->nsources_total),1,LINT_MPI,MPI_SUM,MPI_COMM_WORLD);
#else //_HAVE_MPI
  par->nsources_total=par->nsources_this;
#endif //_HAVE_MPI

  print_info("  There will be %ld particles in total\n",(long)(par->nsources_total));
  //#ifdef _DEBUG
  //  printf("Node %d has %ld particles\n",NodeThis,(long)(par->nsources_this));
  //#endif //_DEBUG

  for(ii=nthr-1;ii>0;ii--) {
    int jj;
    lint nh=0;
    for(jj=0;jj<ii;jj++)
      nh+=np_tot_thr[jj];
    np_tot_thr[ii]=nh;
  }
  np_tot_thr[0]=0;
  //np_tot_thr now contains the id of the first particle in the thread

#ifdef _SPREC
  fftwf_free(par->grid_dens_f);
#else //_SPREC
  fftw_free(par->grid_dens_f);
#endif //_SPREC
  par->grid_dens_f=NULL;
  par->gals=my_malloc(par->nsources_this*sizeof(Gal));

  if(NodeThis==0) timer(0);
  print_info("Assigning coordinates\n");
#ifdef _HAVE_OMP
#pragma omp parallel default(none)		\
  shared(par,IThread0,np_tot_thr)
#endif //_HAVE_OMP
  {
    lint iz;
#ifdef _HAVE_OMP
    int ithr=omp_get_thread_num();
#else //_HAVE_OMP
    int ithr=0;
#endif //_HAVE_OMP
    double dx=par->l_box/par->n_grid;
    int ngx=2*(par->n_grid/2+1);
    unsigned int seed_thr=par->seed_rng+IThread0+ithr;
    gsl_rng *rng_thr=init_rng(seed_thr);

#ifdef _HAVE_OMP
#pragma omp for schedule(static)
#endif //_HAVE_OMP
    for(iz=0;iz<par->nz_here;iz++) {
      int iy;
      lint indexz=iz*((lint)(ngx*par->n_grid));
      double z0=(iz+par->iz0_here)*dx-par->pos_obs[2];
      for(iy=0;iy<par->n_grid;iy++) {
	int ix;
	lint indexy=iy*ngx;
	double y0=iy*dx-par->pos_obs[1];
	for(ix=0;ix<par->n_grid;ix++) {
	  double x0=ix*dx-par->pos_obs[1];
	  lint index=ix+indexy+indexz;
	  int npp=par->nsources[index];
	  if(npp>0) {
	    int ip;
	    double dz_rsd=par->grid_rvel[index];
	    for(ip=0;ip<npp;ip++) {
	      double cth,phi,r;
	      lint pid=np_tot_thr[ithr];
	      double x=x0+dx*rng_01(rng_thr);
	      double y=y0+dx*rng_01(rng_thr);
	      double z=z0+dx*rng_01(rng_thr);
	      cart2sph(x,y,z,&r,&cth,&phi);
	      par->gals[pid].ra=RTOD*phi;
	      par->gals[pid].dec=90-RTOD*acos(cth);
	      par->gals[pid].z0=z_of_r(par,r);
	      par->gals[pid].dz_rsd=dz_rsd;
	      np_tot_thr[ithr]++;
	    }
	  }
	}
      }
    }//end omp for
    end_rng(rng_thr);
  }//end omp parallel
  if(NodeThis==0) timer(2);

  free(np_tot_thr);
  print_info("\n");
}