Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4EmBiasingManager.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// -------------------------------------------------------------------
28//
29// GEANT4 Class file
30//
31//
32// File name: G4EmBiasingManager
33//
34// Author: Vladimir Ivanchenko
35//
36// Creation date: 28.07.2011
37//
38// Modifications:
39//
40// 31-05-12 D. Sawkey put back in high energy limit for brem, russian roulette
41// 30-05-12 D. Sawkey brem split gammas are unique; do weight tests for
42// brem, russian roulette
43// -------------------------------------------------------------------
44//
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
47
48#include "G4EmBiasingManager.hh"
49#include "G4SystemOfUnits.hh"
53#include "G4ProductionCuts.hh"
54#include "G4Region.hh"
55#include "G4RegionStore.hh"
56#include "G4Track.hh"
57#include "G4Electron.hh"
58#include "G4Gamma.hh"
59#include "G4VEmModel.hh"
60#include "G4LossTableManager.hh"
63#include "G4EmParameters.hh"
64
65//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
66
68 : fDirectionalSplittingTarget(0.0,0.0,0.0)
69{
70 fSafetyMin = 1.e-6*mm;
71 theElectron = G4Electron::Electron();
72 theGamma = G4Gamma::Gamma();
73}
74
75//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
76
78
79//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
80
82 const G4String& procName, G4int verbose)
83{
84 //G4cout << "G4EmBiasingManager::Initialise for "
85 // << part.GetParticleName()
86 // << " and " << procName << G4endl;
87 const G4ProductionCutsTable* theCoupleTable=
89 G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
90
91 if(0 < nForcedRegions) { idxForcedCouple.resize(numOfCouples, -1); }
92 if(0 < nSecBiasedRegions) { idxSecBiasedCouple.resize(numOfCouples, -1); }
93
94 // Deexcitation
95 for (G4int j=0; j<numOfCouples; ++j) {
96 const G4MaterialCutsCouple* couple =
97 theCoupleTable->GetMaterialCutsCouple(j);
98 const G4ProductionCuts* pcuts = couple->GetProductionCuts();
99 if(0 < nForcedRegions) {
100 for(G4int i=0; i<nForcedRegions; ++i) {
101 if(forcedRegions[i]) {
102 if(pcuts == forcedRegions[i]->GetProductionCuts()) {
103 idxForcedCouple[j] = i;
104 break;
105 }
106 }
107 }
108 }
109 if(0 < nSecBiasedRegions) {
110 for(G4int i=0; i<nSecBiasedRegions; ++i) {
111 if(secBiasedRegions[i]) {
112 if(pcuts == secBiasedRegions[i]->GetProductionCuts()) {
113 idxSecBiasedCouple[j] = i;
114 break;
115 }
116 }
117 }
118 }
119 }
120
123 if (fDirectionalSplitting) {
126 }
127
128 if (nForcedRegions > 0 && 0 < verbose) {
129 G4cout << " Forced Interaction is activated for "
130 << part.GetParticleName() << " and "
131 << procName
132 << " inside G4Regions: " << G4endl;
133 for (G4int i=0; i<nForcedRegions; ++i) {
134 const G4Region* r = forcedRegions[i];
135 if(r) { G4cout << " " << r->GetName() << G4endl; }
136 }
137 }
138 if (nSecBiasedRegions > 0 && 0 < verbose) {
139 G4cout << " Secondary biasing is activated for "
140 << part.GetParticleName() << " and "
141 << procName
142 << " inside G4Regions: " << G4endl;
143 for (G4int i=0; i<nSecBiasedRegions; ++i) {
144 const G4Region* r = secBiasedRegions[i];
145 if(r) {
146 G4cout << " " << r->GetName()
147 << " BiasingWeight= " << secBiasedWeight[i] << G4endl;
148 }
149 }
150 if (fDirectionalSplitting) {
151 G4cout << " Directional splitting activated, with target position: "
152 << fDirectionalSplittingTarget/cm
153 << " cm; radius: "
154 << fDirectionalSplittingRadius/cm
155 << "cm." << G4endl;
156 }
157 }
158}
159
160//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
161
163 const G4String& rname)
164{
166 G4String name = rname;
167 if(name == "" || name == "world" || name == "World") {
168 name = "DefaultRegionForTheWorld";
169 }
170 const G4Region* reg = regionStore->GetRegion(name, false);
171 if(!reg) {
172 G4cout << "### G4EmBiasingManager::ForcedInteraction WARNING: "
173 << " G4Region <"
174 << rname << "> is unknown" << G4endl;
175 return;
176 }
177
178 // the region is in the list
179 if (0 < nForcedRegions) {
180 for (G4int i=0; i<nForcedRegions; ++i) {
181 if (reg == forcedRegions[i]) {
182 lengthForRegion[i] = val;
183 return;
184 }
185 }
186 }
187 if(val < 0.0) {
188 G4cout << "### G4EmBiasingManager::ForcedInteraction WARNING: "
189 << val << " < 0.0, so no activation for the G4Region <"
190 << rname << ">" << G4endl;
191 return;
192 }
193
194 // new region
195 forcedRegions.push_back(reg);
196 lengthForRegion.push_back(val);
197 ++nForcedRegions;
198}
199
200//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
201
202void
204 G4double factor,
205 G4double energyLimit)
206{
207 //G4cout << "G4EmBiasingManager::ActivateSecondaryBiasing: "
208 // << rname << " F= " << factor << " E(MeV)= " << energyLimit/MeV
209 // << G4endl;
211 G4String name = rname;
212 if(name == "" || name == "world" || name == "World") {
213 name = "DefaultRegionForTheWorld";
214 }
215 const G4Region* reg = regionStore->GetRegion(name, false);
216 if(!reg) {
217 G4cout << "### G4EmBiasingManager::ActivateBremsstrahlungSplitting "
218 << "WARNING: G4Region <"
219 << rname << "> is unknown" << G4endl;
220 return;
221 }
222
223 // Range cut
224 G4int nsplit = 0;
225 G4double w = factor;
226
227 // splitting
228 if(factor >= 1.0) {
229 nsplit = G4lrint(factor);
230 w = 1.0/G4double(nsplit);
231
232 // Russian roulette
233 } else if(0.0 < factor) {
234 nsplit = 1;
235 w = 1.0/factor;
236 }
237
238 // the region is in the list - overwrite parameters
239 if (0 < nSecBiasedRegions) {
240 for (G4int i=0; i<nSecBiasedRegions; ++i) {
241 if (reg == secBiasedRegions[i]) {
242 secBiasedWeight[i] = w;
243 nBremSplitting[i] = nsplit;
244 secBiasedEnegryLimit[i] = energyLimit;
245 return;
246 }
247 }
248 }
249 /*
250 G4cout << "### G4EmBiasingManager::ActivateSecondaryBiasing: "
251 << " nsplit= " << nsplit << " for the G4Region <"
252 << rname << ">" << G4endl;
253 */
254
255 // new region
256 secBiasedRegions.push_back(reg);
257 secBiasedWeight.push_back(w);
258 nBremSplitting.push_back(nsplit);
259 secBiasedEnegryLimit.push_back(energyLimit);
260 ++nSecBiasedRegions;
261 //G4cout << "nSecBiasedRegions= " << nSecBiasedRegions << G4endl;
262}
263
264//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
265
267 G4double previousStep)
268{
269 if(startTracking) {
270 startTracking = false;
271 G4int i = idxForcedCouple[coupleIdx];
272 if(i < 0) {
273 currentStepLimit = DBL_MAX;
274 } else {
275 currentStepLimit = lengthForRegion[i];
276 if(currentStepLimit > 0.0) { currentStepLimit *= G4UniformRand(); }
277 }
278 } else {
279 currentStepLimit -= previousStep;
280 }
281 if(currentStepLimit < 0.0) { currentStepLimit = 0.0; }
282 return currentStepLimit;
283}
284
285//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
286
289 std::vector<G4DynamicParticle*>& vd,
290 const G4Track& track,
291 G4VEmModel* currentModel,
292 G4ParticleChangeForLoss* pPartChange,
293 G4double& eloss,
294 G4int coupleIdx,
295 G4double tcut,
296 G4double safety)
297{
298 G4int index = idxSecBiasedCouple[coupleIdx];
299 G4double weight = 1.;
300 if(0 <= index) {
301 std::size_t n = vd.size();
302
303 // the check cannot be applied per secondary particle
304 // because weight correction is common, so the first
305 // secondary is checked
306 if((0 < n && vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[index])
307 || fDirectionalSplitting) {
308
309 G4int nsplit = nBremSplitting[index];
310
311 // Range cut
312 if(0 == nsplit) {
313 if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
314
315 // Russian Roulette
316 } else if(1 == nsplit) {
317 weight = ApplyRussianRoulette(vd, index);
318
319 // Splitting
320 } else {
321 if (fDirectionalSplitting) {
322 weight = ApplyDirectionalSplitting(vd, track, currentModel, index, tcut);
323 } else {
324 G4double tmpEnergy = pPartChange->GetProposedKineticEnergy();
325 G4ThreeVector tmpMomDir = pPartChange->GetProposedMomentumDirection();
326
327 weight = ApplySplitting(vd, track, currentModel, index, tcut);
328
329 pPartChange->SetProposedKineticEnergy(tmpEnergy);
330 pPartChange->ProposeMomentumDirection(tmpMomDir);
331 }
332 }
333 }
334 }
335 return weight;
336}
337
338//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
339
342 std::vector<G4DynamicParticle*>& vd,
343 const G4Track& track,
344 G4VEmModel* currentModel,
345 G4ParticleChangeForGamma* pPartChange,
346 G4double& eloss,
347 G4int coupleIdx,
348 G4double tcut,
349 G4double safety)
350{
351 G4int index = idxSecBiasedCouple[coupleIdx];
352 G4double weight = 1.;
353 if(0 <= index) {
354 std::size_t n = vd.size();
355
356 // the check cannot be applied per secondary particle
357 // because weight correction is common, so the first
358 // secondary is checked
359 if((0 < n && vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[index])
360 || fDirectionalSplitting) {
361
362 G4int nsplit = nBremSplitting[index];
363
364 // Range cut
365 if(0 == nsplit) {
366 if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
367
368 // Russian Roulette
369 } else if(1 == nsplit) {
370 weight = ApplyRussianRoulette(vd, index);
371
372 // Splitting
373 } else {
374 if (fDirectionalSplitting) {
375 weight = ApplyDirectionalSplitting(vd, track, currentModel,
376 index, tcut, pPartChange);
377 } else {
378 G4double tmpEnergy = pPartChange->GetProposedKineticEnergy();
379 G4ThreeVector tmpMomDir = pPartChange->GetProposedMomentumDirection();
380
381 weight = ApplySplitting(vd, track, currentModel, index, tcut);
382
383 pPartChange->SetProposedKineticEnergy(tmpEnergy);
384 pPartChange->ProposeMomentumDirection(tmpMomDir);
385 }
386 }
387 }
388 }
389 return weight;
390}
391
392//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
393
395G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& track,
396 G4int coupleIdx)
397{
398 G4int index = idxSecBiasedCouple[coupleIdx];
399 G4double weight = 1.;
400 if(0 <= index) {
401 std::size_t n = track.size();
402
403 // the check cannot be applied per secondary particle
404 // because weight correction is common, so the first
405 // secondary is checked
406 if(0 < n && track[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
407
408 G4int nsplit = nBremSplitting[index];
409
410 // Russian Roulette only
411 if(1 == nsplit) {
412 weight = secBiasedWeight[index];
413 for(std::size_t k=0; k<n; ++k) {
414 if(G4UniformRand()*weight > 1.0) {
415 const G4Track* t = track[k];
416 delete t;
417 track[k] = nullptr;
418 }
419 }
420 }
421 }
422 }
423 return weight;
424}
425
426//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
427
428void
429G4EmBiasingManager::ApplyRangeCut(std::vector<G4DynamicParticle*>& vd,
430 const G4Track& track,
431 G4double& eloss, G4double safety)
432{
433 std::size_t n = vd.size();
434 if(!eIonisation) {
435 eIonisation =
437 }
438 if(eIonisation) {
439 for(std::size_t k=0; k<n; ++k) {
440 const G4DynamicParticle* dp = vd[k];
441 if(dp->GetDefinition() == theElectron) {
442 G4double e = dp->GetKineticEnergy();
443 if(eIonisation->GetRange(e, track.GetMaterialCutsCouple()) < safety) {
444 eloss += e;
445 delete dp;
446 vd[k] = nullptr;
447 }
448 }
449 }
450 }
451}
452
453//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
454
456 G4ThreeVector momdir) const
457{
458 G4ThreeVector delta = fDirectionalSplittingTarget - pos;
459 G4double angle = momdir.angle(delta);
460 G4double dist = delta.cross(momdir).mag();
461 if (dist <= fDirectionalSplittingRadius && angle < halfpi) {
462 return true;
463 }
464 return false;
465}
466
467//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
468
470G4EmBiasingManager::ApplySplitting(std::vector<G4DynamicParticle*>& vd,
471 const G4Track& track,
472 G4VEmModel* currentModel,
473 G4int index,
474 G4double tcut)
475{
476 // method is applied only if 1 secondary created PostStep
477 // in the case of many secondaries there is a contradiction
478 G4double weight = 1.;
479 std::size_t n = vd.size();
480 G4double w = secBiasedWeight[index];
481
482 if(1 != n || 1.0 <= w) { return weight; }
483
484 G4double trackWeight = track.GetWeight();
485 const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
486
487 G4int nsplit = nBremSplitting[index];
488
489 // double splitting is suppressed
490 if(1 < nsplit && trackWeight>w) {
491
492 weight = w;
493 if(nsplit > (G4int)tmpSecondaries.size()) {
494 tmpSecondaries.reserve(nsplit);
495 }
496 const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
497 // start from 1, because already one secondary created
498 for(G4int k=1; k<nsplit; ++k) {
499 tmpSecondaries.clear();
500 currentModel->SampleSecondaries(&tmpSecondaries, couple, dynParticle,
501 tcut);
502 for (std::size_t kk=0; kk<tmpSecondaries.size(); ++kk) {
503 vd.push_back(tmpSecondaries[kk]);
504 }
505 }
506 }
507 return weight;
508}
509
510//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
511
513G4EmBiasingManager::ApplyDirectionalSplitting(
514 std::vector<G4DynamicParticle*>& vd,
515 const G4Track& track,
516 G4VEmModel* currentModel,
517 G4int index,
518 G4double tcut,
519 G4ParticleChangeForGamma* partChange)
520{
521 // primary is gamma. do splitting/RR as appropriate
522 // method applied for any number of secondaries
523
524 G4double weight = 1.0;
525 G4double w = secBiasedWeight[index];
526
527 fDirectionalSplittingWeights.clear();
528 if(1.0 <= w) {
529 fDirectionalSplittingWeights.push_back(weight);
530 return weight;
531 }
532
533 G4double trackWeight = track.GetWeight();
534 G4int nsplit = nBremSplitting[index];
535
536 // double splitting is suppressed
537 if(1 < nsplit && trackWeight>w) {
538
539 weight = w;
540 const G4ThreeVector pos = track.GetPosition();
541
542 G4bool foundPrimaryParticle = false;
543 G4double primaryEnergy = 0.;
544 G4ThreeVector primaryMomdir(0.,0.,0.);
545 G4double primaryWeight = trackWeight;
546
547 tmpSecondaries = vd;
548 vd.clear();
549 vd.reserve(nsplit);
550 for (G4int k=0; k<nsplit; ++k) {
551 if (k>0) { // for k==0, SampleSecondaries has already been called
552 tmpSecondaries.clear();
553 // SampleSecondaries modifies primary info stored in partChange
554 currentModel->SampleSecondaries(&tmpSecondaries,
555 track.GetMaterialCutsCouple(),
556 track.GetDynamicParticle(), tcut);
557 }
558 for (std::size_t kk=0; kk<tmpSecondaries.size(); ++kk) {
559 if (tmpSecondaries[kk]->GetParticleDefinition() == theGamma) {
560 if (CheckDirection(pos, tmpSecondaries[kk]->GetMomentumDirection())){
561 vd.push_back(tmpSecondaries[kk]);
562 fDirectionalSplittingWeights.push_back(1.);
563 } else if (G4UniformRand() < w) {
564 vd.push_back(tmpSecondaries[kk]);
565 fDirectionalSplittingWeights.push_back(1./weight);
566 } else {
567 delete tmpSecondaries[kk];
568 tmpSecondaries[kk] = nullptr;
569 }
570 } else if (k==0) { // keep charged 2ry from first splitting
571 vd.push_back(tmpSecondaries[kk]);
572 fDirectionalSplittingWeights.push_back(1./weight);
573 } else {
574 delete tmpSecondaries[kk];
575 tmpSecondaries[kk] = nullptr;
576 }
577 }
578
579 // primary
580 G4double en = partChange->GetProposedKineticEnergy();
581 if (en>0.) { // don't add if kinetic energy = 0
582 G4ThreeVector momdir = partChange->GetProposedMomentumDirection();
583 if (CheckDirection(pos,momdir)) {
584 // keep only one primary; others are secondaries
585 if (!foundPrimaryParticle) {
586 primaryEnergy = en;
587 primaryMomdir = momdir;
588 foundPrimaryParticle = true;
589 primaryWeight = weight;
590 } else {
591 auto dp = new G4DynamicParticle(theGamma,
592 partChange->GetProposedMomentumDirection(),
593 partChange->GetProposedKineticEnergy());
594 vd.push_back(dp);
595 fDirectionalSplittingWeights.push_back(1.);
596 }
597 } else if (G4UniformRand()<w) { // not going to target. play RR.
598 if (!foundPrimaryParticle) {
599 foundPrimaryParticle = true;
600 primaryEnergy = en;
601 primaryMomdir = momdir;
602 primaryWeight = 1.;
603 } else {
604 auto dp = new G4DynamicParticle(theGamma,
605 partChange->GetProposedMomentumDirection(),
606 partChange->GetProposedKineticEnergy());
607 vd.push_back(dp);
608 fDirectionalSplittingWeights.push_back(1./weight);
609 }
610 }
611 }
612 } // end of loop over nsplit
613
614 partChange->ProposeWeight(primaryWeight);
615 partChange->SetProposedKineticEnergy(primaryEnergy);
616 partChange->ProposeMomentumDirection(primaryMomdir);
617 } else {
618 for (std::size_t i = 0; i < vd.size(); ++i) {
619 fDirectionalSplittingWeights.push_back(1.);
620 }
621 }
622
623 return weight;
624}
625
626//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
627
629{
630 // normally return 1. If a directionally split particle survives RR,
631 // return 1./(splitting factor)
632 if (fDirectionalSplittingWeights.size() >= (unsigned int)(i+1) ) {
633 G4double w = fDirectionalSplittingWeights[i];
634 fDirectionalSplittingWeights[i] = 1.; // ensure it's not used again
635 return w;
636 } else {
637 return 1.;
638 }
639}
640
642G4EmBiasingManager::ApplyDirectionalSplitting(
643 std::vector<G4DynamicParticle*>& vd,
644 const G4Track& track,
645 G4VEmModel* currentModel,
646 G4int index,
647 G4double tcut)
648{
649 // primary is not a gamma. Do nothing with primary
650
651 G4double weight = 1.0;
652 G4double w = secBiasedWeight[index];
653
654 fDirectionalSplittingWeights.clear();
655 if(1.0 <= w) {
656 fDirectionalSplittingWeights.push_back(weight);
657 return weight;
658 }
659
660 G4double trackWeight = track.GetWeight();
661 G4int nsplit = nBremSplitting[index];
662
663 // double splitting is suppressed
664 if(1 < nsplit && trackWeight>w) {
665
666 weight = w;
667 const G4ThreeVector pos = track.GetPosition();
668
669 tmpSecondaries = vd;
670 vd.clear();
671 vd.reserve(nsplit);
672 for (G4int k=0; k<nsplit; ++k) {
673 if (k>0) {
674 tmpSecondaries.clear();
675 currentModel->SampleSecondaries(&tmpSecondaries,
676 track.GetMaterialCutsCouple(),
677 track.GetDynamicParticle(), tcut);
678 }
679 //for (auto sec : tmpSecondaries) {
680 for (std::size_t kk=0; kk < tmpSecondaries.size(); ++kk) {
681 if (CheckDirection(pos, tmpSecondaries[kk]->GetMomentumDirection())) {
682 vd.push_back(tmpSecondaries[kk]);
683 fDirectionalSplittingWeights.push_back(1.);
684 } else if (G4UniformRand()<w) {
685 vd.push_back(tmpSecondaries[kk]);
686 fDirectionalSplittingWeights.push_back(1./weight);
687 } else {
688 delete tmpSecondaries[kk];
689 tmpSecondaries[kk] = nullptr;
690 }
691 }
692 } // end of loop over nsplit
693 } else { // no splitting was done; still need weights
694 for (std::size_t i = 0; i < vd.size(); ++i) {
695 fDirectionalSplittingWeights.push_back(1.0);
696 }
697 }
698 return weight;
699}
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector cross(const Hep3Vector &) const
double angle(const Hep3Vector &) const
double mag() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
void SetDirectionalSplittingRadius(G4double r)
void SetDirectionalSplitting(G4bool v)
G4double ApplySecondaryBiasing(std::vector< G4DynamicParticle * > &, const G4Track &track, G4VEmModel *currentModel, G4ParticleChangeForGamma *pParticleChange, G4double &eloss, G4int coupleIdx, G4double tcut, G4double safety=0.0)
void ActivateSecondaryBiasing(const G4String &region, G4double factor, G4double energyLimit)
void Initialise(const G4ParticleDefinition &part, const G4String &procName, G4int verbose)
G4double GetWeight(G4int i)
G4bool CheckDirection(G4ThreeVector pos, G4ThreeVector momdir) const
void ActivateForcedInteraction(G4double length=0.0, const G4String &r="")
void SetDirectionalSplittingTarget(G4ThreeVector v)
G4double GetStepLimit(G4int coupleIdx, G4double previousStep)
static G4EmParameters * Instance()
G4double GetDirectionalSplittingRadius()
G4bool GetDirectionalSplitting() const
G4ThreeVector GetDirectionalSplittingTarget() const
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
static G4LossTableManager * Instance()
G4VEnergyLossProcess * GetEnergyLossProcess(const G4ParticleDefinition *)
G4ProductionCuts * GetProductionCuts() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
const G4ThreeVector & GetProposedMomentumDirection() const
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
G4double GetProposedKineticEnergy() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
const G4ThreeVector & GetProposedMomentumDirection() const
const G4String & GetParticleName() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
const G4String & GetName() const
G4double GetWeight() const
const G4ThreeVector & GetPosition() const
const G4DynamicParticle * GetDynamicParticle() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin=0.0, G4double tmax=DBL_MAX)=0
G4double GetRange(G4double kineticEnergy, const G4MaterialCutsCouple *)
void ProposeWeight(G4double finalWeight)
int G4lrint(double ad)
Definition: templates.hh:134
#define DBL_MAX
Definition: templates.hh:62