00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "cddefines.h"
00018 #include "physconst.h"
00019 #include "hydro_bauman.h"
00020 #include "iso.h"
00021 #include "helike.h"
00022 #include "helike_recom.h"
00023 #include "thirdparty.h"
00024 #include "dense.h"
00025 #include "opacity.h"
00026 #include "atmdat.h"
00027 #include "taulines.h"
00028
00029
00030 STATIC double ExponentialInt( double v );
00031 STATIC double X1Int( double u );
00032 STATIC double X2Int( double u );
00033
00034 STATIC double cross_section(double EgammaRyd, double EthRyd, long nelem, long n, long l, long s);
00035 STATIC double GetHS98CrossSection( long n, long l, long s, double EgammaRyd );
00036
00037 static double Xn_S59;
00038
00039
00040
00041
00042
00043
00044 double He_cross_section( double EgammaRyd , double EthRyd, long n, long l, long S, long nelem )
00045 {
00046 double cs;
00047
00048
00049
00050
00051
00052
00053
00054
00055 cs = (1.e-18)*cross_section( EgammaRyd, EthRyd, nelem, n, l, S );
00056
00057 return cs;
00058 }
00059
00060
00061
00062 STATIC double cross_section(double EgammaRyd, double EthRyd, long nelem, long n, long l, long S)
00063 {
00064
00065
00066
00067 double E0[29] = {
00068 1.36E+01,2.01E+01,1.76E+01,3.34E+01,4.62E+01,6.94E+01,8.71E+01,1.13E+02,1.59E+02,2.27E+02,
00069 2.04E+02,2.74E+02,2.75E+02,3.38E+02,4.39E+02,4.17E+02,4.47E+02,5.18E+02,6.30E+02,6.27E+02,
00070 8.66E+02,7.67E+02,9.70E+02,9.66E+02,1.06E+03,1.25E+03,1.35E+03,1.43E+03,1.56E+03};
00071 double sigma[29] = {
00072 9.49E+02,3.20E+02,5.46E+02,2.85E+02,2.34E+02,1.52E+02,1.33E+02,1.04E+02,6.70E+01,4.00E+01,
00073 6.14E+01,4.04E+01,4.75E+01,3.65E+01,2.45E+01,3.14E+01,3.11E+01,2.59E+01,1.94E+01,2.18E+01,
00074 1.23E+01,1.76E+01,1.19E+01,1.31E+01,1.20E+01,9.05E+00,8.38E+00,8.06E+00,7.17E+00};
00075 double y_a[29] = {
00076 1.47E+00,7.39E+00,1.72E+01,2.16E+01,2.18E+01,2.63E+01,2.54E+01,2.66E+01,3.35E+01,5.32E+01,
00077 2.78E+01,3.57E+01,2.85E+01,3.25E+01,4.41E+01,3.16E+01,3.04E+01,3.28E+01,3.92E+01,3.45E+01,
00078 5.89E+01,3.88E+01,5.35E+01,4.83E+01,5.77E+01,6.79E+01,7.43E+01,7.91E+01,9.10E+01};
00079 double P[29] = {
00080 3.19E+00,2.92E+00,3.16E+00,2.62E+00,2.58E+00,2.32E+00,2.34E+00,2.26E+00,2.00E+00,1.68E+00,
00081 2.16E+00,1.92E+00,2.14E+00,2.00E+00,1.77E+00,2.04E+00,2.09E+00,2.02E+00,1.86E+00,2.00E+00,
00082 1.62E+00,1.93E+00,1.70E+00,1.79E+00,1.72E+00,1.61E+00,1.59E+00,1.58E+00,1.54E+00};
00083 double y_w[29] =
00084 {2.039,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00085 double yzero[29] =
00086 {0.4434,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00087 double yone[29] =
00088 {2.136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00089
00090 double pcs,Egamma,y,F,x;
00091 double rel_photon_energy;
00092
00093 Egamma = EgammaRyd * EVRYD;
00094
00095
00096
00097
00098 rel_photon_energy = EgammaRyd / EthRyd;
00099 rel_photon_energy = MAX2( rel_photon_energy , 1. + FLT_EPSILON*2. );
00100
00101 long s=0;
00102 if( S == 1 )
00103 s=0;
00104 else if( S == 3 )
00105 s=1;
00106 else
00107 TotalInsanity();
00108
00109 if( nelem==ipHELIUM && n<=25 && l<=4 )
00110 {
00111
00112 pcs = GetHS98CrossSection( n, l, s, EgammaRyd );
00113 }
00114 else if( nelem==ipHELIUM && n>25 && l<=2 )
00115 {
00116 double scale[3][2] = {
00117 {1.4673,1.3671},
00118 {1.5458,1.5011},
00119 {1.4912,1.5144}};
00120
00121 long ipLev = iso.QuantumNumbers2Index[ipHE_LIKE][nelem][25][l][S];
00122 double EthRyd_25 = iso.xIsoLevNIonRyd[ipHE_LIKE][nelem][ipLev];
00123 pcs = GetHS98CrossSection( 25, l, s, EthRyd_25 * rel_photon_energy );
00124 pcs *= pow((double)n/25., scale[l][s]);
00125 }
00126 else if( n==1 )
00127 {
00128
00129
00130
00131 x = Egamma/E0[nelem-1] - yzero[nelem-1];
00132 y = sqrt(x*x + yone[nelem-1]*yone[nelem-1]);
00133 F = ((x-1)*(x-1)+y_w[nelem-1]*y_w[nelem-1])
00134 * pow(y,0.5*P[nelem-1]-5.5) * pow((1+sqrt(y/y_a[nelem-1])),-P[nelem-1]);
00135 pcs = sigma[nelem-1]*F;
00136 }
00137 else if( nelem>=ipLITHIUM && nelem<=ipCALCIUM && n<11 && OP_Helike_NumPts[nelem][n][l][s]>0 )
00138 {
00139
00140 long numDataPoints = OP_Helike_NumPts[nelem][n][l][s];
00141 ASSERT( numDataPoints > 0 );
00142 ASSERT( OP_Helike_Xsectn[nelem][n][l][s] != NULL );
00143
00144 if( EgammaRyd < OP_Helike_Energy[nelem][n][l][s][numDataPoints-1] )
00145 {
00146 pcs = linint( OP_Helike_Energy[nelem][n][l][s], OP_Helike_Xsectn[nelem][n][l][s], numDataPoints, EgammaRyd );
00147 }
00148 else
00149 {
00150
00151 pcs = OP_Helike_Xsectn[nelem][n][l][s][numDataPoints-1] * POW3( OP_Helike_Energy[nelem][n][l][s][numDataPoints-1]/EgammaRyd );
00152 }
00153 }
00154 else
00155 {
00156
00157 pcs = (1.e18)*H_photo_cs(rel_photon_energy , n, l, nelem);
00158 }
00159
00160 ASSERT( pcs > 0. && pcs < 1.E10 );
00161
00162 return pcs;
00163 }
00164
00165 STATIC double GetHS98CrossSection( long n, long l, long s, double EgammaRyd )
00166 {
00167 double pcs;
00168 ASSERT( n<=25 );
00169 ASSERT( l<=4 );
00170 ASSERT( s==0 || s==1 );
00171
00172
00173 if( EgammaRyd < HS_He1_Energy[n][l][s][NUM_HS98_DATA_POINTS-1] )
00174 {
00175 pcs = linint( HS_He1_Energy[n][l][s], HS_He1_Xsectn[n][l][s], NUM_HS98_DATA_POINTS, EgammaRyd );
00176 }
00177 else
00178 {
00179
00180 pcs = HS_He1_Xsectn[n][l][s][NUM_HS98_DATA_POINTS-1] * POW3( HS_He1_Energy[n][l][s][NUM_HS98_DATA_POINTS-1]/EgammaRyd );
00181 }
00182
00183 return pcs;
00184 }
00185
00186
00187 double Recomb_Seaton59( long nelem, double temp, long n)
00188 {
00189 double lambda = TE1RYD * nelem * nelem / temp;
00190
00191
00192 double x = lambda / n / n;
00193 double AlphaN;
00194 double SzeroOfX = 0.;
00195 double SoneOfX = 0.;
00196 double StwoOfX = 0.;
00197 double SnOfLambda = 0.;
00198 double lowerlimit, upperlimit, step;
00199
00200 Xn_S59 = x;
00201
00202
00203 lowerlimit = x;
00204 step = 3. * x;
00205 upperlimit = lowerlimit + step;
00206 SzeroOfX = qg32( lowerlimit, upperlimit, ExponentialInt);
00207
00208 do
00209 {
00210 lowerlimit = upperlimit;
00211 step *= 2;
00212 upperlimit = lowerlimit + step;
00213 SzeroOfX += qg32( lowerlimit, upperlimit, ExponentialInt);
00214 } while ( upperlimit < 20. );
00215
00216
00217
00218
00219
00220
00221 lowerlimit = 0.;
00222 step = 0.5;
00223 upperlimit = lowerlimit + step;
00224 SoneOfX = qg32( lowerlimit, upperlimit, X1Int);
00225 StwoOfX = qg32( lowerlimit, upperlimit, X2Int);
00226
00227 do
00228 {
00229 lowerlimit = upperlimit;
00230 step *= 2;
00231 upperlimit = lowerlimit + step;
00232 SoneOfX += qg32( lowerlimit, upperlimit, X1Int);
00233 StwoOfX += qg32( lowerlimit, upperlimit, X2Int);
00234 } while ( upperlimit < 200. );
00235
00236 SoneOfX *= 0.1728 * pow( x, 1./3. );
00237 StwoOfX *= -0.0496 * pow( x, 2./3. );
00238
00239
00240 SnOfLambda = SzeroOfX + pow(1./lambda, 1./3.)*SoneOfX + pow(1./lambda, 2./3.)*StwoOfX;
00241
00242 AlphaN = 5.197E-14 * nelem * pow(x, 1.5) * SnOfLambda;
00243
00244 return AlphaN;
00245
00246 }
00247
00248 STATIC double ExponentialInt( double v )
00249 {
00250 double Integrand;
00251
00252 Integrand = exp( -1. * v + Xn_S59) / v;
00253
00254 return Integrand;
00255 }
00256
00257 STATIC double X1Int( double u )
00258 {
00259 double Integrand;
00260
00261 Integrand = pow(1./(u + 1.), 5./3.) * (u - 1.) * exp( -1. * Xn_S59 * u );
00262
00263 return Integrand;
00264 }
00265
00266 STATIC double X2Int( double u )
00267 {
00268 double Integrand;
00269
00270 Integrand = pow(1./(u + 1.), 7./3.) * (u*u + 4./3.*u + 1.) * exp( -1. * Xn_S59 * u );
00271
00272 return Integrand;
00273 }
00274