00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define R0 (1.0) // Photosphere
00017 #define RS (2.5) // Source surface
00018 #define R0RS (R0 / RS)
00019 #define R0RS2 (R0RS * R0RS)
00020
00021
00022
00023
00024
00025
00026
00027 void rdr (double r, int lmax, double *rrr, double *D_rrr)
00028 {
00029
00030 double R0r = R0/r, rRS = r/RS, rRS2 = rRS*rRS;
00031 double R0rl1 = R0r, rRS2l1 = rRS, R0RS2l1 = R0RS;
00032
00033 for (int l = 0; l <= lmax; l++) {
00034 double denom = l + 1 + l * R0RS2l1;
00035 rrr[l] = R0 * R0rl1 * (1 - rRS2l1) / denom;
00036 D_rrr[l] = -R0r * R0rl1 * (l + 1 + l * rRS2l1) / denom;
00037 R0rl1 *= R0r; rRS2l1 *= rRS2; R0RS2l1 *= R0RS2;
00038 }
00039
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 void csmph (double ph, int lmax, double *g, double *h, double *mgh, double *D_mgh)
00052 {
00053
00054 for (int m = 0; m <= lmax; m++) {
00055 double cosmp = cos(m * ph), sinmp = sin(m * ph);
00056 for (int l = m; l <= lmax; l++) {
00057 int Dptp = (l + 1) * l / 2 + m;
00058 int Dpt = l * (lmax + 1) + m;
00059 mgh[Dptp] = g[Dpt] * cosmp + h[Dpt] * sinmp;
00060 D_mgh[Dptp] = - g[Dpt] * sinmp + h[Dpt] * cosmp;
00061 }
00062 }
00063
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 void pdpth (double th, int lmax, double *leg, double *D_leg, double *mlegs)
00082 {
00083 int Dptt;
00084 double cost, sint;
00085 double t0, t1, t2, dt0, dt1, dt2, t0s, t1s, t2s, expmi;
00086 double m2, l1, l12, s1, s2, f1;
00087
00088 cost = cos(th); sint = sin(th);
00089 for (int m = 0; m <= lmax; m++) {
00090 t1 = (m == 0) ? 1.0 : sqrt(2.0);
00091 t1s = t1;
00092 dt1 = t1 * m * cost;
00093 for (int mi = 0; mi < m; mi++) {
00094 expmi = sqrt((2.0 * mi + 1.0) / (2.0 * mi + 2.0));
00095 t1 *= (sint * expmi);
00096 if (m != 0) {
00097 dt1 *= sint;
00098 t1s *= sint;
00099 }
00100 dt1 *= expmi;
00101 t1s *= expmi;
00102 }
00103 Dptt = (m + 1) * m / 2 + m;
00104 leg[Dptt] = t1; D_leg[Dptt] = dt1; mlegs[Dptt] = t1s * m;
00105
00106 m2 = (double)(m) * m; t0 = 0.0; t0s = 0.0; dt0 = 0.0; s1 = 0.0;
00107 for (int l = m; l < lmax; l++) {
00108 l1 = l + 1.0; l12 = l1 * l1;
00109 s2 = sqrt(l12 - m2);
00110 f1 = 2.0 * l + 1.0;
00111 t2 = (f1 * cost * t1 - s1 * t0) / s2;
00112 t2s = (f1 * cost * t1s - s1 * t0s) / s2;
00113 dt2 = (f1 * (cost * dt1 - sint * t1) - s1 * dt0) / s2;
00114 Dptt = (l + 2) * (l + 1) / 2 + m;
00115 leg[Dptt] = t2; D_leg[Dptt] = dt2; mlegs[Dptt] = t2s * m;
00116 s1 = s2; t0 = t1; t1 = t2; t0s = t1s; t1s = t2s;
00117 dt0 = dt1; dt1 = dt2;
00118 }
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 void gh_pfss (double *br, int np, int nt, int lmax,
00137 double *p, double *t, double *kp, double *kt,
00138 double *g, double *h)
00139 {
00140
00141 int Dpt, Dptp, Dptt;
00142 int lmax1 = lmax + 1;
00143 int lmax12 = lmax1 * (lmax1 + 1) / 2;
00144 int nplmax1 = np * lmax1;
00145 int ntlmax12 = nt * lmax12;
00146
00147
00148
00149 double *cmph = (double *)(calloc(nplmax1, sizeof(double)));
00150 double *smph = (double *)(calloc(nplmax1, sizeof(double)));
00151
00152 for (int i = 0; i < np; i++) {
00153 for (int m = 0; m <= lmax; m++) {
00154 Dptp = i * lmax1 + m;
00155 cmph[Dptp] = cos(m * p[i]);
00156 smph[Dptp] = sin(m * p[i]);
00157 }
00158 }
00159
00160
00161
00162 double *leg = (double *)(calloc(ntlmax12, sizeof(double)));
00163 double *D_leg = (double *)(calloc(ntlmax12, sizeof(double)));
00164 double *mlegs = (double *)(calloc(ntlmax12, sizeof(double)));
00165
00166 for (int j = 0; j < nt; j++) {
00167 Dptt = j * lmax12;
00168 pdpth(t[j], lmax,
00169 (leg + Dptt), (D_leg + Dptt), (mlegs + Dptt));
00170 }
00171
00172
00173
00174 double w;
00175 for (int l = 0; l <= lmax; l++) {
00176 for (int m = 0; m <= l; m++) {
00177 double glm = 0.0, hlm = 0.0;
00178 for (int j = 0; j < nt; j++) {
00179 for (int i = 0; i < np; i++) {
00180 w = kp[i] * kt[j];
00181 Dpt = j * np + i;
00182 Dptp = j * lmax12 + l * (l + 1) / 2 + m;
00183 Dptt = i * lmax1 + m;
00184 glm += (br[Dpt] * leg[Dptp] * cmph[Dptt] * w);
00185 hlm += (br[Dpt] * leg[Dptp] * smph[Dptt] * w);
00186 }
00187 }
00188 g[l * lmax1 + m] = glm * (2 * l + 1.);
00189 h[l * lmax1 + m] = hlm * (2 * l + 1.);
00190 }
00191 h[l * lmax1] = 0.0;
00192 }
00193 g[0] = 0.0;
00194
00195 free(cmph); free(smph);
00196 free(leg); free(D_leg); free(mlegs);
00197
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 void pfss_cube (double *g, double *h, int lmax,
00212 double *p, double *t, double *r, int np, int nt, int nr,
00213 double *Bp, double *Bt, double *Br)
00214 {
00215
00216 int npnt = np * nt;
00217 int lmax1 = lmax + 1;
00218 int lmax12 = lmax1 * (lmax1 + 1) / 2;
00219 int nrlmax1 = nr * lmax1;
00220 int ntlmax12 = nt * lmax12;
00221 int nplmax12 = np * lmax12;
00222
00223
00224
00225 double *rrr = (double *)(calloc(nrlmax1, sizeof(double)));
00226 double *D_rrr = (double *)(calloc(nrlmax1, sizeof(double)));
00227 double *leg = (double *)(calloc(ntlmax12, sizeof(double)));
00228 double *D_leg = (double *)(calloc(ntlmax12, sizeof(double)));
00229 double *mlegs = (double *)(calloc(ntlmax12, sizeof(double)));
00230 double *mgh = (double *)(calloc(nplmax12, sizeof(double)));
00231 double *D_mgh = (double *)(calloc(nplmax12, sizeof(double)));
00232
00233
00234
00235 for (int n = 0; n < nr; n++) {
00236 int Dpt = n * lmax1;
00237 rdr(r[n], lmax, (rrr + Dpt), (D_rrr + Dpt));
00238 }
00239
00240 for (int j = 0; j < nt; j++) {
00241 int Dpt = j * lmax12;
00242 pdpth(t[j], lmax, (leg + Dpt), (D_leg + Dpt), (mlegs + Dpt));
00243 }
00244
00245 for (int i = 0; i < np; i++) {
00246 int Dpt = i * lmax12;
00247 csmph(p[i], lmax, g, h, (mgh + Dpt), (D_mgh + Dpt));
00248 }
00249
00250
00251
00252 for (int n = 0; n < nr; n++) {
00253
00254 double *rrr_t = rrr + n * lmax1;
00255 double *D_rrr_t = D_rrr + n * lmax1;
00256
00257 for (int j = 0; j < nt; j++) {
00258
00259 double *leg_t = leg + j * lmax12;
00260 double *D_leg_t = D_leg + j * lmax12;
00261 double *mlegs_t = mlegs + j * lmax12;
00262
00263 for (int i = 0; i < np; i++) {
00264
00265 double *mgh_t = mgh + i * lmax12;
00266 double *D_mgh_t = D_mgh + i * lmax12;
00267
00268 double x1 = 0.0, x2 = 0.0, x3 = 0.0;
00269
00270 for (int l = 0; l <= lmax; l++) {
00271
00272 int Dptr = l;
00273 int Dptt = (l + 1) * l / 2;
00274 int Dptp = (l + 1) * l / 2;
00275
00276 for (int m = 0; m <= l; m++) {
00277
00278 x1 += (D_rrr_t[Dptr] * leg_t[Dptt + m] * mgh_t[Dptp + m]);
00279 x2 += (rrr_t[Dptr] * D_leg_t[Dptt + m] * mgh_t[Dptp + m]);
00280 x3 += (rrr_t[Dptr] * mlegs_t[Dptt + m] * D_mgh_t[Dptp + m]);
00281
00282 }
00283 }
00284
00285 int Dpt = n * npnt + j * np + i;
00286 Br[Dpt] = - x1;
00287 Bt[Dpt] = - x2 / r[n];
00288 Bp[Dpt] = - x3 / r[n];
00289
00290 }
00291 }
00292 }
00293
00294
00295
00296 free(rrr); free(D_rrr);
00297 free(leg); free(D_leg); free(mlegs);
00298 free(mgh); free(D_mgh);
00299
00300 }
00301