source: trunk/source/processes/hadronic/models/cascade/cascade/src/G4InuclCollider.cc @ 1340

Last change on this file since 1340 was 1340, checked in by garnier, 14 years ago

update ti head

File size: 9.4 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26// $Id: G4InuclCollider.cc,v 1.51 2010/10/19 19:48:39 mkelsey Exp $
27// Geant4 tag: $Name: hadr-casc-V09-03-85 $
28//
29// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
30// 20100309  M. Kelsey -- Eliminate some unnecessary std::pow()
31// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
32// 20100418  M. Kelsey -- Move lab-frame transformation code to G4CollisonOutput
33// 20100429  M. Kelsey -- Change "photon()" to "isPhoton()"
34// 20100517  M. Kelsey -- Inherit from common base class, make other colliders
35//              simple data members, consolidate code
36// 20100620  M. Kelsey -- Reorganize top level if-blocks to reduce nesting,
37//              use new four-vector conservation check.
38// 20100701  M. Kelsey -- Bug fix energy-conservation after equilibrium evap,
39//              pass verbosity through to G4CollisionOutput
40// 20100714  M. Kelsey -- Move conservation checking to base class, report
41//              number of iterations at end
42// 20100715  M. Kelsey -- Remove all the "Before xxx" and "After xxx"
43//              conservation checks, as the colliders now all do so.  Move
44//              local buffers outside while() loop, use new "combined add()"
45//              interface for copying local buffers to global.
46// 20100716  M. Kelsey -- Drop G4IntraNucleiCascader::setInteractionCase()
47// 20100720  M. Kelsey -- Make all the collders pointer members (to reducde
48//              external compile dependences).
49// 20100915  M. Kelsey -- Move post-cascade colliders to G4CascadeDeexcitation,
50//              simplify operational code somewhat
51// 20100922  M. Kelsey -- Add functions to select de-excitation method;
52//              default is G4CascadeDeexcitation (i.e., built-in modules)
53// 20100924  M. Kelsey -- Migrate to integer A and Z
54// 20101019  M. Kelsey -- CoVerity report: check dynamic_cast<> for null
55
56#include "G4InuclCollider.hh"
57#include "G4CascadeDeexcitation.hh"
58#include "G4PreCompoundDeexcitation.hh"
59#include "G4CollisionOutput.hh"
60#include "G4ElementaryParticleCollider.hh"
61#include "G4IntraNucleiCascader.hh"
62#include "G4InuclElementaryParticle.hh"
63#include "G4InuclNuclei.hh"
64#include "G4LorentzConvertor.hh"
65
66
67G4InuclCollider::G4InuclCollider()
68  : G4CascadeColliderBase("G4InuclCollider"),
69    theElementaryParticleCollider(new G4ElementaryParticleCollider),
70    theIntraNucleiCascader(new G4IntraNucleiCascader),
71    theDeexcitation(new G4CascadeDeexcitation) {}
72
73G4InuclCollider::~G4InuclCollider() {
74  delete theElementaryParticleCollider;
75  delete theIntraNucleiCascader;
76  delete theDeexcitation;
77}
78
79
80// Select post-cascade processing (default will be CascadeDeexcitation)
81
82void G4InuclCollider::useCascadeDeexcitation() {
83  delete theDeexcitation;
84  theDeexcitation = new G4CascadeDeexcitation;
85}
86
87void G4InuclCollider::usePreCompoundDeexcitation() {
88  delete theDeexcitation;
89  theDeexcitation = new G4PreCompoundDeexcitation;
90}
91
92
93// Main action
94
95void G4InuclCollider::collide(G4InuclParticle* bullet, G4InuclParticle* target,
96                              G4CollisionOutput& globalOutput) {
97  if (verboseLevel) G4cout << " >>> G4InuclCollider::collide" << G4endl;
98
99  // Initialize colliders verbosity
100  theElementaryParticleCollider->setVerboseLevel(verboseLevel);
101  theIntraNucleiCascader->setVerboseLevel(verboseLevel);
102  theDeexcitation->setVerboseLevel(verboseLevel);
103
104  output.setVerboseLevel(verboseLevel);
105  DEXoutput.setVerboseLevel(verboseLevel);
106
107  const G4int itry_max = 1000;
108
109  // Particle-on-particle collision; no nucleus involved
110  if (useEPCollider(bullet,target)) {
111    if (verboseLevel > 2)
112      G4cout << " InuclCollider -> particle on particle collision" << G4endl;
113 
114    theElementaryParticleCollider->collide(bullet, target, globalOutput);
115    return;
116  }
117 
118  interCase.set(bullet,target);         // Classify collision type
119  if (verboseLevel > 2) {
120    G4cout << " InuclCollider -> inter case " << interCase.code() << G4endl;
121  }
122
123  if (!interCase.valid()) {
124    if (verboseLevel > 1)
125      G4cerr << " InuclCollider -> no collision possible " << G4endl;
126
127    globalOutput.trivialise(bullet, target);
128    return;
129  }
130
131  // Target must be a nucleus
132  G4InuclNuclei* ntarget = dynamic_cast<G4InuclNuclei*>(interCase.getTarget());
133  if (!ntarget) {
134    G4cerr << " InuclCollider -> ERROR target is not a nucleus " << G4endl;
135
136    globalOutput.trivialise(bullet, target);
137    return;
138  }
139
140  G4int btype = 0;
141  G4int ab = 0;
142  G4int zb = 0;
143 
144  if (interCase.hadNucleus()) {         // particle with nuclei
145    G4InuclElementaryParticle* pbullet = 
146      dynamic_cast<G4InuclElementaryParticle*>(interCase.getBullet());
147    if (!pbullet) {
148      G4cerr << " InuclCollider -> ERROR bullet is not a hadron " << G4endl;
149      globalOutput.trivialise(bullet, target);
150      return;
151    } else if (pbullet->isPhoton()) {
152      G4cerr << " InuclCollider -> can not collide with photon " << G4endl;
153      globalOutput.trivialise(bullet, target);
154      return;
155    } else {
156      btype = pbullet->type();
157    } 
158  } else {                              // nuclei with nuclei
159    G4InuclNuclei* nbullet = 
160      dynamic_cast<G4InuclNuclei*>(interCase.getBullet());
161    if (!nbullet) {
162      G4cerr << " InuclCollider -> ERROR bullet is not a nucleus " << G4endl;
163      globalOutput.trivialise(bullet, target);
164      return;
165    }
166   
167    ab = nbullet->getA();
168    zb = nbullet->getZ();
169  }
170
171  G4LorentzConvertor convertToTargetRestFrame(bullet, ntarget);
172  G4double ekin = convertToTargetRestFrame.getKinEnergyInTheTRS();
173 
174  if (verboseLevel > 3) G4cout << " ekin in trs " << ekin << G4endl;
175
176  if (!inelasticInteractionPossible(bullet, target, ekin)) {
177    if (verboseLevel > 3)
178      G4cout << " InuclCollider -> inelastic interaction is impossible\n"
179             << " due to the coulomb barirer " << G4endl;
180
181    globalOutput.trivialise(bullet, target);
182    return;
183  }
184
185  // Generate interaction secondaries in rest frame of target nucleus
186  convertToTargetRestFrame.toTheTargetRestFrame();
187  if (verboseLevel > 3) {
188    G4cout << " degenerated? " << convertToTargetRestFrame.trivial()
189           << G4endl;
190  }
191 
192  G4LorentzVector bmom;                 // Bullet is along local Z
193  bmom.setZ(convertToTargetRestFrame.getTRSMomentum());
194
195  // Need to make copy of bullet with momentum realigned
196  G4InuclParticle* zbullet = 0;
197  if (interCase.hadNucleus())
198    zbullet = new G4InuclElementaryParticle(bmom, btype);
199  else
200    zbullet = new G4InuclNuclei(bmom, ab, zb);
201
202  G4int itry = 0;
203  while (itry < itry_max) {
204    itry++;
205    if (verboseLevel > 2)
206      G4cout << " IntraNucleiCascader itry " << itry << G4endl;
207
208    globalOutput.reset();               // Clear buffers for this attempt
209    output.reset();     
210    DEXoutput.reset();
211
212    theIntraNucleiCascader->collide(zbullet, target, output);
213   
214    if (verboseLevel > 1) G4cout << " After Cascade " << G4endl;
215
216    // FIXME:  The code below still does too much copying!  Would rather
217    //         remove initial fragment from list (or get it a different way)
218    DEXoutput.addOutgoingParticles(output.getOutgoingParticles());
219   
220    if (output.numberOfOutgoingNuclei() == 1) { // Residual fragment
221      // FIXME:  Making a copy here because of constness issues
222      G4InuclNuclei recoil_nucleus = output.getOutgoingNuclei()[0];
223      theDeexcitation->collide(0, &recoil_nucleus, DEXoutput);
224    }
225
226    if (verboseLevel > 2)
227      G4cout << " itry " << itry << " finished, moving to lab frame" << G4endl;
228
229    // convert to the LAB frame and add to final result
230    DEXoutput.boostToLabFrame(convertToTargetRestFrame);
231    globalOutput.add(DEXoutput);
232
233    // Adjust final state particles to balance momentum and energy
234    // FIXME:  This should no longer be necessary!
235    globalOutput.setOnShell(bullet, target);
236    if (globalOutput.acceptable()) {
237      if (verboseLevel) 
238        G4cout << " InuclCollider output after trials " << itry << G4endl;
239      return;
240    }
241  }     // while (itry < itry_max)
242 
243  if (verboseLevel) {
244    G4cout << " InuclCollider -> can not generate acceptable inter. after " 
245           << itry_max << " attempts " << G4endl;
246  }
247 
248  globalOutput.trivialise(bullet, target);
249  return;
250}
Note: See TracBrowser for help on using the repository browser.