Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

MJGeneratorPNNLCascade.cc

Go to the documentation of this file.
00001 // This code implementation is the intellectual property of
00002 // the RD44 GEANT4 collaboration.
00003 //
00004 // By copying, distributing or modifying the Program (or any work
00005 // based on the Program) you indicate your acceptance of this statement,
00006 // and all its terms.
00007 //
00008 // $Id: MJGeneratorPNNLCascade.cc,v 1.2 2004/11/09 13:42:39 xliu Exp $
00009 // GEANT4 tag $Name:  $
00010 //
00011 
00012 #include "generators/MJGeneratorPNNLCascade.hh"
00013 #include "Randomize.hh"
00014 #include <math.h>
00015 #include <iostream.h>
00016 #include <fstream.h>
00017 
00018 const G4int MJGeneratorPNNLCascade::kNUM_BETA_TABLE_ELEMENTS = 100;
00019 const G4int MJGeneratorPNNLCascade::kPARTICLE_INDEX_ALPHA    = 0;
00020 const G4int MJGeneratorPNNLCascade::kPARTICLE_INDEX_BETA     = 1;
00021 const G4int MJGeneratorPNNLCascade::kPARTICLE_INDEX_POSITRON = 2;
00022 
00023 MJGeneratorPNNLCascade::
00024 MJGeneratorPNNLCascade(G4int particle_type, 
00025                        G4double A, G4double Z,
00026                        G4double E_endpoint, G4int delta_L, 
00027                        G4int num_gammas, G4double* gamma_list) :
00028   fType(particle_type),
00029   fA(A), fZ(Z), 
00030   fE_endpoint(E_endpoint), fDelta_L(delta_L),
00031   fNum_gammas(num_gammas)
00032 
00033 {
00034   fGamma_list      = NULL;
00035   f_pBetaEnergyGen = NULL;
00036   fE_alpha = 0.0;
00037 
00038   if (fNum_gammas > 0) {
00039     fGamma_list = new G4double[fNum_gammas];
00040     for (G4int i=0; i<fNum_gammas; i++)
00041       fGamma_list[i] = gamma_list[i];
00042   }
00043 
00044   if ((fType == kPARTICLE_INDEX_BETA) || (fType == kPARTICLE_INDEX_POSITRON)) {
00045 
00046     // Calculate beta(+/-) energy distribution.  Note that arrays of energies,
00047     // distributions, and integrated distributions are stored in the lookup
00048     // table object, so they're not saved as member variables in the Cascade
00049     // object.
00050 
00051     G4double* Beta_E_arr    = new G4double[kNUM_BETA_TABLE_ELEMENTS];
00052     G4double* Beta_dist_arr = new G4double[kNUM_BETA_TABLE_ELEMENTS];
00053     G4double Z_setup = fabs(fZ);  // make sure default is Z_setup > 0
00054 
00055     // N.B. Function Setup_beta_shape expects Z>0 for beta-, Z<0 for beta+
00056     if (fType == kPARTICLE_INDEX_POSITRON)
00057       Z_setup *= -1.0;
00058 
00059     Setup_beta_shape(fE_endpoint, Z_setup, fA, fDelta_L, 
00060                      kNUM_BETA_TABLE_ELEMENTS, Beta_E_arr, Beta_dist_arr);
00061 
00062     f_pBetaEnergyGen = new MJGeneratorPNNLLookup(kNUM_BETA_TABLE_ELEMENTS,
00063                                                  Beta_E_arr, Beta_dist_arr);
00064     delete [] Beta_E_arr;
00065     delete [] Beta_dist_arr;
00066   }
00067   else if (fType == kPARTICLE_INDEX_ALPHA) {
00068     fE_alpha = fE_endpoint;
00069   }
00070   else {
00071     cout << "ERROR in MJGeneratorPNNLCascade constructor: " << endl
00072          << "Unrecognized charged particle type: " << fType << endl
00073          << "Valid options are" << endl
00074          << "(0) alpha" << endl
00075          << "(1) beta-" << endl
00076          << "(2) beta+" << endl
00077          << "Aborting." << endl;
00078     exit(1);
00079   }
00080 }
00081   
00083 MJGeneratorPNNLCascade::
00084 MJGeneratorPNNLCascade(const MJGeneratorPNNLCascade& Cascade)
00085 {
00086   fType       = Cascade.fType;
00087   fA          = Cascade.fA;
00088   fZ          = Cascade.fZ;
00089   fDelta_L    = Cascade.fDelta_L;
00090   fNum_gammas = Cascade.fNum_gammas;
00091   
00092   fE_endpoint = 0.0;
00093   fE_alpha    = 0.0;
00094 
00095   fGamma_list      = NULL;
00096   f_pBetaEnergyGen = NULL;
00097 
00098   if (fNum_gammas > 0) {
00099     fGamma_list = new G4double[fNum_gammas];
00100     for (G4int i=0; i<fNum_gammas; i++)
00101       fGamma_list[i] = Cascade.fGamma_list[i];
00102   }
00103 
00104   if ((fType == kPARTICLE_INDEX_BETA) || (fType == kPARTICLE_INDEX_POSITRON)) {
00105     fE_endpoint = Cascade.fE_endpoint;
00106     f_pBetaEnergyGen = new MJGeneratorPNNLLookup(*(Cascade.f_pBetaEnergyGen));
00107   }
00108   else {
00109     fE_alpha = fE_alpha;
00110   }
00111 }
00112 
00114 void MJGeneratorPNNLCascade::
00115 operator=(const MJGeneratorPNNLCascade& Cascade)
00116 {
00117   fType       = Cascade.fType;
00118   fA          = Cascade.fA;
00119   fZ          = Cascade.fZ;
00120   fDelta_L    = Cascade.fDelta_L;
00121   fNum_gammas = Cascade.fNum_gammas;
00122   
00123   fE_endpoint = 0.0;
00124   fE_alpha    = 0.0;
00125 
00126   fGamma_list      = NULL;
00127   f_pBetaEnergyGen = NULL;
00128 
00129   if (fNum_gammas > 0) {
00130     fGamma_list = new G4double[fNum_gammas];
00131     for (G4int i=0; i<fNum_gammas; i++)
00132       fGamma_list[i] = Cascade.fGamma_list[i];
00133   }
00134 
00135   if ((fType == kPARTICLE_INDEX_BETA) || (fType == kPARTICLE_INDEX_POSITRON)) {
00136     fE_endpoint = Cascade.fE_endpoint;
00137     f_pBetaEnergyGen = new MJGeneratorPNNLLookup(*(Cascade.f_pBetaEnergyGen));
00138   }
00139   else {
00140     fE_alpha = fE_alpha;
00141   }
00142 }
00143 
00145 MJGeneratorPNNLCascade::
00146 ~MJGeneratorPNNLCascade()
00147 {
00148   if (fGamma_list)
00149     delete [] fGamma_list;
00150 }
00151 
00153 void MJGeneratorPNNLCascade::
00154 SetGammaList(G4int num_gammas, G4double* gamma_list) 
00155 {
00156 
00157   fNum_gammas = num_gammas;
00158 
00159   if (fGamma_list)
00160     delete [] fGamma_list;
00161 
00162   fGamma_list = new G4double[num_gammas];
00163   for (G4int i=0; i<num_gammas; i++)
00164     fGamma_list[i] = gamma_list[i];
00165 }
00166 
00168 void MJGeneratorPNNLCascade::
00169 DoPrintCascade() const 
00170 {
00171 
00172   cout << "Particle Type:       " << fType           << endl
00173        << "Parent (A,Z):        " << fA << " " << fZ << endl;
00174 
00175   if (fType == kPARTICLE_INDEX_BETA)
00176     cout << "Beta- endpoint (MeV): " << fE_endpoint << endl
00177          << "Delta(L):            " << fDelta_L    << endl;
00178   else if (fType == kPARTICLE_INDEX_POSITRON)
00179     cout << "Beta+ endpoint (MeV): " << fE_endpoint << endl
00180          << "Delta(L):            " << fDelta_L    << endl;
00181   else
00182     cout << "Alpha energy (MeV):  " << fE_endpoint << endl;
00183 
00184   cout << "Number of gammas:    " << fNum_gammas << endl;
00185   if (fNum_gammas > 0) {
00186     cout << "Gamma energy list:   ";
00187 
00188     for (G4int i=0; i<fNum_gammas; i++) {
00189       if (i == 0)
00190         cout << fGamma_list[i] << endl;
00191       else
00192         cout << "                     " << fGamma_list[i] << endl;
00193     }
00194   }
00195 }
00196 
00198 G4double MJGeneratorPNNLCascade::
00199 DoSampleChargedParticleEnergy() const 
00200 {
00201 
00202   if (fType == kPARTICLE_INDEX_ALPHA)
00203     return fE_alpha;
00204   else
00205     return DoSampleBetaDist();   // beta- or beta+
00206 }
00207 
00209 G4double MJGeneratorPNNLCascade::
00210 DoSampleBetaDist() const 
00211 {
00212 
00213   G4double x = G4UniformRand();
00214   G4double E = f_pBetaEnergyGen->DoLookupInterp(x) * MeV;
00215 
00216   return E;
00217 }
00218 
00220 void MJGeneratorPNNLCascade::
00221 Setup_beta_shape(G4double Qval, G4double Z, 
00222                  G4double A, G4int IDL, G4int num_entries, 
00223                  G4double* E_arr, G4double* Beta_arr) 
00224 {
00225 
00226   // Translated from H.S. Miley's Fortran function BETA_SHAPE, DJ 4-Oct-02
00227   // Given Qval, A, and Z, returns an allowed beta shape, using a 
00228   // non-relativistic Fermi function.  The table of (E_arr, Beta_arr) will
00229   // have num_entries entries.  
00230   //
00231   // N.B. Convention for beta- vs. beta+ decay is Z>0 for beta-, Z<0 for beta+.
00232   //      (This follows Evans, "The Atomic Nucleus", eq. (3.14).)
00233   //
00234   // IDL >=0 gives single beta decay, IDL<0 gives double beta decay.  2beta
00235   // formula (Primakoff-Rosen approx.) taken from CEA's modification of 
00236   // crazy.mortran, Rev. 1.33.
00237 
00238   const G4double PI = 3.1415927;
00239   const G4double M_e = 0.511;
00240 
00241   G4double ZD;
00242   G4double T0;
00243   G4double Estep;
00244   G4double T, UF;
00245   G4double Y, FERFAC;
00246   G4double tmp1, tmp2;
00247 
00248   ZD    = (Z+1.0)/137.0;    // Z>0 ==> beta- decay, Z<0 ==> beta+ decay
00249   T0    = Qval/M_e;  
00250   Estep = Qval/(num_entries-1);
00251 
00252   for (G4int i=0; i<num_entries; i++) {
00253     T = i * Estep/M_e;
00254     E_arr[i] = T * M_e;
00255 
00256     if (IDL >= 0) {   // single beta decay
00257       switch (IDL) {
00258         case 0:
00259           UF = 1.0;
00260           break;
00261         case 1:
00262           UF=T*(T+2.0) + pow(T0-T,2.0);
00263           break;
00264         case 2:
00265           UF= pow((T*(T+2)),2.0) + pow((T0-T),4.0) + 
00266               (10.0/3.0)*T*(T+2)*pow((T0-T),2.0);
00267           break;
00268         case 3:
00269           UF = pow((T*(T+2.0)),3.0) + pow((T0-T),6.0);
00270           UF += 7.0*T*(T+2)*pow((T0-T),2.0)*(T*(T+2.0)+pow((T0-T),2.0));
00271           break;
00272         default:
00273           cout << "Beta_shape: Unsupported value of IDL = " << IDL << endl;
00274           cout << "Only supported values at present are IDL=0,1,2,3." << endl;
00275           cout << "Aborting." << endl;
00276           exit(1);
00277       }
00278 
00279       if (T > 0.0) {
00280         Beta_arr[i] = (T+1.0)*sqrt(T*(T+2.0))*pow((T0-T),2.0);
00281         Y           = ZD*(T+1.0)/sqrt(T*(T+2.0));
00282         FERFAC      = 2.0*PI*Y/(1.0-exp(-2.0*PI*Y));
00283       }
00284       else {
00285         if (Z > 0.0) {  // beta- shape is finite, >0 as E->0
00286           Beta_arr[i] = (T+1.0)*pow((T0-T),2.0);
00287           Y           = ZD*(T+1.0);
00288           FERFAC      = 2.0*PI*Y;
00289         }
00290         else {         // but beta+ shape ->0 as E->0
00291           Beta_arr[i] = 0.0;
00292           FERFAC = 0.0;
00293         }
00294       }
00295 
00296       Beta_arr[i] *= FERFAC*UF;
00297     }
00298 
00299     else {   // double beta-decay; Primakoff-Rosen approximation
00300       tmp1 = double(i)/double(num_entries-1);
00301       tmp2 = 1.0/Qval;
00302       Beta_arr[i] = pow(Qval,2.0) * pow((tmp1 + tmp2),2.0) * 
00303                                     pow((1.0 - tmp1 + tmp2),2.0);
00304     } 
00305      
00306   } 
00307 }
00308 

Generated on Mon Nov 29 16:58:50 2004 for Majorana Simulation by  doxygen 1.3.9.1