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

#include <G4StandardCerenkovModel.hh>

Inheritance diagram for G4StandardCerenkovModel:

Public Member Functions

 G4StandardCerenkovModel ()
 G4StandardCerenkovModel (const G4StandardCerenkovModel &)=default
 ~G4StandardCerenkovModel () override
G4StandardCerenkovModeloperator= (const G4StandardCerenkovModel &right)=delete
G4StandardCerenkovModeloperator== (const G4StandardCerenkovModel &right)=delete
G4StandardCerenkovModeloperator!= (const G4StandardCerenkovModel &right)=delete
void InitialiseModel () override
G4bool StepLimitForVolume (G4double &limit) override
void SampleXRays (std::vector< G4Track * > &out, const G4Step &) override
void ModelDescription (std::ostream &outFile) const override
Public Member Functions inherited from G4VXRayModel
 G4VXRayModel (const G4String &nam)
 G4VXRayModel (const G4VXRayModel &)
virtual ~G4VXRayModel ()
G4double Initialise (std::vector< const G4LogicalVolume * > *)
G4bool StepLimit (std::size_t idx, const G4Track &, G4double preStepBeta, G4double &limit)
const G4StringGetName () const
G4int GetType () const
G4VXRayModeloperator= (const G4VXRayModel &right)=delete

Additional Inherited Members

Protected Attributes inherited from G4VXRayModel
std::vector< const G4LogicalVolume * > * pLogicalVolumes {nullptr}
G4LossTableManagerpEmManager {nullptr}
const G4LogicalVolumepCurrentLV {nullptr}
const G4TrackpCurrentTrack {nullptr}
G4double pBetaMin {1.0}
G4double pPreStepBeta {0.0}
G4double pMaxBetaChange {0.1}
G4int pMaxPhotons {100}
std::size_t pIndex {0}
std::size_t nVolumes {0}
G4int pTypeInt {0}
G4int pVerbose {1}
G4bool isMaster {false}
const G4String pName

Detailed Description

Definition at line 53 of file G4StandardCerenkovModel.hh.

Constructor & Destructor Documentation

◆ G4StandardCerenkovModel() [1/2]

G4StandardCerenkovModel::G4StandardCerenkovModel ( )

Definition at line 63 of file G4StandardCerenkovModel.cc.

64 : G4VXRayModel("theCerenkov")
65{
66 if (nullptr == fBetaLim) {
67 isInitializer = true;
68 fBetaLim = new std::vector<G4double>;
69 fMeanNumberOfPhotons = new std::vector<std::vector<G4double>* >;
70 fIntegral = new std::vector<std::vector<std::vector<G4double>* >* >;
71 fRindex = new std::vector<G4MaterialPropertyVector*>;
72 }
74 fRfact = 369.81 / (CLHEP::eV * CLHEP::cm); // number of photons per mm
75}
static G4OpticalPhoton * OpticalPhoton()
G4VXRayModel(const G4String &nam)

Referenced by G4StandardCerenkovModel(), operator!=(), operator=(), and operator==().

◆ G4StandardCerenkovModel() [2/2]

G4StandardCerenkovModel::G4StandardCerenkovModel ( const G4StandardCerenkovModel & )
default

◆ ~G4StandardCerenkovModel()

G4StandardCerenkovModel::~G4StandardCerenkovModel ( )
override

Definition at line 78 of file G4StandardCerenkovModel.cc.

79{
80 if (isInitializer && isInitialized) {
81 delete fBetaLim;
82 for (auto const & ptr : *fRindex) {
83 delete ptr;
84 }
85 delete fRindex;
86 for (auto const & ptr : *fMeanNumberOfPhotons) {
87 delete ptr;
88 }
89 delete fMeanNumberOfPhotons;
90 for (auto const & ptr : *fIntegral) {
91 for (auto const & p : *ptr) {
92 delete p;
93 }
94 delete ptr;
95 }
96 delete fIntegral;
97 fIntegral = nullptr;
98 fBetaLim = nullptr;
99 fRindex = nullptr;
100 fMeanNumberOfPhotons = nullptr;
101 }
102}

Member Function Documentation

◆ InitialiseModel()

void G4StandardCerenkovModel::InitialiseModel ( )
overridevirtual

Reimplemented from G4VXRayModel.

Definition at line 105 of file G4StandardCerenkovModel.cc.

