Loading...
Searching...
No Matches
GB03BOptnSplitOrKillOnBoundary.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/// \file GB03BOptnSplitOrKillOnBoundary.cc
28/// \brief Implementation of the GB03BOptnSplitOrKillOnBoundary class
29
30#include "Randomize.hh"
32
33//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
34
37 fParticleChange(),
38 fParticleChangeForNothing()
39{}
40
41//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
42
45
46//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
47
50 G4double,
51 G4ForceCondition* condition)
52{
53 // -- return "infinite" distance for interaction, but asks for GenerateBiasingFinalState
54 // -- being called anyway at the end of the step, by returning the "Forced" condition
55 // -- flag.
56 *condition = Forced;
57 return DBL_MAX;
58}
59
60//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
61
64 const G4Step* step )
65{
66
67 // Check if step is limited by the geometry: as we attached the biasing operator
68 // to the absorber layer, this volume boundary is the one of the absorber.
69 // (check of current step # of track is inelegant, but is to fix a "feature"
70 // that a cloned track can wrongly be seen in the wrong volume, because of numerical
71 // precision issue. In this case it makes a tiny step, which should be disregarded).
72 if ( ( step->GetPostStepPoint()->GetStepStatus() == fGeomBoundary ) &&
73 ( track->GetCurrentStepNumber() != 1 ) )
74 {
75
76 // -- Before deciding for killing or splitting, we make decision on applying
77 // -- the technique or not:
78 G4double trial = G4UniformRand(); // -- Note: G4UniformRand() is thread-safe
79 // -- engine for random numbers
80 if ( trial <= fApplyProbability )
81 {
82 // -- Get z component of track, to see if it moves forward or backward:
83 G4double pz = track->GetMomentum().z();
84
85 if ( pz > 0.0 )
86 {
87 // -------------------------------------------------
88 // Here, we are moving "forward". We do "splitting":
89 // -------------------------------------------------
90
91 // Get track weight:
92 G4double initialWeight = track->GetWeight();
93 // Define the tracks weight:
94 G4double weightOfTrack = initialWeight/fSplittingFactor;
95
96 // The "particle change" is the object to be used to communicate to
97 // the tracking the update of the primary state and/or creation
98 // secondary tracks.
99 fParticleChange.Initialize(*track);
100
101 // ask currect track weight to be changed to new value:
102 fParticleChange.ProposeParentWeight( weightOfTrack );
103
104 // Now make clones of this track (this is the actual splitting):
105 // we will then have the primary and N-1 clones of it, hence the
106 // splitting by a factor N:
107 fParticleChange.SetNumberOfSecondaries( fSplittingFactor-1 );
108 for ( G4int iSplit = 1 ; iSplit < fSplittingFactor ; iSplit++ )
109 {
110 G4Track* clone = new G4Track( *track );
111 clone->SetWeight( weightOfTrack );
112 fParticleChange.AddSecondary( clone );
113 }
114 fParticleChange.SetSecondaryWeightByProcess(true); // -- tricky
115 // -- take it as is ;) [though not necessary here, put for safety]
116
117 // this new final state is returned to the tracking;
118 return &fParticleChange;
119
120 }
121
122 else
123
124 {
125 // --------------------------------------------------------------
126 // Here, we are moving backward. We do killing, playing a russian
127 // roulette, killing 1/fSplittingFactor of the tracks in average:
128 // --------------------------------------------------------------
129
130 // Get track weight:
131 G4double initialWeight = track->GetWeight();
132
133 // The "particle change" is the object to be used to communicate to
134 // the tracking the update of the primary state and/or creation
135 // secondary tracks.
136 fParticleChange.Initialize(*track);
137
138 // Shoot a random number (in ]0,1[ segment):
139 G4double random = G4UniformRand();
140
141 // Decide to kill, keeping 1/fSplittingFactor of tracks:
142 G4double survivingProbability = 1.0/fSplittingFactor;
143 if ( random > survivingProbability )
144 {
145 // We ask for the the track to be killed:
146 fParticleChange.ProposeTrackStatus(fStopAndKill);
147 }
148 else
149 {
150 // In this case, the track survives. We change its weight
151 // to conserve weight among killed and survival tracks:
152 fParticleChange.ProposeParentWeight( initialWeight*fSplittingFactor );
153 }
154
155 // this new final state is returned to the tracking;
156 return &fParticleChange;
157 }
158 } // -- end of : if ( trial > probaForApplying )
159 } // -- end of : if ( ( step->GetPostStepPoint()->GetStepStatus() ==
160 // fGeomBoundary ) ...
161
162
163 // Here, the step was not limited by the geometry (but certainly by a physics
164 // process). We do nothing: ie we make no change to the current track.
165 fParticleChangeForNothing.Initialize(*track);
167
168}
169
170//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Definition of the GB03BOptnSplitOrKillOnBoundary class.
G4ParticleChangeForNothing fParticleChangeForNothing
virtual G4VParticleChange * GenerateBiasingFinalState(const G4Track *, const G4Step *)
virtual G4double DistanceToApplyOperation(const G4Track *, G4double, G4ForceCondition *condition)

Applications | User Support | Publications | Collaboration