00001
00002
00003
00004
00005
00006
00007
00008 #include "cddefines.h"
00009 #include "atmdat.h"
00010 #include "conv.h"
00011 #include "dense.h"
00012 #include "helike.h"
00013 #include "helike_cs.h"
00014 #include "hydro_vs_rates.h"
00015 #include "iso.h"
00016 #include "opacity.h"
00017 #include "phycon.h"
00018 #include "physconst.h"
00019 #include "rfield.h"
00020 #include "taulines.h"
00021 #include "thirdparty.h"
00022 #include "trace.h"
00023
00024
00025 STATIC double S62_Therm_ave_coll_str( double EProjectile_eV );
00026
00027
00028
00029 STATIC double Therm_ave_coll_str_int_VF01( double EProjectileRyd);
00030 STATIC double collision_strength_VF01( double velOrEner, bool lgParamIsRedVel );
00031 STATIC double L_mix_integrand_VF01( double alpha );
00032 STATIC double StarkCollTransProb_VF01( long int n, long int l, long int lp, double alpha, double deltaPhi);
00033
00034 static long int global_ipISO, global_n, global_l, global_l_prime, global_s, global_z, global_Collider;
00035 static double global_bmax, global_red_vel, global_an, global_collider_charge;
00036 static double global_I_energy_eV, global_deltaE, global_temp, global_osc_str, global_stat_weight;
00037 static double kTRyd;
00038
00039
00040 static double ColliderMass[4] = {ELECTRON_MASS/PROTON_MASS, 1.0, 4.0, 4.0};
00041 static double ColliderCharge[4] = {1.0, 1.0, 1.0, 2.0};
00042
00043 void HeCollidSetup( void )
00044 {
00045
00046 long i, i1, j, nelem, ipHi, ipLo;
00047 bool lgEOL, lgHIT;
00048 FILE *ioDATA;
00049 long ipISO = ipHE_LIKE;
00050
00051 # define chLine_LENGTH 1000
00052 char chLine[chLine_LENGTH];
00053
00054 DEBUG_ENTRY( "HeCollidSetup()" );
00055
00056
00057 if( trace.lgTrace )
00058 fprintf( ioQQQ," HeCollidSetup opening he1_cs.dat:");
00059
00060 ioDATA = open_data( "he1_cs.dat", "r" );
00061
00062
00063 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00064 {
00065 fprintf( ioQQQ, " HeCollidSetup could not read first line of he1_cs.dat.\n");
00066 cdEXIT(EXIT_FAILURE);
00067 }
00068 i = 1;
00069 i1 = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00070
00071
00072
00073
00074 if( i1 !=COLLISMAGIC )
00075 {
00076 fprintf( ioQQQ,
00077 " HeCollidSetup: the version of he1_cs.dat is not the current version.\n" );
00078 fprintf( ioQQQ,
00079 " HeCollidSetup: I expected to find the number %i and got %li instead.\n" ,
00080 COLLISMAGIC, i1 );
00081 fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
00082 cdEXIT(EXIT_FAILURE);
00083 }
00084
00085
00086 lgHIT = false;
00087 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00088 {
00089
00090 if( chLine[0] != '#')
00091 {
00092 lgHIT = true;
00093 iso.nCS[ipISO] = 0;
00094 lgEOL = false;
00095 i = 1;
00096 while( !lgEOL && iso.nCS[ipISO] < HE1CSARRAY)
00097 {
00098 iso.CSTemp[ipISO][iso.nCS[ipISO]] = FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00099 ++iso.nCS[ipISO];
00100 }
00101 break;
00102 }
00103 }
00104 --iso.nCS[ipISO];
00105 if( !lgHIT )
00106 {
00107 fprintf( ioQQQ, " HeCollidSetup could not find line in CS temperatures in he1_cs.dat.\n");
00108 cdEXIT(EXIT_FAILURE);
00109 }
00110
00111
00112 iso.HeCS.reserve( NISO );
00113 iso.HeCS.reserve( ipISO, LIMELM );
00114
00115 for( nelem=ipHELIUM; nelem<LIMELM; ++nelem )
00116 {
00120 if( nelem != ipHELIUM )
00121 continue;
00122
00123
00124 if( nelem == ipHELIUM || dense.lgElmtOn[nelem])
00125 {
00126 iso.HeCS.reserve( ipISO, nelem, iso.numLevels_max[ipHE_LIKE][nelem]-iso.nCollapsed_max[ipHE_LIKE][nelem] );
00127
00128 for( ipHi=ipHe2s3S; ipHi < iso.numLevels_max[ipHE_LIKE][nelem] - iso.nCollapsed_max[ipHE_LIKE][nelem];++ipHi )
00129 {
00130 iso.HeCS.reserve( ipISO, nelem, ipHi, ipHi );
00131
00132 for( ipLo=ipHe1s1S; ipLo<ipHi; ++ipLo )
00133 iso.HeCS.reserve( ipISO, nelem, ipHi, ipLo, iso.nCS[ipISO] );
00134 }
00135 }
00136 }
00137
00138 iso.HeCS.alloc();
00139 iso.HeCS.zero();
00140
00141
00142 lgHIT = false;
00143 nelem = ipHELIUM;
00144 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00145 {
00146 char *chTemp;
00147
00148 if( (chLine[0] == ' ') || (chLine[0]=='\n') )
00149 break;
00150 if( chLine[0] != '#')
00151 {
00152 lgHIT = true;
00153
00154
00155 j = 1;
00156 ipLo = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00157 ipHi = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00158 ASSERT( ipLo < ipHi );
00159 if( ipHi >= iso.numLevels_max[ipHE_LIKE][nelem] - iso.nCollapsed_max[ipHE_LIKE][nelem] )
00160 continue;
00161 else
00162 {
00163 chTemp = chLine;
00164
00165 for( i=0; i<3; ++i )
00166 {
00167 if( (chTemp = strchr( chTemp, '\t' )) == NULL )
00168 {
00169 fprintf( ioQQQ, " HeCollidSetup no init cs\n" );
00170 cdEXIT(EXIT_FAILURE);
00171 }
00172 ++chTemp;
00173 }
00174
00175 for( i=0; i<iso.nCS[ipISO]; ++i )
00176 {
00177 double a;
00178 if( (chTemp = strchr( chTemp, '\t' )) == NULL )
00179 {
00180 fprintf( ioQQQ, " HeCollidSetup not scan cs, current indices: %li %li\n", ipHi, ipLo );
00181 cdEXIT(EXIT_FAILURE);
00182 }
00183 ++chTemp;
00184 sscanf( chTemp , "%le" , &a );
00185 iso.HeCS[ipISO][nelem][ipHi][ipLo][i] = (realnum)a;
00186 }
00187 }
00188 }
00189 }
00190
00191
00192 fclose( ioDATA );
00193
00194 return;
00195 }
00196
00197
00198 realnum HeCSInterp(long int nelem,
00199 long int ipHi,
00200 long int ipLo,
00201 long int Collider )
00202 {
00203 realnum cs, factor1;
00204
00205
00206
00207 const char *where = " ";
00208
00209 DEBUG_ENTRY( "HeCSInterp()" );
00210
00211 if( !iso.lgColl_excite[ipHE_LIKE] )
00212 {
00213 return (realnum)1E-10;
00214 }
00215
00216 if( nelem == ipHELIUM )
00217 {
00218
00219 cs = AtomCSInterp( nelem, ipHi , ipLo, &factor1, &where, Collider );
00220 }
00221 else
00222 {
00223
00224 cs = IonCSInterp( nelem, ipHi , ipLo, &factor1, &where, Collider );
00225 }
00226
00227
00228 iso_put_error(ipHE_LIKE, nelem, ipHi, ipLo, IPCOLLIS, 0.15f );
00229
00230 ASSERT( cs >= 0.f );
00231
00232
00233
00234
00235 ASSERT( factor1 >= 0.f || nelem!=ipHELIUM );
00236 if( factor1 < 0.f )
00237 {
00238 ASSERT( iso.lgCS_Vriens[ipHE_LIKE] );
00239
00240 factor1 = 1.f;
00241 }
00242
00243
00244
00245 cs *= factor1;
00246
00247 {
00248
00249 enum {DEBUG_LOC=false};
00250
00251
00252 if( DEBUG_LOC && ( nelem==ipOXYGEN ) && (cs > 0.f) && (StatesElem[ipHE_LIKE][nelem][ipHi].n == 2)
00253 && ( StatesElem[ipHE_LIKE][nelem][ipLo].n <= 2 ) )
00254 fprintf(ioQQQ,"%li\t%li\t%li\t-\t%li\t%li\t%li\t%.2e\t%s\n",
00255 StatesElem[ipHE_LIKE][nelem][ipLo].n , StatesElem[ipHE_LIKE][nelem][ipLo].S ,
00256 StatesElem[ipHE_LIKE][nelem][ipLo].l , StatesElem[ipHE_LIKE][nelem][ipHi].n ,
00257 StatesElem[ipHE_LIKE][nelem][ipHi].S , StatesElem[ipHE_LIKE][nelem][ipHi].l , cs,where);
00258 }
00259
00260 return MAX2(cs, 1.e-10f);
00261 }
00262
00263 realnum AtomCSInterp(long int nelem,
00264 long int ipHi,
00265 long int ipLo,
00266 realnum *factor1,
00267 const char **where,
00268 long int Collider )
00269 {
00270 long ipArray;
00271 realnum cs;
00272
00273 DEBUG_ENTRY( "AtomCSInterp()" );
00274
00275 ASSERT( nelem == ipHELIUM );
00276
00277
00278 cs = -1.f;
00279
00280
00281
00282
00283 *factor1 = -1.f;
00284
00285
00286
00287
00288
00289
00290 if( ipLo >= ipHe2p3P0 && ipHi <= ipHe2p3P2 && Collider==ipELECTRON )
00291 {
00292 *factor1 = 1.f;
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 if( ipLo == ipHe2p3P0 && ipHi == ipHe2p3P1 )
00306 {
00307 cs = 1.2f;
00308 }
00309 else if( ipLo == ipHe2p3P0 && ipHi == ipHe2p3P2 )
00310 {
00311 cs = 2.1f;
00312 }
00313 else if( ipLo == ipHe2p3P1 && ipHi == ipHe2p3P2 )
00314 {
00315 cs = 6.0f;
00316 }
00317 else
00318 {
00319 cs = 1.0f;
00320 TotalInsanity();
00321 }
00322
00323 *where = "Berr ";
00324
00325 }
00326
00327
00328
00329 else if( StatesElem[ipHE_LIKE][nelem][ipHi].n <= 5 &&
00330 ( ipHi < iso.numLevels_max[ipHE_LIKE][nelem] - iso.nCollapsed_max[ipHE_LIKE][nelem] ) &&
00331 iso.HeCS[ipHE_LIKE][nelem][ipHi][ipLo][0] >= 0.f && Collider== ipELECTRON )
00332 {
00333 ASSERT( *factor1 == -1.f );
00334 ASSERT( ipLo < ipHi );
00335 ASSERT( ipHe2p3P0 == 3 );
00336
00337
00338 if( ipLo >= ipHe2p3P0 && ipLo <= ipHe2p3P2 )
00339 {
00340
00341
00342
00343 *factor1 = (2.f*((realnum)ipLo-3.f)+1.f) / 9.f;
00344
00345
00346 ASSERT( ipHi > ipHe2p3P2 );
00347 }
00348
00349 else if( ipHi >= ipHe2p3P0 && ipHi <= ipHe2p3P2 )
00350 {
00351 ASSERT( ipLo < ipHe2p3P0 );
00352
00353 *factor1 = (2.f*((realnum)ipHi-3.f)+1.f) / 9.f;
00354 }
00355
00356 else
00357 {
00358 *factor1 = 1.f;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368 if( phycon.alogte <= iso.CSTemp[ipHE_LIKE][0] )
00369 {
00370 cs = iso.HeCS[ipHE_LIKE][nelem][ipHi][ipLo][0];
00371 }
00372 else if( phycon.alogte >= iso.CSTemp[ipHE_LIKE][iso.nCS[ipHE_LIKE]-1] )
00373 {
00374 cs = iso.HeCS[ipHE_LIKE][nelem][ipHi][ipLo][iso.nCS[ipHE_LIKE]-1];
00375 }
00376 else
00377 {
00378 realnum flow;
00379
00380
00381 ipArray = (long)((phycon.alogte - iso.CSTemp[ipHE_LIKE][0])/(iso.CSTemp[ipHE_LIKE][1]-iso.CSTemp[ipHE_LIKE][0]));
00382 ASSERT( ipArray < iso.nCS[ipHE_LIKE] );
00383 ASSERT( ipArray >= 0 );
00384
00385 flow = (realnum)( (phycon.alogte - iso.CSTemp[ipHE_LIKE][ipArray])/
00386 (iso.CSTemp[ipHE_LIKE][ipArray+1]-iso.CSTemp[ipHE_LIKE][ipArray]));
00387 ASSERT( (flow >= 0.f) && (flow <= 1.f) );
00388
00389 cs = iso.HeCS[ipHE_LIKE][nelem][ipHi][ipLo][ipArray] * (1.f-flow) +
00390 iso.HeCS[ipHE_LIKE][nelem][ipHi][ipLo][ipArray+1] * flow;
00391 }
00392
00393 *where = "Bray ";
00394
00395
00396 if( StatesElem[ipHE_LIKE][nelem][ipHi].n == StatesElem[ipHE_LIKE][nelem][ipLo].n )
00397
00398 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00399 else
00400 {
00401
00402 cs *= (realnum)iso.lgColl_excite[ipHE_LIKE];
00403 }
00404
00405 ASSERT( cs >= 0.f );
00406
00407 }
00408
00409 else if( (StatesElem[ipHE_LIKE][nelem][ipHi].n == StatesElem[ipHE_LIKE][nelem][ipLo].n ) &&
00410 (StatesElem[ipHE_LIKE][nelem][ipHi].S == StatesElem[ipHE_LIKE][nelem][ipLo].S ) )
00411 {
00412 ASSERT( *factor1 == -1.f );
00413 *factor1 = 1.f;
00414
00415
00416 ASSERT( StatesElem[ipHE_LIKE][nelem][ipHi].n <= iso.n_HighestResolved_max[ipHE_LIKE][nelem] );
00417
00418 if( (StatesElem[ipHE_LIKE][nelem][ipLo].l <=2) &&
00419 abs(StatesElem[ipHE_LIKE][nelem][ipHi].l - StatesElem[ipHE_LIKE][nelem][ipLo].l)== 1 )
00420 {
00421
00422
00423
00424 cs = (realnum)CS_l_mixing_S62(ipHE_LIKE, nelem, ipLo, ipHi, (double)phycon.te, Collider);
00425 }
00426 else if( iso.lgCS_Vrinceanu[ipHE_LIKE] )
00427 {
00428 if( StatesElem[ipHE_LIKE][nelem][ipLo].l >=3 &&
00429 StatesElem[ipHE_LIKE][nelem][ipHi].l >=3 )
00430 {
00431
00432
00433
00434 cs = (realnum)CS_l_mixing_VF01( ipHE_LIKE,
00435 nelem,
00436 StatesElem[ipHE_LIKE][nelem][ipLo].n,
00437 StatesElem[ipHE_LIKE][nelem][ipLo].l,
00438 StatesElem[ipHE_LIKE][nelem][ipHi].l,
00439 StatesElem[ipHE_LIKE][nelem][ipLo].S,
00440 (double)phycon.te,
00441 Collider );
00442 }
00443 else
00444 {
00445 cs = 0.f;
00446 }
00447 }
00448
00449 else if( abs(StatesElem[ipHE_LIKE][nelem][ipHi].l - StatesElem[ipHE_LIKE][nelem][ipLo].l)== 1)
00450 {
00451
00452
00453 cs = (realnum)CS_l_mixing_PS64( ipHE_LIKE, nelem, ipLo, ipHi, Collider);
00454 }
00455 else
00456 {
00457
00458 cs = 0.f;
00459 }
00460
00461
00462 if( ipLo >= ipHe2p3P0 && ipLo <= ipHe2p3P2 )
00463 {
00464 *factor1 = (2.f*((realnum)ipLo-3.f)+1.f) / 9.f;
00465 }
00466
00467
00468 if( ipHi >= ipHe2p3P0 && ipHi <= ipHe2p3P2 )
00469 {
00470 *factor1 = (2.f*((realnum)ipHi-3.f)+1.f) / 9.f;
00471 }
00472
00473 *where = "lmix ";
00474 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00475 }
00476
00477
00478 else if( StatesElem[ipHE_LIKE][nelem][ipHi].n != StatesElem[ipHE_LIKE][nelem][ipLo].n )
00479 {
00480 ASSERT( *factor1 == -1.f );
00481
00482
00483
00484
00485 if( iso.lgCS_Vriens[ipHE_LIKE] )
00486 {
00487
00488
00489 cs = (realnum)CS_VS80(
00490 ipHE_LIKE,
00491 nelem,
00492 ipHi,
00493 ipLo,
00494 Transitions[ipHE_LIKE][nelem][ipHi][ipLo].Emis->Aul,
00495 phycon.te,
00496 Collider );
00497
00498 *factor1 = 1.f;
00499 *where = "Vriens";
00500 }
00501 else if( iso.lgCS_None[ipHE_LIKE] )
00502 {
00503 cs = 0.f;
00504 *factor1 = 1.f;
00505 *where = "no gb";
00506 }
00507 else if( iso.nCS_new[ipHE_LIKE] )
00508 {
00509 *factor1 = 1.f;
00510
00511
00512
00513
00514
00515 if( Transitions[ipHE_LIKE][nelem][ipHi][ipLo].Emis->Aul > 1. )
00516 {
00517
00518 double x =
00519 log10(MAX2(34.7,Transitions[ipHE_LIKE][nelem][ipHi][ipLo].EnergyWN));
00520
00521 if( iso.nCS_new[ipHE_LIKE] == 1 )
00522 {
00523
00524
00525 if( x < 4.5 )
00526 {
00527
00528 cs = (realnum)pow( 10. , -1.45*x + 6.75);
00529 }
00530 else
00531 {
00532
00533 cs = (realnum)pow( 10. , -3.33*x+15.15);
00534 }
00535 }
00536 else if( iso.nCS_new[ipHE_LIKE] == 2 )
00537 {
00538
00539 cs = (realnum)pow( 10. , -2.3*x+10.3);
00540 }
00541 else
00542 TotalInsanity();
00543 }
00544 else
00545 {
00546
00547 if( Transitions[ipHE_LIKE][nelem][ipHi][ipLo].EnergyWN < 25119.f )
00548 {
00549 cs = 0.631f;
00550 }
00551 else
00552 {
00553 cs = (realnum)pow(10.,
00554 -3.*log10(Transitions[ipHE_LIKE][nelem][ipHi][ipLo].EnergyWN)+12.8);
00555 }
00556 }
00557
00558 *where = "newgb";
00559 }
00560 else
00561 TotalInsanity();
00562
00563
00564 if( ipLo >= ipHe2p3P0 && ipLo <= ipHe2p3P2 )
00565 {
00566 *factor1 = (2.f*((realnum)ipLo-3.f)+1.f) / 9.f;
00567 }
00568
00569
00570 if( ipHi >= ipHe2p3P0 && ipHi <= ipHe2p3P2 )
00571 {
00572 *factor1 = (2.f*((realnum)ipHi-3.f)+1.f) / 9.f;
00573 }
00574
00575
00576 cs *= (realnum)iso.lgColl_excite[ipHE_LIKE];
00577
00578 }
00579 else
00580 {
00581
00582
00583
00584 ASSERT( StatesElem[ipHE_LIKE][nelem][ipHi].S != StatesElem[ipHE_LIKE][nelem][ipLo].S );
00585 cs = 0.f;
00586 *factor1 = 1.f;
00587 }
00588
00589 ASSERT( cs >= 0.f );
00590
00591
00592
00593 return(cs);
00594
00595 }
00596
00597
00598 realnum IonCSInterp( long nelem , long ipHi , long ipLo, realnum *factor1, const char **where, long Collider )
00599 {
00600 realnum cs;
00601
00602 DEBUG_ENTRY( "IonCSInterp()" );
00603
00604 ASSERT( nelem > ipHELIUM );
00605 ASSERT( nelem < LIMELM );
00606
00607
00608 cs = -1.f;
00609
00610
00611
00612
00613 *factor1 = -1.f;
00614
00615
00616
00617
00618
00619
00620
00621
00622 if( StatesElem[ipHE_LIKE][nelem][ipHi].n==2
00623 && StatesElem[ipHE_LIKE][nelem][ipLo].n<=2 && Collider==ipELECTRON)
00624 {
00625 *where = "Zhang";
00626 *factor1 = 1.;
00627
00628
00629 if( ipLo == ipHe1s1S )
00630 {
00631 switch( ipHi )
00632 {
00633 case 1:
00634 cs = 0.25f/POW2(nelem+1.f);
00635 break;
00636 case 2:
00637 cs = 0.4f/POW2(nelem+1.f);
00638 break;
00639 case 3:
00640 cs = 0.15f/POW2(nelem+1.f);
00641 break;
00642 case 4:
00643 cs = 0.45f/POW2(nelem+1.f);
00644 break;
00645 case 5:
00646 cs = 0.75f/POW2(nelem+1.f);
00647 break;
00648 case 6:
00649 cs = 1.3f/POW2(nelem+1.f);
00650 break;
00651 default:
00652 TotalInsanity();
00653 break;
00654 }
00655 cs *= (realnum)iso.lgColl_excite[ipHE_LIKE];
00656 }
00657
00658 else if( ipLo == ipHe2s3S )
00659 {
00660 switch( ipHi )
00661 {
00662 case 2:
00663 cs = 2.75f/POW2(nelem+1.f);
00664 break;
00665 case 3:
00666 cs = 60.f/POW2(nelem+1.f);
00667 break;
00668 case 4:
00669 cs = 180.f/POW2(nelem+1.f);
00670 break;
00671 case 5:
00672 cs = 300.f/POW2(nelem+1.f);
00673 break;
00674 case 6:
00675 cs = 5.8f/POW2(nelem+1.f);
00676 break;
00677 default:
00678 TotalInsanity();
00679 break;
00680 }
00681 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00682 }
00683
00684 else if( ipLo == ipHe2s1S )
00685 {
00686 switch( ipHi )
00687 {
00688 case 3:
00689 cs = 0.56f/POW2(nelem+1.f);
00690 break;
00691 case 4:
00692 cs = 1.74f/POW2(nelem+1.f);
00693 break;
00694 case 5:
00695 cs = 2.81f/POW2(nelem+1.f);
00696 break;
00697 case 6:
00698 cs = 190.f/POW2(nelem+1.f);
00699 break;
00700 default:
00701 TotalInsanity();
00702 break;
00703 }
00704 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00705 }
00706
00707 else if( ipLo == ipHe2p3P0 )
00708 {
00709 switch( ipHi )
00710 {
00711 case 4:
00712 cs = 8.1f/POW2(nelem+1.f);
00713 break;
00714 case 5:
00715 cs = 8.2f/POW2(nelem+1.f);
00716 break;
00717 case 6:
00718 cs = 3.9f/POW2(nelem+1.f);
00719 break;
00720 default:
00721 TotalInsanity();
00722 break;
00723 }
00724 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00725 }
00726
00727 else if( ipLo == ipHe2p3P1 )
00728 {
00729 switch( ipHi )
00730 {
00731 case 5:
00732 cs = 30.f/POW2(nelem+1.f);
00733 break;
00734 case 6:
00735 cs = 11.7f/POW2(nelem+1.f);
00736 break;
00737 default:
00738 TotalInsanity();
00739 break;
00740 }
00741 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00742 }
00743
00744 else if( ipLo == ipHe2p3P2 )
00745 {
00746
00747 cs = 19.5f/POW2(nelem+1.f) * (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00748 }
00749 else
00750 TotalInsanity();
00751
00752
00753 }
00754
00755
00756 else if( (StatesElem[ipHE_LIKE][nelem][ipHi].n == StatesElem[ipHE_LIKE][nelem][ipLo].n ) &&
00757 (StatesElem[ipHE_LIKE][nelem][ipHi].S == StatesElem[ipHE_LIKE][nelem][ipLo].S ) )
00758 {
00759 ASSERT( *factor1 == -1.f );
00760 *factor1 = 1.f;
00761
00762 ASSERT( StatesElem[ipHE_LIKE][nelem][ipHi].n <= iso.n_HighestResolved_max[ipHE_LIKE][nelem] );
00763
00764 if( (StatesElem[ipHE_LIKE][nelem][ipLo].l <=2) &&
00765 abs(StatesElem[ipHE_LIKE][nelem][ipHi].l - StatesElem[ipHE_LIKE][nelem][ipLo].l)== 1 )
00766 {
00767
00768
00769
00770 cs = (realnum)CS_l_mixing_S62(ipHE_LIKE, nelem, ipLo, ipHi, (double)phycon.te, Collider);
00771 }
00772 else if( iso.lgCS_Vrinceanu[ipHE_LIKE] )
00773 {
00774 if( StatesElem[ipHE_LIKE][nelem][ipLo].l >=3 &&
00775 StatesElem[ipHE_LIKE][nelem][ipHi].l >=3 )
00776 {
00777
00778
00779
00780 cs = (realnum)CS_l_mixing_VF01( ipHE_LIKE,
00781 nelem,
00782 StatesElem[ipHE_LIKE][nelem][ipLo].n,
00783 StatesElem[ipHE_LIKE][nelem][ipLo].l,
00784 StatesElem[ipHE_LIKE][nelem][ipHi].l,
00785 StatesElem[ipHE_LIKE][nelem][ipLo].S,
00786 (double)phycon.te,
00787 Collider );
00788 }
00789 else
00790 {
00791 cs = 0.f;
00792 }
00793 }
00794
00795 else if( abs(StatesElem[ipHE_LIKE][nelem][ipHi].l - StatesElem[ipHE_LIKE][nelem][ipLo].l)== 1)
00796 {
00797
00798
00799 cs = (realnum)CS_l_mixing_PS64( ipHE_LIKE, nelem, ipLo, ipHi, Collider);
00800 }
00801 else
00802 {
00803
00804 cs = 0.f;
00805 }
00806
00807
00808 if( ipHi >= ipHe2p3P0 && ipHi <= ipHe2p3P2 )
00809 {
00810 *factor1 = (2.f*((realnum)ipHi-3.f)+1.f) / 9.f;
00811 }
00812
00813 *where = "lmix ";
00814 cs *= (realnum)iso.lgColl_l_mixing[ipHE_LIKE];
00815 }
00816
00817
00818 else if( StatesElem[ipHE_LIKE][nelem][ipHi].n != StatesElem[ipHE_LIKE][nelem][ipLo].n )
00819 {
00820 if( iso.lgCS_Vriens[ipHE_LIKE] )
00821 {
00822
00823
00824
00825 cs = (realnum)CS_VS80(
00826 ipHE_LIKE,
00827 nelem,
00828 ipHi,
00829 ipLo,
00830 Transitions[ipHE_LIKE][nelem][ipHi][ipLo].Emis->Aul,
00831 phycon.te,
00832 Collider );
00833
00834 *factor1 = 1.f;
00835 *where = "Vriens";
00836 }
00837 else
00838 {
00839
00840
00841 fixit();
00842
00843 cs = 0.f;
00844 *where = "hydro";
00845 }
00846 }
00847 else
00848 {
00849
00850
00851
00852 ASSERT( StatesElem[ipHE_LIKE][nelem][ipHi].n == StatesElem[ipHE_LIKE][nelem][ipLo].n );
00853 ASSERT( StatesElem[ipHE_LIKE][nelem][ipHi].S != StatesElem[ipHE_LIKE][nelem][ipLo].S );
00854 cs = 0.f;
00855 *where = "spin ";
00856 }
00857
00858 ASSERT( cs >= 0.f );
00859
00860
00861
00862 return(cs);
00863 }
00864
00865
00866
00867
00868 double CS_l_mixing_S62(
00869 long ipISO,
00870 long nelem ,
00871 long ipLo ,
00872 long ipHi ,
00873 double temp,
00874 long Collider)
00875 {
00876
00877 double coll_str, deltaE;
00878
00879 DEBUG_ENTRY( "CS_l_mixing_S62()" );
00880
00881 if( Transitions[ipISO][nelem][ipHi][ipLo].ipCont <= 0 )
00882 {
00883 return 0.;
00884 }
00885
00886 global_temp = temp;
00887 global_stat_weight = StatesElem[ipISO][nelem][ipLo].g;
00888
00889
00890
00891 global_deltaE = Transitions[ipISO][nelem][ipHi][ipLo].EnergyErg/EN1EV;
00892 deltaE = global_deltaE;
00893 global_I_energy_eV = EVRYD*iso.xIsoLevNIonRyd[ipISO][nelem][0];
00894 global_Collider = Collider;
00895
00896 ASSERT( TRANS_PROB_CONST*POW2(deltaE/WAVNRYD/EVRYD) > 0. );
00897
00898 global_osc_str = Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul/
00899 (TRANS_PROB_CONST*POW2(deltaE/WAVNRYD/EVRYD));
00900
00901
00902 coll_str = qg32( 0.0, 1.0, S62_Therm_ave_coll_str);
00903 coll_str += qg32( 1.0, 10.0, S62_Therm_ave_coll_str);
00904 ASSERT( coll_str > 0. );
00905
00906
00907
00908 return coll_str;
00909 }
00910
00911
00912 STATIC double S62_Therm_ave_coll_str( double proj_energy_overKT )
00913 {
00914
00915 double integrand, cross_section, osc_strength, coll_str, zOverB2;
00916 double deltaE, betaone, zeta_of_betaone, cs2, temp, stat_weight;
00917 double I_energy_eV, Dubya, proj_energy;
00918 long i, Collider;
00919
00920 DEBUG_ENTRY( "S62_Therm_ave_coll_str()" );
00921
00922
00923 proj_energy = proj_energy_overKT * phycon.te / EVDEGK;
00924
00925 deltaE = global_deltaE;
00926 osc_strength = global_osc_str;
00927 temp = (double)global_temp;
00928 stat_weight = global_stat_weight;
00929 I_energy_eV = global_I_energy_eV;
00930 Collider = global_Collider;
00931
00932
00933
00934 proj_energy *= ColliderMass[ipELECTRON]/ColliderMass[Collider];
00935
00936
00937 proj_energy += deltaE;
00938 Dubya = 0.5*(2.*proj_energy-deltaE);
00939 ASSERT( Dubya > 0. );
00940
00941
00942
00943 ASSERT( I_energy_eV > 0. );
00944 ASSERT( osc_strength > 0. );
00945
00946
00947 zOverB2 = 0.5*POW2(Dubya/deltaE)*deltaE/I_energy_eV/osc_strength;
00948
00949 ASSERT( zOverB2 > 0. );
00950
00951 if( zOverB2 > 100. )
00952 {
00953 betaone = sqrt( 1./zOverB2 );
00954 }
00955 else if( zOverB2 < 0.54 )
00956 {
00957
00958 betaone = (1./3.)*(log(PI)-log(zOverB2)+1.28);
00959 if( betaone > 2.38 )
00960 {
00961
00962 betaone += 0.5*(log(PI)-log(zOverB2));
00963 betaone *= 0.5;
00964 }
00965 }
00966 else
00967 {
00968 long ip_zOverB2 = 0;
00969 double zetaOVERbeta2[101] = {
00970 1.030E+02,9.840E+01,9.402E+01,8.983E+01,8.583E+01,8.200E+01,7.835E+01,7.485E+01,
00971 7.151E+01,6.832E+01,6.527E+01,6.236E+01,5.957E+01,5.691E+01,5.436E+01,5.193E+01,
00972 4.961E+01,4.738E+01,4.526E+01,4.323E+01,4.129E+01,3.943E+01,3.766E+01,3.596E+01,
00973 3.434E+01,3.279E+01,3.131E+01,2.989E+01,2.854E+01,2.724E+01,2.601E+01,2.482E+01,
00974 2.369E+01,2.261E+01,2.158E+01,2.059E+01,1.964E+01,1.874E+01,1.787E+01,1.705E+01,
00975 1.626E+01,1.550E+01,1.478E+01,1.409E+01,1.343E+01,1.280E+01,1.219E+01,1.162E+01,
00976 1.107E+01,1.054E+01,1.004E+01,9.554E+00,9.094E+00,8.655E+00,8.234E+00,7.833E+00,
00977 7.449E+00,7.082E+00,6.732E+00,6.397E+00,6.078E+00,5.772E+00,5.481E+00,5.202E+00,
00978 4.937E+00,4.683E+00,4.441E+00,4.210E+00,3.989E+00,3.779E+00,3.578E+00,3.387E+00,
00979 3.204E+00,3.031E+00,2.865E+00,2.707E+00,2.557E+00,2.414E+00,2.277E+00,2.148E+00,
00980 2.024E+00,1.907E+00,1.795E+00,1.689E+00,1.589E+00,1.493E+00,1.402E+00,1.316E+00,
00981 1.235E+00,1.157E+00,1.084E+00,1.015E+00,9.491E-01,8.870E-01,8.283E-01,7.729E-01,
00982 7.206E-01,6.712E-01,6.247E-01,5.808E-01,5.396E-01};
00983
00984 ASSERT( zOverB2 >= zetaOVERbeta2[100] );
00985
00986
00987 for( i=0; i< 100; ++i )
00988 {
00989 if( ( zOverB2 < zetaOVERbeta2[i] ) && ( zOverB2 >= zetaOVERbeta2[i+1] ) )
00990 {
00991
00992 ip_zOverB2 = i;
00993 break;
00994 }
00995 }
00996
00997 ASSERT( (ip_zOverB2 >=0) && (ip_zOverB2 < 100) );
00998
00999 betaone = (zOverB2 - zetaOVERbeta2[ip_zOverB2]) /
01000 (zetaOVERbeta2[ip_zOverB2+1] - zetaOVERbeta2[ip_zOverB2]) *
01001 (pow(10., ((double)ip_zOverB2+1.)/100. - 1.) - pow(10., ((double)ip_zOverB2)/100. - 1.)) +
01002 pow(10., (double)ip_zOverB2/100. - 1.);
01003
01004 }
01005
01006 zeta_of_betaone = zOverB2 * POW2(betaone);
01007
01008
01009 cs2 = 0.5*zeta_of_betaone + betaone * bessel_k0(betaone) * bessel_k1(betaone);
01010
01011
01012 cross_section = cs2;
01013
01014
01015 cross_section *= 8. * (I_energy_eV/deltaE) * osc_strength * (I_energy_eV/proj_energy);
01016
01017
01018 coll_str = cross_section * stat_weight * ( proj_energy/EVRYD );
01019
01020 integrand = exp( -1.*(proj_energy-deltaE)*EVDEGK/temp ) * coll_str;
01021 return integrand;
01022 }
01023
01024
01025 double CS_l_mixing_PS64(
01026 long ipISO,
01027 long nelem ,
01028 long ipLo ,
01029 long ipHi ,
01030 long Collider)
01031 {
01032
01033
01034 double cs, Dnl,
01035 TwoLogDebye, TwoLogRc1,
01036 factor1, factor2,
01037 bestfactor, factorpart,
01038 reduced_mass, reduced_mass_2_emass,
01039 rate, tau;
01040 const double ChargIncoming = ColliderCharge[Collider];
01041
01042 DEBUG_ENTRY( "CS_l_mixing_PS64()" );
01043
01044 ASSERT( ipHi > ipLo );
01045
01046
01047
01048
01049 reduced_mass = dense.AtomicWeight[nelem]*ColliderMass[Collider]/
01050 (dense.AtomicWeight[nelem]+ColliderMass[Collider])*ATOMIC_MASS_UNIT;
01051
01052 reduced_mass_2_emass = reduced_mass / ELECTRON_MASS;
01053
01054
01055 tau = StatesElem[ipISO][nelem][ipLo].lifetime;
01056
01057 if( ipISO == ipH_LIKE && Transitions[ipISO][nelem][ipLo][ipH1s].ipCont > 0 )
01058 {
01059 tau = (1./tau) + Transitions[ipISO][nelem][ipLo][ipH1s].Emis->Aul;
01060 tau = 1./tau;
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070 TwoLogDebye = 1.181 + log10( phycon.te / MIN2(1e10 , dense.eden ) );
01071
01072
01073 TwoLogRc1 = 10.95 + log10( phycon.te * tau * tau / reduced_mass_2_emass );
01074
01075
01076 Dnl = POW2( ChargIncoming / (double)(nelem + 1. - ipISO)) * 6. * POW2( (double)StatesElem[ipISO][nelem][ipLo].n ) *
01077 ( POW2((double)StatesElem[ipISO][nelem][ipLo].n) -
01078 POW2((double)StatesElem[ipISO][nelem][ipLo].l) - StatesElem[ipISO][nelem][ipLo].l - 1);
01079
01080 ASSERT( Dnl > 0. );
01081 ASSERT( phycon.te / Dnl / reduced_mass_2_emass > 0. );
01082
01083 factorpart = (11.54 + log10( phycon.te / Dnl / reduced_mass_2_emass ) );
01084
01085 if( (factor1 = factorpart + TwoLogDebye) <= 0.)
01086 factor1 = BIGDOUBLE;
01087 if( (factor2 = factorpart + TwoLogRc1) <= 0.)
01088 factor2 = BIGDOUBLE;
01089
01090
01091 bestfactor = MIN2(factor1,factor2);
01092
01093 ASSERT( bestfactor > 0. );
01094
01095
01096 if( bestfactor > 100. )
01097 {
01098 return SMALLFLOAT;
01099 }
01100
01101
01102 rate = 9.93e-6 * sqrt( reduced_mass_2_emass ) * Dnl / phycon.sqrte * bestfactor;
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 if( StatesElem[ipISO][nelem][ipLo].l > 0 )
01113 rate /=2;
01114
01115
01116
01117
01118 cs = rate / ( COLL_CONST * pow(reduced_mass_2_emass, -1.5) ) *
01119 phycon.sqrte * StatesElem[ipISO][nelem][ipHi].g;
01120
01121 ASSERT( cs > 0. );
01122
01123
01124
01125 return cs;
01126 }
01127
01128
01129
01130
01131
01132
01133 double CS_l_mixing_VF01(long int ipISO,
01134 long int nelem,
01135 long int n,
01136 long int l,
01137 long int lp,
01138 long int s,
01139 double temp,
01140 long int Collider )
01141 {
01142
01143 double coll_str;
01144
01145 DEBUG_ENTRY( "CS_l_mixing_VF01()" );
01146
01147 global_ipISO = ipISO;
01148 global_z = nelem;
01149 global_n = n;
01150 global_l = l;
01151 global_l_prime = lp;
01152 global_s = s;
01153 global_temp = temp;
01154 global_Collider = Collider;
01155 global_collider_charge = ColliderCharge[Collider];
01156 ASSERT( global_collider_charge > 0. );
01157
01158
01159 if( ipISO > ipH_LIKE )
01160 {
01161 ASSERT( l != 0 );
01162 ASSERT( lp != 0 );
01163 }
01164
01165 kTRyd = temp / TE1RYD;
01166 if( !iso.lgCS_therm_ave[ipISO] )
01167 {
01168
01169
01170
01171
01172 if( (dense.eden > 10000.) && (dense.eden < 1E10 ) )
01173 {
01174 coll_str = qg32( 0.0, 6.0, Therm_ave_coll_str_int_VF01);
01175 }
01176 else
01177 {
01178
01179 coll_str = collision_strength_VF01( kTRyd, false );
01180 }
01181 }
01182 else
01183 {
01184
01185 coll_str = qg32( 0.0, 1.0, Therm_ave_coll_str_int_VF01);
01186 coll_str += qg32( 1.0, 10.0, Therm_ave_coll_str_int_VF01);
01187 }
01188
01189 return coll_str;
01190 }
01191
01192
01193 STATIC double Therm_ave_coll_str_int_VF01( double EOverKT )
01194 {
01195 double integrand;
01196
01197 DEBUG_ENTRY( "Therm_ave_coll_str_int_VF01()" );
01198
01199 integrand = exp( -1.*EOverKT ) * collision_strength_VF01( EOverKT * kTRyd, false );
01200
01201 return integrand;
01202 }
01203
01204 STATIC double collision_strength_VF01( double velOrEner, bool lgParamIsRedVel )
01205 {
01206
01207 double cross_section, coll_str, RMSv, aveRadius, reduced_vel, E_Proj_Ryd;
01208 double ConstantFactors, reduced_mass, CSIntegral, stat_weight;
01209 double ColliderCharge = global_collider_charge;
01210 double quantum_defect1, quantum_defect2, omega_qd1, omega_qd2, omega_qd;
01211 double reduced_b_max, reduced_b_min, alphamax, alphamin, step, alpha1 ;
01212
01213 long ipISO, nelem, n, l, lp, s, ipLo, ipHi, Collider = global_Collider;
01214
01215 DEBUG_ENTRY( "collision_strength_VF01()" );
01216
01217 nelem = global_z;
01218 n = global_n;
01219 ASSERT( n > 0 );
01220 l = global_l;
01221 lp = global_l_prime;
01222 s = global_s;
01223 ipISO = global_ipISO;
01224
01225
01226 ipLo = iso.QuantumNumbers2Index[ipISO][nelem][n][l][s];
01227 ipHi = iso.QuantumNumbers2Index[ipISO][nelem][n][lp][s];
01228
01229 stat_weight = StatesElem[ipISO][nelem][ipLo].g;
01230
01231
01232 if( ipISO > ipH_LIKE )
01233 {
01234
01235 ASSERT( l > 0 );
01236 ASSERT( lp > 0 );
01237 }
01238
01239
01240 reduced_mass = dense.AtomicWeight[nelem]*ColliderMass[Collider]/
01241 (dense.AtomicWeight[nelem]+ColliderMass[Collider])*ATOMIC_MASS_UNIT;
01242 ASSERT( reduced_mass > 0. );
01243
01244
01245
01246 aveRadius = (BOHR_RADIUS_CM/((double)nelem+1.-(double)ipISO))*POW2((double)n);
01247 ASSERT( aveRadius < 1.e-4 );
01248
01249
01250
01251 ASSERT( aveRadius > 3.9/LIMELM * BOHR_RADIUS_CM );
01252 global_an = aveRadius;
01253
01254
01255
01256 RMSv = ((double)nelem+1.-(double)ipISO)*POW2(ELEM_CHARGE_ESU)/(double)n/H_BAR;
01257 ASSERT( RMSv > 0. );
01258
01259 ASSERT( ColliderMass[Collider] > 0. );
01260
01261 if( lgParamIsRedVel )
01262 {
01263
01264 reduced_vel = velOrEner;
01265
01266
01267 E_Proj_Ryd = 0.5 * POW2( reduced_vel * RMSv ) * ColliderMass[Collider] *
01268 PROTON_MASS / EN1RYD;
01269 }
01270 else
01271 {
01272
01273 E_Proj_Ryd = velOrEner;
01274 reduced_vel = sqrt( 2.*E_Proj_Ryd*EN1RYD/ColliderMass[Collider]/PROTON_MASS )/RMSv;
01275 }
01276
01277
01278 ASSERT( reduced_vel > 1.e-10 );
01279 ASSERT( reduced_vel < 1.e10 );
01280
01281 global_red_vel = reduced_vel;
01282
01283
01284 ConstantFactors = 4.5*PI*POW2(ColliderCharge*aveRadius/reduced_vel);
01285
01286
01287 reduced_b_min = 1.5 * ColliderCharge / reduced_vel;
01288 ASSERT( reduced_b_min > 1.e-10 );
01289 ASSERT( reduced_b_min < 1.e10 );
01290
01291 if( ipISO == ipH_LIKE )
01292 {
01293
01294 reduced_b_max = sqrt( BOLTZMANN*global_temp/ColliderCharge/dense.eden )
01295 / (PI2*ELEM_CHARGE_ESU)/aveRadius;
01296 }
01297 else if( ipISO == ipHE_LIKE )
01298 {
01299 quantum_defect1 = (double)n- (double)nelem/sqrt(iso.xIsoLevNIonRyd[ipISO][nelem][ipLo]);
01300 quantum_defect2 = (double)n- (double)nelem/sqrt(iso.xIsoLevNIonRyd[ipISO][nelem][ipHi]);
01301
01302
01303 ASSERT( fabs(quantum_defect1) < 1.0 );
01304 ASSERT( fabs(quantum_defect1) > 0.0 );
01305 ASSERT( fabs(quantum_defect2) < 1.0 );
01306 ASSERT( fabs(quantum_defect2) > 0.0 );
01307
01308
01309 omega_qd1 = fabs( 5.* quantum_defect1 * (1.-0.6*POW2((double)l/(double)n)) / POW3( (double)n ) / (double)l );
01310
01311 omega_qd2 = fabs( 5.* quantum_defect2 * (1.-0.6*POW2((double)lp/(double)n)) / POW3( (double)n ) / (double)lp );
01312
01313 omega_qd = 0.5*( omega_qd1 + omega_qd2 );
01314
01315 ASSERT( omega_qd > 0. );
01316
01317 reduced_b_max = sqrt( 1.5 * ColliderCharge * n / omega_qd )/aveRadius;
01318 }
01319 else
01320
01321 TotalInsanity();
01322
01323 reduced_b_max = MAX2( reduced_b_max, reduced_b_min );
01324 ASSERT( reduced_b_max > 0. );
01325 global_bmax = reduced_b_max*aveRadius;
01326 alphamin = 1.5*ColliderCharge/(reduced_vel * reduced_b_max);
01327 alphamax = 1.5*ColliderCharge/(reduced_vel * reduced_b_min);
01328
01329 ASSERT( alphamin > 0. );
01330 ASSERT( alphamax > 0. );
01331
01332 alphamin = MAX2( alphamin, 1.e-30 );
01333 alphamax = MAX2( alphamax, 1.e-20 );
01334
01335 CSIntegral = 0.;
01336
01337 if( alphamax > alphamin )
01338 {
01339
01340 step = (alphamax - alphamin)/5.;
01341 alpha1 = alphamin;
01342 CSIntegral += qg32( alpha1, alpha1+step, L_mix_integrand_VF01);
01343 CSIntegral += qg32( alpha1+step, alpha1+4.*step, L_mix_integrand_VF01);
01344 }
01345
01346
01347 cross_section = ConstantFactors * CSIntegral;
01348
01349
01350 coll_str = cross_section * stat_weight / PI / BOHR_RADIUS_CM / BOHR_RADIUS_CM;
01351 coll_str *= E_Proj_Ryd;
01352
01353 coll_str = MAX2( SMALLFLOAT, coll_str);
01354
01355 return coll_str;
01356 }
01357
01358 STATIC double L_mix_integrand_VF01( double alpha )
01359 {
01360 double integrand, deltaPhi, b;
01361
01362 DEBUG_ENTRY( "L_mix_integrand_VF01()" );
01363
01364 ASSERT( alpha >= 1.e-30 );
01365 ASSERT( global_bmax > 0. );
01366 ASSERT( global_red_vel > 0. );
01367
01368
01369 b = 1.5*global_collider_charge*global_an/(global_red_vel * alpha);
01370
01371 if( b < global_bmax )
01372 {
01373 deltaPhi = -1.*PI + 2.*asin(b/global_bmax);
01374 }
01375 else
01376 {
01377 deltaPhi = 0.;
01378 }
01379 integrand = 1./alpha/alpha/alpha;
01380 integrand *= StarkCollTransProb_VF01( global_n, global_l, global_l_prime, alpha, deltaPhi );
01381
01382 return integrand;
01383 }
01384
01385 STATIC double StarkCollTransProb_VF01( long n, long l, long lp, double alpha, double deltaPhi)
01386 {
01387 double probability;
01388 double cosU1, cosU2, sinU1, sinU2, cosChiOver2, sinChiOver2, cosChi, A, B;
01389
01390 DEBUG_ENTRY( "StarkCollTransProb_VF01()" );
01391
01392 ASSERT( alpha > 0. );
01393
01394
01395 cosU1 = 2.*POW2((double)l/(double)n) - 1.;
01396 cosU2 = 2.*POW2((double)lp/(double)n) - 1.;
01397
01398 sinU1 = sqrt( 1. - cosU1*cosU1 );
01399 sinU2 = sqrt( 1. - cosU2*cosU2 );
01400
01401
01402 cosChiOver2 = (1. + alpha*alpha*cos( sqrt(1.+alpha*alpha) * deltaPhi ) )/(1.+alpha*alpha);
01403 sinChiOver2 = sqrt( 1. - cosChiOver2*cosChiOver2 );
01404 cosChi = 2. * POW2( cosChiOver2 ) - 1.;
01405
01406 if( l == 0 )
01407 {
01408 if( -1.*cosU2 - cosChi < 0. )
01409 {
01410 probability = 0.;
01411 }
01412 else
01413 {
01414
01415 ASSERT( sinChiOver2 > 0. );
01416 ASSERT( sinChiOver2*sinChiOver2 > POW2((double)lp/(double)n) );
01417
01418
01419 probability = (double)lp/(POW2((double)n)*sinChiOver2*sqrt( POW2(sinChiOver2) - POW2((double)lp/(double)n) ) );
01420 }
01421 }
01422 else
01423 {
01424 double OneMinusCosChi = 1. - cosChi;
01425
01426 if( OneMinusCosChi == 0. )
01427 {
01428 double hold = sin( deltaPhi / 2. );
01429
01430 OneMinusCosChi = 8. * alpha * alpha * POW2( hold );
01431 }
01432
01433 if( OneMinusCosChi == 0. )
01434 {
01435 probability = 0.;
01436 }
01437 else
01438 {
01439
01440 A = (cosU1*cosU2 - sinU1*sinU2 - cosChi)/OneMinusCosChi;
01441 B = (cosU1*cosU2 + sinU1*sinU2 - cosChi)/OneMinusCosChi;
01442
01443 ASSERT( B > A );
01444
01445
01446 if( B <= 0. )
01447 {
01448 probability = 0.;
01449 }
01450 else
01451 {
01452 ASSERT( POW2( sinChiOver2 ) > 0. );
01453
01454 probability = 2.*lp/(PI* n*n*POW2( sinChiOver2 ));
01455
01456 if( A < 0. )
01457 {
01458 probability *= ellpk( -A/(B-A) );
01459 probability /= sqrt( B - A );
01460 }
01461 else
01462 {
01463 probability *= ellpk( A/B );
01464 probability /= sqrt( B );
01465 }
01466 }
01467 }
01468
01469 }
01470
01471 return probability;
01472
01473 }
01474
01475 #if 0
01476 STATIC void updateHeColl(long int nelem)
01477 {
01478 long int ipLo , ipHi, i;
01479
01480
01481
01482
01483 static double TeUsedForCS[LIMELM]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
01484 0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0};
01485
01486 DEBUG_ENTRY("updateHeColl()");
01487
01488
01489
01490
01491
01492
01493
01494 ASSERT(ipELECTRON == 0 && ipPROTON == 1 && ipHE_PLUS == 2);
01495
01496 if( (TeUsedForCS[nelem] == 0.) ||
01497 ( TeUsedForCS[nelem]/phycon.te > 1.15 ) ||
01498 ( TeUsedForCS[nelem]/phycon.te < 0.85 ) )
01499 {
01500 for( ipHi=ipHe2s3S; ipHi <iso.numLevels_max[ipHE_LIKE][nelem]; ipHi++ )
01501 {
01502 for( ipLo=ipHe1s1S; ipLo < ipHi; ipLo++ )
01503 {
01504 for (i=0;i<=ipNCOLLIDER;i++)
01505 {
01506
01507 if (i > ipHE_PLUS)
01508 continue;
01509
01510
01511 Transitions[ipHE_LIKE][nelem][ipHi][ipLo].Coll.csi[i] =
01512 HeCSInterp( nelem , ipHi , ipLo, i );
01513
01514
01515 ASSERT( Transitions[ipHE_LIKE][nelem][ipHi][ipLo].Coll.csi[i] >= 0. );
01516 }
01517 }
01518 }
01519
01520 TeUsedForCS[nelem] = phycon.te;
01521 }
01522 }
01523 #endif
01524