00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4WeightWindowProcess.hh"
00037 #include "G4VWeightWindowAlgorithm.hh"
00038 #include "G4GeometryCell.hh"
00039 #include "G4SamplingPostStepAction.hh"
00040 #include "G4VTrackTerminator.hh"
00041 #include "G4PlaceOfAction.hh"
00042 #include "G4VWeightWindowStore.hh"
00043
00044 #include "G4Step.hh"
00045 #include "G4Navigator.hh"
00046 #include "G4VTouchable.hh"
00047 #include "G4VPhysicalVolume.hh"
00048 #include "G4ParticleChange.hh"
00049 #include "G4PathFinder.hh"
00050 #include "G4TransportationManager.hh"
00051 #include "G4StepPoint.hh"
00052 #include "G4FieldTrackUpdator.hh"
00053
00054
00055 G4WeightWindowProcess::G4WeightWindowProcess(
00056 const G4VWeightWindowAlgorithm &aWeightWindowAlgorithm,
00057 const G4VWeightWindowStore &aWWStore,
00058 const G4VTrackTerminator *TrackTerminator,
00059 G4PlaceOfAction placeOfAction,
00060 const G4String &aName, G4bool para)
00061 : G4VProcess(aName),
00062 fParticleChange(new G4ParticleChange),
00063 fWeightWindowAlgorithm(aWeightWindowAlgorithm),
00064 fWeightWindowStore(aWWStore),
00065 fPostStepAction(0),
00066 fPlaceOfAction(placeOfAction),
00067 fGhostNavigator(0), fNavigatorID(-1), fFieldTrack('0')
00068 {
00069 if (TrackTerminator)
00070 {
00071 fPostStepAction = new G4SamplingPostStepAction(*TrackTerminator);
00072 }
00073 else
00074 {
00075 fPostStepAction = new G4SamplingPostStepAction(*this);
00076 }
00077 if (!fParticleChange)
00078 {
00079 G4Exception("G4WeightWindowProcess::G4WeightWindowProcess()",
00080 "FatalError", FatalException,
00081 "Failed allocation of G4ParticleChange !");
00082 }
00083 G4VProcess::pParticleChange = fParticleChange;
00084
00085 fGhostStep = new G4Step();
00086 fGhostPreStepPoint = fGhostStep->GetPreStepPoint();
00087 fGhostPostStepPoint = fGhostStep->GetPostStepPoint();
00088
00089 fTransportationManager = G4TransportationManager::GetTransportationManager();
00090 fPathFinder = G4PathFinder::GetInstance();
00091
00092 if (verboseLevel>0)
00093 {
00094 G4cout << GetProcessName() << " is created " << G4endl;
00095 }
00096
00097 paraflag = para;
00098
00099 }
00100
00101 G4WeightWindowProcess::~G4WeightWindowProcess()
00102 {
00103
00104 delete fPostStepAction;
00105 delete fParticleChange;
00106 delete fGhostStep;
00107
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 void G4WeightWindowProcess::
00117 SetParallelWorld(G4String parallelWorldName)
00118 {
00119
00120
00121
00122 fGhostWorldName = parallelWorldName;
00123 fGhostWorld = fTransportationManager->GetParallelWorld(fGhostWorldName);
00124 fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
00125
00126 }
00127
00128 void G4WeightWindowProcess::
00129 SetParallelWorld(G4VPhysicalVolume* parallelWorld)
00130 {
00131
00132
00133
00134 fGhostWorldName = parallelWorld->GetName();
00135 fGhostWorld = parallelWorld;
00136 fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
00137
00138 }
00139
00140
00141
00142
00143
00144
00145 void G4WeightWindowProcess::StartTracking(G4Track* trk)
00146 {
00147
00148
00149
00150
00151
00152 if(paraflag) {
00153 if(fGhostNavigator)
00154 { fNavigatorID = fTransportationManager->ActivateNavigator(fGhostNavigator); }
00155 else
00156 {
00157 G4Exception("G4WeightWindowProcess::StartTracking",
00158 "ProcParaWorld000",FatalException,
00159 "G4WeightWindowProcess is used for tracking without having a parallel world assigned");
00160 }
00161
00162
00163
00164
00165
00166
00167 fPathFinder->PrepareNewTrack(trk->GetPosition(),trk->GetMomentumDirection());
00168
00169
00170
00171
00172
00173 fOldGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
00174 fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00175 fNewGhostTouchable = fOldGhostTouchable;
00176 fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00177
00178
00179 fGhostSafety = -1.;
00180 fOnBoundary = false;
00181 }
00182 }
00183
00184
00185 G4double G4WeightWindowProcess::
00186 PostStepGetPhysicalInteractionLength(const G4Track& ,
00187 G4double ,
00188 G4ForceCondition* condition)
00189 {
00190
00191
00192
00193
00194 *condition = Forced;
00195 return DBL_MAX;
00196 }
00197
00198 G4VParticleChange *
00199 G4WeightWindowProcess::PostStepDoIt(const G4Track &aTrack,
00200 const G4Step &aStep)
00201 {
00202
00203 fParticleChange->Initialize(aTrack);
00204
00205 if(paraflag) {
00206 fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
00207
00208 CopyStep(aStep);
00209
00210 if(fOnBoundary)
00211 {
00212
00213
00214
00215
00216
00217 fNewGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
00218
00219 }
00220 else
00221 {
00222
00223
00224
00225
00226
00227
00228
00229 fNewGhostTouchable = fOldGhostTouchable;
00230 }
00231
00232 fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00233 fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00234
00235 }
00236
00237 if (aStep.GetStepLength() > kCarTolerance)
00238 {
00239
00240
00241
00242
00243
00244 if(paraflag) {
00245 if ( ( fPlaceOfAction == onBoundaryAndCollision)
00246 || ( (fPlaceOfAction == onBoundary) &&
00247 (fGhostPostStepPoint->GetStepStatus() == fGeomBoundary) )
00248 || ( (fPlaceOfAction == onCollision) &&
00249 (fGhostPostStepPoint->GetStepStatus() != fGeomBoundary) ) )
00250 {
00251
00252
00253
00254
00255
00256
00257 G4GeometryCell postCell(*(fGhostPostStepPoint->GetPhysicalVolume()),
00258 fGhostPostStepPoint->GetTouchable()->GetReplicaNumber());
00259 G4Nsplit_Weight nw =
00260 fWeightWindowAlgorithm.Calculate(aTrack.GetWeight(),
00261 fWeightWindowStore.GetLowerWeight(postCell,
00262 aTrack.GetKineticEnergy()));
00263 fPostStepAction->DoIt(aTrack, fParticleChange, nw);
00264 }
00265 } else {
00266 if ( ( fPlaceOfAction == onBoundaryAndCollision)
00267 || ( (fPlaceOfAction == onBoundary) &&
00268 (aStep.GetPostStepPoint()->GetStepStatus() == fGeomBoundary) )
00269 || ( (fPlaceOfAction == onCollision) &&
00270 (aStep.GetPostStepPoint()->GetStepStatus() != fGeomBoundary) ) )
00271 {
00272
00273 G4StepPoint *postpoint = aStep.GetPostStepPoint();
00274
00275 G4GeometryCell postCell(*(postpoint->GetPhysicalVolume()),
00276 postpoint->GetTouchable()->GetReplicaNumber());
00277
00278 G4Nsplit_Weight nw =
00279 fWeightWindowAlgorithm.Calculate(aTrack.GetWeight(),
00280 fWeightWindowStore.GetLowerWeight(postCell,
00281 aTrack.GetKineticEnergy()));
00282 fPostStepAction->DoIt(aTrack, fParticleChange, nw);
00283 }
00284 }
00285 }
00286 return fParticleChange;
00287 }
00288
00289 void G4WeightWindowProcess::KillTrack() const
00290 {
00291 fParticleChange->ProposeTrackStatus(fStopAndKill);
00292 }
00293
00294 const G4String &G4WeightWindowProcess::GetName() const
00295 {
00296 return G4VProcess::GetProcessName();
00297 }
00298
00299 G4double G4WeightWindowProcess::
00300 AlongStepGetPhysicalInteractionLength(
00301 const G4Track& track, G4double previousStepSize, G4double currentMinimumStep,
00302 G4double& proposedSafety, G4GPILSelection* selection)
00303 {
00304 if(paraflag) {
00305 static G4FieldTrack endTrack('0');
00306 static ELimited eLimited;
00307
00308 *selection = NotCandidateForSelection;
00309 G4double returnedStep = DBL_MAX;
00310
00311 if (previousStepSize > 0.)
00312 { fGhostSafety -= previousStepSize; }
00313
00314
00315 if (fGhostSafety < 0.) fGhostSafety = 0.0;
00316
00317
00318
00319
00320 if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
00321 {
00322
00323 returnedStep = currentMinimumStep;
00324 fOnBoundary = false;
00325 proposedSafety = fGhostSafety - currentMinimumStep;
00326 }
00327 else
00328 {
00329 G4FieldTrackUpdator::Update(&fFieldTrack,&track);
00330
00331
00332
00333 returnedStep
00334 = fPathFinder->ComputeStep(fFieldTrack,currentMinimumStep,fNavigatorID,
00335 track.GetCurrentStepNumber(),fGhostSafety,eLimited,
00336 endTrack,track.GetVolume());
00337
00338 if(eLimited == kDoNot)
00339 {
00340
00341 fOnBoundary = false;
00342 fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition());
00343 }
00344 else
00345 {
00346
00347 fOnBoundary = true;
00348 proposedSafety = fGhostSafety;
00349 }
00350
00351 if(eLimited == kUnique || eLimited == kSharedOther) {
00352 *selection = CandidateForSelection;
00353 }else if (eLimited == kSharedTransport) {
00354 returnedStep *= (1.0 + 1.0e-9);
00355
00356 }
00357
00358 }
00359
00360
00361
00362
00363
00364
00365 return returnedStep;
00366
00367 } else {
00368 return DBL_MAX;
00369
00370 }
00371
00372 }
00373
00374 G4double G4WeightWindowProcess::
00375 AtRestGetPhysicalInteractionLength(const G4Track& ,
00376 G4ForceCondition*)
00377 {
00378 return -1.0;
00379 }
00380
00381 G4VParticleChange* G4WeightWindowProcess::
00382 AtRestDoIt(const G4Track&, const G4Step&)
00383 {
00384 return 0;
00385 }
00386
00387 G4VParticleChange* G4WeightWindowProcess::
00388 AlongStepDoIt(const G4Track& track, const G4Step&)
00389 {
00390
00391
00392 pParticleChange->Initialize(track);
00393 return pParticleChange;
00394
00395
00396 }
00397
00398 void G4WeightWindowProcess::CopyStep(const G4Step & step)
00399 {
00400 fGhostStep->SetTrack(step.GetTrack());
00401 fGhostStep->SetStepLength(step.GetStepLength());
00402 fGhostStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
00403 fGhostStep->SetControlFlag(step.GetControlFlag());
00404
00405 *fGhostPreStepPoint = *(step.GetPreStepPoint());
00406 *fGhostPostStepPoint = *(step.GetPostStepPoint());
00407
00408
00409
00410
00411 if(fOnBoundary)
00412 { fGhostPostStepPoint->SetStepStatus(fGeomBoundary); }
00413 else if(fGhostPostStepPoint->GetStepStatus()==fGeomBoundary)
00414 { fGhostPostStepPoint->SetStepStatus(fPostStepDoItProc); }
00415
00416 }