Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4QuasiCerenkov Class Reference

#include <G4QuasiCerenkov.hh>

Inheritance diagram for G4QuasiCerenkov:

Public Member Functions

 G4QuasiCerenkov (const G4String &processName="QuasiCerenkov", G4ProcessType type=fElectromagnetic)
 ~G4QuasiCerenkov ()
 G4QuasiCerenkov (const G4QuasiCerenkov &right)
G4QuasiCerenkovoperator= (const G4QuasiCerenkov &right)=delete
G4bool IsApplicable (const G4ParticleDefinition &aParticleType) override
void BuildPhysicsTable (const G4ParticleDefinition &aParticleType) override
void PreparePhysicsTable (const G4ParticleDefinition &part) override
void Initialise ()
G4double GetMeanFreePath (const G4Track &aTrack, G4double, G4ForceCondition *)
G4double PostStepGetPhysicalInteractionLength (const G4Track &aTrack, G4double, G4ForceCondition *) override
G4VParticleChangePostStepDoIt (const G4Track &aTrack, const G4Step &aStep) override
virtual G4double AlongStepGetPhysicalInteractionLength (const G4Track &, G4double, G4double, G4double &, G4GPILSelection *) override
virtual G4double AtRestGetPhysicalInteractionLength (const G4Track &, G4ForceCondition *) override
virtual G4VParticleChangeAtRestDoIt (const G4Track &, const G4Step &) override
virtual G4VParticleChangeAlongStepDoIt (const G4Track &, const G4Step &) override
void SetTrackSecondariesFirst (const G4bool state)
G4bool GetTrackSecondariesFirst () const
void SetMaxBetaChangePerStep (const G4double d)
G4double GetMaxBetaChangePerStep () const
void SetMaxNumPhotonsPerStep (const G4int NumPhotons)
G4int GetMaxNumPhotonsPerStep () const
void SetStackPhotons (const G4bool)
G4bool GetStackPhotons () const
void SetOffloadPhotons (const G4bool)
G4bool GetOffloadPhotons () const
G4int GetNumPhotons () const
G4PhysicsTableGetPhysicsTable () const
void DumpPhysicsTable () const
G4double GetAverageNumberOfPhotons (const G4double charge, const G4double beta, const G4Material *aMaterial, G4MaterialPropertyVector *Rindex) const
void DumpInfo () const override
void ProcessDescription (std::ostream &out) const override
void SetVerboseLevel (G4int)
Public Member Functions inherited from G4VProcess
 G4VProcess (const G4String &aName="NoName", G4ProcessType aType=fNotDefined)
 G4VProcess (const G4VProcess &right)
