Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/de_excitation/fermi_breakup/src/G4FermiBreakUpVI.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 // FermiBreakUp de-excitation model
 28 // by V. Ivanchenko (July 2016)
 29 //
 30 
 31 #include "G4FermiBreakUpVI.hh"
 32 #include "G4FermiBreakUpUtil.hh"
 33 #include "G4FermiFragmentsPoolVI.hh"
 34 #include "G4FermiChannels.hh"
 35 #include "G4FermiPair.hh"
 36 #include "G4PhysicalConstants.hh"
 37 #include "G4NuclearLevelData.hh"
 38 #include "G4DeexPrecoParameters.hh"
 39 #include "G4PhysicsModelCatalog.hh"
 40 #include "Randomize.hh"
 41 #include "G4RandomDirection.hh"
 42 
 43 G4FermiFragmentsPoolVI* G4FermiBreakUpVI::fPool = nullptr;
 44 
 45 G4FermiBreakUpVI::G4FermiBreakUpVI()
 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 
 58 G4FermiBreakUpVI::~G4FermiBreakUpVI()
 59 {
 60   if (isFirst) { 
 61     delete fPool;
 62     fPool = nullptr;
 63   }
 64 }
 65 
 66 void G4FermiBreakUpVI::Initialise()
 67 {
 68   G4DeexPrecoParameters* param = 
 69     G4NuclearLevelData::GetInstance()->GetParameters();
 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 
 80 G4bool G4FermiBreakUpVI::IsApplicable(G4int Z, G4int A, G4double eexc) const
 81 {
 82   return (Z < maxZ && A < maxA && eexc <= fElim && fPool->HasDecay(Z, A, eexc));
 83 }
 84 
 85 void G4FermiBreakUpVI::BreakFragment(G4FragmentVector* theResult, 
 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 
144 G4bool 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     
166     G4double q = G4UniformRand();
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   }
233   G4LorentzVector lv1 = G4LorentzVector(G4RandomDirection()*p1, e1);
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 }
247