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