00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include "pfss_pkg.h"
00058
00059
00060
00061
00062
00063
00064 void rdr(float r, double *rrr, double *D_rrr, int lmax, float apar)
00065 {
00066 int Dptr;
00067 double R0r, rRS, rRS2;
00068 double R0rl1, rRS2l1, R0RS2l1;
00069 R0r = R0/r; rRS = r/RS; rRS2 = rRS*rRS;
00070 R0rl1 = R0r; rRS2l1 = rRS; R0RS2l1 = R0RS;
00071
00072 for (int l = 0; l <= lmax; l++) {
00073 Dptr = l;
00074 double denom = l + 1 + l * R0RS2l1;
00075 rrr[Dptr] = R0 * R0rl1 * (1 - rRS2l1) / denom;
00076 D_rrr[Dptr] = -R0r * R0rl1 * (l + 1 + l * rRS2l1) / denom;
00077 R0rl1 *= R0r; rRS2l1 *= rRS2; R0RS2l1 *= R0RS2;
00078 }
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 void pdpth(float th, double *leg, double *D_leg, int lmax)
00089 {
00090 int Dptt;
00091 double cost, sint;
00092 double t0, t1, t2, dt0, dt1, dt2, expmi;
00093 double m2, l1, l12, s1, s2, f1;
00094
00095 cost = cos(th); sint = sin(th);
00096 for (int m = 0; m <= lmax; m++) {
00097 t1 = (m == 0) ? 1.0 : sqrt(2.0);
00098 dt1 = t1 * m * cost / sint;
00099 for (int mi = 0; mi < m; mi++) {
00100 expmi = sint * sqrt((2.0 * mi + 1.0) / (2.0 * mi + 2.0));
00101 t1 *= expmi; dt1 *= expmi;
00102 }
00103 Dptt = (m + 1) * m / 2 + m;
00104 leg[Dptt] = t1; D_leg[Dptt] = dt1;
00105 m2 = (double)(m) * m; t0 = 0.0; dt0 = 0.0; s1 = 0.0;
00106 for (int l = m; l < lmax; l++) {
00107 l1 = l + 1.0; l12 = l1 * l1;
00108 s2 = sqrt(l12 - m2);
00109 f1 = 2.0 * l + 1.0;
00110 t2 = (f1 * cost * t1 - s1 * t0) / s2;
00111 dt2 = (f1 * (cost * dt1 - sint * t1) - s1 * dt0) / s2;
00112 Dptt = (l + 2) * (l + 1) / 2 + m;
00113 leg[Dptt] = t2; D_leg[Dptt] = dt2;
00114 s1 = s2; t0 = t1; t1 = t2; dt0 = dt1; dt1 = dt2;
00115 }
00116 }
00117 }
00118
00119
00120
00121 void csmph(float ph, double *mgh, double *D_mgh, float *g, float *h, int lmax)
00122 {
00123 int Dptp, Dpt;
00124 double sinmp, cosmp;
00125
00126 for (int m = 0; m <= lmax; m++) {
00127 cosmp = cos(m * ph); sinmp = sin(m * ph);
00128 for (int l = m; l <= lmax; l++) {
00129 Dptp = (l + 1) * l / 2 + m;
00130 Dpt = l * (lmax + 1) + m;
00131 mgh[Dptp] = g[Dpt] * cosmp + h[Dpt] * sinmp;
00132 D_mgh[Dptp] = -m * g[Dpt] * sinmp + m * h[Dpt] * cosmp;
00133 }
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144 void gh_pfss(float *map, float *g, float *h, struct Grid *grid,
00145 int lmax, int sinlat)
00146 {
00147 double *cmph, *smph;
00148 double *leg, *D_leg;
00149 double glm, hlm;
00150
00151 int np = grid->np, nt = grid->nt;
00152 float ph, th, kl;
00153 float kth, sinthdth, mdcosth[nt];
00154 int Dpt, Dptp, Dptt;
00155 int i, j, l, m;
00156 int lmax1 = lmax + 1;
00157 int lmax12 = lmax1 * (lmax1 + 1) / 2;
00158 int nplmax1 = np * lmax1;
00159 int ntlmax12 = nt * lmax12;
00160
00161 cmph = (double *)(calloc(nplmax1, sizeof(double)));
00162 smph = (double *)(calloc(nplmax1, sizeof(double)));
00163 leg = (double *)(calloc(ntlmax12, sizeof(double)));
00164 D_leg = (double *)(calloc(ntlmax12, sizeof(double)));
00165
00166 for (i = 0; i < np; i++) {
00167 ph = grid->ph[i];
00168
00169
00170 for (m = 0; m <= lmax; m++) {
00171 Dptp = i * lmax1 + m;
00172 cmph[Dptp] = cos(m * ph); smph[Dptp] = sin(m * ph);
00173 }
00174 }
00175
00176 for (j = 0; j < nt; j++) {
00177 th = grid->th[j];
00178 mdcosth[j] = cos((nt - j - 1) * M_PI / nt) -
00179 cos((nt - j) * M_PI / nt);
00180 Dptt = j * lmax12;
00181 pdpth(th, (leg + Dptt), (D_leg + Dptt), lmax);
00182 }
00183
00184
00185 sinthdth = 2.0 / nt;
00186 for (l = 0; l <= lmax; l++) {
00187 kl = (2.0 * l + 1.0) / (2.0 * np);
00188 for (m = 0; m <= l; m++) {
00189 glm = 0.0; hlm = 0.0;
00190 for (j = 0; j < nt; j++) {
00191 kth = sinlat ? sinthdth : mdcosth[j];
00192 for (i = 0; i < np; i++) {
00193 Dpt = j * np + i;
00194 Dptp = j * lmax12 + l * (l + 1) / 2 + m;
00195 Dptt = i * lmax1 + m;
00196 glm += map[Dpt] * leg[Dptp] * cmph[Dptt] * kth;
00197 hlm += map[Dpt] * leg[Dptp] * smph[Dptt] * kth;
00198 }
00199 }
00200 g[l * lmax1 + m] = glm * kl;
00201 h[l * lmax1 + m] = hlm * kl;
00202 }
00203 h[l * lmax1] = 0.0;
00204 }
00205
00206 free(cmph); free(smph);
00207 free(leg); free(D_leg);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216 void Brtp(float r, float sint, float *Br0, float *Bt0, float *Bp0,
00217 struct CombinedCoeff *CmbCoeff, int lmax)
00218 {
00219 int Dptr, Dptt, Dptp;
00220 double fr, dfr, ft, dft, fp, dfp;
00221 double x1 = 0.0, x2 = 0.0, x3 = 0.0;
00222 for (int l = 0; l <= lmax; l++) {
00223 Dptr = l;
00224 Dptt = (l + 1) * l / 2;
00225 Dptp = (l + 1) * l / 2;
00226 for (int m = 0; m <= l; m++) {
00227 fr = CmbCoeff->rrr[Dptr];
00228 dfr = CmbCoeff->D_rrr[Dptr];
00229 ft = CmbCoeff->leg[Dptt + m];
00230 dft = CmbCoeff->D_leg[Dptt + m];
00231 fp = CmbCoeff->mgh[Dptp + m];
00232 dfp = CmbCoeff->D_mgh[Dptp + m];
00233 x1 += (dfr * ft * fp);
00234 x2 += (fr * dft * fp);
00235 x3 += (fr * ft * dfp);
00236 }
00237 }
00238 *Br0 = -x1;
00239 *Bt0 = -x2 / r;
00240 *Bp0 = -x3 / r / sint;
00241 }
00242
00243
00244
00245
00246
00247 void Bcube(float *g, float *h, struct Grid *grid, float *Br,
00248 float *Bt, float *Bp, int lmax, float apar,
00249 void (*rfunc)(float, double *, double *, int, float))
00250 {
00251 int np = grid->np, nt = grid->nt, nr = grid->nr;
00252 int npnt = np * nt;
00253 int lmax1 = lmax + 1;
00254 int lmax12 = lmax1 * (lmax1 + 1) / 2;
00255 int nrlmax1 = nr * lmax1;
00256 int ntlmax12 = nt * lmax12;
00257 int nplmax12 = np * lmax12;
00258
00259
00260 int sz = sizeof(double);
00261 double *rrr = (double *)(calloc(nrlmax1, sz));
00262 double *D_rrr = (double *)(calloc(nrlmax1, sz));
00263 double *leg = (double *)(calloc(ntlmax12, sz));
00264 double *D_leg = (double *)(calloc(ntlmax12, sz));
00265 double *mgh = (double *)(calloc(nplmax12, sz));
00266 double *D_mgh = (double *)(calloc(nplmax12, sz));
00267
00268
00269 for (int n = 0; n < nr; n++)
00270 rfunc(grid->rr[n], (rrr + n * lmax1), (D_rrr + n * lmax1), lmax, apar);
00271 for (int j = 0; j < nt; j++)
00272 pdpth(grid->th[j], (leg + j * lmax12), (D_leg + j * lmax12), lmax);
00273 for (int i = 0; i < np; i++)
00274 csmph(grid->ph[i], (mgh + i * lmax12), (D_mgh + i * lmax12), g, h, lmax);
00275
00276
00277 struct CombinedCoeff *CmbCoeff =
00278 (struct CombinedCoeff *)(malloc(sizeof(struct CombinedCoeff)));
00279
00280 for (int n = 0; n < nr; n++) {
00281 float r = grid->rr[n];
00282 CmbCoeff->rrr = rrr + n * lmax1;
00283 CmbCoeff->D_rrr = D_rrr + n * lmax1;
00284 for (int j = 0; j < nt; j++) {
00285 float sint = sin(grid->th[j]);
00286 CmbCoeff->leg = leg + j * lmax12;
00287 CmbCoeff->D_leg = D_leg + j * lmax12;
00288 for (int i = 0; i < np; i++) {
00289 int Dpt = n * npnt + j * np + i;
00290 float *B1 = Br + Dpt;
00291 float *B2 = Bt + Dpt;
00292 float *B3 = Bp + Dpt;
00293 CmbCoeff->mgh = mgh + i * lmax12;
00294 CmbCoeff->D_mgh = D_mgh + i * lmax12;
00295
00296 Brtp(r, sint, B1, B2, B3, CmbCoeff, lmax);
00297 }
00298 }
00299 }
00300
00301 free(rrr); free(D_rrr);
00302 free(leg); free(D_leg);
00303 free(mgh); free(D_mgh);
00304 free(CmbCoeff);
00305 }
00306
00307
00308 void Bpoint(float *g, float *h, struct Point *pt,
00309 float *Bvec, int lmax, float apar,
00310 void (*rfunc)(float, double *, double *, int, float))
00311 {
00312 int lmax1 = lmax + 1;
00313 int lmax12 = lmax1 * (lmax1 + 1) / 2;
00314 int sz = sizeof(double);
00315
00316 struct CombinedCoeff *CmbCoeff =
00317 (struct CombinedCoeff *)(malloc(sizeof(struct CombinedCoeff)));
00318 CmbCoeff->rrr = (double *)(calloc(lmax1, sz));
00319 CmbCoeff->D_rrr = (double *)(calloc(lmax1, sz));
00320 CmbCoeff->leg = (double *)(calloc(lmax12, sz));
00321 CmbCoeff->D_leg = (double *)(calloc(lmax12, sz));
00322 CmbCoeff->mgh = (double *)(calloc(lmax12, sz));
00323 CmbCoeff->D_mgh = (double *)(calloc(lmax12, sz));
00324
00325 rfunc(pt->r, CmbCoeff->rrr, CmbCoeff->D_rrr, lmax, apar);
00326 pdpth(pt->t, CmbCoeff->leg, CmbCoeff->D_leg, lmax);
00327 csmph(pt->p, CmbCoeff->mgh, CmbCoeff->D_mgh, g, h, lmax);
00328
00329 float B1, B2, B3;
00330 Brtp(pt->r, sin(pt->t), &B1, &B2, &B3, CmbCoeff, lmax);
00331 Bvec[0] = B1; Bvec[1] = B2; Bvec[2] = B3;
00332
00333 free(CmbCoeff->rrr); free(CmbCoeff->D_rrr);
00334 free(CmbCoeff->leg); free(CmbCoeff->D_leg);
00335 free(CmbCoeff->mgh); free(CmbCoeff->D_mgh);
00336 free(CmbCoeff);
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 void pfss0(float *g, float *h, struct Point *pt,
00346 float *Bvec, int lmax, float apar)
00347 {
00348 void (*rfunc)(float, double *, double *, int, float);
00349 rfunc = rdr;
00350 Bpoint(g, h, pt, Bvec, lmax, 0.0, rfunc);
00351 }
00352
00353
00354
00355 void pfss(float *g, float *h, struct Grid *grid,
00356 float *Br, float *Bt, float *Bp, int lmax, float apar)
00357 {
00358 void (*rfunc)(float, double *, double *, int, float);
00359 rfunc = rdr;
00360 Bcube(g, h, grid, Br, Bt, Bp, lmax, 0.0, rfunc);
00361 }