00001
00011 #include <math.h>
00012
00013
00014
00015
00016
00017 #include <CLHEP/Random/RandomEngine.h>
00018 #include <CLHEP/Random/RandGeneral.h>
00019 #include <CLHEP/Random/JamesRandom.h>
00020
00021 #include "CrProtonReentrant.h"
00022
00023
00024 typedef double G4double;
00025
00026
00027
00028 namespace {
00029 const G4double pi = 3.14159265358979323846264339;
00030
00031 const G4double restE = 0.938;
00032
00033 const G4double lowE_reentrant = 0.1;
00034 const G4double highE_reentrant = 10.0;
00035
00036
00037
00038
00039
00040
00041 const G4double INTEGRAL_reentrant = 26.449;
00042
00043
00044
00045 inline G4double beta(G4double E ){
00046 return sqrt(1 - pow(E/restE+1, -2));
00047 }
00048
00049
00050 inline G4double rigidity(G4double E ){
00051 return sqrt(pow(E + restE, 2) - pow(restE, 2));
00052 }
00053
00054
00055 inline G4double energy(G4double rigidity ){
00056 return sqrt(pow(rigidity, 2) + pow(restE, 2)) - restE;
00057 }
00058
00059
00060
00072
00073 const G4double A_reentrant = 3.0e-3;
00074
00075 const G4double a_reentrant = 2.5;
00076
00077 G4double LOW_CUTOFF = 0.16;
00078
00079
00080
00081 inline G4double reentrantCRspec(G4double E , G4double cor , G4double phi ){
00082 return A_reentrant * pow(E, -a_reentrant) * exp(-pow(E/LOW_CUTOFF,-1));
00083 }
00084
00085
00086 inline G4double reentrantCRenvelope(G4double E , G4double cor , G4double phi ){
00087 return 2.04e-3*pow(LOW_CUTOFF,-0.3)*pow(E,-2.2)
00088 *exp(-pow(E/(LOW_CUTOFF*0.65),-1.2));
00089 }
00090
00091
00092 inline G4double reentrantCRenvelope_integral
00093 (G4double E , G4double cor , G4double phi ){
00094 return exp(-pow(E/(LOW_CUTOFF*0.65), -1.2));
00095 }
00096
00097
00098 inline G4double reentrantCRenvelope_integral_inv
00099 (G4double value, G4double cor , G4double phi ){
00100 return LOW_CUTOFF * 0.65 * pow(-log(value), 1./-1.2);
00101 }
00102
00103
00104
00105 G4double reentrantCRenergy(HepRandomEngine* engine, G4double cor, G4double solarPotential){
00106 G4double rand_min =
00107 reentrantCRenvelope_integral(lowE_reentrant, cor, solarPotential);
00108 G4double rand_max =
00109 reentrantCRenvelope_integral(highE_reentrant, cor, solarPotential);
00110
00111 G4double r, E;
00112
00113 while(1){
00114 r = engine->flat() * (rand_max - rand_min) + rand_min;
00115 E = reentrantCRenvelope_integral_inv(r, cor, solarPotential);
00116 if (engine->flat() * reentrantCRenvelope(E, cor, solarPotential)
00117 < reentrantCRspec(E, cor, solarPotential)){
00118 break;
00119 }
00120 }
00121 return E;
00122 }
00123
00124 }
00125
00126
00127
00128
00129
00130
00131 CrProtonReentrant::CrProtonReentrant()
00132 {
00133 ;
00134 }
00135
00136
00137 CrProtonReentrant::~CrProtonReentrant()
00138 {
00139 ;
00140 }
00141
00142
00143 std::pair<double,double> CrProtonReentrant::dir(double energy, HepRandomEngine* engine) const
00144
00145
00146
00147 {
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 G4double zenith_angle;
00158 while (1){
00159 zenith_angle = acos(engine->flat());
00160 if (engine->flat()*1.6<1+0.6*sin(zenith_angle)){break;}
00161 }
00162
00163 G4double azimuth = engine->flat() * 2 * pi;
00164
00165 return std::pair<double,double>(cos(zenith_angle), azimuth);
00166 }
00167
00168
00169 double CrProtonReentrant::energySrc(HepRandomEngine* engine) const
00170 {
00171 return reentrantCRenergy(engine, m_cutOffRigidity, m_solarWindPotential);
00172 }
00173
00174
00175 double CrProtonReentrant::flux() const
00176 {
00177
00178
00179
00180
00181
00182
00183
00184 return 0.5 * (1 + 0.15*pi) * INTEGRAL_reentrant;
00185 }
00186
00187
00188 double CrProtonReentrant::solidAngle() const
00189 {
00190 return 2 * pi;
00191 }
00192
00193
00194 const char* CrProtonReentrant::particleName() const
00195 {
00196 return "proton";
00197 }
00198
00199
00200 float CrProtonReentrant::operator()(float r)
00201 {
00202 HepJamesRandom engine;
00203 engine.setSeed(r * 900000000);
00204
00205
00206 return (float)energySrc(&engine);
00207 }
00208
00209
00210 double CrProtonReentrant::calculate_rate(double old_rate)
00211 {
00212 return old_rate;
00213 }
00214
00215
00216 float CrProtonReentrant::flux(float latitude, float longitude) const
00217 {
00218 return flux();
00219 }
00220
00221
00222 float CrProtonReentrant::flux(std::pair<double,double> coords) const
00223 {
00224 return flux();
00225 }
00226
00227
00228 std::string CrProtonReentrant::title() const
00229 {
00230 return "CrProtonReentrant";
00231 }
00232
00233
00234 float CrProtonReentrant::fraction(float energy)
00235
00236 {
00237 return 0;
00238 }
00239
00240
00241 std::pair<float,float> CrProtonReentrant::dir(float energy) const
00242 {
00243 HepJamesRandom engine;
00244
00245 std::pair<G4double,G4double> d = dir(energy, &engine);
00246
00247 return std::pair<float,float>(d.first, d.second);
00248 }
00249