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
00058
00059
00060
00061
00062 #include "fieldline_pkg.h"
00063
00064
00065
00066
00067
00068
00069 void copypoint(struct Point *pt1, struct Point *pt2)
00070 {
00071 pt2->r = pt1->r; pt2->t = pt1->t; pt2->p = pt1->p;
00072 pt2->x = pt1->x; pt2->y = pt1->y; pt2->z = pt1->z;
00073 }
00074
00075
00076
00077 void sph2cart(struct Point *pt)
00078 {
00079 pt->x = pt->r * sin(pt->t) * cos(pt->p);
00080 pt->y = pt->r * sin(pt->t) * sin(pt->p);
00081 pt->z = pt->r * cos(pt->t);
00082 }
00083
00084
00085
00086 void cart2sph(struct Point *pt)
00087 {
00088 pt->r = sqrt(pt->x * pt->x + pt->y * pt->y + pt->z * pt->z);
00089 pt->t = acos(pt->z / pt->r);
00090 pt->p = atan2(pt->y, pt->x);
00091 pt->p = (pt->p > 0) ? pt->p : (pt->p + 2.0 * M_PI);
00092 }
00093
00094
00095
00096 void vec_sph2car(float *vec_s, float *vec_c, struct Point *pt)
00097 {
00098 double costh = cos(pt->t), sinth = sin(pt->t);
00099 double cosph = cos(pt->p), sinph = sin(pt->p);
00100 double vec_abs = sqrt(vec_s[0] * vec_s[0] + vec_s[1] * vec_s[1] + vec_s[2] * vec_s[2]);
00101 vec_c[0] = (vec_s[0] * sinth * cosph + vec_s[1] * costh * cosph - vec_s[2] * sinph) / vec_abs;
00102 vec_c[1] = (vec_s[0] * sinth * sinph + vec_s[1] * costh * sinph + vec_s[2] * cosph) / vec_abs;
00103 vec_c[2] = (vec_s[0] * costh - vec_s[1] * sinth) / vec_abs;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void differential(float *dydx, float *Y, float *g, float *h,
00116 int lmax, float apar, float dir,
00117 void (*Bfunc)(float *, float *, struct Point *, float *, int, float))
00118 {
00119 struct Point *pt = (struct Point *)(malloc(sizeof(struct Point)));;
00120 pt->x = Y[0]; pt->y = Y[1]; pt->z = Y[2];
00121 cart2sph(pt);
00122 float Bvec[3];
00123 (*Bfunc)(g, h, pt, Bvec, lmax, apar);
00124 vec_sph2car(Bvec, dydx, pt);
00125 for (int i = 0; i < 3; i++)
00126 dydx[i] *= (dir * pt->r);
00127 free(pt);
00128 }
00129
00130
00131
00132
00133
00134 void RK4(struct Point *pt1, struct Point *pt2, float *g, float *h,
00135 int lmax, float apar, float dir,
00136 void (*Bfunc)(float *, float *, struct Point *, float *, int, float))
00137 {
00138 float Y[3], Yt[3];
00139 float k1[3], k2[3], k3[3], k4[3];
00140
00141
00142 Y[0] = pt1->x; Y[1] = pt1->y; Y[2] = pt1->z;
00143 differential(k1, Y, g, h, lmax, apar, dir, Bfunc);
00144 for (int i = 0; i < 3; i++) Yt[i] = Y[i] + STEP * k1[i] / 2.0;
00145 differential(k2, Yt, g, h, lmax, apar, dir, Bfunc);
00146 for (int i = 0; i < 3; i++) Yt[i] = Y[i] + STEP * k2[i] / 2.0;
00147 differential(k3, Yt, g, h, lmax, apar, dir, Bfunc);
00148 for (int i = 0; i < 3; i++) Yt[i] = Y[i] + STEP * k3[i];
00149 differential(k4, Yt, g, h, lmax, apar, dir, Bfunc);
00150 pt2->x = Y[0] + STEP * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6.0;
00151 pt2->y = Y[1] + STEP * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6.0;
00152 pt2->z = Y[2] + STEP * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6.0;
00153 }
00154
00155
00156 void Euler(struct Point *pt1, struct Point *pt2, float *g, float *h,
00157 int lmax, float apar, float dir,
00158 void (*Bfunc)(float *, float *, struct Point *, float *, int, float))
00159 {
00160 float Y[3], k[3];
00161 Y[0] = pt1->x; Y[1] = pt1->y; Y[2] = pt1->z;
00162 differential(k, Y, g, h, lmax, apar, dir, Bfunc);
00163 pt2->x = Y[0] + STEP * k[0];
00164 pt2->y = Y[1] + STEP * k[1];
00165 pt2->z = Y[2] + STEP * k[2];
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 void compute_fte(float *g, float *h, struct FldLn *fl, int lmax,
00175 float r_hi, float r_lo, float apar,
00176 void (*Bfunc)(float *, float *, struct Point *, float *, int, float))
00177 {
00178 struct Point *pt = (struct Point *)(malloc(sizeof(struct Point)));
00179 pt->r = r_lo;
00180 pt->t = fl->tt[fl->num];
00181 pt->p = fl->pp[fl->num];
00182 float Bvec[3];
00183 (*Bfunc)(g, h, pt, Bvec, lmax, apar);
00184 fl->fte = (Bvec[0] / fabs(fl->brss)) * (r_lo * r_lo) / (r_hi * r_hi);
00185 free(pt);
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 void trace(float *g, float *h, struct Point *pt0, struct FldLn *fl, int lmax,
00196 void (*integrator)(struct Point *, struct Point *, float *, float *, int, float, float,
00197 void (*)(float *, float *, struct Point *, float *, int, float)),
00198 void (*Bfunc)(float *, float *, struct Point *, float *, int, float),
00199 float r_hi, float r_lo, float apar)
00200 {
00201
00202
00203 struct Point *pt = (struct Point *)(malloc(sizeof(struct Point)));
00204 struct Point *ptt = (struct Point *)(malloc(sizeof(struct Point)));
00205
00206
00207 fl->op_cl = 1;
00208 float bvec[3];
00209
00210 (*Bfunc)(g, h, pt0, bvec, lmax, apar);
00211 fl->brss = bvec[0];
00212 float dir = (bvec[0] > 0) ? -1. : 1.;
00213
00214
00215 sph2cart(pt0);
00216 copypoint(pt0, pt);
00217 int count = 0;
00218
00219 while (pt->r <= r_hi && pt->r >= r_lo && count < MAXSTP) {
00220
00221 fl->rr[count] = pt->r;
00222 fl->tt[count] = pt->t;
00223 fl->pp[count] = pt->p;
00224
00225 (*integrator)(pt, ptt, g, h, lmax, apar, dir, Bfunc);
00226 cart2sph(ptt);
00227 copypoint(ptt, pt);
00228 count++;
00229 }
00230 if (count < MAXSTP) {
00231 fl->num = count - 1;
00232 compute_fte(g, h, fl, lmax, r_hi, r_lo, apar, Bfunc);
00233 }
00234 free(pt); free(ptt);
00235 }
00236