virtual ~G4VProcess ()
G4VProcessoperator= (const G4VProcess &)=delete
G4bool operator== (const G4VProcess &right) const
G4bool operator!= (const G4VProcess &right) const
G4double GetCurrentInteractionLength () const
void SetPILfactor (G4double value)
G4double GetPILfactor () const
G4double AlongStepGPIL (const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &proposedSafety, G4GPILSelection *selection)
G4double AtRestGPIL (const G4Track &track, G4ForceCondition *condition)
G4double PostStepGPIL (const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
virtual G4bool StorePhysicsTable (const G4ParticleDefinition *, const G4String &, G4bool)
virtual G4bool RetrievePhysicsTable (const G4ParticleDefinition *, const G4String &, G4bool)
const G4StringGetPhysicsTableFileName (const G4ParticleDefinition *, const G4String &directory, const G4String &tableName, G4bool ascii=false)
const G4StringGetProcessName () const
G4ProcessType GetProcessType () const
void SetProcessType (G4ProcessType)
G4int GetProcessSubType () const
void SetProcessSubType (G4int)
virtual const G4VProcessGetCreatorProcess () const
virtual void StartTracking (G4Track *)
virtual void EndTracking ()
virtual void SetProcessManager (const G4ProcessManager *)
virtual const G4ProcessManagerGetProcessManager ()
virtual void ResetNumberOfInteractionLengthLeft ()
G4double GetNumberOfInteractionLengthLeft () const
G4double GetTotalNumberOfInteractionLengthTraversed () const
G4bool isAtRestDoItIsEnabled () const
G4bool isAlongStepDoItIsEnabled () const
G4bool isPostStepDoItIsEnabled () const
void SetVerboseLevel (G4int value)
G4int GetVerboseLevel () const
virtual void SetMasterProcess (G4VProcess *masterP)
const G4VProcessGetMasterProcess () const
virtual void BuildWorkerPhysicsTable (const G4ParticleDefinition &part)
virtual void PrepareWorkerPhysicsTable (const G4ParticleDefinition &)

Protected Attributes

G4PhysicsTablethePhysicsTable
std::map< std::size_t, std::size_t > fIndexMPT
Protected Attributes inherited from G4VProcess
const G4ProcessManageraProcessManager = nullptr
G4VParticleChangepParticleChange = nullptr
G4ParticleChange aParticleChange
G4double theNumberOfInteractionLengthLeft = -1.0
G4double currentInteractionLength = -1.0
G4double theInitialNumberOfInteractionLength = -1.0
G4String theProcessName
G4String thePhysicsTableFileName
G4ProcessType theProcessType = fNotDefined
G4int theProcessSubType = -1
G4double thePILfactor = 1.0
G4int verboseLevel = 0
G4bool enableAtRestDoIt = true
G4bool enableAlongStepDoIt = true
G4bool enablePostStepDoIt = true

Additional Inherited Members

Static Public Member Functions inherited from G4VProcess
static const G4StringGetProcessTypeName (G4ProcessType)
Protected Member Functions inherited from G4VProcess
void SubtractNumberOfInteractionLengthLeft (G4double prevStepSize)
void ClearNumberOfInteractionLengthLeft ()

Detailed Description

Definition at line 67 of file G4QuasiCerenkov.hh.

Constructor & Destructor Documentation

◆ G4QuasiCerenkov() [1/2]

G4QuasiCerenkov::G4QuasiCerenkov ( const G4String & processName = "QuasiCerenkov",
G4ProcessType type = fElectromagnetic )
explicit

Definition at line 49 of file G4QuasiCerenkov.cc.

50 : G4VProcess(processName, type)
51 , fNumPhotons(0)
52{
53 secID = G4PhysicsModelCatalog::GetModelID("model_QuasiCerenkov");
55
56 thePhysicsTable = nullptr;
57
58 if(verboseLevel > 0)
59 {
60 G4cout << GetProcessName() << " is created." << G4endl;
61 }
62 Initialise();
63}
@ fCerenkov
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
static G4int GetModelID(const G4int modelIndex)
G4PhysicsTable * thePhysicsTable
G4VProcess(const G4String &aName="NoName", G4ProcessType aType=fNotDefined)
Definition G4VProcess.cc:46
G4int verboseLevel
void SetProcessSubType(G4int)
const G4String & GetProcessName() const

Referenced by G4QuasiCerenkov(), and operator=().

◆ ~G4QuasiCerenkov()

G4QuasiCerenkov::~G4QuasiCerenkov ( )

Definition at line 66 of file G4QuasiCerenkov.cc.

67{
68 if(thePhysicsTable != nullptr)
69 {
70 thePhysicsTable->clearAndDestroy();
71 delete thePhysicsTable;
72 }
73}

◆ G4QuasiCerenkov() [2/2]

G4QuasiCerenkov::G4QuasiCerenkov ( const G4QuasiCerenkov & right)
explicit

Member Function Documentation

◆ AlongStepDoIt()

virtual G4VParticleChange * G4QuasiCerenkov::AlongStepDoIt ( const G4Track & ,
const G4Step &  )
inlineoverridevirtual

Implements G4VProcess.

Definition at line 120 of file G4QuasiCerenkov.hh.

122 {
123 return nullptr;
124 };

◆ AlongStepGetPhysicalInteractionLength()

virtual G4double G4QuasiCerenkov::AlongStepGetPhysicalInteractionLength ( const G4Track & ,
G4double ,
G4double ,
G4double & ,
G4GPILSelection *  )
inlineoverridevirtual

Implements G4VProcess.

Definition at line 102 of file G4QuasiCerenkov.hh.

104 {
105 return -1.0;
106 };

◆ AtRestDoIt()

virtual G4VParticleChange * G4QuasiCerenkov::AtRestDoIt ( const G4Track & ,
const G4Step &  )
inlineoverridevirtual

Implements G4VProcess.

Definition at line 115 of file G4QuasiCerenkov.hh.

116 {
117 return nullptr;
118 };

◆ AtRestGetPhysicalInteractionLength()

virtual G4double G4QuasiCerenkov::AtRestGetPhysicalInteractionLength ( const G4Track & ,
G4ForceCondition *  )
inlineoverridevirtual

Implements G4VProcess.

Definition at line 108 of file G4QuasiCerenkov.hh.

110 {
111 return -1.0;
112 };

◆ BuildPhysicsTable()

void G4QuasiCerenkov::BuildPhysicsTable ( const G4ParticleDefinition & aParticleType)
overridevirtual

Reimplemented from G4VProcess.

Definition at line 115 of file G4QuasiCerenkov.cc.

116{
118 return;
119
120 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
121 std::size_t numOfMaterials = G4Material::GetNumberOfMaterials();
122
123 // Find the number of materials that have non-empty material property tables
124 std::size_t numOfMaterialsWithMPT = 0;
125 for(std::size_t i = 0; i < numOfMaterials; ++i)
126 {
127 if(((*theMaterialTable)[i])->GetMaterialPropertiesTable())
128 {
129 ++numOfMaterialsWithMPT;
130 }
131 }
132
133 thePhysicsTable = new G4PhysicsTable(numOfMaterialsWithMPT);
134
135 // loop over materials
136 std::size_t indexMPT = 0;
137 for(std::size_t i = 0; i < numOfMaterials; ++i)
138 {
139 G4PhysicsFreeVector* cerenkovIntegral = nullptr;
140
141 // Retrieve vector of refraction indices for the material
142 // from the material's optical properties table
143 G4Material* aMaterial = (*theMaterialTable)[i];
144 G4MaterialPropertiesTable* MPT = aMaterial->GetMaterialPropertiesTable();
145
146 if(MPT)
147 {
148 cerenkovIntegral = new G4PhysicsFreeVector();
149 G4MaterialPropertyVector* refractiveIndex = MPT->GetProperty(kRINDEX);
150
151 if(refractiveIndex)
152 {
153 // Retrieve the first refraction index in vector
154 // of (photon energy, refraction index) pairs
155 G4double currentRI = (*refractiveIndex)[0];
156 if(currentRI > 1.0)
157 {
158 // Create first (photon energy, Cerenkov Integral) pair
159 G4double currentPM = refractiveIndex->Energy(0);
160 G4double currentCAI = 0.0;
161
162 cerenkovIntegral->InsertValues(currentPM, currentCAI);
163
164 // Set previous values to current ones prior to loop
165 G4double prevPM = currentPM;
166 G4double prevCAI = currentCAI;
167 G4double prevRI = currentRI;
168
169 // loop over all (photon energy, refraction index)
170 // pairs stored for this material
171 for(std::size_t ii = 1; ii < refractiveIndex->GetVectorLength(); ++ii)
172 {
173 currentRI = (*refractiveIndex)[ii];
174 currentPM = refractiveIndex->Energy(ii);
175 currentCAI = prevCAI + (currentPM - prevPM) * 0.5 *
176 (1.0 / (prevRI * prevRI) +
177 1.0 / (currentRI * currentRI));
178
179 cerenkovIntegral->InsertValues(currentPM, currentCAI);
180
181 prevPM = currentPM;
182 prevCAI = currentCAI;
183 prevRI = currentRI;
184 }
185 }
186 }
187 // The Cerenkov integral for a given material will be inserted in
188 // thePhysicsTable according to the position of the material in
189 // the material table.
190 thePhysicsTable->insertAt(indexMPT, cerenkovIntegral);
191 fIndexMPT.insert(std::make_pair(i, indexMPT));
192 ++indexMPT;
193 }
194 }
195}
G4PhysicsFreeVector G4MaterialPropertyVector
std::vector< G4Material * > G4MaterialTable
double G4double
Definition G4Types.hh:83
G4MaterialPropertyVector * GetProperty(const char *key) const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
static std::size_t GetNumberOfMaterials()
static G4MaterialTable * GetMaterialTable()
void InsertValues(const G4double energy, const G4double value)
G4double Energy(const std::size_t index) const
std::size_t GetVectorLength() const
std::map< std::size_t, std::size_t > fIndexMPT

◆ DumpInfo()

void G4QuasiCerenkov::DumpInfo ( ) const
inlineoverridevirtual

Reimplemented from G4VProcess.

Definition at line 176 of file G4QuasiCerenkov.hh.

void ProcessDescription(std::ostream &out) const override

◆ DumpPhysicsTable()

void G4QuasiCerenkov::DumpPhysicsTable ( ) const

Definition at line 639 of file G4QuasiCerenkov.cc.

640{
641 G4cout << "Dump Physics Table!" << G4endl;
642 for(std::size_t i = 0; i < thePhysicsTable->entries(); ++i)
643 {
644 (*thePhysicsTable)[i]->DumpValues();
645 }
646}

◆ GetAverageNumberOfPhotons()

G4double G4QuasiCerenkov::GetAverageNumberOfPhotons ( const G4double charge,
const G4double beta,
const G4Material * aMaterial,
G4MaterialPropertyVector * Rindex ) const

Definition at line 516 of file G4QuasiCerenkov.cc.

521{
522 constexpr G4double Rfact = 369.81 / (eV * cm);
523 if(beta <= 0.0)
524 return 0.0;
525 G4double BetaInverse = 1. / beta;
526
527 // Vectors used in computation of Cerenkov Angle Integral:
528 // - Refraction Indices for the current material
529 // - new G4PhysicsFreeVector allocated to hold CAI's
530 std::size_t materialIndex = aMaterial->GetIndex();
531
532 // Retrieve the Cerenkov Angle Integrals for this material
533 auto it = fIndexMPT.find(materialIndex);
534
535 std::size_t indexMPT = 0;
536 if(it != fIndexMPT.end())
537 {
538 indexMPT = it->second;
539 }
540 else
541 {
543 ed << "G4MaterialPropertiesTable for " << aMaterial->GetName()
544 << " is not found!" << G4endl;
545 G4Exception("G4QuasiCerenkov::GetAverageNumberOfPhotons",
546 "QuasiCerenkovCerenkov01", FatalException, ed);
547 }
548
549 G4PhysicsVector* CerenkovAngleIntegrals = ((*thePhysicsTable)(indexMPT));
550
551 std::size_t length = CerenkovAngleIntegrals->GetVectorLength();
552 if(0 == length)
553 return 0.0;
554
555 // Min and Max photon energies
556 G4double Pmin = Rindex->Energy(0);
557 G4double Pmax = Rindex->GetMaxEnergy();
558
559 // Min and Max Refraction Indices
560 G4double nMin = Rindex->GetMinValue();
561 G4double nMax = Rindex->GetMaxValue();
562
563 // Max Cerenkov Angle Integral
564 G4double CAImax = (*CerenkovAngleIntegrals)[length - 1];
565
566 G4double dp, ge;
567 // If n(Pmax) < 1/Beta -- no photons generated
568 if(nMax < BetaInverse)
569 {
570 dp = 0.0;
571 ge = 0.0;
572 }
573 // otherwise if n(Pmin) >= 1/Beta -- photons generated
574 else if(nMin > BetaInverse)
575 {
576 dp = Pmax - Pmin;
577 ge = CAImax;
578 }
579 // If n(Pmin) < 1/Beta, and n(Pmax) >= 1/Beta, then we need to find a P such
580 // that the value of n(P) == 1/Beta. Interpolation is performed by the
581 // GetEnergy() and Value() methods of the G4MaterialPropertiesTable and
582 // the Value() method of G4PhysicsVector.
583 else
584 {
585 Pmin = Rindex->GetEnergy(BetaInverse);
586 dp = Pmax - Pmin;
587
588 G4double CAImin = CerenkovAngleIntegrals->Value(Pmin);
589 ge = CAImax - CAImin;
590
591 if(verboseLevel > 1)
592 {
593 G4cout << "CAImin = " << CAImin << G4endl << "ge = " << ge << G4endl;
594 }
595 }
596
597 // Calculate number of photons
598 G4double NumPhotons = Rfact * charge / eplus * charge / eplus *
599 (dp - ge * BetaInverse * BetaInverse);
600
601 return NumPhotons;
602}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
std::size_t GetIndex() const
const G4String & GetName() const
G4double GetEnergy(const G4double value) const
G4double GetMinValue() const
G4double GetMaxEnergy() const
G4double GetMaxValue() const
G4double Value(const G4double energy, std::size_t &lastidx) const

Referenced by PostStepDoIt(), and PostStepGetPhysicalInteractionLength().

◆ GetMaxBetaChangePerStep()

G4double G4QuasiCerenkov::GetMaxBetaChangePerStep ( ) const
inline

Definition at line 205 of file G4QuasiCerenkov.hh.

206{
207 return fMaxBetaChange;
208}

◆ GetMaxNumPhotonsPerStep()

G4int G4QuasiCerenkov::GetMaxNumPhotonsPerStep ( ) const
inline

Definition at line 210 of file G4QuasiCerenkov.hh.

210{ return fMaxPhotons; }

◆ GetMeanFreePath()

G4double G4QuasiCerenkov::GetMeanFreePath ( const G4Track & aTrack,
G4double ,
G4ForceCondition *  )

Definition at line 404 of file G4QuasiCerenkov.cc.

406{
407 return 1.;
408}

◆ GetNumPhotons()

G4int G4QuasiCerenkov::GetNumPhotons ( ) const
inline

Definition at line 216 of file G4QuasiCerenkov.hh.

216{ return fNumPhotons; }

◆ GetOffloadPhotons()

G4bool G4QuasiCerenkov::GetOffloadPhotons ( ) const
inline

Definition at line 214 of file G4QuasiCerenkov.hh.

214{ return fOffloadingFlag; }

◆ GetPhysicsTable()

G4PhysicsTable * G4QuasiCerenkov::GetPhysicsTable ( ) const
inline

Definition at line 218 of file G4QuasiCerenkov.hh.

219{
220 return thePhysicsTable;
221}

◆ GetStackPhotons()

G4bool G4QuasiCerenkov::GetStackPhotons ( ) const
inline

Definition at line 212 of file G4QuasiCerenkov.hh.

212{ return fStackingFlag; }

◆ GetTrackSecondariesFirst()

G4bool G4QuasiCerenkov::GetTrackSecondariesFirst ( ) const
inline

Definition at line 200 of file G4QuasiCerenkov.hh.

201{
202 return fTrackSecondariesFirst;
203}

◆ Initialise()

void G4QuasiCerenkov::Initialise ( )

Definition at line 103 of file G4QuasiCerenkov.cc.

104{
105 G4OpticalParameters* params = G4OpticalParameters::Instance();
112}
G4int GetCerenkovVerboseLevel() const
G4int GetCerenkovMaxPhotonsPerStep() const
static G4OpticalParameters * Instance()
G4double GetCerenkovMaxBetaChange() const
G4bool GetCerenkovOffloadPhotons() const
G4bool GetCerenkovTrackSecondariesFirst() const
G4bool GetCerenkovStackPhotons() const
void SetMaxNumPhotonsPerStep(const G4int NumPhotons)
void SetOffloadPhotons(const G4bool)
void SetTrackSecondariesFirst(const G4bool state)
void SetVerboseLevel(G4int)
void SetMaxBetaChangePerStep(const G4double d)
void SetStackPhotons(const G4bool)

Referenced by G4QuasiCerenkov(), and PreparePhysicsTable().

◆ IsApplicable()

G4bool G4QuasiCerenkov::IsApplicable ( const G4ParticleDefinition & aParticleType)
overridevirtual

Reimplemented from G4VProcess.

Definition at line 92 of file G4QuasiCerenkov.cc.

93{
94 return (aParticleType.GetPDGCharge() != 0.0 &&
95 aParticleType.GetPDGMass() != 0.0 &&
96 aParticleType.GetParticleName() != "chargedgeantino" &&
97 !aParticleType.IsShortLived())
98 ? true
99 : false;
100}
const G4String & GetParticleName() const

◆ operator=()

G4QuasiCerenkov & G4QuasiCerenkov::operator= ( const G4QuasiCerenkov & right)
delete

◆ PostStepDoIt()

G4VParticleChange * G4QuasiCerenkov::PostStepDoIt ( const G4Track & aTrack,
const G4Step & aStep )
overridevirtual

Implements G4VProcess.

Definition at line 198 of file G4QuasiCerenkov.cc.

207{
208 aParticleChange.Initialize(aTrack);
209
210 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
211 const G4Material* aMaterial = aTrack.GetMaterial();
212
213 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
214 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
215
216 G4ThreeVector x0 = pPreStepPoint->GetPosition();
217 G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
218 G4double t0 = pPreStepPoint->GetGlobalTime();
219
220 G4MaterialPropertiesTable* MPT = aMaterial->GetMaterialPropertiesTable();
221 if(!MPT)
222 return pParticleChange;
223
225 if(!Rindex)
226 return pParticleChange;
227
228 G4double charge = aParticle->GetDefinition()->GetPDGCharge();
229
230 G4double beta1 = pPreStepPoint->GetBeta();
231 G4double beta2 = pPostStepPoint->GetBeta();
232 G4double beta = (beta1 + beta2) * 0.5;
233
234 G4double MeanNumberOfPhotons =
235 GetAverageNumberOfPhotons(charge, beta, aMaterial, Rindex);
236 G4double MeanNumberOfPhotons1 =
237 GetAverageNumberOfPhotons(charge, beta1, aMaterial, Rindex);
238 G4double MeanNumberOfPhotons2 =
239 GetAverageNumberOfPhotons(charge, beta2, aMaterial, Rindex);
240
241 if(MeanNumberOfPhotons <= 0.0)
242 {
243 // return unchanged particle and no secondaries
244 aParticleChange.SetNumberOfSecondaries(0);
245 return pParticleChange;
246 }
247
248 MeanNumberOfPhotons *= aStep.GetStepLength();
249 fNumPhotons = (G4int) G4Poisson(MeanNumberOfPhotons);
250
251 // third condition added to prevent infinite loop in do-while below,
252 // see bugzilla 2555
253 if(fNumPhotons <= 0 || !fStackingFlag ||
254 std::max(MeanNumberOfPhotons1, MeanNumberOfPhotons2) < 1e-15)
255 {
256 // return unchanged particle and no secondaries
257 aParticleChange.SetNumberOfSecondaries(0);
258 return pParticleChange;
259 }
260
261 G4double deltaVelocity = pPostStepPoint->GetVelocity() -
262 pPreStepPoint->GetVelocity();
263 auto touchableHandle = aStep.GetPreStepPoint()->GetTouchableHandle();
264
265 if(fOffloadingFlag)
266 {
267 // Create a G4DynamicParticle with G4QuasiOpticalPhoton
268 auto quasiPhoton = new G4DynamicParticle(
270 aParticle->GetMomentum());
271
272 // Create a new G4Track object with the quasi-optical photon
273 G4Track* aSecondaryTrack = new G4Track(quasiPhoton, t0, x0);
274 aSecondaryTrack->SetTouchableHandle(touchableHandle);
275 aSecondaryTrack->SetParentID(aTrack.GetTrackID());
276 aSecondaryTrack->SetCreatorModelID(secID);
277
278 // Attach auxiliary track information with associated metadata
279 G4QuasiOpticalData quasiTrackData{aMaterial->GetIndex(), fNumPhotons,
280 charge, aStep.GetStepLength(), pPreStepPoint->GetVelocity(),
281 deltaVelocity, aStep.GetDeltaPosition()};
282 aSecondaryTrack->SetAuxiliaryTrackInformation(secID,
283 new G4CerenkovQuasiTrackInfo(quasiTrackData,
284 MeanNumberOfPhotons1, MeanNumberOfPhotons2));
285 aParticleChange.AddSecondary(aSecondaryTrack);
286
287 // Return early when offloading is enabled
288 return pParticleChange;
289 }
290
291 ////////////////////////////////////////////////////////////////
292 aParticleChange.SetNumberOfSecondaries(fNumPhotons);
293
294 if(fTrackSecondariesFirst)
295 {
296 if(aTrack.GetTrackStatus() == fAlive)
297 aParticleChange.ProposeTrackStatus(fSuspend);
298 }
299
300 ////////////////////////////////////////////////////////////////
301 G4double Pmin = Rindex->Energy(0);
302 G4double Pmax = Rindex->GetMaxEnergy();
303 G4double dp = Pmax - Pmin;
304 G4double deltaNumberOfPhotons = MeanNumberOfPhotons1 - MeanNumberOfPhotons2;
305 G4double maxNumberOfPhotons =
306 std::max(MeanNumberOfPhotons1, MeanNumberOfPhotons2);
307
308 G4double nMax = Rindex->GetMaxValue();
309 G4double BetaInverse = 1. / beta;
310
311 G4double maxCos = BetaInverse / nMax;
312 G4double maxSin2 = 1.0 - maxCos * maxCos;
313
314 for(G4int i = 0; i < fNumPhotons; ++i)
315 {
316 // Determine photon energy
317 G4double rand;
318 G4double sampledEnergy;
319 G4double cosTheta, sin2Theta;
320
321 // sample an energy
322 do
323 {
324 rand = G4UniformRand();
325 sampledEnergy = Pmin + rand * dp;
326 cosTheta = BetaInverse / Rindex->Value(sampledEnergy);
327
328 sin2Theta = 1.0 - cosTheta * cosTheta;
329 rand = G4UniformRand();
330
331 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
332 } while(rand * maxSin2 > sin2Theta);
333
334 // Create photon momentum direction vector. The momentum direction is still
335 // with respect to the coordinate system where the primary particle
336 // direction is aligned with the z axis
337 rand = G4UniformRand();
338 G4double phi = twopi * rand;
339 G4double sinPhi = std::sin(phi);
340 G4double cosPhi = std::cos(phi);
341 G4double sinTheta = std::sqrt(sin2Theta);
342 G4ParticleMomentum photonMomentum(sinTheta * cosPhi, sinTheta * sinPhi,
343 cosTheta);
344
345 // Rotate momentum direction back to global reference system
346 photonMomentum.rotateUz(p0);
347
348 // Determine polarization of new photon
349 G4ThreeVector photonPolarization(cosTheta * cosPhi, cosTheta * sinPhi,
350 -sinTheta);
351
352 // Rotate back to original coord system
353 photonPolarization.rotateUz(p0);
354
355 // Generate a new photon:
356 auto aCerenkovPhoton =
357 new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(), photonMomentum);
358
359 aCerenkovPhoton->SetPolarization(photonPolarization);
360 aCerenkovPhoton->SetKineticEnergy(sampledEnergy);
361
362 G4double NumberOfPhotons;
363
364 do
365 {
366 rand = G4UniformRand();
367 NumberOfPhotons = MeanNumberOfPhotons1 - rand * deltaNumberOfPhotons;
368 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
369 } while(G4UniformRand() * maxNumberOfPhotons > NumberOfPhotons);
370
371 G4double delta = rand * aStep.GetStepLength();
372 G4double deltaTime =
373 delta / (pPreStepPoint->GetVelocity() + rand * deltaVelocity * 0.5);
374
375 G4double aSecondaryTime = t0 + deltaTime;
376 G4ThreeVector aSecondaryPosition = x0 + rand * aStep.GetDeltaPosition();
377
378 // Generate new G4Track object:
379 G4Track* aSecondaryTrack =
380 new G4Track(aCerenkovPhoton, aSecondaryTime, aSecondaryPosition);
381
382 aSecondaryTrack->SetTouchableHandle(touchableHandle);
383 aSecondaryTrack->SetParentID(aTrack.GetTrackID());
384 aSecondaryTrack->SetCreatorModelID(secID);
385 aParticleChange.AddSecondary(aSecondaryTrack);
386 }
387
388 if(verboseLevel > 1)
389 {
390 G4cout << "\n Exiting from G4QuasiCerenkov::DoIt -- NumberOfSecondaries = "
391 << aParticleChange.GetNumberOfSecondaries() << G4endl;
392 }
393
394 return pParticleChange;
395}
G4ThreeVector G4ParticleMomentum
G4long G4Poisson(G4double mean)
Definition G4Poisson.hh:50
CLHEP::Hep3Vector G4ThreeVector
@ fSuspend
@ fAlive
int G4int
Definition G4Types.hh:85
#define G4UniformRand()
Definition Randomize.hh:52
Hep3Vector unit() const
G4ParticleDefinition * GetDefinition() const
G4ThreeVector GetMomentum() const
static G4OpticalPhoton * OpticalPhoton()
G4double GetAverageNumberOfPhotons(const G4double charge, const G4double beta, const G4Material *aMaterial, G4MaterialPropertyVector *Rindex) const
static G4QuasiOpticalPhoton * QuasiOpticalPhotonDefinition()
G4double GetVelocity() const
G4double GetBeta() const
G4double GetGlobalTime() const
const G4ThreeVector & GetPosition() const
const G4TouchableHandle & GetTouchableHandle() const
G4ThreeVector GetDeltaPosition() const
G4StepPoint * GetPreStepPoint() const
G4double GetStepLength() const
G4StepPoint * GetPostStepPoint() const
G4TrackStatus GetTrackStatus() const
G4int GetTrackID() const
void SetAuxiliaryTrackInformation(G4int id, G4VAuxiliaryTrackInformation *info) const
Definition G4Track.cc:215
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
void SetCreatorModelID(const G4int id)
void SetParentID(const G4int aValue)
G4ParticleChange aParticleChange
G4VParticleChange * pParticleChange

