Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ExcitationHandler.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 // $Id: G4ExcitationHandler.cc 66934 2013-01-21 13:18:35Z vnivanch $
27 //
28 // Hadronic Process: Nuclear De-excitations
29 // by V. Lara (May 1998)
30 //
31 //
32 // Modified:
33 // 30 June 1998 by V. Lara:
34 // -Modified the Transform method for use G4ParticleTable and
35 // therefore G4IonTable. It makes possible to convert all kind
36 // of fragments (G4Fragment) produced in deexcitation to
37 // G4DynamicParticle
38 // -It uses default algorithms for:
39 // Evaporation: G4Evaporation
40 // MultiFragmentation: G4StatMF
41 // Fermi Breakup model: G4FermiBreakUp
42 // 24 Jul 2008 by M. A. Cortes Giraldo:
43 // -Max Z,A for Fermi Break-Up turns to 9,17 by default
44 // -BreakItUp() reorganised and bug in Evaporation loop fixed
45 // -Transform() optimised
46 // (September 2008) by J. M. Quesada. External choices have been added for :
47 // -inverse cross section option (default OPTxs=3)
48 // -superimposed Coulomb barrier (if useSICB is set true, by default it is false)
49 // September 2009 by J. M. Quesada:
50 // -according to Igor Pshenichnov, SMM will be applied (just in case) only once.
51 // 27 Nov 2009 by V.Ivanchenko:
52 // -cleanup the logic, reduce number internal vectors, fixed memory leak.
53 // 11 May 2010 by V.Ivanchenko:
54 // -FermiBreakUp activated, used integer Z and A, used BreakUpFragment method for
55 // final photon deexcitation; used check on adundance of a fragment, decay
56 // unstable fragments with A <5
57 // 22 March 2011 by V.Ivanchenko: general cleanup and addition of a condition:
58 // products of Fermi Break Up cannot be further deexcited by this model
59 // 30 March 2011 by V.Ivanchenko removed private inline methods, moved Set methods
60 // to the source
61 // 23 January 2012 by V.Ivanchenko general cleanup including destruction of
62 // objects, propagate G4PhotonEvaporation pointer to G4Evaporation class and
63 // not delete it here
64 
65 #include <list>
66 
67 #include "G4ExcitationHandler.hh"
68 #include "G4SystemOfUnits.hh"
69 #include "G4LorentzVector.hh"
70 #include "G4NistManager.hh"
71 #include "G4ParticleTable.hh"
72 #include "G4ParticleTypes.hh"
73 
74 #include "G4VMultiFragmentation.hh"
75 #include "G4VFermiBreakUp.hh"
76 #include "G4VFermiFragment.hh"
77 
78 #include "G4VEvaporation.hh"
79 #include "G4VEvaporationChannel.hh"
80 #include "G4VPhotonEvaporation.hh"
81 #include "G4Evaporation.hh"
82 #include "G4StatMF.hh"
83 #include "G4PhotonEvaporation.hh"
84 #include "G4FermiBreakUp.hh"
85 #include "G4FermiFragmentsPool.hh"
86 
88  maxZForFermiBreakUp(9),maxAForFermiBreakUp(17),minEForMultiFrag(4*GeV),
89  minExcitation(keV),OPTxs(3),useSICB(false),isEvapLocal(true)
90 {
91  theTableOfIons = G4ParticleTable::GetParticleTable()->GetIonTable();
92 
93  theMultiFragmentation = new G4StatMF;
94  theFermiModel = new G4FermiBreakUp;
95  thePhotonEvaporation = new G4PhotonEvaporation;
96  theEvaporation = new G4Evaporation(thePhotonEvaporation);
98  SetParameters();
99 }
100 
102 {
103  if(isEvapLocal) { delete theEvaporation; }
104  delete theMultiFragmentation;
105  delete theFermiModel;
106 }
107 
108 void G4ExcitationHandler::SetParameters()
109 {
110  //for inverse cross section choice
111  theEvaporation->SetOPTxs(OPTxs);
112  //for the choice of superimposed Coulomb Barrier for inverse cross sections
113  theEvaporation->UseSICB(useSICB);
114  theEvaporation->Initialise();
115 }
116 
118 G4ExcitationHandler::BreakItUp(const G4Fragment & theInitialState) const
119 {
120  //G4cout << "@@@@@@@@@@ Start G4Excitation Handler @@@@@@@@@@@@@" << G4endl;
121 
122  // Variables existing until end of method
123  G4Fragment * theInitialStatePtr = new G4Fragment(theInitialState);
124 
125  G4FragmentVector * theTempResult = 0; // pointer which receives temporal results
126  std::list<G4Fragment*> theEvapList; // list to apply Evaporation or Fermi Break-Up
127  std::list<G4Fragment*> thePhotoEvapList; // list to apply PhotonEvaporation
128  std::list<G4Fragment*> theResults; // list to store final result
129  //
130  //G4cout << theInitialState << G4endl;
131 
132  // Variables to describe the excited configuration
133  G4double exEnergy = theInitialState.GetExcitationEnergy();
134  G4int A = theInitialState.GetA_asInt();
135  G4int Z = theInitialState.GetZ_asInt();
136 
138 
139  // In case A <= 1 the fragment will not perform any nucleon emission
140  if (A <= 1)
141  {
142  theResults.push_back( theInitialStatePtr );
143  }
144  // check if a fragment is stable
145  else if(exEnergy < minExcitation && nist->GetIsotopeAbundance(Z, A) > 0.0)
146  {
147  theResults.push_back( theInitialStatePtr );
148  }
149  else
150  {
151  // JMQ 150909: first step in de-excitation is treated separately
152  // Fragments after the first step are stored in theEvapList
153  // Statistical Multifragmentation will take place only once
154  //
155  // move to evaporation loop
156  if((A<maxAForFermiBreakUp && Z<maxZForFermiBreakUp)
157  || exEnergy <= minEForMultiFrag*A)
158  {
159  theEvapList.push_back(theInitialStatePtr);
160  }
161  else
162  {
163  theTempResult = theMultiFragmentation->BreakItUp(theInitialState);
164  if(!theTempResult) { theEvapList.push_back(theInitialStatePtr); }
165  else {
166  size_t nsec = theTempResult->size();
167  if(0 == nsec) { theEvapList.push_back(theInitialStatePtr); }
168  else {
169  // secondary are produced
170  // Sort out secondary fragments
171  G4bool deletePrimary = true;
172  G4FragmentVector::iterator j;
173  for (j = theTempResult->begin(); j != theTempResult->end(); ++j) {
174  if((*j) == theInitialStatePtr) { deletePrimary = false; }
175  A = (*j)->GetA_asInt();
176 
177  // gamma, p, n
178  if(A <= 1) { theResults.push_back(*j); }
179 
180  // Analyse fragment A > 1
181  else {
182  G4double exEnergy1 = (*j)->GetExcitationEnergy();
183 
184  // cold fragments
185  if(exEnergy1 < minExcitation) {
186  Z = (*j)->GetZ_asInt();
187  if(nist->GetIsotopeAbundance(Z, A) > 0.0) {
188  theResults.push_back(*j); // stable fragment
189 
190  } else {
191 
192  // check if the cold fragment is from FBU pool
193  const G4VFermiFragment* ffrag = thePool->GetFragment(Z, A);
194  if(ffrag) {
195  if(ffrag->IsStable()) { theResults.push_back(*j); }
196  else { theEvapList.push_back(*j); }
197 
198  // cold fragment may be unstable
199  } else {
200  theEvapList.push_back(*j);
201  }
202  }
203 
204  // hot fragments are unstable
205  } else { theEvapList.push_back(*j); }
206  }
207  }
208  if( deletePrimary ) { delete theInitialStatePtr; }
209  }
210  delete theTempResult;
211  }
212  }
213  }
214  /*
215  G4cout << "## After first step " << theEvapList.size() << " for evap; "
216  << thePhotoEvapList.size() << " for photo-evap; "
217  << theResults.size() << " results. " << G4endl;
218  */
219  // -----------------------------------
220  // FermiBreakUp and De-excitation loop
221  // -----------------------------------
222 
223  std::list<G4Fragment*>::iterator iList;
224  for (iList = theEvapList.begin(); iList != theEvapList.end(); ++iList)
225  {
226  //G4cout << "Next evaporate: " << G4endl;
227  //G4cout << *iList << G4endl;
228  A = (*iList)->GetA_asInt();
229  Z = (*iList)->GetZ_asInt();
230 
231  // Fermi Break-Up
232  G4bool wasFBU = false;
233  if (A < maxAForFermiBreakUp && Z < maxZForFermiBreakUp)
234  {
235  theTempResult = theFermiModel->BreakItUp(*(*iList));
236  wasFBU = true;
237  // if initial fragment returned unchanged try to evaporate it
238  if(1 == theTempResult->size()) {
239  delete theTempResult;
240  theTempResult = theEvaporation->BreakItUp(*(*iList));
241  }
242  }
243  else // apply Evaporation in another case
244  {
245  theTempResult = theEvaporation->BreakItUp(*(*iList));
246  }
247 
248  G4bool deletePrimary = true;
249  size_t nsec = theTempResult->size();
250  //G4cout << "Nproducts= " << nsec << G4endl;
251 
252  // Sort out secondary fragments
253  if ( nsec > 0 ) {
254  G4FragmentVector::iterator j;
255  for (j = theTempResult->begin(); j != theTempResult->end(); ++j) {
256  if((*j) == (*iList)) { deletePrimary = false; }
257 
258  //G4cout << *j << G4endl;
259  A = (*j)->GetA_asInt();
260  exEnergy = (*j)->GetExcitationEnergy();
261 
262  if(A <= 1) { theResults.push_back(*j); } // gamma, p, n
263 
264  // evaporation is not possible
265  else if(1 == nsec) {
266  if(exEnergy < minExcitation) { theResults.push_back(*j); }
267  else { thePhotoEvapList.push_back(*j); }
268 
269  } else { // Analyse fragment
270 
271  // cold fragment
272  if(exEnergy < minExcitation) {
273  Z = (*j)->GetZ_asInt();
274 
275  // natural isotope
276  if(nist->GetIsotopeAbundance(Z, A) > 0.0) {
277  theResults.push_back(*j); // stable fragment
278 
279  } else {
280  const G4VFermiFragment* ffrag = thePool->GetFragment(Z, A);
281 
282  // isotope from FBU pool
283  if(ffrag) {
284  if(ffrag->IsStable()) { theResults.push_back(*j); }
285  else { theEvapList.push_back(*j); }
286 
287  // isotope may be unstable
288  } else {
289  theEvapList.push_back(*j);
290  }
291  }
292 
293  // hot fragment
294  } else if (wasFBU) {
295  thePhotoEvapList.push_back(*j); // FBU applied only once
296  } else {
297  theEvapList.push_back(*j);
298  }
299  }
300  }
301  }
302  if( deletePrimary ) { delete (*iList); }
303  delete theTempResult;
304  } // end of the loop over theEvapList
305 
306  //G4cout << "## After 2nd step " << theEvapList.size() << " was evap; "
307  // << thePhotoEvapList.size() << " for photo-evap; "
308  // << theResults.size() << " results. " << G4endl;
309 
310  // -----------------------
311  // Photon-Evaporation loop
312  // -----------------------
313 
314  // at this point only photon evaporation is possible
315  for(iList = thePhotoEvapList.begin(); iList != thePhotoEvapList.end(); ++iList)
316  {
317  //G4cout << "Next photon evaporate: " << thePhotonEvaporation << G4endl;
318  //G4cout << *iList << G4endl;
319  exEnergy = (*iList)->GetExcitationEnergy();
320 
321  // only hot fragments
322  if(exEnergy >= minExcitation) {
323  theTempResult = thePhotonEvaporation->BreakUpFragment(*iList);
324  size_t nsec = theTempResult->size();
325  //G4cout << "Nproducts= " << nsec << G4endl;
326 
327  // if there is a gamma emission then
328  if (nsec > 0)
329  {
330  G4FragmentVector::iterator j;
331  for (j = theTempResult->begin(); j != theTempResult->end(); ++j)
332  {
333  theResults.push_back(*j);
334  }
335  }
336  delete theTempResult;
337  }
338 
339  // priamry fragment is kept
340  theResults.push_back(*iList);
341 
342  } // end of photon-evaporation loop
343 
344  //G4cout << "## After 3d step " << theEvapList.size() << " was evap; "
345  // << thePhotoEvapList.size() << " was photo-evap; "
346  // << theResults.size() << " results. " << G4endl;
347 
348  G4ReactionProductVector * theReactionProductVector = new G4ReactionProductVector;
349 
350  // MAC (24/07/08)
351  // To optimise the storing speed, we reserve space in memory for the vector
352  theReactionProductVector->reserve( theResults.size() );
353 
354  G4int theFragmentA, theFragmentZ;
355 
356  std::list<G4Fragment*>::iterator i;
357  for (i = theResults.begin(); i != theResults.end(); ++i)
358  {
359  theFragmentA = (*i)->GetA_asInt();
360  theFragmentZ = (*i)->GetZ_asInt();
361  G4ParticleDefinition* theKindOfFragment = 0;
362  if (theFragmentA == 0) { // photon or e-
363  theKindOfFragment = (*i)->GetParticleDefinition();
364  } else if (theFragmentA == 1 && theFragmentZ == 0) { // neutron
365  theKindOfFragment = G4Neutron::NeutronDefinition();
366  } else if (theFragmentA == 1 && theFragmentZ == 1) { // proton
367  theKindOfFragment = G4Proton::ProtonDefinition();
368  } else if (theFragmentA == 2 && theFragmentZ == 1) { // deuteron
369  theKindOfFragment = G4Deuteron::DeuteronDefinition();
370  } else if (theFragmentA == 3 && theFragmentZ == 1) { // triton
371  theKindOfFragment = G4Triton::TritonDefinition();
372  } else if (theFragmentA == 3 && theFragmentZ == 2) { // helium3
373  theKindOfFragment = G4He3::He3Definition();
374  } else if (theFragmentA == 4 && theFragmentZ == 2) { // alpha
375  theKindOfFragment = G4Alpha::AlphaDefinition();;
376  } else {
377  theKindOfFragment =
378  theTableOfIons->GetIon(theFragmentZ,theFragmentA,0.0);
379  }
380  if (theKindOfFragment != 0)
381  {
382  G4ReactionProduct * theNew = new G4ReactionProduct(theKindOfFragment);
383  theNew->SetMomentum((*i)->GetMomentum().vect());
384  theNew->SetTotalEnergy((*i)->GetMomentum().e());
385  theNew->SetFormationTime((*i)->GetCreationTime());
386  theReactionProductVector->push_back(theNew);
387  }
388  delete (*i);
389  }
390 
391  return theReactionProductVector;
392 }
393 
395 {
396  if(ptr && ptr != theEvaporation) {
397  delete theEvaporation;
398  theEvaporation = ptr;
399  thePhotonEvaporation = ptr->GetPhotonEvaporation();
400  SetParameters();
401  isEvapLocal = false;
402  }
403 }
404 
405 void
407 {
408  if(ptr && ptr != theMultiFragmentation) {
409  delete theMultiFragmentation;
410  theMultiFragmentation = ptr;
411  }
412 }
413 
415 {
416  if(ptr && ptr != theFermiModel) {
417  delete theFermiModel;
418  theFermiModel = ptr;
419  }
420 }
421 
422 void
424 {
425  if(ptr && ptr != thePhotonEvaporation) {
426  thePhotonEvaporation = ptr;
427  theEvaporation->SetPhotonEvaporation(ptr);
428  }
429 }
430 
432 {
433  maxZForFermiBreakUp = aZ;
434 }
435 
437 {
438  maxAForFermiBreakUp = std::min(5,anA);
439 }
440 
442 {
445 }
446 
448 {
449  minEForMultiFrag = anE;
450 }