Import Geant4 9.6.0 source tree
This commit is contained in:
@@ -23,8 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4EmBiasingManager.cc,v 1.88 2010-08-17 17:36:59 vnivanch Exp $
|
||||
// GEANT4 tag $Name: not supported by cvs2svn $
|
||||
// $Id$
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -39,27 +38,37 @@
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 31-05-12 D. Sawkey put back in high energy limit for brem, russian roulette
|
||||
// 30-05-12 D. Sawkey brem split gammas are unique; do weight tests for
|
||||
// brem, russian roulette
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4EmBiasingManager.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4ProductionCuts.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4ParticleChangeForLoss.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmBiasingManager::G4EmBiasingManager()
|
||||
: nForcedRegions(0),nSecBiasedRegions(0),
|
||||
: nForcedRegions(0),nSecBiasedRegions(0),eIonisation(0),
|
||||
currentStepLimit(0.0),startTracking(true)
|
||||
{}
|
||||
{
|
||||
fSafetyMin = 1.e-6*mm;
|
||||
theElectron = G4Electron::Electron();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -182,7 +191,6 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
|
||||
//G4cout << "G4EmBiasingManager::ActivateSecondaryBiasing: "
|
||||
// << rname << " F= " << factor << " E(MeV)= " << energyLimit/MeV
|
||||
// << G4endl;
|
||||
if(0.0 >= factor) { return; }
|
||||
G4RegionStore* regionStore = G4RegionStore::GetInstance();
|
||||
G4String name = rname;
|
||||
if(name == "" || name == "world" || name == "World") {
|
||||
@@ -196,15 +204,22 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
|
||||
return;
|
||||
}
|
||||
|
||||
// Range cut
|
||||
G4int nsplit = 0;
|
||||
G4double w = 1.0/factor;
|
||||
G4double w = factor;
|
||||
|
||||
// splitting
|
||||
if(factor >= 1.0) {
|
||||
nsplit = G4int(factor + 0.5);
|
||||
w = 1.0/G4double(nsplit);
|
||||
nsplit = G4lrint(factor);
|
||||
w = 1.0/G4double(nsplit);
|
||||
|
||||
// Russian roulette
|
||||
} else if(0.0 < factor) {
|
||||
nsplit = 1;
|
||||
w = 1.0/factor;
|
||||
}
|
||||
|
||||
// the region is in the list
|
||||
// the region is in the list - overwrite parameters
|
||||
if (0 < nSecBiasedRegions) {
|
||||
for (G4int i=0; i<nSecBiasedRegions; ++i) {
|
||||
if (reg == secBiasedRegions[i]) {
|
||||
@@ -215,12 +230,11 @@ G4EmBiasingManager::ActivateSecondaryBiasing(const G4String& rname,
|
||||
}
|
||||
}
|
||||
}
|
||||
if(1 == nsplit) {
|
||||
G4cout << "### G4EmBiasingManager::ActivateSecondaryBiasing WARNING: "
|
||||
<< nsplit << " = 1, so no activation for the G4Region <"
|
||||
<< rname << ">" << G4endl;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
G4cout << "### G4EmBiasingManager::ActivateSecondaryBiasing: "
|
||||
<< " nsplit= " << nsplit << " for the G4Region <"
|
||||
<< rname << ">" << G4endl;
|
||||
*/
|
||||
|
||||
// new region
|
||||
secBiasedRegions.push_back(reg);
|
||||
@@ -255,35 +269,125 @@ G4double G4EmBiasingManager::GetStepLimit(G4int coupleIdx,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4DynamicParticle*>& vd,
|
||||
G4EmBiasingManager::ApplySecondaryBiasing(
|
||||
std::vector<G4DynamicParticle*>& vd,
|
||||
const G4Track& track,
|
||||
G4VEmModel* currentModel,
|
||||
G4ParticleChangeForLoss* pPartChange,
|
||||
G4double& eloss,
|
||||
G4int coupleIdx,
|
||||
G4double tcut,
|
||||
G4double safety)
|
||||
{
|
||||
G4int index = idxSecBiasedCouple[coupleIdx];
|
||||
G4double weight = 1.0;
|
||||
if(0 <= index) {
|
||||
size_t n = vd.size();
|
||||
|
||||
// the check cannot be applied per secondary particle
|
||||
// because weight correction is common, so the first
|
||||
// secondary is checked
|
||||
if(0 < n && vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
|
||||
|
||||
G4int nsplit = nBremSplitting[index];
|
||||
|
||||
// Range cut
|
||||
if(0 == nsplit) {
|
||||
if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
|
||||
|
||||
// Russian Roulette
|
||||
} if(1 == nsplit) {
|
||||
weight = ApplyRussianRoulette(vd, index);
|
||||
|
||||
// Splitting
|
||||
} else {
|
||||
G4double tmpEnergy = pPartChange->GetProposedKineticEnergy();
|
||||
G4ThreeVector tmpMomDir = pPartChange->GetProposedMomentumDirection();
|
||||
|
||||
weight = ApplySplitting(vd, track, currentModel, index, tcut);
|
||||
|
||||
pPartChange->SetProposedKineticEnergy(tmpEnergy);
|
||||
pPartChange->ProposeMomentumDirection(tmpMomDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4EmBiasingManager::ApplySecondaryBiasing(
|
||||
std::vector<G4DynamicParticle*>& vd,
|
||||
const G4Track& track,
|
||||
G4VEmModel* currentModel,
|
||||
G4ParticleChangeForGamma* pPartChange,
|
||||
G4double& eloss,
|
||||
G4int coupleIdx,
|
||||
G4double tcut,
|
||||
G4double safety)
|
||||
{
|
||||
G4int index = idxSecBiasedCouple[coupleIdx];
|
||||
G4double weight = 1.0;
|
||||
if(0 <= index) {
|
||||
size_t n = vd.size();
|
||||
|
||||
// the check cannot be applied per secondary particle
|
||||
// because weight correction is common, so the first
|
||||
// secondary is checked
|
||||
if(0 < n && vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
|
||||
|
||||
G4int nsplit = nBremSplitting[index];
|
||||
|
||||
// Range cut
|
||||
if(0 == nsplit) {
|
||||
if(safety > fSafetyMin) { ApplyRangeCut(vd, track, eloss, safety); }
|
||||
|
||||
// Russian Roulette
|
||||
} if(1 == nsplit) {
|
||||
weight = ApplyRussianRoulette(vd, index);
|
||||
|
||||
// Splitting
|
||||
} else {
|
||||
G4double tmpEnergy = pPartChange->GetProposedKineticEnergy();
|
||||
G4ThreeVector tmpMomDir = pPartChange->GetProposedMomentumDirection();
|
||||
|
||||
weight = ApplySplitting(vd, track, currentModel, index, tcut);
|
||||
|
||||
pPartChange->SetProposedKineticEnergy(tmpEnergy);
|
||||
pPartChange->ProposeMomentumDirection(tmpMomDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& track,
|
||||
G4int coupleIdx)
|
||||
{
|
||||
G4int index = idxSecBiasedCouple[coupleIdx];
|
||||
G4double weight = 1.0;
|
||||
size_t n = vd.size();
|
||||
G4int i = idxSecBiasedCouple[coupleIdx];
|
||||
if(0 <= i && 0 < n) {
|
||||
if(0 <= index) {
|
||||
size_t n = track.size();
|
||||
|
||||
// apply biasing if first secondary has energy below the threshold
|
||||
if(vd[0]->GetKineticEnergy() < secBiasedEnegryLimit[i]) {
|
||||
weight = secBiasedWeight[i];
|
||||
G4int nsplit = nBremSplitting[i];
|
||||
// the check cannot be applied per secondary particle
|
||||
// because weight correction is common, so the first
|
||||
// secondary is checked
|
||||
if(0 < n && track[0]->GetKineticEnergy() < secBiasedEnegryLimit[index]) {
|
||||
|
||||
// splitting
|
||||
if(1 < nsplit) {
|
||||
G4int nsplit = nBremSplitting[index];
|
||||
|
||||
// Russian Roulette only
|
||||
if(1 == nsplit) {
|
||||
weight = secBiasedWeight[index];
|
||||
for(size_t k=0; k<n; ++k) {
|
||||
const G4DynamicParticle* dp = vd[k];
|
||||
for(G4int j=1; j<nsplit; ++j) {
|
||||
G4DynamicParticle* dpnew = new G4DynamicParticle(*dp);
|
||||
vd.push_back(dpnew);
|
||||
}
|
||||
}
|
||||
// Russian roulette
|
||||
} else {
|
||||
for(size_t k=0; k<n; ++k) {
|
||||
const G4DynamicParticle* dp = vd[k];
|
||||
if(G4UniformRand()*weight > 1.0) {
|
||||
delete dp;
|
||||
vd[k] = 0;
|
||||
const G4Track* t = track[k];
|
||||
delete t;
|
||||
track[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,38 +399,23 @@ G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4DynamicParticle*>& vd,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void
|
||||
G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& tr,
|
||||
G4double primaryWeight,
|
||||
G4int coupleIdx)
|
||||
G4EmBiasingManager::ApplyRangeCut(std::vector<G4DynamicParticle*>& vd,
|
||||
const G4Track& track,
|
||||
G4double& eloss, G4double safety)
|
||||
{
|
||||
G4double weight = primaryWeight;
|
||||
size_t n = tr.size();
|
||||
G4int i = idxSecBiasedCouple[coupleIdx];
|
||||
if(0 <= i && 0 < n) {
|
||||
|
||||
weight *= secBiasedWeight[i];
|
||||
G4int nsplit = nBremSplitting[i];
|
||||
|
||||
// splitting
|
||||
if(1 < nsplit) {
|
||||
for(size_t k=0; k<n; ++k) {
|
||||
G4Track* t = tr[k];
|
||||
t->SetWeight(weight);
|
||||
for(G4int j=1; j<nsplit; ++j) {
|
||||
G4Track* tnew = new G4Track(*t);
|
||||
tnew->SetWeight(weight);
|
||||
tr.push_back(tnew);
|
||||
}
|
||||
}
|
||||
// Russian roulette
|
||||
} else {
|
||||
for(size_t k=0; k<n; ++k) {
|
||||
G4Track* t = tr[k];
|
||||
if(G4UniformRand()*secBiasedWeight[i] <= 1.0) {
|
||||
t->SetWeight(weight);
|
||||
} else {
|
||||
delete t;
|
||||
tr[k] = 0;
|
||||
size_t n = vd.size();
|
||||
if(!eIonisation) {
|
||||
eIonisation = G4LossTableManager::Instance()->GetEnergyLossProcess(theElectron);
|
||||
}
|
||||
if(eIonisation) {
|
||||
for(size_t k=0; k<n; ++k) {
|
||||
const G4DynamicParticle* dp = vd[k];
|
||||
if(dp->GetDefinition() == theElectron) {
|
||||
G4double e = dp->GetKineticEnergy();
|
||||
if(eIonisation->GetRangeForLoss(e, track.GetMaterialCutsCouple()) < safety) {
|
||||
eloss += e;
|
||||
delete dp;
|
||||
vd[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,3 +423,45 @@ G4EmBiasingManager::ApplySecondaryBiasing(std::vector<G4Track*>& tr,
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4EmBiasingManager::ApplySplitting(std::vector<G4DynamicParticle*>& vd,
|
||||
const G4Track& track,
|
||||
G4VEmModel* currentModel,
|
||||
G4int index,
|
||||
G4double tcut)
|
||||
{
|
||||
// method is applied only if 1 secondary created PostStep
|
||||
// in the case of many secodndaries there is a contrudition
|
||||
G4double weight = 1.0;
|
||||
size_t n = vd.size();
|
||||
G4double w = secBiasedWeight[index];
|
||||
|
||||
if(1 != n || 1.0 <= w) { return weight; }
|
||||
|
||||
G4double trackWeight = track.GetWeight();
|
||||
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
|
||||
|
||||
G4int nsplit = nBremSplitting[index];
|
||||
|
||||
// double splitting is supressed
|
||||
if(1 < nsplit && trackWeight>w) {
|
||||
|
||||
weight = w;
|
||||
// start from 1, because already one secondary created
|
||||
if(nsplit > (G4int)tmpSecondaries.size()) {
|
||||
tmpSecondaries.reserve(nsplit);
|
||||
}
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
for(G4int k=1; k<nsplit; ++k) {
|
||||
tmpSecondaries.clear();
|
||||
currentModel->SampleSecondaries(&tmpSecondaries, couple, dynParticle, tcut);
|
||||
for (size_t kk=0; kk<tmpSecondaries.size(); ++kk) {
|
||||
vd.push_back(tmpSecondaries[kk]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
Reference in New Issue
Block a user