Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VAtomDeexcitation.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$
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class class file
31 //
32 //
33 // File name: G4VAtomDeexcitation
34 //
35 // Author: Alfonso Mantero & Vladimir Ivanchenko
36 //
37 // Creation date: 21.04.2010
38 //
39 // Modifications:
40 //
41 // Class Description:
42 //
43 // Abstract interface to energy loss models
44 
45 // -------------------------------------------------------------------
46 //
47 
48 #include "G4VAtomDeexcitation.hh"
49 #include "G4SystemOfUnits.hh"
50 #include "G4ParticleDefinition.hh"
51 #include "G4DynamicParticle.hh"
52 #include "G4Step.hh"
53 #include "G4Region.hh"
54 #include "G4RegionStore.hh"
55 #include "G4MaterialCutsCouple.hh"
56 #include "G4MaterialCutsCouple.hh"
57 #include "G4Material.hh"
58 #include "G4Element.hh"
59 #include "G4ElementVector.hh"
60 #include "Randomize.hh"
61 #include "G4VParticleChange.hh"
62 
63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
64 
66  const G4String& pname)
67  : lowestKinEnergy(keV), verbose(1), name(modname), namePIXE(pname),
68  nameElectronPIXE(""), isActive(false), flagAuger(false), flagPIXE(false)
69 {
70  vdyn.reserve(5);
71  theCoupleTable = 0;
72 }
73 
74 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
75 
77 {}
78 
79 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
80 
82 {
83  // Define list of couples
85  size_t numOfCouples = theCoupleTable->GetTableSize();
86 
87  // needed for unit tests
88  if(0 == numOfCouples) { numOfCouples = 1; }
89 
90  activeDeexcitationMedia.resize(numOfCouples, false);
91  activeAugerMedia.resize(numOfCouples, false);
92  activePIXEMedia.resize(numOfCouples, false);
93  activeZ.resize(93, false);
94 
95  // check if deexcitation is active for the given run
96  if( !isActive ) { return; }
97 
98  // Define list of regions
99  size_t nRegions = deRegions.size();
100 
101  if(0 == nRegions) {
102  SetDeexcitationActiveRegion("World",isActive,flagAuger,flagPIXE);
103  nRegions = 1;
104  }
105 
106  if(0 < verbose) {
107  G4cout << G4endl;
108  G4cout << "### === Deexcitation model " << name
109  << " is activated for " << nRegions;
110  if(1 == nRegions) { G4cout << " region:" << G4endl; }
111  else { G4cout << " regions:" << G4endl;}
112  }
113 
114  // Identify active media
115  G4RegionStore* regionStore = G4RegionStore::GetInstance();
116  for(size_t j=0; j<nRegions; ++j) {
117  const G4Region* reg = regionStore->GetRegion(activeRegions[j], false);
118  const G4ProductionCuts* rpcuts = reg->GetProductionCuts();
119  if(0 < verbose) {
120  G4cout << " " << activeRegions[j] << G4endl;
121  }
122 
123  for(size_t i=0; i<numOfCouples; ++i) {
124  const G4MaterialCutsCouple* couple =
125  theCoupleTable->GetMaterialCutsCouple(i);
126  if (couple->GetProductionCuts() == rpcuts) {
127  activeDeexcitationMedia[i] = deRegions[j];
128  activeAugerMedia[i] = AugerRegions[j];
129  activePIXEMedia[i] = PIXERegions[j];
130  const G4Material* mat = couple->GetMaterial();
131  const G4ElementVector* theElementVector =
132  mat->GetElementVector();
133  G4int nelm = mat->GetNumberOfElements();
134  if(deRegions[j]) {
135  for(G4int k=0; k<nelm; ++k) {
136  G4int Z = G4lrint(((*theElementVector)[k])->GetZ());
137  if(Z > 5 && Z < 93) {
138  activeZ[Z] = true;
139  //G4cout << "!!! Active de-excitation Z= " << Z << G4endl;
140  }
141  }
142  }
143  }
144  }
145  }
146 
147  // Initialise derived class
149 
150  if(0 < verbose && flagPIXE) {
151  G4cout << "### === PIXE model for hadrons: " << namePIXE
152  << " " << IsPIXEActive()
153  << G4endl;
154  G4cout << "### === PIXE model for e+-: " << nameElectronPIXE
155  << " " << IsPIXEActive()
156  << G4endl;
157  }
158 }
159 
160 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
161 
162 void
164  G4bool valDeexcitation,
165  G4bool valAuger,
166  G4bool valPIXE)
167 {
168  G4String ss = rname;
169  //G4cout << "### G4VAtomDeexcitation::SetDeexcitationActiveRegion " << ss
170  // << " " << valDeexcitation << " " << valAuger
171  // << " " << valPIXE << G4endl;
172  if(ss == "world" || ss == "World" || ss == "WORLD") {
173  ss = "DefaultRegionForTheWorld";
174  }
175  size_t n = deRegions.size();
176  if(n > 0) {
177  for(size_t i=0; i<n; ++i) {
178 
179  // Region already exist
180  if(ss == activeRegions[i]) {
181  deRegions[i] = valDeexcitation;
182  AugerRegions[i] = valAuger;
183  PIXERegions[i] = valPIXE;
184  return;
185  }
186  }
187  }
188  // New region
189  activeRegions.push_back(ss);
190  deRegions.push_back(valDeexcitation);
191  AugerRegions.push_back(valAuger);
192  PIXERegions.push_back(valPIXE);
193 }
194 
195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
196 
197 void
198 G4VAtomDeexcitation::AlongStepDeexcitation(std::vector<G4Track*>& tracks,
199  const G4Step& step,
200  G4double& eLossMax,
201  G4int coupleIndex)
202 {
203  G4double truelength = step.GetStepLength();
204  if(!flagPIXE && !activePIXEMedia[coupleIndex]) { return; }
205  if(eLossMax <= 0.0 || truelength <= 0.0) { return; }
206 
207  // step parameters
208  const G4StepPoint* preStep = step.GetPreStepPoint();
209  G4ThreeVector prePos = preStep->GetPosition();
210  G4ThreeVector delta = step.GetPostStepPoint()->GetPosition() - prePos;
211  G4double preTime = preStep->GetGlobalTime();
212  G4double dt = step.GetPostStepPoint()->GetGlobalTime() - preTime;
213 
214  // particle parameters
215  const G4Track* track = step.GetTrack();
216  const G4ParticleDefinition* part = track->GetDefinition();
217  G4double ekin = preStep->GetKineticEnergy();
218 
219  // media parameters
220  G4double gCut = (*theCoupleTable->GetEnergyCutsVector(0))[coupleIndex];
221  G4double eCut = DBL_MAX;
222  if(CheckAugerActiveRegion(coupleIndex)) {
223  eCut = (*theCoupleTable->GetEnergyCutsVector(1))[coupleIndex];
224  }
225 
226  //G4cout<<"!Sample PIXE gCut(MeV)= "<<gCut<<" eCut(MeV)= "<<eCut
227  // <<" Ekin(MeV)= " << ekin/MeV << G4endl;
228 
229  const G4Material* material = preStep->GetMaterial();
230  const G4ElementVector* theElementVector = material->GetElementVector();
231  const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
232  G4int nelm = material->GetNumberOfElements();
233 
234  // loop over deexcitations
235  for(G4int i=0; i<nelm; ++i) {
236  G4int Z = G4lrint((*theElementVector)[i]->GetZ());
237  if(activeZ[Z] && Z < 93) {
238  G4int nshells = std::min(9,(*theElementVector)[i]->GetNbOfAtomicShells());
239  G4double rho = truelength*theAtomNumDensityVector[i];
240  //G4cout << " Z " << Z <<" is active x(mm)= " << truelength/mm << G4endl;
241  for(G4int ii=0; ii<nshells; ++ii) {
243  const G4AtomicShell* shell = GetAtomicShell(Z, as);
245 
246  if(gCut > bindingEnergy) { break; }
247 
248  if(eLossMax > bindingEnergy) {
249  G4double sig = rho*
250  GetShellIonisationCrossSectionPerAtom(part, Z, as, ekin, material);
251 
252  // mfp is mean free path in units of step size
253  if(sig > 0.0) {
254  G4double mfp = 1.0/sig;
255  G4double stot = 0.0;
256  //G4cout << " Shell " << ii << " mfp(mm)= " << mfp/mm << G4endl;
257  // sample ionisation points
258  do {
259  stot -= mfp*std::log(G4UniformRand());
260  if( stot > 1.0 || eLossMax < bindingEnergy) { break; }
261  // sample deexcitation
262  vdyn.clear();
263  GenerateParticles(&vdyn, shell, Z, gCut, eCut);
264  G4int nsec = vdyn.size();
265  if(nsec > 0) {
266  G4ThreeVector r = prePos + stot*delta;
267  G4double time = preTime + stot*dt;
268  for(G4int j=0; j<nsec; ++j) {
269  G4DynamicParticle* dp = vdyn[j];
270  G4double e = dp->GetKineticEnergy();
271 
272  // save new secondary if there is enough energy
273  if(eLossMax >= e) {
274  eLossMax -= e;
275  G4Track* t = new G4Track(dp, time, r);
276  tracks.push_back(t);
277  } else {
278  delete dp;
279  }
280  }
281  }
282  } while (stot < 1.0);
283  }
284  }
285  }
286  }
287  }
288  return;
289 }
290 
291 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....