Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
41  : G4HadronicInteraction(name)
42  , theTransport(0), theHighEnergyGenerator(0)
43  , theQuasielastic(0), theProjectileDiffraction(0)
44  {
45  theParticleChange = new G4HadFinalState;
46 }
47 
49 {
50  delete theParticleChange;
51 }
52 
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 
231 std::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 }