Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4NeutronHPElasticFS.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 // 25-08-06 New Final State type (refFlag==3 , Legendre (Low Energy) + Probability (High Energy) )
31 // is added by T. KOI
32 // 080904 Add Protection for negative energy results in very low energy ( 1E-6 eV ) scattering by T. Koi
33 //
34 #include "G4NeutronHPElasticFS.hh"
35 #include "G4PhysicalConstants.hh"
36 #include "G4SystemOfUnits.hh"
37 #include "G4ReactionProduct.hh"
38 #include "G4Nucleus.hh"
39 #include "G4Proton.hh"
40 #include "G4Deuteron.hh"
41 #include "G4Triton.hh"
42 #include "G4Alpha.hh"
43 #include "G4ThreeVector.hh"
44 #include "G4LorentzVector.hh"
45 #include "G4ParticleTable.hh"
46 #include "G4NeutronHPDataUsed.hh"
47 
49  {
50  G4String tString = "/FS";
51  G4bool dbool;
52  G4NeutronHPDataUsed aFile = theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M, dirName, tString, dbool);
53  G4String filename = aFile.GetName();
54  SetAZMs( A, Z, M, aFile );
55  //theBaseA = aFile.GetA();
56  //theBaseZ = aFile.GetZ();
57  if(!dbool)
58  {
59  hasAnyData = false;
60  hasFSData = false;
61  hasXsec = false;
62  return;
63  }
64  std::ifstream theData(filename, std::ios::in);
65  theData >> repFlag >> targetMass >> frameFlag;
66  if(repFlag==1)
67  {
68  G4int nEnergy;
69  theData >> nEnergy;
70  theCoefficients = new G4NeutronHPLegendreStore(nEnergy);
71  theCoefficients->InitInterpolation(theData);
72  G4double temp, energy;
73  G4int tempdep, nLegendre;
74  G4int i, ii;
75  for (i=0; i<nEnergy; i++)
76  {
77  theData >> temp >> energy >> tempdep >> nLegendre;
78  energy *=eV;
79  theCoefficients->Init(i, energy, nLegendre);
80  theCoefficients->SetTemperature(i, temp);
81  G4double coeff=0;
82  for(ii=0; ii<nLegendre; ii++)
83  {
84  // load legendre coefficients.
85  theData >> coeff;
86  theCoefficients->SetCoeff(i, ii+1, coeff); // @@@HPW@@@
87  }
88  }
89  }
90  else if (repFlag==2)
91  {
92  G4int nEnergy;
93  theData >> nEnergy;
94  theProbArray = new G4NeutronHPPartial(nEnergy, nEnergy);
95  theProbArray->InitInterpolation(theData);
96  G4double temp, energy;
97  G4int tempdep, nPoints;
98  for(G4int i=0; i<nEnergy; i++)
99  {
100  theData >> temp >> energy >> tempdep >> nPoints;
101  energy *= eV;
102  theProbArray->InitInterpolation(i, theData);
103  theProbArray->SetT(i, temp);
104  theProbArray->SetX(i, energy);
105  G4double prob, costh;
106  for(G4int ii=0; ii<nPoints; ii++)
107  {
108  // fill probability arrays.
109  theData >> costh >> prob;
110  theProbArray->SetX(i, ii, costh);
111  theProbArray->SetY(i, ii, prob);
112  }
113  }
114  }
115  else if ( repFlag==3 )
116  {
117  G4int nEnergy_Legendre;
118  theData >> nEnergy_Legendre;
119  theCoefficients = new G4NeutronHPLegendreStore( nEnergy_Legendre );
120  theCoefficients->InitInterpolation( theData );
121  G4double temp, energy;
122  G4int tempdep, nLegendre;
123  //G4int i, ii;
124  for ( G4int i = 0 ; i < nEnergy_Legendre ; i++ )
125  {
126  theData >> temp >> energy >> tempdep >> nLegendre;
127  energy *=eV;
128  theCoefficients->Init( i , energy , nLegendre );
129  theCoefficients->SetTemperature( i , temp );
130  G4double coeff = 0;
131  for (G4int ii = 0 ; ii < nLegendre ; ii++ )
132  {
133  // load legendre coefficients.
134  theData >> coeff;
135  theCoefficients->SetCoeff(i, ii+1, coeff); // @@@HPW@@@
136  }
137  }
138 
139  tE_of_repFlag3 = energy;
140 
141  G4int nEnergy_Prob;
142  theData >> nEnergy_Prob;
143  theProbArray = new G4NeutronHPPartial( nEnergy_Prob , nEnergy_Prob );
144  theProbArray->InitInterpolation( theData );
145  G4int nPoints;
146  for ( G4int i=0 ; i < nEnergy_Prob ; i++ )
147  {
148  theData >> temp >> energy >> tempdep >> nPoints;
149 
150  energy *= eV;
151 
152 // consistency check
153  if ( i == 0 )
154  //if ( energy != tE_of_repFlag3 ) //110620TK This is too tight for 32bit machines
155  if ( std::abs( energy - tE_of_repFlag3 ) / tE_of_repFlag3 > 1.0e-15 )
156  G4cout << "Warning Transition Energy of repFlag3 is not consistent." << G4endl;
157 
158  theProbArray->InitInterpolation( i , theData );
159  theProbArray->SetT( i , temp );
160  theProbArray->SetX( i , energy );
161  G4double prob, costh;
162  for( G4int ii = 0 ; ii < nPoints ; ii++ )
163  {
164  // fill probability arrays.
165  theData >> costh >> prob;
166  theProbArray->SetX( i , ii , costh );
167  theProbArray->SetY( i , ii , prob );
168  }
169  }
170  }
171  else if (repFlag==0)
172  {
173  theData >> frameFlag;
174  }
175  else
176  {
177  G4cout << "unusable number for repFlag: repFlag="<<repFlag<<G4endl;
178  throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPElasticFS::Init -- unusable number for repFlag");
179  }
180  theData.close();
181  }
183  {
184 // G4cout << "G4NeutronHPElasticFS::ApplyYourself+"<<G4endl;
185  theResult.Clear();
186  G4double eKinetic = theTrack.GetKineticEnergy();
187  const G4HadProjectile *incidentParticle = &theTrack;
188  G4ReactionProduct theNeutron( const_cast<G4ParticleDefinition *>(incidentParticle->GetDefinition()) );
189  theNeutron.SetMomentum( incidentParticle->Get4Momentum().vect() );
190  theNeutron.SetKineticEnergy( eKinetic );
191 // G4cout << "G4NeutronHPElasticFS::ApplyYourself++"<<eKinetic<<" "<<G4endl;
192 // G4cout << "CMSVALUES 0 "<<theNeutron.GetTotalMomentum()<<G4endl;
193 
195  G4Nucleus aNucleus;
196  G4ThreeVector neuVelo = (1./incidentParticle->GetDefinition()->GetPDGMass())*theNeutron.GetMomentum();
197  theTarget = aNucleus.GetBiasedThermalNucleus( targetMass, neuVelo, theTrack.GetMaterial()->GetTemperature());
198 // G4cout << "Nucleus-test"<<" "<<targetMass<<" ";
199 // G4cout << theTarget.GetMomentum().x()<<" ";
200 // G4cout << theTarget.GetMomentum().y()<<" ";
201 // G4cout << theTarget.GetMomentum().z()<<G4endl;
202 
203  // neutron and target defined as reaction products.
204 
205 // prepare lorentz-transformation to Lab.
206 
207  G4ThreeVector the3Neutron = theNeutron.GetMomentum();
208  G4double nEnergy = theNeutron.GetTotalEnergy();
209  G4ThreeVector the3Target = theTarget.GetMomentum();
210 // cout << "@@@" << the3Target<<G4endl;
211  G4double tEnergy = theTarget.GetTotalEnergy();
212  G4ReactionProduct theCMS;
213  G4double totE = nEnergy+tEnergy;
214  G4ThreeVector the3CMS = the3Target+the3Neutron;
215  theCMS.SetMomentum(the3CMS);
216  G4double cmsMom = std::sqrt(the3CMS*the3CMS);
217  G4double sqrts = std::sqrt((totE-cmsMom)*(totE+cmsMom));
218  theCMS.SetMass(sqrts);
219  theCMS.SetTotalEnergy(totE);
220 
221  // data come as fcn of n-energy in nuclear rest frame
222  G4ReactionProduct boosted;
223  boosted.Lorentz(theNeutron, theTarget);
224  eKinetic = boosted.GetKineticEnergy(); // get kinetic energy for scattering
225  G4double cosTh = -2;
226  if(repFlag == 1)
227  {
228  cosTh = theCoefficients->SampleElastic(eKinetic);
229  }
230 
231  else if (repFlag==2)
232  {
233  cosTh = theProbArray->Sample(eKinetic);
234  }
235  else if (repFlag==3)
236  {
237  if ( eKinetic <= tE_of_repFlag3 )
238  {
239  cosTh = theCoefficients->SampleElastic(eKinetic);
240  }
241  else
242  {
243  cosTh = theProbArray->Sample(eKinetic);
244  }
245  }
246  else if (repFlag==0)
247  {
248  cosTh = 2.*G4UniformRand()-1.;
249  }
250  else
251  {
252  G4cout << "unusable number for repFlag: repFlag="<<repFlag<<G4endl;
253  throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPElasticFS::Init -- unusable number for repFlag");
254  }
255  if(cosTh<-1.1) { return 0; }
256  G4double phi = twopi*G4UniformRand();
257  G4double theta = std::acos(cosTh);
258  G4double sinth = std::sin(theta);
259  if (frameFlag == 1) // final state data given in target rest frame.
260  {
261  // we have the scattering angle, now we need the energy, then do the
262  // boosting.
263  // relativistic elastic scattering energy angular correlation:
264  theNeutron.Lorentz(theNeutron, theTarget);
265  G4double e0 = theNeutron.GetTotalEnergy();
266  G4double p0 = theNeutron.GetTotalMomentum();
267  G4double mN = theNeutron.GetMass();
268  G4double mT = theTarget.GetMass();
269  G4double eE = e0+mT;
270  G4double ap = (mT+eE)*(mT-eE) + (p0+mN)*(p0-mN);
271  G4double a = 4*(eE+p0*cosTh)*(eE-p0*cosTh);
272  G4double b = 4*ap*p0*cosTh;
273  G4double c = (2.*eE*mN-ap)*(2.*eE*mN+ap);
274  G4double en = (-b+std::sqrt(b*b - 4*a*c) )/(2*a);
275  G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
276  theNeutron.SetMomentum(tempVector);
277  theNeutron.SetTotalEnergy(std::sqrt(en*en+theNeutron.GetMass()*theNeutron.GetMass()));
278  // first to lab
279  theNeutron.Lorentz(theNeutron, -1.*theTarget);
280  // now to CMS
281  theNeutron.Lorentz(theNeutron, theCMS);
282  theTarget.SetMomentum(-theNeutron.GetMomentum());
283  theTarget.SetTotalEnergy(theNeutron.GetTotalEnergy());
284  // and back to lab
285  theNeutron.Lorentz(theNeutron, -1.*theCMS);
286  theTarget.Lorentz(theTarget, -1.*theCMS);
287 //111005 Protection for not producing 0 kinetic energy target
288  if ( theNeutron.GetKineticEnergy() <= 0 ) theNeutron.SetTotalEnergy ( theNeutron.GetMass() * ( 1 + std::pow( 10 , -15.65 ) ) );
289  if ( theTarget.GetKineticEnergy() <= 0 ) theTarget.SetTotalEnergy ( theTarget.GetMass() * ( 1 + std::pow( 10 , -15.65 ) ) );
290  }
291  else if (frameFlag == 2) // CMS
292  {
293  theNeutron.Lorentz(theNeutron, theCMS);
294  theTarget.Lorentz(theTarget, theCMS);
295  G4double en = theNeutron.GetTotalMomentum(); // already in CMS.
296  G4ThreeVector cmsMom_tmp=theNeutron.GetMomentum(); // for neutron direction in CMS
297  G4double cms_theta=cmsMom_tmp.theta();
298  G4double cms_phi=cmsMom_tmp.phi();
299  G4ThreeVector tempVector;
300  tempVector.setX(std::cos(theta)*std::sin(cms_theta)*std::cos(cms_phi)
301  +std::sin(theta)*std::cos(phi)*std::cos(cms_theta)*std::cos(cms_phi)
302  -std::sin(theta)*std::sin(phi)*std::sin(cms_phi) );
303  tempVector.setY(std::cos(theta)*std::sin(cms_theta)*std::sin(cms_phi)
304  +std::sin(theta)*std::cos(phi)*std::cos(cms_theta)*std::sin(cms_phi)
305  +std::sin(theta)*std::sin(phi)*std::cos(cms_phi) );
306  tempVector.setZ(std::cos(theta)*std::cos(cms_theta)
307  -std::sin(theta)*std::cos(phi)*std::sin(cms_theta) );
308  tempVector *= en;
309  theNeutron.SetMomentum(tempVector);
310  theTarget.SetMomentum(-tempVector);
311  G4double tP = theTarget.GetTotalMomentum();
312  G4double tM = theTarget.GetMass();
313  theTarget.SetTotalEnergy(std::sqrt((tP+tM)*(tP+tM)-2.*tP*tM));
314 
315 /*
316 For debug purpose.
317 Same transformation G4ReactionProduct.Lorentz() by 4vectors
318 {
319 G4LorentzVector n4p = G4LorentzVector ( theNeutron.GetMomentum() , theNeutron.GetKineticEnergy() + theNeutron.GetMass() );
320 G4cout << "before " << ( n4p.e() - n4p.m() ) / eV<< G4endl;
321 G4LorentzVector cm4p = G4LorentzVector ( theCMS.GetMomentum() , theCMS.GetKineticEnergy() + theCMS.GetMass() );
322 n4p.boost( cm4p.boostVector() );
323 G4cout << cm4p/eV << G4endl;
324 G4cout << "after " << ( n4p.e() - n4p.m() ) / eV<< G4endl;
325 }
326 */
327 
328  theNeutron.Lorentz(theNeutron, -1.*theCMS);
329 //080904 Add Protection for very low energy (1e-6eV) scattering
330  if ( theNeutron.GetKineticEnergy() <= 0 )
331  {
332  //theNeutron.SetMomentum( G4ThreeVector(0) );
333  //theNeutron.SetTotalEnergy ( theNeutron.GetMass() );
334 //110822 Protection for not producing 0 kinetic energy neutron
335  theNeutron.SetTotalEnergy ( theNeutron.GetMass() * ( 1 + std::pow( 10 , -15.65 ) ) );
336  }
337 
338  theTarget.Lorentz(theTarget, -1.*theCMS);
339 //080904 Add Protection for very low energy (1e-6eV) scattering
340  if ( theTarget.GetKineticEnergy() < 0 )
341  {
342  //theTarget.SetMomentum( G4ThreeVector(0) );
343  //theTarget.SetTotalEnergy ( theTarget.GetMass() );
344 //110822 Protection for not producing 0 kinetic energy target
345  theTarget.SetTotalEnergy ( theTarget.GetMass() * ( 1 + std::pow( 10 , -15.65 ) ) );
346  }
347  }
348  else
349  {
350  G4cout <<"Value of frameFlag (1=LAB, 2=CMS): "<<frameFlag;
351  throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPElasticFS::ApplyYourSelf frameflag incorrect");
352  }
353  // now all in Lab
354 // nun den recoil generieren...und energy change, momentum change angeben.
357  G4DynamicParticle* theRecoil = new G4DynamicParticle;
358  if(targetMass<4.5)
359  {
360  if(targetMass<1)
361  {
362  // proton
363  theRecoil->SetDefinition(G4Proton::Proton());
364  }
365  else if(targetMass<2 )
366  {
367  // deuteron
368  theRecoil->SetDefinition(G4Deuteron::Deuteron());
369  }
370  else if(targetMass<2.999 )
371  {
372  // 3He
373  theRecoil->SetDefinition(G4He3::He3());
374  }
375  else if(targetMass<3 )
376  {
377  // Triton
378  theRecoil->SetDefinition(G4Triton::Triton());
379  }
380  else
381  {
382  // alpha
383  theRecoil->SetDefinition(G4Alpha::Alpha());
384  }
385  }
386  else
387  {
389  ->FindIon(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA), 0, static_cast<G4int>(theBaseZ)));
390  }
391  theRecoil->SetMomentum(theTarget.GetMomentum());
392  theResult.AddSecondary(theRecoil);
393 // G4cout << "G4NeutronHPElasticFS::ApplyYourself 10+"<<G4endl;
394  // postpone the tracking of the primary neutron
396  return &theResult;
397  }