◆ PostStepGetPhysicalInteractionLength()

G4double G4QuasiCerenkov::PostStepGetPhysicalInteractionLength ( const G4Track & aTrack,
G4double ,
G4ForceCondition * condition )
overridevirtual

Implements G4VProcess.

Definition at line 411 of file G4QuasiCerenkov.cc.

413{
415 G4double StepLimit = DBL_MAX;
416 fNumPhotons = 0;
417
418 const G4Material* aMaterial = aTrack.GetMaterial();
419 std::size_t materialIndex = aMaterial->GetIndex();
420
421 // If Physics Vector is not defined no Cerenkov photons
422 const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
423 G4MaterialPropertiesTable* MPT =
424 ((*materialTable)[materialIndex])->GetMaterialPropertiesTable();
425 // if(!(*thePhysicsTable)[materialIndex])
426 if(!MPT)
427 {
428 return StepLimit;
429 }
430
431 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
432 const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
433
434 G4double kineticEnergy = aParticle->GetKineticEnergy();
435 const G4ParticleDefinition* particleType = aParticle->GetDefinition();
436 G4double mass = particleType->GetPDGMass();
437
438 G4double beta = aParticle->GetTotalMomentum() / aParticle->GetTotalEnergy();
439 G4double gamma = aParticle->GetTotalEnergy() / mass;
440
441 G4MaterialPropertiesTable* aMaterialPropertiesTable =
442 aMaterial->GetMaterialPropertiesTable();
443
444 G4MaterialPropertyVector* Rindex = nullptr;
445
446 if(aMaterialPropertiesTable)
447 Rindex = aMaterialPropertiesTable->GetProperty(kRINDEX);
448
449 G4double nMax;
450 if(Rindex)
451 {
452 nMax = Rindex->GetMaxValue();
453 }
454 else
455 {
456 return StepLimit;
457 }
458
459 G4double BetaMin = 1. / nMax;
460 if(BetaMin >= 1.)
461 return StepLimit;
462
463 G4double GammaMin = 1. / std::sqrt(1. - BetaMin * BetaMin);
464 if(gamma < GammaMin)
465 return StepLimit;
466
467 G4double kinEmin = mass * (GammaMin - 1.);
468 G4double RangeMin =
469 G4LossTableManager::Instance()->GetRange(particleType, kinEmin, couple);
471 particleType, kineticEnergy, couple);
472 G4double Step = Range - RangeMin;
473
474 // If the step is smaller than G4ThreeVector::getTolerance(), it may happen
475 // that the particle does not move. See bug 1992.
476 static const G4double minAllowedStep = G4ThreeVector::getTolerance();
477 if(Step < minAllowedStep)
478 return StepLimit;
479
480 if(Step < StepLimit)
481 StepLimit = Step;
482
483 // If user has defined an average maximum number of photons to be generated in
484 // a Step, then calculate the Step length for that number of photons.
485 if(fMaxPhotons > 0)
486 {
487 const G4double charge = aParticle->GetDefinition()->GetPDGCharge();
488 G4double MeanNumberOfPhotons =
489 GetAverageNumberOfPhotons(charge, beta, aMaterial, Rindex);
490 Step = 0.;
491 if(MeanNumberOfPhotons > 0.0)
492 Step = fMaxPhotons / MeanNumberOfPhotons;
493 if(Step > 0. && Step < StepLimit)
494 StepLimit = Step;
495 }
496
497 // If user has defined an maximum allowed change in beta per step
498 if(fMaxBetaChange > 0.)
499 {
501 particleType, kineticEnergy, couple);
502 G4double deltaGamma =
503 gamma - 1. / std::sqrt(1. - beta * beta * (1. - fMaxBetaChange) *
504 (1. - fMaxBetaChange));
505
506 Step = mass * deltaGamma / dedx;
507 if(Step > 0. && Step < StepLimit)
508 StepLimit = Step;
509 }
510
512 return StepLimit;
513}
G4double condition(const G4ErrorSymMatrix &m)
@ StronglyForced
@ NotForced
static double getTolerance()
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4double GetTotalMomentum() const
static G4LossTableManager * Instance()
G4double GetRange(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
#define DBL_MAX
Definition templates.hh:62

◆ PreparePhysicsTable()

void G4QuasiCerenkov::PreparePhysicsTable ( const G4ParticleDefinition & part)
overridevirtual

Reimplemented from G4VProcess.

Definition at line 398 of file G4QuasiCerenkov.cc.

399{
400 Initialise();
401}

◆ ProcessDescription()

void G4QuasiCerenkov::ProcessDescription ( std::ostream & out) const
overridevirtual

Reimplemented from G4VProcess.

Definition at line 75 of file G4QuasiCerenkov.cc.

76{
77 out << "The Cerenkov effect simulates optical photons created by the\n";
78 out << "passage of charged particles through matter. Materials need\n";
79 out << "to have the property RINDEX (refractive index) defined.\n";
81
82 G4OpticalParameters* params = G4OpticalParameters::Instance();
83 out << "Maximum beta change per step: " << params->GetCerenkovMaxBetaChange();
84 out << "Maximum photons per step: " << params->GetCerenkovMaxPhotonsPerStep();
85 out << "Track secondaries first: "
87 out << "Stack photons: " << params->GetCerenkovStackPhotons();
88 out << "Verbose level: " << params->GetCerenkovVerboseLevel();
89}
virtual void DumpInfo() const

Referenced by DumpInfo().

◆ SetMaxBetaChangePerStep()

void G4QuasiCerenkov::SetMaxBetaChangePerStep ( const G4double d)

Definition at line 613 of file G4QuasiCerenkov.cc.

614{
615 fMaxBetaChange = value * CLHEP::perCent;
617}
void SetCerenkovMaxBetaChange(G4double)

Referenced by Initialise().

◆ SetMaxNumPhotonsPerStep()

void G4QuasiCerenkov::SetMaxNumPhotonsPerStep ( const G4int NumPhotons)

Definition at line 620 of file G4QuasiCerenkov.cc.

621{
622 fMaxPhotons = NumPhotons;
624}
void SetCerenkovMaxPhotonsPerStep(G4int)

Referenced by Initialise().

◆ SetOffloadPhotons()

void G4QuasiCerenkov::SetOffloadPhotons ( const G4bool offloadingFlag)

Definition at line 632 of file G4QuasiCerenkov.cc.

633{
634 fOffloadingFlag = offloadingFlag;
636}
void SetCerenkovOffloadPhotons(G4bool)

Referenced by Initialise().

◆ SetStackPhotons()

void G4QuasiCerenkov::SetStackPhotons ( const G4bool stackingFlag)

Definition at line 626 of file G4QuasiCerenkov.cc.

627{
628 fStackingFlag = stackingFlag;
630}
void SetCerenkovStackPhotons(G4bool)

Referenced by Initialise().

◆ SetTrackSecondariesFirst()

void G4QuasiCerenkov::SetTrackSecondariesFirst ( const G4bool state)

Definition at line 605 of file G4QuasiCerenkov.cc.

606{
607 fTrackSecondariesFirst = state;
609 fTrackSecondariesFirst);
610}
void SetCerenkovTrackSecondariesFirst(G4bool)

Referenced by Initialise().

◆ SetVerboseLevel()

void G4QuasiCerenkov::SetVerboseLevel ( G4int verbose)

Definition at line 649 of file G4QuasiCerenkov.cc.

Referenced by Initialise().

Member Data Documentation

◆ fIndexMPT

std::map<std::size_t, std::size_t> G4QuasiCerenkov::fIndexMPT
protected

Definition at line 184 of file G4QuasiCerenkov.hh.

Referenced by BuildPhysicsTable(), and GetAverageNumberOfPhotons().

◆ thePhysicsTable

G4PhysicsTable* G4QuasiCerenkov::thePhysicsTable
protected

The documentation for this class was generated from the following files: