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