Geant4 9.6.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//
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