Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4BertiniEvaporation.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 //
27 // Implementation of the HETC88 code into Geant4.
28 // Evaporation and De-excitation parts
29 // T. Lampen, Helsinki Institute of Physics, May-2000
30 
31 #include "globals.hh"
32 #include "G4BertiniEvaporation.hh"
33 #include "G4PhysicalConstants.hh"
34 #include "G4SystemOfUnits.hh"
35 #include "G4BENeutronChannel.hh"
36 #include "G4BEProtonChannel.hh"
37 #include "G4BEDeuteronChannel.hh"
38 #include "G4BETritonChannel.hh"
39 #include "G4BEHe3Channel.hh"
40 #include "G4BEHe4Channel.hh"
41 #include "G4BEGammaDeexcitation.hh"
42 
43 // verboseLevels : 4 inform about basic probabilities and branchings
44 // 6 some details about calculations
45 // 8 inform about final values
46 // 10 inform everything
47 
49 {
50  G4cout << "Info G4BertiniEvaporation: This is still very fresh code."<< G4endl;
51  G4cout << " G4BertiniEvaporation: feed-back for improvement is very wellcome."<< G4endl;
52  verboseLevel = 0;
53 
54  channelVector.push_back( new G4BENeutronChannel );
55  channelVector.push_back( new G4BEProtonChannel );
56  channelVector.push_back( new G4BEDeuteronChannel);
57  channelVector.push_back( new G4BETritonChannel );
58  channelVector.push_back( new G4BEHe3Channel );
59  channelVector.push_back( new G4BEHe4Channel );
60 }
61 
62 
64 {
65  while ( !channelVector.empty() )
66  {
67  delete channelVector.back();
68  channelVector.pop_back();
69  }
70 }
71 
72 
74 {
75  verboseLevel = verbose;
76 
77  // Update verbose level to all evaporation channels.
78  std::vector< G4BertiniEvaporationChannel * >::iterator iChannel = channelVector.begin();
79  for ( ; iChannel != channelVector.end() ; *iChannel++ )
80  ( *iChannel )->setVerboseLevel( verboseLevel );
81 }
82 
83 
85 {
86  G4int nucleusA;
87  G4int nucleusZ;
88  G4int i;
89  G4double totalProbability;
90  G4double excE;
91  G4double newExcitation;
92  G4double nucleusTotalMomentum;
93  G4double nucleusKineticEnergy;
94  G4double mRes; // Mass of residual nucleus.
95  G4ThreeVector nucleusMomentumVector;
96  G4DynamicParticle *pEmittedParticle;
97  std::vector< G4DynamicParticle * > secondaryParticleVector;
98  G4FragmentVector * result = new G4FragmentVector;
99 
100  // Read properties of the nucleus.
101  nucleusA = nucleus.GetA_asInt();
102  nucleusZ = nucleus.GetZ_asInt();
103  excE = nucleus.GetEnergyDeposit();
104  nucleusMomentumVector = nucleus.GetMomentum();
105 
106  // Move to CMS frame, save initial velocity of the nucleus to boostToLab vector.
107  G4ThreeVector boostToLab( ( 1/G4NucleiProperties::GetNuclearMass( nucleusA, nucleusZ ) )
108  * nucleusMomentumVector ); // xx mass ok?
109 
110  if ( verboseLevel >= 10 )
111  G4cout << " G4BertiniEvaporation : initial kinematics : boostToLab vector = " << boostToLab << G4endl
112  << " excitation energy : " << excE<< G4endl;
113 
114  if ( nucleusA == 8 && nucleusZ == 4 )
115  {
116  splitBe8( excE, boostToLab, secondaryParticleVector );
117  fillResult( secondaryParticleVector, result);
118  return result;
119  }
120 
121  // Initialize evaporation channels and calculate sum of emission
122  // probabilities.
123  std::vector< G4BertiniEvaporationChannel * >::iterator iChannel = channelVector.begin();
124  totalProbability = 0;
125  for ( ; iChannel != channelVector.end() ; *iChannel++ )
126  {
127  ( *iChannel )->setNucleusA( nucleusA );
128  ( *iChannel )->setNucleusZ( nucleusZ );
129  ( *iChannel )->setExcitationEnergy( excE );
130  ( *iChannel )->setPairingCorrection( 1 );
131  ( *iChannel )->calculateProbability();
132  totalProbability += ( *iChannel )->getProbability();
133  }
134 
135  // If no evaporation process is possible, try without pairing energy.
136  if ( totalProbability == 0 )
137  {
138  if ( verboseLevel >= 4 )
139  G4cout << "G4BertiniEvaporation : no emission possible with pairing correction, trying without it" << G4endl;
140  for ( iChannel = channelVector.begin() ; iChannel != channelVector.end() ; *iChannel++ )
141  {
142  ( *iChannel )->setPairingCorrection(0);
143  ( *iChannel )->calculateProbability();
144  totalProbability += ( *iChannel )->getProbability();
145  }
146  if ( verboseLevel >= 4 )
147  G4cout << " probability without correction " << totalProbability << G4endl;
148 
149  }
150 
151  // Normal evaporation cycle follows.
152  // Particles are evaporated till all probabilities are zero.
153  while ( totalProbability > 0 )
154  {
155  G4BertiniEvaporationChannel *pSelectedChannel;
156 
157  // Sample active emission channel.
158  G4double sampledProbability = G4UniformRand() * totalProbability;
159  if ( verboseLevel >= 10 ) G4cout << " RandomProb : " << sampledProbability << G4endl;
160  for ( iChannel = channelVector.begin() ; iChannel != channelVector.end() ; *iChannel++ )
161  {
162  sampledProbability -= ( *iChannel )->getProbability();
163  if ( sampledProbability < 0 ) break;
164  }
165  pSelectedChannel = ( *iChannel );
166  if ( iChannel == channelVector.end() )
167  throw G4HadronicException(__FILE__, __LINE__, "G4BertiniEvaporation : Error while sampling evaporation particle" );
168 
169  if ( verboseLevel >= 4 )
170  G4cout << "G4BertiniEvaporation : particle " << pSelectedChannel->getName() << " selected " << G4endl;
171 
172  // Max 10 tries to get a physically acceptable particle energy
173  // in this emission channel.
174  i = 0;
175 
176  do
177  {
178  pEmittedParticle = pSelectedChannel->emit();
179  // This loop checks that particle with too large energy is not emitted.
180  // CMS frame is considered in this loop. Nonrelativistic treatment. xxx
181 
182 
183  const G4int zRes = nucleusZ - pSelectedChannel->getParticleZ();
184  const G4int aRes = nucleusA - pSelectedChannel->getParticleA();
185  // const G4double eBind = G4NucleiProperties::GetBindingEnergy( aRes, zRes ); // Binding energy of the nucleus.
186  mRes = G4NucleiProperties::GetNuclearMass( aRes, zRes ); // Mass of the target nucleus
187  // In HETC88:
188  // eBind = Z * (-0.78244) + A * 8.36755 - cameron ( A , Z );
189  // mRes = zRes * 938.79304 + ( aRes - zRes ) * 939.57548 - eBind;
190  // where cameron ( A, Z ) is the mass excess by Cameron, see Canadian Journal of Physics,
191  // vol. 35, 1957, p.1022
192 
193  nucleusTotalMomentum = pEmittedParticle->GetTotalMomentum(); // CMS frame
194  nucleusKineticEnergy = std::pow( nucleusTotalMomentum, 2 ) / ( 2 * mRes );
195  newExcitation = excE - pEmittedParticle->GetKineticEnergy() - nucleusKineticEnergy - pSelectedChannel->getQ();
196 
197  if ( verboseLevel >= 10)
198  G4cout << "G4BertiniEvaporation : Kinematics " << G4endl
199  << " part kinetic E in CMS = "
200  << pEmittedParticle->GetKineticEnergy() << G4endl
201  << " new excitation E = "
202  << newExcitation << G4endl;
203 
204  i++;
205  if ( !( newExcitation > 0 ) && i < 10) delete pEmittedParticle;
206  } while ( !( newExcitation > 0 ) && i < 10 );
207 
208  if ( i >= 10 )
209  {
210  // No appropriate particle energy found.
211  // Set probability of this channel to zero
212  // and try to sample another particle on the
213  // next round.
214  delete pEmittedParticle;
215 
216  if ( verboseLevel >= 4 )
217  G4cout << "G4BertiniEvaporation : No appropriate energy for particle "
218  << pSelectedChannel->getName() << " found." << G4endl;
219 
220  pSelectedChannel->setProbability( 0 );
221 
222  totalProbability = 0;
223  for ( ; iChannel != channelVector.end() ; *iChannel++ )
224  totalProbability += ( *iChannel )->getProbability();
225  } // Treatment of physically unacceptable particle ends.
226  else
227  {
228  // Good particle found.
229 
230  // Transform particle properties to lab frame and save it.
231  G4LorentzVector particleFourVector = pEmittedParticle->Get4Momentum();
232  G4LorentzVector nucleusFourVector( - pEmittedParticle->GetMomentum(), // CMS Frame.
233  nucleusKineticEnergy + mRes ); // Total energy.
234  particleFourVector.boost( boostToLab );
235  nucleusFourVector.boost( boostToLab );
236  G4DynamicParticle *pPartLab = new G4DynamicParticle( pEmittedParticle->GetDefinition(),
237  particleFourVector.e(), // Total energy
238  particleFourVector.vect() ); // momentum vector
239  secondaryParticleVector.push_back( pPartLab );
240 
241  // Update residual nucleus and boostToLab vector.
242  nucleusA = nucleusA - pSelectedChannel->getParticleA();
243  nucleusZ = nucleusZ - pSelectedChannel->getParticleZ();
244  excE = newExcitation;
245  boostToLab = G4ThreeVector ( ( 1/mRes ) * nucleusFourVector.vect() );
246 
247  if ( verboseLevel >= 10 )
248  G4cout << " particle mom in cms " << pEmittedParticle->GetMomentum() << G4endl
249  << " particle mom in cms " << pEmittedParticle->GetTotalMomentum() << G4endl
250  << " Etot in cms " << pEmittedParticle->GetTotalEnergy() << G4endl
251  << " Ekin in cms " << pEmittedParticle->GetKineticEnergy() << G4endl
252  << " particle mass " << pEmittedParticle->GetMass() << G4endl
253  << " boost vect " << boostToLab << G4endl
254  << " boosted 4v " << particleFourVector << G4endl
255  << " nucleus 4v " << nucleusFourVector << G4endl
256  << " nucl cm mom " << nucleusTotalMomentum << G4endl
257  << " particle k.e. in lab " << pPartLab->GetKineticEnergy() << G4endl
258  << " new boost vector " << boostToLab << G4endl;
259 
260  delete pEmittedParticle;
261 
262  // If the residual nucleus is Be8, split it.
263  if ( nucleusA == 8 && nucleusZ == 4 )
264  {
265  splitBe8( excE, boostToLab, secondaryParticleVector );
266  fillResult( secondaryParticleVector, result);
267  return result;
268  }
269 
270  // Update evaporation channels and
271  // total emission probability.
272  totalProbability = 0;
273  for ( iChannel = channelVector.begin() ; iChannel != channelVector.end() ; *iChannel++ )
274  {
275  ( *iChannel )->setNucleusA( nucleusA );
276  ( *iChannel )->setNucleusZ( nucleusZ );
277  ( *iChannel )->setExcitationEnergy( excE );
278  ( *iChannel )->calculateProbability();
279  totalProbability += ( *iChannel )->getProbability();
280  }
281  } // Treatment of physically acceptable particle ends.
282  } // End of evaporation cycle.
283 
284  // Gamma de-excitation.
285  G4BEGammaDeexcitation *pGammaChannel = new G4BEGammaDeexcitation;
286  pGammaChannel->setNucleusA( nucleusA );
287  pGammaChannel->setNucleusZ( nucleusZ );
288  pGammaChannel->setVerboseLevel( verboseLevel );
289  pGammaChannel->setExcitationEnergy( excE );
290 
291  // Emit equally sampled photons until all the excitation energy is
292  // used; the last photon gets the remaining de-excitation energy.
293  // Change of momentum of the nucleus is neglected.
294  G4double gammaEnergy;
295  G4double totalDeExcEnergy = 0;
296 
297  while ( excE > 0 )
298  {
299  pEmittedParticle = pGammaChannel->emit();
300  gammaEnergy = pEmittedParticle->GetKineticEnergy();
301 
302  if ( ( totalDeExcEnergy + gammaEnergy ) > excE )
303  {
304  // All the remaining energy is used here.
305  gammaEnergy = excE - totalDeExcEnergy;
306  excE = 0;
307  }
308 
309  totalDeExcEnergy += gammaEnergy;
310 
311  if ( verboseLevel >= 10 )
312  G4cout << " G4BertiniEvaporation : gamma de-excitation, g of " << gammaEnergy << " MeV " << G4endl;
313 
314  G4LorentzVector gammaFourVector( pEmittedParticle->GetMomentum(),
315  pEmittedParticle->GetKineticEnergy() );
316  gammaFourVector.boost( boostToLab );
317  pEmittedParticle->SetKineticEnergy( gammaFourVector.e() );
318  pEmittedParticle->SetMomentumDirection( gammaFourVector.vect().unit() );
319 
320  secondaryParticleVector.push_back( pEmittedParticle );
321 
322  }
323 
324  delete pGammaChannel;
325 
326  // Residual nucleus is not returned.
327 
328  fillResult( secondaryParticleVector, result);
329 
330  return result;
331 }
332 
333 
334 void G4BertiniEvaporation::splitBe8( const G4double E,
335  const G4ThreeVector boostToLab,
336  std::vector< G4DynamicParticle * > & secondaryParticleVector )
337 {
338  G4double kineticEnergy;
339  G4double u;
340  G4double v;
341  G4double w;
342  const G4double Be8DecayEnergy = 0.093 * MeV;
343 
344  if ( E <= 0 ) throw G4HadronicException(__FILE__, __LINE__, "G4BertiniEvaporation : excitation energy < 0 " );
345  if ( verboseLevel >= 4 ) G4cout << " Be8 split to 2 x He4" << G4endl;
346 
347  kineticEnergy = 0.5 * ( E + Be8DecayEnergy );
348 
349  // Create two alpha particles in CMS frame.
350  isotropicCosines( u , v , w );
351  G4ThreeVector momentumDirectionCMS( u, v, w );
352 
354  momentumDirectionCMS,
355  kineticEnergy );
357  -momentumDirectionCMS,
358  kineticEnergy );
359  G4LorentzVector fourVector1( pP1Cms->GetMomentum(),
360  pP1Cms->GetTotalEnergy() );
361  G4LorentzVector fourVector2( pP2Cms->GetMomentum(),
362  pP2Cms->GetTotalEnergy() );
363 
364  // Transform into lab frame by transforming the four vectors. Then
365  // add to the vector of secondary particles.
366  fourVector1.boost( boostToLab );
367  fourVector2.boost( boostToLab );
369  fourVector1.vect(),
370  fourVector1.e() );
372  fourVector2.vect(),
373  fourVector2.e() );
374  secondaryParticleVector.push_back( pP1Lab );
375  secondaryParticleVector.push_back( pP2Lab );
376 
377  delete pP1Cms;
378  delete pP2Cms;
379 
380  return;
381 }
382 
383 
384 void G4BertiniEvaporation::fillResult( std::vector<G4DynamicParticle *> secondaryParticleVector,
385  G4FragmentVector * aResult )
386 {
387  // Fill the vector pParticleChange with secondary particles stored in vector.
388  for ( size_t i = 0 ; i < secondaryParticleVector.size() ; i++ )
389  {
390  G4int aZ = static_cast<G4int> (secondaryParticleVector[i]->GetDefinition()->GetPDGCharge() );
391  G4int aA = static_cast<G4int> (secondaryParticleVector[i]->GetDefinition()->GetBaryonNumber());
392  G4LorentzVector aMomentum = secondaryParticleVector[i]->Get4Momentum();
393  if(aA>0)
394  {
395  aResult->push_back( new G4Fragment(aA, aZ, aMomentum) );
396  }
397  else
398  {
399  aResult->push_back( new G4Fragment(aMomentum, secondaryParticleVector[i]->GetDefinition()) );
400  }
401  }
402  return;
403 }
404 
405 
406 void G4BertiniEvaporation::isotropicCosines( G4double & u, G4double & v, G4double & w )
407 {
408  // Samples isotropic random direction cosines.
409  G4double CosTheta = 1.0 - 2.0 * G4UniformRand();
410  G4double SinTheta = std::sqrt( 1.0 - CosTheta * CosTheta );
411  G4double Phi = twopi * G4UniformRand();
412 
413  u = std::cos( Phi ) * SinTheta;
414  v = std::cos( Phi ) * CosTheta,
415  w = std::sin( Phi );
416 
417  return;
418 }