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