G4InuclCollider.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 // 20100309  M. Kelsey -- Eliminate some unnecessary std::pow()
00030 // 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
00031 // 20100418  M. Kelsey -- Move lab-frame transformation code to G4CollisonOutput
00032 // 20100429  M. Kelsey -- Change "photon()" to "isPhoton()"
00033 // 20100517  M. Kelsey -- Inherit from common base class, make other colliders
00034 //              simple data members, consolidate code
00035 // 20100620  M. Kelsey -- Reorganize top level if-blocks to reduce nesting,
00036 //              use new four-vector conservation check.
00037 // 20100701  M. Kelsey -- Bug fix energy-conservation after equilibrium evap,
00038 //              pass verbosity through to G4CollisionOutput
00039 // 20100714  M. Kelsey -- Move conservation checking to base class, report
00040 //              number of iterations at end
00041 // 20100715  M. Kelsey -- Remove all the "Before xxx" and "After xxx"
00042 //              conservation checks, as the colliders now all do so.  Move
00043 //              local buffers outside while() loop, use new "combined add()"
00044 //              interface for copying local buffers to global.
00045 // 20100716  M. Kelsey -- Drop G4IntraNucleiCascader::setInteractionCase()
00046 // 20100720  M. Kelsey -- Make all the collders pointer members (to reducde
00047 //              external compile dependences).
00048 // 20100915  M. Kelsey -- Move post-cascade colliders to G4CascadeDeexcitation,
00049 //              simplify operational code somewhat
00050 // 20100922  M. Kelsey -- Add functions to select de-excitation method;
00051 //              default is G4CascadeDeexcitation (i.e., built-in modules)
00052 // 20100924  M. Kelsey -- Migrate to integer A and Z
00053 // 20101019  M. Kelsey -- CoVerity report: check dynamic_cast<> for null
00054 // 20110224  M. Kelsey -- Add ::rescatter() function which takes a list of
00055 //              pre-existing secondaries as input.  Add setVerboseLevel().
00056 // 20110301  M. Kelsey -- Pass verbosity to new or changed de-excitation
00057 // 20110304  M. Kelsey -- Modify rescatter to use original Propagate() input
00058 // 20110308  M. Kelsey -- Separate de-excitation block from collide(); check
00059 //              for single-nucleon "fragment", rather than for null fragment
00060 // 20110413  M. Kelsey -- Modify diagnostic messages in ::rescatter() to be
00061 //              equivalent to those from ::collide().
00062 // 20111003  M. Kelsey -- Prepare for gamma-N interactions by checking for
00063 //              final-state tables instead of particle "isPhoton()"
00064 
00065 #include "G4InuclCollider.hh"
00066 #include "G4CascadeChannelTables.hh"
00067 #include "G4CascadeCheckBalance.hh"
00068 #include "G4CascadeDeexcitation.hh"
00069 #include "G4CollisionOutput.hh"
00070 #include "G4ElementaryParticleCollider.hh"
00071 #include "G4IntraNucleiCascader.hh"
00072 #include "G4InuclElementaryParticle.hh"
00073 #include "G4InuclNuclei.hh"
00074 #include "G4LorentzConvertor.hh"
00075 #include "G4PreCompoundDeexcitation.hh"
00076 
00077 
00078 G4InuclCollider::G4InuclCollider()
00079   : G4CascadeColliderBase("G4InuclCollider"),
00080     theElementaryParticleCollider(new G4ElementaryParticleCollider),
00081     theIntraNucleiCascader(new G4IntraNucleiCascader),
00082     theDeexcitation(new G4CascadeDeexcitation) {}
00083 
00084 G4InuclCollider::~G4InuclCollider() {
00085   delete theElementaryParticleCollider;
00086   delete theIntraNucleiCascader;
00087   delete theDeexcitation;
00088 }
00089 
00090 
00091 // Set verbosity and pass on to member objects
00092 void G4InuclCollider::setVerboseLevel(G4int verbose) {
00093   G4CascadeColliderBase::setVerboseLevel(verbose);
00094 
00095   theElementaryParticleCollider->setVerboseLevel(verboseLevel);
00096   theIntraNucleiCascader->setVerboseLevel(verboseLevel);
00097   theDeexcitation->setVerboseLevel(verboseLevel);
00098 
00099   output.setVerboseLevel(verboseLevel);
00100   DEXoutput.setVerboseLevel(verboseLevel);
00101 }
00102 
00103 
00104 // Select post-cascade processing (default will be CascadeDeexcitation)
00105 
00106 void G4InuclCollider::useCascadeDeexcitation() {
00107   delete theDeexcitation;
00108   theDeexcitation = new G4CascadeDeexcitation;
00109   theDeexcitation->setVerboseLevel(verboseLevel);
00110 }
00111 
00112 void G4InuclCollider::usePreCompoundDeexcitation() {
00113   delete theDeexcitation;
00114   theDeexcitation = new G4PreCompoundDeexcitation;
00115   theDeexcitation->setVerboseLevel(verboseLevel);
00116 }
00117 
00118 
00119 // Main action
00120 
00121 void G4InuclCollider::collide(G4InuclParticle* bullet, G4InuclParticle* target,
00122                               G4CollisionOutput& globalOutput) {
00123   if (verboseLevel) G4cout << " >>> G4InuclCollider::collide" << G4endl;
00124 
00125   const G4int itry_max = 100;
00126 
00127   // Particle-on-particle collision; no nucleus involved
00128   if (useEPCollider(bullet,target)) {
00129     if (verboseLevel > 2)
00130       G4cout << " InuclCollider -> particle on particle collision" << G4endl;
00131  
00132     theElementaryParticleCollider->collide(bullet, target, globalOutput);
00133     return;
00134   }
00135   
00136   interCase.set(bullet,target);         // Classify collision type
00137   if (verboseLevel > 2) {
00138     G4cout << " InuclCollider -> inter case " << interCase.code() << G4endl;
00139   }
00140 
00141   if (!interCase.valid()) {
00142     if (verboseLevel > 1)
00143       G4cerr << " InuclCollider -> no collision possible " << G4endl;
00144 
00145     globalOutput.trivialise(bullet, target);
00146     return;
00147   }
00148 
00149   // Target must be a nucleus
00150   G4InuclNuclei* ntarget = dynamic_cast<G4InuclNuclei*>(interCase.getTarget());
00151   if (!ntarget) {
00152     G4cerr << " InuclCollider -> ERROR target is not a nucleus " << G4endl;
00153 
00154     globalOutput.trivialise(bullet, target);
00155     return;
00156   }
00157 
00158   G4int btype = 0;
00159   G4int ab = 0;
00160   G4int zb = 0;
00161   
00162   if (interCase.hadNucleus()) {         // particle with nuclei
00163     G4InuclElementaryParticle* pbullet = 
00164       dynamic_cast<G4InuclElementaryParticle*>(interCase.getBullet());
00165 
00166     if (!pbullet) {
00167       G4cerr << " InuclCollider -> ERROR bullet is not a hadron " << G4endl;
00168       globalOutput.trivialise(bullet, target);
00169       return;
00170     }
00171 
00172     if (!G4CascadeChannelTables::GetTable(pbullet->type())) {
00173       G4cerr << " InuclCollider -> ERROR can not collide with "
00174              << pbullet->getDefinition()->GetParticleName() << G4endl;
00175       globalOutput.trivialise(bullet, target);
00176       return;
00177     }
00178 
00179     btype = pbullet->type();
00180   } else {                              // nuclei with nuclei
00181     G4InuclNuclei* nbullet = 
00182       dynamic_cast<G4InuclNuclei*>(interCase.getBullet());
00183     if (!nbullet) {
00184       G4cerr << " InuclCollider -> ERROR bullet is not a nucleus " << G4endl;
00185       globalOutput.trivialise(bullet, target);
00186       return;
00187     }
00188     
00189     ab = nbullet->getA();
00190     zb = nbullet->getZ();
00191   }
00192 
00193   G4LorentzConvertor convertToTargetRestFrame(bullet, ntarget);
00194   G4double ekin = convertToTargetRestFrame.getKinEnergyInTheTRS();
00195   
00196   if (verboseLevel > 3) G4cout << " ekin in trs " << ekin << G4endl;
00197 
00198   if (!inelasticInteractionPossible(bullet, target, ekin)) {
00199     if (verboseLevel > 3)
00200       G4cout << " InuclCollider -> inelastic interaction is impossible\n"
00201              << " due to the coulomb barirer " << G4endl;
00202 
00203     globalOutput.trivialise(bullet, target);
00204     return;
00205   }
00206 
00207   // Generate interaction secondaries in rest frame of target nucleus
00208   convertToTargetRestFrame.toTheTargetRestFrame();
00209   if (verboseLevel > 3) {
00210     G4cout << " degenerated? " << convertToTargetRestFrame.trivial()
00211            << G4endl;
00212   }
00213   
00214   G4LorentzVector bmom;                 // Bullet is along local Z
00215   bmom.setZ(convertToTargetRestFrame.getTRSMomentum());
00216 
00217   // Need to make copy of bullet with momentum realigned
00218   G4InuclParticle* zbullet = 0;
00219   if (interCase.hadNucleus())
00220     zbullet = new G4InuclElementaryParticle(bmom, btype);
00221   else
00222     zbullet = new G4InuclNuclei(bmom, ab, zb);
00223 
00224   G4int itry = 0;
00225   while (itry < itry_max) {
00226     itry++;
00227     if (verboseLevel > 2)
00228       G4cout << " InuclCollider itry " << itry << G4endl;
00229 
00230     globalOutput.reset();               // Clear buffers for this attempt
00231     output.reset();
00232 
00233     theIntraNucleiCascader->collide(zbullet, target, output);
00234     
00235     if (verboseLevel > 1) G4cout << " After Cascade " << G4endl;
00236 
00237     deexcite(output.getRecoilFragment(), output);
00238     output.removeRecoilFragment();
00239 
00240     if (verboseLevel > 2)
00241       G4cout << " itry " << itry << " finished, moving to lab frame" << G4endl;
00242 
00243     // convert to the LAB frame and add to final result
00244     output.boostToLabFrame(convertToTargetRestFrame);
00245 
00246     globalOutput.add(output);
00247 
00248     // Adjust final state particles to balance momentum and energy
00249     // FIXME:  This should no longer be necessary!
00250     globalOutput.setOnShell(bullet, target);
00251     if (globalOutput.acceptable()) {
00252       if (verboseLevel) 
00253         G4cout << " InuclCollider output after trials " << itry << G4endl;
00254       delete zbullet;
00255       return;
00256     } else {
00257       if (verboseLevel>2)
00258         G4cerr << " InuclCollider setOnShell failed." << G4endl;
00259     }
00260   }     // while (itry < itry_max)
00261   
00262   if (verboseLevel) {
00263     G4cout << " InuclCollider -> can not generate acceptable inter. after " 
00264            << itry_max << " attempts " << G4endl;
00265   }
00266   
00267   globalOutput.trivialise(bullet, target);
00268 
00269   delete zbullet;
00270   return;
00271 }
00272 
00273 
00274 // For use with Propagate to preload a set of secondaries
00275 
00276 void G4InuclCollider::rescatter(G4InuclParticle* bullet,
00277                                 G4KineticTrackVector* theSecondaries,
00278                                 G4V3DNucleus* theNucleus,
00279                                 G4CollisionOutput& globalOutput) {
00280   if (verboseLevel) G4cout << " >>> G4InuclCollider::rescatter" << G4endl;
00281 
00282   G4int itry=1;         // For diagnostic post-processing only
00283   if (verboseLevel > 2) G4cout << " InuclCollider itry " << itry << G4endl;
00284 
00285   globalOutput.reset();         // Clear buffers for this attempt
00286   output.reset();
00287 
00288   theIntraNucleiCascader->rescatter(bullet, theSecondaries, theNucleus, 
00289                                     output);
00290 
00291   if (verboseLevel > 1) G4cout << " After Rescatter" << G4endl;
00292 
00293   deexcite(output.getRecoilFragment(), output);
00294   output.removeRecoilFragment();
00295 
00296   globalOutput.add(output);     // Add local results to global output
00297 
00298   if (verboseLevel) 
00299     G4cout << " InuclCollider output after trials " << itry << G4endl;
00300 }
00301 
00302 
00303 // De-excite nuclear fragment to ground state
00304 
00305 void G4InuclCollider::deexcite(const G4Fragment& fragment,
00306                                G4CollisionOutput& globalOutput) {
00307   if (fragment.GetA() <= 1) return;     // Nothing real to be de-excited
00308 
00309   if (verboseLevel) G4cout << " >>> G4InuclCollider::deexcite" << G4endl;
00310 
00311   G4InuclNuclei frag(fragment);         // Eventually unnecessary
00312 
00313   const G4int itry_max = 10;            // Maximum number of attempts
00314   G4int itry = 0;
00315   do {
00316     if (verboseLevel > 2) G4cout << " deexcite itry " << itry << G4endl;
00317 
00318     DEXoutput.reset();
00319     theDeexcitation->collide(0, &frag, DEXoutput);
00320   } while (!validateOutput(0, &frag, DEXoutput) && (++itry < itry_max));
00321 
00322   // Add de-excitation products to output buffer
00323   globalOutput.add(DEXoutput);
00324 }

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