00001
00002
00003
00004
00005 #include "cddefines.h"
00006 #include "physconst.h"
00007 #include "thirdparty.h"
00008 #include "dense.h"
00009 #include "elementnames.h"
00010 #include "continuum.h"
00011 #include "helike_recom.h"
00012 #include "rfield.h"
00013 #include "taulines.h"
00014 #include "hypho.h"
00015 #include "iso.h"
00016 #include "opacity.h"
00017 #include "hydro_bauman.h"
00018 #include "hydrogenic.h"
00019 #include "heavy.h"
00020 #include "trace.h"
00021 #include "cloudy.h"
00022
00023 namespace {
00024 class my_Integrand: public std::unary_function<double, double>
00025 {
00026 public:
00027 double operator() (double x)
00028 {
00029 return sin(x);
00030 }
00031
00032 my_Integrand() {}
00033 };
00034
00035
00036
00037 double mySin(double x)
00038 {
00039 return sin(x);
00040 }
00041 }
00042
00043
00044
00045
00046 STATIC void SanityCheckBegin(void );
00047 STATIC void SanityCheckFinal(void );
00048
00049
00050
00051 void SanityCheck( const char *chJob )
00052 {
00053 DEBUG_ENTRY( "SanityCheck()" );
00054
00055 if( strcmp(chJob,"begin") == 0 )
00056 {
00057 SanityCheckBegin();
00058 }
00059 else if( strcmp(chJob,"final") == 0 )
00060 {
00061 SanityCheckFinal();
00062 }
00063 else
00064 {
00065 fprintf(ioQQQ,"SanityCheck called with insane argument.\n");
00066 cdEXIT(EXIT_FAILURE);
00067 }
00068 }
00069
00070 STATIC void SanityCheckFinal(void )
00071 {
00072
00073 }
00074
00075 STATIC void SanityCheckBegin(void )
00076 {
00077 bool lgOK=true;
00078 int lgFlag;
00079 int32 ner, ipiv[3];
00080 long i ,
00081 j ,
00082 nelem ,
00083 ion ,
00084 nshells;
00085 double *A;
00086
00087
00088 double Aul ,
00089 error,
00090 Z4, gaunt;
00091
00092 long n, logu, loggamma2;
00093
00094 const int NDIM = 10;
00095 double x , ans1 , ans2 , xMatrix[NDIM][NDIM] , yVector[NDIM] ,
00096 rcond;
00097 realnum *fvector;
00098 long int *ipvector;
00099
00100 DEBUG_ENTRY( "SanityCheck()" );
00101
00102
00103
00104
00105
00106
00107
00108
00109 lgOK = true;
00110
00111
00112
00113
00114
00115
00116 for( nelem=0; nelem<LIMELM; ++nelem )
00117 {
00118
00119 if( dense.lgElmtOn[nelem] )
00120 {
00121
00122 Aul = H_Einstein_A( 2, 1, 1, 0, nelem+1 );
00123
00124 if( fabs(Aul - Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Aul ) /Aul > 0.01 )
00125 {
00126 fprintf(ioQQQ," SanityCheck found insane H-like As.\n");
00127 lgOK = false;
00128 }
00129 }
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 for( logu=-4; logu<=4; logu++)
00141 {
00142
00143 for(loggamma2=-4; loggamma2<=4; loggamma2++)
00144 {
00145 double SutherlandGff[9][9]=
00146 { {5.5243, 5.5213, 5.4983, 5.3780, 5.0090, 4.4354, 3.8317, 3.2472, 2.7008},
00147 {4.2581, 4.2577, 4.2403, 4.1307, 3.7816, 3.2436, 2.7008, 2.2126, 1.8041},
00148 {3.0048, 3.0125, 3.0152, 2.9434, 2.6560, 2.2131, 1.8071, 1.4933, 1.2771},
00149 {1.8153, 1.8367, 1.8880, 1.9243, 1.7825, 1.5088, 1.2886, 1.1507, 1.0747},
00150 {0.8531, 0.8815, 0.9698, 1.1699, 1.2939, 1.1988, 1.1033, 1.0501, 1.0237},
00151 {0.3101, 0.3283, 0.3900, 0.5894, 0.9725, 1.1284, 1.0825, 1.0419, 1.0202},
00152 {0.1007, 0.1080, 0.1335, 0.2281, 0.5171, 0.9561, 1.1065, 1.0693, 1.0355},
00153 {0.0320, 0.0344, 0.0432, 0.0772, 0.1997, 0.5146, 0.9548, 1.1042, 1.0680},
00154 {0.0101, 0.0109, 0.0138, 0.0249, 0.0675, 0.1987, 0.5146, 0.9547, 1.1040}};
00155
00156 gaunt = cont_gaunt_calc( TE1RYD/pow(10.,(double)loggamma2), 1., pow(10.,(double)(logu-loggamma2)) );
00157 error = fabs( gaunt - SutherlandGff[logu+4][loggamma2+4] ) /gaunt;
00158
00159 if( error>0.11 || ( loggamma2<2 && error>0.05 ) )
00160 {
00161 fprintf(ioQQQ," SanityCheck found insane gff. log(u) %li, log(gamma2) %li, error %.3e\n",
00162 logu, loggamma2, error );
00163 lgOK = false;
00164 }
00165 }
00166
00167 }
00168
00169
00170
00171
00172
00173
00174 for( nelem=1; nelem<LIMELM; ++nelem )
00175 {
00176
00177 double as[]={
00178
00179 0. ,9.47e+006 ,3.44e+008 ,1.74e+009 ,5.51e+009 ,1.34e+010 ,
00180 2.79e+010 ,5.32E+010 ,8.81e+010 ,1.46E+011 ,2.15e+011 ,3.15e+011 ,
00181 4.46e+011 ,6.39E+011 ,8.26e+011 ,1.09e+012 ,1.41e+012 ,1.86E+012 ,
00182 2.26e+012 ,2.80e+012 ,3.44e+012 ,4.18e+012 ,5.04e+012 ,6.02e+012 ,
00183 7.14e+012 ,8.40e+012 ,9.83e+012 ,1.14e+013 ,1.32e+013 ,1.52e+013
00184 };
00185
00186 if( iso.numLevels_max[ipHE_LIKE][nelem] > 8 && dense.lgElmtOn[nelem])
00187 {
00188
00189
00190 if( fabs( as[nelem] - Transitions[ipHE_LIKE][nelem][9][1].Emis->Aul ) /as[nelem] > 0.025 )
00191 {
00192 fprintf(ioQQQ,
00193 " SanityCheck found insane He-like As: expected, nelem=%li found: %.2e %.2e.\n",
00194 nelem,
00195 as[nelem] ,
00196 Transitions[ipHE_LIKE][nelem][9][1].Emis->Aul );
00197 lgOK = false;
00198 }
00199 }
00200 }
00201
00202
00203 if( !opac.lgCaseB )
00204 {
00205
00206 for( i = 0; i <=110; i++ )
00207 {
00208 double DrakeTotalAuls[111] = {
00209 -1.0000E+00, -1.0000E+00, -1.0000E+00, 1.02160E+07,
00210 1.02160E+07, 1.02160E+07, 1.80090E+09, 2.78530E+07,
00211 1.82990E+07, 1.05480E+07, 7.07210E+07, 6.37210E+07,
00212 5.79960E+08, 1.60330E+07, 1.13640E+07, 7.21900E+06,
00213 3.11920E+07, 2.69830E+07, 1.38380E+07, 1.38330E+07,
00214 2.52270E+08, 9.20720E+06, 6.82220E+06, 4.56010E+06,
00215 1.64120E+07, 1.39290E+07, 7.16030E+06, 7.15560E+06,
00216 4.25840E+06, 4.25830E+06, 1.31150E+08, 5.62960E+06,
00217 4.29430E+06, 2.95570E+06, 9.66980E+06, 8.12340E+06,
00218 4.19010E+06, 4.18650E+06, 2.48120E+06, 2.48120E+06,
00219 1.64590E+06, 1.64590E+06, 7.65750E+07, 3.65330E+06,
00220 2.84420E+06, 1.99470E+06, 6.16640E+06, 5.14950E+06,
00221 2.66460E+06, 2.66200E+06, 1.57560E+06, 1.57560E+06,
00222 1.04170E+06, 1.04170E+06, 7.41210E+05, 7.41210E+05,
00223 4.84990E+07, 2.49130E+06, 1.96890E+06, 1.39900E+06,
00224 4.16900E+06, 3.46850E+06, 1.79980E+06, 1.79790E+06,
00225 1.06410E+06, 1.06410E+06, 7.02480E+05, 7.02480E+05,
00226 4.98460E+05, 4.98460E+05, -1.0000E+00, -1.0000E+00,
00227 3.26190E+07, 1.76920E+06, 1.41440E+06, 1.01460E+06,
00228 2.94830E+06, 2.44680E+06, 1.27280E+06, 1.27140E+06,
00229 7.52800E+05, 7.52790E+05, 4.96740E+05, 4.96740E+05,
00230 3.51970E+05, 3.51970E+05, -1.0000E+00, -1.0000E+00,
00231 -1.0000E+00, -1.0000E+00, 2.29740E+07, 1.29900E+06,
00232 1.04800E+06, 7.57160E+05, 2.16090E+06, 1.79030E+06,
00233 9.33210E+05, 9.32120E+05, 5.52310E+05, 5.52310E+05,
00234 3.64460E+05, 3.64460E+05, 2.58070E+05, 2.58070E+05,
00235 -1.0000E+00, -1.0000E+00, -1.0000E+00, -1.0000E+00,
00236 -1.0000E+00, -1.0000E+00, 1.67840E+07};
00237
00238 if( DrakeTotalAuls[i] > 0. &&
00239 i < iso.numLevels_max[ipHE_LIKE][ipHELIUM] - iso.nCollapsed_max[ipHE_LIKE][ipHELIUM])
00240 {
00241 if( fabs( DrakeTotalAuls[i] - (1./StatesElemNEW[ipHELIUM][ipHELIUM-ipHE_LIKE][i].lifetime) ) /DrakeTotalAuls[i] > 0.001 )
00242 {
00243 fprintf(ioQQQ,
00244 " SanityCheck found helium lifetime outside 0.1 pct of Drake values: index, expected, found: %li %.4e %.4e\n",
00245 i,
00246 DrakeTotalAuls[i],
00247 (1./StatesElemNEW[ipHELIUM][ipHELIUM-ipHE_LIKE][i].lifetime) );
00248 lgOK = false;
00249 }
00250 }
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259 if( dense.lgElmtOn[ipHELIUM] )
00260 {
00261
00262 const int NHE1CS = 20;
00263 double he1cs[NHE1CS] =
00264 {
00265 5.480E-18 , 9.253E-18 , 1.598E-17 , 1.598E-17 , 1.598E-17 , 1.348E-17 ,
00266 8.025E-18 , 1.449E-17 , 2.852E-17 , 1.848E-17 , 1.813E-17 , 2.699E-17 ,
00267 1.077E-17 , 2.038E-17 , 4.159E-17 , 3.670E-17 , 3.575E-17 , 1.900E-17 ,
00268 1.900E-17 , 4.175E-17
00269 };
00270
00271
00272 j = MIN2( NHE1CS+1 , iso.numLevels_max[ipHE_LIKE][ipHELIUM] -iso.nCollapsed_max[ipHE_LIKE][ipHELIUM] );
00273 for( n=1; n<j; ++n )
00274 {
00275
00276 i = iso.ipOpac[ipHE_LIKE][ipHELIUM][n];
00277 ASSERT( i>0 );
00278
00279
00280
00281
00282
00283
00284
00285 if( fabs( he1cs[n-1] - opac.OpacStack[i - 1] ) /he1cs[n-1] > 0.15 )
00286 {
00287 fprintf(ioQQQ,
00288 " SanityCheck found insane HeI photo cs: expected, n=%li found: %.3e %.3e.\n",
00289 n,
00290 he1cs[n-1] ,
00291 opac.OpacStack[i - 1]);
00292 fprintf(ioQQQ,
00293 " n=%li, l=%li, s=%li\n",
00294 StatesElemNEW[ipHELIUM][ipHELIUM-ipHE_LIKE][n].n ,
00295 StatesElemNEW[ipHELIUM][ipHELIUM-ipHE_LIKE][n].l ,
00296 StatesElemNEW[ipHELIUM][ipHELIUM-ipHE_LIKE][n].S);
00297 lgOK = false;
00298 }
00299 }
00300 }
00301
00302 for( long ipISO=ipH_LIKE; ipISO<NISO; ipISO++ )
00303 {
00304 long nelem = ipISO;
00305
00306
00307 if( !iso.lgNoRecombInterp[ipISO] )
00308 {
00309
00310 error = fabs( iso_recomb_check( ipISO, nelem , 0 , 7500. ) );
00311 if( error > 0.01 )
00312 {
00313 fprintf(ioQQQ,
00314 " SanityCheck found insane1 %s %s recom coef: expected, n=%i error: %.2e \n",
00315 iso.chISO[ipISO],
00316 elementnames.chElementSym[nelem],
00317 0,
00318 error );
00319 lgOK = false;
00320 }
00321
00322
00323 error = fabs( iso_recomb_check( ipISO, nelem , 1 , 12500. ) );
00324 if( error > 0.01 )
00325 {
00326 fprintf(ioQQQ,
00327 " SanityCheck found insane2 %s %s recom coef: expected, n=%i error: %.2e \n",
00328 iso.chISO[ipISO],
00329 elementnames.chElementSym[nelem],
00330 1,
00331 error );
00332 lgOK = false;
00333 }
00334 }
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 const int NSORT = 100 ;
00344
00345 fvector = (realnum *)MALLOC((NSORT)*sizeof(realnum) );
00346
00347 ipvector = (long *)MALLOC((NSORT)*sizeof(long int) );
00348
00349 nelem = 1;
00350
00351 for( i=0; i<NSORT; ++i )
00352 {
00353 nelem *= -1;
00354 fvector[i] = (realnum)nelem * ((realnum)NSORT-i);
00355 }
00356
00357
00358 spsort(fvector,
00359 NSORT,
00360 ipvector,
00361
00362
00363 1,
00364 &lgFlag);
00365
00366 if( lgFlag ) lgOK = false;
00367
00368 for( i=1; i<NSORT; ++i )
00369 {
00370
00371
00372 if( fvector[ipvector[i]] <= fvector[ipvector[i-1]] )
00373 {
00374 fprintf(ioQQQ," SanityCheck found insane sort\n");
00375 lgOK = false;
00376 }
00377 }
00378
00379 free( fvector );
00380 free( ipvector);
00381
00382 # if 0
00383 ttemp = (realnum)sqrt(phycon.te);
00384
00385 if( fabs(ttemp - phycon.sqrte )/ttemp > 1e-5 )
00386 {
00387 fprintf(ioQQQ , "SanityCheck finds insane te %e sqrt te %e sqrte %e dif %e\n",
00388 phycon.te ,
00389 sqrt(phycon.te) ,
00390 phycon.sqrte ,
00391 fabs(sqrt(phycon.te) - phycon.sqrte ) );
00392 lgOK = false;
00393 }
00394 # endif
00395
00396
00397
00398
00399
00400
00401
00402
00403 # if 0
00404
00405
00406 # if !defined(NDEBUG)
00407 x = 0.;
00408 for( i=1; i<rfield.nupper-1; ++i )
00409 {
00410 if( fabs( ((rfield.anu[i+1]-rfield.anu[i]) + (rfield.anu[i]-rfield.anu[i-1])) /rfield.widflx[i] /2.-1.) > 0.02 )
00411 {
00412 ans1 = fabs( ((rfield.anu[i+1]-rfield.anu[i]) + (rfield.anu[i]-rfield.anu[i-1])) /rfield.widflx[i] /2.-1.);
00413 fprintf(ioQQQ," SanityCheck found insane widflx anu[i+1]=%e anu[i]=%e widflx=%e delta=%e rel err %e\n",
00414 rfield.anu[i+1] , rfield.anu[i] , rfield.widflx[i] , rfield.anu[i+1] -rfield.anu[i] , ans1 );
00415 lgOK = false;
00416 x = MAX2( ans1 , x);
00417 }
00418
00419
00420 ans1 = rfield.widflx[i] / rfield.anu[i];
00421 if( (rfield.anu[i]+rfield.widflx[i]/2.)*(1.-ans1/10.) > rfield.anu[i+1] - rfield.widflx[i+1]/2.)
00422 {
00423 fprintf(ioQQQ," SanityCheck found insane overlap1 widflx %e %e %e %e %e %e\n",
00424 rfield.anu[i] , rfield.widflx[i], rfield.anu[i] + rfield.widflx[i]/2. , rfield.anu[i+1],
00425 rfield.widflx[i+1], rfield.anu[i+1] -rfield.widflx[i+1]/2. );
00426 lgOK = false;
00427 }
00428 if( !lgOK )
00429 {
00430 fprintf(ioQQQ," big error was %e\n", x);
00431 }
00432 }
00433 # endif
00434 # endif
00435
00436
00437
00438
00439
00440
00441
00442 for( nelem=0; nelem<2; ++nelem )
00443 {
00444
00445 if( dense.lgElmtOn[nelem] )
00446 {
00447
00448
00449 Z4 = (double)(nelem+1);
00450 Z4 *= Z4;
00451 Z4 *= Z4;
00452
00453 ans1 = Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Aul;
00454 ans2 = 6.265e8*Z4;
00455 if( fabs(ans1-ans2)/ans2 > 1e-3 )
00456 {
00457 fprintf(ioQQQ , "SanityCheck finds insane A for H Lya %g %g nelem=%li\n",
00458 ans1 , ans2 , nelem );
00459 lgOK = false;
00460 }
00461 }
00462 }
00463
00464
00465 for( nelem=0; nelem<LIMELM; ++nelem )
00466 {
00467 if( dense.lgElmtOn[nelem] )
00468 {
00469 int ipHi, ipLo;
00470 for( ipHi=4; ipHi< iso.numLevels_max[ipH_LIKE][nelem]-iso.nCollapsed_max[ipH_LIKE][nelem]; ++ipHi )
00471 {
00472 double sum = 0.;
00473 for( ipLo=0; ipLo<ipHi; ++ipLo )
00474 {
00475 sum += iso.BranchRatio[ipH_LIKE][nelem][ipHi][ipLo];
00476 }
00477 if( fabs(sum-1.)>0.01 )
00478 {
00479 fprintf(ioQQQ ,
00480 "SanityCheck H branching ratio sum not unity for nelem=%li upper level=%i sum=%.3e\n",
00481 nelem, ipHi, sum );
00482 lgOK = false;
00483 }
00484 }
00485 }
00486 }
00487
00488
00489 for( nelem=0; nelem<LIMELM; ++nelem )
00490 {
00491 if( dense.lgElmtOn[nelem] )
00492 {
00493 int ipHi, ipLo;
00494 for( ipHi=1; ipHi< iso.numLevels_max[ipH_LIKE][nelem]-iso.nCollapsed_max[ipH_LIKE][nelem]; ++ipHi )
00495 {
00496 double inverse_sum = 0.;
00497 double sum = 0.;
00498 long ipISO = ipH_LIKE;
00499
00500
00501 if( L_(ipHi)==0 )
00502 continue;
00503
00504 for( ipLo=0; ipLo<ipHi; ++ipLo )
00505 {
00506 sum += Transitions[ipH_LIKE][nelem][ipHi][ipLo].Emis->Aul;
00507 }
00508
00509 inverse_sum = 1./sum;
00510
00511 double lifetime = iso_state_lifetime( ipH_LIKE, nelem, N_(ipHi), L_(ipHi) );
00512 double percent_error = (1. - inverse_sum/lifetime)*100;
00513
00514
00515
00516
00517 if( fabs(percent_error) > 0.5 )
00518 {
00519 fprintf(ioQQQ ,
00520 "SanityCheck hydrogenic lifetime not consistent with closed form for nelem=%2li upper level=%2i inverse-sum= %.3e lifetime= %.3e error= %.2f%%\n",
00521 nelem, ipHi, inverse_sum, lifetime, percent_error );
00522 lgOK = false;
00523 }
00524 }
00525 }
00526 }
00527
00528
00529
00530 long ipISO = ipH_LIKE;
00531 nelem = 0;
00532 for( long n=1; n <= iso.n_HighestResolved_max[ipISO][nelem]; ++n )
00533 {
00534 double rel_photon_energy = 1. + FLT_EPSILON*2.;
00535 for( long l=0; l < n; l++ )
00536 {
00537 double cs;
00538 long index = iso.QuantumNumbers2Index[ipISO][nelem][n][l][2];
00539
00540 cs = H_photo_cs( rel_photon_energy, n, l, nelem+1 );
00541
00542 error = fabs(cs - opac.OpacStack[iso.ipOpac[ipISO][nelem][index]-1] )/
00543 ( (cs + opac.OpacStack[iso.ipOpac[ipISO][nelem][index]-1] )/2.);
00544
00545 if( error > 0.05 )
00546 {
00547 fprintf(ioQQQ , "SanityCheck finds insane H photo cs, n,l = %li, %li, expected, found = %e, %e, error = %e\n",
00548 n, l, opac.OpacStack[iso.ipOpac[ipISO][nelem][index]-1], cs, error );
00549 lgOK = false;
00550 }
00551 }
00552 }
00553
00554
00555
00556
00557
00558
00559 ASSERT( fp_equal( qg32( 0., PI, mySin ) , 2. ) );
00560
00561
00562 my_Integrand func;
00563 Integrator<my_Integrand,Gaussian32> mySine;
00564 ASSERT( fp_equal( mySine.sum( 0., PI, func ), 2. ) );
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 x = 1e-3;
00575 do
00576 {
00577
00578 ans1 = ee1(x);
00579 ans2 = expn( 1 , x );
00580 if( fabs(ans1-ans2)/(ans1+ans2) > 1e-6 )
00581 {
00582 fprintf(ioQQQ , "SanityCheck finds insane E1 %g %g %g\n",
00583 x , ans1 , ans2 );
00584 lgOK = false;
00585 }
00586
00587
00588 ans1 = e2(x);
00589 ans2 = expn( 2 , x );
00590 if( fabs(ans1-ans2)/(ans1+ans2) > 1e-6 )
00591 {
00592 fprintf(ioQQQ , "SanityCheck finds insane E2 %g %g %g\n",
00593 x , ans1 , ans2 );
00594 lgOK = false;
00595 }
00596
00597
00598 x *= 2.;
00599
00600 } while( x < 64. );
00601
00602
00603
00604
00605
00606
00607
00608
00609 yVector[0] = 1.;
00610 yVector[1] = 3.;
00611 yVector[2] = 3.;
00612
00613
00614 for(i=0;i<3;++i)
00615 {
00616 for( j=0;j<3;++j )
00617 {
00618 xMatrix[i][j] = 0.;
00619 }
00620 }
00621
00622
00623 xMatrix[0][0] = 1.;
00624 xMatrix[0][1] = 1.;
00625 xMatrix[1][1] = 1.;
00626 xMatrix[2][2] = 1.;
00627
00628
00629
00630
00631
00632
00633 A = (double*)MALLOC( sizeof(double)*NDIM*NDIM );
00634
00635
00636 for( i=0; i < 3; ++i )
00637 {
00638 for( j=0; j < 3; ++j )
00639 {
00640 A[i*NDIM+j] = xMatrix[i][j];
00641 }
00642 }
00643
00644 ner = 0;
00645
00646
00647
00648 getrf_wrapper(3, 3, A, NDIM, ipiv, &ner);
00649 if( ner != 0 )
00650 {
00651 fprintf( ioQQQ, " SanityCheck DGETRF error\n" );
00652 cdEXIT(EXIT_FAILURE);
00653 }
00654
00655
00656
00657
00658
00659
00660
00661 getrs_wrapper('N', 3, 1, A, NDIM, ipiv, yVector, 3, &ner);
00662
00663 if( ner != 0 )
00664 {
00665 fprintf( ioQQQ, " SanityCheck DGETRS error\n" );
00666 cdEXIT(EXIT_FAILURE);
00667 }
00668
00669 free( A );
00670
00671
00672
00673
00674
00675
00676 rcond = 0.;
00677 for(i=0;i<3;++i)
00678 {
00679 x = fabs( yVector[i]-i-1.);
00680 rcond = MAX2( rcond, x );
00681
00682 }
00683
00684 if( rcond>DBL_EPSILON)
00685 {
00686 fprintf(ioQQQ,
00687 "SanityCheck found too large a deviation in matrix solver = %g \n",
00688 rcond);
00689
00690 lgOK = false;
00691 }
00692
00693
00694
00695
00696
00697 for( nelem=0; nelem<LIMELM; ++nelem )
00698 {
00699
00700 realnum xIonF[NISO][LIMELM];
00701 double hbn[NISO][LIMELM], hn[NISO][LIMELM];
00702
00703 if( dense.lgElmtOn[nelem] )
00704 {
00705
00706 hbn[ipH_LIKE][nelem] = iso.DepartCoef[ipH_LIKE][nelem][0];
00707 hn[ipH_LIKE][nelem] = StatesElemNEW[nelem][nelem-ipH_LIKE][0].Pop;
00708 xIonF[ipH_LIKE][nelem] = dense.xIonDense[nelem][nelem+1-ipH_LIKE];
00709
00710 iso.DepartCoef[ipH_LIKE][nelem][0] = 0.;
00711 StatesElemNEW[nelem][nelem-ipH_LIKE][0].Pop = 1.;
00712 dense.xIonDense[nelem][nelem+1-ipH_LIKE] = 1.;
00713
00714 if( nelem > ipHYDROGEN )
00715 {
00716
00717 hbn[ipHE_LIKE][nelem] = iso.DepartCoef[ipHE_LIKE][nelem][0];
00718 hn[ipHE_LIKE][nelem] = StatesElemNEW[nelem][nelem-ipHE_LIKE][0].Pop;
00719 xIonF[ipHE_LIKE][nelem] = dense.xIonDense[nelem][nelem+1-ipHE_LIKE];
00720
00721
00722 iso.DepartCoef[ipHE_LIKE][nelem][0] = 0.;
00723 StatesElemNEW[nelem][nelem-ipHE_LIKE][0].Pop = 1.;
00724 dense.xIonDense[nelem][nelem+1-ipHE_LIKE] = 1.;
00725 }
00726
00727 for( ion=0; ion<=nelem; ++ion )
00728 {
00729
00730 for( nshells=0; nshells<Heavy.nsShells[nelem][ion]; ++nshells )
00731 {
00732 for( j=0; j<3; ++j )
00733 {
00734
00735
00736 if( opac.ipElement[nelem][ion][nshells][j] <=0 )
00737 {
00738
00739 fprintf(ioQQQ,
00740 "SanityCheck found insane ipElement for nelem=%li ion=%li nshells=%li j=%li \n",
00741 nelem , ion , nshells, j );
00742 fprintf(ioQQQ,
00743 "value was %li \n", opac.ipElement[nelem][ion][nshells][j] );
00744
00745 lgOK = false;
00746 }
00747 }
00748 }
00749
00750 if( nelem > 1 )
00751 {
00752 realnum saveion[LIMELM+3];
00753
00754 for( j=1; j <= (nelem + 2); j++ )
00755 {
00756 saveion[j] = dense.xIonDense[nelem][j-1];
00757 dense.xIonDense[nelem][j-1] = 0.;
00758 }
00759
00760 dense.xIonDense[nelem][ion] = 1.;
00761
00762 OpacityZero();
00763 opac.lgRedoStatic = true;
00764
00765
00766
00767 OpacityAdd1Element(nelem);
00768
00769
00770 for( j=Heavy.ipHeavy[nelem][ion]; j < MIN2(rfield.nflux,continuum.KshellLimit); j++ )
00771 {
00772 if( opac.opacity_abs[j]+opac.OpacStatic[j] < FLT_MIN )
00773 {
00774
00775 fprintf(ioQQQ,
00776 "SanityCheck found non-positive photo cs for nelem=%li ion=%li \n",
00777 nelem , ion );
00778 fprintf(ioQQQ,
00779 "value was %.2e + %.2e nelem %li ion %li at energy %.2e\n",
00780 opac.opacity_abs[j] ,
00781 opac.OpacStatic[j] ,
00782 nelem ,
00783 ion ,
00784 rfield.anu[j]);
00785
00786 lgOK = false;
00787 break;
00788 }
00789 }
00790
00791 for( j=1; j <= (nelem + 2); j++ )
00792 {
00793 dense.xIonDense[nelem][j-1] = saveion[j];
00794 }
00795
00796 }
00797 }
00798 iso.DepartCoef[ipH_LIKE][nelem][ipH1s] = hbn[ipH_LIKE][nelem];
00799 StatesElemNEW[nelem][nelem-ipH_LIKE][ipH1s].Pop = hn[ipH_LIKE][nelem];
00800 dense.xIonDense[nelem][nelem+1-ipH_LIKE] = xIonF[ipH_LIKE][nelem];
00801
00802 if( nelem > ipHYDROGEN )
00803 {
00804 iso.DepartCoef[ipHE_LIKE][nelem][ipHe1s1S] = hbn[ipHE_LIKE][nelem];
00805 StatesElemNEW[nelem][nelem-ipHE_LIKE][ipHe1s1S].Pop = hn[ipHE_LIKE][nelem];
00806 dense.xIonDense[nelem][nelem+1-ipHE_LIKE] = xIonF[ipHE_LIKE][nelem];
00807 }
00808 }
00809 }
00810
00811
00812
00813
00814
00815
00816
00817
00818 if( lgOK )
00819 {
00820
00821 if( trace.lgTrace )
00822 {
00823 fprintf( ioQQQ, " SanityCheck returns OK\n");
00824 }
00825 return;
00826 }
00827
00828 else
00829 {
00830
00831 fprintf(ioQQQ , "SanityCheck finds insanity so exiting\n");
00832 ShowMe();
00833 cdEXIT(EXIT_FAILURE);
00834 }
00835 }