Geant4  10.02.p01
G4ParticleHPEnAngCorrelation.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 // particle_hp -- source file
27 // J.P. Wellisch, Nov-1996
28 // A prototype of the low energy neutron transport model.
29 //
30 // 100413 Fix bug in incidence energy by T. Koi
31 //
32 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
33 //
35 #include "G4LorentzRotation.hh"
36 #include "G4LorentzVector.hh"
37 #include "G4RotationMatrix.hh"
38 #include "G4IonTable.hh"
39 
41 {
42  G4ReactionProduct * result = new G4ReactionProduct;
43 
44  // do we have an appropriate distribution
45  if(nProducts!=1) throw G4HadronicException(__FILE__, __LINE__, "More than one product in SampleOne");
46 
47  // get the result
48  G4ReactionProductVector * temp=0;
49  G4int i=0;
50 
51  G4int icounter=0;
52  G4int icounter_max=1024;
53  while(temp == 0) {
54  icounter++;
55  if ( icounter > icounter_max ) {
56  G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of " << __FILE__ << "." << G4endl;
57  break;
58  }
59  temp = theProducts[i++].Sample(anEnergy,1);
60  }
61 
62  // is the multiplicity correct
63  if(temp->size()!=1) throw G4HadronicException(__FILE__, __LINE__, "SampleOne: Yield not correct");
64 
65  // fill result
66  result = temp->operator[](0);
67 
68  // some garbage collection
69  delete temp;
70 
71  // return result
72  return result;
73 }
74 
76 {
78  G4int i;
80  G4ReactionProduct theCMS;
82 
83  if(frameFlag==2
84  || frameFlag==3) // Added for particle HP
85  {
86  // simplify and double check @
87  G4ThreeVector the3IncidentPart = fCache.Get().theProjectileRP->GetMomentum(); //theProjectileRP has value in LAB
88  G4double nEnergy = fCache.Get().theProjectileRP->GetTotalEnergy();
89  G4ThreeVector the3Target = fCache.Get().theTarget->GetMomentum(); //theTarget has value in LAB
90  G4double tEnergy = fCache.Get().theTarget->GetTotalEnergy();
91  G4double totE = nEnergy+tEnergy;
92  G4ThreeVector the3CMS = the3Target+the3IncidentPart;
93  theCMS.SetMomentum(the3CMS);
94  G4double cmsMom = std::sqrt(the3CMS*the3CMS);
95  G4double sqrts = std::sqrt((totE-cmsMom)*(totE+cmsMom));
96  theCMS.SetMass(sqrts);
97  theCMS.SetTotalEnergy(totE);
98  G4ReactionProduct aIncidentPart;
99  aIncidentPart.Lorentz(*fCache.Get().theProjectileRP, theCMS);
100  //TKDB 100413
101  //ENDF-6 Formats Manual ENDF-102
102  //CHAPTER 6. FILE 6: PRODUCT ENERGY-ANGLE DISTRIBUTIONS
103  //LCT Reference system for secondary energy and angle (incident energy is always given in the LAB system)
104  //anEnergy = aIncidentPart.GetKineticEnergy();
105  anEnergy = fCache.Get().theProjectileRP->GetKineticEnergy(); //should be same argumment of "anEnergy"
106 
107  G4LorentzVector Ptmp (aIncidentPart.GetMomentum(), aIncidentPart.GetTotalEnergy());
108 
109  toZ.rotateZ(-1*Ptmp.phi());
110  toZ.rotateY(-1*Ptmp.theta());
111  }
112  fCache.Get().theTotalMeanEnergy=0;
113  G4LorentzRotation toLab(toZ.inverse()); //toLab only change axis NOT to LAB system
114  //- get first number of particles, to check if sum of Z and N is not bigger than target values
115  std::vector<int> nParticles;
116  bool bNPOK = true;
117 //TKDB_PHP_150507
118 #ifdef PHP_AS_HP
119  G4int iTry(0);
120 #endif
121 //TKDB_PHP_150507
122  do {
123  G4int sumZ = 0;
124  G4int sumA = 0;
125  nParticles.clear();
126  for(i=0; i<nProducts; i++)
127  {
128  G4int massCode = G4int(theProducts[i].GetMassCode());
129  G4int nPart;
130  nPart = theProducts[i].GetMultiplicity(anEnergy);
131  sumZ += massCode/1000 * nPart;
132  sumA += massCode % 1000 * nPart;
133 #ifdef G4PHPDEBUG
134  if( getenv("G4ParticleHPDebug") ) G4cout << i << " G4ParticleHPEnAngCorrelation::MULTIPLICITY " << massCode << " sumZ " << sumZ << " sumA " << sumA << " NPART " << nPart << G4endl;
135 #endif
136  nParticles.push_back( nPart );
137  }
138  bNPOK = true;
139  double targetZ = fCache.Get().theTarget->GetDefinition()->GetAtomicNumber();
140  double targetA = fCache.Get().theTarget->GetDefinition()->GetAtomicMass();
141  targetZ += fCache.Get().theProjectileRP->GetDefinition()->GetAtomicNumber();
142  targetA += fCache.Get().theProjectileRP->GetDefinition()->GetAtomicMass();
143  if( bAdjustFinalState ) {
144  if ( (sumZ != targetZ || sumA != targetA ) &&
145  (sumZ > targetZ || sumA > targetA
146  || ! G4IonTable::GetIonTable()->GetIon ( int(targetZ - sumZ), (int)(targetA - sumA), 0.0 ) ) ){ // e.g. Z=3, A=2
147  bNPOK = false;
148  //nParticles.clear();
149 #ifdef G4PHPDEBUG
150  if( getenv("G4ParticleHPDebug") )
151  G4cerr << " WRONG MULTIPLICITY Z= " << sumZ
152  << " > " << targetZ
153  << " A= " << sumA
154  << " > " << targetA << G4endl;
155 #endif
156  }
157  }
158 //TKDB_PHP_150507
159 #ifdef PHP_AS_HP
160  iTry++;
161  if ( iTry > 1024 ) {
162  G4Exception("G4ParticleHPEnAngCorrelation::Sample",
163  "Warning",
164  JustWarning,
165  "Too many trials were done. Exiting current loop by force. You may have Probably, the result violating (baryon number) conservation law will be obtained.");
166  bNPOK=true;
167  }
168 #endif
169 //TKDB_PHP_150507
170 
171  }while(!bNPOK); // Loop checking, 11.05.2015, T. Koi
172 
173  for(i=0; i<nProducts; i++)
174  {
175  //- if( nParticles[i] == 0 ) continue;
176  it = theProducts[i].Sample(anEnergy,nParticles[i]);
178  // if( getenv("G4PHPTEST") ) G4cout << " EnAnG energy sampled " << it->operator[](0)->GetKineticEnergy() << " aMeanEnergy " << aMeanEnergy << G4endl; // GDEB
179  //if(aMeanEnergy>0)
180  //151120 TK Modified for solving reproducibility problem
181  //This change may have side effect.
182  if(aMeanEnergy>=0)
183  {
184  fCache.Get().theTotalMeanEnergy += aMeanEnergy;
185  }
186  else
187  {
188  fCache.Get().theTotalMeanEnergy = anEnergy/nProducts+theProducts[i].GetQValue();
189  }
190  if(it!=0)
191  {
192  for(unsigned int ii=0; ii<it->size(); ii++)
193  {
194  //if(!getenv("G4PHP_NO_LORENTZ_BOOST")) {
195  G4LorentzVector pTmp1 (it->operator[](ii)->GetMomentum(),
196  it->operator[](ii)->GetTotalEnergy());
197  pTmp1 = toLab*pTmp1;
198  if( getenv("G4PHPTEST") ) G4cout << " G4particleHPEnAngCorrelation COS THETA " << std::cos(it->operator[](ii)->GetMomentum().theta()) << G4endl;
199  it->operator[](ii)->SetMomentum(pTmp1.vect());
200  it->operator[](ii)->SetTotalEnergy(pTmp1.e());
201  if( getenv("G4PHPTEST") ) G4cout << " G4particleHPEnAngCorrelation COS THETA after toLab " << std::cos(it->operator[](ii)->GetMomentum().theta()) << G4endl;
202 
203  if(frameFlag==1) // target rest //TK 100413 should be LAB?
204  {
205  it->operator[](ii)->Lorentz(*(it->operator[](ii)), -1.*(*fCache.Get().theTarget)); //TK 100413 Is this really need?
206  }
207  else if(frameFlag==2 ) // CMS
208  {
209 #ifdef G4PHPDEBUG
210  if( getenv("G4ParticleHPDebug") )
211  G4cout <<"G4ParticleHPEnAngCorrelation: before Lorentz boost "<<
212  it->at(ii)->GetKineticEnergy()<<" "<<
213  it->at(ii)->GetMomentum()<<G4endl;
214 #endif
215  it->operator[](ii)->Lorentz(*(it->operator[](ii)), -1.*theCMS);
216 #ifdef G4PHPDEBUG
217  if( getenv("G4ParticleHPDebug") )
218  G4cout <<"G4ParticleHPEnAngCorrelation: after Lorentz boost "<<
219  it->at(ii)->GetKineticEnergy()<<" "<<
220  it->at(ii)->GetMomentum()<<G4endl;
221 #endif
222  }
223  //TK120515 migrate frameFlag (MF6 LCT) = 3
224  else if(frameFlag==3) // CMS A<=4 other LAB
225  {
226  if ( theProducts[i].GetMassCode() > 4 ) //Alpha AWP 3.96713
227  {
228  //LAB
229  it->operator[](ii)->Lorentz(*(it->operator[](ii)), -1.*(*fCache.Get().theTarget)); //TK 100413 Is this really need?
230 #ifdef G4PHPDEBUG
231  if( getenv("G4ParticleHPDebug") )
232  G4cout <<"G4ParticleHPEnAngCorrelation: after Lorentz boost "<<
233  it->at(ii)->GetKineticEnergy()<<" "<<
234  it->at(ii)->GetMomentum()<<G4endl;
235 #endif
236  }
237  else
238  {
239  //CMS
240  it->operator[](ii)->Lorentz(*(it->operator[](ii)), -1.*theCMS);
241 #ifdef G4PHPDEBUG
242  if( getenv("G4ParticleHPDebug") )
243  G4cout <<"G4ParticleHPEnAngCorrelation: after Lorentz boost "<<
244  it->at(ii)->GetKineticEnergy()<<" "<<
245  it->at(ii)->GetMomentum()<<G4endl;
246 #endif
247  }
248  }
249  else
250  {
251  throw G4HadronicException(__FILE__, __LINE__, "G4ParticleHPEnAngCorrelation::Sample: The frame of the finalstate is not specified");
252  }
253  if( getenv("G4PHPTEST") ) G4cout << frameFlag << " G4particleHPEnAngCorrelation COS THETA after Lorentz " << std::cos(it->operator[](ii)->GetMomentum().theta()) << G4endl;
254 
255  // }//getenv("G4PHP_NO_LORENTZ_BOOST"))
256  // G4cout << ii << " EnAnG energy after boost " << it->operator[](ii)->GetKineticEnergy() << G4endl; //GDEB
257  result->push_back(it->operator[](ii));
258  }
259  delete it;
260  }
261  }
262 
263  return result;
264 }
265 
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepLorentzRotation G4LorentzRotation
void SetMomentum(const G4double x, const G4double y, const G4double z)
G4double MeanEnergyOfThisInteraction()
int G4int
Definition: G4Types.hh:78
G4ReactionProductVector * Sample(G4double anEnergy)
std::vector< G4ReactionProduct * > G4ReactionProductVector
void SetMass(const G4double mas)
G4GLOB_DLL std::ostream G4cout
void SetTotalEnergy(const G4double en)
static G4IonTable * GetIonTable()
Definition: G4IonTable.hh:78
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4double GetTotalEnergy() const
G4int GetMultiplicity(G4double anEnergy)
G4ReactionProduct * SampleOne(G4double anEnergy)
G4ReactionProductVector * Sample(G4double anEnergy, G4int nParticles)
G4ThreeVector GetMomentum() const
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4GLOB_DLL std::ostream G4cerr
CLHEP::HepLorentzVector G4LorentzVector