Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4RPGPiMinusInelastic.cc
Go to the documentation of this file.
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$
27//
28
30#include "G4SystemOfUnits.hh"
31#include "Randomize.hh"
32
35 G4Nucleus& targetNucleus)
36{
37 const G4HadProjectile* originalIncident = &aTrack;
38
39 if (originalIncident->GetKineticEnergy()<= 0.1) {
43 return &theParticleChange;
44 }
45
46 // create the target particle
47
48 G4DynamicParticle* originalTarget = targetNucleus.ReturnTargetParticle();
49 G4ReactionProduct targetParticle( originalTarget->GetDefinition() );
50
51 G4ReactionProduct currentParticle(
52 const_cast<G4ParticleDefinition *>(originalIncident->GetDefinition() ) );
53 currentParticle.SetMomentum( originalIncident->Get4Momentum().vect() );
54 currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() );
55
56 // Fermi motion and evaporation
57 // As of Geant3, the Fermi energy calculation had not been Done
58
59 G4double ek = originalIncident->GetKineticEnergy();
60 G4double amas = originalIncident->GetDefinition()->GetPDGMass();
61
62 G4double tkin = targetNucleus.Cinema( ek );
63 ek += tkin;
64 currentParticle.SetKineticEnergy( ek );
65 G4double et = ek + amas;
66 G4double p = std::sqrt( std::abs((et-amas)*(et+amas)) );
67 G4double pp = currentParticle.GetMomentum().mag();
68 if( pp > 0.0 ) {
69 G4ThreeVector momentum = currentParticle.GetMomentum();
70 currentParticle.SetMomentum( momentum * (p/pp) );
71 }
72
73 // calculate black track energies
74
75 tkin = targetNucleus.EvaporationEffects( ek );
76 ek -= tkin;
77 currentParticle.SetKineticEnergy( ek );
78 et = ek + amas;
79 p = std::sqrt( std::abs((et-amas)*(et+amas)) );
80 pp = currentParticle.GetMomentum().mag();
81 if( pp > 0.0 ) {
82 G4ThreeVector momentum = currentParticle.GetMomentum();
83 currentParticle.SetMomentum( momentum * (p/pp) );
84 }
85
86 G4ReactionProduct modifiedOriginal = currentParticle;
87
88 currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere
89 targetParticle.SetSide( -1 ); // target always goes in backward hemisphere
90 G4bool incidentHasChanged = false;
91 G4bool targetHasChanged = false;
92 G4bool quasiElastic = false;
93 G4FastVector<G4ReactionProduct,256> vec; // vec will contain the secondary particles
94 G4int vecLen = 0;
95 vec.Initialize( 0 );
96
97 const G4double cutOff = 0.1;
98 if( currentParticle.GetKineticEnergy() > cutOff )
99 InitialCollision(vec, vecLen, currentParticle, targetParticle,
100 incidentHasChanged, targetHasChanged);
101
102 CalculateMomenta(vec, vecLen,
103 originalIncident, originalTarget, modifiedOriginal,
104 targetNucleus, currentParticle, targetParticle,
105 incidentHasChanged, targetHasChanged, quasiElastic);
106
107 SetUpChange(vec, vecLen,
108 currentParticle, targetParticle,
109 incidentHasChanged);
110
111 delete originalTarget;
112 return &theParticleChange;
113}
114
115
116// Initial Collision
117// selects the particle types arising from the initial collision of
118// the projectile and target nucleon. Secondaries are assigned to
119// forward and backward reaction hemispheres, but final state energies
120// and momenta are not calculated here.
121
122void
123G4RPGPiMinusInelastic::InitialCollision(G4FastVector<G4ReactionProduct,256>& vec,
124 G4int& vecLen,
125 G4ReactionProduct& currentParticle,
126 G4ReactionProduct& targetParticle,
127 G4bool& incidentHasChanged,
128 G4bool& targetHasChanged)
129{
130 G4double KE = currentParticle.GetKineticEnergy()/GeV;
131
132 G4int mult;
133 G4int partType;
134 std::vector<G4int> fsTypes;
135
136 G4double testCharge;
137 G4double testBaryon;
138 G4double testStrange;
139
140 // Get particle types according to incident and target types
141
142 if (targetParticle.GetDefinition() == particleDef[pro]) {
143 mult = GetMultiplicityT12(KE);
144 fsTypes = GetFSPartTypesForPimP(mult, KE);
145 partType = fsTypes[0];
146 if (partType != pro) {
147 targetHasChanged = true;
148 targetParticle.SetDefinition(particleDef[partType]);
149 }
150
151 testCharge = 0.0;
152 testBaryon = 1.0;
153 testStrange = 0.0;
154
155 } else { // target was a neutron
156 mult = GetMultiplicityT32(KE);
157 fsTypes = GetFSPartTypesForPimN(mult, KE);
158 partType = fsTypes[0];
159 if (partType != neu) {
160 targetHasChanged = true;
161 targetParticle.SetDefinition(particleDef[partType]);
162 }
163
164 testCharge = -1.0;
165 testBaryon = 1.0;
166 testStrange = 0.0;
167 }
168
169 // Remove target particle from list
170
171 fsTypes.erase(fsTypes.begin());
172
173 // See if the incident particle changed type
174
175 G4int choose = -1;
176 for(G4int i=0; i < mult-1; ++i ) {
177 partType = fsTypes[i];
178 if (partType == pim) {
179 choose = i;
180 break;
181 }
182 }
183 if (choose == -1) {
184 incidentHasChanged = true;
185 choose = G4int(G4UniformRand()*(mult-1) );
186 partType = fsTypes[choose];
187 currentParticle.SetDefinition(particleDef[partType]);
188 }
189
190 fsTypes.erase(fsTypes.begin()+choose);
191
192 // Remaining particles are secondaries. Put them into vec.
193
194 G4ReactionProduct* rp(0);
195 for(G4int i=0; i < mult-2; ++i ) {
196 partType = fsTypes[i];
197 rp = new G4ReactionProduct();
198 rp->SetDefinition(particleDef[partType]);
199 (G4UniformRand() < 0.5) ? rp->SetSide(-1) : rp->SetSide(1);
200 if (partType > pim && partType < pro) rp->SetMayBeKilled(false); // kaons
201 vec.SetElement(vecLen++, rp);
202 }
203
204 // if (mult == 2 && !incidentHasChanged && !targetHasChanged)
205 // quasiElastic = true;
206
207 // Check conservation of charge, strangeness, baryon number
208
209 CheckQnums(vec, vecLen, currentParticle, targetParticle,
210 testCharge, testBaryon, testStrange);
211
212 return;
213}
@ isAlive
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
double mag() const
Hep3Vector vect() const
G4ParticleDefinition * GetDefinition() const
void SetElement(G4int anIndex, Type *anElement)
Definition: G4FastVector.hh:76
void Initialize(G4int items)
Definition: G4FastVector.hh:63
void SetStatusChange(G4HadFinalStateStatus aS)
void SetEnergyChange(G4double anEnergy)
void SetMomentumChange(const G4ThreeVector &aV)
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
G4double EvaporationEffects(G4double kineticEnergy)
Definition: G4Nucleus.cc:264
G4double Cinema(G4double kineticEnergy)
Definition: G4Nucleus.cc:368
G4DynamicParticle * ReturnTargetParticle() const
Definition: G4Nucleus.cc:227
void CheckQnums(G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen, G4ReactionProduct &currentParticle, G4ReactionProduct &targetParticle, G4double Q, G4double B, G4double S)
void CalculateMomenta(G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen, const G4HadProjectile *originalIncident, const G4DynamicParticle *originalTarget, G4ReactionProduct &modifiedOriginal, G4Nucleus &targetNucleus, G4ReactionProduct &currentParticle, G4ReactionProduct &targetParticle, G4bool &incidentHasChanged, G4bool &targetHasChanged, G4bool quasiElastic)
void SetUpChange(G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen, G4ReactionProduct &currentParticle, G4ReactionProduct &targetParticle, G4bool &incidentHasChanged)
G4ParticleDefinition * particleDef[18]
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)
G4int GetMultiplicityT32(G4double KE) const
G4int GetMultiplicityT12(G4double KE) const
std::vector< G4int > GetFSPartTypesForPimP(G4int mult, G4double KE) const
std::vector< G4int > GetFSPartTypesForPimN(G4int mult, G4double KE) const
void SetMomentum(const G4double x, const G4double y, const G4double z)
G4double GetKineticEnergy() const
G4ThreeVector GetMomentum() const
void SetSide(const G4int sid)
void SetKineticEnergy(const G4double en)
G4ParticleDefinition * GetDefinition() const
void SetDefinition(G4ParticleDefinition *aParticleDefinition)