Geant4-11
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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// Hadronic Process: Nuclear De-excitations
27// by V. Lara (May 1998)
28//
29//
30// Modified:
31// 30 June 1998 by V. Lara:
32// -Modified the Transform method for use G4ParticleTable and
33// therefore G4IonTable. It makes possible to convert all kind
34// of fragments (G4Fragment) produced in deexcitation to
35// G4DynamicParticle
36// -It uses default algorithms for:
37// Evaporation: G4Evaporation
38// MultiFragmentation: G4StatMF
39// Fermi Breakup model: G4FermiBreakUp
40// 24 Jul 2008 by M. A. Cortes Giraldo:
41// -Max Z,A for Fermi Break-Up turns to 9,17 by default
42// -BreakItUp() reorganised and bug in Evaporation loop fixed
43// -Transform() optimised
44// (September 2008) by J. M. Quesada. External choices have been added for :
45// -inverse cross section option (default OPTxs=3)
46// -superimposed Coulomb barrier (if useSICB is set true, by default it is false)
47// September 2009 by J. M. Quesada:
48// -according to Igor Pshenichnov, SMM will be applied (just in case) only once.
49// 27 Nov 2009 by V.Ivanchenko:
50// -cleanup the logic, reduce number internal vectors, fixed memory leak.
51// 11 May 2010 by V.Ivanchenko:
52// -FermiBreakUp activated, used integer Z and A, used BreakUpFragment method for
53// final photon deexcitation; used check on adundance of a fragment, decay
54// unstable fragments with A <5
55// 22 March 2011 by V.Ivanchenko: general cleanup and addition of a condition:
56// products of Fermi Break Up cannot be further deexcited by this model
57// 30 March 2011 by V.Ivanchenko removed private inline methods, moved Set methods
58// to the source
59// 23 January 2012 by V.Ivanchenko general cleanup including destruction of
60// objects, propagate G4PhotonEvaporation pointer to G4Evaporation class and
61// not delete it here
62
64#include "G4SystemOfUnits.hh"
65#include "G4LorentzVector.hh"
66#include "G4ParticleTable.hh"
67#include "G4ParticleTypes.hh"
68#include "G4Ions.hh"
69#include "G4Electron.hh"
70
72#include "G4VFermiBreakUp.hh"
73#include "G4Element.hh"
74#include "G4ElementTable.hh"
75
76#include "G4VEvaporation.hh"
78#include "G4Evaporation.hh"
80#include "G4StatMF.hh"
81#include "G4FermiBreakUpVI.hh"
82#include "G4NuclearLevelData.hh"
83#include "G4Pow.hh"
85
87 : icID(0),maxZForFermiBreakUp(9),maxAForFermiBreakUp(17),
88 fVerbose(1),fWarnings(0),minEForMultiFrag(1.*CLHEP::TeV),
89 minExcitation(1.*CLHEP::eV),maxExcitation(100.*CLHEP::MeV),
90 isInitialised(false),isEvapLocal(true),isActive(true)
91{
94
95 theMultiFragmentation = nullptr;
96 theFermiModel = nullptr;
97 theEvaporation = nullptr;
98 thePhotonEvaporation = nullptr;
99 theResults.reserve(60);
100 results.reserve(30);
101 theEvapList.reserve(30);
102
111
112 if(fVerbose > 1) { G4cout << "### New handler " << this << G4endl; }
113}
114
116{
118 delete theFermiModel;
119 if(isEvapLocal) { delete theEvaporation; }
120}
121
123{
125 auto param = ndata->GetParameters();
126 isActive = true;
127 // check if de-excitation is needed
128 if(fDummy == param->GetDeexChannelsType()) {
129 isActive = false;
130 } else {
131 // upload data for elements used in geometry
132 G4int Zmax = 20;
134 for(auto & elm : *table) { Zmax = std::max(Zmax, elm->GetZasInt()); }
135 ndata->UploadNuclearLevelData(Zmax+1);
136 }
137 minEForMultiFrag = param->GetMinExPerNucleounForMF();
138 minExcitation = param->GetMinExcitation();
139 maxExcitation = param->GetPrecoHighEnergy();
140 icID = G4PhysicsModelCatalog::GetModelID("model_e-InternalConversion");
141
142 // allowing local debug printout
143 fVerbose = std::max(fVerbose, param->GetVerbose());
144 if(isActive) {
146 if(!theEvaporation) {
148 }
151 }
153 if(fVerbose > 1) {
154 G4cout << "G4ExcitationHandler::SetParameters() done " << this << G4endl;
155 }
156}
157
159{
160 if(isInitialised) { return; }
161 if(fVerbose > 1) {
162 G4cout << "G4ExcitationHandler::Initialise() started " << this << G4endl;
163 }
164 G4DeexPrecoParameters* param =
166 isInitialised = true;
168 if(isActive) {
171 }
172 // dump level is controlled by parameter class
173 param->Dump();
174}
175
177{
178 if(ptr && ptr != theEvaporation) {
179 delete theEvaporation;
180 theEvaporation = ptr;
183 isEvapLocal = flag;
184 if(fVerbose > 1) {
185 G4cout << "G4ExcitationHandler::SetEvaporation() for " << this << G4endl;
186 }
187 }
188}
189
190void
192{
193 if(ptr && ptr != theMultiFragmentation) {
196 }
197}
198
200{
201 if(ptr && ptr != theFermiModel) {
202 delete theFermiModel;
203 theFermiModel = ptr;
205 }
206}
207
208void
210{
211 if(ptr && ptr != thePhotonEvaporation) {
215 if(fVerbose > 1) {
216 G4cout << "G4ExcitationHandler::SetPhotonEvaporation() " << ptr
217 << " for handler " << this << G4endl;
218 }
219 }
220}
221
223{
224 G4Evaporation* evap = static_cast<G4Evaporation*>(theEvaporation);
225 if(fVerbose > 1) {
226 G4cout << "G4ExcitationHandler::SetDeexChannelsType " << val
227 << " for " << this << G4endl;
228 }
229 if(val == fDummy) {
230 isActive = false;
231 return;
232 }
233 if(!evap) { return; }
234 if(val == fEvaporation) {
235 evap->SetDefaultChannel();
236 } else if(val == fCombined) {
237 evap->SetCombinedChannel();
238 } else if(val == fGEM) {
239 evap->SetGEMChannel();
240 } else if(val == fGEMVI) {
241 evap->SetGEMVIChannel();
242 }
243 evap->InitialiseChannels();
244 if(fVerbose > 1) {
246 G4cout << "Number of de-excitation channels is changed to: "
248 G4cout << " " << this;
249 }
250 G4cout << G4endl;
251 }
252}
253
255{
256 if(!theEvaporation) { SetParameters(); }
257 return theEvaporation;
258}
259
261{
264}
265
267{
268 if(!theFermiModel) { SetParameters(); }
269 return theFermiModel;
270}
271
273{
276}
277
280{
281 // Variables existing until end of method
282 G4Fragment * theInitialStatePtr = new G4Fragment(theInitialState);
283 if(fVerbose > 1) {
284 G4cout << "@@@@@@@@@@ Start G4Excitation Handler @@@@@@@@@@@@@ " << G4endl;
285 G4cout << theInitialState << G4endl;
286 }
287 if(!isInitialised) { Initialise(); }
288
289 // pointer to fragment vector which receives temporal results
290 G4FragmentVector * theTempResult = nullptr;
291
292 theResults.clear();
293 theEvapList.clear();
294
295 // Variables to describe the excited configuration
296 G4double exEnergy = theInitialState.GetExcitationEnergy();
297 G4int A = theInitialState.GetA_asInt();
298 G4int Z = theInitialState.GetZ_asInt();
299
300 // too much excitation
301 if(exEnergy > A*maxExcitation && A > 0) {
302 ++fWarnings;
303 if(fWarnings < 0) {
305 ed << "High excitation Fragment Z= " << Z << " A= " << A
306 << " Eex/A(MeV)= " << exEnergy/A;
307 G4Exception("G4ExcitationHandler::BreakItUp()","had0034",JustWarning,ed,"");
308 }
309 }
310
311 // In case A <= 1 the fragment will not perform any nucleon emission
312 if (A <= 1 || !isActive) {
313 theResults.push_back( theInitialStatePtr );
314
315 // check if a fragment is stable
316 } else if(exEnergy < minExcitation && nist->GetIsotopeAbundance(Z, A) > 0.0) {
317 theResults.push_back( theInitialStatePtr );
318
319 // JMQ 150909: first step in de-excitation is treated separately
320 // Fragments after the first step are stored in theEvapList
321 } else {
323 || exEnergy <= minEForMultiFrag*A) {
324 theEvapList.push_back(theInitialStatePtr);
325
326 // Statistical Multifragmentation will take place only once
327 } else {
328 theTempResult = theMultiFragmentation->BreakItUp(theInitialState);
329 if(!theTempResult) {
330 theEvapList.push_back(theInitialStatePtr);
331 } else {
332 size_t nsec = theTempResult->size();
333
334 // no fragmentation
335 if(0 == nsec) {
336 theEvapList.push_back(theInitialStatePtr);
337
338 // secondary are produced - sort out secondary fragments
339 } else {
340 G4bool deletePrimary = true;
341 for (auto ptr : *theTempResult) {
342 if(ptr == theInitialStatePtr) { deletePrimary = false; }
344 }
345 if( deletePrimary ) { delete theInitialStatePtr; }
346 }
347 delete theTempResult; // end multifragmentation
348 }
349 }
350 }
351 if(fVerbose > 2) {
352 G4cout << "## After first step of handler " << theEvapList.size()
353 << " for evap; "
354 << theResults.size() << " results. " << G4endl;
355 }
356 // -----------------------------------
357 // FermiBreakUp and De-excitation loop
358 // -----------------------------------
359
360 static const G4int countmax = 1000;
361 size_t kk;
362 for (kk=0; kk<theEvapList.size(); ++kk) {
363 G4Fragment* frag = theEvapList[kk];
364 if(fVerbose > 3) {
365 G4cout << "Next evaporate: " << G4endl;
366 G4cout << *frag << G4endl;
367 }
368 if(kk >= countmax) {
370 ed << "Infinite loop in the de-excitation module: " << kk
371 << " iterations \n"
372 << " Initial fragment: \n" << theInitialState
373 << "\n Current fragment: \n" << *frag;
374 G4Exception("G4ExcitationHandler::BreakItUp","had0333",FatalException,
375 ed,"Stop execution");
376
377 }
378 A = frag->GetA_asInt();
379 Z = frag->GetZ_asInt();
380 results.clear();
381 if(fVerbose > 2) {
382 G4cout << "G4ExcitationHandler# " << kk << " Z= " << Z << " A= " << A
383 << " Eex(MeV)= " << frag->GetExcitationEnergy() << G4endl;
384 }
385 // Fermi Break-Up
388 size_t nsec = results.size();
389 if(fVerbose > 2) { G4cout << "FermiBreakUp Nsec= " << nsec << G4endl; }
390
391 // FBU takes care to delete input fragment or add it to the results
392 // The secondary may be excited - photo-evaporation should be applied
393 if(1 < nsec) {
394 for(auto & res : results) {
396 }
397 continue;
398 }
399 // evaporation will be applied
400 }
401 // apply Evaporation, residual nucleus is always added to the results
402 // photon evaporation is possible
404 if(fVerbose > 3) {
405 G4cout << "Evaporation Nsec= " << results.size() << G4endl;
406 }
407 if(0 == results.size()) {
408 theResults.push_back(frag);
409 } else {
411 }
412
413 // Sort out secondary fragments
414 for (auto & res : results) {
415 if(fVerbose > 4) {
416 G4cout << "Evaporated product #" << *res << G4endl;
417 }
419 } // end of loop on secondary
420 } // end of the loop over theEvapList
421 if(fVerbose > 2) {
422 G4cout << "## After 2nd step of handler " << theEvapList.size()
423 << " was evap; "
424 << theResults.size() << " results. " << G4endl;
425 }
426 G4ReactionProductVector * theReactionProductVector =
428
429 // MAC (24/07/08)
430 // To optimise the storing speed, we reserve space
431 // in memory for the vector
432 theReactionProductVector->reserve( theResults.size() );
433
434 if(fVerbose > 2) {
435 G4cout << "### ExcitationHandler provides " << theResults.size()
436 << " evaporated products:" << G4endl;
437 }
438 for (auto & frag : theResults) {
439
440 // in the case of dummy de-excitation, excitation energy is transfered
441 // into kinetic energy of output ion
442 if(!isActive) {
443 G4double mass = frag->GetGroundStateMass();
444 G4double ptot = (frag->GetMomentum()).vect().mag();
445 G4double etot = (frag->GetMomentum()).e();
446 G4double fac = (etot <= mass || 0.0 == ptot) ? 0.0
447 : std::sqrt((etot - mass)*(etot + mass))/ptot;
448 G4LorentzVector lv((frag->GetMomentum()).px()*fac,
449 (frag->GetMomentum()).py()*fac,
450 (frag->GetMomentum()).pz()*fac, etot);
451 frag->SetMomentum(lv);
452 }
453 if(fVerbose > 3) {
454 G4cout << *frag;
455 if(frag->NuclearPolarization()) {
456 G4cout << " " << frag->NuclearPolarization();
457 }
458 G4cout << G4endl;
459 }
460
461 G4int fragmentA = frag->GetA_asInt();
462 G4int fragmentZ = frag->GetZ_asInt();
463 G4double etot= frag->GetMomentum().e();
464 G4double eexc = 0.0;
465 const G4ParticleDefinition* theKindOfFragment = nullptr;
466 if (fragmentA == 0) { // photon or e-
467 theKindOfFragment = frag->GetParticleDefinition();
468 } else if (fragmentA == 1 && fragmentZ == 0) { // neutron
469 theKindOfFragment = theNeutron;
470 } else if (fragmentA == 1 && fragmentZ == 1) { // proton
471 theKindOfFragment = theProton;
472 } else if (fragmentA == 2 && fragmentZ == 1) { // deuteron
473 theKindOfFragment = theDeuteron;
474 } else if (fragmentA == 3 && fragmentZ == 1) { // triton
475 theKindOfFragment = theTriton;
476 } else if (fragmentA == 3 && fragmentZ == 2) { // helium3
477 theKindOfFragment = theHe3;
478 } else if (fragmentA == 4 && fragmentZ == 2) { // alpha
479 theKindOfFragment = theAlpha;
480 } else {
481
482 // fragment
483 eexc = frag->GetExcitationEnergy();
484 G4int idxf = frag->GetFloatingLevelNumber();
485 if(eexc < minExcitation) {
486 eexc = 0.0;
487 idxf = 0;
488 }
489
490 theKindOfFragment = theTableOfIons->GetIon(fragmentZ,fragmentA,eexc,
492 if(fVerbose > 3) {
493 G4cout << "### EXCH: Find ion Z= " << fragmentZ
494 << " A= " << fragmentA
495 << " Eexc(MeV)= " << eexc/MeV << " idx= " << idxf
496 << G4endl;
497 }
498 }
499 // fragment identified
500 if(theKindOfFragment) {
501 G4ReactionProduct * theNew = new G4ReactionProduct(theKindOfFragment);
502 theNew->SetMomentum(frag->GetMomentum().vect());
503 theNew->SetTotalEnergy(etot);
504 theNew->SetFormationTime(frag->GetCreationTime());
505 if(theKindOfFragment == theElectron) {
506 theNew->SetCreatorModelID(icID);
507 } else {
508 theNew->SetCreatorModelID(frag->GetCreatorModelID());
509 }
510 theReactionProductVector->push_back(theNew);
511
512 // fragment not found out ground state is created
513 } else {
514 theKindOfFragment =
515 theTableOfIons->GetIon(fragmentZ,fragmentA,0.0,noFloat,0);
516 if(theKindOfFragment) {
517 G4ThreeVector mom(0.0,0.0,0.0);
518 G4double ionmass = theKindOfFragment->GetPDGMass();
519 if(etot <= ionmass) {
520 etot = ionmass;
521 } else {
522 G4double ptot = std::sqrt((etot - ionmass)*(etot + ionmass));
523 mom = (frag->GetMomentum().vect().unit())*ptot;
524 }
525 G4ReactionProduct * theNew = new G4ReactionProduct(theKindOfFragment);
526 theNew->SetMomentum(mom);
527 theNew->SetTotalEnergy(etot);
528 theNew->SetFormationTime(frag->GetCreationTime());
529 theNew->SetCreatorModelID(frag->GetCreatorModelID());
530 theReactionProductVector->push_back(theNew);
531 if(fVerbose > 3) {
532 G4cout << " ground state, energy corrected E(MeV)= "
533 << etot << G4endl;
534 }
535 }
536 }
537 delete frag;
538 }
539 if(fVerbose > 3) {
540 G4cout << "@@@@@@@@@@ End G4Excitation Handler "<< G4endl;
541 }
542 return theReactionProductVector;
543}
544
545void G4ExcitationHandler::ModelDescription(std::ostream& outFile) const
546{
547 outFile << "G4ExcitationHandler description\n"
548 << "This class samples de-excitation of excited nucleus using\n"
549 << "Fermi Break-up model for light fragments (Z < 9, A < 17), "
550 << "evaporation, fission, and photo-evaporation models. Evaporated\n"
551 << "particle may be proton, neutron, and other light fragment \n"
552 << "(Z < 13, A < 29). During photon evaporation produced gamma \n"
553 << "or electrons due to internal conversion \n";
554}
555
556
557
@ fEvaporation
std::vector< G4Element * > G4ElementTable
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
std::vector< G4Fragment * > G4FragmentVector
Definition: G4Fragment.hh:64
#define noFloat
Definition: G4Ions.hh:112
static const G4double fac
std::vector< G4ReactionProduct * > G4ReactionProductVector
static constexpr double eV
Definition: G4SIunits.hh:201
static constexpr double MeV
Definition: G4SIunits.hh:200
static constexpr double TeV
Definition: G4SIunits.hh:204
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
const G4double A[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4Alpha * AlphaDefinition()
Definition: G4Alpha.cc:83
static G4Deuteron * DeuteronDefinition()
Definition: G4Deuteron.cc:88
static G4Electron * Electron()
Definition: G4Electron.cc:93
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:397
virtual void InitialiseChannels() final
void SetGEMChannel()
void SetDefaultChannel()
void SetCombinedChannel()
void SetGEMVIChannel()
const G4ParticleDefinition * theAlpha
const G4ParticleDefinition * theHe3
G4VEvaporationChannel * GetPhotonEvaporation()
G4VEvaporation * GetEvaporation()
G4VEvaporation * theEvaporation
void SetEvaporation(G4VEvaporation *ptr, G4bool isLocal=false)
void SetFermiModel(G4VFermiBreakUp *ptr)
const G4ParticleDefinition * theProton
void SetPhotonEvaporation(G4VEvaporationChannel *ptr)
std::vector< G4Fragment * > results
void ModelDescription(std::ostream &outFile) const
void SortSecondaryFragment(G4Fragment *)
G4VFermiBreakUp * theFermiModel
G4ReactionProductVector * BreakItUp(const G4Fragment &theInitialState)
void SetMultiFragmentation(G4VMultiFragmentation *ptr)
std::vector< G4Fragment * > theEvapList
const G4ParticleDefinition * theTriton
G4VMultiFragmentation * theMultiFragmentation
G4VMultiFragmentation * GetMultiFragmentation()
const G4ParticleDefinition * theDeuteron
G4VEvaporationChannel * thePhotonEvaporation
const G4ParticleDefinition * theElectron
const G4ParticleDefinition * theNeutron
G4VFermiBreakUp * GetFermiModel()
std::vector< G4Fragment * > theResults
void SetDeexChannelsType(G4DeexChannelType val)
G4double GetExcitationEnergy() const
Definition: G4Fragment.hh:299
G4int GetZ_asInt() const
Definition: G4Fragment.hh:276
G4int GetA_asInt() const
Definition: G4Fragment.hh:271
static G4He3 * He3Definition()
Definition: G4He3.cc:88
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:522
static G4Ions::G4FloatLevelBase FloatLevelBase(char flbChar)
Definition: G4Ions.cc:103
static G4Neutron * NeutronDefinition()
Definition: G4Neutron.cc:98
static G4NistManager * Instance()
G4DeexPrecoParameters * GetParameters()
void UploadNuclearLevelData(G4int Z)
static G4NuclearLevelData * GetInstance()
G4IonTable * GetIonTable() const
static G4ParticleTable * GetParticleTable()
static G4int GetModelID(const G4int modelIndex)
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:87
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetTotalEnergy(const G4double en)
void SetCreatorModelID(const G4int mod)
void SetFormationTime(G4double aTime)
static G4Triton * TritonDefinition()
Definition: G4Triton.cc:88
virtual void BreakFragment(G4FragmentVector *, G4Fragment *theNucleus)
size_t GetNumberOfChannels() const
G4VEvaporationChannel * GetPhotonEvaporation()
virtual void SetPhotonEvaporation(G4VEvaporationChannel *ptr)
void SetFermiBreakUp(G4VFermiBreakUp *ptr)
virtual void InitialiseChannels()
virtual void Initialise()=0
virtual G4bool IsApplicable(G4int Z, G4int A, G4double mass) const =0
virtual void BreakFragment(G4FragmentVector *results, G4Fragment *theNucleus)=0
void SetVerbose(G4int val)
virtual G4FragmentVector * BreakItUp(const G4Fragment &theNucleus)=0
Definition: DoubConv.h:17
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4bool IsMasterThread()
Definition: G4Threading.cc:124