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