Loading...
Searching...
No Matches
GB06BOptnSplitAndKillByImportance.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 GB06BOptnSplitAndKillByImportance.cc
28/// \brief Implementation of the GB06BOptnSplitAndKillByImportance class
29
31#include "Randomize.hh"
32
33
34#include "G4BiasingProcessInterface.hh"
35#include "G4ParallelGeometriesLimiterProcess.hh"
36#include "G4BiasingProcessSharedData.hh"
37#include "G4ProcessManager.hh"
38
39
40//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
41
43: G4VBiasingOperation (name),
44 fParallelWorldIndex ( -1 ),
45 fBiasingSharedData ( nullptr ),
46 fParticleChange(),
47 fDummyParticleChange()
48{}
49
50//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
51
54
55//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
56
59 G4double,
60 G4ForceCondition* condition)
61{
62
63 // -- Remember the touchable history (ie geometry state) at the beginning of the step:
64 // -- Start by getting the process handling the step limitation in parallel
65 // -- geometries for the generic biasing:
66 auto biasingLimiterProcess = fBiasingSharedData->GetParallelGeometriesLimiterProcess();
68 biasingLimiterProcess
69 ->GetNavigator( fParallelWorldIndex ) // -- get the navigator of the geometry...
70 ->CreateTouchableHistoryHandle(); // -- ...and collect the geometry state.
71
72 // -- We request to be "forced" : meaning GenerateBiasingFinalState(...) will be called
73 // -- anyway at the PostStepDoIt(...) stage (ie, when the track will have been moved to
74 // -- its end point position) and, there, we will have to handle the decision to
75 // -- split/kill if we are on a volume boundary, or do nothing, if we're not:
76 *condition = Forced;
77
78 // -- As we're forced, we make this returned length void:
79 return DBL_MAX;
80}
81
82//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83
86 const G4Step* )
87{
88 // -- Given we used the "Forced" condition, this method is always called.
89 // -- We check the status of the step in the parallel geometry, and apply
90 // -- splitting/killing if the step has been limited by the geometry.
91
92 // -- We first check if we limit the step in the parallel geometry:
93 G4bool isLimiting = fBiasingSharedData
94 ->GetParallelGeometriesLimiterProcess()
95 ->GetIsLimiting( fParallelWorldIndex );
96
97 // -- if not limiting, we leave the track unchanged:
98 if ( !isLimiting )
99 {
100 fDummyParticleChange.Initialize( *track );
101 return &fDummyParticleChange;
102 }
103
104 // -- We collect the geometry state at the end point step:
105 // -- Note this is the same call than in the DistanceToApplyOperation(...) for the
106 // -- fPreStepTouchableHistory, but the navigator has pushed the track in the next
107 // -- volume since then (even if the track is still on the boundary), and hence the
108 // -- geometry state has changed.
109 auto biasingLimiterProcess = fBiasingSharedData->GetParallelGeometriesLimiterProcess();
111 biasingLimiterProcess
112 ->GetNavigator( fParallelWorldIndex )
113 ->CreateTouchableHistoryHandle();
114
115
116 // -- We verify we are still in the "same" physical volume:
117 // -- remember : using a replica, we have "one" physical volume
118 // -- but representing many different placements, distinguished
119 // -- by replica number. By checking we are in the same physical
120 // -- volume, we verify the end step point has not reached the
121 // -- world volume of the parallel geometry:
122 if ( fPreStepTouchableHistory ->GetVolume() !=
123 fPostStepTouchableHistory->GetVolume() )
124 {
125 // -- the track is leaving the volumes in which biasing is applied,
126 // -- we leave this track unchanged:
127 fDummyParticleChange.Initialize( *track );
128 return &fDummyParticleChange;
129 }
130
131 // -------------------------------------------------------------------------------------
132 // -- At this stage, we know we have a particle crossing a boundary between two slices,
133 // -- each of this slice has a well defined importance : we apply the biasing.
134 // -- We will split if the track is entering a volume with higher importance, and
135 // -- kill (applying Russian roulette) in the other case.
136 // -------------------------------------------------------------------------------------
137
138 // -- We start by getting the replica numbers:
139 G4int preReplicaNumber = fPreStepTouchableHistory->GetReplicaNumber();
140 G4int postReplicaNumber = fPostStepTouchableHistory->GetReplicaNumber();
141
142 // -- and get the related importance we defined in the importance map:
143 G4int preImportance = (*fImportanceMap)[ preReplicaNumber];
144 G4int postImportance = (*fImportanceMap)[postReplicaNumber];
145
146
147 // -- Get track weight:
148 G4double initialWeight = track->GetWeight();
149
150 // -- Initialize the "particle change" (it will communicate the new track state to
151 // -- the tracking):
152 fParticleChange.Initialize(*track);
153
154 if ( postImportance > preImportance )
155 {
156 // -- We split :
157 G4int splittingFactor = postImportance/preImportance;
158
159 // Define the tracks weight:
160 G4double weightOfTrack = initialWeight/splittingFactor;
161
162 // Ask currect track weight to be changed to the new value:
163 fParticleChange.ProposeParentWeight( weightOfTrack );
164 // Now we clone this track (this is the actual splitting):
165 // we will then have the primary and clone of it, hence the
166 // splitting by a factor 2:
167 G4Track* clone = new G4Track( *track );
168 clone->SetWeight( weightOfTrack );
169 fParticleChange.AddSecondary( clone );
170 // -- Below's call added for safety & illustration : inform particle change to not
171 // -- modify the clone (ie : daughter) weight to make it that of the primary.
172 // -- Here this call is not mandatory as both tracks have same weights.
173 fParticleChange.SetSecondaryWeightByProcess(true);
174 }
175 else
176 {
177 // -- We apply Russian roulette:
178 G4double survivingProbability = G4double(postImportance) / G4double(preImportance);
179
180 // Shoot a random number (in ]0,1[ segment):
181 G4double random = G4UniformRand();
182 if ( random > survivingProbability )
183 {
184 // We ask for the the track to be killed:
185 fParticleChange.ProposeTrackStatus(fStopAndKill);
186 }
187 else
188 {
189 // In this case, the track survives. We change its weight
190 // to conserve weight among killed and survival tracks:
191 fParticleChange.ProposeParentWeight( initialWeight/survivingProbability );
192 }
193 }
194
195 return &fParticleChange;
196
197}
198
199//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Definition of the GB06BOptnSplitAndKillByImportance class.
const G4BiasingProcessSharedData * fBiasingSharedData
virtual G4VParticleChange * GenerateBiasingFinalState(const G4Track *, const G4Step *) final
virtual G4double DistanceToApplyOperation(const G4Track *, G4double, G4ForceCondition *condition) final

Applications | User Support | Publications | Collaboration