Changeset 37537
- Timestamp:
- Oct 30, 2014, 6:33:23 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20140904/Ohana/src/libohana/src/spherical.c
r37536 r37537 1 1 # include "ohana.h" 2 2 3 void VSH () { 3 typedef struct { 4 double *dR_B; 5 double *dR_E; 6 double *dD_B; 7 double *dD_E; 8 int lmax; 9 int Nterms; 10 } VSHterms; 11 12 VSHterms *InitVSHterms (int lmax) { 13 14 // 0,0 -- N = 1, S = 1 15 // 1,-1; 1,0; 1,1 -- N = 3, S = 4 16 // 2,-2; 2,-1; 2,0; 2,1; 2,2 -- N = 5, S = 9 17 // 3,-3; 3,-2; 3,-1; 3,0; 3,1; 3,2, 3,3 -- N = 7, S = 16 18 int 19 20 } 21 22 void getVSHterms (int lmax, double R, double D, VSHterms *VlmSet) { 4 23 5 24 // given a point on the sky R,D … … 15 34 // dD^E = \sum_{l,m} e_{l,m} dD^E_{l,m} (l,m,R,D) 16 35 36 // dR^E_{l,m} is Valeri's Elm, item[0], dD^E_{l,m} is Valeri's Elm, item[1] 37 // dR^B_{l,m} is Valeri's Blm, item[0], dD^B_{l,m} is Valeri's Blm, item[1] 38 17 39 // NOTE : as implemented by Valeri, the coeffs b_{l,m} are the same for both R and D 18 40 // components; ditto for e_{l,m} 19 41 20 // there are thus for X_l,m terms that need to be generated, for dR^B, dR^E, dD^B, dD^E. Valeri calls21 // these S_lm_lat and S_lm_lon42 // there are thus 4 X_l,m terms that need to be generated, for dR^B, dR^E, dD^B, dD^E. 43 // Valeri calls these S_lm_lat and S_lm_lon 22 44 23 45 // dR^B_{l,m} = +S^D_{l,m}(l,m,R,D) … … 27 49 // dD^E_{l,m} = +S^D_{l,m}(l,m,R,D) 28 50 29 // S^R_{l,m} :51 // S^R_{l,m} == Slm_lng 30 52 // (m > 0) : -m S_{l,m}(l,-m,R,D) 31 53 // (m <= 0) : -m S_{l,m}(l,-m,R,D) 32 54 // NOTE: these are in fact the same... 55 // NOTE: sending in -m means we get sin() for (m > 0) and cos() for (m <= 0) 33 56 34 // S_^D_{l,m} : 35 // P_{l,m}(D) 57 // S_{l,m}(l,m,R,D) : 58 // aP_{l,m} = gsl_Plm(l,|m|,cos(90-D)) 59 60 // (m > 0) : S_{l,m} = aP_{l,m}*cos(m*R) = gsl_Plm(l,|m|,cos(90-D))*cos(|m|*R) [cos(x) == cos(-x)] 61 // (m < 0) : S_{l,m} = aP_{l,m}*sin(|m|*R) = gsl_Plm(l,|m|,cos(90-D))*sin(|m|*R) 62 // (m == 0) : S_{l,m} = aP_{l,m} = gsl_Plm(l,|m|,cos(90-D)) 63 64 // S^R_{l,m} = -m S_{l,m}(l,-m,R,D) 65 // (m > 0) : S^R_{l,m} = -m aP_lm*sin(|m|*R) 66 // (m < 0) : S^R_{l,m} = -m aP_lm*cos(|m|*R) 67 // (m == 0) : S^R_{l,m} = 0 68 69 // S_^D_{l,m} == Slm_lat: 70 // 71 // aP_{l, m}(D) = gsl_Plm(l, |m|,cos(90-D)) 72 // aP_{l+1,m}(D) = gsl_Plm(l+1,|m|,cos(90-D)) 73 74 // dPlm_dD = ((l+1)*sin(D)*aP_{l,m} - (l+1-|m|)*aP_{l+1,m}) / cos(D) 75 // dSlm_dD 76 // (m == 0) : dPlm_dD 77 // (m > 0) : dPlm_dD*cos( m *R) 78 // (m < 0) : dPlm_dD*sin(|m|*R) 79 80 double Rrad = R * RAD_DEG; 81 double Drad = D * RAD_DEG; 82 83 int l, m; 84 int n = 0; 85 for (l = 1; l < lmax; l++) { 86 87 for (m = -l; m <= l; m++) { 88 89 int m_abs = abs(m); 90 double aP_lm = gsl_sf_legendre_Plm(l, m_abs, cos(M_PI/2 - Drad)); // alt-P_lm = P_lm (l, |m|, cos(90 - D)) 91 92 // note that for m == 0, S_R_lm -> 0 (due to m*) 93 double S_R_lm = (m > 0) ? -m * aP_lm * sin (m_abs * Rrad) : -m * aP_lm * cos (m_abs * Rrad) ; 94 95 double aP_lp1m = gsl_sf_legendre_Plm(l + 1, m_abs, cos(M_PI/2 - Drad)); 96 // reuse for aP_lm above? 97 98 double dPlm_dD = ((l+1) * sin(Drad) * aP_lm - (l+1-m_abs)*aP_lp1m) / cos(D); 99 // XXX : this diverges @ D = 90.0?? 100 101 double S_D_lm = (m < 0) ? dPlm_dD * sin(m_abs * Rrad) : dPlm_dD * cos(m_abs * Rrad); 36 102 103 VlmSet->dR_B[n] = +S_D_lm; 104 VlmSet->dD_B[n] = -S_R_lm / cos(Drad); 105 VlmSet->dR_E[n] = +S_R_lm / cos(Drad); 106 VlmSet->dR_B[n] = +S_D_lm; 107 n++; 108 } 109 } 37 110 } 111
Note:
See TracChangeset
for help on using the changeset viewer.
