File indexing completed on 2026-09-08 08:29:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "EmStandardPhysicsTrackingManager.hh"
0035
0036 #include "TrackingManagerHelper.hh"
0037
0038 #include "G4ComptonScattering.hh"
0039 #include "G4CoulombScattering.hh"
0040 #include "G4Electron.hh"
0041 #include "G4EmParameters.hh"
0042 #include "G4Gamma.hh"
0043 #include "G4GammaConversion.hh"
0044 #include "G4KleinNishinaModel.hh"
0045 #include "G4LivermorePhotoElectricModel.hh"
0046 #include "G4LivermorePolarizedRayleighModel.hh"
0047 #include "G4PhotoElectricAngularGeneratorPolarized.hh"
0048 #include "G4PhotoElectricEffect.hh"
0049 #include "G4Positron.hh"
0050 #include "G4RayleighScattering.hh"
0051 #include "G4SystemOfUnits.hh"
0052 #include "G4UrbanMscModel.hh"
0053 #include "G4WentzelVIModel.hh"
0054 #include "G4eBremsstrahlung.hh"
0055 #include "G4eCoulombScatteringModel.hh"
0056 #include "G4eIonisation.hh"
0057 #include "G4eMultipleScattering.hh"
0058 #include "G4eplusAnnihilation.hh"
0059
0060
0061
0062 EmStandardPhysicsTrackingManager* EmStandardPhysicsTrackingManager::fMasterTrackingManager =
0063 nullptr;
0064
0065
0066
0067 EmStandardPhysicsTrackingManager::EmStandardPhysicsTrackingManager()
0068 {
0069 G4EmParameters* param = G4EmParameters::Instance();
0070 G4double highEnergyLimit = param->MscEnergyLimit();
0071 G4bool polar = param->EnablePolarisation();
0072
0073
0074 {
0075 G4eMultipleScattering* msc = new G4eMultipleScattering;
0076 G4UrbanMscModel* msc1 = new G4UrbanMscModel;
0077 G4WentzelVIModel* msc2 = new G4WentzelVIModel;
0078 msc1->SetHighEnergyLimit(highEnergyLimit);
0079 msc2->SetLowEnergyLimit(highEnergyLimit);
0080 msc->SetEmModel(msc1);
0081 msc->SetEmModel(msc2);
0082 fElectronProcs.msc = msc;
0083
0084 fElectronProcs.ioni = new G4eIonisation;
0085 fElectronProcs.brems = new G4eBremsstrahlung;
0086
0087 G4CoulombScattering* ss = new G4CoulombScattering;
0088 G4eCoulombScatteringModel* ssm = new G4eCoulombScatteringModel;
0089 ssm->SetLowEnergyLimit(highEnergyLimit);
0090 ssm->SetActivationLowEnergyLimit(highEnergyLimit);
0091 ss->SetEmModel(ssm);
0092 ss->SetMinKinEnergy(highEnergyLimit);
0093 fElectronProcs.ss = ss;
0094 }
0095
0096
0097 {
0098 G4eMultipleScattering* msc = new G4eMultipleScattering;
0099 G4UrbanMscModel* msc1 = new G4UrbanMscModel;
0100 G4WentzelVIModel* msc2 = new G4WentzelVIModel;
0101 msc1->SetHighEnergyLimit(highEnergyLimit);
0102 msc2->SetLowEnergyLimit(highEnergyLimit);
0103 msc->SetEmModel(msc1);
0104 msc->SetEmModel(msc2);
0105 fPositronProcs.msc = msc;
0106
0107 fPositronProcs.ioni = new G4eIonisation;
0108 fPositronProcs.brems = new G4eBremsstrahlung;
0109 fPositronProcs.annihilation = new G4eplusAnnihilation;
0110
0111 G4CoulombScattering* ss = new G4CoulombScattering;
0112 G4eCoulombScatteringModel* ssm = new G4eCoulombScatteringModel;
0113 ssm->SetLowEnergyLimit(highEnergyLimit);
0114 ssm->SetActivationLowEnergyLimit(highEnergyLimit);
0115 ss->SetEmModel(ssm);
0116 ss->SetMinKinEnergy(highEnergyLimit);
0117 fPositronProcs.ss = ss;
0118 }
0119
0120 {
0121 G4PhotoElectricEffect* pe = new G4PhotoElectricEffect;
0122 G4VEmModel* peModel = new G4LivermorePhotoElectricModel;
0123 if (polar) {
0124 peModel->SetAngularDistribution(new G4PhotoElectricAngularGeneratorPolarized);
0125 }
0126 pe->SetEmModel(peModel);
0127 fGammaProcs.pe = pe;
0128
0129 G4ComptonScattering* cs = new G4ComptonScattering;
0130 if (polar) {
0131 cs->SetEmModel(new G4KleinNishinaModel);
0132 }
0133 fGammaProcs.compton = cs;
0134
0135 fGammaProcs.conversion = new G4GammaConversion;
0136
0137 G4RayleighScattering* rl = new G4RayleighScattering;
0138 if (polar) {
0139 rl->SetEmModel(new G4LivermorePolarizedRayleighModel);
0140 }
0141 fGammaProcs.rayleigh = rl;
0142 }
0143
0144 if (fMasterTrackingManager == nullptr) {
0145 fMasterTrackingManager = this;
0146 }
0147 else {
0148 fElectronProcs.msc->SetMasterProcess(fMasterTrackingManager->fElectronProcs.msc);
0149 fElectronProcs.ss->SetMasterProcess(fMasterTrackingManager->fElectronProcs.ss);
0150 fElectronProcs.ioni->SetMasterProcess(fMasterTrackingManager->fElectronProcs.ioni);
0151 fElectronProcs.brems->SetMasterProcess(fMasterTrackingManager->fElectronProcs.brems);
0152
0153 fPositronProcs.msc->SetMasterProcess(fMasterTrackingManager->fPositronProcs.msc);
0154 fPositronProcs.ss->SetMasterProcess(fMasterTrackingManager->fPositronProcs.ss);
0155 fPositronProcs.ioni->SetMasterProcess(fMasterTrackingManager->fPositronProcs.ioni);
0156 fPositronProcs.brems->SetMasterProcess(fMasterTrackingManager->fPositronProcs.brems);
0157 fPositronProcs.annihilation->SetMasterProcess(
0158 fMasterTrackingManager->fPositronProcs.annihilation);
0159
0160 fGammaProcs.pe->SetMasterProcess(fMasterTrackingManager->fGammaProcs.pe);
0161 fGammaProcs.compton->SetMasterProcess(fMasterTrackingManager->fGammaProcs.compton);
0162 fGammaProcs.conversion->SetMasterProcess(fMasterTrackingManager->fGammaProcs.conversion);
0163 fGammaProcs.rayleigh->SetMasterProcess(fMasterTrackingManager->fGammaProcs.rayleigh);
0164 }
0165 }
0166
0167
0168
0169 EmStandardPhysicsTrackingManager::~EmStandardPhysicsTrackingManager()
0170 {
0171 if (fMasterTrackingManager == this) {
0172 fMasterTrackingManager = nullptr;
0173 }
0174 }
0175
0176
0177
0178 void EmStandardPhysicsTrackingManager::BuildPhysicsTable(const G4ParticleDefinition& part)
0179 {
0180 if (&part == G4Electron::Definition()) {
0181 fElectronProcs.msc->BuildPhysicsTable(part);
0182 fElectronProcs.ioni->BuildPhysicsTable(part);
0183 fElectronProcs.brems->BuildPhysicsTable(part);
0184 fElectronProcs.ss->BuildPhysicsTable(part);
0185 }
0186 else if (&part == G4Positron::Definition()) {
0187 fPositronProcs.msc->BuildPhysicsTable(part);
0188 fPositronProcs.ioni->BuildPhysicsTable(part);
0189 fPositronProcs.brems->BuildPhysicsTable(part);
0190 fPositronProcs.annihilation->BuildPhysicsTable(part);
0191 fPositronProcs.ss->BuildPhysicsTable(part);
0192 }
0193 else if (&part == G4Gamma::Definition()) {
0194 fGammaProcs.pe->BuildPhysicsTable(part);
0195 fGammaProcs.compton->BuildPhysicsTable(part);
0196 fGammaProcs.conversion->BuildPhysicsTable(part);
0197 fGammaProcs.rayleigh->BuildPhysicsTable(part);
0198 }
0199 }
0200
0201
0202
0203 void EmStandardPhysicsTrackingManager::PreparePhysicsTable(const G4ParticleDefinition& part)
0204 {
0205 if (&part == G4Electron::Definition()) {
0206 fElectronProcs.msc->PreparePhysicsTable(part);
0207 fElectronProcs.ioni->PreparePhysicsTable(part);
0208 fElectronProcs.brems->PreparePhysicsTable(part);
0209 fElectronProcs.ss->PreparePhysicsTable(part);
0210 }
0211 else if (&part == G4Positron::Definition()) {
0212 fPositronProcs.msc->PreparePhysicsTable(part);
0213 fPositronProcs.ioni->PreparePhysicsTable(part);
0214 fPositronProcs.brems->PreparePhysicsTable(part);
0215 fPositronProcs.annihilation->PreparePhysicsTable(part);
0216 fPositronProcs.ss->PreparePhysicsTable(part);
0217 }
0218 else if (&part == G4Gamma::Definition()) {
0219 fGammaProcs.pe->PreparePhysicsTable(part);
0220 fGammaProcs.compton->PreparePhysicsTable(part);
0221 fGammaProcs.conversion->PreparePhysicsTable(part);
0222 fGammaProcs.rayleigh->PreparePhysicsTable(part);
0223 }
0224 }
0225
0226
0227
0228 void EmStandardPhysicsTrackingManager::TrackElectron(G4Track* aTrack)
0229 {
0230 class ElectronPhysics final : public TrackingManagerHelper::Physics
0231 {
0232 public:
0233 ElectronPhysics(EmStandardPhysicsTrackingManager& mgr) : fMgr(mgr) {}
0234
0235 void StartTracking(G4Track* aTrack) override
0236 {
0237 auto& electronProcs = fMgr.fElectronProcs;
0238
0239 electronProcs.msc->StartTracking(aTrack);
0240 electronProcs.ioni->StartTracking(aTrack);
0241 electronProcs.brems->StartTracking(aTrack);
0242 electronProcs.ss->StartTracking(aTrack);
0243
0244 fPreviousStepLength = 0;
0245 }
0246 void EndTracking() override
0247 {
0248 auto& electronProcs = fMgr.fElectronProcs;
0249
0250 electronProcs.msc->EndTracking();
0251 electronProcs.ioni->EndTracking();
0252 electronProcs.brems->EndTracking();
0253 electronProcs.ss->EndTracking();
0254 }
0255
0256 G4double GetPhysicalInteractionLength(const G4Track& track) override
0257 {
0258 auto& electronProcs = fMgr.fElectronProcs;
0259 G4double physIntLength, proposedSafety = DBL_MAX;
0260 G4ForceCondition condition;
0261 G4GPILSelection selection;
0262
0263 fProposedStep = DBL_MAX;
0264 fSelected = -1;
0265
0266 physIntLength = electronProcs.ss->PostStepGPIL(track, fPreviousStepLength, &condition);
0267 if (physIntLength < fProposedStep) {
0268 fProposedStep = physIntLength;
0269 fSelected = 0;
0270 }
0271
0272 physIntLength = electronProcs.brems->PostStepGPIL(track, fPreviousStepLength, &condition);
0273 if (physIntLength < fProposedStep) {
0274 fProposedStep = physIntLength;
0275 fSelected = 1;
0276 }
0277
0278 physIntLength = electronProcs.ioni->PostStepGPIL(track, fPreviousStepLength, &condition);
0279 if (physIntLength < fProposedStep) {
0280 fProposedStep = physIntLength;
0281 fSelected = 2;
0282 }
0283
0284 physIntLength = electronProcs.ioni->AlongStepGPIL(track, fPreviousStepLength, fProposedStep,
0285 proposedSafety, &selection);
0286 if (physIntLength < fProposedStep) {
0287 fProposedStep = physIntLength;
0288 fSelected = -1;
0289 }
0290
0291 physIntLength = electronProcs.msc->AlongStepGPIL(track, fPreviousStepLength, fProposedStep,
0292 proposedSafety, &selection);
0293 if (physIntLength < fProposedStep) {
0294 fProposedStep = physIntLength;
0295
0296
0297 if (selection == CandidateForSelection) {
0298 fSelected = -1;
0299 }
0300 }
0301
0302 return fProposedStep;
0303 }
0304
0305 void AlongStepDoIt(G4Track& track, G4Step& step, G4TrackVector&) override
0306 {
0307 if (step.GetStepLength() == fProposedStep) {
0308 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc);
0309 }
0310 else {
0311
0312 fSelected = -1;
0313 }
0314 auto& electronProcs = fMgr.fElectronProcs;
0315 G4VParticleChange* particleChange;
0316
0317 particleChange = electronProcs.msc->AlongStepDoIt(track, step);
0318 particleChange->UpdateStepForAlongStep(&step);
0319 track.SetTrackStatus(particleChange->GetTrackStatus());
0320 particleChange->Clear();
0321
0322 particleChange = electronProcs.ioni->AlongStepDoIt(track, step);
0323 particleChange->UpdateStepForAlongStep(&step);
0324 track.SetTrackStatus(particleChange->GetTrackStatus());
0325 particleChange->Clear();
0326
0327 fPreviousStepLength = step.GetStepLength();
0328 }
0329
0330 void PostStepDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override
0331 {
0332 if (fSelected < 0) {
0333 return;
0334 }
0335 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc);
0336
0337 auto& electronProcs = fMgr.fElectronProcs;
0338 G4VProcess* process = nullptr;
0339 G4VParticleChange* particleChange = nullptr;
0340
0341 switch (fSelected) {
0342 case 0:
0343 process = electronProcs.ss;
0344 particleChange = electronProcs.ss->PostStepDoIt(track, step);
0345 break;
0346 case 1:
0347 process = electronProcs.brems;
0348 particleChange = electronProcs.brems->PostStepDoIt(track, step);
0349 break;
0350 case 2:
0351 process = electronProcs.ioni;
0352 particleChange = electronProcs.ioni->PostStepDoIt(track, step);
0353 break;
0354 }
0355
0356 particleChange->UpdateStepForPostStep(&step);
0357 step.UpdateTrack();
0358
0359 G4int numSecondaries = particleChange->GetNumberOfSecondaries();
0360 for (G4int i = 0; i < numSecondaries; ++i) {
0361 G4Track* secondary = particleChange->GetSecondary(i);
0362 secondary->SetParentID(track.GetTrackID());
0363 secondary->SetCreatorProcess(process);
0364 secondaries.push_back(secondary);
0365 }
0366
0367 track.SetTrackStatus(particleChange->GetTrackStatus());
0368 particleChange->Clear();
0369 }
0370
0371 private:
0372 EmStandardPhysicsTrackingManager& fMgr;
0373 G4double fPreviousStepLength;
0374 G4double fProposedStep;
0375 G4int fSelected;
0376 };
0377
0378 ElectronPhysics physics(*this);
0379 TrackingManagerHelper::TrackChargedParticle(aTrack, physics);
0380 }
0381
0382
0383
0384 void EmStandardPhysicsTrackingManager::TrackPositron(G4Track* aTrack)
0385 {
0386 class PositronPhysics final : public TrackingManagerHelper::Physics
0387 {
0388 public:
0389 PositronPhysics(EmStandardPhysicsTrackingManager& mgr) : fMgr(mgr) {}
0390
0391 void StartTracking(G4Track* aTrack) override
0392 {
0393 auto& positronProcs = fMgr.fPositronProcs;
0394
0395 positronProcs.msc->StartTracking(aTrack);
0396 positronProcs.ioni->StartTracking(aTrack);
0397 positronProcs.brems->StartTracking(aTrack);
0398 positronProcs.annihilation->StartTracking(aTrack);
0399 positronProcs.ss->StartTracking(aTrack);
0400
0401 fPreviousStepLength = 0;
0402 }
0403 void EndTracking() override
0404 {
0405 auto& positronProcs = fMgr.fPositronProcs;
0406
0407 positronProcs.msc->EndTracking();
0408 positronProcs.ioni->EndTracking();
0409 positronProcs.brems->EndTracking();
0410 positronProcs.annihilation->EndTracking();
0411 positronProcs.ss->EndTracking();
0412 }
0413
0414 G4double GetPhysicalInteractionLength(const G4Track& track) override
0415 {
0416 auto& positronProcs = fMgr.fPositronProcs;
0417 G4double physIntLength, proposedSafety = DBL_MAX;
0418 G4ForceCondition condition;
0419 G4GPILSelection selection;
0420
0421 fProposedStep = DBL_MAX;
0422 fSelected = -1;
0423
0424 physIntLength = positronProcs.ss->PostStepGPIL(track, fPreviousStepLength, &condition);
0425 if (physIntLength < fProposedStep) {
0426 fProposedStep = physIntLength;
0427 fSelected = 0;
0428 }
0429
0430 physIntLength =
0431 positronProcs.annihilation->PostStepGPIL(track, fPreviousStepLength, &condition);
0432 if (physIntLength < fProposedStep) {
0433 fProposedStep = physIntLength;
0434 fSelected = 1;
0435 }
0436
0437 physIntLength = positronProcs.brems->PostStepGPIL(track, fPreviousStepLength, &condition);
0438 if (physIntLength < fProposedStep) {
0439 fProposedStep = physIntLength;
0440 fSelected = 2;
0441 }
0442
0443 physIntLength = positronProcs.ioni->PostStepGPIL(track, fPreviousStepLength, &condition);
0444 if (physIntLength < fProposedStep) {
0445 fProposedStep = physIntLength;
0446 fSelected = 3;
0447 }
0448
0449 physIntLength = positronProcs.ioni->AlongStepGPIL(track, fPreviousStepLength, fProposedStep,
0450 proposedSafety, &selection);
0451 if (physIntLength < fProposedStep) {
0452 fProposedStep = physIntLength;
0453 fSelected = -1;
0454 }
0455
0456 physIntLength = positronProcs.msc->AlongStepGPIL(track, fPreviousStepLength, fProposedStep,
0457 proposedSafety, &selection);
0458 if (physIntLength < fProposedStep) {
0459 fProposedStep = physIntLength;
0460
0461
0462 if (selection == CandidateForSelection) {
0463 fSelected = -1;
0464 }
0465 }
0466
0467 return fProposedStep;
0468 }
0469
0470 void AlongStepDoIt(G4Track& track, G4Step& step, G4TrackVector&) override
0471 {
0472 if (step.GetStepLength() == fProposedStep) {
0473 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc);
0474 }
0475 else {
0476
0477 fSelected = -1;
0478 }
0479 auto& positronProcs = fMgr.fPositronProcs;
0480 G4VParticleChange* particleChange;
0481
0482 particleChange = positronProcs.msc->AlongStepDoIt(track, step);
0483 particleChange->UpdateStepForAlongStep(&step);
0484 track.SetTrackStatus(particleChange->GetTrackStatus());
0485 particleChange->Clear();
0486
0487 particleChange = positronProcs.ioni->AlongStepDoIt(track, step);
0488 particleChange->UpdateStepForAlongStep(&step);
0489 track.SetTrackStatus(particleChange->GetTrackStatus());
0490 particleChange->Clear();
0491
0492 fPreviousStepLength = step.GetStepLength();
0493 }
0494
0495 void PostStepDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override
0496 {
0497 if (fSelected < 0) {
0498 return;
0499 }
0500 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc);
0501
0502 auto& positronProcs = fMgr.fPositronProcs;
0503 G4VProcess* process = nullptr;
0504 G4VParticleChange* particleChange = nullptr;
0505
0506 switch (fSelected) {
0507 case 0:
0508 process = positronProcs.ss;
0509 particleChange = positronProcs.ss->PostStepDoIt(track, step);
0510 break;
0511 case 1:
0512 process = positronProcs.annihilation;
0513 particleChange = positronProcs.annihilation->PostStepDoIt(track, step);
0514 break;
0515 case 2:
0516 process = positronProcs.brems;
0517 particleChange = positronProcs.brems->PostStepDoIt(track, step);
0518 break;
0519 case 3:
0520 process = positronProcs.ioni;
0521 particleChange = positronProcs.ioni->PostStepDoIt(track, step);
0522 break;
0523 }
0524
0525 particleChange->UpdateStepForPostStep(&step);
0526 step.UpdateTrack();
0527
0528 G4int numSecondaries = particleChange->GetNumberOfSecondaries();
0529 for (G4int i = 0; i < numSecondaries; ++i) {
0530 G4Track* secondary = particleChange->GetSecondary(i);
0531 secondary->SetParentID(track.GetTrackID());
0532 secondary->SetCreatorProcess(process);
0533 secondaries.push_back(secondary);
0534 }
0535
0536 track.SetTrackStatus(particleChange->GetTrackStatus());
0537 particleChange->Clear();
0538 }
0539
0540 G4bool HasAtRestProcesses() override { return true; }
0541
0542 void AtRestDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override
0543 {
0544 auto& positronProcs = fMgr.fPositronProcs;
0545
0546 G4VParticleChange* particleChange = positronProcs.annihilation->AtRestDoIt(track, step);
0547 particleChange->UpdateStepForAtRest(&step);
0548 step.UpdateTrack();
0549
0550 G4int numSecondaries = particleChange->GetNumberOfSecondaries();
0551 for (G4int i = 0; i < numSecondaries; ++i) {
0552 G4Track* secondary = particleChange->GetSecondary(i);
0553 secondary->SetParentID(track.GetTrackID());
0554 secondary->SetCreatorProcess(positronProcs.annihilation);
0555 secondaries.push_back(secondary);
0556 }
0557
0558 track.SetTrackStatus(particleChange->GetTrackStatus());
0559 particleChange->Clear();
0560 }
0561
0562 private:
0563 EmStandardPhysicsTrackingManager& fMgr;
0564 G4double fPreviousStepLength;
0565 G4double fProposedStep;
0566 G4int fSelected;
0567 };
0568
0569 PositronPhysics physics(*this);
0570 TrackingManagerHelper::TrackChargedParticle(aTrack, physics);
0571 }
0572
0573
0574
0575 void EmStandardPhysicsTrackingManager::TrackGamma(G4Track* aTrack)
0576 {
0577 class GammaPhysics final : public TrackingManagerHelper::Physics
0578 {
0579 public:
0580 GammaPhysics(EmStandardPhysicsTrackingManager& mgr) : fMgr(mgr) {}
0581
0582 void StartTracking(G4Track* aTrack) override
0583 {
0584 auto& gammaProcs = fMgr.fGammaProcs;
0585
0586 gammaProcs.pe->StartTracking(aTrack);
0587 gammaProcs.compton->StartTracking(aTrack);
0588 gammaProcs.conversion->StartTracking(aTrack);
0589 gammaProcs.rayleigh->StartTracking(aTrack);
0590
0591 fPreviousStepLength = 0;
0592 }
0593 void EndTracking() override
0594 {
0595 auto& gammaProcs = fMgr.fGammaProcs;
0596
0597 gammaProcs.pe->EndTracking();
0598 gammaProcs.compton->EndTracking();
0599 gammaProcs.conversion->EndTracking();
0600 gammaProcs.rayleigh->EndTracking();
0601 }
0602
0603 G4double GetPhysicalInteractionLength(const G4Track& track) override
0604 {
0605 auto& gammaProcs = fMgr.fGammaProcs;
0606 G4double physIntLength;
0607 G4ForceCondition condition;
0608
0609 fProposedStep = DBL_MAX;
0610 fSelected = -1;
0611
0612 physIntLength = gammaProcs.rayleigh->PostStepGPIL(track, fPreviousStepLength, &condition);
0613 if (physIntLength < fProposedStep) {
0614 fProposedStep = physIntLength;
0615 fSelected = 0;
0616 }
0617
0618 physIntLength = gammaProcs.conversion->PostStepGPIL(track, fPreviousStepLength, &condition);
0619 if (physIntLength < fProposedStep) {
0620 fProposedStep = physIntLength;
0621 fSelected = 1;
0622 }
0623
0624 physIntLength = gammaProcs.compton->PostStepGPIL(track, fPreviousStepLength, &condition);
0625 if (physIntLength < fProposedStep) {
0626 fProposedStep = physIntLength;
0627 fSelected = 2;
0628 }
0629
0630 physIntLength = gammaProcs.pe->PostStepGPIL(track, fPreviousStepLength, &condition);
0631 if (physIntLength < fProposedStep) {
0632 fProposedStep = physIntLength;
0633 fSelected = 3;
0634 }
0635
0636 return fProposedStep;
0637 }
0638
0639 void AlongStepDoIt(G4Track&, G4Step& step, G4TrackVector&) override
0640 {
0641 if (step.GetStepLength() == fProposedStep) {
0642 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc);
0643 }
0644 else {
0645
0646 fSelected = -1;
0647 }
0648 fPreviousStepLength = step.GetStepLength();
0649 }
0650
0651 void PostStepDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override
0652 {
0653 if (fSelected < 0) {
0654 return;
0655 }
0656 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc);
0657
0658 auto& gammaProcs = fMgr.fGammaProcs;
0659 G4VProcess* process = nullptr;
0660 G4VParticleChange* particleChange = nullptr;
0661
0662 switch (fSelected) {
0663 case 0:
0664 process = gammaProcs.rayleigh;
0665 particleChange = gammaProcs.rayleigh->PostStepDoIt(track, step);
0666 break;
0667 case 1:
0668 process = gammaProcs.conversion;
0669 particleChange = gammaProcs.conversion->PostStepDoIt(track, step);
0670 break;
0671 case 2:
0672 process = gammaProcs.compton;
0673 particleChange = gammaProcs.compton->PostStepDoIt(track, step);
0674 break;
0675 case 3:
0676 process = gammaProcs.pe;
0677 particleChange = gammaProcs.pe->PostStepDoIt(track, step);
0678 break;
0679 }
0680
0681 particleChange->UpdateStepForPostStep(&step);
0682 step.UpdateTrack();
0683
0684 G4int numSecondaries = particleChange->GetNumberOfSecondaries();
0685 for (G4int i = 0; i < numSecondaries; ++i) {
0686 G4Track* secondary = particleChange->GetSecondary(i);
0687 secondary->SetParentID(track.GetTrackID());
0688 secondary->SetCreatorProcess(process);
0689 secondaries.push_back(secondary);
0690 }
0691
0692 track.SetTrackStatus(particleChange->GetTrackStatus());
0693 particleChange->Clear();
0694 }
0695
0696 private:
0697 EmStandardPhysicsTrackingManager& fMgr;
0698 G4double fPreviousStepLength;
0699 G4double fProposedStep;
0700 G4int fSelected;
0701 };
0702
0703 GammaPhysics physics(*this);
0704 TrackingManagerHelper::TrackNeutralParticle(aTrack, physics);
0705 }
0706
0707
0708
0709 void EmStandardPhysicsTrackingManager::HandOverOneTrack(G4Track* aTrack)
0710 {
0711 const G4ParticleDefinition* part = aTrack->GetParticleDefinition();
0712
0713 if (part == G4Electron::Definition()) {
0714 TrackElectron(aTrack);
0715 }
0716 else if (part == G4Positron::Definition()) {
0717 TrackPositron(aTrack);
0718 }
0719 else if (part == G4Gamma::Definition()) {
0720 TrackGamma(aTrack);
0721 }
0722
0723 aTrack->SetTrackStatus(fStopAndKill);
0724 delete aTrack;
0725 }
0726
0727