1 #include <G4ParticleTypes.hh> 2 #include <G4EmProcessSubType.hh> 3 #include <G4Version.hh> 4 #include <G4SystemOfUnits.hh> 5 #include <G4PhysicalConstants.hh> 6 #include <G4FieldManager.hh> 20 : G4VRestDiscreteProcess(processName, type),
21 fEmSaturation(nullptr)
23 SetProcessSubType(fScintillation);
26 G4cout << GetProcessName() <<
" is created " << G4endl;
39 if (aParticleType.IsShortLived())
return false;
40 if (aParticleType.GetParticleName() ==
"opticalphoton")
return false;
41 if (aParticleType.GetParticleName() ==
"thermalelectron")
return false;
43 if (
std::abs(aParticleType.GetPDGEncoding())==12)
return false;
44 if (
std::abs(aParticleType.GetPDGEncoding())==14)
return false;
45 if (
std::abs(aParticleType.GetPDGEncoding())==16)
return false;
62 aParticleChange.Initialize(aTrack);
64 const G4Material* aMaterial = aTrack.GetMaterial();
66 bool inLiquidArgon =
true;
68 if (aMaterial->GetState() != kStateLiquid) {
70 if (aMaterial->GetState() == kStateUndefined) {
72 << aMaterial->GetName());
74 inLiquidArgon =
false;
76 if (aMaterial->GetNumberOfElements() > 1) {
78 inLiquidArgon =
false;
80 if (
std::abs(aMaterial->GetElement(0)->GetZ()-18.0) > 0.5) {
82 inLiquidArgon =
false;
85 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
86 const G4ParticleDefinition *pDef = aParticle->GetDefinition();
87 G4String particleName = pDef->GetParticleName();
89 G4double totalEnergyDeposit = aStep.GetTotalEnergyDeposit();
91 if (totalEnergyDeposit <= 0.0) {
92 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
95 if (aStep.GetStepLength() <= 0.0) {
96 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
101 G4double nonIonizingEnergy
103 aParticleChange.ProposeNonIonizingEnergyDeposit(nonIonizingEnergy);
104 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
108 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
109 const G4VPhysicalVolume* aVolume = pPostStepPoint->GetPhysicalVolume();
110 const G4LogicalVolume* aLogVolume = aVolume->GetLogicalVolume();
111 const G4FieldManager* aFieldManager = aLogVolume->GetFieldManager();
112 if (!aFieldManager) {
113 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
115 if (!aFieldManager->DoesFieldExist()) {
116 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
118 const G4Field* aField = aFieldManager->GetDetectorField();
121 << aLogVolume->GetName()
122 <<
" should have field!");
123 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
126 G4ThreeVector thePosition = pPostStepPoint->GetPosition();
127 double theTime = pPostStepPoint->GetGlobalTime();
129 thePosition.x(), thePosition.y(), thePosition.z(), theTime};
131 aField->GetFieldValue(point,bField);
133 double electricField = bField[3]*bField[3];
134 electricField += bField[4]*bField[4];
135 electricField += bField[5]*bField[5];
136 if (electricField > 0) {
137 electricField = std::sqrt(electricField);
142 G4double dokeBirks[3];
144 dokeBirks[0] = 0.07*
pow((electricField),-0.85);
146 dokeBirks[1] = dokeBirks[0]/(1-dokeBirks[2]);
148 G4double dE = totalEnergyDeposit/
MeV;
149 G4double dx = aStep.GetStepLength()/
cm;
150 G4double density = aMaterial->GetDensity()/(
g/
cm3);
152 if (dx != 0.0) LET = (dE/dx)*(1/density);
156 if (particleName ==
"gamma") {
160 else if (
std::abs(pDef->GetPDGCharge()) < 0.1) {
166 double electronStep = dE/density/tempLET;
167 if (dx > electronStep) {
176 if (particleName !=
"e+" || particleName !=
"e-")
break;
177 if (aTrack.GetCurrentStepNumber() != 1)
break;
179 if (ratio > 0.7)
break;
184 G4double recombProb = (dokeBirks[0]*LET)/(1+dokeBirks[1]*LET)+dokeBirks[2];
186 G4double ScintillationYield = 1 / (19.5*
eV);
187 G4double NumQuanta = ScintillationYield*totalEnergyDeposit;
188 G4double ExcitationRatio = 0.21;
189 G4double NumExcitons = NumQuanta*ExcitationRatio/(1+ExcitationRatio);
190 G4double NumIons = NumQuanta - NumExcitons;
191 G4double NumPhotons = NumExcitons + NumIons*recombProb;
198 G4double nonIonizingEnergy = totalEnergyDeposit;
199 nonIonizingEnergy *= NumPhotons/NumQuanta;
200 aParticleChange.ProposeNonIonizingEnergyDeposit(nonIonizingEnergy);
201 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
208 G4ForceCondition* condition)
210 *condition = StronglyForced;
223 G4ForceCondition* condition)
235 if ( E >= 1 ) LET = 116.70-162.97*log10(E)+99.361*
pow(log10(E),2)-
236 33.405*
pow(log10(E),3)+6.5069*
pow(log10(E),4)-
237 0.69334*
pow(log10(E),5)+.031563*
pow(log10(E),6);
238 else if ( E>0 && E<1 ) LET = 100;
static constexpr double cm
G4bool IsApplicable(const G4ParticleDefinition &aParticleType)
Determine which particles this process should be applied too.
static constexpr double g
static constexpr double cm3
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
Apply the scintilation process for an in-flight particle.
static constexpr double MeV
static constexpr double eV
#define EDepSimError(outStream)
G4double CalculateElectronLET(G4double E)
G4VParticleChange * AtRestDoIt(const G4Track &aTrack, const G4Step &aStep)
G4double GetMeanLifeTime(const G4Track &aTrack, G4ForceCondition *)
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
DokeBirks(const G4String &processName="Doke-Birks", G4ProcessType type=fElectromagnetic)
G4EmSaturation * fEmSaturation