Geant4 11.2.2
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) != 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