Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4ParticleHPElasticFS.cc
이 파일의 문서화 페이지로 가기
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 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
35 //
36 #include "G4ParticleHPElasticFS.hh"
37 #include "G4ParticleHPManager.hh"
38 
39 #include "G4PhysicalConstants.hh"
40 #include "G4SystemOfUnits.hh"
41 #include "G4ReactionProduct.hh"
42 #include "G4Nucleus.hh"
43 #include "G4Proton.hh"
44 #include "G4Deuteron.hh"
45 #include "G4Triton.hh"
46 #include "G4Alpha.hh"
47 #include "G4ThreeVector.hh"
48 #include "G4LorentzVector.hh"
49 #include "G4IonTable.hh"
50 #include "G4ParticleHPDataUsed.hh"
51 #include "G4Pow.hh"
52 #include "zlib.h"
53 
55  {
56  G4String tString = "/FS";
57  G4bool dbool;
58  G4ParticleHPDataUsed aFile = theNames.GetName(static_cast<G4int>(A), static_cast<G4int>(Z), M, dirName, tString, dbool);
59  G4String filename = aFile.GetName();
60  SetAZMs( A, Z, M, aFile );
61  //theBaseA = aFile.GetA();
62  //theBaseZ = aFile.GetZ();
63  if(!dbool)
64  {
65  hasAnyData = false;
66  hasFSData = false;
67  hasXsec = false;
68  return;
69  }
70  //130205 For compressed data files
71  std::istringstream theData(std::ios::in);
73  //130205 END
74  theData >> repFlag >> targetMass >> frameFlag;
75  if(repFlag==1)
76  {
77  G4int nEnergy;
78  theData >> nEnergy;
81  G4double temp, energy;
82  G4int tempdep, nLegendre;
83  G4int i, ii;
84  for (i=0; i<nEnergy; i++)
85  {
86  theData >> temp >> energy >> tempdep >> nLegendre;
87  energy *=eV;
88  theCoefficients->Init(i, energy, nLegendre);
90  G4double coeff=0;
91  for(ii=0; ii<nLegendre; ii++)
92  {
93  // load legendre coefficients.
94  theData >> coeff;
95  theCoefficients->SetCoeff(i, ii+1, coeff); // @@@HPW@@@
96  }
97  }
98  }
99  else if (repFlag==2)
100  {
101  G4int nEnergy;
102  theData >> nEnergy;
103  theProbArray = new G4ParticleHPPartial(nEnergy, nEnergy);
105  G4double temp, energy;
106  G4int tempdep, nPoints;
107  for(G4int i=0; i<nEnergy; i++)
108  {
109  theData >> temp >> energy >> tempdep >> nPoints;
110  energy *= eV;
111  theProbArray->InitInterpolation(i, theData);
112  theProbArray->SetT(i, temp);
113  theProbArray->SetX(i, energy);
114  G4double prob, costh;
115  for(G4int ii=0; ii<nPoints; ii++)
116  {
117  // fill probability arrays.
118  theData >> costh >> prob;
119  theProbArray->SetX(i, ii, costh);
120  theProbArray->SetY(i, ii, prob);
121  }
122  theProbArray->DoneSetXY( i );
123  }
124  }
125  else if ( repFlag==3 )
126  {
127  G4int nEnergy_Legendre;
128  theData >> nEnergy_Legendre;
129  if ( nEnergy_Legendre <= 0 ) {
130  std::stringstream iss;
131  iss << "G4ParticleHPElasticFS::Init Data Error repFlag is 3 but nEnergy_Legendre <= 0";
132  iss << "Z, A and M of problematic file is " << theNDLDataZ << ", " << theNDLDataA << " and " << theNDLDataM << " respectively.";
133  throw G4HadronicException(__FILE__, __LINE__, iss.str() );
134  }
135  theCoefficients = new G4ParticleHPLegendreStore( nEnergy_Legendre );
137  G4double temp, energy;
138  G4int tempdep, nLegendre;
139  //G4int i, ii;
140  for ( G4int i = 0 ; i < nEnergy_Legendre ; i++ )
141  {
142  theData >> temp >> energy >> tempdep >> nLegendre;
143  energy *=eV;
144  theCoefficients->Init( i , energy , nLegendre );
145  theCoefficients->SetTemperature( i , temp );
146  G4double coeff = 0;
147  for (G4int ii = 0 ; ii < nLegendre ; ii++ )
148  {
149  // load legendre coefficients.
150  theData >> coeff;
151  theCoefficients->SetCoeff(i, ii+1, coeff); // @@@HPW@@@
152  }
153  }
154 
156 
157  G4int nEnergy_Prob;
158  theData >> nEnergy_Prob;
159  theProbArray = new G4ParticleHPPartial( nEnergy_Prob , nEnergy_Prob );
160  theProbArray->InitInterpolation( theData );
161  G4int nPoints;
162  for ( G4int i=0 ; i < nEnergy_Prob ; i++ )
163  {
164  theData >> temp >> energy >> tempdep >> nPoints;
165 
166  energy *= eV;
167 
168 // consistency check
169  if ( i == 0 )
170  //if ( energy != tE_of_repFlag3 ) //110620TK This is too tight for 32bit machines
171  if ( std::abs( energy - tE_of_repFlag3 ) / tE_of_repFlag3 > 1.0e-15 )
172  G4cout << "Warning Transition Energy of repFlag3 is not consistent." << G4endl;
173 
174  theProbArray->InitInterpolation( i , theData );
175  theProbArray->SetT( i , temp );
176  theProbArray->SetX( i , energy );
177  G4double prob, costh;
178  for( G4int ii = 0 ; ii < nPoints ; ii++ )
179  {
180  // fill probability arrays.
181  theData >> costh >> prob;
182  theProbArray->SetX( i , ii , costh );
183  theProbArray->SetY( i , ii , prob );
184  }
185  theProbArray->DoneSetXY( i );
186  }
187  }
188  else if (repFlag==0)
189  {
190  theData >> frameFlag;
191  }
192  else
193  {
194  G4cout << "unusable number for repFlag: repFlag="<<repFlag<<G4endl;
195  throw G4HadronicException(__FILE__, __LINE__, "G4ParticleHPElasticFS::Init -- unusable number for repFlag");
196  }
197  //130205 For compressed data files(theData changed from ifstream to istringstream)
198  //theData.close();
199  }
201  {
202 // G4cout << "G4ParticleHPElasticFS::ApplyYourself+"<<G4endl;
203  if ( theResult.Get() == NULL ) theResult.Put( new G4HadFinalState );
204  theResult.Get()->Clear();
205  G4double eKinetic = theTrack.GetKineticEnergy();
206  const G4HadProjectile *incidentParticle = &theTrack;
207  G4ReactionProduct theNeutron( const_cast<G4ParticleDefinition *>(incidentParticle->GetDefinition() ));
208  theNeutron.SetMomentum( incidentParticle->Get4Momentum().vect() );
209  theNeutron.SetKineticEnergy( eKinetic );
210 // G4cout << "G4ParticleHPElasticFS::ApplyYourself++"<<eKinetic<<" "<<G4endl;
211 // G4cout << "CMSVALUES 0 "<<theNeutron.GetTotalMomentum()<<G4endl;
212 
214  G4Nucleus aNucleus;
215  G4ThreeVector neuVelo = (1./incidentParticle->GetDefinition()->GetPDGMass())*theNeutron.GetMomentum();
216  theTarget = aNucleus.GetBiasedThermalNucleus( targetMass, neuVelo, theTrack.GetMaterial()->GetTemperature());
217  //t theTarget.SetDefinition( G4IonTable::GetIonTable()->GetIon( G4int(theBaseZ), G4int(theBaseA) , 0.0 ) ); //TESTPHP
218 // G4cout << "Nucleus-test"<<" "<<targetMass<<" ";
219 // G4cout << theTarget.GetMomentum().x()<<" ";
220 // G4cout << theTarget.GetMomentum().y()<<" ";
221 // G4cout << theTarget.GetMomentum().z()<<G4endl;
222 
223  // neutron and target defined as reaction products.
224 
225 // prepare lorentz-transformation to Lab.
226 
227  G4ThreeVector the3Neutron = theNeutron.GetMomentum();
228  G4double nEnergy = theNeutron.GetTotalEnergy();
229  G4ThreeVector the3Target = theTarget.GetMomentum();
230 // cout << "@@@" << the3Target<<G4endl;
231  G4double tEnergy = theTarget.GetTotalEnergy();
232  G4ReactionProduct theCMS;
233  G4double totE = nEnergy+tEnergy;
234  G4ThreeVector the3CMS = the3Target+the3Neutron;
235  theCMS.SetMomentum(the3CMS);
236  G4double cmsMom = std::sqrt(the3CMS*the3CMS);
237  G4double sqrts = std::sqrt((totE-cmsMom)*(totE+cmsMom));
238  theCMS.SetMass(sqrts);
239  theCMS.SetTotalEnergy(totE);
240 
241  // data come as fcn of n-energy in nuclear rest frame
242  G4ReactionProduct boosted;
243  boosted.Lorentz(theNeutron, theTarget);
244  eKinetic = boosted.GetKineticEnergy(); // get kinetic energy for scattering
245  G4double cosTh = -2;
246  if(repFlag == 1)
247  {
248  cosTh = theCoefficients->SampleElastic(eKinetic);
249  }
250 
251  else if (repFlag==2)
252  {
253  cosTh = theProbArray->Sample(eKinetic);
254  }
255  else if (repFlag==3)
256  {
257  if ( eKinetic <= tE_of_repFlag3 )
258  {
259  cosTh = theCoefficients->SampleElastic(eKinetic);
260  }
261  else
262  {
263  cosTh = theProbArray->Sample(eKinetic);
264  }
265  }
266  else if (repFlag==0)
267  {
268  cosTh = 2.*G4UniformRand()-1.;
269  }
270  else
271  {
272  G4cout << "unusable number for repFlag: repFlag="<<repFlag<<G4endl;
273  throw G4HadronicException(__FILE__, __LINE__, "G4ParticleHPElasticFS::Init -- unusable number for repFlag");
274  }
275  if(cosTh<-1.1) { return 0; }
276  G4double phi = twopi*G4UniformRand();
277  G4double theta = std::acos(cosTh);
278  G4double sinth = std::sin(theta);
279  if (frameFlag == 1) // final state data given in target rest frame.
280  {
281  // we have the scattering angle, now we need the energy, then do the
282  // boosting.
283  // relativistic elastic scattering energy angular correlation:
284  theNeutron.Lorentz(theNeutron, theTarget);
285  G4double e0 = theNeutron.GetTotalEnergy();
286  G4double p0 = theNeutron.GetTotalMomentum();
287  G4double mN = theNeutron.GetMass();
288  G4double mT = theTarget.GetMass();
289  G4double eE = e0+mT;
290  G4double ap = (mT+eE)*(mT-eE) + (p0+mN)*(p0-mN);
291  G4double a = 4*(eE+p0*cosTh)*(eE-p0*cosTh);
292  G4double b = 4*ap*p0*cosTh;
293  G4double c = (2.*eE*mN-ap)*(2.*eE*mN+ap);
294  G4double en = (-b+std::sqrt(b*b - 4*a*c) )/(2*a);
295  G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
296  theNeutron.SetMomentum(tempVector);
297  theNeutron.SetTotalEnergy(std::sqrt(en*en+theNeutron.GetMass()*theNeutron.GetMass()));
298  // first to lab
299  theNeutron.Lorentz(theNeutron, -1.*theTarget);
300  // now to CMS
301  theNeutron.Lorentz(theNeutron, theCMS);
302  theTarget.SetMomentum(-theNeutron.GetMomentum());
303  theTarget.SetTotalEnergy(theNeutron.GetTotalEnergy());
304  // and back to lab
305  theNeutron.Lorentz(theNeutron, -1.*theCMS);
306  theTarget.Lorentz(theTarget, -1.*theCMS);
307 //111005 Protection for not producing 0 kinetic energy target
308  if ( theNeutron.GetKineticEnergy() <= 0 ) theNeutron.SetTotalEnergy ( theNeutron.GetMass() * ( 1 + G4Pow::GetInstance()->powA( 10 , -15.65 ) ) );
309  if ( theTarget.GetKineticEnergy() <= 0 ) theTarget.SetTotalEnergy ( theTarget.GetMass() * ( 1 + G4Pow::GetInstance()->powA( 10 , -15.65 ) ) );
310  }
311  else if (frameFlag == 2) // CMS
312  {
313  theNeutron.Lorentz(theNeutron, theCMS);
314  theTarget.Lorentz(theTarget, theCMS);
315  G4double en = theNeutron.GetTotalMomentum(); // already in CMS.
316  G4ThreeVector cmsMom_tmp=theNeutron.GetMomentum(); // for neutron direction in CMS
317  G4double cms_theta=cmsMom_tmp.theta();
318  G4double cms_phi=cmsMom_tmp.phi();
319  G4ThreeVector tempVector;
320  tempVector.setX(std::cos(theta)*std::sin(cms_theta)*std::cos(cms_phi)
321  +std::sin(theta)*std::cos(phi)*std::cos(cms_theta)*std::cos(cms_phi)
322  -std::sin(theta)*std::sin(phi)*std::sin(cms_phi) );
323  tempVector.setY(std::cos(theta)*std::sin(cms_theta)*std::sin(cms_phi)
324  +std::sin(theta)*std::cos(phi)*std::cos(cms_theta)*std::sin(cms_phi)
325  +std::sin(theta)*std::sin(phi)*std::cos(cms_phi) );
326  tempVector.setZ(std::cos(theta)*std::cos(cms_theta)
327  -std::sin(theta)*std::cos(phi)*std::sin(cms_theta) );
328  tempVector *= en;
329  theNeutron.SetMomentum(tempVector);
330  theTarget.SetMomentum(-tempVector);
331  G4double tP = theTarget.GetTotalMomentum();
332  G4double tM = theTarget.GetMass();
333  theTarget.SetTotalEnergy(std::sqrt((tP+tM)*(tP+tM)-2.*tP*tM));
334 
335 /*
336 For debug purpose.
337 Same transformation G4ReactionProduct.Lorentz() by 4vectors
338 {
339 G4LorentzVector n4p = G4LorentzVector ( theNeutron.GetMomentum() , theNeutron.GetKineticEnergy() + theNeutron.GetMass() );
340 G4cout << "before " << ( n4p.e() - n4p.m() ) / eV<< G4endl;
341 G4LorentzVector cm4p = G4LorentzVector ( theCMS.GetMomentum() , theCMS.GetKineticEnergy() + theCMS.GetMass() );
342 n4p.boost( cm4p.boostVector() );
343 G4cout << cm4p/eV << G4endl;
344 G4cout << "after " << ( n4p.e() - n4p.m() ) / eV<< G4endl;
345 }
346 */
347 
348  theNeutron.Lorentz(theNeutron, -1.*theCMS);
349 //080904 Add Protection for very low energy (1e-6eV) scattering
350  if ( theNeutron.GetKineticEnergy() <= 0 )
351  {
352  //theNeutron.SetMomentum( G4ThreeVector(0) );
353  //theNeutron.SetTotalEnergy ( theNeutron.GetMass() );
354 //110822 Protection for not producing 0 kinetic energy neutron
355  theNeutron.SetTotalEnergy ( theNeutron.GetMass() * ( 1 + G4Pow::GetInstance()->powA( 10 , -15.65 ) ) );
356  }
357 
358  theTarget.Lorentz(theTarget, -1.*theCMS);
359 //080904 Add Protection for very low energy (1e-6eV) scattering
360  if ( theTarget.GetKineticEnergy() < 0 )
361  {
362  //theTarget.SetMomentum( G4ThreeVector(0) );
363  //theTarget.SetTotalEnergy ( theTarget.GetMass() );
364 //110822 Protection for not producing 0 kinetic energy target
365  theTarget.SetTotalEnergy ( theTarget.GetMass() * ( 1 + G4Pow::GetInstance()->powA( 10 , -15.65 ) ) );
366  }
367  }
368  else
369  {
370  G4cout <<"Value of frameFlag (1=LAB, 2=CMS): "<<frameFlag;
371  throw G4HadronicException(__FILE__, __LINE__, "G4ParticleHPElasticFS::ApplyYourSelf frameflag incorrect");
372  }
373  // now all in Lab
374 // nun den recoil generieren...und energy change, momentum change angeben.
376  theResult.Get()->SetMomentumChange(theNeutron.GetMomentum().unit());
377  G4DynamicParticle* theRecoil = new G4DynamicParticle;
378  theRecoil->SetDefinition( G4IonTable::GetIonTable()->GetIon(static_cast<G4int>(theBaseZ), static_cast<G4int>(theBaseA), 0 ) );
379  theRecoil->SetMomentum(theTarget.GetMomentum());
380  theResult.Get()->AddSecondary(theRecoil);
381 // G4cout << "G4ParticleHPElasticFS::ApplyYourself 10+"<<G4endl;
382  // postpone the tracking of the primary neutron
384  return theResult.Get();
385  }
static G4ParticleHPManager * GetInstance()
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
static G4IonTable * GetIonTable()
Definition: G4IonTable.hh:78
void SetMomentumChange(const G4ThreeVector &aV)
void SetMomentum(const G4double x, const G4double y, const G4double z)
#define G4endl
Definition: G4ios.hh:61
void SetX(G4int i, G4double x)
void SetTemperature(G4int i, G4double temp)
G4ParticleHPLegendreStore * theCoefficients
void SetCoeff(G4int i, G4int l, G4double coeff)
void AddSecondary(G4DynamicParticle *aP, G4int mod=-1)
G4double Sample(G4double x)
G4double GetPDGMass() const
void setX(double)
double theta() const
void SetTotalEnergy(const G4double en)
void SetMass(const G4double mas)
Float_t Z
void SetEnergyChange(G4double anEnergy)
void GetDataStream(G4String, std::istringstream &iss)
G4double GetTotalEnergy() const
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
void SetKineticEnergy(const G4double en)
void SetAZMs(G4double anA, G4double aZ, G4int aM, G4ParticleHPDataUsed used)
G4double GetKineticEnergy() const
static G4Pow * GetInstance()
Definition: G4Pow.cc:57
const G4Material * GetMaterial() const
G4double powA(G4double A, G4double y) const
Definition: G4Pow.hh:242
void setZ(double)
G4Cache< G4HadFinalState * > theResult
#define G4UniformRand()
Definition: Randomize.hh:53
static constexpr double twopi
Definition: G4SIunits.hh:76
G4ErrorTarget * theTarget
Definition: errprop.cc:59
double energy
Definition: plottest35.C:25
G4double GetTotalMomentum() const
double A(double temperature)
void SetY(G4int i, G4int j, G4double y)
void Init(G4double A, G4double Z, G4int M, G4String &dirName, G4String &aFSType, G4ParticleDefinition *)
static constexpr double eV
Definition: G4SIunits.hh:215
value_type & Get() const
Definition: G4Cache.hh:314
G4ThreeVector GetMomentum() const
G4ParticleHPDataUsed GetName(G4int A, G4int Z, G4String base, G4String rest, G4bool &active)
void Put(const value_type &val) const
Definition: G4Cache.hh:318
const G4LorentzVector & Get4Momentum() const
Hep3Vector unit() const
G4double GetKineticEnergy() const
G4double GetMass() const
const G4ParticleDefinition * GetDefinition() const
void InitInterpolation(std::istream &aDataFile)
int G4int
Definition: G4Types.hh:78
double phi() const
ifstream in
Definition: comparison.C:7
G4ParticleHPPartial * theProbArray
void SetMomentum(const G4ThreeVector &momentum)
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
G4GLOB_DLL std::ostream G4cout
G4HadFinalState * ApplyYourself(const G4HadProjectile &theTrack)
Hep3Vector vect() const
G4double SampleElastic(G4double anEnergy)
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
void InitInterpolation(G4int i, std::istream &aDataFile)
G4ReactionProduct GetBiasedThermalNucleus(G4double aMass, G4ThreeVector aVelocity, G4double temp=-1) const
Definition: G4Nucleus.cc:113
void setY(double)
void SetT(G4int i, G4double x)
void Init(G4int i, G4double e, G4int n)
void SetStatusChange(G4HadFinalStateStatus aS)
G4double GetTemperature() const
Definition: G4Material.hh:183