Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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) != nullptr)
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 delete fUserInfo;
115}
116
117// ********************************************************************
118// SetName - Set region name and notify store of the change
119// ********************************************************************
120//
121void G4Region::SetName(const G4String& pName)
122{
123 fName = pName;
125}
126
127// ********************************************************************
128// SetFastSimulationManager
129// ********************************************************************
130//
135
136// ********************************************************************
137// GetFastSimulationManager
138// ********************************************************************
139//
144
145// ********************************************************************
146// SetRegionalSteppingAction
147// ********************************************************************
148//
153
154// ********************************************************************
155// GetRegionalSteppingAction
156// ********************************************************************
157//
162
163// *******************************************************************
164// ScanVolumeTree:
165// - Scans recursively the 'lv' logical volume tree, retrieves
166// and places all materials in the list.
167// - The boolean flag 'region' identifies if the volume tree must
168// have region reset (false) or if the current region must be
169// associated to the logical volume 'lv' and its tree (true).
170// *******************************************************************
171//
173{
174 // If logical volume is going to become a region, add
175 // its material to the list if not already present
176 //
177 G4Region* currentRegion = nullptr;
178 std::size_t noDaughters = lv->GetNoDaughters();
179 G4Material* volMat = lv->GetMaterial();
180 if((volMat == nullptr) && fInMassGeometry)
181 {
182 std::ostringstream message;
183 message << "Logical volume <" << lv->GetName() << ">" << G4endl
184 << "does not have a valid material pointer." << G4endl
185 << "A logical volume belonging to the (tracking) world volume "
186 << "must have a valid material.";
187 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
188 FatalException, message, "Check your geometry construction.");
189 }
190 if (region)
191 {
192 currentRegion = this;
193 if (volMat != nullptr)
194 {
195 AddMaterial(volMat);
196 auto baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
197 if (baseMat != nullptr) { AddMaterial(baseMat); }
198 }
199 }
200
201 // Set the LV region to be either the current region or NULL,
202 // according to the boolean selector
203 //
204 lv->SetRegion(currentRegion);
205
206 // Stop recursion here if no further daughters are involved
207 //
208 if(noDaughters==0) return;
209
210 G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0);
211 if (daughterPVol->IsParameterised())
212 {
213 // Adopt special treatment in case of parameterised volumes,
214 // where parameterisation involves a new material scan
215 //
216 G4VPVParameterisation* pParam = daughterPVol->GetParameterisation();
217
218 if (pParam->GetMaterialScanner() != nullptr)
219 {
220 std::size_t matNo = pParam->GetMaterialScanner()->GetNumberOfMaterials();
221 for (std::size_t mat=0; mat<matNo; ++mat)
222 {
223 volMat = pParam->GetMaterialScanner()->GetMaterial((G4int)mat);
224 if((volMat == nullptr) && fInMassGeometry)
225 {
226 std::ostringstream message;
227 message << "The parameterisation for the physical volume <"
228 << daughterPVol->GetName() << ">" << G4endl
229 << "does not return a valid material pointer." << G4endl
230 << "A volume belonging to the (tracking) world volume must "
231 << "have a valid material.";
232 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
233 FatalException, message, "Check your parameterisation.");
234 }
235 if (volMat != nullptr)
236 {
237 AddMaterial(volMat);
238 auto baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
239 if (baseMat != nullptr) { AddMaterial(baseMat); }
240 }
241 }
242 }
243 else
244 {
245 std::size_t repNo = daughterPVol->GetMultiplicity();
246 for (std::size_t rep=0; rep<repNo; ++rep)
247 {
248 volMat = pParam->ComputeMaterial((G4int)rep, daughterPVol);
249 if((volMat == nullptr) && fInMassGeometry)
250 {
251 std::ostringstream message;
252 message << "The parameterisation for the physical volume <"
253 << daughterPVol->GetName() << ">" << G4endl
254 << "does not return a valid material pointer." << G4endl
255 << "A volume belonging to the (tracking) world volume must "
256 << "have a valid material.";
257 G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
258 FatalException, message, "Check your parameterisation.");
259 }
260 if(volMat != nullptr)
261 {
262 AddMaterial(volMat);
263 auto baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
264 if (baseMat != nullptr) { AddMaterial(baseMat); }
265 }
266 }
267 }
268 G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume();
269 ScanVolumeTree(daughterLVol, region);
270 }
271 else
272 {
273 for (std::size_t i=0; i<noDaughters; ++i)
274 {
275 G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume();
276 if (!daughterLVol->IsRootRegion())
277 {
278 // Set daughter's LV to be a region and store materials in
279 // the materials list, if the LV is not already a root region
280 //
281 ScanVolumeTree(daughterLVol, region);
282 }
283 }
284 }
285}
286
287// *******************************************************************
288// AddRootLogicalVolume:
289// - Adds a root logical volume and sets its daughters flags as
290// regions. It also recomputes the materials list for the region.
291// *******************************************************************
292//
294{
295 // Check if logical volume is already belonging to another region
296 //
297 if ((lv->IsRootRegion()) && (lv->GetRegion() != this))
298 {
299 std::ostringstream message;
300 message << "Logical volume <" << lv->GetName() << "> is already set as" << G4endl
301 << "root for region <" << lv->GetRegion()->GetName() << ">." << G4endl
302 << "It cannot be root logical volume for another region <" << GetName()
303 << ">" << G4endl;
304 G4Exception("G4Region::AddRootLogicalVolume()", "GeomMgt0002", FatalException,
305 message, "A logical volume cannot belong to more than one region!");
306 return;
307 }
308
309 // Check the logical volume is not already in the list
310 //
311 if (search)
312 {
313 auto pos = std::find(fRootVolumes.cbegin(),fRootVolumes.cend(),lv);
314 if (pos == fRootVolumes.cend())
315 {
316 // Insert the root volume in the list and set it as root region
317 //
318 fRootVolumes.push_back(lv);
319 lv->SetRegionRootFlag(true);
320 }
321 }
322 else // WARNING: user *MUST* guarantee lv is not already inserted.
323 { // Providing speedup for very complex flat geometries
324 fRootVolumes.push_back(lv);
325 lv->SetRegionRootFlag(true);
326 }
327 // Scan recursively the tree of daugther volumes and set regions
328 //
329 ScanVolumeTree(lv, true);
330
331 // Set region as modified
332 //
333 fRegionMod = true;
334}
335
336// *******************************************************************
337// RemoveRootLogicalVolume:
338// - Removes a root logical volume and resets its daughters flags as
339// regions. It also recomputes the materials list for the region.
340// *******************************************************************
341//
343{
344 // Find and remove logical volume from the list
345 //
346 auto pos = std::find(fRootVolumes.cbegin(),fRootVolumes.cend(),lv);
347 if (pos != fRootVolumes.cend())
348 {
349 if (fRootVolumes.size() != 1) // Avoid resetting flag for world since
350 { // volume may be already deleted !
351 lv->SetRegionRootFlag(false);
352 }
353 fRootVolumes.erase(pos);
354 }
355
356 if (scan) // Update the materials list
357 {
359 }
360
361 // Set region as modified
362 //
363 fRegionMod = true;
364}
365
366// ********************************************************************
367// Clean
368// ********************************************************************
369//
371{
372 subInstanceManager.FreeSlave();
373}
374
375// *******************************************************************
376// ClearMaterialList:
377// - Clears the material list.
378// *******************************************************************
379//
381{
382 fMaterials.clear();
383}
384
385// *******************************************************************
386// UpdateMaterialList:
387// - computes material list looping through
388// each root logical volume in the region.
389// *******************************************************************
390//
392{
393 // Reset the materials list
394 //
396
397 // Loop over the root logical volumes and rebuild the list
398 // of materials from scratch
399 //
400 for (auto pLV=fRootVolumes.cbegin(); pLV!=fRootVolumes.cend(); ++pLV)
401 {
402 ScanVolumeTree(*pLV, true);
403 }
404}
405
406// *******************************************************************
407// SetWorld:
408// - Set the world physical volume if this region belongs to this
409// world. If the given pointer is null, reset the pointer.
410// *******************************************************************
411//
413{
414 if(wp == nullptr)
415 { fWorldPhys = nullptr; }
416 else
417 { if(BelongsTo(wp)) fWorldPhys = wp; }
418
419 return;
420}
421
422// *******************************************************************
423// BelongsTo:
424// - Returns whether this region belongs to the given physical volume
425// (recursively scanned to the bottom of the hierarchy)
426// *******************************************************************
427//
429{
430 G4LogicalVolume* currLog = thePhys->GetLogicalVolume();
431 if (currLog->GetRegion()==this) {return true;}
432
433 std::size_t nDaughters = currLog->GetNoDaughters();
434 while ((nDaughters--) != 0) // Loop checking, 06.08.2015, G.Cosmo
435 {
436 if (BelongsTo(currLog->GetDaughter(nDaughters))) {return true;}
437 }
438
439 return false;
440}
441
442// *******************************************************************
443// ClearFastSimulationManager:
444// - Set G4FastSimulationManager pointer to the one for the parent region
445// if it exists. Otherwise set to null.
446// *******************************************************************
447//
449{
450 G4bool isUnique;
451 G4Region* parent = GetParentRegion(isUnique);
452 if(parent != nullptr)
453 {
454 if (isUnique)
455 {
457 }
458 else
459 {
460 std::ostringstream message;
461 message << "Region <" << fName << "> belongs to more than"
462 << " one parent region !" << G4endl
463 << "A region cannot belong to more than one direct parent region,"
464 << G4endl
465 << "to have fast-simulation assigned.";
466 G4Exception("G4Region::ClearFastSimulationManager()",
467 "GeomMgt1002", JustWarning, message);
468 G4MT_fsmanager = nullptr;
469 }
470 }
471 else
472 {
473 G4MT_fsmanager = nullptr;
474 }
475}
476
477// *******************************************************************
478// GetParentRegion:
479// - Returns a region that contains this region.
480// Otherwise null is returned.
481// *******************************************************************
482//
484{
485 G4Region* parent = nullptr; unique = true;
487
488 // Loop over all logical volumes in the store
489 //
490 for(auto lvItr=lvStore->cbegin(); lvItr!=lvStore->cend(); ++lvItr)
491 {
492 std::size_t nD = (*lvItr)->GetNoDaughters();
493 G4Region* aR = (*lvItr)->GetRegion();
494
495 // Loop over all daughters of each logical volume
496 //
497 for(std::size_t iD=0; iD<nD; ++iD)
498 {
499 if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
500 {
501 if(parent != nullptr)
502 {
503 if(parent!=aR) { unique = false; }
504 }
505 else // Cache LV parent region which includes a daughter volume
506 // with the same associated region as the current one
507 {
508 parent = aR;
509 }
510 }
511 }
512 }
513 return parent;
514}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#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:67
G4int CreateSubInstance()
static G4LogicalVolumeStore * GetInstance()
std::size_t GetNoDaughters() const
void SetRegionRootFlag(G4bool rreg)
void SetRegion(G4Region *reg)
G4bool IsRootRegion() const
G4Region * GetRegion() const
G4Material * GetMaterial() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
const G4String & GetName() const
const G4Material * GetBaseMaterial() const
static void DeRegister(G4Region *pRegion)
static void Register(G4Region *pRegion)
static G4RegionStore * GetInstance()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
void SetMapValid(G4bool val)
G4bool BelongsTo(G4VPhysicalVolume *thePhys) const
Definition G4Region.cc:428
void ScanVolumeTree(G4LogicalVolume *lv, G4bool region)
Definition G4Region.cc:172
void ClearMaterialList()
Definition G4Region.cc:380
G4Region * GetParentRegion(G4bool &unique) const
Definition G4Region.cc:483
G4FastSimulationManager * GetFastSimulationManager() const
Definition G4Region.cc:140
virtual ~G4Region()
Definition G4Region.cc:111
void SetWorld(G4VPhysicalVolume *wp)
Definition G4Region.cc:412
void RemoveRootLogicalVolume(G4LogicalVolume *lv, G4bool scan=true)
Definition G4Region.cc:342
const G4String & GetName() const
void UpdateMaterialList()
Definition G4Region.cc:391
G4Region(const G4String &name)
Definition G4Region.cc:65
void SetFastSimulationManager(G4FastSimulationManager *fsm)
Definition G4Region.cc:131
void SetRegionalSteppingAction(G4UserSteppingAction *rusa)
Definition G4Region.cc:149
void SetName(const G4String &name)
Definition G4Region.cc:121
static const G4RegionManager & GetSubInstanceManager()
Definition G4Region.cc:55
G4UserSteppingAction * GetRegionalSteppingAction() const
Definition G4Region.cc:158
static void Clean()
Definition G4Region.cc:370
void ClearFastSimulationManager()
Definition G4Region.cc:448
void AddRootLogicalVolume(G4LogicalVolume *lv, G4bool search=true)
Definition G4Region.cc:293
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