00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "cddefines.h"
00010 #include "physconst.h"
00011 #include "radius.h"
00012 #include "dense.h"
00013 #include "hyperfine.h"
00014 #include "magnetic.h"
00015 #include "hmi.h"
00016 #include "phycon.h"
00017 #include "geometry.h"
00018 #include "mean.h"
00019
00020
00021 void MeanInc(void)
00022 {
00023 long int ion,
00024 nelem;
00025 double dc,
00026 dcv;
00027
00028
00029
00030
00031 DEBUG_ENTRY( "MeanInc()" );
00032
00033 for( nelem=0; nelem < LIMELM; nelem++ )
00034 {
00035
00036 if( nelem==ipHYDROGEN )
00037 {
00038
00039
00040 ion = 2;
00041
00042
00043
00044
00045 dc = 2.*hmi.H2_total*radius.drad_x_fillfac;
00046 mean.xIonMeans[0][nelem][ion] += dc;
00047
00048 dc = 2.*hmi.H2_total*radius.drad_x_fillfac*dense.eden;
00049 mean.xIonEdenMeans[0][nelem][ion] += dc;
00050
00051 dcv = 2.*hmi.H2_total*radius.dVeff;
00052 mean.xIonMeans[1][nelem][ion] += dcv;
00053
00054 dcv = 2.*hmi.H2_total*radius.dVeff*dense.eden;
00055 mean.xIonEdenMeans[1][nelem][ion] += dcv;
00056 }
00057 for( ion=0; ion < (nelem + 2); ion++ )
00058 {
00059
00060 dc = dense.xIonDense[nelem][ion]*radius.drad_x_fillfac;
00061 mean.xIonMeans[0][nelem][ion] += dc;
00062
00063
00064 dc = dense.xIonDense[nelem][ion]*radius.drad_x_fillfac*dense.eden;
00065 mean.xIonEdenMeans[0][nelem][ion] += dc;
00066
00067
00068
00069
00070 dcv = dense.xIonDense[nelem][ion]*radius.dVeff;
00071 mean.xIonMeans[1][nelem][ion] += dcv;
00072
00073
00074
00075
00076 dcv = dense.xIonDense[nelem][ion]*radius.dVeff*dense.eden;
00077 mean.xIonEdenMeans[1][nelem][ion] += dcv;
00078 }
00079
00080
00081 dc = dense.gas_phase[nelem]*radius.drad_x_fillfac;
00082 mean.xIonMeansNorm[0][nelem] += dc;
00083 dc = dense.gas_phase[nelem]*radius.drad_x_fillfac*dense.eden;
00084 mean.xIonEdenMeansNorm[0][nelem] += dc;
00085
00086
00087
00088
00089
00090 dcv = dense.gas_phase[nelem]*radius.dVeff;
00091 mean.xIonMeansNorm[1][nelem] += dcv;
00092
00093 dcv = dense.gas_phase[nelem]*radius.dVeff*dense.eden;
00094 mean.xIonEdenMeansNorm[1][nelem] += dcv;
00095
00096
00097
00098
00099
00100
00101 if( nelem==ipHYDROGEN )
00102 {
00103 ion = 2;
00104
00105 dc = 2.*hmi.H2_total*radius.drad_x_fillfac;
00106 mean.TempMeans[0][nelem][ion] += dc*phycon.te;
00107 mean.TempMeansNorm[0][nelem][ion] += dc;
00108
00109
00110 dc = 2.*hmi.H2_total*radius.drad_x_fillfac*dense.eden;
00111 mean.TempEdenMeans[0][nelem][ion] += dc*phycon.te;
00112 mean.TempEdenMeansNorm[0][nelem][ion] += dc;
00113
00114
00115
00116 dcv = 2.*hmi.H2_total*radius.dVeff;
00117 mean.TempMeans[1][nelem][ion] += dcv*phycon.te;
00118 mean.TempMeansNorm[1][nelem][ion] += dcv;
00119
00120
00121 dcv = 2.*hmi.H2_total*radius.dVeff*dense.eden;
00122 mean.TempEdenMeans[1][nelem][ion] += dcv*phycon.te;
00123 mean.TempEdenMeansNorm[1][nelem][ion] += dcv;
00124 }
00125 for( ion=0; ion < (nelem + 2); ion++ )
00126 {
00127
00128 dc = dense.xIonDense[nelem][ion]*radius.drad_x_fillfac;
00129 mean.TempMeans[0][nelem][ion] += dc*phycon.te;
00130 mean.TempMeansNorm[0][nelem][ion] += dc;
00131
00132
00133 dc = dense.xIonDense[nelem][ion]*radius.drad_x_fillfac*dense.eden;
00134 mean.TempEdenMeans[0][nelem][ion] += dc*phycon.te;
00135 mean.TempEdenMeansNorm[0][nelem][ion] += dc;
00136
00137
00138
00139 dcv = dense.xIonDense[nelem][ion]*radius.dVeff;
00140 mean.TempMeans[1][nelem][ion] += dcv*phycon.te;
00141 mean.TempMeansNorm[1][nelem][ion] += dcv;
00142
00143
00144 dcv = dense.xIonDense[nelem][ion]*radius.dVeff*dense.eden;
00145 mean.TempEdenMeans[1][nelem][ion] += dcv*phycon.te;
00146 mean.TempEdenMeansNorm[1][nelem][ion] += dcv;
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 if( hyperfine.Tspin21cm > SMALLFLOAT )
00159 {
00160 dc = dense.xIonDense[ipHYDROGEN][0]*radius.drad_x_fillfac/phycon.te;
00161 }
00162 else
00163 {
00164 dc = 0.;
00165 }
00166
00167 mean.B_HarMeanTempRadius[0] += sqrt(fabs(magnetic.pressure)*PI8) * dc;
00168
00169 mean.B_HarMeanTempRadius[1] += dc;
00170
00171
00172
00173 dc = dense.xIonDense[ipHYDROGEN][0]*radius.drad_x_fillfac;
00174
00175
00176
00177
00178
00179 mean.HarMeanTempRadius[0] += dc;
00180 mean.HarMeanTempRadius[1] += dc/phycon.te;
00181
00182
00183 mean.HarMeanTempVolume[0] += dc*radius.r1r0sq;
00184 mean.HarMeanTempVolume[1] += dc/phycon.te*radius.r1r0sq;
00185
00186
00187 mean.H_21cm_spin_mean_radius[0] += dc;
00188 mean.H_21cm_spin_mean_radius[1] += dc / SDIV( hyperfine.Tspin21cm );
00189
00190
00191 dc = hmi.H2_total*radius.drad_x_fillfac;
00192 mean.H2MeanTempRadius[0] += dc*phycon.te;
00193 mean.H2MeanTempRadius[1] += dc;
00194
00195
00196 dcv = hmi.H2_total*radius.dVeff;
00197 mean.H2MeanTempVolume[0] += dc*phycon.te;
00198 mean.H2MeanTempVolume[1] += dc;
00199
00200
00201 dc = radius.drad_x_fillfac;
00202 mean.TempMeanRadius[0] += dc*phycon.te;
00203 mean.TempMeanRadius[1] += dc;
00204
00205 dcv = radius.dVeff;
00206 mean.TempMeanVolume[0] += dc*phycon.te;
00207 mean.TempMeanVolume[1] += dc;
00208 return;
00209 }
00210
00211
00212 void MeanZero(void)
00213 {
00214 long int ion,
00215 j,
00216 nelem,
00217 limit;
00218 static bool lgFirst=true;
00219
00220 DEBUG_ENTRY( "MeanZero()" );
00221
00222
00223
00224
00225
00226
00227 if( lgFirst )
00228 {
00229 lgFirst = false;
00230
00231 mean.xIonMeans = (double ***)MALLOC(sizeof(double **)*(unsigned)(2) );
00232 mean.xIonEdenMeans = (double ***)MALLOC(sizeof(double **)*(unsigned)(2) );
00233 mean.xIonMeansNorm = (double **)MALLOC(sizeof(double *)*(unsigned)(2) );
00234 mean.xIonEdenMeansNorm = (double **)MALLOC(sizeof(double *)*(unsigned)(2) );
00235 mean.TempMeans = (double ***)MALLOC(sizeof(double **)*(unsigned)(2) );
00236 mean.TempEdenMeans = (double ***)MALLOC(sizeof(double **)*(unsigned)(2) );
00237 mean.TempMeansNorm = (double ***)MALLOC(sizeof(double **)*(unsigned)(2) );
00238 mean.TempEdenMeansNorm = (double ***)MALLOC(sizeof(double **)*(unsigned)(2) );
00239 for( j=0; j<2; ++j )
00240 {
00241 mean.xIonMeans[j] = (double **)MALLOC(sizeof(double *)*(unsigned)(LIMELM) );
00242 mean.xIonEdenMeans[j] = (double **)MALLOC(sizeof(double *)*(unsigned)(LIMELM) );
00243 mean.xIonMeansNorm[j] = (double *)MALLOC(sizeof(double )*(unsigned)(LIMELM) );
00244 mean.xIonEdenMeansNorm[j] = (double *)MALLOC(sizeof(double )*(unsigned)(LIMELM) );
00245 mean.TempMeans[j] = (double **)MALLOC(sizeof(double *)*(unsigned)(LIMELM) );
00246 mean.TempEdenMeans[j] = (double **)MALLOC(sizeof(double *)*(unsigned)(LIMELM) );
00247 mean.TempMeansNorm[j] = (double **)MALLOC(sizeof(double *)*(unsigned)(LIMELM) );
00248 mean.TempEdenMeansNorm[j] = (double **)MALLOC(sizeof(double *)*(unsigned)(LIMELM) );
00249 for( nelem=0; nelem<LIMELM; ++nelem )
00250 {
00251 limit = MAX2(3,nelem+2);
00252 mean.xIonMeans[j][nelem] = (double *)MALLOC(sizeof(double )*(unsigned)(limit) );
00253 mean.xIonEdenMeans[j][nelem] = (double *)MALLOC(sizeof(double )*(unsigned)(limit) );
00254 mean.TempMeans[j][nelem] = (double *)MALLOC(sizeof(double )*(unsigned)(limit) );
00255 mean.TempEdenMeans[j][nelem] = (double *)MALLOC(sizeof(double )*(unsigned)(limit) );
00256 mean.TempMeansNorm[j][nelem] = (double *)MALLOC(sizeof(double )*(unsigned)(limit) );
00257 mean.TempEdenMeansNorm[j][nelem] = (double *)MALLOC(sizeof(double )*(unsigned)(limit) );
00258 }
00259 }
00260 }
00261
00262 for( j=0; j < 2; j++ )
00263 {
00264 for( nelem=0; nelem < LIMELM; nelem++ )
00265 {
00266 mean.xIonMeansNorm[j][nelem] = 0.;
00267 mean.xIonEdenMeansNorm[j][nelem] = 0.;
00268
00269 limit = MAX2(3,nelem+2);
00270
00271 for( ion=0; ion < limit; ion++ )
00272 {
00273 mean.TempMeansNorm[j][nelem][ion] = 0.;
00274 mean.TempEdenMeansNorm[j][nelem][ion] = 0.;
00275
00276 mean.xIonMeans[j][nelem][ion] = 0.;
00277 mean.xIonEdenMeans[j][nelem][ion] = 0.;
00278
00279 mean.TempMeans[j][nelem][ion] = 0.;
00280 mean.TempEdenMeans[j][nelem][ion] = 0.;
00281 }
00282 }
00283 }
00284
00285
00286 mean.HarMeanTempRadius[0] = 0.;
00287 mean.HarMeanTempRadius[1] = 0.;
00288
00289
00290 mean.HarMeanTempVolume[0] = 0.;
00291 mean.HarMeanTempVolume[1] = 0.;
00292
00293
00294 mean.H_21cm_spin_mean_radius[0] = 0.;
00295 mean.H_21cm_spin_mean_radius[1] = 0.;
00296
00297
00298 mean.H2MeanTempRadius[0] = 0.;
00299 mean.H2MeanTempRadius[1] = 0.;
00300
00301 mean.H2MeanTempVolume[0] = 0.;
00302 mean.H2MeanTempVolume[1] = 0.;
00303
00304 mean.TempMeanRadius[0] = 0.;
00305 mean.TempMeanRadius[1] = 0.;
00306 mean.TempMeanVolume[0] = 0.;
00307 mean.TempMeanVolume[1] = 0.;
00308
00309 mean.B_HarMeanTempRadius[0] = 0.;
00310 mean.B_HarMeanTempRadius[1] = 0.;
00311 return;
00312 }
00313
00314
00315 void MeanIonRadius(
00316
00317 char chType,
00318
00319 long int nelem,
00320
00321 long int *n,
00322
00323
00324 realnum arlog[],
00325
00326 bool lgDensity )
00327 {
00328 long int ion,
00329 limit;
00330 double abund_radmean,
00331 normalize;
00332
00333 DEBUG_ENTRY( "MeanIonRadius()" );
00334
00335 ASSERT( chType=='i' || chType=='t' );
00336
00337
00338
00339
00340 limit = MAX2( 3, nelem+2 );
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 if( !dense.lgElmtOn[nelem] )
00351 {
00352
00353
00354
00355 for( ion=0; ion < limit; ion++ )
00356 {
00357 arlog[ion] = -30.f;
00358 }
00359 *n = 0;
00360 return;
00361 }
00362
00363
00364
00365 *n = limit;
00366 while( *n > 0 && mean.xIonMeans[0][nelem][*n-1] <= 0. )
00367 {
00368 arlog[*n-1] = -30.f;
00369 --*n;
00370 }
00371
00372 if( chType=='i' && lgDensity)
00373 {
00374
00375 for( ion=0; ion < *n; ion++ )
00376 {
00377 if( mean.xIonEdenMeans[0][nelem][ion] > 0. )
00378 {
00379 abund_radmean = mean.xIonEdenMeans[0][nelem][ion];
00380 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_radmean / mean.xIonEdenMeansNorm[0][nelem]));
00381 }
00382 else
00383 {
00384 arlog[ion] = -30.f;
00385 }
00386 }
00387 }
00388 else if( chType=='i' )
00389 {
00390
00391 for( ion=0; ion < *n; ion++ )
00392 {
00393 if( mean.xIonMeans[0][nelem][ion] > 0. )
00394 {
00395 abund_radmean = mean.xIonMeans[0][nelem][ion];
00396 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_radmean/mean.xIonMeansNorm[0][nelem]));
00397 }
00398 else
00399 {
00400 arlog[ion] = -30.f;
00401 }
00402 }
00403 }
00404 else if( chType=='t' && lgDensity )
00405 {
00406
00407 for( ion=0; ion < *n; ion++ )
00408 {
00409 normalize = mean.TempEdenMeansNorm[0][nelem][ion];
00410 if( normalize > SMALLFLOAT )
00411 {
00412 abund_radmean = mean.TempEdenMeans[0][nelem][ion];
00413 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_radmean/normalize));
00414 }
00415 else
00416 {
00417 arlog[ion] = -30.f;
00418 }
00419 }
00420 }
00421 else if( chType=='t' )
00422 {
00423
00424 for( ion=0; ion < *n; ion++ )
00425 {
00426 normalize = mean.TempMeansNorm[0][nelem][ion];
00427 if( normalize > SMALLFLOAT )
00428 {
00429 abund_radmean = mean.TempMeans[0][nelem][ion];
00430 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_radmean/normalize));
00431 }
00432 else
00433 {
00434 arlog[ion] = -30.f;
00435 }
00436 }
00437 }
00438 else
00439 {
00440 fprintf(ioQQQ," MeanIonRadius called with insane job \n");
00441 }
00442 return;
00443 }
00444
00445
00446 void MeanIonVolume(
00447
00448 char chType,
00449
00450 long int nelem,
00451
00452 long int *n,
00453
00454 realnum arlog[],
00455
00456 bool lgDensity )
00457 {
00458 long int ion;
00459 double abund_volmean,
00460 normalize;
00461 long int limit;
00462
00463 DEBUG_ENTRY( "MeanIonVolume()" );
00464
00465 ASSERT( chType=='i' || chType=='t' );
00466
00467
00468
00469 limit = MAX2( 3, nelem+2 );
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 if( !dense.lgElmtOn[nelem] )
00481 {
00482
00483 for( ion=0; ion <= limit; ion++ )
00484 {
00485 arlog[ion] = -30.f;
00486 }
00487 *n = 0;
00488 return;
00489 }
00490
00491
00492 *n = limit;
00493
00494
00495 while( *n > 0 && mean.xIonMeans[1][nelem][*n-1] <= 0. )
00496 {
00497 arlog[*n-1] = -30.f;
00498 --*n;
00499 }
00500
00501
00502 if( chType=='i' && lgDensity)
00503 {
00504
00505
00506
00507 for( ion=0; ion < *n; ion++ )
00508 {
00509 if( mean.xIonEdenMeans[1][nelem][ion] > 0. )
00510 {
00511 abund_volmean = mean.xIonEdenMeans[1][nelem][ion];
00512 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_volmean) / mean.xIonEdenMeansNorm[1][nelem]);
00513 }
00514 else
00515 {
00516 arlog[ion] = -30.f;
00517 }
00518 }
00519 }
00520 else if( chType=='i' )
00521 {
00522
00523
00524
00525 for( ion=0; ion < *n; ion++ )
00526 {
00527 if( mean.xIonMeans[1][nelem][ion] > 0. )
00528 {
00529 abund_volmean = mean.xIonMeans[1][nelem][ion];
00530 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_volmean) / mean.xIonMeansNorm[1][nelem]);
00531 }
00532 else
00533 {
00534 arlog[ion] = -30.f;
00535 }
00536 }
00537 }
00538 else if( chType=='t' && lgDensity )
00539 {
00540
00541
00542
00543 for( ion=0; ion < *n; ion++ )
00544 {
00545 normalize = mean.TempEdenMeansNorm[1][nelem][ion];
00546 if( normalize > SMALLFLOAT )
00547 {
00548 abund_volmean = mean.TempEdenMeans[1][nelem][ion];
00549 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_volmean)/normalize);
00550 }
00551 else
00552 {
00553 arlog[ion] = -30.f;
00554 }
00555 }
00556 }
00557 else if( chType=='t' )
00558 {
00559
00560
00561
00562 for( ion=0; ion < *n; ion++ )
00563 {
00564 normalize = mean.TempMeansNorm[1][nelem][ion];
00565 if( normalize > SMALLFLOAT )
00566 {
00567 abund_volmean = mean.TempMeans[1][nelem][ion];
00568 arlog[ion] = (realnum)log10(MAX2(1e-30,abund_volmean)/normalize);
00569 }
00570 else
00571 {
00572 arlog[ion] = -30.f;
00573 }
00574 }
00575 }
00576 else
00577 {
00578 fprintf(ioQQQ," MeanIonVolume called with insane job\n");
00579 }
00580 return;
00581 }
00582
00583
00584
00585 void aver(
00586
00587 const char *chWhat,
00588
00589 double quan,
00590
00591 double weight,
00592
00593 const char *chLabl)
00594 {
00595
00596 # define NAVER 20
00597 static char chLabavr[NAVER][11];
00598 long int i,
00599 ioff,
00600 j;
00601 static long int n;
00602 double raver[NAVER]={0.},
00603 vaver[NAVER]={0.};
00604 static double aversv[4][NAVER];
00605
00606 DEBUG_ENTRY( "aver()" );
00607
00608 if( strcmp(chWhat,"zero") == 0 )
00609 {
00610
00611 for( i=0; i < NAVER; i++ )
00612 {
00613 for( j=0; j < 4; j++ )
00614 {
00615 aversv[j][i] = 0.;
00616 }
00617 }
00618 n = 0;
00619 }
00620 else if( strcmp(chWhat,"zone") == 0 )
00621 {
00622 n = 0;
00623 }
00624 else if( strcmp(chWhat,"doit") == 0 )
00625 {
00626
00627 if( n >= NAVER )
00628 {
00629 fprintf( ioQQQ, " Too many values entered into AVER, increase NAVER\n" );
00630 cdEXIT(EXIT_FAILURE);
00631 }
00632 aversv[0][n] += weight*quan*radius.drad_x_fillfac;
00633 aversv[1][n] += weight*radius.drad_x_fillfac;
00634 aversv[2][n] += weight*quan*radius.dVeff;
00635 aversv[3][n] += weight*radius.dVeff;
00636
00637
00638 strcpy( chLabavr[n], chLabl );
00639 n += 1;
00640 }
00641 else if( strcmp(chWhat,"prin") == 0 )
00642 {
00643
00644 ioff = n*10/2 + 1;
00645
00646
00647 fprintf( ioQQQ,"\n");
00648 for( i=0; i < ioff; i++ )
00649 {
00650
00651 fprintf( ioQQQ, " " );
00652 }
00653
00654
00655 fprintf( ioQQQ, "Averaged Quantities\n " );
00656
00657 fprintf( ioQQQ, " " );
00658 for( i=0; i < n; i++ )
00659 {
00660 fprintf( ioQQQ, "%10.10s", chLabavr[i] );
00661 }
00662 fprintf( ioQQQ, " \n" );
00663
00664 for( i=0; i < n; i++ )
00665 {
00666 if( aversv[1][i] > 0. )
00667 {
00668 raver[i] = aversv[0][i]/aversv[1][i];
00669 }
00670 else
00671 {
00672 raver[i] = 0.;
00673 }
00674 if( aversv[3][i] > 0. )
00675 {
00676 vaver[i] = aversv[2][i]/aversv[3][i];
00677 }
00678 else
00679 {
00680 vaver[i] = 0.;
00681 }
00682 }
00683
00684 fprintf( ioQQQ, " Radius:" );
00685 for( i=0; i < n; i++ )
00686 {
00687
00688 fprintf( ioQQQ, " ");
00689 fprintf(ioQQQ,PrintEfmt("%9.2e", raver[i] ) );
00690 }
00691 fprintf( ioQQQ, "\n" );
00692
00693
00694 if( geometry.lgSphere )
00695 {
00696 fprintf( ioQQQ, " Volume:" );
00697 for( i=0; i < n; i++ )
00698 {
00699
00700 fprintf( ioQQQ, " ");
00701 fprintf(ioQQQ,PrintEfmt("%9.2e", vaver[i] ) );
00702 }
00703 fprintf( ioQQQ, "\n" );
00704 }
00705 }
00706 else
00707 {
00708 fprintf( ioQQQ, " AVER does not understand chWhat=%4.4s\n",
00709 chWhat );
00710 ShowMe();
00711 cdEXIT(EXIT_FAILURE);
00712 }
00713 return;
00714 }