G4EquilibriumEvaporator.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id$
00027 //
00028 // 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
00029 // 20100308  M. Kelsey -- Bug fix for setting masses of evaporating nuclei
00030 // 20100319  M. Kelsey -- Use new generateWithRandomAngles for theta,phi stuff;
00031 //              eliminate some unnecessary std::pow()
00032 // 20100319  M. Kelsey -- Bug fix in new GetBindingEnergy() use right after
00033 //              goodRemnant() -- Q1 should be outside call.
00034 // 20100412  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
00035 // 20100413  M. Kelsey -- Pass buffers to paraMaker[Truncated]
00036 // 20100419  M. Kelsey -- Handle fission output list via const-ref
00037 // 20100517  M. Kelsey -- Use G4CascadeInterpolator for QFF
00038 // 20100520  M. Kelsey -- Inherit from common base class, make other colliders
00039 //              simple data members.  Rename timeToBigBang() to override
00040 //              base explosion().
00041 // 20100617  M. Kelsey -- Remove "RUN" preprocessor flag and all "#else" code,
00042 //              pass verbosity to colliders.
00043 // 20100620  M. Kelsey -- Use local "bindingEnergy()" function to call through.
00044 // 20100701  M. Kelsey -- Don't need to add excitation to nuclear mass; compute
00045 //              new excitation energies properly (mass differences)
00046 // 20100702  M. Kelsey -- Simplify if-cascades, indentation
00047 // 20100712  M. Kelsey -- Add conservation checking
00048 // 20100714  M. Kelsey -- Move conservation checking to base class.  Use
00049 //              _generated_ evaporate energy (S) to adjust EEXS directly,
00050 //              and test for S < EEXS before any particle generation; shift
00051 //              nucleus momentum (PEX) by evaporate momentum directly
00052 // 20100719  M. Kelsey -- Remove duplicative EESX_new calculation.
00053 // 20100923  M. Kelsey -- Migrate to integer A and Z
00054 // 20110214  M. Kelsey -- Follow G4InuclParticle::Model enumerator migration
00055 // 20110728  M. Kelsey -- Fix Coverity #22951: check for "icase = -1" after
00056 //              loop which is supposed to set it.  Otherwise indexing is wrong.
00057 // 20110801  M. Kelsey -- Move "parms" buffer to data member, allocate in
00058 //              constructor.
00059 // 20110809  M. Kelsey -- Move "foutput" to data member, get list by reference;
00060 //              create final-state particles within "push_back" to avoid
00061 //              creation of temporaries.
00062 // 20110922  M. Kelsey -- Follow G4InuclParticle::print(ostream&) migration
00063 // 20111007  M. Kelsey -- Add G4InuclParticleNames, replace hardcoded numbers
00064 // 20120608  M. Kelsey -- Fix variable-name "shadowing" compiler warnings.
00065 // 20121009  M. Kelsey -- Improve debugging output
00066 
00067 #include "G4EquilibriumEvaporator.hh"
00068 #include "G4SystemOfUnits.hh"
00069 #include "G4BigBanger.hh"
00070 #include "G4CascadeInterpolator.hh"
00071 #include "G4CollisionOutput.hh"
00072 #include "G4Fissioner.hh"
00073 #include "G4InuclNuclei.hh"
00074 #include "G4InuclSpecialFunctions.hh"
00075 #include "G4InuclParticleNames.hh"
00076 #include "G4LorentzConvertor.hh"
00077 #include "G4LorentzVector.hh"
00078 #include "G4ThreeVector.hh"
00079 
00080 using namespace G4InuclParticleNames;
00081 using namespace G4InuclSpecialFunctions;
00082 
00083 
00084 G4EquilibriumEvaporator::G4EquilibriumEvaporator()
00085   : G4CascadeColliderBase("G4EquilibriumEvaporator") {
00086   parms.first.resize(6,0.);
00087   parms.second.resize(6,0.);
00088 }
00089 
00090 G4EquilibriumEvaporator::~G4EquilibriumEvaporator() {}
00091 
00092 
00093 void G4EquilibriumEvaporator::collide(G4InuclParticle* /*bullet*/,
00094                                       G4InuclParticle* target,
00095                                       G4CollisionOutput& output) {
00096   if (verboseLevel) {
00097     G4cout << " >>> G4EquilibriumEvaporator::collide" << G4endl;
00098   }
00099 
00100   // Sanity check
00101   G4InuclNuclei* nuclei_target = dynamic_cast<G4InuclNuclei*>(target);
00102   if (!nuclei_target) {
00103     G4cerr << " EquilibriumEvaporator -> target is not nuclei " << G4endl;    
00104     return;
00105   }
00106 
00107   if (verboseLevel>1) G4cout << " evaporating target: \n" << *target << G4endl;
00108 
00109   theFissioner.setVerboseLevel(verboseLevel);
00110   theBigBanger.setVerboseLevel(verboseLevel);
00111 
00112   // simple implementation of the equilibium evaporation a la Dostrowski
00113   const G4double huge_num = 50.0;
00114   const G4double small = -50.0;
00115   const G4double prob_cut_off = 1.0e-15;
00116   const G4double Q1[6] = { 0.0, 0.0, 2.23, 8.49, 7.72, 28.3 };
00117   const G4int AN[6] = { 1, 1, 2, 3, 3, 4 };
00118   const G4int Q[6] =  { 0, 1, 1, 1, 2, 2 };
00119   const G4double G[6] = { 2.0, 2.0, 6.0, 6.0, 6.0, 4.0 };
00120   const G4double BE = 0.0063;
00121   const G4double fisssion_cut = 1000.0;
00122   const G4double cut_off_energy = 0.1;
00123 
00124   const G4double BF = 0.0242;
00125   const G4int itry_max = 1000;
00126   const G4int itry_global_max = 1000;
00127   const G4double small_ekin = 1.0e-6;
00128   const G4int itry_gam_max = 100;
00129 
00130   G4double W[8], u[6], V[6], TM[6];
00131   G4int A1[6], Z1[6];
00132 
00133   G4int A = nuclei_target->getA();
00134   G4int Z = nuclei_target->getZ();
00135   G4LorentzVector PEX = nuclei_target->getMomentum();
00136   G4double EEXS = nuclei_target->getExitationEnergy();
00137   
00138   if (verboseLevel > 3) G4cout << " after noeq: eexs " << EEXS << G4endl;
00139 
00140   G4InuclElementaryParticle dummy(small_ekin, proton);
00141   G4LorentzConvertor toTheNucleiSystemRestFrame;
00142   //*** toTheNucleiSystemRestFrame.setVerbose(verboseLevel);
00143   toTheNucleiSystemRestFrame.setBullet(dummy);
00144 
00145   G4LorentzVector ppout;
00146   
00147   // See if fragment should just be dispersed
00148   if (explosion(A, Z, EEXS)) {
00149     if (verboseLevel > 1) G4cout << " big bang in eql start " << G4endl;
00150     theBigBanger.collide(0, target, output);
00151 
00152     validateOutput(0, target, output);          // Check energy conservation
00153     return;
00154   }
00155 
00156   // If nucleus is in ground state, no evaporation
00157   if (EEXS < cut_off_energy) {
00158     if (verboseLevel > 1) G4cout << " no energy for evaporation" << G4endl;
00159     output.addOutgoingNucleus(*nuclei_target);
00160 
00161     validateOutput(0, target, output);          // Check energy conservation
00162     return;
00163   }
00164 
00165   // Initialize evaporation attempts
00166   G4double coul_coeff = (A >= 100.0) ? 1.4 : 1.2;
00167    
00168   G4LorentzVector pin = PEX;    // Save original target for testing
00169     
00170   G4bool try_again = true;  
00171   G4bool fission_open = true;
00172   G4int itry_global = 0;
00173     
00174   while (try_again && itry_global < itry_global_max) {
00175     itry_global++;
00176 
00177     // Set rest frame of current (recoiling) nucleus
00178     toTheNucleiSystemRestFrame.setTarget(PEX);
00179     toTheNucleiSystemRestFrame.toTheTargetRestFrame();
00180       
00181     if (verboseLevel > 2) {
00182       G4double nuc_mass = G4InuclNuclei::getNucleiMass(A, Z, EEXS);
00183       G4cout << " A " << A << " Z " << Z << " mass " << nuc_mass
00184              << " EEXS " << EEXS << G4endl;
00185     }
00186       
00187     if (explosion(A, Z, EEXS)) {                        // big bang
00188       if (verboseLevel > 2) 
00189         G4cout << " big bang in eql step " << itry_global << G4endl;
00190 
00191       G4InuclNuclei nuclei(PEX, A, Z, EEXS, G4InuclParticle::Equilib);        
00192       theBigBanger.collide(0, &nuclei, output);
00193 
00194       validateOutput(0, target, output);        // Check energy conservation
00195       return;   
00196     } 
00197 
00198     if (EEXS < cut_off_energy) {        // Evaporation not possible
00199       if (verboseLevel > 2)
00200         G4cout << " no energy for evaporation in eql step " << itry_global 
00201                << G4endl;
00202 
00203       try_again = false;
00204       break;
00205     }
00206 
00207     // Normal evaporation chain
00208     G4double E0 = getE0(A);
00209     G4double parlev = getPARLEVDEN(A, Z);
00210     G4double u1 = parlev * A;
00211 
00212     paraMaker(Z, parms);
00213     const std::vector<G4double>& AK = parms.first;
00214     const std::vector<G4double>& CPA = parms.second;
00215 
00216     G4double DM0 = bindingEnergy(A,Z);
00217     G4int i(0);
00218 
00219     for (i = 0; i < 6; i++) {
00220       A1[i] = A - AN[i];
00221       Z1[i] = Z - Q[i];
00222       u[i] = parlev * A1[i];
00223       V[i] = 0.0;
00224       TM[i] = -0.1;
00225 
00226       if (goodRemnant(A1[i], Z1[i])) {
00227         G4double QB = DM0 - bindingEnergy(A1[i],Z1[i]) - Q1[i];
00228         V[i] = coul_coeff * Z * Q[i] * AK[i] / (1.0 + EEXS / E0) /
00229           (G4cbrt(A1[i]) + G4cbrt(AN[i]));
00230         TM[i] = EEXS - QB - V[i] * A / A1[i];
00231         if (verboseLevel > 3) {
00232           G4cout << " i=" << i << " : QB " << QB << " u " << u[i]
00233                  << " V " << V[i] << " TM " << TM[i] << G4endl;
00234         }
00235       }
00236     }
00237       
00238     G4double ue = 2.0 * std::sqrt(u1 * EEXS);
00239     G4double prob_sum = 0.0;
00240 
00241     W[0] = 0.0;
00242     if (TM[0] > cut_off_energy) {
00243       G4double AL = getAL(A);
00244       W[0] = BE * G4cbrt(A1[0]*A1[0]) * G[0] * AL;
00245       G4double TM1 = 2.0 * std::sqrt(u[0] * TM[0]) - ue;
00246 
00247       if (TM1 > huge_num) TM1 = huge_num;
00248       else if (TM1 < small) TM1 = small;
00249 
00250       W[0] *= std::exp(TM1);
00251       prob_sum += W[0];
00252     }
00253       
00254     for (i = 1; i < 6; i++) {
00255       W[i] = 0.0;
00256       if (TM[i] > cut_off_energy) {
00257         W[i] = BE * G4cbrt(A1[i]*A1[i]) * G[i] * (1.0 + CPA[i]);
00258         G4double TM1 = 2.0 * std::sqrt(u[i] * TM[i]) - ue;
00259 
00260         if (TM1 > huge_num) TM1 = huge_num;
00261         else if (TM1 < small) TM1 = small;
00262 
00263         W[i] *= std::exp(TM1);
00264         prob_sum += W[i];
00265       }
00266     }
00267 
00268     // fisson part
00269     W[6] = 0.0;
00270     if (A >= 100.0 && fission_open) {
00271       G4double X2 = Z * Z / A;
00272       G4double X1 = 1.0 - 2.0 * Z / A; 
00273       G4double X = 0.019316 * X2 / (1.0 - 1.79 * X1 * X1);
00274       G4double EF = EEXS - getQF(X, X2, A, Z, EEXS);
00275           
00276       if (EF > 0.0) {
00277         G4double AF = u1 * getAF(X, A, Z, EEXS);
00278         G4double TM1 = 2.0 * std::sqrt(AF * EF) - ue;
00279 
00280         if (TM1 > huge_num) TM1 = huge_num;
00281         else if (TM1 < small) TM1 = small;
00282 
00283         W[6] = BF * std::exp(TM1);
00284         if (W[6] > fisssion_cut*W[0]) W[6] = fisssion_cut*W[0];              
00285 
00286         prob_sum += W[6];
00287       }
00288     } 
00289 
00290     // again time to decide what next
00291     if (verboseLevel > 2) {
00292       G4cout << " Evaporation probabilities: sum = " << prob_sum
00293              << "\n\t n " << W[0] << " p " << W[1] << " d " << W[2]
00294              << " He3 " << W[3] << "\n\t t " << W[4] << " alpha " << W[5]
00295              << " fission " << W[6] << G4endl;
00296     }
00297 
00298     G4int icase = -1;
00299 
00300     if (prob_sum < prob_cut_off) {              // photon emission chain
00301       G4double UCR0 = 2.5 + 150.0 / A;
00302       G4double T00 = 1.0 / (std::sqrt(u1 / UCR0) - 1.25 / UCR0);
00303 
00304       if (verboseLevel > 3)
00305         G4cout << " UCR0 " << UCR0 << " T00 " << T00 << G4endl;
00306 
00307       G4int itry_gam = 0;
00308       while (EEXS > cut_off_energy && try_again) {
00309         itry_gam++;
00310         G4int itry = 0;
00311         G4double T04 = 4.0 * T00;
00312         G4double FMAX;
00313 
00314         if (T04 < EEXS) {
00315           FMAX = (T04*T04*T04*T04) * std::exp((EEXS - T04) / T00);
00316         } else {
00317           FMAX = EEXS*EEXS*EEXS*EEXS;
00318         }; 
00319 
00320         if (verboseLevel > 3)
00321           G4cout << " T04 " << T04 << " FMAX (EEXS^4) " << FMAX << G4endl;
00322 
00323         G4double S(0), X1(0);
00324         while (itry < itry_max) {
00325           itry++;
00326           S = EEXS * inuclRndm();
00327           X1 = (S*S*S*S) * std::exp((EEXS - S) / T00);
00328 
00329           if (X1 > FMAX * inuclRndm()) break;
00330         };
00331 
00332         if (itry == itry_max) {         // Maximum attempts exceeded
00333           try_again = false;
00334           break;
00335         }
00336 
00337         if (verboseLevel > 2) G4cout << " photon escape ?" << G4endl;
00338 
00339         if (S < EEXS) {         // Valid evaporate
00340           S /= GeV;                             // Convert to Bertini units
00341 
00342           G4double pmod = S;
00343           G4LorentzVector mom = generateWithRandomAngles(pmod, 0.);
00344 
00345           // Push evaporated particle into current rest frame
00346           mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
00347 
00348           if (verboseLevel > 3) {
00349             G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
00350                    << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
00351                    << " evaporate px " << mom.px() << " py " << mom.py()
00352                    << " pz " << mom.pz() << " E " << mom.e() << G4endl;
00353           }
00354 
00355           PEX -= mom;                   // Remaining four-momentum
00356           EEXS -= S*GeV;                // New excitation energy (in MeV)
00357 
00358           // NOTE:  In-situ construction will be optimized away (no copying)
00359           output.addOutgoingParticle(G4InuclElementaryParticle(mom, photon,
00360                                      G4InuclParticle::Equilib));
00361           
00362           if (verboseLevel > 3)
00363             G4cout << output.getOutgoingParticles().back() << G4endl;
00364           
00365           ppout += mom;
00366         } else {
00367           if (itry_gam == itry_gam_max) try_again = false;
00368         }
00369       }         // while (EEXS > cut_off
00370       try_again = false;
00371     } else {                    // if (prob_sum < prob_cut_off)
00372       G4double SL = prob_sum * inuclRndm();
00373       if (verboseLevel > 3) G4cout << " random SL " << SL << G4endl;
00374 
00375       G4double S1 = 0.0;
00376       for (i = 0; i < 7; i++) { // Select evaporation scenario
00377         S1 += W[i];
00378         if (SL <= S1) {
00379           icase = i;
00380           break;
00381         };
00382       };
00383 
00384       if (icase < 0) continue;  // Failed to choose scenario, try again
00385 
00386       if (icase < 6) { // particle or light nuclei escape
00387         if (verboseLevel > 2) {
00388           G4cout << " particle/light-ion escape ("
00389                  << (icase==0 ? "neutron" : icase==1 ? "proton" :
00390                      icase==2 ? "deuteron" : icase==3 ? "He3" :
00391                      icase==4 ? "triton" : icase==5 ? "alpha" : "ERROR!")
00392                  << ")?" << G4endl;
00393         }
00394 
00395         G4double uc = 2.0 * std::sqrt(u[icase] * TM[icase]);
00396         G4double ur = (uc > huge_num ? std::exp(huge_num) : std::exp(uc));
00397         G4double d1 = 1.0 / ur;
00398         G4double d2 = 1.0 / (ur - 1.0);     
00399         G4int itry1 = 0;
00400         G4bool bad = true;
00401 
00402         while (itry1 < itry_max && bad) {
00403           itry1++; 
00404           G4int itry = 0;
00405           G4double EPR = -1.0;
00406           G4double S = 0.0;
00407 
00408           while (itry < itry_max && EPR < 0.0) {
00409             itry++;
00410             G4double uu = uc + std::log((1.0 - d1) * inuclRndm() + d2);
00411             S = 0.5 * (uc * uc - uu * uu) / u[icase];
00412             EPR = TM[icase] - S * A / (A - 1.0) + V[icase];
00413           }; 
00414 
00415           if (verboseLevel > 3) {
00416             G4cout << " EPR " << EPR << " V " << V[icase]
00417                    << " S " << S << " EEXS " << EEXS << G4endl;
00418           }
00419 
00420           if (EPR > 0.0 && S > V[icase] && S < EEXS) {  // real escape
00421             if (verboseLevel > 2)
00422               G4cout << " escape itry1 " << itry1 << " icase "
00423                      << icase << " S (MeV) " << S << G4endl;
00424 
00425             S /= GeV;                           // Convert to Bertini units
00426 
00427             if (icase < 2) {    // particle escape
00428               G4int ptype = 2 - icase;
00429               if (verboseLevel > 2)
00430                 G4cout << " particle " << ptype << " escape" << G4endl;
00431               
00432               // generate particle momentum
00433               G4double mass =
00434                 G4InuclElementaryParticle::getParticleMass(ptype);
00435               
00436               G4double pmod = std::sqrt((2.0 * mass + S) * S);
00437               G4LorentzVector mom = generateWithRandomAngles(pmod, mass);
00438               
00439               // Push evaporated particle into current rest frame
00440               mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
00441               
00442               if (verboseLevel > 2) {
00443                 G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
00444                        << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
00445                        << " evaporate px " << mom.px() << " py " << mom.py()
00446                        << " pz " << mom.pz() << " E " << mom.e() << G4endl;
00447               }
00448               
00449               // New excitation energy depends on residual nuclear state
00450               G4double mass_new =
00451                 G4InuclNuclei::getNucleiMass(A1[icase],Z1[icase]);
00452               
00453               G4double EEXS_new = ((PEX-mom).m() - mass_new)*GeV;
00454               if (EEXS_new < 0.0) continue;     // Sanity check for new nucleus
00455               
00456               PEX -= mom;               // Remaining four-momentum
00457               EEXS = EEXS_new;
00458               
00459               A = A1[icase];
00460               Z = Z1[icase];          
00461               
00462               // NOTE:  In-situ construction optimizes away (no copying)
00463               output.addOutgoingParticle(G4InuclElementaryParticle(mom,
00464                                          ptype, G4InuclParticle::Equilib));
00465               
00466               if (verboseLevel > 3)
00467                 G4cout << output.getOutgoingParticles().back() << G4endl;
00468               
00469               ppout += mom;
00470               bad = false;
00471             } else {    // if (icase < 2)
00472               if (verboseLevel > 2) {
00473                 G4cout << " nucleus A " << AN[icase] << " Z " << Q[icase]
00474                        << " escape icase " << icase << G4endl;
00475               }
00476               
00477               G4double mass =
00478                 G4InuclNuclei::getNucleiMass(AN[icase],Q[icase]);
00479               
00480               // generate particle momentum
00481               G4double pmod = std::sqrt((2.0 * mass + S) * S);
00482               G4LorentzVector mom = generateWithRandomAngles(pmod,mass);
00483               
00484               // Push evaporated particle into current rest frame
00485               mom = toTheNucleiSystemRestFrame.backToTheLab(mom);
00486               
00487               if (verboseLevel > 2) {
00488                 G4cout << " nucleus   px " << PEX.px() << " py " << PEX.py()
00489                        << " pz " << PEX.pz() << " E " << PEX.e() << G4endl
00490                        << " evaporate px " << mom.px() << " py " << mom.py()
00491                        << " pz " << mom.pz() << " E " << mom.e() << G4endl;
00492               }
00493               
00494               // New excitation energy depends on residual nuclear state
00495               G4double mass_new =
00496                 G4InuclNuclei::getNucleiMass(A1[icase],Z1[icase]);
00497               
00498               G4double EEXS_new = ((PEX-mom).m() - mass_new)*GeV;
00499               if (EEXS_new < 0.0) continue;     // Sanity check for new nucleus
00500               
00501               PEX -= mom;               // Remaining four-momentum
00502               EEXS = EEXS_new;
00503               
00504               A = A1[icase];
00505               Z = Z1[icase];
00506               
00507               // NOTE:  In-situ constructor optimizes away (no copying)
00508               output.addOutgoingNucleus(G4InuclNuclei(mom,
00509                                         AN[icase], Q[icase], 0.*GeV, 
00510                                         G4InuclParticle::Equilib));
00511               
00512               if (verboseLevel > 3) 
00513                 G4cout << output.getOutgoingNuclei().back() << G4endl;
00514               
00515               ppout += mom;
00516               bad = false;
00517             }           // if (icase < 2)
00518           }             // if (EPR > 0.0 ...
00519         }               // while (itry1 ...
00520 
00521         if (itry1 == itry_max || bad) try_again = false;
00522       } else {  // if (icase < 6)
00523         G4InuclNuclei nuclei(A, Z, EEXS, G4InuclParticle::Equilib);        
00524 
00525         if (verboseLevel > 2) {
00526           G4cout << " fission: A " << A << " Z " << Z << " eexs " << EEXS
00527                  << " Wn " << W[0] << " Wf " << W[6] << G4endl;
00528         }
00529 
00530         // Catch fission output separately for verification
00531         fission_output.reset();
00532         theFissioner.collide(0, &nuclei, fission_output);
00533 
00534         std::vector<G4InuclNuclei>& nuclea = fission_output.getOutgoingNuclei();
00535         if (nuclea.size() == 2) {               // fission ok
00536           if (verboseLevel > 2) G4cout << " fission done in eql" << G4endl;
00537 
00538           // Move fission fragments to lab frame for processing
00539           fission_output.boostToLabFrame(toTheNucleiSystemRestFrame);
00540 
00541           // Now evaporate the fission fragments individually
00542           G4bool prevDoChecks = doConservationChecks;   // Turn off checking
00543           setConservationChecks(false);
00544 
00545           this->collide(0, &nuclea[0], output);
00546           this->collide(0, &nuclea[1], output);
00547 
00548           setConservationChecks(prevDoChecks);  // Restore previous flag value
00549           validateOutput(0, target, output);    // Check energy conservation
00550           return;
00551         } else { // fission forbidden now
00552           fission_open = false;
00553         }
00554       }         // End of fission case
00555     }           // if (prob_sum < prob_cut_off)
00556   }             // while (try_again
00557 
00558   // this time it's final nuclei
00559 
00560   if (itry_global == itry_global_max) {
00561     if (verboseLevel > 3) {
00562       G4cout << " ! itry_global " << itry_global_max << G4endl;
00563     }
00564   }
00565 
00566   G4LorentzVector pnuc = pin - ppout;
00567 
00568   // NOTE:  In-situ constructor will be optimized away (no copying)
00569   output.addOutgoingNucleus(G4InuclNuclei(pnuc, A, Z, EEXS,
00570                                           G4InuclParticle::Equilib));
00571 
00572   if (verboseLevel > 3) {
00573     G4cout << " remaining nucleus \n" << output.getOutgoingNuclei().back()
00574            << G4endl;
00575   }
00576 
00577 
00578   validateOutput(0, target, output);            // Check energy conservation
00579   return;
00580 }                    
00581 
00582 G4bool G4EquilibriumEvaporator::explosion(G4int a, 
00583                                           G4int z, 
00584                                           G4double e) const {
00585   if (verboseLevel > 3) {
00586     G4cout << " >>> G4EquilibriumEvaporator::explosion? ";
00587   }
00588 
00589   const G4double be_cut = 3.0;
00590 
00591   // Different criteria from base class, since nucleus more "agitated"
00592   G4bool bigb = (!(a >= 12 && z >= 0 && z < 3*(a-z)) &&
00593                  (e >= be_cut * bindingEnergy(a,z))
00594                  );
00595 
00596   if (verboseLevel > 3) G4cout << bigb << G4endl;
00597 
00598   return bigb;
00599 }
00600 
00601 G4bool G4EquilibriumEvaporator::goodRemnant(G4int a, 
00602                                             G4int z) const {
00603   if (verboseLevel > 3) {
00604     G4cout << " >>> G4EquilibriumEvaporator::goodRemnant(" << a << "," << z
00605            << ")? " << (a>1 && z>0 && a>z) << G4endl;
00606   }
00607 
00608   return a > 1 && z > 0 && a > z;
00609 }
00610 
00611 G4double G4EquilibriumEvaporator::getQF(G4double x, 
00612                                         G4double x2, 
00613                                         G4int a,
00614                                         G4int /*z*/, 
00615                                         G4double ) const {
00616   if (verboseLevel > 3) {
00617     G4cout << " >>> G4EquilibriumEvaporator::getQF ";
00618   }
00619   
00620   static const G4double QFREP[72] = {  
00621     //     TL201 *     *   *    *
00622     //      1    2     3   4    5
00623     22.5, 22.0, 21.0, 21.0, 20.0,
00624     //     BI209 BI207 PO210 AT213 *    TH234
00625     //      6     7    8     9     10   11
00626     20.6, 20.6, 18.6, 15.8, 13.5, 6.5,
00627     //     TH233 TH232 TH231 TH230 TX229 PA233 PA232 PA231 PA230 U240
00628     //     12    13    14    15    16    17    18    19    20    21
00629     6.65, 6.22, 6.27, 6.5,  6.7,  6.2,  6.25, 5.9,  6.1,  5.75,
00630     //     U239 U238 U237  U236 U235 U234 U233 U232 U231
00631     //     22   23   24    25   26   27   28   29   30
00632     6.46, 5.7, 6.28, 5.8, 6.15, 5.6, 5.8, 5.2, 5.8,
00633     //     NP238 NP237 NP236 NP235 PU245 NP234  PU244 NP233
00634     //     31    32    33    34    35    36     37    38
00635     6.2 , 5.9 , 5.9,  6.0,  5.8,  5.7,   5.4,  5.4,
00636     //     PU242 PU241 PU240 PU239 PU238 AM247 PU236 AM245 AM244 AM243
00637     //     39    40    41    42    43    44    45    46    47    48
00638     5.6,  6.1,  5.57, 6.3,  5.5,  5.8,  4.7,  6.2,  6.4,  6.2,
00639     //     AM242 AM241 AM240 CM250 AM239 CM249 CM248 CM247 CM246
00640     //     49    50    51    52    53    54    55    56    57
00641     6.5,  6.2,  6.5,  5.3,  6.4,  5.7,  5.7,  6.2,  5.7,
00642     //     CM245 CM244 CM243 CM242 CM241 BK250 CM240
00643     //     58    59    60    61    62    63    64
00644     6.3,  5.8,  6.7,  5.8,  6.6,  6.1,  4.3,
00645     //     BK249 CF252 CF250 CF248 CF246 ES254 ES253 FM254
00646     //     65    66    67    68    69    70    71    72
00647     6.2,  3.8,  5.6,  4.0,  4.0,  4.2,  4.2,  3.5 };
00648      
00649   static const G4double XREP[72] = {
00650     //      1      2     3      4      5
00651     0.6761, 0.677, 0.6788, 0.6803, 0.685,
00652     //      6     7     8     9     10     11
00653     0.6889, 0.6914, 0.6991, 0.7068, 0.725, 0.7391,
00654     //     12  13    14   15   16    17  18    19    20    21
00655     0.74, 0.741, 0.742, 0.743, 0.744, 0.7509, 0.752, 0.7531, 0.7543, 0.7548,
00656     //     22    23    24
00657     0.7557, 0.7566, 0.7576,
00658     //      25     26   27    28    29   30   31    32     33    34
00659     0.7587, 0.7597, 0.7608, 0.762, 0.7632, 0.7644, 0.7675, 0.7686, 0.7697, 0.7709,
00660     //      35    36    37    38    39   40    41
00661     0.7714, 0.7721, 0.7723, 0.7733, 0.7743, 0.7753, 0.7764,
00662     //      42    43    44    45    46    47    48   49
00663     0.7775, 0.7786, 0.7801, 0.781, 0.7821, 0.7831, 0.7842, 0.7852,
00664     //     50     51    52    53    54    55    56    57    58
00665     0.7864, 0.7875, 0.7880, 0.7887, 0.7889, 0.7899, 0.7909, 0.7919, 0.7930,
00666     //      59    60    61    62    63    64
00667     0.7941, 0.7953, 0.7965, 0.7977, 0.7987, 0.7989,
00668     //      65    66    67    68    69    70    71    72
00669     0.7997, 0.8075, 0.8097, 0.8119, 0.8143, 0.8164, 0.8174, 0.8274 };
00670 
00671   const G4double G0 = 20.4;
00672   const G4double XMIN = 0.6761;
00673   const G4double XMAX = 0.8274;
00674 
00675   G4double QFF = 0.0;
00676 
00677   if (x < XMIN || x > XMAX) {
00678     G4double X1 = 1.0 - 0.02 * x2;
00679     G4double FX = (0.73 + (3.33 * X1 - 0.66) * X1) * (X1*X1*X1);
00680 
00681     QFF = G0 * FX * G4cbrt(a*a);
00682   } else {
00683     static G4CascadeInterpolator<72> interp(XREP);      // Only need one!
00684     QFF = interp.interpolate(x, QFREP);
00685   }
00686 
00687   if (QFF < 0.0) QFF = 0.0;
00688 
00689   if (verboseLevel>3) G4cout << " returns " << QFF << G4endl;
00690 
00691   return QFF; 
00692 }
00693 
00694 G4double G4EquilibriumEvaporator::getAF(G4double , 
00695                                         G4int /*a*/, 
00696                                         G4int /*z*/, 
00697                                         G4double e) const {
00698 
00699   if (verboseLevel > 3) {
00700     G4cout << " >>> G4EquilibriumEvaporator::getAF" << G4endl;
00701   }
00702 
00703   // ugly parameterisation to fit the experimental fission cs for Hg - Bi nuclei
00704   G4double AF = 1.285 * (1.0 - e / 1100.0);
00705 
00706   if(AF < 1.06) AF = 1.06;
00707   // if(AF < 1.08) AF = 1.08;
00708 
00709   return AF;
00710 }       
00711 
00712 G4double G4EquilibriumEvaporator::getPARLEVDEN(G4int /*a*/, 
00713                                                G4int /*z*/) const {
00714 
00715   if (verboseLevel > 3) {
00716     G4cout << " >>> G4EquilibriumEvaporator::getPARLEVDEN" << G4endl;
00717   }
00718 
00719   const G4double par = 0.125;
00720 
00721   return par;
00722 }
00723 
00724 G4double G4EquilibriumEvaporator::getE0(G4int /*a*/) const {
00725 
00726   if (verboseLevel > 3) {
00727     G4cout << " >>> G4EquilibriumEvaporator::getE0" << G4endl;
00728   }
00729 
00730   const G4double e0 = 200.0;   
00731 
00732   return e0;   
00733 }

Generated on Mon May 27 17:48:10 2013 for Geant4 by  doxygen 1.4.7