Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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