106{
107 G4double beta = 1.0;
108 if (0 == nVolumes) { return; }
109 if (isInitializer && !isInitialized) {
110 isInitialized = true;
111 fBetaLim->resize(nVolumes, 1.0);
112 fRindex->resize(nVolumes, nullptr);
113 fMeanNumberOfPhotons->resize(nVolumes, new std::vector<G4double>(nvec, 0.0));
114 fIntegral->resize(nVolumes, nullptr);
115
116 for (std::size_t i = 0; i < nVolumes; ++i) {
117 auto mat = ((*pLogicalVolumes)[i])->GetMaterial();
118 auto MPT = mat->GetMaterialPropertiesTable();
119
120 if (nullptr == MPT) { continue; }
121 G4MaterialPropertyVector* rindex = MPT->GetProperty(kRINDEX);
122 if (nullptr == rindex) { continue; }
123 (*fRindex)[i] = rindex;
124
125 G4double nMax = rindex->GetMaxValue();
126 if (nMax <= 1.0) { continue; }
127 G4double b = 1.0/nMax;
128 (*fBetaLim)[i] = b;
129 beta = std::min(beta, b);
130 G4double dbeta = (1.0 - b)/(G4double)(nvec - 1);
131 G4double b0 = b;
132 std::size_t nn = rindex->GetVectorLength();
133 if (0 == nn) { continue; }
134
135 auto iptr = new std::vector<std::vector<G4double>* >((std::size_t)nvec, nullptr);
136 (*fIntegral)[i] = iptr;
137 for (auto & ptr : *iptr) {
138 ptr = new std::vector<G4double>(nn, 0.0);
139 }
140
141 // Initialisation for charge = 1.0
142 G4double y0 = AverageNumberOfPhotons(1.0, b0, (*rindex)[0]);
143 (*(*fMeanNumberOfPhotons)[i])[0] = y0;
144 if (1 == nn) { continue; }
145
146 // Initialisation for charge = 1.0
147 for (G4int k = 0; k < nvec; ++k) {
148 (*((*fIntegral)[i]))[k]->resize(nn, 0.0);
149 G4double sum = 0.0;
150 G4double e0 = rindex->GetMinEnergy();
151 G4double deltae = rindex->GetMaxEnergy() - e0;
152 for (std::size_t j = 1; j < nn; ++j) {
153 G4double e = rindex->Energy(j);
154 G4double y = AverageNumberOfPhotons(1.0, beta, (*rindex)[j]);
155 sum += 0.5*(y - y0)*(e - e0);
156 y0 = y;
157 e0 = e;
158 (*(*((*fIntegral)[i]))[k])[j] = sum;
159 }
160 if (deltae > 0.0) { (*(*fMeanNumberOfPhotons)[i])[k] = sum/deltae; }
161 if (sum > 0.0) { sum = 1.0/sum; }
162 for (std::size_t j = 1; j < nn; ++j) {
163 G4double y = (*(*((*fIntegral)[i]))[k])[j]/sum;
164 (*(*((*fIntegral)[i]))[k])[j] = y;
165 }
166 beta += dbeta;
167 beta = std::min(beta, 1.0);
168 }
169 }
170 } else {
171 for (std::size_t i = 0; i < nVolumes; ++i) {
172 beta = std::min(beta, (*fBetaLim)[i]);
173 }
174 }
175 pBetaMin = beta;
176}
G4PhysicsFreeVector G4MaterialPropertyVector
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
G4double GetMaxEnergy() const
G4double GetMaxValue() const
G4double Energy(const std::size_t index) const
G4double GetMinEnergy() const
std::size_t GetVectorLength() const
G4double pBetaMin
std::size_t nVolumes

◆ ModelDescription()

void G4StandardCerenkovModel::ModelDescription ( std::ostream & outFile) const
overridevirtual

Reimplemented from G4VXRayModel.

Definition at line 304 of file G4StandardCerenkovModel.cc.

305{
306 out << "The Cerenkov effect simulates optical photons created by the\n";
307 out << "passage of charged particles through matter. Materials need\n";
308 out << "to have the property RINDEX (refractive index) defined." << G4endl;
309}
#define G4endl
Definition G4ios.hh:67

◆ operator!=()

G4StandardCerenkovModel & G4StandardCerenkovModel::operator!= ( const G4StandardCerenkovModel & right)
delete

◆ operator=()

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

◆ operator==()

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

◆ SampleXRays()

void G4StandardCerenkovModel::SampleXRays ( std::vector< G4Track * > & out,
const G4Step & step )
overridevirtual

Reimplemented from G4VXRayModel.

Definition at line 211 of file G4StandardCerenkovModel.cc.

