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
G4TheoFSGenerator.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// G4TheoFSGenerator
29//
30// 20110307 M. Kelsey -- Add call to new theTransport->SetPrimaryProjectile()
31// to provide access to full initial state (for Bertini)
32// 20110805 M. Kelsey -- Follow change to G4V3DNucleus::GetNucleons()
33
34#include "G4DynamicParticle.hh"
35#include "G4TheoFSGenerator.hh"
37#include "G4ReactionProduct.hh"
38#include "G4IonTable.hh"
39
42 , theTransport(0), theHighEnergyGenerator(0)
43 , theQuasielastic(0), theProjectileDiffraction(0)
44 {
45 theParticleChange = new G4HadFinalState;
46}
47
49{
50 delete theParticleChange;
51}
52
53void G4TheoFSGenerator::ModelDescription(std::ostream& outFile) const
54{
55 outFile << GetModelName() <<" consists of a " << theHighEnergyGenerator->GetModelName()
56 << " string model and of "
57 << ".\n"
58 << "The string model simulates the interaction of\n"
59 << "an incident hadron with a nucleus, forming \n"
60 << "excited strings, decays these strings into hadrons,\n"
61 << "and leaves an excited nucleus.\n"
62 << "The string model:\n";
63 theHighEnergyGenerator->ModelDescription(outFile);
64//theTransport->IntraNuclearTransportDescription(outFile)
65}
66
67
69{
70 // init particle change
71 theParticleChange->Clear();
72 theParticleChange->SetStatusChange(stopAndKill);
73
74 // check if models have been registered, and use default, in case this is not true @@
75
76 // get result from high energy model
77 G4DynamicParticle aTemp(const_cast<G4ParticleDefinition *>(thePrimary.GetDefinition()),
78 thePrimary.Get4Momentum().vect());
79 const G4DynamicParticle * aPart = &aTemp;
80
81 if ( theQuasielastic ) {
82
83 if ( theQuasielastic->GetFraction(theNucleus, *aPart) > G4UniformRand() )
84 {
85 //G4cout<<"___G4TheoFSGenerator: before Scatter (1) QE=" << theQuasielastic<<G4endl;
86 G4KineticTrackVector *result= theQuasielastic->Scatter(theNucleus, *aPart);
87 //G4cout << "^^G4TheoFSGenerator: after Scatter (1) " << G4endl;
88 if (result)
89 {
90 for(unsigned int i=0; i<result->size(); i++)
91 {
92 G4DynamicParticle * aNew =
93 new G4DynamicParticle(result->operator[](i)->GetDefinition(),
94 result->operator[](i)->Get4Momentum().e(),
95 result->operator[](i)->Get4Momentum().vect());
96 theParticleChange->AddSecondary(aNew);
97 delete result->operator[](i);
98 }
99 delete result;
100
101 } else
102 {
103 theParticleChange->SetStatusChange(isAlive);
104 theParticleChange->SetEnergyChange(thePrimary.GetKineticEnergy());
105 theParticleChange->SetMomentumChange(thePrimary.Get4Momentum().vect().unit());
106
107 }
108 return theParticleChange;
109 }
110 }
111 if ( theProjectileDiffraction) {
112
113 if ( theProjectileDiffraction->GetFraction(theNucleus, *aPart) > G4UniformRand() )
114 // strictly, this returns fraction on inelastic, so quasielastic should
115 // already be substracted, ie. quasielastic should always be used
116 // before diffractive
117 {
118 //G4cout << "____G4TheoFSGenerator: before Scatter (2) " << G4endl;
119 G4KineticTrackVector *result= theProjectileDiffraction->Scatter(theNucleus, *aPart);
120 //G4cout << "^^^^G4TheoFSGenerator: after Scatter (2) " << G4endl;
121 if (result)
122 {
123 for(unsigned int i=0; i<result->size(); i++)
124 {
125 G4DynamicParticle * aNew =
126 new G4DynamicParticle(result->operator[](i)->GetDefinition(),
127 result->operator[](i)->Get4Momentum().e(),
128 result->operator[](i)->Get4Momentum().vect());
129 theParticleChange->AddSecondary(aNew);
130 delete result->operator[](i);
131 }
132 delete result;
133
134 } else
135 {
136 theParticleChange->SetStatusChange(isAlive);
137 theParticleChange->SetEnergyChange(thePrimary.GetKineticEnergy());
138 theParticleChange->SetMomentumChange(thePrimary.Get4Momentum().vect().unit());
139
140 }
141 return theParticleChange;
142 }
143 }
144 G4KineticTrackVector * theInitialResult =
145 theHighEnergyGenerator->Scatter(theNucleus, *aPart);
146
147//#define DEBUG_initial_result
148 #ifdef DEBUG_initial_result
149 G4double E_out(0);
151 std::vector<G4KineticTrack *>::iterator ir_iter;
152 for(ir_iter=theInitialResult->begin(); ir_iter!=theInitialResult->end(); ir_iter++)
153 {
154 //G4cout << "TheoFS secondary, mom " << (*ir_iter)->GetDefinition()->GetParticleName() << " " << (*ir_iter)->Get4Momentum() << G4endl;
155 E_out += (*ir_iter)->Get4Momentum().e();
156 }
157 G4double init_mass= ionTable->GetIonMass(theNucleus.GetZ_asInt(),theNucleus.GetA_asInt());
158 G4double init_E=aPart->Get4Momentum().e();
159 // residual nucleus
160 const std::vector<G4Nucleon> & thy = theHighEnergyGenerator->GetWoundedNucleus()->GetNucleons();
161 G4int resZ(0),resA(0);
162 G4double delta_m(0);
163 for(size_t them=0; them<thy.size(); them++)
164 {
165 if(thy[them].AreYouHit()) {
166 ++resA;
167 if ( thy[them].GetDefinition() == G4Proton::Proton() ) {
168 ++resZ;
169 delta_m +=G4Proton::Proton()->GetPDGMass();
170 } else {
171 delta_m +=G4Neutron::Neutron()->GetPDGMass();
172 }
173 }
174 }
175 G4double final_mass(0);
176 if ( theNucleus.GetA_asInt() ) {
177 final_mass=ionTable->GetIonMass(theNucleus.GetZ_asInt()-resZ,theNucleus.GetA_asInt()- resA);
178 }
179 G4double E_excit=init_mass + init_E - final_mass - E_out;
180 G4cout << " Corrected delta mass " << init_mass - final_mass - delta_m << G4endl;
181 G4cout << "initial E, mass = " << init_E << ", " << init_mass << G4endl;
182 G4cout << " final E, mass = " << E_out <<", " << final_mass << " excitation_E " << E_excit << G4endl;
183 #endif
184
185 G4ReactionProductVector * theTransportResult = NULL;
186 G4int hitCount = 0;
187 const std::vector<G4Nucleon>& they = theHighEnergyGenerator->GetWoundedNucleus()->GetNucleons();
188 for(size_t them=0; them<they.size(); them++)
189 {
190 if(they[them].AreYouHit()) hitCount ++;
191 }
192 if(hitCount != theHighEnergyGenerator->GetWoundedNucleus()->GetMassNumber() )
193 {
194 theTransport->SetPrimaryProjectile(thePrimary); // For Bertini Cascade
195 theTransportResult =
196 theTransport->Propagate(theInitialResult, theHighEnergyGenerator->GetWoundedNucleus());
197 if ( !theTransportResult ) {
198 G4cout << "G4TheoFSGenerator: null ptr from transport propagate " << G4endl;
199 throw G4HadronicException(__FILE__, __LINE__, "Null ptr from transport propagate");
200 }
201 }
202 else
203 {
204 theTransportResult = theDecay.Propagate(theInitialResult, theHighEnergyGenerator->GetWoundedNucleus());
205 if ( !theTransportResult ) {
206 G4cout << "G4TheoFSGenerator: null ptr from decay propagate " << G4endl;
207 throw G4HadronicException(__FILE__, __LINE__, "Null ptr from decay propagate");
208 }
209 }
210
211 // Fill particle change
212 unsigned int i;
213 for(i=0; i<theTransportResult->size(); i++)
214 {
215 G4DynamicParticle * aNew =
216 new G4DynamicParticle(theTransportResult->operator[](i)->GetDefinition(),
217 theTransportResult->operator[](i)->GetTotalEnergy(),
218 theTransportResult->operator[](i)->GetMomentum());
219 // @@@ - overkill? G4double newTime = theParticleChange->GetGlobalTime(theTransportResult->operator[](i)->GetFormationTime());
220 theParticleChange->AddSecondary(aNew);
221 delete theTransportResult->operator[](i);
222 }
223
224 // some garbage collection
225 delete theTransportResult;
226
227 // Done
228 return theParticleChange;
229}
230
231std::pair<G4double, G4double> G4TheoFSGenerator::GetEnergyMomentumCheckLevels() const
232{
233 if ( theHighEnergyGenerator ) {
234 return theHighEnergyGenerator->GetEnergyMomentumCheckLevels();
235 } else {
236 return std::pair<G4double, G4double>(DBL_MAX, DBL_MAX);
237 }
238}
@ isAlive
@ stopAndKill
std::vector< G4ReactionProduct * > G4ReactionProductVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
Hep3Vector vect() const
G4ReactionProductVector * Propagate(G4KineticTrackVector *theSecondaries, G4V3DNucleus *)
G4LorentzVector Get4Momentum() const
void SetStatusChange(G4HadFinalStateStatus aS)
void AddSecondary(G4DynamicParticle *aP)
void SetEnergyChange(G4double anEnergy)
void SetMomentumChange(const G4ThreeVector &aV)
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
const G4String & GetModelName() const
G4double GetIonMass(G4int Z, G4int A, G4int L=0) const
!! Only ground states are supported now
Definition: G4IonTable.cc:774
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
static G4ParticleTable * GetParticleTable()
G4IonTable * GetIonTable()
G4double GetFraction(G4Nucleus &theNucleus, const G4DynamicParticle &thePrimary)
G4KineticTrackVector * Scatter(G4Nucleus &theNucleus, const G4DynamicParticle &thePrimary)
static G4Proton * Proton()
Definition: G4Proton.cc:93
G4KineticTrackVector * Scatter(G4Nucleus &theNucleus, const G4DynamicParticle &thePrimary)
G4double GetFraction(G4Nucleus &theNucleus, const G4DynamicParticle &thePrimary)
G4TheoFSGenerator(const G4String &name="TheoFSGenerator")
void ModelDescription(std::ostream &outFile) const
virtual std::pair< G4double, G4double > GetEnergyMomentumCheckLevels() const
G4HadFinalState * ApplyYourself(const G4HadProjectile &thePrimary, G4Nucleus &theNucleus)
virtual const std::vector< G4Nucleon > & GetNucleons()=0
virtual G4int GetMassNumber()=0
virtual G4String GetModelName() const
std::pair< G4double, G4double > GetEnergyMomentumCheckLevels() const
virtual void ModelDescription(std::ostream &) const
virtual G4V3DNucleus * GetWoundedNucleus() const =0
virtual G4KineticTrackVector * Scatter(const G4Nucleus &theNucleus, const G4DynamicParticle &thePrimary)=0
void SetPrimaryProjectile(const G4HadProjectile &aPrimary)
virtual G4ReactionProductVector * Propagate(G4KineticTrackVector *theSecondaries, G4V3DNucleus *theNucleus)=0
#define DBL_MAX
Definition: templates.hh:83