Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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//
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"
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;
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
194 G4ReactionProduct theTarget;
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/*
316For debug purpose.
317Same transformation G4ReactionProduct.Lorentz() by 4vectors
318{
319G4LorentzVector n4p = G4LorentzVector ( theNeutron.GetMomentum() , theNeutron.GetKineticEnergy() + theNeutron.GetMass() );
320G4cout << "before " << ( n4p.e() - n4p.m() ) / eV<< G4endl;
321G4LorentzVector cm4p = G4LorentzVector ( theCMS.GetMomentum() , theCMS.GetKineticEnergy() + theCMS.GetMass() );
322n4p.boost( cm4p.boostVector() );
323G4cout << cm4p/eV << G4endl;
324G4cout << "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
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 }
@ suspend
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
double phi() const
double theta() const
void setY(double)
void setZ(double)
void setX(double)
Hep3Vector vect() const
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void SetMomentum(const G4ThreeVector &momentum)
void SetStatusChange(G4HadFinalStateStatus aS)
void AddSecondary(G4DynamicParticle *aP)
void SetEnergyChange(G4double anEnergy)
void SetMomentumChange(const G4ThreeVector &aV)
const G4Material * GetMaterial() const
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
static G4He3 * He3()
Definition: G4He3.cc:94
G4double GetTemperature() const
Definition: G4Material.hh:181
void Init(G4double A, G4double Z, G4int M, G4String &dirName, G4String &aFSType)
G4HadFinalState * ApplyYourself(const G4HadProjectile &theTrack)
void SetAZMs(G4double anA, G4double aZ, G4int aM, G4NeutronHPDataUsed used)
void SetCoeff(G4int i, G4int l, G4double coeff)
void Init(G4int i, G4double e, G4int n)
void InitInterpolation(std::ifstream &aDataFile)
G4double SampleElastic(G4double anEnergy)
void SetTemperature(G4int i, G4double temp)
G4NeutronHPDataUsed GetName(G4int A, G4int Z, G4String base, G4String rest, G4bool &active)
void SetY(G4int i, G4int j, G4double y)
void InitInterpolation(G4int i, std::ifstream &aDataFile)
void SetT(G4int i, G4double x)
G4double Sample(G4double x)
void SetX(G4int i, G4double x)
G4ReactionProduct GetBiasedThermalNucleus(G4double aMass, G4ThreeVector aVelocity, G4double temp=-1) const
Definition: G4Nucleus.cc:108
static G4ParticleTable * GetParticleTable()
static G4Proton * Proton()
Definition: G4Proton.cc:93
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetTotalEnergy(const G4double en)
G4double GetTotalMomentum() const
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4ThreeVector GetMomentum() const
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
void SetKineticEnergy(const G4double en)
G4double GetMass() const
void SetMass(const G4double mas)
static G4Triton * Triton()
Definition: G4Triton.cc:95