Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/pre_equilibrium/exciton_model/src/G4PreCompoundEmission.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 //
 27 // -------------------------------------------------------------------
 28 //
 29 // GEANT4 Class file
 30 //
 31 //
 32 // File name:     G4PreCompoundEmission
 33 //
 34 // Author:         V.Lara
 35 //
 36 // Modified:  
 37 // 15.01.2010 J.M.Quesada  added protection against unphysical values of parameter an 
 38 // 19.01.2010 V.Ivanchenko simplified computation of parameter an, sample cosTheta 
 39 //                         instead of theta; protect all calls to sqrt 
 40 // 20.08.2010 V.Ivanchenko added G4Pow and G4PreCompoundParameters pointers
 41 //                         use int Z and A and cleanup
 42 //
 43 
 44 #include "G4PreCompoundEmission.hh"
 45 #include "G4PhysicalConstants.hh"
 46 #include "G4SystemOfUnits.hh"
 47 #include "G4Pow.hh"
 48 #include "G4Exp.hh"
 49 #include "G4Log.hh"
 50 #include "Randomize.hh"
 51 #include "G4RandomDirection.hh"
 52 #include "G4PreCompoundEmissionFactory.hh"
 53 #include "G4HETCEmissionFactory.hh"
 54 #include "G4HadronicException.hh"
 55 #include "G4NuclearLevelData.hh"
 56 #include "G4DeexPrecoParameters.hh"
 57 #include "G4PhysicsModelCatalog.hh"
 58 
 59 
 60 G4PreCompoundEmission::G4PreCompoundEmission()
 61 {
 62   theFragmentsFactory = new G4PreCompoundEmissionFactory();
 63   theFragmentsVector = 
 64     new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector());
 65   g4calc = G4Pow::GetInstance();
 66   fNuclData = G4NuclearLevelData::GetInstance();
 67   G4DeexPrecoParameters* param = fNuclData->GetParameters();
 68   fFermiEnergy  = param->GetFermiEnergy();
 69   fUseAngularGenerator = param->UseAngularGen();
 70   fModelID = G4PhysicsModelCatalog::GetModelID("model_PRECO");
 71 }
 72 
 73 G4PreCompoundEmission::~G4PreCompoundEmission()
 74 {
 75   delete theFragmentsFactory; 
 76   delete theFragmentsVector; 
 77 }
 78 
 79 void G4PreCompoundEmission::SetDefaultModel()
 80 {
 81   if (theFragmentsFactory) { delete theFragmentsFactory; }
 82   theFragmentsFactory = new G4PreCompoundEmissionFactory();
 83   if (theFragmentsVector) {
 84     theFragmentsVector->SetVector(theFragmentsFactory->GetFragmentVector());
 85   } else {
 86     theFragmentsVector = 
 87       new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector());
 88   }
 89 }
 90 
 91 void G4PreCompoundEmission::SetHETCModel()
 92 {
 93   if (theFragmentsFactory) delete theFragmentsFactory;
 94   theFragmentsFactory = new G4HETCEmissionFactory();
 95   if (theFragmentsVector) {
 96     theFragmentsVector->SetVector(theFragmentsFactory->GetFragmentVector());
 97   } else {
 98     theFragmentsVector = 
 99       new G4PreCompoundFragmentVector(theFragmentsFactory->GetFragmentVector());
100   }
101 }
102 
103 G4ReactionProduct* 
104 G4PreCompoundEmission::PerformEmission(G4Fragment & aFragment)
105 {
106   // Choose a Fragment for emission
107   G4VPreCompoundFragment * thePreFragment =
108     theFragmentsVector->ChooseFragment();
109   if (thePreFragment == nullptr)
110     {
111       G4cout << "G4PreCompoundEmission::PerformEmission : "
112        << "I couldn't choose a fragment\n"
113        << "while trying to de-excite\n" 
114        << aFragment << G4endl;
115       throw G4HadronicException(__FILE__, __LINE__, "");
116     }
117 
118   //G4cout << "Chosen fragment: " << G4endl;
119   //G4cout << *thePreFragment << G4endl;
120 
121   // Kinetic Energy of emitted fragment
122   G4double kinEnergy = thePreFragment->SampleKineticEnergy(aFragment);
123   kinEnergy = std::max(kinEnergy, 0.0);
124   
125   // Calculate the fragment momentum (three vector)
126   if(fUseAngularGenerator) {
127     AngularDistribution(thePreFragment,aFragment,kinEnergy);
128   } else {
129     G4double pmag = 
130       std::sqrt(kinEnergy*(kinEnergy + 2.0*thePreFragment->GetNuclearMass()));
131     theFinalMomentum = pmag*G4RandomDirection();
132   }
133 
134   // Mass of emittef fragment
135   G4double EmittedMass = thePreFragment->GetNuclearMass();
136   // Now we can calculate the four momentum 
137   // both options are valid and give the same result but 2nd one is faster
138   G4LorentzVector Emitted4Momentum(theFinalMomentum,EmittedMass + kinEnergy);
139     
140   // Perform Lorentz boost
141   G4LorentzVector Rest4Momentum = aFragment.GetMomentum();
142   Emitted4Momentum.boost(Rest4Momentum.boostVector());  
143 
144   // Set emitted fragment momentum
145   thePreFragment->SetMomentum(Emitted4Momentum);  
146 
147   // NOW THE RESIDUAL NUCLEUS
148   // ------------------------
149 
150   Rest4Momentum -= Emitted4Momentum;
151     
152   // Update nucleus parameters:
153   // --------------------------
154 
155   // Z and A
156   aFragment.SetZandA_asInt(thePreFragment->GetRestZ(),
157          thePreFragment->GetRestA());
158     
159   // Number of excitons
160   aFragment.SetNumberOfParticles(aFragment.GetNumberOfParticles()-
161          thePreFragment->GetA());
162   // Number of charges
163   aFragment.SetNumberOfCharged(aFragment.GetNumberOfCharged()-
164              thePreFragment->GetZ());
165     
166   // Update nucleus momentum 
167   // A check on consistence of Z, A, and mass will be performed
168   aFragment.SetMomentum(Rest4Momentum);
169   
170   // Create a G4ReactionProduct 
171   G4ReactionProduct * MyRP = thePreFragment->GetReactionProduct();
172 
173   // Set the creator model ID
174   aFragment.SetCreatorModelID(fModelID);
175   if (MyRP != nullptr) MyRP->SetCreatorModelID(fModelID);
176 
177   return MyRP;
178 }
179 
180 void G4PreCompoundEmission::AngularDistribution(
181                             G4VPreCompoundFragment* thePreFragment,
182           const G4Fragment& aFragment,
183           G4double ekin) 
184 {
185   G4int p = aFragment.GetNumberOfParticles();
186   G4int h = aFragment.GetNumberOfHoles();
187   G4double U = aFragment.GetExcitationEnergy();
188 
189   // Emission particle separation energy
190   G4double Bemission = thePreFragment->GetBindingEnergy();
191   
192   G4double gg = (6.0/pi2)*fNuclData->GetLevelDensity(aFragment.GetZ_asInt(),
193                                                      aFragment.GetA_asInt(),U);
194   
195   // Average exciton energy relative to bottom of nuclear well
196   G4double Eav = 2*p*(p+1)/((p+h)*gg);
197   
198   // Excitation energy relative to the Fermi Level
199   G4double Uf = std::max(U - (p - h)*fFermiEnergy , 0.0);
200   //  G4double Uf = U - KineticEnergyOfEmittedFragment - Bemission;
201 
202   G4double w_num = rho(p+1, h, gg, Uf, fFermiEnergy);
203   G4double w_den = rho(p,   h, gg, Uf, fFermiEnergy);
204   if (w_num > 0.0 && w_den > 0.0)
205     {
206       Eav *= (w_num/w_den);
207       Eav += - Uf/(p+h) + fFermiEnergy;
208     }
209   else 
210     {
211       Eav = fFermiEnergy;
212     }
213   
214   // VI + JMQ 19/01/2010 update computation of the parameter an
215   //
216   G4double an = 0.0;
217   G4double Eeff = ekin + Bemission + fFermiEnergy;
218   if(ekin > DBL_MIN && Eeff > DBL_MIN) {
219 
220     G4double zeta = std::max(1.0,9.3/std::sqrt(ekin/CLHEP::MeV));
221   
222     // This should be the projectile energy. If I would know which is 
223     // the projectile (proton, neutron) I could remove the binding energy. 
224     // But, what happens if INC precedes precompound? This approximation
225     // seems to work well enough
226     G4double ProjEnergy = aFragment.GetExcitationEnergy();
227 
228     an = 3*std::sqrt((ProjEnergy+fFermiEnergy)*Eeff)/(zeta*Eav);
229 
230     G4int ne = aFragment.GetNumberOfExcitons() - 1;
231     if ( ne > 1 ) { an /= static_cast<G4double>(ne); }
232       
233     // protection of exponent
234     if ( an > 10. ) { an = 10.; }
235   }
236 
237   // sample cosine of theta and not theta as in old versions  
238   G4double random = G4UniformRand();
239   G4double cost;
240  
241   if(an < 0.1) { cost = 1. - 2*random; }
242   else {
243     G4double exp2an = G4Exp(-2*an);
244     cost = 1. + G4Log(1-random*(1-exp2an))/an;
245     if(cost > 1.) { cost = 1.; }
246     else if(cost < -1.) {cost = -1.; }
247   }  
248 
249   G4double phi = CLHEP::twopi*G4UniformRand();
250   
251   // Calculate the momentum magnitude of emitted fragment   
252   G4double pmag = 
253     std::sqrt(ekin*(ekin + 2.0*thePreFragment->GetNuclearMass()));
254   
255   G4double sint = std::sqrt((1.0-cost)*(1.0+cost));
256 
257   theFinalMomentum.set(pmag*std::cos(phi)*sint,pmag*std::sin(phi)*sint,
258            pmag*cost);
259 
260   // theta is the angle wrt the incident direction
261   G4ThreeVector theIncidentDirection = aFragment.GetMomentum().vect().unit();
262   theFinalMomentum.rotateUz(theIncidentDirection);
263 }
264 
265 G4double G4PreCompoundEmission::rho(G4int p, G4int h, G4double gg, 
266             G4double E, G4double Ef) const
267 { 
268   // 25.02.2010 V.Ivanchenko added more protections
269   G4double Aph = (p*p + h*h + p - 3.0*h)/(4.0*gg);
270   
271   if ( E - Aph < 0.0) { return 0.0; }
272   
273   G4double logConst = (p+h)*G4Log(gg) 
274     - g4calc->logfactorial(p+h-1) - g4calc->logfactorial(p) 
275     - g4calc->logfactorial(h);
276 
277   // initialise values using j=0
278 
279   G4double t1=1;
280   G4double t2=1;
281   G4double logt3 = (p+h-1) * G4Log(E-Aph) + logConst;
282   const G4double logmax = 200.;
283   if(logt3 > logmax) { logt3 = logmax; }
284   G4double tot = G4Exp( logt3 );
285 
286   // and now sum rest of terms
287   // 25.02.2010 V.Ivanchenko change while to for loop and cleanup 
288   G4double Eeff = E - Aph; 
289   for(G4int j=1; j<=h; ++j) 
290     {
291       Eeff -= Ef;
292       if(Eeff < 0.0) { break; }
293       t1 *= -1.;
294       t2 *= static_cast<G4double>(h+1-j)/static_cast<G4double>(j);
295       logt3 = (p+h-1) * G4Log( Eeff) + logConst;
296       if(logt3 > logmax) { logt3 = logmax; }
297       tot += t1*t2*G4Exp(logt3);
298     }
299         
300   return tot;
301 }
302