Geant4  10.01.p02
G4ParticleHPCaptureFS.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 // neutron_hp -- source file
27 // J.P. Wellisch, Nov-1996
28 // A prototype of the low energy neutron transport model.
29 //
30 // 12-April-06 Enable IC electron emissions T. Koi
31 // 26-January-07 Add G4NEUTRONHP_USE_ONLY_PHOTONEVAPORATION flag
32 // 081024 G4NucleiPropertiesTable:: to G4NucleiProperties::
33 // 101203 Bugzilla/Geant4 Problem 1155 Lack of residual in some case
34 // 110430 Temporary solution in the case of being MF6 final state in Capture reaction (MT102)
35 //
36 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
37 //
38 #include "G4ParticleHPCaptureFS.hh"
39 #include "G4ParticleHPManager.hh"
40 #include "G4PhysicalConstants.hh"
41 #include "G4SystemOfUnits.hh"
42 #include "G4Gamma.hh"
43 #include "G4ReactionProduct.hh"
44 #include "G4Nucleus.hh"
45 #include "G4PhotonEvaporation.hh"
46 #include "G4Fragment.hh"
47 #include "G4IonTable.hh"
48 #include "G4ParticleHPDataUsed.hh"
49 
51  {
52 
53  G4int i;
54  theResult.Clear();
55 // prepare neutron
56  G4double eKinetic = theTrack.GetKineticEnergy();
57  const G4HadProjectile *incidentParticle = &theTrack;
58  G4ReactionProduct theNeutron( const_cast<G4ParticleDefinition *>(incidentParticle->GetDefinition() ) );
59  theNeutron.SetMomentum( incidentParticle->Get4Momentum().vect() );
60  theNeutron.SetKineticEnergy( eKinetic );
61 
62 // prepare target
64  G4Nucleus aNucleus;
65  G4double eps = 0.0001;
66  if(targetMass<500*MeV)
67  targetMass = ( G4NucleiProperties::GetNuclearMass( static_cast<G4int>(theBaseA+eps) , static_cast<G4int>(theBaseZ+eps) )) /
69  G4ThreeVector neutronVelocity = 1./G4Neutron::Neutron()->GetPDGMass()*theNeutron.GetMomentum();
70  G4double temperature = theTrack.GetMaterial()->GetTemperature();
71  theTarget = aNucleus.GetBiasedThermalNucleus(targetMass, neutronVelocity, temperature);
72  theTarget.SetDefinition( G4IonTable::GetIonTable()->GetIon( G4int(theBaseZ), G4int(theBaseA) , 0.0 ) ); //TESTPHP
73 
74 // go to nucleus rest system
75  theNeutron.Lorentz(theNeutron, -1*theTarget);
76  eKinetic = theNeutron.GetKineticEnergy();
77 
78 // dice the photons
79 
80  G4ReactionProductVector * thePhotons = 0;
81  if ( HasFSData() && !getenv ( "G4NEUTRONHP_USE_ONLY_PHOTONEVAPORATION" ) )
82  {
83  //NDL has final state data
84  if ( hasExactMF6 )
85  {
86  theMF6FinalState.SetTarget(theTarget);
88  thePhotons = theMF6FinalState.Sample( eKinetic );
89  }
90  else
91  thePhotons = theFinalStatePhotons.GetPhotons(eKinetic);
92  }
93  else
94  {
95  //NDL does not have final state data or forced to use PhotoEvaporation model
96  G4ThreeVector aCMSMomentum = theNeutron.GetMomentum()+theTarget.GetMomentum();
97  G4LorentzVector p4(aCMSMomentum, theTarget.GetTotalEnergy() + theNeutron.GetTotalEnergy());
98  G4Fragment nucleus(static_cast<G4int>(theBaseA+1), static_cast<G4int>(theBaseZ) ,p4);
99  G4PhotonEvaporation photonEvaporation;
100  // T. K. add
101  photonEvaporation.SetICM( TRUE );
102  G4FragmentVector* products = photonEvaporation.BreakItUp(nucleus);
103  G4FragmentVector::iterator it;
104  thePhotons = new G4ReactionProductVector;
105  for(it=products->begin(); it!=products->end(); it++)
106  {
107  G4ReactionProduct * theOne = new G4ReactionProduct;
108  // T. K. add
109  if ( (*it)->GetParticleDefinition() != 0 )
110  theOne->SetDefinition( (*it)->GetParticleDefinition() );
111  else
112  theOne->SetDefinition( G4Gamma::Gamma() ); // this definiion will be over writen
113 
114  // T. K. comment out below line
115  //theOne->SetDefinition( G4Gamma::Gamma() );
116  G4IonTable* theTable = G4IonTable::GetIonTable();
117  if( (*it)->GetMomentum().mag() > 10*MeV ) theOne->SetDefinition( theTable->GetIon(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA+1), 0 ) );
118 
119  //if ( (*i)->GetExcitationEnergy() > 0 )
120  if ( (*it)->GetExcitationEnergy() > 1.0e-2*eV )
121  {
122  G4double ex = (*it)->GetExcitationEnergy();
123  G4ReactionProduct* aPhoton = new G4ReactionProduct;
124  aPhoton->SetDefinition( G4Gamma::Gamma() );
125  aPhoton->SetMomentum( (*it)->GetMomentum().vect().unit() * ex );
126  //aPhoton->SetTotalEnergy( ex ); //will be calculated from momentum
127  thePhotons->push_back(aPhoton);
128  }
129 
130  theOne->SetMomentum( (*it)->GetMomentum().vect() * ( (*it)->GetMomentum().t() - (*it)->GetExcitationEnergy() ) / (*it)->GetMomentum().t() ) ;
131  //theOne->SetTotalEnergy( (*i)->GetMomentum().t() - (*i)->GetExcitationEnergy() ); //will be calculated from momentum
132  thePhotons->push_back(theOne);
133  delete *it;
134  }
135  delete products;
136  }
137 
138 // add them to the final state
139 
140  G4int nPhotons = 0;
141  if(thePhotons!=0) nPhotons=thePhotons->size();
142 
144  if ( DoNotAdjustFinalState() ) {
145 //Make at least one photon
146 //101203 TK
147  if ( nPhotons == 0 )
148  {
149  G4ReactionProduct * theOne = new G4ReactionProduct;
150  theOne->SetDefinition( G4Gamma::Gamma() );
151  G4double theta = pi*G4UniformRand();
152  G4double phi = twopi*G4UniformRand();
153  G4double sinth = std::sin(theta);
154  G4ThreeVector direction( sinth*std::cos(phi), sinth*std::sin(phi), std::cos(theta) );
155  theOne->SetMomentum( direction ) ;
156  thePhotons->push_back(theOne);
157  nPhotons++; // 0 -> 1
158  }
159 //One photon case: energy set to Q-value
160 //101203 TK
161  //if ( nPhotons == 1 )
162  if ( nPhotons == 1 && thePhotons->operator[](0)->GetDefinition()->GetBaryonNumber() == 0 )
163  {
164  G4ThreeVector direction = thePhotons->operator[](0)->GetMomentum().unit();
165 
166  G4double Q = G4IonTable::GetIonTable()->GetIonMass(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA), 0) + G4Neutron::Neutron()->GetPDGMass()
167  - G4IonTable::GetIonTable()->GetIonMass(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA+1), 0);
168 
169  thePhotons->operator[](0)->SetMomentum( Q*direction );
170  }
171 //
172  }
173 
174  // back to lab system
175  for(i=0; i<nPhotons; i++)
176  {
177  thePhotons->operator[](i)->Lorentz(*(thePhotons->operator[](i)), theTarget);
178  }
179 
180  // Recoil, if only one gamma
181  //if (1==nPhotons)
182  if ( nPhotons == 1 && thePhotons->operator[](0)->GetDefinition()->GetBaryonNumber() == 0 )
183  {
184  G4DynamicParticle * theOne = new G4DynamicParticle;
186  ->GetIon(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA+1), 0);
187  theOne->SetDefinition(aRecoil);
188  // Now energy;
189  // Can be done slightly better @
190  G4ThreeVector aMomentum = theTrack.Get4Momentum().vect()
191  +theTarget.GetMomentum()
192  -thePhotons->operator[](0)->GetMomentum();
193 
194  //TKDB 140520
195  //G4ThreeVector theMomUnit = aMomentum.unit();
196  //G4double aKinEnergy = theTrack.GetKineticEnergy()
197  // +theTarget.GetKineticEnergy(); // gammas come from Q-value
198  //G4double theResMass = aRecoil->GetPDGMass();
199  //G4double theResE = aRecoil->GetPDGMass()+aKinEnergy;
200  //G4double theAbsMom = std::sqrt(theResE*theResE - theResMass*theResMass);
201  //G4ThreeVector theMomentum = theAbsMom*theMomUnit;
202  //theOne->SetMomentum(theMomentum);
203 
204  theOne->SetMomentum(aMomentum);
205  theResult.AddSecondary(theOne);
206  }
207 
208  // Now fill in the gammas.
209  for(i=0; i<nPhotons; i++)
210  {
211  // back to lab system
212  G4DynamicParticle * theOne = new G4DynamicParticle;
213  theOne->SetDefinition(thePhotons->operator[](i)->GetDefinition());
214  theOne->SetMomentum(thePhotons->operator[](i)->GetMomentum());
215  theResult.AddSecondary(theOne);
216  delete thePhotons->operator[](i);
217  }
218  delete thePhotons;
219 
220 //101203TK
221  G4bool residual = false;
223  ->GetIon(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA+1), 0);
224  for ( G4int j = 0 ; j != theResult.GetNumberOfSecondaries() ; j++ )
225  {
226  if ( theResult.GetSecondary(j)->GetParticle()->GetDefinition() == aRecoil ) residual = true;
227  }
228 
229  if ( residual == false )
230  {
231  G4int nNonZero = 0;
232  G4LorentzVector p_photons(0,0,0,0);
233  for ( G4int j = 0 ; j != theResult.GetNumberOfSecondaries() ; j++ )
234  {
235  p_photons += theResult.GetSecondary(j)->GetParticle()->Get4Momentum();
236  // To many 0 momentum photons -> Check PhotonDist
237  if ( theResult.GetSecondary(j)->GetParticle()->Get4Momentum().e() > 0 ) nNonZero++;
238  }
239 
240  // Can we include kinetic energy here?
241  G4double deltaE = ( theTrack.Get4Momentum().e() + theTarget.GetTotalEnergy() )
242  - ( p_photons.e() + aRecoil->GetPDGMass() );
243 
244 //Add photons
245  if ( nPhotons - nNonZero > 0 )
246  {
247  //G4cout << "TKDB G4ParticleHPCaptureFS::ApplyYourself we will create additional " << nPhotons - nNonZero << " photons" << G4endl;
248  std::vector<G4double> vRand;
249  vRand.push_back( 0.0 );
250  for ( G4int j = 0 ; j != nPhotons - nNonZero - 1 ; j++ )
251  {
252  vRand.push_back( G4UniformRand() );
253  }
254  vRand.push_back( 1.0 );
255  std::sort( vRand.begin(), vRand.end() );
256 
257  std::vector<G4double> vEPhoton;
258  for ( G4int j = 0 ; j < (G4int)vRand.size() - 1 ; j++ )
259  {
260  vEPhoton.push_back( deltaE * ( vRand[j+1] - vRand[j] ) );
261  }
262  std::sort( vEPhoton.begin(), vEPhoton.end() );
263 
264  for ( G4int j = 0 ; j < nPhotons - nNonZero - 1 ; j++ )
265  {
266  //Isotopic in LAB OK?
267  G4double theta = pi*G4UniformRand();
268  G4double phi = twopi*G4UniformRand();
269  G4double sinth = std::sin(theta);
270  G4double en = vEPhoton[j];
271  G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
272 
273  p_photons += G4LorentzVector ( tempVector, tempVector.mag() );
274  G4DynamicParticle * theOne = new G4DynamicParticle;
275  theOne->SetDefinition( G4Gamma::Gamma() );
276  theOne->SetMomentum( tempVector );
277  theResult.AddSecondary(theOne);
278  }
279 
280 // Add last photon
281  G4DynamicParticle * theOne = new G4DynamicParticle;
282  theOne->SetDefinition( G4Gamma::Gamma() );
283 // For better momentum conservation
284  G4ThreeVector lastPhoton = -p_photons.vect().unit()*vEPhoton.back();
285  p_photons += G4LorentzVector( lastPhoton , lastPhoton.mag() );
286  theOne->SetMomentum( lastPhoton );
287  theResult.AddSecondary(theOne);
288  }
289 
290 //Add residual
291  G4DynamicParticle * theOne = new G4DynamicParticle;
292  G4ThreeVector aMomentum = theTrack.Get4Momentum().vect() + theTarget.GetMomentum()
293  - p_photons.vect();
294  theOne->SetDefinition(aRecoil);
295  theOne->SetMomentum( aMomentum );
296  theResult.AddSecondary(theOne);
297 
298  }
299 //101203TK END
300 
301 // clean up the primary neutron
303  return &theResult;
304  }
305 
306 #include <sstream>
308  {
309 
310  //TK110430 BEGIN
311  std::stringstream ss;
312  ss << static_cast<G4int>(Z);
313  G4String sZ;
314  ss >> sZ;
315  ss.clear();
316  ss << static_cast<G4int>(A);
317  G4String sA;
318  ss >> sA;
319 
320  ss.clear();
321  G4String sM;
322  if ( M > 0 )
323  {
324  ss << "m";
325  ss << M;
326  ss >> sM;
327  ss.clear();
328  }
329 
330  G4String element_name = theNames.GetName( static_cast<G4int>(Z)-1 );
331  G4String filenameMF6 = dirName+"/FSMF6/"+sZ+"_"+sA+sM+"_"+element_name;
332  //std::ifstream dummyIFS(filenameMF6, std::ios::in);
333  //if ( dummyIFS.good() == true ) hasExactMF6=true;
334  std::istringstream theData(std::ios::in);
335  G4ParticleHPManager::GetInstance()->GetDataStream(filenameMF6,theData);
336 
337  //TK110430 Only use MF6MT102 which has exactly same A and Z
338  //Even _nat_ do not select and there is no _nat_ case in ENDF-VII.0
339  if ( theData.good() == true ) {
340  hasExactMF6=true;
341  theMF6FinalState.Init(theData);
342  //theData.close();
343  return;
344  }
345  //TK110430 END
346 
347 
348  G4String tString = "/FS";
349  G4bool dbool;
350  G4ParticleHPDataUsed aFile = theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M, dirName, tString, dbool);
351 
352  G4String filename = aFile.GetName();
353  SetAZMs( A, Z, M, aFile );
354  //theBaseA = A;
355  //theBaseZ = G4int(Z+.5);
356  if(!dbool || ( Z<2.5 && ( std::abs(theBaseZ - Z)>0.0001 || std::abs(theBaseA - A)>0.0001)))
357  {
358  hasAnyData = false;
359  hasFSData = false;
360  hasXsec = false;
361  return;
362  }
363  //std::ifstream theData(filename, std::ios::in);
364  //std::istringstream theData(std::ios::in);
365  theData.clear();
366  G4ParticleHPManager::GetInstance()->GetDataStream(filename,theData);
368  if(hasFSData)
369  {
373  }
374  //theData.close();
375  }
static G4ParticleHPManager * GetInstance()
static const double MeV
Definition: G4SIunits.hh:193
static G4double GetNuclearMass(const G4double A, const G4double Z)
void SetMomentum(const G4ThreeVector &momentum)
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
G4HadSecondary * GetSecondary(size_t i)
CLHEP::Hep3Vector G4ThreeVector
void SetKineticEnergy(const G4double en)
void SetMomentum(const G4double x, const G4double y, const G4double z)
G4ParticleHPPhotonDist theFinalStatePhotons
void SetProjectileRP(G4ReactionProduct &aIncidentPart)
void Init(G4double A, G4double Z, G4int M, G4String &dirName, G4String &aFSType, G4ParticleDefinition *)
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:463
const G4double pi
G4ParticleHPEnAngCorrelation theMF6FinalState
void SetAZMs(G4double anA, G4double aZ, G4int aM, G4ParticleHPDataUsed used)
void GetDataStream(G4String, std::istringstream &iss)
G4HadFinalState * ApplyYourself(const G4HadProjectile &theTrack)
static const G4double eps
G4ParticleDefinition * GetDefinition() const
int G4int
Definition: G4Types.hh:78
G4ReactionProductVector * Sample(G4double anEnergy)
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void SetStatusChange(G4HadFinalStateStatus aS)
std::vector< G4ReactionProduct * > G4ReactionProductVector
G4ReactionProduct GetBiasedThermalNucleus(G4double aMass, G4ThreeVector aVelocity, G4double temp=-1) const
Definition: G4Nucleus.cc:108
#define G4UniformRand()
Definition: Randomize.hh:93
const G4ParticleDefinition * GetDefinition() const
G4bool InitMean(std::istream &aDataFile)
bool G4bool
Definition: G4Types.hh:79
G4double GetIonMass(G4int Z, G4int A, G4int L=0, G4int lvl=0) const
Definition: G4IonTable.cc:1249
G4double GetKineticEnergy() const
G4ErrorTarget * theTarget
Definition: errprop.cc:59
std::vector< G4Fragment * > G4FragmentVector
Definition: G4Fragment.hh:65
#define TRUE
Definition: globals.hh:55
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
static const G4double A[nN]
const G4LorentzVector & Get4Momentum() const
G4LorentzVector Get4Momentum() const
static G4IonTable * GetIonTable()
Definition: G4IonTable.hh:78
G4double GetKineticEnergy() const
static const double eV
Definition: G4SIunits.hh:194
G4double GetTotalEnergy() const
G4double GetPDGMass() const
G4DynamicParticle * GetParticle()
void SetTarget(G4ReactionProduct &aTarget)
G4ReactionProductVector * GetPhotons(G4double anEnergy)
G4ThreeVector GetMomentum() const
G4double GetTemperature() const
Definition: G4Material.hh:182
virtual G4FragmentVector * BreakItUp(const G4Fragment &nucleus)
G4ParticleHPDataUsed GetName(G4int A, G4int Z, G4String base, G4String rest, G4bool &active)
const G4Material * GetMaterial() const
void AddSecondary(G4DynamicParticle *aP, G4int mod=-1)
void InitEnergies(std::istream &aDataFile)
double G4double
Definition: G4Types.hh:76
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void InitAngular(std::istream &aDataFile)
G4int GetNumberOfSecondaries() const
void Init(std::istream &aDataFile)
CLHEP::HepLorentzVector G4LorentzVector