Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GeneralCerenkov.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// G4GeneralCerenkov
28//
29// Created 25.05.2025 V.Ivanchenko
30//
31// --------------------------------------------------------------------
32
33#include "G4GeneralCerenkov.hh"
35
36#include "G4Material.hh"
40#include "G4EmProcessSubType.hh"
42
43std::vector<std::vector<const G4LogicalVolume*>* >* G4GeneralCerenkov::fLV = nullptr;
44std::vector<G4VXRayModel*>* G4GeneralCerenkov::fSharedModels = nullptr;
45
46//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48 : G4VDiscreteProcess(nam, type)
49{
50 secID = G4PhysicsModelCatalog::GetModelID("model_Cerenkov");
52 if (nullptr == fLV) {
53 // initialise static data
54 fSharedModels = new std::vector<G4VXRayModel*>;
55 fLV = new std::vector<std::vector<const G4LogicalVolume*>* >;
56 fLVNames = new std::vector<G4String>;
57
58 isInitializer = true;
59 }
60}
61
62//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
64{
65 if (isInitializer) {
66 delete fSharedModels;
67 fSharedModels = nullptr;
68 delete fLVNames;
69 for (auto const & p : *fLV) {
70 delete p;
71 }
72 delete fLV;
73 fLV = nullptr;
74 }
75}
76
77//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
85 const G4String& nameLogVolume)
86{
87 if (isPrepared || !isInitializer || nullptr == model) {
89 G4String nam;
90 if (model != nullptr) { nam = model->GetName(); }
91 ed << " Attempt to add Cerenkov model <" << nam << "> for LogicalVolume "
92 << nameLogVolume << " is failed!\n isPrepared:" << isPrepared
93 << " isInitilizer:" << isInitializer;
94 G4Exception("G4GeneralCerenkov::AddModelForVolume", "em0304",
95 FatalException, ed, "");
96 return;
97 }
98 fSharedModels->push_back(model);
99 fLVNames->push_back(nameLogVolume);
100}
101
102//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
104{
105 // definition of models is done only once
106 if (isPrepared) { return; }
107 isPrepared = true;
108
110 fMaxBetaChange = params->GetCerenkovMaxBetaChange();
111 fMaxPhotons = params->GetCerenkovMaxPhotonsPerStep();
112 fStackingFlag = params->GetCerenkovStackPhotons();
113 fTrackSecondariesFirst = params->GetCerenkovTrackSecondariesFirst();
115
116 auto nmod = fSharedModels->size();
117 if (0 == nmod) {
118 // the default model is added without association with a logical volume
120 fSharedModels->push_back(mod);
121 nmod = 1;
122 }
123
124 fSecondaries.reserve(fMaxPhotons);
125 nModels = (G4int)nmod;
126
127 // fill static data structures
128 if (isInitializer) {
130 const auto & modAndVol = params->ActiveVolumes();
131
132 // preparation of logical volume vector per model
133 fLV->reserve(nmod);
134 for (G4int i=0; i<nModels; ++i) {
135 auto v = new std::vector<const G4LogicalVolume*>;
136 fLV->push_back(v);
137 }
138
139 for (auto const & lv : *lvs) {
140 // only volumes with material property defined are considered
141 auto const MPT = lv->GetMaterial()->GetMaterialPropertiesTable();
142 if (nullptr == MPT) { continue; }
143
144 const G4String& lvname = lv->GetName();
145 G4bool ok{false};
146 // search for the default model in the list
147 if (!modAndVol.empty()) {
148 for (auto const & it : modAndVol) {
149 if (it.second == lvname) {
150 if (kCerenkovDefault == it.first) {
151 (*fLV)[0]->push_back(lv);
152 fLVNames->push_back(lvname);
153 ok = true;
154 break;
155 }
156 }
157 }
158 }
159 if (ok) { continue; }
160
161 // search in external models
162 for (G4int i=0; i<nModels; ++i) {
163 if (lvname == (*fLVNames)[i]) {
164 (*fLV)[i]->push_back(lv);
165 ok = true;
166 break;
167 }
168 }
169 if (ok) { continue; }
170
171 // temporary for backward compatibility search for a RINDEX of the volume
172 if (nullptr != MPT->GetProperty(kRINDEX)) {
173 (*fLV)[0]->push_back(lv);
174 fLVNames->push_back(lvname);
175 }
176 }
177 }
178}
179
180//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
182{
183 // Initialisation of models is done only once
184 if (isBuilt) { return; }
185 isBuilt = true;
186 if (nModels == 0) { return; }
187
188 // worker thread
189 if (!isInitializer) {
190 // worker initialisation - clone master models
191 fModels.reserve(nModels);
192 for (G4int i=0; i<nModels; ++i) {
193 auto newmod = new G4VXRayModel(*((*fSharedModels)[i]));
194 fModels.push_back(newmod);
195 G4double b = newmod->Initialise((*fLV)[i]);
196 fBetaMin = std::min(fBetaMin, b);
197 }
198 } else if (verboseLevel > 0) {
199 // needed for printout
200 std::size_t nn = 0;
201 for (G4int i=0; i<nModels; ++i) {
202 G4double b = (*fSharedModels)[i]->Initialise((*fLV)[i]);
203 fBetaMin = std::min(fBetaMin, b);
204 nn += ((*fLV)[i])->size();
205 }
206 G4long pres = G4cout.precision();
207 G4cout.precision(6);
208 G4cout << " " << GetProcessName() << std::setw(20) << " fBetaMin=" << fBetaMin
209 << " fMaxBetaChange=" << fMaxBetaChange << G4endl;
210 G4cout << std::setw(20) << "fMaxNphot=" << fMaxPhotons
211 << " Nlv=" << nn << " fStackingFlag:" << fStackingFlag
212 << " fTrackSecondariesFirst:" << fTrackSecondariesFirst
213 << G4endl;
214 for (G4int i=0; i<nModels; ++i) {
215 G4int n = (G4int)((*fLV)[i]->size());
216 G4cout << std::setw(10) << (*fSharedModels)[i]->GetName()
217 << std::setw(30) << "Nvolumes=" << n << " Volumes:" << G4endl;
218 G4cout << std::setw(12);
219 for (G4int j=0; j<n; ++j) {
220 G4cout << (*((*fLV)[i]))[j]->GetName() << " ";
221 if (0 != j && (j/5)*5 == j) {
222 G4cout << G4endl << std::setw(12);
223 }
224 }
225 G4cout << G4endl;
226 }
227 G4cout.precision(pres);
228 }
229}
230
231//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
234 G4double,
235 G4ForceCondition* cond)
236{
237 *cond = NotForced;
238 G4double limit = DBL_MAX;
239 auto const dp = aTrack.GetDynamicParticle();
240 if (dp->GetCharge() == 0.0) { return limit; }
241 fCurrentModel = nullptr;
242 fPreStepBeta = dp->GetBeta();
243 if (fPreStepBeta <= fBetaMin) { return limit; }
244
245 auto volume = aTrack.GetVolume();
246 if (nullptr == volume) { return limit; }
247
248 fCurrentLV = volume->GetLogicalVolume();
249 auto const MPT = fCurrentLV->GetMaterial()->GetMaterialPropertiesTable();
250 if (nullptr == MPT) { return limit; }
251
252 G4bool ok{false};
253 for (G4int i=0; i<nModels; ++i) {
254 auto const v = (*fLV)[i];
255 std::size_t nn = v->size();
256 for (std::size_t j = 0; j < nn; ++j) {
257 if ((*v)[j] == fCurrentLV) {
258 fCurrentModel = fModels[i];
259 if (fCurrentModel->StepLimit(j, aTrack, fPreStepBeta, limit)) {
260 *cond = StronglyForced;
261 }
262 ok = true;
263 break;
264 }
265 }
266 if (ok) { break; }
267 }
268 return limit;
269}
270
271//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
273 const G4Step& aStep)
274{
275 aParticleChange.Initialize(aTrack);
276 if (fCurrentModel == nullptr) { return &aParticleChange; }
277 fCurrentModel->SampleXRays(fSecondaries, aStep);
278 if (!fSecondaries.empty()) {
279
280 // X-rays
281 auto touch = aStep.GetPreStepPoint()->GetTouchableHandle();
282 G4int parent = aTrack.GetTrackID();
283 for (auto & t : fSecondaries) {
284 t->SetTouchableHandle(touch);
285 t->SetParentID(parent);
286 t->SetCreatorModelID(secID);
287 aParticleChange.AddSecondary(t);
288 }
289 fSecondaries.clear();
290
291 // primary track suspended
292 if (fTrackSecondariesFirst && aTrack.GetTrackStatus() == fAlive) {
293 aParticleChange.ProposeTrackStatus(fSuspend);
294 }
295 }
296 return &aParticleChange;
297}
298
299//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
300void G4GeneralCerenkov::ProcessDescription(std::ostream& out) const
301{
302 out << "The Cerenkov effect simulates optical photons created by the\n";
303 out << "passage of charged particles through matter. Materials need\n";
304 out << "to have the property RINDEX (refractive index) defined." << G4endl;
305}
306
307//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
309{
310 fTrackSecondariesFirst = state;
312 fTrackSecondariesFirst);
313}
314
315//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
317{
318 fMaxBetaChange = value;
320}
321
322//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
324{
325 fMaxPhotons = NumPhotons;
327}
328
329//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
331{
332 fStackingFlag = stackingFlag;
334}
335
336//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
342
343//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
349
350//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@ fCerenkov
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ForceCondition
@ StronglyForced
@ NotForced
@ kCerenkovDefault
G4ProcessType
@ fSuspend
@ fAlive
double G4double
Definition G4Types.hh:83
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4double GetBeta() const
void PreparePhysicsTable(const G4ParticleDefinition &part) override
G4GeneralCerenkov(const G4String &processName="Cerenkov", G4ProcessType type=fElectromagnetic)
~G4GeneralCerenkov() override
void SetTrackSecondariesFirst(const G4bool state)
void AddModelForVolume(G4VXRayModel *, const G4String &nameLogVolume)
void SetMaxBetaChangePerStep(const G4double d)
void SetStackPhotons(const G4bool)
G4bool IsApplicable(const G4ParticleDefinition &aParticleType) override
void SetMaxNumPhotonsPerStep(const G4int NumPhotons)
void BuildPhysicsTable(const G4ParticleDefinition &aParticleType) override
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *) override
void ProcessDescription(std::ostream &out) const override
G4double PostStepGetPhysicalInteractionLength(const G4Track &aTrack, G4double, G4ForceCondition *) override
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
G4LogicalVolumeStore is a singleton class, acting as container for all logical volumes,...
static G4LogicalVolumeStore * GetInstance()
G4Material * GetMaterial() const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
void SetCerenkovMaxBetaChange(G4double)
void SetCerenkovMaxPhotonsPerStep(G4int)
G4int GetCerenkovVerboseLevel() const
const std::vector< std::pair< G4XRayModelType, const G4String > > & ActiveVolumes() const
G4int GetCerenkovMaxPhotonsPerStep() const
static G4OpticalParameters * Instance()
G4double GetCerenkovMaxBetaChange() const
void SetCerenkovStackPhotons(G4bool)
void SetCerenkovTrackSecondariesFirst(G4bool)
G4bool GetCerenkovTrackSecondariesFirst() const
G4bool GetCerenkovStackPhotons() const
static G4int GetModelID(const G4int modelIndex)
const G4TouchableHandle & GetTouchableHandle() const
G4StepPoint * GetPreStepPoint() const
G4TrackStatus GetTrackStatus() const
G4int GetTrackID() const
G4VPhysicalVolume * GetVolume() const
const G4DynamicParticle * GetDynamicParticle() const
G4VDiscreteProcess(const G4String &aName, G4ProcessType aType=fNotDefined)
G4LogicalVolume * GetLogicalVolume() const
G4ParticleChange aParticleChange
G4int verboseLevel
void SetProcessSubType(G4int)
const G4String & GetProcessName() const
const G4String & GetName() const
#define DBL_MAX
Definition templates.hh:62