Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/particle_hp/src/G4ParticleHPAngular.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 // 070523 bug fix for G4FPE_DEBUG on by A. Howard ( and T. Koi)
 31 // 080612 bug fix contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #5
 32 // 110505 protection for object is created but not initialized
 33 // 110510 delete above protection with more coordinated work to other classes
 34 //
 35 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
 36 //
 37 #include "G4ParticleHPAngular.hh"
 38 
 39 #include "G4PhysicalConstants.hh"
 40 #include "G4SystemOfUnits.hh"
 41 
 42 void G4ParticleHPAngular::Init(std::istream& aDataFile)
 43 {
 44   //  G4cout << "here we are entering the Angular Init"<<G4endl;
 45   aDataFile >> theAngularDistributionType >> targetMass;
 46   aDataFile >> frameFlag;
 47   if (theAngularDistributionType == 0) {
 48     theIsoFlag = true;
 49   }
 50   else if (theAngularDistributionType == 1) {
 51     theIsoFlag = false;
 52     G4int nEnergy;
 53     aDataFile >> nEnergy;
 54     theCoefficients = new G4ParticleHPLegendreStore(nEnergy);
 55     theCoefficients->InitInterpolation(aDataFile);
 56     G4double temp, energy;
 57     G4int tempdep, nLegendre;
 58     G4int i, ii;
 59     for (i = 0; i < nEnergy; i++) {
 60       aDataFile >> temp >> energy >> tempdep >> nLegendre;
 61       energy *= eV;
 62       theCoefficients->Init(i, energy, nLegendre);
 63       theCoefficients->SetTemperature(i, temp);
 64       G4double coeff = 0;
 65       for (ii = 0; ii < nLegendre; ii++) {
 66         aDataFile >> coeff;
 67         theCoefficients->SetCoeff(i, ii + 1, coeff);
 68       }
 69     }
 70   }
 71   else if (theAngularDistributionType == 2) {
 72     theIsoFlag = false;
 73     G4int nEnergy;
 74     aDataFile >> nEnergy;
 75     theProbArray = new G4ParticleHPPartial(nEnergy, nEnergy);
 76     theProbArray->InitInterpolation(aDataFile);
 77     G4double temp, energy;
 78     G4int tempdep;
 79     for (G4int i = 0; i < nEnergy; i++) {
 80       aDataFile >> temp >> energy >> tempdep;
 81       energy *= eV;
 82       theProbArray->SetT(i, temp);
 83       theProbArray->SetX(i, energy);
 84       theProbArray->InitData(i, aDataFile);
 85     }
 86   }
 87   else {
 88     theIsoFlag = false;
 89     G4cout << "unknown distribution found for Angular: " << theAngularDistributionType << G4endl;
 90     throw G4HadronicException(__FILE__, __LINE__, "unknown distribution needs implementation!!!");
 91   }
 92 }
 93 
 94 void G4ParticleHPAngular::SampleAndUpdate(G4ReactionProduct& aHadron)
 95 {
 96   //********************************************************************
 97   // EMendoza -> sampling can be isotropic in LAB or in CMS
 98   /*
 99   if(theIsoFlag)
100   {
101 //  G4cout << "Angular result "<<aHadron.GetTotalMomentum()<<" ";
102 // @@@ add code for isotropic emission in CMS.
103       G4double costheta = 2.*G4UniformRand()-1;
104       G4double theta = std::acos(costheta);
105       G4double phi = twopi*G4UniformRand();
106       G4double sinth = std::sin(theta);
107       G4double en = aHadron.GetTotalMomentum();
108       G4ThreeVector temp(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
109       aHadron.SetMomentum( temp );
110       aHadron.Lorentz(aHadron, -1.*theTarget);
111   }
112   else
113   {
114   */
115   //********************************************************************
116   if (frameFlag == 1)  // LAB
117   {
118     G4double en = aHadron.GetTotalMomentum();
119     G4ReactionProduct boosted;
120     boosted.Lorentz(*fCache.Get().theProjectileRP, *fCache.Get().theTarget);
121     G4double kineticEnergy = boosted.GetKineticEnergy();
122     G4double cosTh = 0.0;
123     //********************************************************************
124     // EMendoza --> sampling can be also isotropic
125     /*
126     if(theAngularDistributionType == 1) cosTh = theCoefficients->SampleMax(kineticEnergy);
127     if(theAngularDistributionType == 2) cosTh = theProbArray->Sample(kineticEnergy);
128     */
129     //********************************************************************
130     if (theIsoFlag) {
131       cosTh = 2. * G4UniformRand() - 1;
132     }
133     else if (theAngularDistributionType == 1) {
134       cosTh = theCoefficients->SampleMax(kineticEnergy);
135     }
136     else if (theAngularDistributionType == 2) {
137       cosTh = theProbArray->Sample(kineticEnergy);
138     }
139     else {
140       G4cout << "unknown distribution found for Angular: " << theAngularDistributionType << G4endl;
141       throw G4HadronicException(__FILE__, __LINE__, "unknown distribution needs implementation!!!");
142     }
143     //********************************************************************
144     G4double theta = std::acos(cosTh);
145     G4double phi = twopi * G4UniformRand();
146     G4double sinth = std::sin(theta);
147     G4ThreeVector temp(en * sinth * std::cos(phi), en * sinth * std::sin(phi),
148                        en * std::cos(theta));
149     aHadron.SetMomentum(temp);
150   }
151   else if (frameFlag == 2)  // costh in CMS
152   {
153     G4ReactionProduct boostedN;
154     boostedN.Lorentz(*fCache.Get().theProjectileRP, *fCache.Get().theTarget);
155     G4double kineticEnergy = boostedN.GetKineticEnergy();
156 
157     G4double cosTh = 0.0;
158     //********************************************************************
159     // EMendoza --> sampling can be also isotropic
160     /*
161     if(theAngularDistributionType == 1) cosTh = theCoefficients->SampleMax(kineticEnergy);
162     if(theAngularDistributionType == 2) cosTh = theProbArray->Sample(kineticEnergy);
163     */
164     //********************************************************************
165     if (theIsoFlag) {
166       cosTh = 2. * G4UniformRand() - 1;
167     }
168     else if (theAngularDistributionType == 1) {
169       cosTh = theCoefficients->SampleMax(kineticEnergy);
170     }
171     else if (theAngularDistributionType == 2) {
172       cosTh = theProbArray->Sample(kineticEnergy);
173     }
174     else {
175       G4cout << "unknown distribution found for Angular: " << theAngularDistributionType << G4endl;
176       throw G4HadronicException(__FILE__, __LINE__, "unknown distribution needs implementation!!!");
177     }
178     //********************************************************************
179     // 080612TK bug fix contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern)
180     /*
181         if(theAngularDistributionType == 1) // LAB
182         {
183           G4double en = aHadron.GetTotalMomentum();
184           G4ReactionProduct boosted;
185           boosted.Lorentz(theProjectile, theTarget);
186           G4double kineticEnergy = boosted.GetKineticEnergy();
187           G4double cosTh = theCoefficients->SampleMax(kineticEnergy);
188           G4double theta = std::acos(cosTh);
189           G4double phi = twopi*G4UniformRand();
190           G4double sinth = std::sin(theta);
191           G4ThreeVector temp(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
192           aHadron.SetMomentum( temp );
193         }
194         else if(theAngularDistributionType == 2) // costh in CMS {
195         }
196     */
197 
198     //      G4ReactionProduct boostedN;
199     //      boostedN.Lorentz(theProjectile, theTarget);
200     //      G4double kineticEnergy = boostedN.GetKineticEnergy();
201     //      G4double cosTh = theProbArray->Sample(kineticEnergy);
202 
203     G4double theta = std::acos(cosTh);
204     G4double phi = twopi * G4UniformRand();
205     G4double sinth = std::sin(theta);
206 
207     G4ThreeVector temp(sinth * std::cos(phi), sinth * std::sin(phi), std::cos(theta));  // CMS
208 
209     // 080612TK bug fix contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #5
210     /*
211           G4double en = aHadron.GetTotalEnergy(); // Target rest
212 
213           // get trafo from Target rest frame to CMS
214           G4ReactionProduct boostedT;
215           boostedT.Lorentz(theTarget, theTarget);
216 
217           G4ThreeVector the3IncidentParticle = boostedN.GetMomentum();
218           G4double nEnergy = boostedN.GetTotalEnergy();
219           G4ThreeVector the3Target = boostedT.GetMomentum();
220           G4double tEnergy = boostedT.GetTotalEnergy();
221           G4double totE = nEnergy+tEnergy;
222           G4ThreeVector the3trafo = -the3Target-the3IncidentParticle;
223           G4ReactionProduct trafo; // for transformation from CMS to target rest frame
224           trafo.SetMomentum(the3trafo);
225           G4double cmsMom = std::sqrt(the3trafo*the3trafo);
226           G4double sqrts = std::sqrt((totE-cmsMom)*(totE+cmsMom));
227           trafo.SetMass(sqrts);
228           trafo.SetTotalEnergy(totE);
229 
230           G4double gamma = trafo.GetTotalEnergy()/trafo.GetMass();
231           G4double cosalpha = temp*trafo.GetMomentum()/trafo.GetTotalMomentum()/temp.mag();
232           G4double fac = cosalpha*trafo.GetTotalMomentum()/trafo.GetMass();
233           fac*=gamma;
234 
235           G4double mom;
236     //    For G4FPE_DEBUG ON
237           G4double mom2 = ( en*fac*en*fac -
238                        (fac*fac - gamma*gamma)*
239                        (en*en - gamma*gamma*aHadron.GetMass()*aHadron.GetMass())
240                     );
241           if ( mom2 > 0.0 )
242             mom = std::sqrt( mom2 );
243           else
244             mom = 0.0;
245 
246           mom = -en*fac - mom;
247           mom /= (fac*fac-gamma*gamma);
248           temp = mom*temp;
249 
250           aHadron.SetMomentum( temp ); // now all in CMS
251           aHadron.SetTotalEnergy( std::sqrt( mom*mom + aHadron.GetMass()*aHadron.GetMass() ) );
252           aHadron.Lorentz(aHadron, trafo); // now in target rest frame
253     */
254     // Determination of the hadron kinetic energy in CMS
255     // aHadron.GetKineticEnergy() is actually the residual kinetic energy in CMS (or target frame)
256     // kineticEnergy is incident neutron kinetic energy  in CMS (or target frame)
257     G4double QValue = aHadron.GetKineticEnergy() - kineticEnergy;
258     G4double A1 = fCache.Get().theTarget->GetMass() / boostedN.GetMass();
259     G4double A1prim = aHadron.GetMass() / boostedN.GetMass();
260     G4double kinE =
261       (A1 + 1 - A1prim) / (A1 + 1) / (A1 + 1) * (A1 * kineticEnergy + (1 + A1) * QValue);
262     G4double totalE = kinE + aHadron.GetMass();
263     G4double mom2 = totalE * totalE - aHadron.GetMass() * aHadron.GetMass();
264     G4double mom;
265     if (mom2 > 0.0)
266       mom = std::sqrt(mom2);
267     else
268       mom = 0.0;
269 
270     aHadron.SetMomentum(mom * temp);  // Set momentum in CMS
271     aHadron.SetKineticEnergy(kinE);  // Set kinetic energy in CMS
272 
273     // get trafo from Target rest frame to CMS
274     G4ReactionProduct boostedT;
275     boostedT.Lorentz(*fCache.Get().theTarget, *fCache.Get().theTarget);
276 
277     G4ThreeVector the3IncidentParticle = boostedN.GetMomentum();
278     G4double nEnergy = boostedN.GetTotalEnergy();
279     G4ThreeVector the3Target = boostedT.GetMomentum();
280     G4double tEnergy = boostedT.GetTotalEnergy();
281     G4double totE = nEnergy + tEnergy;
282     G4ThreeVector the3trafo = -the3Target - the3IncidentParticle;
283     G4ReactionProduct trafo;  // for transformation from CMS to target rest frame
284     trafo.SetMomentum(the3trafo);
285     G4double cmsMom = std::sqrt(the3trafo * the3trafo);
286     G4double sqrts = std::sqrt((totE - cmsMom) * (totE + cmsMom));
287     trafo.SetMass(sqrts);
288     trafo.SetTotalEnergy(totE);
289 
290     aHadron.Lorentz(aHadron, trafo);
291   }
292   else {
293     throw G4HadronicException(__FILE__, __LINE__, "Tried to sample non isotropic neutron angular");
294   }
295   aHadron.Lorentz(aHadron, -1. * (*fCache.Get().theTarget));
296   //  G4cout << aHadron.GetMomentum()<<" ";
297   //  G4cout << aHadron.GetTotalMomentum()<<G4endl;
298 }
299