Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4FermiBreakUpVI.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// FermiBreakUp de-excitation model
28// by V. Ivanchenko (July 2016)
29//
30
31#include "G4FermiBreakUpVI.hh"
32#include "G4FermiBreakUpUtil.hh"
34#include "G4FermiChannels.hh"
35#include "G4FermiPair.hh"
37#include "G4NuclearLevelData.hh"
40#include "Randomize.hh"
41#include "G4RandomDirection.hh"
42
43G4FermiFragmentsPoolVI* G4FermiBreakUpVI::fPool = nullptr;
44
46{
47 frag.reserve(10);
48 lvect.reserve(10);
49 secID = G4PhysicsModelCatalog::GetModelID("model_G4FermiBreakUpVI");
50 prob.resize(12,0.0);
51 if (nullptr == fPool) {
52 fPool = new G4FermiFragmentsPoolVI();
53 fPool->Initialise();
54 isFirst = true;
55 }
56}
57
59{
60 if (isFirst) {
61 delete fPool;
62 fPool = nullptr;
63 }
64}
65
67{
68 G4DeexPrecoParameters* param =
70 fTolerance = param->GetMinExcitation();
71 fElim = param->GetFBUEnergyLimit();
72 fTimeLim = param->GetMaxLifeTime();
73 if (verbose > 1) {
74 G4cout << "### G4FermiBreakUpVI::Initialise(): the pool is initilized="
75 << fPool->IsInitialized() << " fTolerance(eV)=" << fTolerance/CLHEP::eV
76 << " Elim(MeV)=" << fElim/CLHEP::MeV << G4endl;
77 }
78}
79
81{
82 return (Z < maxZ && A < maxA && eexc <= fElim && fPool->HasDecay(Z, A, eexc));
83}
84
86 G4Fragment* theNucleus)
87{
88 if (verbose > 1) {
89 G4cout << "### G4FermiBreakUpVI::BreakFragment start new fragment "
90 << G4endl;
91 G4cout << *theNucleus << G4endl;
92 }
93 if (!fPool->IsInitialized()) { fPool->Initialise(); }
94
95 // initial fragment
96 G4int Z = theNucleus->GetZ_asInt();
97 G4int A = theNucleus->GetA_asInt();
98 G4double excitation = theNucleus->GetExcitationEnergy();
99 if (!IsApplicable(Z, A, excitation)) { return; }
100 G4double mass = theNucleus->GetGroundStateMass() + excitation;
101 G4LorentzVector lv0 = theNucleus->GetMomentum();
102
103 // sample first decay of an initial state
104 // if not possible to decay - exit
105 if (!SampleDecay(Z, A, mass, excitation, lv0)) { return; }
106
107 G4double time = theNucleus->GetCreationTime();
108 delete theNucleus;
109
110 static const G4int imax = 100;
111
112 // loop over vector of Fermi fragments
113 // vector may grow at each iteraction
114 for (std::size_t i=0; i<frag.size(); ++i) {
115 Z = frag[i]->GetZ();
116 A = frag[i]->GetA();
117 excitation = frag[i]->GetExcitationEnergy();
118 lv0 = lvect[i];
119 G4bool unstable = (IsApplicable(Z, A, excitation) && frag[i]->GetLifeTime() < fTimeLim);
120 if (unstable) {
121 mass = frag[i]->GetTotalEnergy();
122 if (verbose > 1) {
123 G4cout << "# FermiFrag " << i << ". Z= " << Z << " A= " << A
124 << " mass= " << mass << " exc= "
125 << frag[i]->GetExcitationEnergy() << G4endl;
126 }
127 unstable = SampleDecay(Z, A, mass, excitation, lv0);
128 }
129 // stable fragment
130 if (!unstable) {
131 if(verbose > 1) { G4cout << " New G4Fragment" << G4endl; }
132 G4Fragment* f = new G4Fragment(A, Z, lv0);
133 f->SetCreationTime(time);
134 f->SetCreatorModelID(secID);
135 theResult->push_back(f);
136 }
137 // limit the loop
138 if (i == imax) { break; }
139 }
140 frag.clear();
141 lvect.clear();
142}
143
144G4bool G4FermiBreakUpVI::SampleDecay(const G4int Z, const G4int A, const G4double mass,
145 const G4double exc, G4LorentzVector& lv0)
146{
147 const G4FermiChannels* chan = fPool->ClosestChannels(Z, A, mass);
148 if (nullptr == chan) { return false; }
149 std::size_t nn = chan->NumberPairs();
150 if (verbose > 1) {
151 G4cout << "G4FermiBreakUpVI::SampleDecay " << nn << " channels Eex= "
152 << chan->GetExcitation() << G4endl;
153 }
154 if (0 == nn) { return false; }
155 if (nn > prob.size()) { prob.resize(nn, 0.0); }
156
157 const G4FermiPair* fpair = nullptr;
158
159 // one unstable fragment
160 if (1 == nn) {
161 fpair = chan->GetPair(0);
162
163 // more pairs
164 } else {
165
167 const std::vector<G4FermiPair*>& pvect = chan->GetChannels();
168 std::size_t i{0};
169 G4bool pre = true;
170 if (std::abs(exc - chan->GetExcitation()) < fTolerance) {
171 // static probabilities may be used
172 for (; i<nn; ++i) {
173 if (q <= pvect[i]->Probability()) {
174 fpair = pvect[i];
175 break;
176 }
177 }
178 } else {
179 // recompute probabilities
180 pre = false;
181 G4double ptot = 0.0;
182 for (i=0; i<nn; ++i) {
183 ptot += G4FermiBreakUpUtil::Probability(A, pvect[i]->GetFragment1(),
184 pvect[i]->GetFragment2(),
185 mass, exc);
186 prob[i] = ptot;
187 }
188 ptot *= q;
189 for (i=0; i<nn; ++i) {
190 if(ptot <= prob[i]) {
191 fpair = pvect[i];
192 break;
193 }
194 }
195 }
196 if (verbose > 2) {
197 G4cout << "Probabilities of 2-body decay: Nchannels=" << nn
198 << " channels; i=" << i << " is selected; predefined="
199 << pre << G4endl;
200 for (std::size_t j=0; j<nn; ++j) {
201 G4cout << j << ". ";
202 if (pre) { G4cout << pvect[j]->Probability(); }
203 else { G4cout << prob[j]; }
204 G4cout << " Z1= " << pvect[j]->GetFragment1()->GetZ()
205 << " A1= " << pvect[j]->GetFragment1()->GetA()
206 << " Z2= " << pvect[j]->GetFragment2()->GetZ()
207 << " A2= " << pvect[j]->GetFragment2()->GetA()
208 << G4endl;
209 }
210 }
211 }
212 if (nullptr == fpair) { return false; }
213
214 auto frag1 = fpair->GetFragment1();
215 auto frag2 = fpair->GetFragment2();
216
217 G4double mass1 = frag1->GetTotalEnergy();
218 G4double mass2 = frag2->GetTotalEnergy();
219 if (verbose > 2) {
220 G4cout << " M= " << mass << " M1= " << mass1 << " M2= " << mass2
221 << " Exc1= " << frag1->GetExcitationEnergy()
222 << " Exc2= " << frag2->GetExcitationEnergy() << G4endl;
223 }
224 // sample fragment1
225 G4double e1 = 0.5*(mass*mass - mass2*mass2 + mass1*mass1)/mass;
226 //G4cout << "ekin1= " << e1 - mass1 << G4endl;
227 G4double p1(0.0);
228 if (e1 > mass1) {
229 p1 = std::sqrt((e1 - mass1)*(e1 + mass1));
230 } else {
231 e1 = mass1;
232 }
234
235 // compute kinematics
236 auto boostVector = lv0.boostVector();
237 lv1.boost(boostVector);
238 G4LorentzVector lv2 = lv0 - lv1;
239
240 frag.push_back(frag1);
241 frag.push_back(frag2);
242 lvect.push_back(lv1);
243 lvect.push_back(lv2);
244
245 return true;
246}
std::vector< G4Fragment * > G4FragmentVector
Definition G4Fragment.hh:65
CLHEP::HepLorentzVector G4LorentzVector
G4ThreeVector G4RandomDirection()
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
const G4double A[17]
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
~G4FermiBreakUpVI() override
void BreakFragment(G4FragmentVector *, G4Fragment *theNucleus) override
G4bool IsApplicable(G4int ZZ, G4int AA, G4double eexc) const override
void Initialise() override
G4double GetExcitation() const
std::size_t NumberPairs() const
const G4FermiPair * GetPair(std::size_t idx) const
const std::vector< G4FermiPair * > & GetChannels() const
G4double GetTotalEnergy(void) const
const G4FermiChannels * ClosestChannels(const G4int Z, const G4int A, const G4double mass) const
const G4FermiFragment * GetFragment2() const
const G4FermiFragment * GetFragment1() const
G4double GetGroundStateMass() const
G4double GetExcitationEnergy() const
const G4LorentzVector & GetMomentum() const
void SetCreatorModelID(G4int value)
G4double GetCreationTime() const
G4int GetZ_asInt() const
void SetCreationTime(G4double time)
G4int GetA_asInt() const
G4DeexPrecoParameters * GetParameters()
static G4NuclearLevelData * GetInstance()
static G4int GetModelID(const G4int modelIndex)
G4double Probability(const G4int A, const G4FermiFragment *f1, const G4FermiFragment *f2, const G4double mass, const G4double exc)