213{
214 auto const preStep = step.GetPreStepPoint();
215 auto const postStep = step.GetPostStepPoint();
216 G4double kinE = postStep->GetKineticEnergy();
217 G4double beta = pPreStepBeta;
218 G4double b = (*fBetaLim)[pIndex];
219 G4double dbeta = (1.0 - b)/(G4double)(nvec - 1);
220 G4int idx = std::max(G4int((beta - b)/dbeta), 0);
221 idx = std::min(idx, nvec - 1);
222 std::vector<G4double>* v = (*((*fIntegral)[pIndex]))[idx];
223
224 G4ThreeVector pos = preStep->GetPosition();
225 G4ThreeVector dpos = postStep->GetPosition() - pos;
226 G4ThreeVector dir = dpos.unit();
227 G4double time = preStep->GetGlobalTime();
228 G4double dt = postStep->GetGlobalTime() - time;
229 G4double de = fPreStepKinE - kinE;
230
231 // define sub-steps inside the current step
232 G4double x = (1.0 + fPreStepKinE/fMass);
233 G4double delim = fMass*pMaxBetaChange*x*x*x;
234 G4int nn = (G4int)(de/delim) + 1;
235 x = 1.0/(G4double)nn;
236 dpos *= x;
237 dt *= x;
238 de *= x;
239 G4double delta = dpos.mag();
240 fMeanNPhotons *= x;
241
242 // produce Cerenkov gamma - loop over sub-steps
243 G4double ekin = fPreStepKinE;
244 auto const rindex = (*fRindex)[pIndex];
245 std::size_t ni = rindex->GetVectorLength();
246 if (0 == ni) { return; }
247 G4double emin = rindex->Energy(0);
248 G4double mean = delta*fCharge*fCharge*(*(*fMeanNumberOfPhotons)[pIndex])[idx];
249
250 for (G4int i=0; i<nn; ++i) {
251 G4int ngamma = (G4int)G4Poisson(mean);
252 for (G4int j = 0; j < ngamma; ++j) {
254 G4double e = emin;
255 G4double n = (*rindex)[0];
256 if (ni > 1) {
257 for (std::size_t k = 1; k < ni; ++k) {
258 if ((*v)[k] <= q) {
259 e = rindex->Energy(k - 1);
260 e += (rindex->Energy(k) - e)*(q - (*v)[k - 1])/((*v)[k] - (*v)[k - 1]);
261 n = (*rindex)[k - 1];
262 n += ((*rindex)[k] - n)*(q - (*v)[k - 1])/((*v)[k] - (*v)[k - 1]);
263 }
264 }
265 }
266 q = G4UniformRand();
267 G4double t = time + q*dt;
268 G4ThreeVector posnew = pos + q*dpos;
269 G4double minCos = 1.0/(n*beta);
270 G4double maxSin2 = (1.0 - minCos)*(1.0 + minCos);
271 G4double cost, sint2;
272 do {
273 cost = 1.0 - G4UniformRand()*(1.0 - minCos);
274 sint2 = (1.0 - cost)*(1.0 + cost);
275 q = G4UniformRand();
276 } while(q * maxSin2 > sint2);
277
278 G4double sint = std::sqrt(sint2);
279 G4double phi = G4UniformRand()*CLHEP::twopi;
280 G4double cosPhi = std::cos(phi);
281 G4double sinPhi = std::sin(phi);
282 G4ThreeVector dirnew(sint*cosPhi, sint*sinPhi, cost);
283 dirnew.rotateUz(dir);
284
285 // Determine polarization of new photon
286 G4ThreeVector photonPolarization(cost*cosPhi, cost*sinPhi, -sint);
287
288 // Rotate back to original coord system
289 photonPolarization.rotateUz(dir);
290
291 auto dp = new G4DynamicParticle(fPhoton, dirnew, e);
292 dp->SetPolarization(photonPolarization);
293 auto track = new G4Track(dp, t, posnew);
294 out.push_back(track);
295 }
296 pos += dpos;
297 time += dt;
298 ekin -= de;
299 beta = std::sqrt(ekin * (ekin + 2*fMass))/(fMass + ekin);
300 }
301}
G4long G4Poisson(G4double mean)
Definition G4Poisson.hh:50
CLHEP::Hep3Vector G4ThreeVector
#define G4UniformRand()
Definition Randomize.hh:52
Hep3Vector unit() const
double mag() const
G4double GetKineticEnergy() const
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
G4double pMaxBetaChange
std::size_t pIndex
G4double pPreStepBeta

◆ StepLimitForVolume()

G4bool G4StandardCerenkovModel::StepLimitForVolume ( G4double & limit)
overridevirtual

Reimplemented from G4VXRayModel.

Definition at line 179 of file G4StandardCerenkovModel.cc.

180{
181 G4double betaMin = (*fBetaLim)[pIndex];
182 if (pPreStepBeta <= betaMin) { return false; }
183
184 // step limitation
185 betaMin = std::max(betaMin, pPreStepBeta*pMaxBetaChange);
186
187 auto const dynPart = pCurrentTrack->GetDynamicParticle();
188 fParticle = dynPart->GetDefinition();
189 fPreStepKinE = dynPart->GetKineticEnergy();
190 fCharge = fParticle->GetPDGCharge()/CLHEP::eplus;
191 fMass = fParticle->GetPDGMass();
192 G4double x = limit;
193
194 // If the step is smaller than G4ThreeVector::getTolerance(), it may happen
195 // that the particle does not move. See bug 1992.
196 if (x < minAllowedStep) { return false; }
197
198 // If user has defined an average maximum number of photons to be generated in
199 // a Step, then calculate the Step length for that number of photons using preStep beta.
200 G4double nmax = (*fRindex)[pIndex]->GetMaxValue();
201 fMeanNPhotons = x * AverageNumberOfPhotons(fCharge, pPreStepBeta, nmax);
202 if (pMaxPhotons < fMeanNPhotons) {
203 x *= pMaxPhotons/fMeanNPhotons;
204 x = std::max(x, minAllowedStep);
205 }
206 limit = x;
207 return true;
208}
const G4Track * pCurrentTrack

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