Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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