Import Geant4 10.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 14:11:04 +02:00
parent c9b32a6c0a
commit d4af681f38
4886 changed files with 420149 additions and 1023309 deletions
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4PolarizedAnnihilationModel.cc 68046 2013-03-13 14:31:38Z gcosmo $
// $Id: G4PolarizedAnnihilationModel.cc 91742 2015-08-04 11:48:51Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -252,6 +252,7 @@ void G4PolarizedAnnihilationModel::SampleSecondaries(std::vector<G4DynamicPartic
break;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while( treject < gmax*G4UniformRand() );
//
@@ -309,6 +310,7 @@ void G4PolarizedAnnihilationModel::SampleSecondaries(std::vector<G4DynamicPartic
G4cout<<" epsil = "<<epsil<<G4endl;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while( treject < G4UniformRand() );
// G4cout<<"phi dicing END"<<G4endl;
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4PolarizedCompton.cc 85018 2014-10-23 09:51:37Z gcosmo $
// $Id: G4PolarizedCompton.cc 93113 2015-10-07 07:49:04Z gcosmo $
//
//
// File name: G4PolarizedCompton
@@ -68,7 +68,7 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PhysicsTable* G4PolarizedCompton::theAsymmetryTable = 0;
G4PhysicsTable* G4PolarizedCompton::theAsymmetryTable = nullptr;
G4PolarizedCompton::G4PolarizedCompton(const G4String& processName,
G4ProcessType type):
@@ -76,7 +76,8 @@ G4PolarizedCompton::G4PolarizedCompton(const G4String& processName,
buildAsymmetryTable(true),
useAsymmetryTable(true),
isInitialised(false),
mType(10)
mType(10),
targetPolarization(0.0,0.0,0.0)
{
SetStartFromNullFlag(true);
SetBuildTableFlag(true);
@@ -84,14 +85,32 @@ G4PolarizedCompton::G4PolarizedCompton(const G4String& processName,
SetProcessSubType(fComptonScattering);
SetMinKinEnergyPrim(1*MeV);
SetSplineFlag(true);
emModel = 0;
emModel = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4PolarizedCompton::~G4PolarizedCompton()
{
delete theAsymmetryTable;
CleanTable();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::CleanTable()
{
if( theAsymmetryTable) {
theAsymmetryTable->clearAndDestroy();
delete theAsymmetryTable;
theAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4PolarizedCompton::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Gamma::Gamma());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -133,35 +152,79 @@ void G4PolarizedCompton::SetModel(const G4String& ss)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::GetMeanFreePath(
const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
G4double G4PolarizedCompton::GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEmProcess::GetMeanFreePath(aTrack, previousStepSize, condition);
if (theAsymmetryTable && useAsymmetryTable) {
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4StokesVector GammaPolarization = aTrack.GetPolarization();
const G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
if (theAsymmetryTable && useAsymmetryTable && mfp < DBL_MAX) {
mfp *= ComputeSaturationFactor(aTrack);
}
if (verboseLevel>=2) {
G4cout << "G4PolarizedCompton::MeanFreePath: " << mfp / mm << " mm " << G4endl;
}
return mfp;
}
G4Material* aMaterial = aTrack.GetMaterial();
G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// G4Material* bMaterial = aLVolume->GetMaterial();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
G4double G4PolarizedCompton::PostStepGetPhysicalInteractionLength(
const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{
// save previous value
G4double nLength = theNumberOfInteractionLengthLeft;
G4bool VolumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector ElectronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
if (!VolumeIsPolarized || mfp == DBL_MAX) return mfp;
// *** compute uppolarized step limit ***
G4double x = G4VEmProcess::PostStepGetPhysicalInteractionLength(aTrack,
previousStepSize,
condition);
// *** add corrections on polarisation ***
if (theAsymmetryTable && useAsymmetryTable && x < DBL_MAX) {
G4double curLength = currentInteractionLength*ComputeSaturationFactor(aTrack);
if(nLength > 0.0) {
theNumberOfInteractionLengthLeft =
std::max(nLength - previousStepSize/curLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if (verboseLevel>=2) {
G4cout << "G4PolarizedCompton::PostStepGetPhysicalInteractionLength: "
<< x/mm << " mm " << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::ComputeSaturationFactor(const G4Track& aTrack)
{
G4double factor = 1.0;
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4StokesVector GammaPolarization = aTrack.GetPolarization();
const G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
G4Material* aMaterial = aTrack.GetMaterial();
G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
// G4Material* bMaterial = aLVolume->GetMaterial();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool VolumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector ElectronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
if (VolumeIsPolarized) {
if (verboseLevel>=2) {
G4cout << "G4PolarizedCompton::ComputeSaturationFactor: " << G4endl;
G4cout << " Mom " << GammaDirection0 << G4endl;
G4cout << " Polarization " << GammaPolarization << G4endl;
G4cout << " MaterialPol. " << ElectronPolarization << G4endl;
@@ -170,127 +233,40 @@ G4double G4PolarizedCompton::GetMeanFreePath(
G4cout << " Material " << aMaterial << G4endl;
}
G4int midx= CurrentMaterialCutsCoupleIndex();
G4PhysicsVector * aVector=(*theAsymmetryTable)(midx);
G4double asymmetry=0;
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
if(midx < theAsymmetryTable->size()) {
aVector = (*theAsymmetryTable)(midx);
}
if (aVector) {
asymmetry = aVector->Value(GammaEnergy);
G4double asymmetry = aVector->Value(GammaEnergy);
// we have to determine angle between particle motion
// and target polarisation here
// circ pol * Vec(ElectronPol)*Vec(PhotonMomentum)
// both vectors in global reference frame
G4double pol = ElectronPolarization*GammaDirection0;
G4double polProduct = GammaPolarization.p3() * pol;
factor /= (1. + polProduct * asymmetry);
if (verboseLevel>=2) {
G4cout << " Asymmetry: " << asymmetry << G4endl;
G4cout << " PolProduct: " << polProduct << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
} else {
G4cout << " MaterialIndex " << midx << " is out of range \n";
asymmetry=0;
}
// we have to determine angle between particle motion
// and target polarisation here
// circ pol * Vec(ElectronPol)*Vec(PhotonMomentum)
// both vectors in global reference frame
G4double pol=ElectronPolarization*GammaDirection0;
G4double polProduct = GammaPolarization.p3() * pol;
mfp *= 1. / ( 1. + polProduct * asymmetry );
if (verboseLevel>=2) {
G4cout << " MeanFreePath: " << mfp / mm << " mm " << G4endl;
G4cout << " Asymmetry: " << asymmetry << G4endl;
G4cout << " PolProduct: " << polProduct << G4endl;
G4ExceptionDescription ed;
ed << "Problem with asymmetry table: material index " << midx
<< " is out of range or the table is not filled";
G4Exception("G4PolarizedComptonModel::ComputeSaturationFactor","em0048",
JustWarning, ed, "");
}
}
return mfp;
}
G4double G4PolarizedCompton::PostStepGetPhysicalInteractionLength(
const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEmProcess::PostStepGetPhysicalInteractionLength(aTrack, previousStepSize, condition);
if (theAsymmetryTable && useAsymmetryTable) {
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4StokesVector GammaPolarization = aTrack.GetPolarization();
const G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
G4Material* aMaterial = aTrack.GetMaterial();
G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
// G4Material* bMaterial = aLVolume->GetMaterial();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool VolumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector ElectronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
if (!VolumeIsPolarized || mfp == DBL_MAX) return mfp;
if (verboseLevel>=2) {
G4cout << " Mom " << GammaDirection0 << G4endl;
G4cout << " Polarization " << GammaPolarization << G4endl;
G4cout << " MaterialPol. " << ElectronPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
G4int midx= CurrentMaterialCutsCoupleIndex();
G4PhysicsVector * aVector=(*theAsymmetryTable)(midx);
G4double asymmetry=0;
if (aVector) {
asymmetry = aVector->Value(GammaEnergy);
} else {
G4cout << " MaterialIndex " << midx << " is out of range \n";
asymmetry=0;
}
// we have to determine angle between particle motion
// and target polarisation here
// circ pol * Vec(ElectronPol)*Vec(PhotonMomentum)
// both vectors in global reference frame
G4double pol=ElectronPolarization*GammaDirection0;
G4double polProduct = GammaPolarization.p3() * pol;
mfp *= 1. / ( 1. + polProduct * asymmetry );
if (verboseLevel>=2) {
G4cout << " MeanFreePath: " << mfp / mm << " mm " << G4endl;
G4cout << " Asymmetry: " << asymmetry << G4endl;
G4cout << " PolProduct: " << polProduct << G4endl;
}
}
return mfp;
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::PreparePhysicsTable(const G4ParticleDefinition& part)
{
G4VEmProcess::PreparePhysicsTable(part);
if(buildAsymmetryTable && emModel) {
G4bool isMaster = true;
const G4PolarizedCompton* masterProcess =
static_cast<const G4PolarizedCompton*>(GetMasterProcess());
if(masterProcess && masterProcess != this) { isMaster = false; }
if(isMaster) {
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& part)
{
// *** build (unpolarized) cross section tables (Lambda)
@@ -306,9 +282,13 @@ void G4PolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& part)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PolarizedCompton::BuildAsymmetryTable(const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTable();
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
// Access to materials
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
@@ -340,7 +320,6 @@ void G4PolarizedCompton::BuildAsymmetryTable(const G4ParticleDefinition& part)
G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
bVector->PutValue(j,asym);
}
G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, bVector);
}
}
@@ -348,7 +327,6 @@ void G4PolarizedCompton::BuildAsymmetryTable(const G4ParticleDefinition& part)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PolarizedCompton::ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle,
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4PolarizedComptonModel.cc 82755 2014-07-08 14:07:29Z gcosmo $
// $Id: G4PolarizedComptonModel.cc 93316 2015-10-16 12:36:02Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -56,14 +56,19 @@
#include "G4DataVector.hh"
#include "G4ParticleChangeForGamma.hh"
#include "G4StokesVector.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4PolarizedComptonCrossSection.hh"
#include "G4SystemOfUnits.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
static const G4int nlooplim = 10000;
G4PolarizedComptonModel::G4PolarizedComptonModel(const G4ParticleDefinition*,
const G4String& nam)
: G4KleinNishinaCompton(0,nam),
@@ -89,8 +94,8 @@ G4double G4PolarizedComptonModel::ComputeAsymmetryPerAtom
G4double k1 = 1 + 2*k0 ;
asymmetry = -k0;
asymmetry *= (k0 + 1.)*sqr(k1)*std::log(k1) - 2.*k0*(5.*sqr(k0) + 4.*k0 + 1.);
asymmetry /= ((k0 - 2.)*k0 -2.)*sqr(k1)*std::log(k1) + 2.*k0*(k0*(k0 + 1.)*(k0 + 8.) + 2.);
asymmetry *= (k0 + 1.)*sqr(k1)*G4Log(k1) - 2.*k0*(5.*sqr(k0) + 4.*k0 + 1.);
asymmetry /= ((k0 - 2.)*k0 -2.)*sqr(k1)*G4Log(k1) + 2.*k0*(k0*(k0 + 1.)*(k0 + 8.) + 2.);
// G4cout<<"energy = "<<GammaEnergy<<" asymmetry = "<<asymmetry<<"\t\t GAM = "<<k0<<G4endl;
if (asymmetry>1.) G4cout<<"ERROR in G4PolarizedComptonModel::ComputeAsymmetryPerAtom"<<G4endl;
@@ -113,7 +118,7 @@ G4double G4PolarizedComptonModel::ComputeCrossSectionPerAtom(
G4double polzz = theBeamPolarization.p3()*theTargetPolarization.z();
if (polzz > 0.0) {
G4double asym = ComputeAsymmetryPerAtom(kinEnergy, Z);
xs*=(1.+polzz*asym);
xs *= (1.+polzz*asym);
}
return xs;
}
@@ -173,90 +178,117 @@ void G4PolarizedComptonModel::SampleSecondaries(
// sample the energy rate of the scattered gamma
//
G4double epsilon, epsilonsq, onecost, sint2, greject ;
G4double epsilon, sint2;
G4double onecost = 0.0;
G4double Phi = 0.0;
G4double greject = 1.0;
G4double cosTeta = 1.0;
G4double sinTeta = 0.0;
G4double eps0 = 1./(1. + 2.*E0_m);
G4double epsilon0sq = eps0*eps0;
G4double alpha1 = - std::log(eps0);
G4double alpha2 = 0.5*(1.- epsilon0sq);
G4double alpha1 = - G4Log(eps0);
G4double alpha2 = alpha1 + 0.5*(1.- epsilon0sq);
G4double polarization =
theBeamPolarization.p3()*theTargetPolarization.p3();
CLHEP::HepRandomEngine* rndmEngineMod = G4Random::getTheEngine();
G4int nloop = 0;
G4bool end = false;
G4double rndm[3];
do {
++nloop;
// false interaction if too many iterations
if(nloop > 1000) { return; }
do {
++nloop;
// false interaction if too many iterations
if(nloop > nlooplim) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"too many iterations");
return;
}
if ( alpha1/(alpha1+alpha2) > G4UniformRand() ) {
epsilon = std::exp(-alpha1*G4UniformRand()); // epsilon0**r
epsilonsq = epsilon*epsilon;
// 3 random numbers to sample scattering
rndmEngineMod->flatArray(3, rndm);
} else {
epsilonsq = epsilon0sq + (1.- epsilon0sq)*G4UniformRand();
epsilon = std::sqrt(epsilonsq);
}
if ( alpha1 > alpha2*rndm[0]) {
epsilon = G4Exp(-alpha1*rndm[1]); // epsilon0**r
} else {
epsilon = std::sqrt(epsilon0sq + (1.- epsilon0sq)*rndm[1]);
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sint2 = onecost*(2.-onecost);
onecost = (1.- epsilon)/(epsilon*E0_m);
sint2 = onecost*(2.-onecost);
G4double gdiced = 2.*(1./epsilon+epsilon);
G4double gdist = 1./epsilon + epsilon - sint2
- polarization*(1./epsilon-epsilon)*(1.-onecost);
G4double gdiced = 2.*(1./epsilon+epsilon);
G4double gdist = 1./epsilon + epsilon - sint2
- polarization*(1./epsilon-epsilon)*(1.-onecost);
greject = gdist/gdiced;
greject = gdist/gdiced;
if (greject>1) {
G4cout<<"ERROR in PolarizedComptonScattering::PostStepDoIt\n"
<<" costh rejection does not work properly: "<<greject
<<G4endl;
}
} while (greject < G4UniformRand());
if (greject > 1.0) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"theta majoranta wrong");
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (greject < rndm[2]);
// assuming phi loop sucessful
end = true;
//
// scattered gamma angles. ( Z - axis along the parent gamma)
//
//
// scattered gamma angles. ( Z - axis along the parent gamma)
//
cosTeta = 1. - onecost;
sinTeta = std::sqrt(sint2);
do {
++nloop;
G4double cosTeta = 1. - onecost;
G4double sinTeta = std::sqrt (sint2);
G4double Phi;
do {
++nloop;
// false interaction if too many iterations
if(nloop > 1000) { return; }
// 2 random numbers to sample scattering
rndmEngineMod->flatArray(2, rndm);
Phi = twopi * G4UniformRand();
G4double gdiced = 1./epsilon + epsilon - sint2
+ std::abs(theBeamPolarization.p3())*
( std::abs((1./epsilon-epsilon)*cosTeta*theTargetPolarization.p3())
+(1.-epsilon)*sinTeta*(std::sqrt(sqr(theTargetPolarization.p1())
+ sqr(theTargetPolarization.p2()))))
+sint2*(std::sqrt(sqr(theBeamPolarization.p1()) +
sqr(theBeamPolarization.p2())));
// false interaction if too many iterations
Phi = twopi * rndm[0];
if(nloop > nlooplim) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"too many iterations");
return;
}
G4double gdist = 1./epsilon + epsilon - sint2
+ theBeamPolarization.p3()*
((1./epsilon-epsilon)*cosTeta*theTargetPolarization.p3()
+(1.-epsilon)*sinTeta*(std::cos(Phi)*theTargetPolarization.p1()+
std::sin(Phi)*theTargetPolarization.p2()))
-sint2*(std::cos(2.*Phi)*theBeamPolarization.p1()
+std::sin(2.*Phi)*theBeamPolarization.p2());
greject = gdist/gdiced;
G4double gdiced = 1./epsilon + epsilon - sint2
+ std::abs(theBeamPolarization.p3())*
( std::abs((1./epsilon-epsilon)*cosTeta*theTargetPolarization.p3())
+(1.-epsilon)*sinTeta*(std::sqrt(sqr(theTargetPolarization.p1())
+ sqr(theTargetPolarization.p2()))))
+sint2*(std::sqrt(sqr(theBeamPolarization.p1()) +
sqr(theBeamPolarization.p2())));
if (greject>1.+1.e-10 || greject<0) {
G4cout<<"ERROR in PolarizedComptonScattering::PostStepDoIt\n"
<<" phi rejection does not work properly: "<<greject<<G4endl;
}
if (greject<1.e-3) {
G4cout<<"ERROR in PolarizedComptonScattering::PostStepDoIt\n"
<<" phi rejection does not work properly: "<<greject<<"\n";
G4cout<<" greject="<<greject<<" phi="<<Phi<<" cost="<<cosTeta<<"\n";
G4cout<<" gdiced="<<gdiced<<" gdist="<<gdist<<"\n";
G4cout<<" eps="<<epsilon<<" 1/eps="<<1./epsilon<<"\n";
}
G4double gdist = 1./epsilon + epsilon - sint2
+ theBeamPolarization.p3()*
((1./epsilon-epsilon)*cosTeta*theTargetPolarization.p3()
+(1.-epsilon)*sinTeta*(std::cos(Phi)*theTargetPolarization.p1()+
std::sin(Phi)*theTargetPolarization.p2()))
-sint2*(std::cos(2.*Phi)*theBeamPolarization.p1()
+std::sin(2.*Phi)*theBeamPolarization.p2());
greject = gdist/gdiced;
if (greject > 1.0) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"phi majoranta wrong");
}
if(greject < 1.e-3) {
PrintWarning(aDynamicGamma, nloop, greject, onecost, Phi,
"phi loop ineffective");
// restart theta loop
end = false;
break;
}
} while (greject < G4UniformRand());
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (greject < rndm[1]);
} while(!end);
G4double dirx = sinTeta*std::cos(Phi), diry = sinTeta*std::sin(Phi),
dirz = cosTeta;
@@ -321,14 +353,14 @@ void G4PolarizedComptonModel::SampleSecondaries(
// translate polarization into particle reference frame
finalGammaPolarization.RotateAz(nInteractionFrame,gamDirection1);
//store polarization vector
fParticleChange->ProposePolarization(finalGammaPolarization);
if (finalGammaPolarization.mag() > 1.+1.e-8){
G4cout<<"ERROR in Polarizaed Compton Scattering !"<<G4endl;
G4cout<<"Polarization of final photon more than 100%"<<G4endl;
G4cout<<finalGammaPolarization<<" mag = "
<<finalGammaPolarization.mag()<<G4endl;
}
//store polarization vector
fParticleChange->ProposePolarization(finalGammaPolarization);
if (verboseLevel>=1) {
G4cout << " gammaPolarization1 = " <<finalGammaPolarization<<"\n";
G4cout << " GammaDirection1 = " <<gamDirection1<<"\n";
@@ -384,4 +416,23 @@ void G4PolarizedComptonModel::SampleSecondaries(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void
G4PolarizedComptonModel::PrintWarning(const G4DynamicParticle* dp, G4int nloop,
G4double grej, G4double onecos,
G4double phi, const G4String sss) const
{
G4ExceptionDescription ed;
ed << "Problem of scattering sampling: " << sss << "\n"
<< "Niter= " << nloop << " grej= " << grej << " cos(theta)= "
<< 1.0-onecos << " phi= " << phi << "\n"
<< "Gamma E(MeV)= " << dp->GetKineticEnergy()/MeV
<< " dir= " << dp->GetMomentumDirection()
<< " pol= " << dp->GetPolarization();
G4Exception("G4PolarizedComptonModel::SampleSecondaries","em0044",
JustWarning, ed, "");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4PolarizedMollerBhabhaModel.cc 68046 2013-03-13 14:31:38Z gcosmo $
// $Id: G4PolarizedMollerBhabhaModel.cc 91742 2015-08-04 11:48:51Z gcosmo $
// -------------------------------------------------------------------
//
// GEANT4 Class file
@@ -220,7 +220,8 @@ void G4PolarizedMollerBhabhaModel::SampleSecondaries(std::vector<G4DynamicPartic
} else {
G4cout<<"No calculator in Moller scattering"<<G4endl;
}
} while(grej * G4UniformRand() > z);
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > z);
//Bhabha (e+e-) scattering
} else {
// *** dice according to polarized cross section
@@ -256,6 +257,7 @@ void G4PolarizedMollerBhabhaModel::SampleSecondaries(std::vector<G4DynamicPartic
<< " e+e- (Bhabha) scattering"<<" at KinEnergy "<<kineticEnergy<<G4endl;
G4cout<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"<<G4endl;
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > z);
}
//
@@ -287,6 +289,7 @@ void G4PolarizedMollerBhabhaModel::SampleSecondaries(std::vector<G4DynamicPartic
<<"PHI DICING"<<G4endl;
}
}
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while(grej * G4UniformRand() > xs);
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4VPolarizedCrossSection.cc 68046 2013-03-13 14:31:38Z gcosmo $
// $Id: G4VPolarizedCrossSection.cc 91742 2015-08-04 11:48:51Z gcosmo $
// File name: G4VPolarizedCrossSection
//
// Author: Andreas Schaelicke
@@ -117,6 +117,7 @@ void G4VPolarizedCrossSection::DicePolarization()
G4int k = 0;
G4double disc = sigma[3]*G4UniformRand();
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
while (sigma[k]<disc && k<4) {
++k;
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ePolarizedBremsstrahlung.cc 85018 2014-10-23 09:51:37Z gcosmo $
// $Id: G4ePolarizedBremsstrahlung.cc 93113 2015-10-07 07:49:04Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -62,7 +62,6 @@ G4ePolarizedBremsstrahlung::G4ePolarizedBremsstrahlung(const G4String& name):
G4eBremsstrahlung(name)
{}
void G4ePolarizedBremsstrahlung::InitialiseEnergyLossProcess(
const G4ParticleDefinition*,
const G4ParticleDefinition*)
@@ -72,8 +71,8 @@ void G4ePolarizedBremsstrahlung::InitialiseEnergyLossProcess(
SetSecondaryParticle(G4Gamma::Gamma());
SetIonisation(false);
//G4VEmFluctuationModel* fm = 0;
G4VEmFluctuationModel* fm = new G4UniversalFluctuation();
G4VEmFluctuationModel* fm = 0;
//G4VEmFluctuationModel* fm = new G4UniversalFluctuation();
G4VEmModel* em = new G4ePolarizedBremsstrahlungModel;
em->SetLowEnergyLimit(0.1*keV);
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4ePolarizedIonisation.cc 85018 2014-10-23 09:51:37Z gcosmo $
// $Id: G4ePolarizedIonisation.cc 93113 2015-10-07 07:49:04Z gcosmo $
// -------------------------------------------------------------------
//
// GEANT4 Class file
@@ -53,16 +53,18 @@
#include "G4ePolarizedIonisation.hh"
#include "G4Electron.hh"
#include "G4UniversalFluctuation.hh"
#include "G4BohrFluctuations.hh"
#include "G4UnitsTable.hh"
#include "G4PolarizedMollerBhabhaModel.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4ProductionCutsTable.hh"
#include "G4PolarizationManager.hh"
#include "G4PolarizationHelper.hh"
#include "G4StokesVector.hh"
#include "G4EmParameters.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ePolarizedIonisation::G4ePolarizedIonisation(const G4String& name)
@@ -70,26 +72,59 @@ G4ePolarizedIonisation::G4ePolarizedIonisation(const G4String& name)
theElectron(G4Electron::Electron()),
isElectron(true),
isInitialised(false),
theAsymmetryTable(NULL),
theTransverseAsymmetryTable(NULL)
theTargetPolarization(0.,0.,0.),
theAsymmetryTable(nullptr),
theTransverseAsymmetryTable(nullptr)
{
verboseLevel=0;
SetProcessSubType(fIonisation);
SetSecondaryParticle(theElectron);
flucModel = 0;
emModel = 0;
flucModel = nullptr;
emModel = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ePolarizedIonisation::~G4ePolarizedIonisation()
{
delete theAsymmetryTable;
delete theTransverseAsymmetryTable;
CleanTables();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::CleanTables()
{
if(theAsymmetryTable) {
theAsymmetryTable->clearAndDestroy();
delete theAsymmetryTable;
theAsymmetryTable = nullptr;
}
if(theTransverseAsymmetryTable) {
theTransverseAsymmetryTable->clearAndDestroy();
delete theTransverseAsymmetryTable;
theTransverseAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4ePolarizedIonisation::MinPrimaryEnergy(const G4ParticleDefinition*,
const G4Material*, G4double cut)
{
G4double x = cut;
if(isElectron) { x += cut; }
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4ePolarizedIonisation::IsApplicable(const G4ParticleDefinition& p)
{
return (&p == G4Electron::Electron() || &p == G4Positron::Positron());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::InitialiseEnergyLossProcess(
const G4ParticleDefinition* part,
const G4ParticleDefinition* /*part2*/)
@@ -125,127 +160,144 @@ G4double G4ePolarizedIonisation::GetMeanFreePath(const G4Track& track,
{
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEnergyLossProcess::GetMeanFreePath(track, step, cond);
// *** get asymmetry, if target is polarized ***
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
const G4StokesVector ePolarization = track.GetPolarization();
if (mfp != DBL_MAX && volumeIsPolarized && !ePolarization.IsZero()) {
const G4DynamicParticle* aDynamicElectron = track.GetDynamicParticle();
G4double eEnergy = aDynamicElectron->GetKineticEnergy();
const G4ParticleMomentum eDirection0 = aDynamicElectron->GetMomentumDirection();
G4StokesVector volumePolarization = polarizationManger->GetVolumePolarization(aLVolume);
G4bool isOutRange;
size_t idx = CurrentMaterialCutsCoupleIndex();
G4double lAsymmetry = (*theAsymmetryTable)(idx)->
GetValue(eEnergy, isOutRange);
G4double tAsymmetry = (*theTransverseAsymmetryTable)(idx)->
GetValue(eEnergy, isOutRange);
// calculate longitudinal spin component
G4double polZZ = ePolarization.z()*
volumePolarization*eDirection0;
// calculate transvers spin components
G4double polXX = ePolarization.x()*
volumePolarization*G4PolarizationHelper::GetParticleFrameX(eDirection0);
G4double polYY = ePolarization.y()*
volumePolarization*G4PolarizationHelper::GetParticleFrameY(eDirection0);
G4double impact = 1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry;
// determine polarization dependent mean free path
mfp /= impact;
if (mfp <=0.) {
G4cout <<"PV impact ( "<<polXX<<" , "<<polYY<<" , "<<polZZ<<" )"<<G4endl;
G4cout << " impact on MFP is "<< impact <<G4endl;
G4cout<<" lAsymmetry= "<<lAsymmetry<<" ("<<std::fabs(lAsymmetry)-1.<<")\n";
G4cout<<" tAsymmetry= "<<tAsymmetry<<" ("<<std::fabs(tAsymmetry)-1.<<")\n";
}
if(theAsymmetryTable && theTransverseAsymmetryTable && mfp < DBL_MAX) {
mfp *= ComputeSaturationFactor(track);
}
if (verboseLevel>=2) {
G4cout << "G4ePolarizedIonisation::MeanFreePath: "
<< mfp / mm << " mm " << G4endl;
}
return mfp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ePolarizedIonisation::PostStepGetPhysicalInteractionLength(const G4Track& track,
G4double step,
G4ForceCondition* cond)
{
// save previous value
G4double nLength = theNumberOfInteractionLengthLeft;
// *** get unploarised mean free path from lambda table ***
G4double mfp = G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(track, step, cond);
G4double x = G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(track, step, cond);
// *** get asymmetry, if target is polarized ***
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
const G4StokesVector ePolarization = track.GetPolarization();
if (mfp != DBL_MAX && volumeIsPolarized && !ePolarization.IsZero()) {
const G4DynamicParticle* aDynamicElectron = track.GetDynamicParticle();
G4double eEnergy = aDynamicElectron->GetKineticEnergy();
const G4ParticleMomentum eDirection0 = aDynamicElectron->GetMomentumDirection();
G4StokesVector volumePolarization = polarizationManger->GetVolumePolarization(aLVolume);
size_t idx = CurrentMaterialCutsCoupleIndex();
G4double lAsymmetry = (*theAsymmetryTable)(idx)->Value(eEnergy);
G4double tAsymmetry = (*theTransverseAsymmetryTable)(idx)->Value(eEnergy);
// calculate longitudinal spin component
G4double polZZ = ePolarization.z()*
volumePolarization*eDirection0;
// calculate transvers spin components
G4double polXX = ePolarization.x()*
volumePolarization*G4PolarizationHelper::GetParticleFrameX(eDirection0);
G4double polYY = ePolarization.y()*
volumePolarization*G4PolarizationHelper::GetParticleFrameY(eDirection0);
G4double impact = 1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry;
// determine polarization dependent mean free path
mfp /= impact;
if (mfp <=0.) {
G4cout <<"PV impact ( "<<polXX<<" , "<<polYY<<" , "<<polZZ<<" )"<<G4endl;
G4cout << " impact on MFP is "<< impact <<G4endl;
G4cout<<" lAsymmetry= "<<lAsymmetry<<" ("<<std::fabs(lAsymmetry)-1.<<")\n";
G4cout<<" tAsymmetry= "<<tAsymmetry<<" ("<<std::fabs(tAsymmetry)-1.<<")\n";
if(theAsymmetryTable && theTransverseAsymmetryTable && x < DBL_MAX) {
G4double curLength = currentInteractionLength*ComputeSaturationFactor(track);
if(nLength > 0.0) {
theNumberOfInteractionLengthLeft =
std::max(nLength - step/curLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
return mfp;
if (verboseLevel>=2) {
G4cout << "G4ePolarizedIonisation::PostStepGetPhysicalInteractionLength: "
<< x/mm << " mm " << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::BuildPhysicsTable(const G4ParticleDefinition& part)
G4double
G4ePolarizedIonisation::ComputeSaturationFactor(const G4Track& track)
{
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector volPolarization = polarizationManger->GetVolumePolarization(aLVolume);
G4double factor = 1.0;
if (volumeIsPolarized && !volPolarization.IsZero()) {
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPart = track.GetDynamicParticle();
const G4double energy = aDynamicPart->GetKineticEnergy();
const G4StokesVector polarization = track.GetPolarization();
const G4ParticleMomentum direction0 = aDynamicPart->GetMomentumDirection();
if (verboseLevel>=2) {
G4cout << "G4ePolarizedIonisation::ComputeSaturationFactor: " << G4endl;
G4cout << " Energy(MeV) " << energy/MeV << G4endl;
G4cout << " Direction " << direction0 << G4endl;
G4cout << " Polarization " << polarization << G4endl;
G4cout << " MaterialPol. " << volPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
const G4PhysicsVector* bVector = nullptr;
if(midx < theAsymmetryTable->size()) {
aVector = (*theAsymmetryTable)(midx);
}
if(midx < theTransverseAsymmetryTable->size()) {
bVector = (*theTransverseAsymmetryTable)(midx);
}
if(aVector && bVector) {
G4double lAsymmetry = aVector->Value(energy);
G4double tAsymmetry = bVector->Value(energy);
G4double polZZ = polarization.z()*(volPolarization*direction0);
G4double polXX = polarization.x()*
(volPolarization*G4PolarizationHelper::GetParticleFrameX(direction0));
G4double polYY = polarization.y()*
(volPolarization*G4PolarizationHelper::GetParticleFrameY(direction0));
factor /= (1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry);
if (verboseLevel>=2) {
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
} else {
G4ExceptionDescription ed;
ed << "Problem with asymmetry tables: material index " << midx
<< " is out of range or tables are not filled";
G4Exception("G4ePolarizedIonisation::ComputeSaturationFactor","em0048",
JustWarning, ed, "");
}
}
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ePolarizedIonisation::BuildPhysicsTable(
const G4ParticleDefinition& part)
{
// *** build DEDX and (unpolarized) cross section tables
G4VEnergyLossProcess::BuildPhysicsTable(part);
// G4PhysicsTable* pt =
// BuildDEDXTable();
G4bool master = true;
const G4ePolarizedIonisation* masterProcess =
static_cast<const G4ePolarizedIonisation*>(GetMasterProcess());
if(masterProcess && masterProcess != this) { master = false; }
if(master) { BuildAsymmetryTables(part); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// *** build asymmetry-table
if (theAsymmetryTable) {
theAsymmetryTable->clearAndDestroy(); delete theAsymmetryTable;}
if (theTransverseAsymmetryTable) {
theTransverseAsymmetryTable->clearAndDestroy(); delete theTransverseAsymmetryTable;}
void G4ePolarizedIonisation::BuildAsymmetryTables(
const G4ParticleDefinition& part)
{
// cleanup old, initialise new table
CleanTables();
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
theTransverseAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
theAsymmetryTable = new G4PhysicsTable(numOfCouples);
theTransverseAsymmetryTable = new G4PhysicsTable(numOfCouples);
for (size_t j=0 ; j < numOfCouples; j++ ) {
// get cut value
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(j);
@@ -267,19 +319,20 @@ void G4ePolarizedIonisation::BuildPhysicsTable(const G4ParticleDefinition& part)
theAsymmetryTable->insertAt( j , ptrVectorA ) ;
theTransverseAsymmetryTable->insertAt( j , ptrVectorB ) ;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ePolarizedIonisation::ComputeAsymmetry(G4double energy,
G4double
G4ePolarizedIonisation::ComputeAsymmetry(G4double energy,
const G4MaterialCutsCouple* couple,
const G4ParticleDefinition& aParticle,
G4double cut,
G4double & tAsymmetry)
const G4ParticleDefinition& aParticle,
G4double cut,
G4double & tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
if (isElectron) {lAsymmetry = tAsymmetry = -1.0;}
if (isElectron) { lAsymmetry = tAsymmetry = -1.0; }
// calculate polarized cross section
theTargetPolarization=G4ThreeVector(0.,0.,1.);
@@ -297,24 +350,25 @@ G4double G4ePolarizedIonisation::ComputeAsymmetry(G4double energy,
theTargetPolarization=G4ThreeVector();
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
G4double sigma0 = emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// determine assymmetries
if (sigma0>0.) {
lAsymmetry=sigma2/sigma0-1.;
tAsymmetry=sigma3/sigma0-1.;
if (sigma0 > 0.) {
lAsymmetry=sigma2/sigma0 - 1.;
tAsymmetry=sigma3/sigma0 - 1.;
}
if (std::fabs(lAsymmetry)>1.) {
G4cout<<" energy="<<energy<<"\n";
G4cout<<"WARNING lAsymmetry= "<<lAsymmetry<<" ("<<std::fabs(lAsymmetry)-1.<<")\n";
G4cout<<"G4ePolarizedIonisation::ComputeAsymmetry WARNING: E(MeV)= "
<< energy << " lAsymmetry= "<<lAsymmetry
<<" ("<<std::fabs(lAsymmetry)-1.<<")\n";
}
if (std::fabs(tAsymmetry)>1.) {
G4cout<<" energy="<<energy<<"\n";
G4cout<<"WARNING tAsymmetry= "<<tAsymmetry<<" ("<<std::fabs(tAsymmetry)-1.<<")\n";
G4cout<<"G4ePolarizedIonisation::ComputeAsymmetry WARNING: E(MeV)= "
<< energy << " tAsymmetry= "<<tAsymmetry
<<" ("<<std::fabs(tAsymmetry)-1.<<")\n";
}
// else {
// G4cout<<" tAsymmetry= "<<tAsymmetry<<" ("<<std::fabs(tAsymmetry)-1.<<")\n";
// }
return lAsymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4eplusPolarizedAnnihilation.cc 76472 2013-11-11 10:34:07Z gcosmo $
// $Id: G4eplusPolarizedAnnihilation.cc 93113 2015-10-07 07:49:04Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -62,7 +62,6 @@
#include "G4PhysicsVector.hh"
#include "G4PhysicsLogVector.hh"
#include "G4PolarizedAnnihilationModel.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4ProductionCutsTable.hh"
@@ -73,111 +72,52 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4eplusPolarizedAnnihilation::G4eplusPolarizedAnnihilation(const G4String& name)
: G4VEmProcess(name), isInitialised(false),
theAsymmetryTable(NULL),
theTransverseAsymmetryTable(NULL)
: G4eplusAnnihilation(name), isInitialised(false),
theAsymmetryTable(nullptr),
theTransverseAsymmetryTable(nullptr)
{
enableAtRestDoIt = true;
SetProcessSubType(fAnnihilation);
emModel = 0;
emModel = new G4PolarizedAnnihilationModel();
SetEmModel(emModel, 1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4eplusPolarizedAnnihilation::~G4eplusPolarizedAnnihilation()
{
delete theAsymmetryTable;
delete theTransverseAsymmetryTable;
CleanTables();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::InitialiseProcess(const G4ParticleDefinition*)
void G4eplusPolarizedAnnihilation::CleanTables()
{
if(!isInitialised) {
isInitialised = true;
// SetVerboseLevel(3);
SetBuildTableFlag(true);
SetStartFromNullFlag(false);
SetSecondaryParticle(G4Gamma::Gamma());
G4double emin = 0.1*keV;
G4double emax = 100.*TeV;
SetLambdaBinning(120);
SetMinKinEnergy(emin);
SetMaxKinEnergy(emax);
emModel = new G4PolarizedAnnihilationModel();
emModel->SetLowEnergyLimit(emin);
emModel->SetHighEnergyLimit(emax);
AddEmModel(1, emModel);
if(theAsymmetryTable) {
theAsymmetryTable->clearAndDestroy();
delete theAsymmetryTable;
theAsymmetryTable = nullptr;
}
if(theTransverseAsymmetryTable) {
theTransverseAsymmetryTable->clearAndDestroy();
delete theTransverseAsymmetryTable;
theTransverseAsymmetryTable = nullptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// for polarization
G4double G4eplusPolarizedAnnihilation::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
G4double mfp = G4VEmProcess::GetMeanFreePath(track, previousStepSize, condition);
if (theAsymmetryTable) {
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
// G4Material* bMaterial = aLVolume->GetMaterial();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
if (!volumeIsPolarized || mfp == DBL_MAX) return mfp;
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
const G4StokesVector positronPolarization = track.GetPolarization();
const G4ParticleMomentum positronDirection0 = aDynamicPositron->GetMomentumDirection();
if (verboseLevel>=2) {
G4cout << " Mom " << positronDirection0 << G4endl;
G4cout << " Polarization " << positronPolarization << G4endl;
G4cout << " MaterialPol. " << electronPolarization << G4endl;
G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
G4cout << " Material " << aMaterial << G4endl;
}
G4bool isOutRange;
G4int idx= CurrentMaterialCutsCoupleIndex();
G4double lAsymmetry = (*theAsymmetryTable)(idx)->
GetValue(positronEnergy, isOutRange);
G4double tAsymmetry = (*theTransverseAsymmetryTable)(idx)->
GetValue(positronEnergy, isOutRange);
G4double polZZ = positronPolarization.z()*
electronPolarization*positronDirection0;
G4double polXX = positronPolarization.x()*
electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0);
G4double polYY = positronPolarization.y()*
electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0);
G4double impact = 1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry;
mfp *= 1. / impact;
if (verboseLevel>=2) {
G4cout << " MeanFreePath: " << mfp / mm << " mm " << G4endl;
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
}
if(theAsymmetryTable && theTransverseAsymmetryTable && mfp < DBL_MAX) {
mfp *= ComputeSaturationFactor(track);
}
if (verboseLevel>=2) {
G4cout << "G4eplusPolarizedAnnihilation::MeanFreePath: "
<< mfp / mm << " mm " << G4endl;
}
return mfp;
}
@@ -188,21 +128,46 @@ G4double G4eplusPolarizedAnnihilation::PostStepGetPhysicalInteractionLength(
G4double previousStepSize,
G4ForceCondition* condition)
{
G4double mfp = G4VEmProcess::PostStepGetPhysicalInteractionLength(track, previousStepSize, condition);
// save previous value
G4double nLength = theNumberOfInteractionLengthLeft;
if (theAsymmetryTable) {
// *** compute uppolarized step limit ***
G4double x = G4VEmProcess::PostStepGetPhysicalInteractionLength(track,
previousStepSize,
condition);
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
if(theAsymmetryTable && theTransverseAsymmetryTable && x < DBL_MAX) {
G4double curLength = currentInteractionLength*ComputeSaturationFactor(track);
if(nLength > 0.0) {
theNumberOfInteractionLengthLeft =
std::max(nLength - previousStepSize/curLength, 0.0);
}
x = theNumberOfInteractionLengthLeft * curLength;
}
if (verboseLevel>=2) {
G4cout << "G4eplusPolarizedAnnihilation::PostStepGetPhysicalInteractionLength: "
<< x/mm << " mm " << G4endl;
}
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double
G4eplusPolarizedAnnihilation::ComputeSaturationFactor(const G4Track& track)
{
G4Material* aMaterial = track.GetMaterial();
G4VPhysicalVolume* aPVolume = track.GetVolume();
G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
// G4Material* bMaterial = aLVolume->GetMaterial();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
G4PolarizationManager * polarizationManger = G4PolarizationManager::GetInstance();
const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
if (!volumeIsPolarized || mfp == DBL_MAX) return mfp;
G4double factor = 1.0;
if (volumeIsPolarized) {
// *** get asymmetry, if target is polarized ***
const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
@@ -211,7 +176,7 @@ G4double G4eplusPolarizedAnnihilation::PostStepGetPhysicalInteractionLength(
const G4ParticleMomentum positronDirection0 = aDynamicPositron->GetMomentumDirection();
if (verboseLevel>=2) {
G4cout << "G4eplusPolarizedAnnihilation::ComputeSaturationFactor: " << G4endl;
G4cout << " Mom " << positronDirection0 << G4endl;
G4cout << " Polarization " << positronPolarization << G4endl;
G4cout << " MaterialPol. " << electronPolarization << G4endl;
@@ -220,62 +185,79 @@ G4double G4eplusPolarizedAnnihilation::PostStepGetPhysicalInteractionLength(
G4cout << " Material " << aMaterial << G4endl;
}
G4bool isOutRange;
G4int idx= CurrentMaterialCutsCoupleIndex();
G4double lAsymmetry = (*theAsymmetryTable)(idx)->
GetValue(positronEnergy, isOutRange);
G4double tAsymmetry = (*theTransverseAsymmetryTable)(idx)->
GetValue(positronEnergy, isOutRange);
size_t midx = CurrentMaterialCutsCoupleIndex();
const G4PhysicsVector* aVector = nullptr;
const G4PhysicsVector* bVector = nullptr;
if(midx < theAsymmetryTable->size()) {
aVector = (*theAsymmetryTable)(midx);
}
if(midx < theTransverseAsymmetryTable->size()) {
bVector = (*theTransverseAsymmetryTable)(midx);
}
if(aVector && bVector) {
G4double lAsymmetry = aVector->Value(positronEnergy);
G4double tAsymmetry = bVector->Value(positronEnergy);
G4double polZZ = positronPolarization.z()*
(electronPolarization*positronDirection0);
G4double polXX = positronPolarization.x()*
(electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0));
G4double polYY = positronPolarization.y()*
(electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0));
G4double polZZ = positronPolarization.z()*
electronPolarization*positronDirection0;
G4double polXX = positronPolarization.x()*
electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0);
G4double polYY = positronPolarization.y()*
electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0);
factor /= (1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry);
G4double impact = 1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry;
mfp *= 1. / impact;
if (verboseLevel>=2) {
G4cout << " MeanFreePath: " << mfp / mm << " mm " << G4endl;
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
if (verboseLevel>=2) {
G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
G4cout << " Factor: " << factor << G4endl;
}
} else {
G4ExceptionDescription ed;
ed << "Problem with asymmetry tables: material index " << midx
<< " is out of range or tables are not filled";
G4Exception("G4eplusPolarizedAnnihilation::ComputeSaturationFactor","em0048",
JustWarning, ed, "");
}
}
return mfp;
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::BuildPhysicsTable(const G4ParticleDefinition& pd)
void G4eplusPolarizedAnnihilation::BuildPhysicsTable(
const G4ParticleDefinition& part)
{
G4VEmProcess::BuildPhysicsTable(pd);
BuildAsymmetryTable(pd);
G4VEmProcess::BuildPhysicsTable(part);
G4bool isMaster = true;
const G4eplusPolarizedAnnihilation* masterProcess =
static_cast<const G4eplusPolarizedAnnihilation*>(GetMasterProcess());
if(masterProcess && masterProcess != this) { isMaster = false; }
if(isMaster) { BuildAsymmetryTables(part); }
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::PreparePhysicsTable(const G4ParticleDefinition& pd)
void G4eplusPolarizedAnnihilation::BuildAsymmetryTables(
const G4ParticleDefinition& part)
{
G4VEmProcess::PreparePhysicsTable(pd);
theAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
theTransverseAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
}
// cleanup old, initialise new table
CleanTables();
theAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
theTransverseAsymmetryTable =
G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
void G4eplusPolarizedAnnihilation::BuildAsymmetryTable(const G4ParticleDefinition& part)
{
// Access to materials
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
G4cout<<" annih-numOfCouples="<<numOfCouples<<"\n";
//G4cout<<" annih-numOfCouples="<<numOfCouples<<"\n";
for(size_t i=0; i<numOfCouples; ++i) {
G4cout<<"annih- "<<i<<"/"<<numOfCouples<<"\n";
//G4cout<<"annih- "<<i<<"/"<<numOfCouples<<"\n";
if (!theAsymmetryTable) break;
G4cout<<"annih- "<<theAsymmetryTable->GetFlag(i)<<"\n";
//G4cout<<"annih- "<<theAsymmetryTable->GetFlag(i)<<"\n";
if (theAsymmetryTable->GetFlag(i)) {
G4cout<<" building pol-annih ... \n";
//G4cout<<" building pol-annih ... \n";
// create physics vector and fill it
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
@@ -291,15 +273,12 @@ void G4eplusPolarizedAnnihilation::BuildAsymmetryTable(const G4ParticleDefinitio
aVector->PutValue(j,asym);
tVector->PutValue(j,tasm);
}
G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, aVector);
G4PhysicsTableHelper::SetPhysicsVector(theTransverseAsymmetryTable, i, tVector);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4eplusPolarizedAnnihilation::ComputeAsymmetry(G4double energy,
@@ -308,38 +287,35 @@ G4double G4eplusPolarizedAnnihilation::ComputeAsymmetry(G4double energy,
G4double cut,
G4double &tAsymmetry)
{
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
G4double lAsymmetry = 0.0;
tAsymmetry = 0.0;
// calculate polarized cross section
theTargetPolarization=G4ThreeVector(0.,0.,1.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate polarized cross section
theTargetPolarization=G4ThreeVector(0.,0.,1.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate transversely polarized cross section
theTargetPolarization=G4ThreeVector(1.,0.,0.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate transversely polarized cross section
theTargetPolarization=G4ThreeVector(1.,0.,0.);
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate unpolarized cross section
theTargetPolarization=G4ThreeVector();
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// calculate unpolarized cross section
theTargetPolarization=G4ThreeVector();
emModel->SetTargetPolarization(theTargetPolarization);
emModel->SetBeamPolarization(theTargetPolarization);
G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
// determine assymmetries
// determine assymmetries
if (sigma0>0.) {
lAsymmetry=sigma2/sigma0-1.;
tAsymmetry=sigma3/sigma0-1.;
}
return lAsymmetry;
}
return lAsymmetry;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusPolarizedAnnihilation::PrintInfo()
@@ -349,32 +325,3 @@ void G4eplusPolarizedAnnihilation::PrintInfo()
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4eplusPolarizedAnnihilation::AtRestDoIt(const G4Track& aTrack,
const G4Step& )
//
// Performs the e+ e- annihilation when both particles are assumed at rest.
// It generates two back to back photons with energy = electron_mass.
// The angular distribution is isotropic.
// GEANT4 internal units
//
// Note : Effects due to binding of atomic electrons are negliged.
{
fParticleChange.InitializeForPostStep(aTrack);
fParticleChange.SetNumberOfSecondaries(2);
G4double cosTeta = 2.*G4UniformRand()-1. , sinTeta = std::sqrt(1.-cosTeta*cosTeta);
G4double phi = twopi * G4UniformRand();
G4ThreeVector direction (sinTeta*std::cos(phi), sinTeta*std::sin(phi), cosTeta);
fParticleChange.AddSecondary( new G4DynamicParticle (G4Gamma::Gamma(),
direction, electron_mass_c2) );
fParticleChange.AddSecondary( new G4DynamicParticle (G4Gamma::Gamma(),
-direction, electron_mass_c2) );
// Kill the incident positron
//
fParticleChange.ProposeTrackStatus(fStopAndKill);
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....