Geant4 11.1.1
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))
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// 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//
132{
133 G4MT_fsmanager = fsm;
134}
135
136// ********************************************************************
137// GetFastSimulationManager
138// ********************************************************************
139//
141{
142 return G4MT_fsmanager;
143}
144
145// ********************************************************************
146// SetRegionalSteppingAction
147// ********************************************************************
148//
150{
151 G4MT_rsaction = rusa;
152}
153
154// ********************************************************************
155// GetRegionalSteppingAction
156// ********************************************************************
157//
159{
160 return G4MT_rsaction;
161}
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 G4Material* 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 && 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 G4Material* 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 G4Material* 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 the logical volume is not already in the list
296 //
297 if (search)
298 {
299 auto pos = std::find(fRootVolumes.cbegin(),fRootVolumes.cend(),lv);
300 if (pos == fRootVolumes.cend())
301 {
302 // Insert the root volume in the list and set it as root region
303 //
304 fRootVolumes.push_back(lv);
305 lv->SetRegionRootFlag(true);
306 }
307 }
308 else // WARNING: user *MUST* guarantee lv is not already inserted.
309 { // Providing speedup for very complex flat geometries
310 fRootVolumes.push_back(lv);
311 lv->SetRegionRootFlag(true);
312 }
313 // Scan recursively the tree of daugther volumes and set regions
314 //
315 ScanVolumeTree(lv, true);
316
317 // Set region as modified
318 //
319 fRegionMod = true;
320}
321
322// *******************************************************************
323// RemoveRootLogicalVolume:
324// - Removes a root logical volume and resets its daughters flags as
325// regions. It also recomputes the materials list for the region.
326// *******************************************************************
327//
329{
330 // Find and remove logical volume from the list
331 //
332 auto pos = std::find(fRootVolumes.cbegin(),fRootVolumes.cend(),lv);
333 if (pos != fRootVolumes.cend())
334 {
335 if (fRootVolumes.size() != 1) // Avoid resetting flag for world since
336 { // volume may be already deleted !
337 lv->SetRegionRootFlag(false);
338 }
339 fRootVolumes.erase(pos);
340 }
341
342 if (scan) // Update the materials list
343 {
345 }
346
347 // Set region as modified
348 //
349 fRegionMod = true;
350}
351
352// ********************************************************************
353// Clean
354// ********************************************************************
355//
357{
358 subInstanceManager.FreeSlave();
359}
360
361// *******************************************************************
362// ClearMaterialList:
363// - Clears the material list.
364// *******************************************************************
365//
367{
368 fMaterials.clear();
369}
370
371// *******************************************************************
372// UpdateMaterialList:
373// - computes material list looping through
374// each root logical volume in the region.
375// *******************************************************************
376//
378{
379 // Reset the materials list
380 //
382
383 // Loop over the root logical volumes and rebuild the list
384 // of materials from scratch
385 //
386 for (auto pLV=fRootVolumes.cbegin(); pLV!=fRootVolumes.cend(); ++pLV)
387 {
388 ScanVolumeTree(*pLV, true);
389 }
390}
391
392// *******************************************************************
393// SetWorld:
394// - Set the world physical volume if this region belongs to this
395// world. If the given pointer is null, reset the pointer.
396// *******************************************************************
397//
399{
400 if(!wp)
401 { fWorldPhys = nullptr; }
402 else
403 { if(BelongsTo(wp)) fWorldPhys = wp; }
404
405 return;
406}
407
408// *******************************************************************
409// BelongsTo:
410// - Returns whether this region belongs to the given physical volume
411// (recursively scanned to the bottom of the hierarchy)
412// *******************************************************************
413//
415{
416 G4LogicalVolume* currLog = thePhys->GetLogicalVolume();
417 if (currLog->GetRegion()==this) {return true;}
418
419 std::size_t nDaughters = currLog->GetNoDaughters();
420 while (nDaughters--) // Loop checking, 06.08.2015, G.Cosmo
421 {
422 if (BelongsTo(currLog->GetDaughter(nDaughters))) {return true;}
423 }
424
425 return false;
426}
427
428// *******************************************************************
429// ClearFastSimulationManager:
430// - Set G4FastSimulationManager pointer to the one for the parent region
431// if it exists. Otherwise set to null.
432// *******************************************************************
433//
435{
436 G4bool isUnique;
437 G4Region* parent = GetParentRegion(isUnique);
438 if(parent != nullptr)
439 {
440 if (isUnique)
441 {
443 }
444 else
445 {
446 std::ostringstream message;
447 message << "Region <" << fName << "> belongs to more than"
448 << " one parent region !" << G4endl
449 << "A region cannot belong to more than one direct parent region,"
450 << G4endl
451 << "to have fast-simulation assigned.";
452 G4Exception("G4Region::ClearFastSimulationManager()",
453 "GeomMgt1002", JustWarning, message);
454 G4MT_fsmanager = nullptr;
455 }
456 }
457 else
458 {
459 G4MT_fsmanager = nullptr;
460 }
461}
462
463// *******************************************************************
464// GetParentRegion:
465// - Returns a region that contains this region.
466// Otherwise null is returned.
467// *******************************************************************
468//
470{
471 G4Region* parent = nullptr; unique = true;
473
474 // Loop over all logical volumes in the store
475 //
476 for(auto lvItr=lvStore->cbegin(); lvItr!=lvStore->cend(); ++lvItr)
477 {
478 std::size_t nD = (*lvItr)->GetNoDaughters();
479 G4Region* aR = (*lvItr)->GetRegion();
480
481 // Loop over all daughters of each logical volume
482 //
483 for(std::size_t iD=0; iD<nD; ++iD)
484 {
485 if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
486 {
487 if(parent)
488 {
489 if(parent!=aR) { unique = false; }
490 }
491 else // Cache LV parent region which includes a daughter volume
492 // with the same associated region as the current one
493 {
494 parent = aR;
495 }
496 }
497 }
498 }
499 return parent;
500}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
#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()
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
Definition: G4Material.hh:228
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:414
void ScanVolumeTree(G4LogicalVolume *lv, G4bool region)
Definition: G4Region.cc:172
void ClearMaterialList()
Definition: G4Region.cc:366
G4Region * GetParentRegion(G4bool &unique) const
Definition: G4Region.cc:469
G4FastSimulationManager * GetFastSimulationManager() const
Definition: G4Region.cc:140
virtual ~G4Region()
Definition: G4Region.cc:111
void SetWorld(G4VPhysicalVolume *wp)
Definition: G4Region.cc:398
void RemoveRootLogicalVolume(G4LogicalVolume *lv, G4bool scan=true)
Definition: G4Region.cc:328
void UpdateMaterialList()
Definition: G4Region.cc:377
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:356
void ClearFastSimulationManager()
Definition: G4Region.cc:434
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