Import Geant4 10.2.0 source tree
This commit is contained in:
@@ -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....
|
||||
|
||||
|
||||
+132
-185
@@ -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....
|
||||
|
||||
Reference in New Issue
Block a user