source: trunk/source/processes/hadronic/models/cascade/cascade/src/G4PreCompoundCascadeInterface.cc @ 1337

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

tag geant4.9.4 beta 1 + modifs locales

File size: 10.9 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: G4PreCompoundCascadeInterface.cc,v 1.13.2.1 2010/06/25 09:45:00 gunter Exp $
27// Geant4 tag: $Name: geant4-09-04-beta-01 $
28//
29// 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
30// 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
31// 20100414  M. Kelsey -- Check for K0L/K0S before using G4InuclElemPart::type
32// 20100419  M. Kelsey -- Access G4CollisionOutput lists by const-ref, and
33//              const_iterator
34// 20100428  M. Kelsey -- Use G4InuclParticleNames enum
35// 20100429  M. Kelsey -- Change "case gamma:" to "case photon:"
36// 20100517  M. Kelsey -- Follow new ctors for G4*Collider family.
37// 20100520  M. Kelsey -- Add missing name string to ctor, follow code changes
38//              from G4CascadeInterface.
39
40#include "G4PreCompoundCascadeInterface.hh"
41#include "globals.hh"
42#include "G4CollisionOutput.hh"
43#include "G4DynamicParticle.hh"
44#include "G4InuclElementaryParticle.hh"
45#include "G4InuclNuclei.hh"
46#include "G4InuclParticle.hh"
47#include "G4InuclParticleNames.hh"
48#include "G4KaonZeroShort.hh"
49#include "G4KaonZeroLong.hh"
50#include "G4LorentzRotation.hh"
51#include "G4Nucleus.hh"
52#include "G4ParticleDefinition.hh"
53#include "G4PreCompoundInuclCollider.hh"
54#include "G4Track.hh"
55#include "G4V3DNucleus.hh"
56
57using namespace G4InuclParticleNames;
58
59
60typedef std::vector<G4InuclElementaryParticle>::const_iterator particleIterator;
61typedef std::vector<G4InuclNuclei>::const_iterator nucleiIterator;
62
63G4PreCompoundCascadeInterface::G4PreCompoundCascadeInterface(const G4String& nam)
64  :G4VIntraNuclearTransportModel(nam), verboseLevel(0)  {
65
66  if (verboseLevel > 3) {
67    G4cout << " >>> G4PreCompoundCascadeInterface::G4PreCompoundCascadeInterface" << G4endl;
68  }
69}
70   
71G4ReactionProductVector* G4PreCompoundCascadeInterface::Propagate(G4KineticTrackVector* , 
72                                                                  G4V3DNucleus* ) {
73  return 0;
74}
75
76// #define debug_G4PreCompoundCascadeInterface
77
78G4HadFinalState* G4PreCompoundCascadeInterface::ApplyYourself(const G4HadProjectile& aTrack, 
79                                                              G4Nucleus& theNucleus) {
80#ifdef debug_G4PreCompoundCascadeInterface
81  static G4int counter(0);
82  counter++;
83  G4cerr << "Reaction number "<< counter << " "<<aTrack.GetDynamicParticle()->GetDefinition()->GetParticleName()<<" "<< aTrack.GetDynamicParticle()->GetKineticEnergy()<<G4endl;
84#endif
85
86  theResult.Clear();
87
88  if (verboseLevel > 3) {
89    G4cout << " >>> G4PreCompoundCascadeInterface::ApplyYourself" << G4endl;
90  };
91
92  G4double eInit     = 0.0;
93  G4double eTot      = 0.0;
94  G4double sumBaryon = 0.0;
95  G4double sumEnergy = 0.0;
96
97  // Make conversion between native Geant4 and Bertini cascade classes.
98  // NOTE: Geant4 units are MeV = 1 and GeV = 1000. Cascade code by default use GeV = 1.
99
100  G4int bulletType;
101  if (aTrack.GetDefinition() == G4KaonZeroLong::KaonZeroLong() ||
102      aTrack.GetDefinition() == G4KaonZeroShort::KaonZeroShort() )
103    bulletType = (G4UniformRand() > 0.5) ? kaonZero : kaonZeroBar;
104  else 
105    bulletType = G4InuclElementaryParticle::type(aTrack.GetDefinition());
106
107  // Code momentum and energy.
108  G4LorentzVector projectileMomentum = aTrack.Get4Momentum();
109  G4LorentzRotation toZ;
110  toZ.rotateZ(-projectileMomentum.phi());
111  toZ.rotateY(-projectileMomentum.theta());
112  G4LorentzRotation toLabFrame = toZ.inverse();
113
114  G4LorentzVector momentumBullet(0., 0., aTrack.GetTotalMomentum()/GeV,
115                                 aTrack.GetTotalEnergy()/GeV);
116
117  G4InuclElementaryParticle *  bullet =
118    new G4InuclElementaryParticle(momentumBullet, bulletType); 
119
120  sumEnergy = bullet->getKineticEnergy(); // In GeV
121  sumBaryon += bullet->baryon();
122
123  // Set target
124  G4InuclNuclei*   target  = 0;
125  G4InuclParticle* targetH = 0;
126
127  G4double theNucleusA = theNucleus.GetN();
128
129  if ( !(G4int(theNucleusA) == 1) ) {
130    target  = new G4InuclNuclei(theNucleusA, theNucleus.GetZ());
131    eInit = bullet->getEnergy() + target->getEnergy();
132
133    sumBaryon += theNucleusA;
134
135    if (verboseLevel > 2) {
136      G4cout << "Bullet:  " << G4endl; 
137      bullet->printParticle();
138    }
139    if (verboseLevel > 2) {
140      G4cout << "Target:  " << G4endl; 
141      target->printParticle();
142    }
143  }
144
145  G4CollisionOutput output;
146
147  // Colliders initialisation
148  G4PreCompoundInuclCollider*  collider = new G4PreCompoundInuclCollider;
149
150  G4int  maxTries = 10; // maximum tries for inelastic collision to avoid infinite loop
151  G4int  nTries   = 0;  // try counter
152
153  if (G4int(theNucleusA) == 1) { // special treatment for target H(1,1) (proton)
154
155    targetH = new G4InuclElementaryParticle(1);
156
157    G4float cutElastic[32];
158
159    cutElastic[proton   ]   = 1.0; // 1 GeV
160    cutElastic[neutron  ]   = 1.0;
161    cutElastic[lambda]      = 1.0;
162    cutElastic[sigmaPlus]   = 1.0;
163    cutElastic[sigmaZero]   = 1.0;
164    cutElastic[sigmaMinus]  = 1.0;
165    cutElastic[xiZero]      = 1.0;
166    cutElastic[xiMinus]     = 1.0;
167
168    cutElastic[pionPlus ]   = 0.6; // 0.6 GeV
169
170    cutElastic[kaonPlus ]   = 0.5; // 0.5 GeV
171    cutElastic[kaonMinus]   = 0.5;
172    cutElastic[kaonZero]    = 0.5;
173    cutElastic[kaonZeroBar] = 0.5;
174
175    cutElastic[pionMinus]   = 0.2; // 0.2 GeV
176    cutElastic[pionZero ]   = 0.2;
177
178
179    if (momentumBullet.z() > cutElastic[bulletType]) { // inelastic collision possible
180
181      do {   // we try to create inelastic interaction
182        output.reset();
183        collider->collide(bullet, targetH, output);
184        nTries++;
185      } while(
186              (nTries < maxTries) &&
187              (output.getOutgoingParticles().size() == 2 && // elastic: bullet + p = H(1,1) coming out
188               (output.getOutgoingParticles().begin()->type() == bulletType || output.getOutgoingParticles().begin()->type() == proton)
189               )
190              );
191
192    } else { // only elastic collision is energetically possible
193      collider->collide(bullet, targetH, output);
194    }
195
196    sumBaryon += 1;
197
198    eInit = bullet->getEnergy() + target->getEnergy();
199
200    if (verboseLevel > 2) {
201      G4cout << "Target:  " << G4endl;
202      targetH->printParticle();
203    }
204
205  } else {  // treat all other targets excepet H(1,1)
206
207    do  // we try to create inelastic interaction
208      {
209        output.reset();
210        collider->collide(bullet, target, output);
211        nTries++;
212      } while (
213               (nTries < maxTries) &&
214               output.getOutgoingParticles().size() == 1 &&     // we retry when elastic collision happened
215               output.getNucleiFragments().size() == 1 &&           
216               output.getOutgoingParticles().begin()->type() == bullet->type() &&
217               output.getNucleiFragments().begin()->getA() == target->getA() && 
218               output.getNucleiFragments().begin()->getZ() == target->getZ() 
219               );
220  }
221 
222  if (verboseLevel > 1) {
223      G4cout << " Cascade output: " << G4endl;
224      output.printCollisionOutput();
225  }
226 
227  // Rotate event to put Z axis along original projectile direction
228  output.rotateEvent(toLabFrame);
229
230  // Convert cascade data to use hadronics interface
231  const std::vector<G4InuclNuclei>& nucleiFragments = output.getNucleiFragments();
232  const std::vector<G4InuclElementaryParticle>& particles = output.getOutgoingParticles();
233
234  theResult.SetStatusChange(stopAndKill);
235
236  // Get outcoming particles
237  G4DynamicParticle* cascadeParticle = 0;
238  if (!particles.empty()) { 
239    particleIterator ipart = particles.begin();
240    for (; ipart != particles.end(); ipart++) {
241      G4int outgoingType = ipart->type();
242
243      eTot += ipart->getEnergy();
244      sumBaryon -= ipart->baryon();
245      sumEnergy -= ipart->getKineticEnergy();
246
247      if (!ipart->valid() || ipart->quasi_deutron()) {
248        G4cerr << " ERROR: G4PreCompoundCascadeInterface::Propagate incompatible"
249               << " particle type " << ipart->type() << G4endl;
250        continue;
251      }
252
253      // Copy local G4DynPart to public output (handle kaon mixing specially)
254      if (outgoingType == kaonZero || outgoingType == kaonZeroBar) {
255        G4ThreeVector momDir = ipart->getMomentum().vect().unit();
256        G4double ekin = ipart->getKineticEnergy();
257
258        G4ParticleDefinition* pd = G4KaonZeroShort::Definition();
259        if (G4UniformRand() > 0.5) pd = G4KaonZeroLong::Definition();
260
261        cascadeParticle = new G4DynamicParticle(pd, momDir, ekin);
262      } else {
263        cascadeParticle = new G4DynamicParticle(ipart->getDynamicParticle());
264      }
265 
266      theResult.AddSecondary(cascadeParticle); 
267    }
268  }
269
270  // get nuclei fragments
271  G4DynamicParticle * aFragment = 0;
272  if (!nucleiFragments.empty()) { 
273    nucleiIterator ifrag = nucleiFragments.begin();
274    for (; ifrag != nucleiFragments.end(); ifrag++) {
275      eTot += ifrag->getEnergy();
276      sumBaryon -= ifrag->getA();
277      sumEnergy -= ifrag->getKineticEnergy();
278
279      if (verboseLevel > 2) {
280        G4cout << " Nuclei fragment: " << G4endl;
281        ifrag->printParticle();
282      }
283
284      // Copy local G4DynPart to public output
285      aFragment =  new G4DynamicParticle(ifrag->getDynamicParticle());
286      theResult.AddSecondary(aFragment); 
287    }
288  }
289
290  // Report violations of energy, baryon conservation
291  if (verboseLevel > 2) {
292    if (sumBaryon != 0) {
293      G4cout << "ERROR: no baryon number conservation, sum of baryons = "
294             << sumBaryon << G4endl;
295    }
296
297    if (sumEnergy > 0.01 ) {
298      G4cout << "Kinetic energy conservation violated by "
299             << sumEnergy << " GeV" << G4endl;
300    }
301     
302    G4cout << "Total energy conservation at level ~"
303           << (eInit - eTot) * GeV << " MeV" << G4endl;
304   
305    if (sumEnergy < -5.0e-5 ) { // 0.05 MeV
306      G4cout << "FATAL ERROR: energy created  "
307             << sumEnergy * GeV << " MeV" << G4endl;
308    }
309  }
310
311  delete bullet;
312  delete collider;
313
314  if(target != 0) delete target;
315  if(targetH != 0) delete targetH;
316
317  return &theResult;
318  }
Note: See TracBrowser for help on using the repository browser.