Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4OpWLS.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28////////////////////////////////////////////////////////////////////////
29// Optical Photon WaveLength Shifting (WLS) Class Implementation
30////////////////////////////////////////////////////////////////////////
31//
32// File: G4OpWLS.cc
33// Description: Discrete Process -- Wavelength Shifting of Optical Photons
34// Version: 1.0
35// Created: 2003-05-13
36// Author: John Paul Archambault
37// (Adaptation of G4Scintillation and G4OpAbsorption)
38// Updated: 2005-07-28 - add G4ProcessType to constructor
39// 2006-05-07 - add G4VWLSTimeGeneratorProfile
40//
41////////////////////////////////////////////////////////////////////////
42
43#include "G4OpWLS.hh"
44#include "G4ios.hh"
46#include "G4SystemOfUnits.hh"
47#include "G4OpProcessSubType.hh"
48#include "G4Poisson.hh"
52
53//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
54G4OpWLS::G4OpWLS(const G4String& processName, G4ProcessType type)
55 : G4VDiscreteProcess(processName, type)
56{
58 Initialise();
60 theIntegralTable = nullptr;
61
62 if(verboseLevel > 0)
63 G4cout << GetProcessName() << " is created " << G4endl;
64}
65
66//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
68{
70 {
71 theIntegralTable->clearAndDestroy();
72 delete theIntegralTable;
73 }
75}
76
77//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
79
80//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
87
88//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90 const G4Step& aStep)
91{
92 aParticleChange.Initialize(aTrack);
93 aParticleChange.ProposeTrackStatus(fStopAndKill);
94
95 if(verboseLevel > 1)
96 {
97 G4cout << "\n** G4OpWLS: Photon absorbed! **" << G4endl;
98 }
99
102 if(!MPT)
103 {
104 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
105 }
106
107 G4PhysicsFreeVector* WLSIntegral = nullptr;
108 if(!MPT->GetProperty(kWLSCOMPONENT))
109 {
110 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
111 }
112 else
113 {
114 // Retrieve the WLS Integral for this material
115 WLSIntegral = (G4PhysicsFreeVector*) ((*theIntegralTable)
116 (aTrack.GetMaterial()->GetIndex()));
117 }
118
119 G4double primaryEnergy = aTrack.GetDynamicParticle()->GetKineticEnergy();
120 // No WLS photons are produced if the primary photon's energy is below
121 // the lower bound of the WLS integral range
122 if(primaryEnergy < WLSIntegral->GetMinValue())
123 {
124 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
125 }
126
127 G4int NumPhotons = 1;
129 {
130 G4double MeanNumberOfPhotons = MPT->GetConstProperty(kWLSMEANNUMBERPHOTONS);
131 NumPhotons = G4int(G4Poisson(MeanNumberOfPhotons));
132 if(NumPhotons <= 0)
133 {
134 // return unchanged particle and no secondaries
135 aParticleChange.SetNumberOfSecondaries(0);
136 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
137 }
138 }
139
141 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
142 std::vector<G4Track*> proposedSecondaries;
143
144 // Max WLS Integral - force sampling of a WLS photon with energy below
145 // the primary photon's energy
146 G4double CIImax = (primaryEnergy > WLSIntegral->GetMaxEnergy()) ?
147 WLSIntegral->GetMaxValue() : WLSIntegral->Value(primaryEnergy);
148
149 for(G4int i = 0; i < NumPhotons; ++i)
150 {
151 // Determine photon energy
152 G4double sampledEnergy = WLSIntegral->GetEnergy(G4UniformRand() * CIImax);
153
154 // Make sure the energy of the secondary is less than that of the primary
155 if(sampledEnergy > primaryEnergy)
156 {
158 ed << "Sampled photon energy " << sampledEnergy << " is greater than "
159 << "the primary photon energy " << primaryEnergy << G4endl;
160 G4Exception("G4OpWLS::PostStepDoIt", "WSL01", FatalException, ed);
161 }
162 else if(verboseLevel > 1)
163 {
164 G4cout << "G4OpWLS: Created photon with energy: " << sampledEnergy
165 << G4endl;
166 }
167
168 // Generate random photon direction
169 G4double cost = 1. - 2. * G4UniformRand();
170 G4double sint = std::sqrt((1. - cost) * (1. + cost));
171 G4double phi = twopi * G4UniformRand();
172 G4double sinp = std::sin(phi);
173 G4double cosp = std::cos(phi);
174 G4ParticleMomentum photonMomentum(sint * cosp, sint * sinp, cost);
175
176 G4ThreeVector photonPolarization(cost * cosp, cost * sinp, -sint);
177 G4ThreeVector perp = photonMomentum.cross(photonPolarization);
178
179 phi = twopi * G4UniformRand();
180 sinp = std::sin(phi);
181 cosp = std::cos(phi);
182 photonPolarization = (cosp * photonPolarization + sinp * perp).unit();
183
184 // Generate a new photon:
185 auto sec_dp =
187 sec_dp->SetPolarization(photonPolarization);
188 sec_dp->SetKineticEnergy(sampledEnergy);
189
190 G4double secTime = pPostStepPoint->GetGlobalTime() +
191 WLSTimeGeneratorProfile->GenerateTime(WLSTime);
192 G4ThreeVector secPos = pPostStepPoint->GetPosition();
193 G4Track* secTrack = new G4Track(sec_dp, secTime, secPos);
194
195 secTrack->SetTouchableHandle(aTrack.GetTouchableHandle());
196 secTrack->SetParentID(aTrack.GetTrackID());
197
198 proposedSecondaries.push_back(secTrack);
199 }
200
201 aParticleChange.SetNumberOfSecondaries((G4int)proposedSecondaries.size());
202 for(auto sec : proposedSecondaries)
203 {
204 aParticleChange.AddSecondary(sec);
205 }
206 if(verboseLevel > 1)
207 {
208 G4cout << "\n Exiting from G4OpWLS::DoIt -- NumberOfSecondaries = "
209 << aParticleChange.GetNumberOfSecondaries() << G4endl;
210 }
211
212 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
213}
214
215//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
217{
219 {
220 theIntegralTable->clearAndDestroy();
221 delete theIntegralTable;
222 theIntegralTable = nullptr;
223 }
224
225 const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
226 std::size_t numOfMaterials = G4Material::GetNumberOfMaterials();
227 theIntegralTable = new G4PhysicsTable(numOfMaterials);
228
229 // loop for materials
230 for(std::size_t i = 0; i < numOfMaterials; ++i)
231 {
232 auto physVector = new G4PhysicsFreeVector();
233
234 // Retrieve vector of WLS wavelength intensity for
235 // the material from the material's optical properties table.
237 (*materialTable)[i]->GetMaterialPropertiesTable();
238 if(MPT)
239 {
241 if(wlsVector)
242 {
243 // Retrieve the first intensity point in vector
244 // of (photon energy, intensity) pairs
245 G4double currentIN = (*wlsVector)[0];
246 if(currentIN >= 0.0)
247 {
248 // Create first (photon energy)
249 G4double currentPM = wlsVector->Energy(0);
250 G4double currentCII = 0.0;
251 physVector->InsertValues(currentPM, currentCII);
252
253 // Set previous values to current ones prior to loop
254 G4double prevPM = currentPM;
255 G4double prevCII = currentCII;
256 G4double prevIN = currentIN;
257
258 // loop over all (photon energy, intensity)
259 // pairs stored for this material
260 for(std::size_t j = 1; j < wlsVector->GetVectorLength(); ++j)
261 {
262 currentPM = wlsVector->Energy(j);
263 currentIN = (*wlsVector)[j];
264 currentCII =
265 prevCII + 0.5 * (currentPM - prevPM) * (prevIN + currentIN);
266
267 physVector->InsertValues(currentPM, currentCII);
268
269 prevPM = currentPM;
270 prevCII = currentCII;
271 prevIN = currentIN;
272 }
273 }
274 }
275 }
276 theIntegralTable->insertAt(i, physVector);
277 }
278}
279
280//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
283{
284 G4double thePhotonEnergy = aTrack.GetDynamicParticle()->GetTotalEnergy();
285 G4double attLength = DBL_MAX;
288
289 if(MPT)
290 {
292 if(attVector)
293 {
294 attLength = attVector->Value(thePhotonEnergy, idx_wls);
295 }
296 }
297 return attLength;
298}
299
300//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
302{
304 {
306 WLSTimeGeneratorProfile = nullptr;
307 }
308 if(name == "delta")
309 {
311 }
312 else if(name == "exponential")
313 {
315 new G4WLSTimeGeneratorProfileExponential("exponential");
316 }
317 else
318 {
319 G4Exception("G4OpWLS::UseTimeProfile", "em0202", FatalException,
320 "generator does not exist");
321 }
323}
324
325//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ForceCondition
G4PhysicsFreeVector G4MaterialPropertyVector
std::vector< G4Material * > G4MaterialTable
G4ThreeVector G4ParticleMomentum
G4long G4Poisson(G4double mean)
Definition G4Poisson.hh:50
G4ProcessType
CLHEP::Hep3Vector G4ThreeVector
@ fStopAndKill
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
Hep3Vector cross(const Hep3Vector &) const
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
G4bool ConstPropertyExists(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
G4MaterialPropertyVector * GetProperty(const char *key) const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
static std::size_t GetNumberOfMaterials()
std::size_t GetIndex() const
static G4MaterialTable * GetMaterialTable()
virtual void BuildPhysicsTable(const G4ParticleDefinition &aParticleType) override
Definition G4OpWLS.cc:216
virtual void Initialise()
Definition G4OpWLS.cc:81
void SetVerboseLevel(G4int)
Definition G4OpWLS.cc:326
virtual G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *) override
Definition G4OpWLS.cc:281
G4PhysicsTable * theIntegralTable
Definition G4OpWLS.hh:91
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
Definition G4OpWLS.cc:89
virtual ~G4OpWLS()
Definition G4OpWLS.cc:67
G4VWLSTimeGeneratorProfile * WLSTimeGeneratorProfile
Definition G4OpWLS.hh:90
G4OpWLS(const G4String &processName="OpWLS", G4ProcessType type=fOptical)
Definition G4OpWLS.cc:54
virtual void UseTimeProfile(const G4String name)
Definition G4OpWLS.cc:301
virtual void PreparePhysicsTable(const G4ParticleDefinition &) override
Definition G4OpWLS.cc:78
static G4OpticalParameters * Instance()
G4String GetWLSTimeProfile() const
void SetWLSTimeProfile(const G4String &)
static G4OpticalPhoton * OpticalPhoton()
G4double GetEnergy(const G4double value) const
G4double GetMaxEnergy() const
G4double GetMaxValue() const
G4double Energy(const std::size_t index) const
G4double Value(const G4double energy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
G4double GetGlobalTime() const
const G4ThreeVector & GetPosition() const
G4StepPoint * GetPostStepPoint() const
G4int GetTrackID() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
void SetParentID(const G4int aValue)
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4VDiscreteProcess(const G4String &aName, G4ProcessType aType=fNotDefined)
G4ParticleChange aParticleChange
G4int verboseLevel
void SetProcessSubType(G4int)
const G4String & GetProcessName() const
#define DBL_MAX
Definition templates.hh:62