1 xudong 1.1 /*===========================================
|
2 xudong 1.27
3 The following 14 functions calculate the following spaceweather indices:
4
5 USFLUX Total unsigned flux in Maxwells
6 MEANGAM Mean inclination angle, gamma, in degrees
7 MEANGBT Mean value of the total field gradient, in Gauss/Mm
8 MEANGBZ Mean value of the vertical field gradient, in Gauss/Mm
9 MEANGBH Mean value of the horizontal field gradient, in Gauss/Mm
10 MEANJZD Mean vertical current density, in mA/m2
11 TOTUSJZ Total unsigned vertical current, in Amperes
12 MEANALP Mean twist parameter, alpha, in 1/Mm
13 MEANJZH Mean current helicity in G2/m
14 TOTUSJH Total unsigned current helicity in G2/m
15 ABSNJZH Absolute value of the net current helicity in G2/m
16 SAVNCPP Sum of the Absolute Value of the Net Currents Per Polarity in Amperes
17 MEANPOT Mean photospheric excess magnetic energy density in ergs per cubic centimeter
18 TOTPOT Total photospheric magnetic energy density in ergs per cubic centimeter
19 MEANSHR Mean shear angle (measured using Btotal) in degrees
|
20 mbobra 1.29 R_VALUE Karel Schrijver's R parameter
|
21 xudong 1.27
22 The indices are calculated on the pixels in which the conf_disambig segment is greater than 70 and
23 pixels in which the bitmap segment is greater than 30. These ranges are selected because the CCD
24 coordinate bitmaps are interpolated for certain data (at the time of this CVS submit, all data
25 prior to 2013.08.21_17:24:00_TAI contain interpolated bitmaps; data post-2013.08.21_17:24:00_TAI
26 contain nearest-neighbor bitmaps).
27
28 In the CCD coordinates, this means that we are selecting the pixels that equal 90 in conf_disambig
29 and the pixels that equal 33 or 34 in bitmap. Here are the definitions of the pixel values:
30
31 For conf_disambig:
32 50 : not all solutions agree (weak field method applied)
33 60 : not all solutions agree (weak field + annealed)
34 90 : all solutions agree (strong field + annealed)
35 0 : not disambiguated
36
37 For bitmap:
38 1 : weak field outside smooth bounding curve
39 2 : strong field outside smooth bounding curve
40 33 : weak field inside smooth bounding curve
41 34 : strong field inside smooth bounding curve
42 xudong 1.27
43 Written by Monica Bobra 15 August 2012
44 Potential Field code (appended) written by Keiji Hayashi
45 Error analysis modification 21 October 2013
46
47 ===========================================*/
|
48 xudong 1.1 #include <math.h>
|
49 mbobra 1.9 #include <mkl.h>
|
50 xudong 1.1
|
51 mbobra 1.9 #define PI (M_PI)
|
52 xudong 1.1 #define MUNAUGHT (0.0000012566370614) /* magnetic constant */
53
54 /*===========================================*/
55
56 /* Example function 1: Compute total unsigned flux in units of G/cm^2 */
57
|
58 xudong 1.27 // To compute the unsigned flux, we simply calculate
|
59 xudong 1.1 // flux = surface integral [(vector Bz) dot (normal vector)],
60 // = surface integral [(magnitude Bz)*(magnitude normal)*(cos theta)].
61 // However, since the field is radial, we will assume cos theta = 1.
62 // Therefore the pixels only need to be corrected for the projection.
63
64 // To convert G to G*cm^2, simply multiply by the number of square centimeters per pixel.
65 // As an order of magnitude estimate, we can assign 0.5 to CDELT1 and 722500m/arcsec to (RSUN_REF/RSUN_OBS).
66 // (Gauss/pix^2)(CDELT1)^2(RSUN_REF/RSUN_OBS)^2(100.cm/m)^2
|
67 mbobra 1.20 // =Gauss*cm^2
|
68 xudong 1.1
|
69 xudong 1.27 int computeAbsFlux(float *bz_err, float *bz, int *dims, float *absFlux,
70 float *mean_vf_ptr, float *mean_vf_err_ptr, float *count_mask_ptr, int *mask,
|
71 mbobra 1.9 int *bitmask, float cdelt1, double rsun_ref, double rsun_obs)
|
72 xudong 1.1
73 {
|
74 xudong 1.27
|
75 mbobra 1.14 int nx = dims[0];
76 int ny = dims[1];
|
77 mbobra 1.15 int i = 0;
78 int j = 0;
79 int count_mask = 0;
80 double sum = 0.0;
81 double err = 0.0;
|
82 mbobra 1.14 *absFlux = 0.0;
83 *mean_vf_ptr = 0.0;
|
84 xudong 1.27
85
|
86 xudong 1.1 if (nx <= 0 || ny <= 0) return 1;
|
87 xudong 1.27
88 for (i = 0; i < nx; i++)
|
89 xudong 1.1 {
|
90 xudong 1.27 for (j = 0; j < ny; j++)
|
91 xudong 1.1 {
|
92 xudong 1.27 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
93 if isnan(bz[j * nx + i]) continue;
94 sum += (fabs(bz[j * nx + i]));
95 err += bz_err[j * nx + i]*bz_err[j * nx + i];
96 count_mask++;
97 }
|
98 xudong 1.1 }
|
99 xudong 1.27
100 *mean_vf_ptr = sum*cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0;
101 *mean_vf_err_ptr = (sqrt(err))*fabs(cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0); // error in the unsigned flux
102 *count_mask_ptr = count_mask;
103 return 0;
|
104 xudong 1.1 }
105
106 /*===========================================*/
|
107 mbobra 1.9 /* Example function 2: Calculate Bh, the horizontal field, in units of Gauss */
|
108 xudong 1.1 // Native units of Bh are Gauss
109
|
110 xudong 1.27 int computeBh(float *bx_err, float *by_err, float *bh_err, float *bx, float *by, float *bz, float *bh, int *dims,
|
111 mbobra 1.3 float *mean_hf_ptr, int *mask, int *bitmask)
|
112 xudong 1.1
113 {
|
114 xudong 1.27
|
115 mbobra 1.14 int nx = dims[0];
116 int ny = dims[1];
|
117 mbobra 1.15 int i = 0;
|
118 xudong 1.27 int j = 0;
|
119 mbobra 1.15 int count_mask = 0;
|
120 xudong 1.27 double sum = 0.0;
|
121 mbobra 1.9 *mean_hf_ptr = 0.0;
|
122 xudong 1.27
|
123 xudong 1.1 if (nx <= 0 || ny <= 0) return 1;
|
124 xudong 1.27
125 for (i = 0; i < nx; i++)
126 {
|
127 mbobra 1.5 for (j = 0; j < ny; j++)
|
128 xudong 1.27 {
129 if isnan(bx[j * nx + i])
130 {
131 bh[j * nx + i] = NAN;
132 bh_err[j * nx + i] = NAN;
133 continue;
134 }
135 if isnan(by[j * nx + i])
136 {
137 bh[j * nx + i] = NAN;
138 bh_err[j * nx + i] = NAN;
139 continue;
140 }
141 bh[j * nx + i] = sqrt( bx[j * nx + i]*bx[j * nx + i] + by[j * nx + i]*by[j * nx + i] );
142 sum += bh[j * nx + i];
143 bh_err[j * nx + i]=sqrt( bx[j * nx + i]*bx[j * nx + i]*bx_err[j * nx + i]*bx_err[j * nx + i] + by[j * nx + i]*by[j * nx + i]*by_err[j * nx + i]*by_err[j * nx + i])/ bh[j * nx + i];
144 count_mask++;
145 }
146 }
147
|
148 xudong 1.1 *mean_hf_ptr = sum/(count_mask); // would be divided by nx*ny if shape of count_mask = shape of magnetogram
|
149 xudong 1.27
|
150 xudong 1.1 return 0;
151 }
152
153 /*===========================================*/
154 /* Example function 3: Calculate Gamma in units of degrees */
155 // Native units of atan(x) are in radians; to convert from radians to degrees, multiply by (180./PI)
|
156 xudong 1.27 //
|
157 mbobra 1.20 // Error analysis calculations are done in radians (since derivatives are only true in units of radians),
158 // and multiplied by (180./PI) at the end for consistency in units.
|
159 xudong 1.1
|
160 mbobra 1.9 int computeGamma(float *bz_err, float *bh_err, float *bx, float *by, float *bz, float *bh, int *dims,
161 float *mean_gamma_ptr, float *mean_gamma_err_ptr, int *mask, int *bitmask)
|
162 xudong 1.1 {
|
163 mbobra 1.14 int nx = dims[0];
164 int ny = dims[1];
|
165 mbobra 1.15 int i = 0;
166 int j = 0;
167 int count_mask = 0;
168 double sum = 0.0;
169 double err = 0.0;
170 *mean_gamma_ptr = 0.0;
|
171 xudong 1.27
|
172 xudong 1.1 if (nx <= 0 || ny <= 0) return 1;
|
173 xudong 1.27
174 for (i = 0; i < nx; i++)
175 {
176 for (j = 0; j < ny; j++)
177 {
178 if (bh[j * nx + i] > 100)
179 {
180 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
181 if isnan(bz[j * nx + i]) continue;
182 if isnan(bz_err[j * nx + i]) continue;
183 if isnan(bh_err[j * nx + i]) continue;
184 if isnan(bh[j * nx + i]) continue;
185 if (bz[j * nx + i] == 0) continue;
186 sum += fabs(atan(bh[j * nx + i]/fabs(bz[j * nx + i])))*(180./PI);
187 err += (1/(1+((bh[j * nx + i]*bh[j * nx + i])/(bz[j * nx + i]*bz[j * nx + i]))))*(1/(1+((bh[j * nx + i]*bh[j * nx + i])/(bz[j * nx + i]*bz[j * nx + i])))) *
188 ( ((bh_err[j * nx + i]*bh_err[j * nx + i])/(bz[j * nx + i]*bz[j * nx + i])) +
189 ((bh[j * nx + i]*bh[j * nx + i]*bz_err[j * nx + i]*bz_err[j * nx + i])/(bz[j * nx + i]*bz[j * nx + i]*bz[j * nx + i]*bz[j * nx + i])) );
190 count_mask++;
191 }
192 }
193 }
194 xudong 1.27
195 *mean_gamma_ptr = sum/count_mask;
196 *mean_gamma_err_ptr = (sqrt(err)/(count_mask))*(180./PI);
197 //printf("MEANGAM=%f\n",*mean_gamma_ptr);
198 //printf("MEANGAM_err=%f\n",*mean_gamma_err_ptr);
199 return 0;
|
200 xudong 1.1 }
201
202 /*===========================================*/
203 /* Example function 4: Calculate B_Total*/
204 // Native units of B_Total are in gauss
205
|
206 mbobra 1.9 int computeB_total(float *bx_err, float *by_err, float *bz_err, float *bt_err, float *bx, float *by, float *bz, float *bt, int *dims, int *mask, int *bitmask)
|
207 xudong 1.1 {
|
208 xudong 1.27
|
209 mbobra 1.14 int nx = dims[0];
210 int ny = dims[1];
|
211 mbobra 1.15 int i = 0;
212 int j = 0;
213 int count_mask = 0;
|
214 xudong 1.1
215 if (nx <= 0 || ny <= 0) return 1;
|
216 xudong 1.27
217 for (i = 0; i < nx; i++)
218 {
219 for (j = 0; j < ny; j++)
220 {
221 if isnan(bx[j * nx + i])
222 {
223 bt[j * nx + i] = NAN;
224 bt_err[j * nx + i] = NAN;
225 continue;
226 }
227 if isnan(by[j * nx + i])
228 {
229 bt[j * nx + i] = NAN;
230 bt_err[j * nx + i] = NAN;
231 continue;
232 }
233 if isnan(bz[j * nx + i])
234 {
235 bt[j * nx + i] = NAN;
236 bt_err[j * nx + i] = NAN;
237 xudong 1.27 continue;
238 }
239 bt[j * nx + i] = sqrt( bx[j * nx + i]*bx[j * nx + i] + by[j * nx + i]*by[j * nx + i] + bz[j * nx + i]*bz[j * nx + i]);
240 bt_err[j * nx + i]=sqrt(bx[j * nx + i]*bx[j * nx + i]*bx_err[j * nx + i]*bx_err[j * nx + i] + by[j * nx + i]*by[j * nx + i]*by_err[j * nx + i]*by_err[j * nx + i] + bz[j * nx + i]*bz[j * nx + i]*bz_err[j * nx + i]*bz_err[j * nx + i] ) / bt[j * nx + i];
241 }
242 }
243 return 0;
|
244 xudong 1.1 }
245
246 /*===========================================*/
247 /* Example function 5: Derivative of B_Total SQRT( (dBt/dx)^2 + (dBt/dy)^2 ) */
248
|
249 mbobra 1.9 int computeBtotalderivative(float *bt, int *dims, float *mean_derivative_btotal_ptr, int *mask, int *bitmask, float *derx_bt, float *dery_bt, float *bt_err, float *mean_derivative_btotal_err_ptr)
|
250 xudong 1.1 {
|
251 xudong 1.27
|
252 mbobra 1.14 int nx = dims[0];
253 int ny = dims[1];
|
254 mbobra 1.15 int i = 0;
255 int j = 0;
256 int count_mask = 0;
|
257 xudong 1.27 double sum = 0.0;
|
258 mbobra 1.15 double err = 0.0;
|
259 mbobra 1.14 *mean_derivative_btotal_ptr = 0.0;
|
260 xudong 1.27
|
261 xudong 1.1 if (nx <= 0 || ny <= 0) return 1;
|
262 xudong 1.27
263 /* brute force method of calculating the derivative (no consideration for edges) */
264 for (i = 1; i <= nx-2; i++)
265 {
266 for (j = 0; j <= ny-1; j++)
267 {
268 derx_bt[j * nx + i] = (bt[j * nx + i+1] - bt[j * nx + i-1])*0.5;
269 }
270 }
271
272 /* brute force method of calculating the derivative (no consideration for edges) */
273 for (i = 0; i <= nx-1; i++)
274 {
275 for (j = 1; j <= ny-2; j++)
276 {
277 dery_bt[j * nx + i] = (bt[(j+1) * nx + i] - bt[(j-1) * nx + i])*0.5;
278 }
279 }
280
281
282 /* consider the edges */
283 xudong 1.27 i=0;
284 for (j = 0; j <= ny-1; j++)
285 {
286 derx_bt[j * nx + i] = ( (-3*bt[j * nx + i]) + (4*bt[j * nx + (i+1)]) - (bt[j * nx + (i+2)]) )*0.5;
287 }
288
289 i=nx-1;
290 for (j = 0; j <= ny-1; j++)
291 {
292 derx_bt[j * nx + i] = ( (3*bt[j * nx + i]) + (-4*bt[j * nx + (i-1)]) - (-bt[j * nx + (i-2)]) )*0.5;
293 }
294
295 j=0;
296 for (i = 0; i <= nx-1; i++)
297 {
298 dery_bt[j * nx + i] = ( (-3*bt[j*nx + i]) + (4*bt[(j+1) * nx + i]) - (bt[(j+2) * nx + i]) )*0.5;
299 }
300
301 j=ny-1;
302 for (i = 0; i <= nx-1; i++)
303 {
304 xudong 1.27 dery_bt[j * nx + i] = ( (3*bt[j * nx + i]) + (-4*bt[(j-1) * nx + i]) - (-bt[(j-2) * nx + i]) )*0.5;
305 }
306
307
308 for (i = 1; i <= nx-2; i++)
309 {
310 for (j = 1; j <= ny-2; j++)
311 {
312 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
313 if ( (derx_bt[j * nx + i] + dery_bt[j * nx + i]) == 0) continue;
314 if isnan(bt[j * nx + i]) continue;
315 if isnan(bt[(j+1) * nx + i]) continue;
316 if isnan(bt[(j-1) * nx + i]) continue;
317 if isnan(bt[j * nx + i-1]) continue;
318 if isnan(bt[j * nx + i+1]) continue;
319 if isnan(bt_err[j * nx + i]) continue;
320 if isnan(derx_bt[j * nx + i]) continue;
321 if isnan(dery_bt[j * nx + i]) continue;
322 sum += sqrt( derx_bt[j * nx + i]*derx_bt[j * nx + i] + dery_bt[j * nx + i]*dery_bt[j * nx + i] ); /* Units of Gauss */
323 err += (((bt[(j+1) * nx + i]-bt[(j-1) * nx + i])*(bt[(j+1) * nx + i]-bt[(j-1) * nx + i])) * (bt_err[(j+1) * nx + i]*bt_err[(j+1) * nx + i] + bt_err[(j-1) * nx + i]*bt_err[(j-1) * nx + i])) / (16.0*( derx_bt[j * nx + i]*derx_bt[j * nx + i] + dery_bt[j * nx + i]*dery_bt[j * nx + i] ))+
324 (((bt[j * nx + (i+1)]-bt[j * nx + (i-1)])*(bt[j * nx + (i+1)]-bt[j * nx + (i-1)])) * (bt_err[j * nx + (i+1)]*bt_err[j * nx + (i+1)] + bt_err[j * nx + (i-1)]*bt_err[j * nx + (i-1)])) / (16.0*( derx_bt[j * nx + i]*derx_bt[j * nx + i] + dery_bt[j * nx + i]*dery_bt[j * nx + i] )) ;
325 xudong 1.27 count_mask++;
326 }
327 }
328
329 *mean_derivative_btotal_ptr = (sum)/(count_mask);
330 *mean_derivative_btotal_err_ptr = (sqrt(err))/(count_mask);
331 //printf("MEANGBT=%f\n",*mean_derivative_btotal_ptr);
332 //printf("MEANGBT_err=%f\n",*mean_derivative_btotal_err_ptr);
333
334 return 0;
|
335 xudong 1.1 }
336
337
338 /*===========================================*/
339 /* Example function 6: Derivative of Bh SQRT( (dBh/dx)^2 + (dBh/dy)^2 ) */
340
|
341 mbobra 1.9 int computeBhderivative(float *bh, float *bh_err, int *dims, float *mean_derivative_bh_ptr, float *mean_derivative_bh_err_ptr, int *mask, int *bitmask, float *derx_bh, float *dery_bh)
|
342 xudong 1.1 {
|
343 xudong 1.27
344 int nx = dims[0];
345 int ny = dims[1];
346 int i = 0;
347 int j = 0;
348 int count_mask = 0;
349 double sum= 0.0;
350 double err =0.0;
351 *mean_derivative_bh_ptr = 0.0;
352
353 if (nx <= 0 || ny <= 0) return 1;
354
355 /* brute force method of calculating the derivative (no consideration for edges) */
356 for (i = 1; i <= nx-2; i++)
357 {
358 for (j = 0; j <= ny-1; j++)
359 {
360 derx_bh[j * nx + i] = (bh[j * nx + i+1] - bh[j * nx + i-1])*0.5;
361 }
362 }
363
364 xudong 1.27 /* brute force method of calculating the derivative (no consideration for edges) */
365 for (i = 0; i <= nx-1; i++)
366 {
367 for (j = 1; j <= ny-2; j++)
368 {
369 dery_bh[j * nx + i] = (bh[(j+1) * nx + i] - bh[(j-1) * nx + i])*0.5;
370 }
371 }
372
373
374 /* consider the edges */
375 i=0;
376 for (j = 0; j <= ny-1; j++)
377 {
378 derx_bh[j * nx + i] = ( (-3*bh[j * nx + i]) + (4*bh[j * nx + (i+1)]) - (bh[j * nx + (i+2)]) )*0.5;
379 }
380
381 i=nx-1;
382 for (j = 0; j <= ny-1; j++)
383 {
384 derx_bh[j * nx + i] = ( (3*bh[j * nx + i]) + (-4*bh[j * nx + (i-1)]) - (-bh[j * nx + (i-2)]) )*0.5;
385 xudong 1.27 }
386
387 j=0;
388 for (i = 0; i <= nx-1; i++)
389 {
390 dery_bh[j * nx + i] = ( (-3*bh[j*nx + i]) + (4*bh[(j+1) * nx + i]) - (bh[(j+2) * nx + i]) )*0.5;
391 }
392
393 j=ny-1;
394 for (i = 0; i <= nx-1; i++)
395 {
396 dery_bh[j * nx + i] = ( (3*bh[j * nx + i]) + (-4*bh[(j-1) * nx + i]) - (-bh[(j-2) * nx + i]) )*0.5;
397 }
398
399
400 for (i = 0; i <= nx-1; i++)
401 {
402 for (j = 0; j <= ny-1; j++)
403 {
404 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
405 if ( (derx_bh[j * nx + i] + dery_bh[j * nx + i]) == 0) continue;
406 xudong 1.27 if isnan(bh[j * nx + i]) continue;
407 if isnan(bh[(j+1) * nx + i]) continue;
408 if isnan(bh[(j-1) * nx + i]) continue;
409 if isnan(bh[j * nx + i-1]) continue;
410 if isnan(bh[j * nx + i+1]) continue;
411 if isnan(bh_err[j * nx + i]) continue;
412 if isnan(derx_bh[j * nx + i]) continue;
413 if isnan(dery_bh[j * nx + i]) continue;
414 sum += sqrt( derx_bh[j * nx + i]*derx_bh[j * nx + i] + dery_bh[j * nx + i]*dery_bh[j * nx + i] ); /* Units of Gauss */
415 err += (((bh[(j+1) * nx + i]-bh[(j-1) * nx + i])*(bh[(j+1) * nx + i]-bh[(j-1) * nx + i])) * (bh_err[(j+1) * nx + i]*bh_err[(j+1) * nx + i] + bh_err[(j-1) * nx + i]*bh_err[(j-1) * nx + i])) / (16.0*( derx_bh[j * nx + i]*derx_bh[j * nx + i] + dery_bh[j * nx + i]*dery_bh[j * nx + i] ))+
416 (((bh[j * nx + (i+1)]-bh[j * nx + (i-1)])*(bh[j * nx + (i+1)]-bh[j * nx + (i-1)])) * (bh_err[j * nx + (i+1)]*bh_err[j * nx + (i+1)] + bh_err[j * nx + (i-1)]*bh_err[j * nx + (i-1)])) / (16.0*( derx_bh[j * nx + i]*derx_bh[j * nx + i] + dery_bh[j * nx + i]*dery_bh[j * nx + i] )) ;
417 count_mask++;
418 }
419 }
420
421 *mean_derivative_bh_ptr = (sum)/(count_mask); // would be divided by ((nx-2)*(ny-2)) if shape of count_mask = shape of magnetogram
422 *mean_derivative_bh_err_ptr = (sqrt(err))/(count_mask); // error in the quantity (sum)/(count_mask)
423 //printf("MEANGBH=%f\n",*mean_derivative_bh_ptr);
424 //printf("MEANGBH_err=%f\n",*mean_derivative_bh_err_ptr);
425
426 return 0;
|
427 xudong 1.1 }
428
429 /*===========================================*/
430 /* Example function 7: Derivative of B_vertical SQRT( (dBz/dx)^2 + (dBz/dy)^2 ) */
431
|
432 mbobra 1.9 int computeBzderivative(float *bz, float *bz_err, int *dims, float *mean_derivative_bz_ptr, float *mean_derivative_bz_err_ptr, int *mask, int *bitmask, float *derx_bz, float *dery_bz)
|
433 xudong 1.1 {
|
434 xudong 1.27
435 int nx = dims[0];
436 int ny = dims[1];
437 int i = 0;
438 int j = 0;
439 int count_mask = 0;
|
440 mbobra 1.15 double sum = 0.0;
|
441 xudong 1.27 double err = 0.0;
|
442 mbobra 1.14 *mean_derivative_bz_ptr = 0.0;
|
443 xudong 1.27
|
444 xudong 1.1 if (nx <= 0 || ny <= 0) return 1;
|
445 xudong 1.27
446 /* brute force method of calculating the derivative (no consideration for edges) */
447 for (i = 1; i <= nx-2; i++)
448 {
449 for (j = 0; j <= ny-1; j++)
450 {
451 if isnan(bz[j * nx + i]) continue;
452 derx_bz[j * nx + i] = (bz[j * nx + i+1] - bz[j * nx + i-1])*0.5;
453 }
454 }
455
456 /* brute force method of calculating the derivative (no consideration for edges) */
457 for (i = 0; i <= nx-1; i++)
458 {
459 for (j = 1; j <= ny-2; j++)
460 {
461 if isnan(bz[j * nx + i]) continue;
462 dery_bz[j * nx + i] = (bz[(j+1) * nx + i] - bz[(j-1) * nx + i])*0.5;
463 }
464 }
465
466 xudong 1.27
467 /* consider the edges */
468 i=0;
469 for (j = 0; j <= ny-1; j++)
470 {
471 if isnan(bz[j * nx + i]) continue;
472 derx_bz[j * nx + i] = ( (-3*bz[j * nx + i]) + (4*bz[j * nx + (i+1)]) - (bz[j * nx + (i+2)]) )*0.5;
473 }
474
475 i=nx-1;
476 for (j = 0; j <= ny-1; j++)
477 {
478 if isnan(bz[j * nx + i]) continue;
479 derx_bz[j * nx + i] = ( (3*bz[j * nx + i]) + (-4*bz[j * nx + (i-1)]) - (-bz[j * nx + (i-2)]) )*0.5;
480 }
481
482 j=0;
483 for (i = 0; i <= nx-1; i++)
484 {
485 if isnan(bz[j * nx + i]) continue;
486 dery_bz[j * nx + i] = ( (-3*bz[j*nx + i]) + (4*bz[(j+1) * nx + i]) - (bz[(j+2) * nx + i]) )*0.5;
487 xudong 1.27 }
488
489 j=ny-1;
490 for (i = 0; i <= nx-1; i++)
491 {
492 if isnan(bz[j * nx + i]) continue;
493 dery_bz[j * nx + i] = ( (3*bz[j * nx + i]) + (-4*bz[(j-1) * nx + i]) - (-bz[(j-2) * nx + i]) )*0.5;
494 }
495
496
497 for (i = 0; i <= nx-1; i++)
498 {
499 for (j = 0; j <= ny-1; j++)
500 {
501 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
502 if ( (derx_bz[j * nx + i] + dery_bz[j * nx + i]) == 0) continue;
503 if isnan(bz[j * nx + i]) continue;
504 if isnan(bz[(j+1) * nx + i]) continue;
505 if isnan(bz[(j-1) * nx + i]) continue;
506 if isnan(bz[j * nx + i-1]) continue;
507 if isnan(bz[j * nx + i+1]) continue;
508 xudong 1.27 if isnan(bz_err[j * nx + i]) continue;
509 if isnan(derx_bz[j * nx + i]) continue;
510 if isnan(dery_bz[j * nx + i]) continue;
511 sum += sqrt( derx_bz[j * nx + i]*derx_bz[j * nx + i] + dery_bz[j * nx + i]*dery_bz[j * nx + i] ); /* Units of Gauss */
512 err += (((bz[(j+1) * nx + i]-bz[(j-1) * nx + i])*(bz[(j+1) * nx + i]-bz[(j-1) * nx + i])) * (bz_err[(j+1) * nx + i]*bz_err[(j+1) * nx + i] + bz_err[(j-1) * nx + i]*bz_err[(j-1) * nx + i])) /
513 (16.0*( derx_bz[j * nx + i]*derx_bz[j * nx + i] + dery_bz[j * nx + i]*dery_bz[j * nx + i] )) +
514 (((bz[j * nx + (i+1)]-bz[j * nx + (i-1)])*(bz[j * nx + (i+1)]-bz[j * nx + (i-1)])) * (bz_err[j * nx + (i+1)]*bz_err[j * nx + (i+1)] + bz_err[j * nx + (i-1)]*bz_err[j * nx + (i-1)])) /
515 (16.0*( derx_bz[j * nx + i]*derx_bz[j * nx + i] + dery_bz[j * nx + i]*dery_bz[j * nx + i] )) ;
516 count_mask++;
517 }
518 }
519
|
520 xudong 1.1 *mean_derivative_bz_ptr = (sum)/(count_mask); // would be divided by ((nx-2)*(ny-2)) if shape of count_mask = shape of magnetogram
|
521 xudong 1.27 *mean_derivative_bz_err_ptr = (sqrt(err))/(count_mask); // error in the quantity (sum)/(count_mask)
522 //printf("MEANGBZ=%f\n",*mean_derivative_bz_ptr);
523 //printf("MEANGBZ_err=%f\n",*mean_derivative_bz_err_ptr);
524
|
525 xudong 1.1 return 0;
526 }
527
528 /*===========================================*/
529 /* Example function 8: Current Jz = (dBy/dx) - (dBx/dy) */
530
531 // In discretized space like data pixels,
532 // the current (or curl of B) is calculated as
533 // the integration of the field Bx and By along
534 // the circumference of the data pixel divided by the area of the pixel.
535 // One form of differencing (a word for the differential operator
|
536 xudong 1.27 // in the discretized space) of the curl is expressed as
|
537 xudong 1.1 // (dx * (Bx(i,j-1)+Bx(i,j)) / 2
538 // +dy * (By(i+1,j)+By(i,j)) / 2
539 // -dx * (Bx(i,j+1)+Bx(i,j)) / 2
|
540 xudong 1.27 // -dy * (By(i-1,j)+By(i,j)) / 2) / (dx * dy)
541 //
|
542 xudong 1.1 //
543 // To change units from Gauss/pixel to mA/m^2 (the units for Jz in Leka and Barnes, 2003),
544 // one must perform the following unit conversions:
|
545 mbobra 1.8 // (Gauss)(1/arcsec)(arcsec/meter)(Newton/Gauss*Ampere*meter)(Ampere^2/Newton)(milliAmpere/Ampere), or
546 // (Gauss)(1/CDELT1)(RSUN_OBS/RSUN_REF)(1 T / 10^4 Gauss)(1 / 4*PI*10^-7)( 10^3 milliAmpere/Ampere), or
|
547 xudong 1.27 // (Gauss)(1/CDELT1)(RSUN_OBS/RSUN_REF)(0.00010)(1/MUNAUGHT)(1000.),
|
548 xudong 1.1 // where a Tesla is represented as a Newton/Ampere*meter.
|
549 mbobra 1.4 //
|
550 xudong 1.1 // As an order of magnitude estimate, we can assign 0.5 to CDELT1 and 722500m/arcsec to (RSUN_REF/RSUN_OBS).
551 // In that case, we would have the following:
552 // (Gauss/pix)(1/0.5)(1/722500)(10^-4)(4*PI*10^7)(10^3), or
553 // jz * (35.0)
554 //
555 // The units of total unsigned vertical current (us_i) are simply in A. In this case, we would have the following:
|
556 mbobra 1.8 // (Gauss/pix)(1/CDELT1)(RSUN_OBS/RSUN_REF)(0.00010)(1/MUNAUGHT)(CDELT1)(CDELT1)(RSUN_REF/RSUN_OBS)(RSUN_REF/RSUN_OBS)
557 // = (Gauss/pix)(0.00010)(1/MUNAUGHT)(CDELT1)(RSUN_REF/RSUN_OBS)
|
558 xudong 1.1
559
|
560 xudong 1.27 // Comment out random number generator, which can only run on solar3
|
561 mbobra 1.33 // int computeJz(float *bx_err, float *by_err, float *bx, float *by, int *dims, float *jz, float *jz_err, float *jz_err_squared,
|
562 xudong 1.27 // int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs,float *derx, float *dery, float *noisebx,
|
563 mbobra 1.9 // float *noiseby, float *noisebz)
564
565 int computeJz(float *bx_err, float *by_err, float *bx, float *by, int *dims, float *jz, float *jz_err, float *jz_err_squared,
|
566 mbobra 1.33 int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs,float *derx, float *dery, float *err_term1, float *err_term2)
|
567 mbobra 1.9
|
568 xudong 1.1
|
569 xudong 1.27 {
570 int nx = dims[0];
571 int ny = dims[1];
572 int i = 0;
573 int j = 0;
574 int count_mask = 0;
575
576 if (nx <= 0 || ny <= 0) return 1;
577
578 /* Calculate the derivative*/
579 /* brute force method of calculating the derivative (no consideration for edges) */
580
581 for (i = 1; i <= nx-2; i++)
582 {
583 for (j = 0; j <= ny-1; j++)
584 {
585 if isnan(by[j * nx + i]) continue;
|
586 mbobra 1.33 derx[j * nx + i] = (by[j * nx + i+1] - by[j * nx + i-1])*0.5;
587 err_term1[j * nx + i] = (by_err[j * nx + i+1])*(by_err[j * nx + i+1]) + (by_err[j * nx + i-1])*(by_err[j * nx + i-1]);
|
588 xudong 1.27 }
589 }
590
591 for (i = 0; i <= nx-1; i++)
592 {
593 for (j = 1; j <= ny-2; j++)
594 {
595 if isnan(bx[j * nx + i]) continue;
|
596 mbobra 1.33 dery[j * nx + i] = (bx[(j+1) * nx + i] - bx[(j-1) * nx + i])*0.5;
597 err_term2[j * nx + i] = (bx_err[(j+1) * nx + i])*(bx_err[(j+1) * nx + i]) + (bx_err[(j-1) * nx + i])*(bx_err[(j-1) * nx + i]);
|
598 xudong 1.27 }
599 }
|
600 mbobra 1.33
|
601 xudong 1.27 // consider the edges
602 i=0;
603 for (j = 0; j <= ny-1; j++)
604 {
605 if isnan(by[j * nx + i]) continue;
|
606 mbobra 1.33 derx[j * nx + i] = ( (-3*by[j * nx + i]) + (4*by[j * nx + (i+1)]) - (by[j * nx + (i+2)]) )*0.5;
607 err_term1[j * nx + i] = ( (3*by_err[j * nx + i])*(3*by_err[j * nx + i]) + (4*by_err[j * nx + (i+1)])*(4*by_err[j * nx + (i+1)]) + (by_err[j * nx + (i+2)])*(by_err[j * nx + (i+2)]) );
|
608 xudong 1.27 }
609
610 i=nx-1;
611 for (j = 0; j <= ny-1; j++)
612 {
613 if isnan(by[j * nx + i]) continue;
|
614 mbobra 1.33 derx[j * nx + i] = ( (3*by[j * nx + i]) + (-4*by[j * nx + (i-1)]) - (-by[j * nx + (i-2)]) )*0.5;
615 err_term1[j * nx + i] = ( (3*by_err[j * nx + i])*(3*by_err[j * nx + i]) + (4*by_err[j * nx + (i+1)])*(4*by_err[j * nx + (i+1)]) + (by_err[j * nx + (i+2)])*(by_err[j * nx + (i+2)]) );
|
616 xudong 1.27 }
617
618 j=0;
619 for (i = 0; i <= nx-1; i++)
620 {
621 if isnan(bx[j * nx + i]) continue;
|
622 mbobra 1.33 dery[j * nx + i] = ( (-3*bx[j*nx + i]) + (4*bx[(j+1) * nx + i]) - (bx[(j+2) * nx + i]) )*0.5;
623 err_term2[j * nx + i] = ( (3*bx_err[j*nx + i])*(3*bx_err[j*nx + i]) + (4*bx_err[(j+1) * nx + i])*(4*bx_err[(j+1) * nx + i]) + (bx_err[(j+2) * nx + i])*(bx_err[(j+2) * nx + i]) );
|
624 xudong 1.27 }
625
626 j=ny-1;
627 for (i = 0; i <= nx-1; i++)
628 {
629 if isnan(bx[j * nx + i]) continue;
|
630 mbobra 1.33 dery[j * nx + i] = ( (3*bx[j * nx + i]) + (-4*bx[(j-1) * nx + i]) - (-bx[(j-2) * nx + i]) )*0.5;
631 err_term2[j * nx + i] = ( (3*bx_err[j*nx + i])*(3*bx_err[j*nx + i]) + (4*bx_err[(j+1) * nx + i])*(4*bx_err[(j+1) * nx + i]) + (bx_err[(j+2) * nx + i])*(bx_err[(j+2) * nx + i]) );
632
|
633 xudong 1.27 }
|
634 mbobra 1.33
|
635 xudong 1.27
|
636 mbobra 1.33 for (i = 0; i <= nx-1; i++)
|
637 xudong 1.27 {
|
638 mbobra 1.33 for (j = 0; j <= ny-1; j++)
|
639 xudong 1.27 {
|
640 mbobra 1.33 // calculate jz at all points
|
641 xudong 1.27 jz[j * nx + i] = (derx[j * nx + i]-dery[j * nx + i]); // jz is in units of Gauss/pix
|
642 mbobra 1.33 jz_err[j * nx + i] = 0.5*sqrt( err_term1[j * nx + i] + err_term2[j * nx + i] ) ;
|
643 xudong 1.27 jz_err_squared[j * nx + i]= (jz_err[j * nx + i]*jz_err[j * nx + i]);
|
644 mbobra 1.33 count_mask++;
|
645 xudong 1.27 }
646 }
647 return 0;
648 }
|
649 mbobra 1.33
|
650 mbobra 1.5 /*===========================================*/
651
|
652 mbobra 1.11 /* Example function 9: Compute quantities on Jz array */
|
653 xudong 1.27 // Compute mean and total current on Jz array.
|
654 mbobra 1.6
|
655 mbobra 1.9 int computeJzsmooth(float *bx, float *by, int *dims, float *jz, float *jz_smooth, float *jz_err, float *jz_rms_err, float *jz_err_squared_smooth,
|
656 xudong 1.27 float *mean_jz_ptr, float *mean_jz_err_ptr, float *us_i_ptr, float *us_i_err_ptr, int *mask, int *bitmask,
|
657 mbobra 1.9 float cdelt1, double rsun_ref, double rsun_obs,float *derx, float *dery)
|
658 mbobra 1.5
659 {
|
660 xudong 1.27
661 int nx = dims[0];
662 int ny = dims[1];
663 int i = 0;
664 int j = 0;
665 int count_mask = 0;
|
666 mbobra 1.15 double curl = 0.0;
|
667 xudong 1.27 double us_i = 0.0;
668 double err = 0.0;
669
|
670 mbobra 1.5 if (nx <= 0 || ny <= 0) return 1;
|
671 xudong 1.27
672 /* At this point, use the smoothed Jz array with a Gaussian (FWHM of 4 pix and truncation width of 12 pixels) but keep the original array dimensions*/
673 for (i = 0; i <= nx-1; i++)
674 {
675 for (j = 0; j <= ny-1; j++)
676 {
677 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
678 if isnan(derx[j * nx + i]) continue;
679 if isnan(dery[j * nx + i]) continue;
680 if isnan(jz[j * nx + i]) continue;
681 curl += (jz[j * nx + i])*(1/cdelt1)*(rsun_obs/rsun_ref)*(0.00010)*(1/MUNAUGHT)*(1000.); /* curl is in units of mA / m^2 */
682 us_i += fabs(jz[j * nx + i])*(cdelt1/1)*(rsun_ref/rsun_obs)*(0.00010)*(1/MUNAUGHT); /* us_i is in units of A */
683 err += (jz_err[j * nx + i]*jz_err[j * nx + i]);
684 count_mask++;
685 }
686 }
687
688 /* Calculate mean vertical current density (mean_jz) and total unsigned vertical current (us_i) using smoothed Jz array and continue conditions above */
689 *mean_jz_ptr = curl/(count_mask); /* mean_jz gets populated as MEANJZD */
690 *mean_jz_err_ptr = (sqrt(err)/count_mask)*((1/cdelt1)*(rsun_obs/rsun_ref)*(0.00010)*(1/MUNAUGHT)*(1000.)); // error in the quantity MEANJZD
691
692 xudong 1.27 *us_i_ptr = (us_i); /* us_i gets populated as TOTUSJZ */
693 *us_i_err_ptr = (sqrt(err))*((cdelt1/1)*(rsun_ref/rsun_obs)*(0.00010)*(1/MUNAUGHT)); // error in the quantity TOTUSJZ
694
695 //printf("MEANJZD=%f\n",*mean_jz_ptr);
696 //printf("MEANJZD_err=%f\n",*mean_jz_err_ptr);
697
698 //printf("TOTUSJZ=%g\n",*us_i_ptr);
699 //printf("TOTUSJZ_err=%g\n",*us_i_err_ptr);
700
|
701 xudong 1.1 return 0;
|
702 xudong 1.27
|
703 xudong 1.1 }
704
|
705 mbobra 1.5 /*===========================================*/
706
707 /* Example function 10: Twist Parameter, alpha */
|
708 xudong 1.1
|
709 mbobra 1.5 // The twist parameter, alpha, is defined as alpha = Jz/Bz. In this case, the calculation
|
710 mbobra 1.19 // for alpha is weighted by Bz (following Hagino et al., http://adsabs.harvard.edu/abs/2004PASJ...56..831H):
|
711 xudong 1.27
712 // numerator = sum of all Jz*Bz
713 // denominator = sum of Bz*Bz
714 // alpha = numerator/denominator
|
715 mbobra 1.6
|
716 mbobra 1.5 // The units of alpha are in 1/Mm
|
717 xudong 1.1 // The units of Jz are in Gauss/pix; the units of Bz are in Gauss.
718 //
|
719 xudong 1.27 // Therefore, the units of Jz/Bz = (Gauss/pix)(1/Gauss)(pix/arcsec)(arsec/meter)(meter/Mm), or
|
720 xudong 1.1 // = (Gauss/pix)(1/Gauss)(1/CDELT1)(RSUN_OBS/RSUN_REF)(10^6)
721 // = 1/Mm
722
|
723 mbobra 1.9 int computeAlpha(float *jz_err, float *bz_err, float *bz, int *dims, float *jz, float *jz_smooth, float *mean_alpha_ptr, float *mean_alpha_err_ptr, int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs)
|
724 mbobra 1.5
|
725 xudong 1.1 {
|
726 xudong 1.27 int nx = dims[0];
727 int ny = dims[1];
728 int i = 0;
729 int j = 0;
|
730 mbobra 1.19 double alpha_total = 0.0;
|
731 xudong 1.27 double C = ((1/cdelt1)*(rsun_obs/rsun_ref)*(1000000.));
732 double total = 0.0;
733 double A = 0.0;
734 double B = 0.0;
735
|
736 xudong 1.1 if (nx <= 0 || ny <= 0) return 1;
|
737 xudong 1.27 for (i = 1; i < nx-1; i++)
738 {
739 for (j = 1; j < ny-1; j++)
740 {
741 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
742 if isnan(jz[j * nx + i]) continue;
743 if isnan(bz[j * nx + i]) continue;
744 if (jz[j * nx + i] == 0.0) continue;
745 if (bz[j * nx + i] == 0.0) continue;
746 A += jz[j*nx+i]*bz[j*nx+i];
747 B += bz[j*nx+i]*bz[j*nx+i];
748 }
749 }
750
751 for (i = 1; i < nx-1; i++)
752 {
753 for (j = 1; j < ny-1; j++)
754 {
755 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
756 if isnan(jz[j * nx + i]) continue;
757 if isnan(bz[j * nx + i]) continue;
758 xudong 1.27 if (jz[j * nx + i] == 0.0) continue;
759 if (bz[j * nx + i] == 0.0) continue;
760 total += bz[j*nx+i]*bz[j*nx+i]*jz_err[j*nx+i]*jz_err[j*nx+i] + (jz[j*nx+i]-2*bz[j*nx+i]*A/B)*(jz[j*nx+i]-2*bz[j*nx+i]*A/B)*bz_err[j*nx+i]*bz_err[j*nx+i];
761 }
762 }
763
764 /* Determine the absolute value of alpha. The units for alpha are 1/Mm */
765 alpha_total = ((A/B)*C);
766 *mean_alpha_ptr = alpha_total;
767 *mean_alpha_err_ptr = (C/B)*(sqrt(total));
768
|
769 xudong 1.1 return 0;
770 }
771
772 /*===========================================*/
|
773 mbobra 1.9 /* Example function 11: Helicity (mean current helicty, total unsigned current helicity, absolute value of net current helicity) */
|
774 xudong 1.1
775 // The current helicity is defined as Bz*Jz and the units are G^2 / m
776 // The units of Jz are in G/pix; the units of Bz are in G.
|
777 xudong 1.27 // Therefore, the units of Bz*Jz = (Gauss)*(Gauss/pix) = (Gauss^2/pix)(pix/arcsec)(arcsec/meter)
778 // = (Gauss^2/pix)(1/CDELT1)(RSUN_OBS/RSUN_REF)
|
779 mbobra 1.9 // = G^2 / m.
|
780 xudong 1.1
|
781 xudong 1.27 int computeHelicity(float *jz_err, float *jz_rms_err, float *bz_err, float *bz, int *dims, float *jz, float *mean_ih_ptr,
782 float *mean_ih_err_ptr, float *total_us_ih_ptr, float *total_abs_ih_ptr,
|
783 mbobra 1.9 float *total_us_ih_err_ptr, float *total_abs_ih_err_ptr, int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs)
|
784 xudong 1.1
785 {
|
786 xudong 1.27
787 int nx = dims[0];
788 int ny = dims[1];
789 int i = 0;
790 int j = 0;
791 int count_mask = 0;
|
792 mbobra 1.20 double sum = 0.0;
793 double sum2 = 0.0;
794 double err = 0.0;
|
795 xudong 1.1
796 if (nx <= 0 || ny <= 0) return 1;
|
797 xudong 1.27
798 for (i = 0; i < nx; i++)
|
799 xudong 1.1 {
|
800 xudong 1.27 for (j = 0; j < ny; j++)
|
801 xudong 1.1 {
|
802 xudong 1.27 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
803 if isnan(jz[j * nx + i]) continue;
804 if isnan(bz[j * nx + i]) continue;
805 if isnan(jz_err[j * nx + i]) continue;
806 if isnan(bz_err[j * nx + i]) continue;
807 if (bz[j * nx + i] == 0.0) continue;
808 if (jz[j * nx + i] == 0.0) continue;
809 sum += (jz[j * nx + i]*bz[j * nx + i])*(1/cdelt1)*(rsun_obs/rsun_ref); // contributes to MEANJZH and ABSNJZH
810 sum2 += fabs(jz[j * nx + i]*bz[j * nx + i])*(1/cdelt1)*(rsun_obs/rsun_ref); // contributes to TOTUSJH
811 err += (jz_err[j * nx + i]*jz_err[j * nx + i]*bz[j * nx + i]*bz[j * nx + i]) + (bz_err[j * nx + i]*bz_err[j * nx + i]*jz[j * nx + i]*jz[j * nx + i]);
812 count_mask++;
813 }
814 }
815
816 *mean_ih_ptr = sum/count_mask ; /* Units are G^2 / m ; keyword is MEANJZH */
|
817 mbobra 1.9 *total_us_ih_ptr = sum2 ; /* Units are G^2 / m ; keyword is TOTUSJH */
818 *total_abs_ih_ptr = fabs(sum) ; /* Units are G^2 / m ; keyword is ABSNJZH */
|
819 xudong 1.27
820 *mean_ih_err_ptr = (sqrt(err)/count_mask)*(1/cdelt1)*(rsun_obs/rsun_ref) ; // error in the quantity MEANJZH
821 *total_us_ih_err_ptr = (sqrt(err))*(1/cdelt1)*(rsun_obs/rsun_ref) ; // error in the quantity TOTUSJH
822 *total_abs_ih_err_ptr = (sqrt(err))*(1/cdelt1)*(rsun_obs/rsun_ref) ; // error in the quantity ABSNJZH
823
824 //printf("MEANJZH=%f\n",*mean_ih_ptr);
825 //printf("MEANJZH_err=%f\n",*mean_ih_err_ptr);
826
827 //printf("TOTUSJH=%f\n",*total_us_ih_ptr);
828 //printf("TOTUSJH_err=%f\n",*total_us_ih_err_ptr);
829
830 //printf("ABSNJZH=%f\n",*total_abs_ih_ptr);
831 //printf("ABSNJZH_err=%f\n",*total_abs_ih_err_ptr);
832
|
833 xudong 1.1 return 0;
834 }
835
836 /*===========================================*/
|
837 mbobra 1.5 /* Example function 12: Sum of Absolute Value per polarity */
|
838 xudong 1.1
839 // The Sum of the Absolute Value per polarity is defined as the following:
|
840 mbobra 1.32 // fabs(sum(jz gt 0)) + fabs(sum(jz lt 0)) and the units are in Amperes per arcsecond.
|
841 xudong 1.1 // The units of jz are in G/pix. In this case, we would have the following:
842 // Jz = (Gauss/pix)(1/CDELT1)(0.00010)(1/MUNAUGHT)(RSUN_REF/RSUN_OBS)(RSUN_REF/RSUN_OBS)(RSUN_OBS/RSUN_REF),
843 // = (Gauss/pix)(1/CDELT1)(0.00010)(1/MUNAUGHT)(RSUN_REF/RSUN_OBS)
|
844 mbobra 1.9 //
845 // The error in this quantity is the same as the error in the mean vertical current (mean_jz_err).
|
846 xudong 1.1
|
847 xudong 1.27 int computeSumAbsPerPolarity(float *jz_err, float *bz_err, float *bz, float *jz, int *dims, float *totaljzptr, float *totaljz_err_ptr,
|
848 mbobra 1.3 int *mask, int *bitmask, float cdelt1, double rsun_ref, double rsun_obs)
|
849 xudong 1.1
|
850 xudong 1.27 {
851 int nx = dims[0];
852 int ny = dims[1];
853 int i=0;
854 int j=0;
855 int count_mask=0;
|
856 mbobra 1.32 double sum1=0.0;
|
857 xudong 1.27 double sum2=0.0;
858 double err=0.0;
|
859 mbobra 1.33 *totaljzptr=0.0;
|
860 xudong 1.27
|
861 mbobra 1.33 if (nx <= 0 || ny <= 0) return 1;
|
862 xudong 1.27
|
863 mbobra 1.33 for (i = 0; i < nx; i++)
|
864 xudong 1.27 {
|
865 mbobra 1.33 for (j = 0; j < ny; j++)
|
866 xudong 1.27 {
867 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
868 if isnan(bz[j * nx + i]) continue;
869 if isnan(jz[j * nx + i]) continue;
870 if (bz[j * nx + i] > 0) sum1 += ( jz[j * nx + i])*(1/cdelt1)*(0.00010)*(1/MUNAUGHT)*(rsun_ref/rsun_obs);
871 if (bz[j * nx + i] <= 0) sum2 += ( jz[j * nx + i])*(1/cdelt1)*(0.00010)*(1/MUNAUGHT)*(rsun_ref/rsun_obs);
872 err += (jz_err[j * nx + i]*jz_err[j * nx + i]);
873 count_mask++;
874 }
875 }
|
876 xudong 1.1
|
877 mbobra 1.32 *totaljzptr = fabs(sum1) + fabs(sum2); /* Units are Amperes per arcsecond */
|
878 xudong 1.27 *totaljz_err_ptr = sqrt(err)*(1/cdelt1)*fabs((0.00010)*(1/MUNAUGHT)*(rsun_ref/rsun_obs));
879 //printf("SAVNCPP=%g\n",*totaljzptr);
880 //printf("SAVNCPP_err=%g\n",*totaljz_err_ptr);
881
|
882 mbobra 1.33 return 0;
|
883 xudong 1.1 }
884
885 /*===========================================*/
|
886 mbobra 1.5 /* Example function 13: Mean photospheric excess magnetic energy and total photospheric excess magnetic energy density */
|
887 xudong 1.1 // The units for magnetic energy density in cgs are ergs per cubic centimeter. The formula B^2/8*PI integrated over all space, dV
|
888 xudong 1.27 // automatically yields erg per cubic centimeter for an input B in Gauss. Note that the 8*PI can come out of the integral; thus,
889 // the integral is over B^2 dV and the 8*PI is divided at the end.
|
890 xudong 1.1 //
891 // Total magnetic energy is the magnetic energy density times dA, or the area, and the units are thus ergs/cm. To convert
892 // ergs per centimeter cubed to ergs per centimeter, simply multiply by the area per pixel in cm:
|
893 mbobra 1.9 // erg/cm^3*(CDELT1^2)*(RSUN_REF/RSUN_OBS ^2)*(100.^2)
894 // = erg/cm^3*(0.5 arcsec/pix)^2(722500m/arcsec)^2(100cm/m)^2
895 // = erg/cm^3*(1.30501e15)
|
896 xudong 1.1 // = erg/cm(1/pix^2)
897
|
898 xudong 1.27 int computeFreeEnergy(float *bx_err, float *by_err, float *bx, float *by, float *bpx, float *bpy, int *dims,
899 float *meanpotptr, float *meanpot_err_ptr, float *totpotptr, float *totpot_err_ptr, int *mask, int *bitmask,
|
900 xudong 1.1 float cdelt1, double rsun_ref, double rsun_obs)
901
902 {
|
903 xudong 1.27 int nx = dims[0];
904 int ny = dims[1];
905 int i = 0;
906 int j = 0;
907 int count_mask = 0;
|
908 mbobra 1.31 double sum = 0.0;
|
909 xudong 1.27 double sum1 = 0.0;
910 double err = 0.0;
911 *totpotptr = 0.0;
|
912 mbobra 1.31 *meanpotptr = 0.0;
|
913 xudong 1.27
|
914 mbobra 1.31 if (nx <= 0 || ny <= 0) return 1;
|
915 xudong 1.27
|
916 mbobra 1.31 for (i = 0; i < nx; i++)
|
917 xudong 1.27 {
|
918 mbobra 1.31 for (j = 0; j < ny; j++)
|
919 xudong 1.27 {
920 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
921 if isnan(bx[j * nx + i]) continue;
922 if isnan(by[j * nx + i]) continue;
923 sum += ( ((bx[j * nx + i] - bpx[j * nx + i])*(bx[j * nx + i] - bpx[j * nx + i])) + ((by[j * nx + i] - bpy[j * nx + i])*(by[j * nx + i] - bpy[j * nx + i])) )*(cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0);
924 sum1 += ( ((bx[j * nx + i] - bpx[j * nx + i])*(bx[j * nx + i] - bpx[j * nx + i])) + ((by[j * nx + i] - bpy[j * nx + i])*(by[j * nx + i] - bpy[j * nx + i])) );
925 err += 4.0*(bx[j * nx + i] - bpx[j * nx + i])*(bx[j * nx + i] - bpx[j * nx + i])*(bx_err[j * nx + i]*bx_err[j * nx + i]) +
926 4.0*(by[j * nx + i] - bpy[j * nx + i])*(by[j * nx + i] - bpy[j * nx + i])*(by_err[j * nx + i]*by_err[j * nx + i]);
927 count_mask++;
928 }
929 }
930
931 /* Units of meanpotptr are ergs per centimeter */
|
932 mbobra 1.20 *meanpotptr = (sum1) / (count_mask*8.*PI) ; /* Units are ergs per cubic centimeter */
|
933 xudong 1.27 *meanpot_err_ptr = (sqrt(err)) / (count_mask*8.*PI); // error in the quantity (sum)/(count_mask)
934
935 /* Units of sum are ergs/cm^3, units of factor are cm^2/pix^2; therefore, units of totpotptr are ergs per centimeter */
936 *totpotptr = (sum)/(8.*PI);
937 *totpot_err_ptr = (sqrt(err))*fabs(cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0*(1/(8.*PI)));
938
939 //printf("MEANPOT=%g\n",*meanpotptr);
940 //printf("MEANPOT_err=%g\n",*meanpot_err_ptr);
941
942 //printf("TOTPOT=%g\n",*totpotptr);
943 //printf("TOTPOT_err=%g\n",*totpot_err_ptr);
944
|
945 mbobra 1.31 return 0;
|
946 xudong 1.1 }
947
948 /*===========================================*/
|
949 mbobra 1.5 /* Example function 14: Mean 3D shear angle, area with shear greater than 45, mean horizontal shear angle, area with horizontal shear angle greater than 45 */
|
950 xudong 1.1
|
951 mbobra 1.20 int computeShearAngle(float *bx_err, float *by_err, float *bz_err, float *bx, float *by, float *bz, float *bpx, float *bpy, float *bpz, int *dims,
|
952 mbobra 1.9 float *meanshear_angleptr, float *meanshear_angle_err_ptr, float *area_w_shear_gt_45ptr, int *mask, int *bitmask)
|
953 mbobra 1.21
954
|
955 xudong 1.27 {
956 int nx = dims[0];
957 int ny = dims[1];
958 int i = 0;
959 int j = 0;
960 float count_mask = 0;
961 float count = 0;
962 double dotproduct = 0.0;
963 double magnitude_potential = 0.0;
964 double magnitude_vector = 0.0;
965 double shear_angle = 0.0;
966 double denominator = 0.0;
967 double term1 = 0.0;
968 double term2 = 0.0;
969 double term3 = 0.0;
970 double sumsum = 0.0;
971 double err = 0.0;
972 double part1 = 0.0;
973 double part2 = 0.0;
974 double part3 = 0.0;
975 *area_w_shear_gt_45ptr = 0.0;
|
976 mbobra 1.31 *meanshear_angleptr = 0.0;
|
977 xudong 1.1
|
978 mbobra 1.31 if (nx <= 0 || ny <= 0) return 1;
|
979 xudong 1.27
|
980 mbobra 1.31 for (i = 0; i < nx; i++)
|
981 xudong 1.27 {
|
982 mbobra 1.31 for (j = 0; j < ny; j++)
|
983 xudong 1.27 {
984 if ( mask[j * nx + i] < 70 || bitmask[j * nx + i] < 30 ) continue;
985 if isnan(bpx[j * nx + i]) continue;
986 if isnan(bpy[j * nx + i]) continue;
987 if isnan(bpz[j * nx + i]) continue;
988 if isnan(bz[j * nx + i]) continue;
989 if isnan(bx[j * nx + i]) continue;
990 if isnan(by[j * nx + i]) continue;
991 if isnan(bx_err[j * nx + i]) continue;
992 if isnan(by_err[j * nx + i]) continue;
993 if isnan(bz_err[j * nx + i]) continue;
994
995 /* For mean 3D shear angle, percentage with shear greater than 45*/
996 dotproduct = (bpx[j * nx + i])*(bx[j * nx + i]) + (bpy[j * nx + i])*(by[j * nx + i]) + (bpz[j * nx + i])*(bz[j * nx + i]);
997 magnitude_potential = sqrt( (bpx[j * nx + i]*bpx[j * nx + i]) + (bpy[j * nx + i]*bpy[j * nx + i]) + (bpz[j * nx + i]*bpz[j * nx + i]));
998 magnitude_vector = sqrt( (bx[j * nx + i]*bx[j * nx + i]) + (by[j * nx + i]*by[j * nx + i]) + (bz[j * nx + i]*bz[j * nx + i]) );
999 //printf("dotproduct=%f\n",dotproduct);
1000 //printf("magnitude_potential=%f\n",magnitude_potential);
1001 //printf("magnitude_vector=%f\n",magnitude_vector);
1002
1003 shear_angle = acos(dotproduct/(magnitude_potential*magnitude_vector))*(180./PI);
1004 xudong 1.27 sumsum += shear_angle;
1005 //printf("shear_angle=%f\n",shear_angle);
1006 count ++;
1007
1008 if (shear_angle > 45) count_mask ++;
1009
1010 // For the error analysis
1011
1012 term1 = bx[j * nx + i]*by[j * nx + i]*bpy[j * nx + i] - by[j * nx + i]*by[j * nx + i]*bpx[j * nx + i] + bz[j * nx + i]*bx[j * nx + i]*bpz[j * nx + i] - bz[j * nx + i]*bz[j * nx + i]*bpx[j * nx + i];
1013 term2 = bx[j * nx + i]*bx[j * nx + i]*bpy[j * nx + i] - bx[j * nx + i]*by[j * nx + i]*bpx[j * nx + i] + bx[j * nx + i]*bz[j * nx + i]*bpy[j * nx + i] - bz[j * nx + i]*by[j * nx + i]*bpz[j * nx + i];
1014 term3 = bx[j * nx + i]*bx[j * nx + i]*bpz[j * nx + i] - bx[j * nx + i]*bz[j * nx + i]*bpx[j * nx + i] + by[j * nx + i]*by[j * nx + i]*bpz[j * nx + i] - by[j * nx + i]*bz[j * nx + i]*bpy[j * nx + i];
1015
1016 part1 = bx[j * nx + i]*bx[j * nx + i] + by[j * nx + i]*by[j * nx + i] + bz[j * nx + i]*bz[j * nx + i];
1017 part2 = bpx[j * nx + i]*bpx[j * nx + i] + bpy[j * nx + i]*bpy[j * nx + i] + bpz[j * nx + i]*bpz[j * nx + i];
1018 part3 = bx[j * nx + i]*bpx[j * nx + i] + by[j * nx + i]*bpy[j * nx + i] + bz[j * nx + i]*bpz[j * nx + i];
1019
1020 // denominator is squared
1021 denominator = part1*part1*part1*part2*(1.0-((part3*part3)/(part1*part2)));
1022
1023 err = (term1*term1*bx_err[j * nx + i]*bx_err[j * nx + i])/(denominator) +
1024 (term1*term1*bx_err[j * nx + i]*bx_err[j * nx + i])/(denominator) +
1025 xudong 1.27 (term1*term1*bx_err[j * nx + i]*bx_err[j * nx + i])/(denominator) ;
1026
1027 }
1028 }
1029 /* For mean 3D shear angle, area with shear greater than 45*/
1030 *meanshear_angleptr = (sumsum)/(count); /* Units are degrees */
1031 *meanshear_angle_err_ptr = (sqrt(err)/count_mask)*(180./PI);
1032
1033 /* The area here is a fractional area -- the % of the total area. This has no error associated with it. */
1034 *area_w_shear_gt_45ptr = (count_mask/(count))*(100.0);
1035
1036 //printf("MEANSHR=%f\n",*meanshear_angleptr);
1037 //printf("MEANSHR_err=%f\n",*meanshear_angle_err_ptr);
1038 //printf("SHRGT45=%f\n",*area_w_shear_gt_45ptr);
1039
1040 return 0;
1041 }
|
1042 xudong 1.1
|
1043 xudong 1.27 /*===========================================*/
|
1044 mbobra 1.29 /* Example function 15: R parameter as defined in Schrijver, 2007 */
1045 //
1046 // Note that there is a restriction on the function fsample()
1047 // If the following occurs:
1048 // nx_out > floor((ny_in-1)/scale + 1)
1049 // ny_out > floor((ny_in-1)/scale + 1),
1050 // where n*_out are the dimensions of the output array and n*_in
1051 // are the dimensions of the input array, fsample() will usually result
1052 // in a segfault (though not always, depending on how the segfault was accessed.)
1053
|
1054 xudong 1.27 int computeR(float *bz_err, float *los, int *dims, float *Rparam, float cdelt1,
1055 float *rim, float *p1p0, float *p1n0, float *p1p, float *p1n, float *p1,
|
1056 mbobra 1.30 float *pmap, int nx1, int ny1,
1057 int scale, float *p1pad, int nxp, int nyp, float *pmapn)
1058
|
1059 mbobra 1.29 {
|
1060 xudong 1.27 int nx = dims[0];
1061 int ny = dims[1];
1062 int i = 0;
1063 int j = 0;
|
1064 mbobra 1.30 int index, index1;
|
1065 xudong 1.27 double sum = 0.0;
1066 double err = 0.0;
1067 *Rparam = 0.0;
1068 struct fresize_struct fresboxcar, fresgauss;
|
1069 mbobra 1.30 struct fint_struct fints;
|
1070 xudong 1.27 float sigma = 10.0/2.3548;
1071
|
1072 mbobra 1.30 // set up convolution kernels
|
1073 xudong 1.27 init_fresize_boxcar(&fresboxcar,1,1);
1074 init_fresize_gaussian(&fresgauss,sigma,20,1);
|
1075 mbobra 1.29
|
1076 mbobra 1.30 // =============== [STEP 1] ===============
1077 // bin the line-of-sight magnetogram down by a factor of scale
|
1078 xudong 1.27 fsample(los, rim, nx, ny, nx, nx1, ny1, nx1, scale, 0, 0, 0.0);
|
1079 mbobra 1.29
|
1080 mbobra 1.30 // =============== [STEP 2] ===============
1081 // identify positive and negative pixels greater than +/- 150 gauss
1082 // and label those pixels with a 1.0 in arrays p1p0 and p1n0
|
1083 xudong 1.27 for (i = 0; i < nx1; i++)
1084 {
1085 for (j = 0; j < ny1; j++)
1086 {
1087 index = j * nx1 + i;
1088 if (rim[index] > 150)
1089 p1p0[index]=1.0;
1090 else
1091 p1p0[index]=0.0;
1092 if (rim[index] < -150)
1093 p1n0[index]=1.0;
1094 else
1095 p1n0[index]=0.0;
1096 }
1097 }
|
1098 mbobra 1.30
1099 // =============== [STEP 3] ===============
1100 // smooth each of the negative and positive pixel bitmaps
|
1101 xudong 1.27 fresize(&fresboxcar, p1p0, p1p, nx1, ny1, nx1, nx1, ny1, nx1, 0, 0, 0.0);
1102 fresize(&fresboxcar, p1n0, p1n, nx1, ny1, nx1, nx1, ny1, nx1, 0, 0, 0.0);
|
1103 mbobra 1.30
1104 // =============== [STEP 4] ===============
1105 // find the pixels for which p1p and p1n are both equal to 1.
1106 // this defines the polarity inversion line
|
1107 xudong 1.27 for (i = 0; i < nx1; i++)
1108 {
1109 for (j = 0; j < ny1; j++)
1110 {
1111 index = j * nx1 + i;
|
1112 mbobra 1.30 if ((p1p[index] > 0.0) && (p1n[index] > 0.0))
|
1113 xudong 1.27 p1[index]=1.0;
1114 else
1115 p1[index]=0.0;
1116 }
1117 }
|
1118 mbobra 1.30
1119 // pad p1 with zeroes so that the gaussian colvolution in step 5
1120 // does not cut off data within hwidth of the edge
1121
1122 // step i: zero p1pad
1123 for (i = 0; i < nxp; i++)
1124 {
1125 for (j = 0; j < nyp; j++)
1126 {
1127 index = j * nxp + i;
1128 p1pad[index]=0.0;
1129 }
1130 }
1131
1132 // step ii: place p1 at the center of p1pad
1133 for (i = 0; i < nx1; i++)
1134 {
1135 for (j = 0; j < ny1; j++)
1136 {
1137 index = j * nx1 + i;
1138 index1 = (j+20) * nxp + (i+20);
1139 mbobra 1.30 p1pad[index1]=p1[index];
1140 }
1141 }
1142
1143 // =============== [STEP 5] ===============
1144 // convolve the polarity inversion line map with a gaussian
1145 // to identify the region near the plarity inversion line
1146 // the resultant array is called pmap
1147 fresize(&fresgauss, p1pad, pmap, nxp, nyp, nxp, nxp, nyp, nxp, 0, 0, 0.0);
1148
1149
1150 // select out the nx1 x ny1 non-padded array within pmap
1151 for (i = 0; i < nx1; i++)
1152 {
1153 for (j = 0; j < ny1; j++)
1154 {
1155 index = j * nx1 + i;
1156 index1 = (j+20) * nxp + (i+20);
1157 pmapn[index]=pmap[index1];
1158 }
1159 }
1160 mbobra 1.30
1161 // =============== [STEP 6] ===============
1162 // the R parameter is calculated
|
1163 xudong 1.27 for (i = 0; i < nx1; i++)
1164 {
1165 for (j = 0; j < ny1; j++)
1166 {
1167 index = j * nx1 + i;
|
1168 mbobra 1.32 if isnan(pmapn[index]) continue;
1169 if isnan(rim[index]) continue;
|
1170 mbobra 1.30 sum += pmapn[index]*abs(rim[index]);
|
1171 xudong 1.27 }
1172 }
1173
1174 if (sum < 1.0)
1175 *Rparam = 0.0;
1176 else
1177 *Rparam = log10(sum);
|
1178 mbobra 1.30
|
1179 mbobra 1.32 //printf("R_VALUE=%f\n",*Rparam);
1180
|
1181 xudong 1.27 free_fresize(&fresboxcar);
1182 free_fresize(&fresgauss);
|
1183 mbobra 1.30
|
1184 xudong 1.27 return 0;
|
1185 mbobra 1.30
|
1186 xudong 1.1 }
1187
|
1188 mbobra 1.31 /*===========================================*/
1189 /* Example function 16: Lorentz force as defined in Fisher, 2012 */
1190 //
1191 // This calculation is adapted from Xudong's code
1192 // at /proj/cgem/lorentz/apps/lorentz.c
1193
1194 int computeLorentz(float *bx, float *by, float *bz, float *fx, float *fy, float *fz, int *dims,
1195 float *totfx_ptr, float *totfy_ptr, float *totfz_ptr, float *totbsq_ptr,
1196 float *epsx_ptr, float *epsy_ptr, float *epsz_ptr, int *mask, int *bitmask,
1197 float cdelt1, double rsun_ref, double rsun_obs)
1198
1199 {
1200
1201 int nx = dims[0];
1202 int ny = dims[1];
1203 int nxny = nx*ny;
1204 int j = 0;
1205 int index;
1206 double totfx = 0, totfy = 0, totfz = 0;
1207 double bsq = 0, totbsq = 0;
1208 double epsx = 0, epsy = 0, epsz = 0;
1209 mbobra 1.31 double area = cdelt1*cdelt1*(rsun_ref/rsun_obs)*(rsun_ref/rsun_obs)*100.0*100.0;
1210 double k_h = -1.0 * area / (4. * PI) / 1.0e20;
1211 double k_z = area / (8. * PI) / 1.0e20;
1212
1213 if (nx <= 0 || ny <= 0) return 1;
1214
1215 for (int i = 0; i < nxny; i++)
1216 {
1217 if ( mask[i] < 70 || bitmask[i] < 30 ) continue;
1218 if isnan(bx[i]) continue;
1219 if isnan(by[i]) continue;
1220 if isnan(bz[i]) continue;
|
1221 mbobra 1.32 fx[i] = bx[i] * bz[i] * k_h;
1222 fy[i] = by[i] * bz[i] * k_h;
|
1223 mbobra 1.31 fz[i] = (bx[i] * bx[i] + by[i] * by[i] - bz[i] * bz[i]) * k_z;
1224 bsq = bx[i] * bx[i] + by[i] * by[i] + bz[i] * bz[i];
1225 totfx += fx[i]; totfy += fy[i]; totfz += fz[i];
1226 totbsq += bsq;
1227 }
1228
1229 *totfx_ptr = totfx;
1230 *totfy_ptr = totfy;
1231 *totfz_ptr = totfz;
1232 *totbsq_ptr = totbsq;
1233 *epsx_ptr = (totfx / k_h) / totbsq;
1234 *epsy_ptr = (totfy / k_h) / totbsq;
1235 *epsz_ptr = (totfz / k_z) / totbsq;
1236
|
1237 mbobra 1.32 //printf("TOTBSQ=%f\n",*totbsq_ptr);
1238
|
1239 mbobra 1.31 return 0;
1240
1241 }
1242
|
1243 xudong 1.1 /*==================KEIJI'S CODE =========================*/
1244
1245 // #include <omp.h>
1246 #include <math.h>
1247
1248 void greenpot(float *bx, float *by, float *bz, int nnx, int nny)
1249 {
|
1250 xudong 1.27 /* local workings */
1251 int inx, iny, i, j, n;
1252 /* local array */
1253 float *pfpot, *rdist;
1254 pfpot=(float *)malloc(sizeof(float) *nnx*nny);
1255 rdist=(float *)malloc(sizeof(float) *nnx*nny);
1256 float *bztmp;
1257 bztmp=(float *)malloc(sizeof(float) *nnx*nny);
1258 /* make nan */
1259 // unsigned long long llnan = 0x7ff0000000000000;
1260 // float NAN = (float)(llnan);
1261
1262 // #pragma omp parallel for private (inx)
1263 for (iny=0; iny < nny; iny++){for (inx=0; inx < nnx; inx++){pfpot[nnx*iny+inx] = 0.0;}}
1264 // #pragma omp parallel for private (inx)
1265 for (iny=0; iny < nny; iny++){for (inx=0; inx < nnx; inx++){rdist[nnx*iny+inx] = 0.0;}}
1266 // #pragma omp parallel for private (inx)
1267 for (iny=0; iny < nny; iny++){for (inx=0; inx < nnx; inx++){bx[nnx*iny+inx] = 0.0;}}
1268 // #pragma omp parallel for private (inx)
1269 for (iny=0; iny < nny; iny++){for (inx=0; inx < nnx; inx++){by[nnx*iny+inx] = 0.0;}}
1270 // #pragma omp parallel for private (inx)
1271 xudong 1.27 for (iny=0; iny < nny; iny++){for (inx=0; inx < nnx; inx++)
1272 {
1273 float val0 = bz[nnx*iny + inx];
1274 if (isnan(val0)){bztmp[nnx*iny + inx] = 0.0;}else{bztmp[nnx*iny + inx] = val0;}
1275 }}
1276
1277 // dz is the monopole depth
1278 float dz = 0.001;
1279
1280 // #pragma omp parallel for private (inx)
1281 for (iny=0; iny < nny; iny++){for (inx=0; inx < nnx; inx++)
1282 {
1283 float rdd, rdd1, rdd2;
1284 float r;
1285 rdd1 = (float)(inx);
1286 rdd2 = (float)(iny);
1287 rdd = rdd1 * rdd1 + rdd2 * rdd2 + dz * dz;
1288 rdist[nnx*iny+inx] = 1.0/sqrt(rdd);
1289 }}
1290
1291 int iwindow;
1292 xudong 1.27 if (nnx > nny) {iwindow = nnx;} else {iwindow = nny;}
1293 float rwindow;
1294 rwindow = (float)(iwindow);
1295 rwindow = rwindow * rwindow + 0.01; // must be of square
1296
1297 rwindow = 1.0e2; // limit the window size to be 10.
1298
1299 rwindow = sqrt(rwindow);
1300 iwindow = (int)(rwindow);
1301
1302 // #pragma omp parallel for private(inx)
1303 for (iny=0;iny<nny;iny++){for (inx=0;inx<nnx;inx++)
|
1304 xudong 1.1 {
|
1305 xudong 1.27 float val0 = bz[nnx*iny + inx];
1306 if (isnan(val0))
1307 {
1308 pfpot[nnx*iny + inx] = 0.0; // hmmm.. NAN;
1309 }
1310 else
1311 {
1312 float sum;
1313 sum = 0.0;
1314 int j2, i2;
1315 int j2s, j2e, i2s, i2e;
1316 j2s = iny - iwindow;
1317 j2e = iny + iwindow;
1318 if (j2s < 0){j2s = 0;}
1319 if (j2e > nny){j2e = nny;}
1320 i2s = inx - iwindow;
1321 i2e = inx + iwindow;
1322 if (i2s < 0){i2s = 0;}
1323 if (i2e > nnx){i2e = nnx;}
1324
1325 for (j2=j2s;j2<j2e;j2++){for (i2=i2s;i2<i2e;i2++)
1326 xudong 1.27 {
1327 float val1 = bztmp[nnx*j2 + i2];
1328 float rr, r1, r2;
1329 // r1 = (float)(i2 - inx);
1330 // r2 = (float)(j2 - iny);
1331 // rr = r1*r1 + r2*r2;
1332 // if (rr < rwindow)
1333 // {
1334 int di, dj;
1335 di = abs(i2 - inx);
1336 dj = abs(j2 - iny);
1337 sum = sum + val1 * rdist[nnx * dj + di] * dz;
1338 // }
1339 } }
1340 pfpot[nnx*iny + inx] = sum; // Note that this is a simplified definition.
1341 }
1342 } } // end of OpenMP parallelism
1343
1344 // #pragma omp parallel for private(inx)
1345 for (iny=1; iny < nny - 1; iny++){for (inx=1; inx < nnx - 1; inx++)
|
1346 xudong 1.1 {
|
1347 xudong 1.27 bx[nnx*iny + inx] = -(pfpot[nnx*iny + (inx+1)]-pfpot[nnx*iny + (inx-1)]) * 0.5;
1348 by[nnx*iny + inx] = -(pfpot[nnx*(iny+1) + inx]-pfpot[nnx*(iny-1) + inx]) * 0.5;
1349 } } // end of OpenMP parallelism
1350
1351 free(rdist);
1352 free(pfpot);
1353 free(bztmp);
|
1354 xudong 1.1 } // end of void func. greenpot
1355
1356
1357 /*===========END OF KEIJI'S CODE =========================*/
|
1358 mbobra 1.14
1359 char *sw_functions_version() // Returns CVS version of sw_functions.c
1360 {
|
1361 xudong 1.27 return strdup("$Id");
|
1362 mbobra 1.14 }
1363
|
1364 xudong 1.1 /* ---------------- end of this file ----------------*/
|