Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Region.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// G4Region class implementation
27//
28// 18.09.02, G.Cosmo - Initial version
29// --------------------------------------------------------------------
30
31#include "G4Region.hh"
32#include "G4RegionStore.hh"
33#include "G4LogicalVolume.hh"
34#include "G4VPhysicalVolume.hh"
38#include "G4Material.hh"
39
40// These macros changes the references to fields that are now encapsulated
41// in the class G4RegionData.
42//
43#define G4MT_fsmanager ((subInstanceManager.offset[instanceID]).fFastSimulationManager)
44#define G4MT_rsaction ((subInstanceManager.offset[instanceID]).fRegionalSteppingAction)
45
46// This new field helps to use the class G4RegionManager
47//
48G4RegionManager G4Region::subInstanceManager;
49
50// *******************************************************************
51// GetSubInstanceManager:
52// - Returns the private data instance manager.
53// *******************************************************************
54//
56{
57 return subInstanceManager;
58}
59
60// *******************************************************************
61// Constructor:
62// - Adds self to region Store
63// *******************************************************************
64//
66 : fName(pName)
67{
68
69 instanceID = subInstanceManager.CreateSubInstance();
70 G4MT_fsmanager = nullptr;
71 G4MT_rsaction = nullptr;
72
74 if (rStore->GetRegion(pName, false))
75 {
76 std::ostringstream message;
77 message << "The region has NOT been registered !" << G4endl
78 << " Region " << pName << " already existing in store !"
79 << G4endl;
80 G4Exception("G4Region::G4Region()", "GeomMgt1001",
81 JustWarning, message);
82 }
83 else
84 {
85 rStore->Register(this);
86 }
87}
88
89// ********************************************************************
90// Fake default constructor - sets only member data and allocates memory
91// for usage restricted to object persistency.
92// ********************************************************************
93//
95 : fName("")
96{
97 instanceID = subInstanceManager.CreateSubInstance();
98 G4MT_fsmanager = nullptr;
99 G4MT_rsaction = nullptr;
100
101 // Register to store
102 //
104}
105
106// *******************************************************************
107// Destructor:
108// - Removes self from region Store
109// *******************************************************************
110//
112{
114 if(fUserInfo != nullptr) { delete fUserInfo; }
115}
116
117// ********************************************************************
118// SetFastSimulationManager
119// ********************************************************************
120//
122{
123 G4MT_fsmanager = fsm;
124}
125
126// ********************************************************************
127// GetFastSimulationManager
128// ********************************************************************
129//
131{
132 return G4MT_fsmanager;
133}
134
135// ********************************************************************
136// SetRegionalSteppingAction
137// ********************************************************************
138//
140{
141 G4MT_rsaction = rusa;
142}
143
144// ********************************************************************
145// GetRegionalSteppingAction
146// ********************************************************************
147//
149{
150 return G4MT_rsaction;
151}
152
153// *******************************************************************
154// ScanVolumeTree:
155// - Scans recursively the 'lv' logical volume tree, retrieves
156// and places all materials in the list.
157// - The boolean flag 'region' identifies if the volume tree must
158// have region reset (false) or if the current region must be
159// associated to the logical volume 'lv' and its tree (true).
160// *******************************************************************
161//
163{
164 // If logical volume is going to become a region, add
165 // its material to the list if not already present
166 //
167 G4Region* currentRegion = nullptr;
168 size_t noDaughters = lv->GetNoDaughters();
169 G4Material* volMat = lv->GetMaterial();
170 if((volMat == nullptr) && fInMassGeometry)
171 {
172 std::ostringstream message;
173 message << "Logical volume <" << lv->GetName() << ">" << G4endl
174 << "does not have a valid material pointer." << G4endl
175 << "A logical volume belonging to the (tracking) world volume "
176 << "must have a valid material.";
177 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
178 FatalException, message, "Check your geometry construction.");
179 }
180 if (region)
181 {
182 currentRegion = this;
183 if (volMat != nullptr)
184 {
185 AddMaterial(volMat);
186 G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
187 if (baseMat != nullptr) { AddMaterial(baseMat); }
188 }
189 }
190
191 // Set the LV region to be either the current region or NULL,
192 // according to the boolean selector
193 //
194 lv->SetRegion(currentRegion);
195
196 // Stop recursion here if no further daughters are involved
197 //
198 if(noDaughters==0) return;
199
200 G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0);
201 if (daughterPVol->IsParameterised())
202 {
203 // Adopt special treatment in case of parameterised volumes,
204 // where parameterisation involves a new material scan
205 //
206 G4VPVParameterisation* pParam = daughterPVol->GetParameterisation();
207
208 if (pParam->GetMaterialScanner() != nullptr)
209 {
210 size_t matNo = pParam->GetMaterialScanner()->GetNumberOfMaterials();
211 for (size_t mat=0; mat<matNo; ++mat)
212 {
213 volMat = pParam->GetMaterialScanner()->GetMaterial(mat);
214 if(!volMat && fInMassGeometry)
215 {
216 std::ostringstream message;
217 message << "The parameterisation for the physical volume <"
218 << daughterPVol->GetName() << ">" << G4endl
219 << "does not return a valid material pointer." << G4endl
220 << "A volume belonging to the (tracking) world volume must "
221 << "have a valid material.";
222 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
223 FatalException, message, "Check your parameterisation.");
224 }
225 if (volMat != nullptr)
226 {
227 AddMaterial(volMat);
228 G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
229 if (baseMat != nullptr) { AddMaterial(baseMat); }
230 }
231 }
232 }
233 else
234 {
235 size_t repNo = daughterPVol->GetMultiplicity();
236 for (size_t rep=0; rep<repNo; ++rep)
237 {
238 volMat = pParam->ComputeMaterial(rep, daughterPVol);
239 if((volMat == nullptr) && fInMassGeometry)
240 {
241 std::ostringstream message;
242 message << "The parameterisation for the physical volume <"
243 << daughterPVol->GetName() << ">" << G4endl
244 << "does not return a valid material pointer." << G4endl
245 << "A volume belonging to the (tracking) world volume must "
246 << "have a valid material.";
247 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
248 FatalException, message, "Check your parameterisation.");
249 }
250 if(volMat != nullptr)
251 {
252 AddMaterial(volMat);
253 G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
254 if (baseMat != nullptr) { AddMaterial(baseMat); }
255 }
256 }
257 }
258 G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume();
259 ScanVolumeTree(daughterLVol, region);
260 }
261 else
262 {
263 for (size_t i=0; i<noDaughters; ++i)
264 {
265 G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume();
266 if (!daughterLVol->IsRootRegion())
267 {
268 // Set daughter's LV to be a region and store materials in
269 // the materials list, if the LV is not already a root region
270 //
271 ScanVolumeTree(daughterLVol, region);
272 }
273 }
274 }
275}
276
277// *******************************************************************
278// AddRootLogicalVolume:
279// - Adds a root logical volume and sets its daughters flags as
280// regions. It also recomputes the materials list for the region.
281// *******************************************************************
282//
284{
285 // Check the logical volume is not already in the list
286 //
287 if (search)
288 {
289 auto pos = std::find(fRootVolumes.cbegin(),fRootVolumes.cend(),lv);
290 if (pos == fRootVolumes.cend())
291 {
292 // Insert the root volume in the list and set it as root region
293 //
294 fRootVolumes.push_back(lv);
295 lv->SetRegionRootFlag(true);
296 }
297 }
298 else // WARNING: user *MUST* guarantee lv is not already inserted.
299 { // Providing speedup for very complex flat geometries
300 fRootVolumes.push_back(lv);
301 lv->SetRegionRootFlag(true);
302 }
303 // Scan recursively the tree of daugther volumes and set regions
304 //
305 ScanVolumeTree(lv, true);
306
307 // Set region as modified
308 //
309 fRegionMod = true;
310}
311
312// *******************************************************************
313// RemoveRootLogicalVolume:
314// - Removes a root logical volume and resets its daughters flags as
315// regions. It also recomputes the materials list for the region.
316// *******************************************************************
317//
319{
320 // Find and remove logical volume from the list
321 //
322 auto pos = std::find(fRootVolumes.cbegin(),fRootVolumes.cend(),lv);
323 if (pos != fRootVolumes.cend())
324 {
325 if (fRootVolumes.size() != 1) // Avoid resetting flag for world since
326 { // volume may be already deleted !
327 lv->SetRegionRootFlag(false);
328 }
329 fRootVolumes.erase(pos);
330 }
331
332 if (scan) // Update the materials list
333 {
335 }
336
337 // Set region as modified
338 //
339 fRegionMod = true;
340}
341
342// ********************************************************************
343// Clean
344// ********************************************************************
345//
347{
348 subInstanceManager.FreeSlave();
349}
350
351// *******************************************************************
352// ClearMaterialList:
353// - Clears the material list.
354// *******************************************************************
355//
357{
358 fMaterials.clear();
359}
360
361// *******************************************************************
362// UpdateMaterialList:
363// - computes material list looping through
364// each root logical volume in the region.
365// *******************************************************************
366//
368{
369 // Reset the materials list
370 //
372
373 // Loop over the root logical volumes and rebuild the list
374 // of materials from scratch
375 //
376 for (auto pLV=fRootVolumes.cbegin(); pLV!=fRootVolumes.cend(); ++pLV)
377 {
378 ScanVolumeTree(*pLV, true);
379 }
380}
381
382// *******************************************************************
383// SetWorld:
384// - Set the world physical volume if this region belongs to this
385// world. If the given pointer is null, reset the pointer.
386// *******************************************************************
387//
389{
390 if(!wp)
391 { fWorldPhys = 0; }
392 else
393 { if(BelongsTo(wp)) fWorldPhys = wp; }
394
395 return;
396}
397
398// *******************************************************************
399// BelongsTo:
400// - Returns whether this region belongs to the given physical volume
401// (recursively scanned to the bottom of the hierarchy)
402// *******************************************************************
403//
405{
406 G4LogicalVolume* currLog = thePhys->GetLogicalVolume();
407 if (currLog->GetRegion()==this) {return true;}
408
409 G4int nDaughters = currLog->GetNoDaughters();
410 while (nDaughters--) // Loop checking, 06.08.2015, G.Cosmo
411 {
412 if (BelongsTo(currLog->GetDaughter(nDaughters))) {return true;}
413 }
414
415 return false;
416}
417
418// *******************************************************************
419// ClearFastSimulationManager:
420// - Set G4FastSimulationManager pointer to the one for the parent region
421// if it exists. Otherwise set to null.
422// *******************************************************************
423//
425{
426 G4bool isUnique;
427 G4Region* parent = GetParentRegion(isUnique);
428 if(parent != nullptr)
429 {
430 if (isUnique)
431 {
433 }
434 else
435 {
436 std::ostringstream message;
437 message << "Region <" << fName << "> belongs to more than"
438 << " one parent region !" << G4endl
439 << "A region cannot belong to more than one direct parent region,"
440 << G4endl
441 << "to have fast-simulation assigned.";
442 G4Exception("G4Region::ClearFastSimulationManager()",
443 "GeomMgt1002", JustWarning, message);
444 G4MT_fsmanager = nullptr;
445 }
446 }
447 else
448 {
449 G4MT_fsmanager = nullptr;
450 }
451}
452
453// *******************************************************************
454// GetParentRegion:
455// - Returns a region that contains this region.
456// Otherwise null is returned.
457// *******************************************************************
458//
460{
461 G4Region* parent = nullptr; unique = true;
463
464 // Loop over all logical volumes in the store
465 //
466 for(auto lvItr=lvStore->cbegin(); lvItr!=lvStore->cend(); ++lvItr)
467 {
468 G4int nD = (*lvItr)->GetNoDaughters();
469 G4Region* aR = (*lvItr)->GetRegion();
470
471 // Loop over all daughters of each logical volume
472 //
473 for(auto iD=0; iD<nD; ++iD)
474 {
475 if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
476 {
477 if(parent)
478 {
479 if(parent!=aR) { unique = false; }
480 }
481 else // Cache LV parent region which includes a daughter volume
482 // with the same associated region as the current one
483 {
484 parent = aR;
485 }
486 }
487 }
488 }
489 return parent;
490}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
#define G4MT_rsaction
Definition: G4Region.cc:44
#define G4MT_fsmanager
Definition: G4Region.cc:43
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4int CreateSubInstance()
static G4LogicalVolumeStore * GetInstance()
void SetRegionRootFlag(G4bool rreg)
void SetRegion(G4Region *reg)
size_t GetNoDaughters() const
G4bool IsRootRegion() const
G4Region * GetRegion() const
G4Material * GetMaterial() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4String & GetName() const
const G4Material * GetBaseMaterial() const
Definition: G4Material.hh:231
static void DeRegister(G4Region *pRegion)
static void Register(G4Region *pRegion)
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
G4bool BelongsTo(G4VPhysicalVolume *thePhys) const
Definition: G4Region.cc:404
void ScanVolumeTree(G4LogicalVolume *lv, G4bool region)
Definition: G4Region.cc:162
void ClearMaterialList()
Definition: G4Region.cc:356
G4Region * GetParentRegion(G4bool &unique) const
Definition: G4Region.cc:459
G4FastSimulationManager * GetFastSimulationManager() const
Definition: G4Region.cc:130
virtual ~G4Region()
Definition: G4Region.cc:111
void SetWorld(G4VPhysicalVolume *wp)
Definition: G4Region.cc:388
void RemoveRootLogicalVolume(G4LogicalVolume *lv, G4bool scan=true)
Definition: G4Region.cc:318
void UpdateMaterialList()
Definition: G4Region.cc:367
G4Region(const G4String &name)
Definition: G4Region.cc:65
void SetFastSimulationManager(G4FastSimulationManager *fsm)
Definition: G4Region.cc:121
void SetRegionalSteppingAction(G4UserSteppingAction *rusa)
Definition: G4Region.cc:139
static const G4RegionManager & GetSubInstanceManager()
Definition: G4Region.cc:55
G4UserSteppingAction * GetRegionalSteppingAction() const
Definition: G4Region.cc:148
static void Clean()
Definition: G4Region.cc:346
void ClearFastSimulationManager()
Definition: G4Region.cc:424
void AddRootLogicalVolume(G4LogicalVolume *lv, G4bool search=true)
Definition: G4Region.cc:283
virtual G4VVolumeMaterialScanner * GetMaterialScanner()
virtual G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=nullptr)
G4LogicalVolume * GetLogicalVolume() const
virtual G4int GetMultiplicity() const
const G4String & GetName() const
virtual G4VPVParameterisation * GetParameterisation() const =0
virtual G4bool IsParameterised() const =0
virtual G4Material * GetMaterial(G4int idx) const =0
virtual G4int GetNumberOfMaterials() const =0