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 #include "hccsss_pkg.h"
00049
00050
00051
00052
00053
00054
00055 void hchf(float r, double *rrr, double *D_rrr, int lmax, float apar)
00056 {
00057 int Dptr;
00058 double R02, r2;
00059 double aR0, aR0l;
00060 double ar, arl, arl1;
00061
00062 R02 = R0 * R0; r2 = r * r;
00063 aR0 = R0 + apar; aR0l = 1.0;
00064 ar = r + apar; arl = 1.0; arl1 = ar;
00065 for (int l = 0; l <= lmax; l++) {
00066 Dptr = l;
00067
00068 rrr[Dptr] = R02 * aR0l / ((l + 1.0) * arl1);
00069
00070 D_rrr[Dptr] = - R02 * aR0l / (r2 * arl);
00071 aR0l *= aR0; arl = arl1; arl1 *= ar;
00072 }
00073 }
00074
00075
00076
00077 void cshf(float r, double *rrr, double *D_rrr, int lc, float apar)
00078 {
00079 int Dptr;
00080 double RC2, r2;
00081 double aRC, aRC2, aRCl, aRCl1, aRC2l1;
00082 double aRS, aRS2, aRS2l1;
00083 double ar, ar2, arl, arl1, ar2l1;
00084
00085 RC2 = RCP * RCP; r2 = r * r;
00086 aRC = RCP + apar; aRCl = 1.0; aRCl1 = aRC;
00087 aRS = RSS + apar; aRS2 = aRS * aRS; aRS2l1 = aRS;
00088 ar = r + apar; arl = 1.0; arl1 = ar;
00089 for (int l = 0; l <= lc; l++) {
00090 Dptr = l;
00091 double denom = ((l + 1.0) * aRS2l1 + l * aRC2l1) / (aRCl * aRS2l1);
00092
00093 rrr[Dptr] = RC2 * (1.0 / arl1 - arl / aRS2l1) / denom;
00094
00095 D_rrr[Dptr] = - (RC2 / r2) *
00096 ((l + 1.0) / arl + l * arl1 / aRS2l1) / denom;
00097 aRCl = aRCl1; aRCl1 *= aRC;
00098 aRS2l1 *= aRS2;
00099 arl = arl1; arl1 *= ar;
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 void gh_hccsss(float *g, float *h, struct Grid *grid, int lmax,
00115 float *gc, float *hc, int lc, float apar)
00116 {
00117
00118 struct Grid *gridt;
00119 int nt, np, npnt;
00120 float *Brcp, *Btcp, *Bpcp;
00121 void (*rfunc)(float, double *, double *, int, float);
00122
00123 nt = grid->nt; np = grid->np; npnt = np * nt;
00124 gridt = (struct Grid *)(malloc(sizeof(struct Grid)));
00125 gridt->nr = 1; gridt->nt = nt; gridt->np = np;
00126 gridt->rr = (float *)(malloc(gridt->nr * sizeof(float)));
00127 gridt->th = (float *)(malloc(gridt->nt * sizeof(float)));
00128 gridt->ph = (float *)(malloc(gridt->np * sizeof(float)));
00129 gridt->rr[0] = RCP;
00130 for (int j = 0; j < nt; j++) gridt->th[j] = grid->th[j];
00131 for (int i = 0; i < np; i++) gridt->ph[i] = grid->ph[i];
00132
00133 Brcp = (float *)(malloc(npnt * sizeof(float)));
00134 Btcp = (float *)(malloc(npnt * sizeof(float)));
00135 Bpcp = (float *)(malloc(npnt * sizeof(float)));
00136
00137 rfunc = hchf;
00138
00139 Bcube(g, h, gridt, Brcp, Btcp, Bpcp, lmax, apar, rfunc);
00140
00141
00142
00143 int lc1 = lc + 1;
00144 int lc12 = lc1 * (lc1 + 1) / 2;
00145 int nplc1 = np * lc1;
00146 int ntlc12 = nt * lc12;
00147
00148
00149 double *leg = (double *)(calloc(ntlc12, sizeof(double)));
00150 double *D_leg = (double *)(calloc(ntlc12, sizeof(double)));
00151 for (int j = 0; j < nt; j++)
00152 pdpth(gridt->th[j], (leg + j * lc12), (D_leg + j * lc12), lc);
00153
00154
00155 double *cmph = (double *)(malloc(nplc1 * sizeof(double)));
00156 double *smph = (double *)(malloc(nplc1 * sizeof(double)));
00157 for (int i = 0; i < np; i++) {
00158 for (int m = 0; m <= lc; m++) {
00159 cmph[i * lc1 + m] = cos(m * gridt->ph[i]);
00160 smph[i * lc1 + m] = sin(m * gridt->ph[i]);
00161 }
00162 }
00163
00164
00165 double *sth = (double *)(malloc(nt * sizeof(double)));
00166 for (int j = 0; j < nt; j++)
00167 sth[j] = sin(gridt->th[j]);
00168
00169
00170 double *ar1 = (double *)(malloc(lc1 * sizeof(double)));
00171 double *ar2 = (double *)(malloc(lc1 * sizeof(double)));
00172 double *ar3 = (double *)(malloc(lc1 * lc1 * sizeof(double)));
00173
00174 double ars = apar + RSS, arc = apar + RCP;
00175 double ars2 = ars * ars, arc2 = arc * arc;
00176 double ars2l1 = ars, arc2l1 = arc;
00177 double Kl;
00178
00179 for (int l = 0; l <= lc; l++) {
00180 Kl = (RCP / arc) * (ars2l1 - arc2l1) /
00181 ((l + 1) * ars2l1 + l * arc2l1);
00182 ar1[l] = 1.0;
00183 ar2[l] = -1.0 * Kl;
00184 for (int m = 0; m <= l; m++)
00185 ar3[l * lc1 + m] = m * Kl;
00186 ars2l1 *= ars2; arc2l1 *= arc2;
00187 }
00188
00189
00190 int ixx = lc1 * lc1, iyy = 3 * npnt;
00191 double *ab = (double *)(malloc(ixx * iyy * sizeof(double)));
00192
00193 int lm, ptr0, ptr, ptrt0, ptrt, ptrp;
00194
00195
00196 ptr = 0;
00197 for (int l = 0; l <= lc; l++) {
00198 for (int m = 0; m <= l; m++) {
00199 lm = l * lc1 + m;
00200 ptrt0 = (l + 1) * l / 2 + m;
00201 for (int j = 0; j < nt; j++) {
00202 ptrt = j * lc12 + ptrt0;
00203 for (int i = 0; i < np; i++) {
00204 ptrp = i * lc1 + m;
00205 ab[ptr++] = ar1[l] * cmph[ptrp] * leg[ptrt];
00206 ab[ptr++] = ar2[l] * cmph[ptrp] * D_leg[ptrt];
00207 ab[ptr++] = ar3[lm] * smph[ptrp] * leg[ptrt] / sth[j];
00208 }}
00209 }}
00210
00211 for (int l = 1; l <= lc; l++) {
00212 for (int m = 1; m <= l; m++) {
00213 lm = l * lc1 + m;
00214 ptrt0 = (l + 1) * l / 2 + m;
00215 for (int j = 0; j < nt; j++) {
00216 ptrt = j * lc12 + ptrt0;
00217 for (int i = 0; i < np; i++) {
00218 ptrp = i * lc1 + m;
00219 ab[ptr++] = ar1[l] * smph[ptrp] * leg[ptrt];
00220 ab[ptr++] = ar2[l] * smph[ptrp] * D_leg[ptrt];
00221 ab[ptr++] = - ar3[lm] * cmph[ptrp] * leg[ptrt] / sth[j];
00222 }}
00223 }}
00224
00225
00226 double *abtab = (double *)(calloc(ixx * ixx, sizeof(double)));
00227 for (int ia = 0; ia < ixx; ia++) {
00228 for (int ib = 0; ib < ixx; ib++) {
00229 for (int ix = 0; ix < iyy; ix++)
00230 abtab[ia * ixx + ib] += ab[ia * iyy + ix] * ab[ib * iyy + ix];
00231 }}
00232
00233
00234 double *abtab1 = (double *)(calloc(ixx * ixx, sizeof(double)));
00235 for (int i = 0; i < ixx * ixx; i++) abtab1[i] = abtab[i];
00236
00237 int info;
00238 int *ipvt = (int *)(malloc(ixx * sizeof(int)));
00239 dgetrf_(&ixx, &ixx, abtab1, &ixx, ipvt, &info);
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 int lwork = 200 * ixx;
00252 double *work = (double *)(malloc(lwork * ixx * sizeof(double)));
00253 dgetri_(&ixx, abtab1, &ixx, ipvt, work, &lwork, &info);
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 double *Bout = (double *)(malloc(iyy * sizeof(double)));
00266 double sign;
00267 ptr = 0;
00268 for (int j = 0; j < nt; j++) {
00269 for (int i = 0; i < np; i++) {
00270 ptr0 = j * np + i;
00271 sign = (Brcp[ptr0] < 0) ? -1.0 : 1.0;
00272 Bout[ptr++] = Brcp[ptr0] * sign;
00273 Bout[ptr++] = Btcp[ptr0] * sign;
00274 Bout[ptr++] = Bpcp[ptr0] * sign;
00275 }}
00276
00277
00278 double *abB = (double *)(calloc(ixx, sizeof(double)));
00279 for (int ix = 0; ix < ixx; ix++) {
00280 for (int iy = 0; iy < iyy; iy++) {
00281 abB[ix] += ab[ix * iyy + iy] * Bout[iy];
00282 }}
00283
00284
00285 double *ghout = (double *)(calloc(ixx, sizeof(double)));
00286 for (int i = 0; i < ixx; i++) {
00287 for (int ix = 0; ix < ixx; ix++) {
00288 ghout[i] += abtab1[i * ixx + ix] * abB[ix];
00289 }}
00290
00291
00292 ptr = 0;
00293 for (int l = 0; l <= lc; l++) {
00294 for (int m = 0; m <= l; m++) {
00295 gc[l * lc1 + m] = ghout[ptr++];
00296 }}
00297 for (int l = 1; l <= lc; l++) {
00298 for (int m = 1; m <= l; m++) {
00299 hc[l * lc1 + m] = ghout[ptr++];
00300 }}
00301 for (int l = 0; l <= lc; l++) {
00302 for (int m = l + 1; m <= lc; m++) {
00303 gc[l * lc1 + m] = NAN;
00304 hc[l * lc1 + m] = NAN;
00305 }
00306 hc[l * lc1] = 0.0;
00307 }
00308
00309
00310 free(gridt->rr); free(gridt->th); free(gridt->ph); free(gridt);
00311 free(Brcp); free(Btcp); free(Bpcp);
00312 free(leg); free(D_leg);
00313 free(cmph); free(smph); free(sth);
00314 free(ar1); free(ar2); free(ar3);
00315 free(ab); free(abtab); free(abtab1);
00316 free(ipvt); free(work);
00317 free(Bout); free(abB); free(ghout);
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 void hccsss0_hc(float *g, float *h, struct Point *pt,
00327 float *Bvec, int lmax, float apar)
00328 {
00329 void (*rfunc)(float, double *, double *, int, float);
00330 rfunc = hchf;
00331 Bpoint(g, h, pt, Bvec, lmax, apar, rfunc);
00332 }
00333
00334
00335
00336 void hccsss0_cs(float *g, float *h, struct Point *pt,
00337 float *Bvec, int lmax, float apar)
00338 {
00339 void (*rfunc)(float, double *, double *, int, float);
00340 rfunc = cshf;
00341 Bpoint(g, h, pt, Bvec, lmax, apar, rfunc);
00342 }
00343
00344
00345
00346 void hccsss(float *g, float *h, float *gc, float *hc, struct Grid *grid,
00347 float *Br, float *Bt, float *Bp, int lmax, int lc, float apar)
00348 {
00349 int nt = grid->nt, np = grid->np;
00350 int npnt = np * nt;
00351
00352 int nr = grid->nr;
00353 int nr0, nr1;
00354 for (nr0 = 0; nr0 < nr; nr0++)
00355 if (grid->rr[nr0] > RCP) break;
00356 nr1 = nr - nr0;
00357
00358 void (*rfunc)(float, double *, double *, int, float);
00359 struct Grid *gridt = (struct Grid *)(malloc(sizeof(struct Grid)));
00360 gridt->nt = nt; gridt->np = np;
00361 gridt->th = (float *)(malloc(nt * sizeof(float)));
00362 gridt->ph = (float *)(malloc(np * sizeof(float)));
00363 for (int j = 0; j < nt; j++) gridt->th[j] = grid->th[j];
00364 for (int i = 0; i < np; i++) gridt->ph[i] = grid->ph[i];
00365
00366
00367 if (nr0 > 0) {
00368 rfunc = hchf;
00369 gridt->nr = nr0;
00370 gridt->rr = (float *)(malloc(nr0 * sizeof(float)));
00371 for (int n = 0; n < nr0; n++) gridt->rr[n] = grid->rr[n];
00372 Bcube(g, h, gridt, Br, Bt, Bp, lmax, apar, rfunc);
00373 free(gridt->rr);
00374 }
00375
00376
00377 if (nr1 > 0) {
00378 rfunc = cshf;
00379 gridt->nr = nr1;
00380 gridt->rr = (float *)(malloc(nr1 * sizeof(float)));
00381 for (int n = 0; n < nr1; n++) gridt->rr[n] = grid->rr[n + nr0];
00382 int Dpt = nr0 * npnt;
00383 float *Brt = Br + Dpt, *Btt = Bt + Dpt, *Bpt = Bp + Dpt;
00384 Bcube(gc, hc, gridt, Brt, Btt, Bpt, lc, apar, rfunc);
00385
00386 void (*integrator)(struct Point *, struct Point *, float *, float *, int, float, float,
00387 void (*)(float *, float *, struct Point *, float *, int, float));
00388 void (*Bfunc)(float *, float *, struct Point *, float *, int, float);
00389 integrator = Euler;
00390 Bfunc = hccsss0_cs;
00391 struct Point *pt0 = (struct Point *)(malloc(sizeof(struct Point)));
00392 struct Point *pt = (struct Point *)(malloc(sizeof(struct Point)));
00393 pt->r = RCP;
00394 struct FldLn *fl = (struct FldLn *)(malloc(sizeof(struct FldLn)));
00395 float Bvec[3];
00396 for (int n = 0; n < nr1; n++) {
00397 pt0->r = gridt->rr[n];
00398 for (int j = 0; j < nt; j++) {
00399 pt0->t = gridt->th[j];
00400 for (int i = 0; i < np; i++) {
00401 pt0->p = gridt->ph[i];
00402 trace(gc, hc, pt0, fl, lc, integrator, Bfunc, gridt->rr[n], RCP, apar);
00403 if (fl->num) {
00404 pt->t = fl->tt[fl->num];
00405 pt->p = fl->pp[fl->num];
00406 hccsss0_hc(g, h, pt, Bvec, lmax, apar);
00407 if (Bvec[0] < 0) {
00408 Dpt = n * npnt + j * np + i;
00409 Brt[Dpt] *= -1; Btt[Dpt] *= -1; Bpt[Dpt] *= -1;
00410 }
00411 }
00412 }}}
00413 free(pt); free(pt0); free(fl);
00414 free(gridt->rr);
00415 }
00416
00417 free(gridt->th); free(gridt->ph); free(gridt);
00418 }