Geant4  10.03.p01
 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 //
27 // $Id: G4Region.cc 100428 2016-10-21 12:59:37Z 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 // These macros changes the references to fields that are now encapsulated
44 // in the class G4RegionData.
45 //
46 #define G4MT_fsmanager ((subInstanceManager.offset[instanceID]).fFastSimulationManager)
47 #define G4MT_rsaction ((subInstanceManager.offset[instanceID]).fRegionalSteppingAction)
48 
49 // This new field helps to use the class G4RegionManager
50 //
51 G4RegionManager G4Region::subInstanceManager;
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 
74  instanceID = subInstanceManager.CreateSubInstance();
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 {
104  instanceID = subInstanceManager.CreateSubInstance();
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 // SetFastSimulationManager
126 // ********************************************************************
127 //
129 {
130  G4MT_fsmanager = fsm;
131 }
132 
133 // ********************************************************************
134 // GetFastSimulationManager
135 // ********************************************************************
136 //
138 {
139  return G4MT_fsmanager;
140 }
141 
142 // ********************************************************************
143 // SetRegionalSteppingAction
144 // ********************************************************************
145 //
147 {
148  G4MT_rsaction = rusa;
149 }
150 
151 // ********************************************************************
152 // GetRegionalSteppingAction
153 // ********************************************************************
154 //
156 {
157  return G4MT_rsaction;
158 }
159 
160 // *******************************************************************
161 // ScanVolumeTree:
162 // - Scans recursively the 'lv' logical volume tree, retrieves
163 // and places all materials in the list.
164 // - The boolean flag 'region' identifies if the volume tree must
165 // have region reset (false) or if the current region must be
166 // associated to the logical volume 'lv' and its tree (true).
167 // *******************************************************************
168 //
170 {
171  // If logical volume is going to become a region, add
172  // its material to the list if not already present
173  //
174  G4Region* currentRegion = 0;
175  size_t noDaughters = lv->GetNoDaughters();
176  G4Material* volMat = lv->GetMaterial();
177  if(!volMat && fInMassGeometry)
178  {
179  std::ostringstream message;
180  message << "Logical volume <" << lv->GetName() << ">" << G4endl
181  << "does not have a valid material pointer." << G4endl
182  << "A logical volume belonging to the (tracking) world volume "
183  << "must have a valid material.";
184  G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
185  FatalException, message, "Check your geometry construction.");
186  }
187  if (region)
188  {
189  currentRegion = this;
190  if (volMat)
191  {
192  AddMaterial(volMat);
193  G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
194  if (baseMat) { AddMaterial(baseMat); }
195  }
196  }
197 
198  // Set the LV region to be either the current region or NULL,
199  // according to the boolean selector
200  //
201  lv->SetRegion(currentRegion);
202 
203  // Stop recursion here if no further daughters are involved
204  //
205  if(noDaughters==0) return;
206 
207  G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0);
208  if (daughterPVol->IsParameterised())
209  {
210  // Adopt special treatment in case of parameterised volumes,
211  // where parameterisation involves a new material scan
212  //
213  G4VPVParameterisation* pParam = daughterPVol->GetParameterisation();
214 
215  if (pParam->GetMaterialScanner())
216  {
217  size_t matNo = pParam->GetMaterialScanner()->GetNumberOfMaterials();
218  for (size_t mat=0; mat<matNo; mat++)
219  {
220  volMat = pParam->GetMaterialScanner()->GetMaterial(mat);
221  if(!volMat && fInMassGeometry)
222  {
223  std::ostringstream message;
224  message << "The parameterisation for the physical volume <"
225  << daughterPVol->GetName() << ">" << G4endl
226  << "does not return a valid material pointer." << G4endl
227  << "A volume belonging to the (tracking) world volume must "
228  << "have a valid material.";
229  G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
230  FatalException, message, "Check your parameterisation.");
231  }
232  if (volMat)
233  {
234  AddMaterial(volMat);
235  G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
236  if (baseMat) { AddMaterial(baseMat); }
237  }
238  }
239  }
240  else
241  {
242  size_t repNo = daughterPVol->GetMultiplicity();
243  for (size_t rep=0; rep<repNo; rep++)
244  {
245  volMat = pParam->ComputeMaterial(rep, daughterPVol);
246  if(!volMat && fInMassGeometry)
247  {
248  std::ostringstream message;
249  message << "The parameterisation for the physical volume <"
250  << daughterPVol->GetName() << ">" << G4endl
251  << "does not return a valid material pointer." << G4endl
252  << "A volume belonging to the (tracking) world volume must "
253  << "have a valid material.";
254  G4Exception("G4Region::ScanVolumeTree()", "GeomMgt0002",
255  FatalException, message, "Check your parameterisation.");
256  }
257  if(volMat)
258  {
259  AddMaterial(volMat);
260  G4Material* baseMat = const_cast<G4Material*>(volMat->GetBaseMaterial());
261  if (baseMat) { AddMaterial(baseMat); }
262  }
263  }
264  }
265  G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume();
266  ScanVolumeTree(daughterLVol, region);
267  }
268  else
269  {
270  for (size_t i=0; i<noDaughters; i++)
271  {
272  G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume();
273  if (!daughterLVol->IsRootRegion())
274  {
275  // Set daughter's LV to be a region and store materials in
276  // the materials list, if the LV is not already a root region
277  //
278  ScanVolumeTree(daughterLVol, region);
279  }
280  }
281  }
282 }
283 
284 // *******************************************************************
285 // AddRootLogicalVolume:
286 // - Adds a root logical volume and sets its daughters flags as
287 // regions. It also recomputes the materials list for the region.
288 // *******************************************************************
289 //
291 {
292  // Check the logical volume is not already in the list
293  //
294  G4RootLVList::iterator pos;
295  pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv);
296  if (pos == fRootVolumes.end())
297  {
298  // Insert the root volume in the list and set it as root region
299  //
300  fRootVolumes.push_back(lv);
301  lv->SetRegionRootFlag(true);
302  }
303 
304  // Scan recursively the tree of daugther volumes and set regions
305  //
306  ScanVolumeTree(lv, true);
307 
308  // Set region as modified
309  //
310  fRegionMod = true;
311 }
312 
313 // *******************************************************************
314 // RemoveRootLogicalVolume:
315 // - Removes a root logical volume and resets its daughters flags as
316 // regions. It also recomputes the materials list for the region.
317 // *******************************************************************
318 //
320 {
321  // Find and remove logical volume from the list
322  //
323  G4RootLVList::iterator pos;
324  pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv);
325  if (pos != fRootVolumes.end())
326  {
327  if (fRootVolumes.size() != 1) // Avoid resetting flag for world since
328  { // volume may be already deleted !
329  lv->SetRegionRootFlag(false);
330  }
331  fRootVolumes.erase(pos);
332  }
333 
334  if (scan) // Update the materials list
335  {
337  }
338 
339  // Set region as modified
340  //
341  fRegionMod = true;
342 }
343 
344 // *******************************************************************
345 // ClearMaterialList:
346 // - Clears the material list.
347 // *******************************************************************
348 //
350 {
351  fMaterials.clear();
352 }
353 
354 // *******************************************************************
355 // UpdateMaterialList:
356 // - computes material list looping through
357 // each root logical volume in the region.
358 // *******************************************************************
359 //
361 {
362  // Reset the materials list
363  //
365 
366  // Loop over the root logical volumes and rebuild the list
367  // of materials from scratch
368  //
369  G4RootLVList::iterator pLV;
370  for (pLV=fRootVolumes.begin(); pLV!=fRootVolumes.end(); pLV++)
371  {
372  ScanVolumeTree(*pLV, true);
373  }
374 }
375 
376 // *******************************************************************
377 // SetWorld:
378 // - Set the world physical volume if this region belongs to this
379 // world. If the given pointer is null, reset the pointer.
380 // *******************************************************************
381 //
383 {
384  if(!wp)
385  { fWorldPhys = 0; }
386  else
387  { if(BelongsTo(wp)) fWorldPhys = wp; }
388 
389  return;
390 }
391 
392 // *******************************************************************
393 // BelongsTo:
394 // - Returns whether this region belongs to the given physical volume
395 // (recursively scanned to the bottom of the hierarchy)
396 // *******************************************************************
397 //
399 {
400  G4LogicalVolume* currLog = thePhys->GetLogicalVolume();
401  if (currLog->GetRegion()==this) {return true;}
402 
403  G4int nDaughters = currLog->GetNoDaughters();
404  while (nDaughters--) // Loop checking, 06.08.2015, G.Cosmo
405  {
406  if (BelongsTo(currLog->GetDaughter(nDaughters))) {return true;}
407  }
408 
409  return false;
410 }
411 
412 // *******************************************************************
413 // ClearFastSimulationManager:
414 // - Set G4FastSimulationManager pointer to the one for the parent region
415 // if it exists. Otherwise set to null.
416 // *******************************************************************
417 //
419 {
420  G4bool isUnique;
421  G4Region* parent = GetParentRegion(isUnique);
422  if(parent)
423  {
424  if (isUnique)
425  {
427  }
428  else
429  {
430  std::ostringstream message;
431  message << "Region <" << fName << "> belongs to more than"
432  << " one parent region !" << G4endl
433  << "A region cannot belong to more than one direct parent region,"
434  << G4endl
435  << "to have fast-simulation assigned.";
436  G4Exception("G4Region::ClearFastSimulationManager()",
437  "GeomMgt1002", JustWarning, message);
438  G4MT_fsmanager = 0;
439  }
440  }
441  else
442  {
443  G4MT_fsmanager = 0;
444  }
445 }
446 
447 // *******************************************************************
448 // GetParentRegion:
449 // - Returns a region that contains this region.
450 // Otherwise null is returned.
451 // *******************************************************************
452 //
454 {
455  G4Region* parent = 0; unique = true;
457  G4LogicalVolumeStore::iterator lvItr;
458 
459  // Loop over all logical volumes in the store
460  //
461  for(lvItr=lvStore->begin(); lvItr!=lvStore->end(); lvItr++)
462  {
463  G4int nD = (*lvItr)->GetNoDaughters();
464  G4Region* aR = (*lvItr)->GetRegion();
465 
466  // Loop over all daughters of each logical volume
467  //
468  for(G4int iD=0; iD<nD; iD++)
469  {
470  if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
471  {
472  if(parent)
473  {
474  if(parent!=aR) { unique = false; }
475  }
476  else // Cache LV parent region which includes a daughter volume
477  // with the same associated region as the current one
478  {
479  parent = aR;
480  }
481  }
482  }
483  }
484  return parent;
485 }
virtual G4VVolumeMaterialScanner * GetMaterialScanner()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
virtual G4Material * ComputeMaterial(const G4int repNo, G4VPhysicalVolume *currentVol, const G4VTouchable *parentTouch=0)
G4Material * GetMaterial() const
G4UserSteppingAction * GetRegionalSteppingAction() const
Definition: G4Region.cc:155
void AddRootLogicalVolume(G4LogicalVolume *lv)
Definition: G4Region.cc:290
G4String fName
Definition: G4AttUtils.hh:55
void SetRegionRootFlag(G4bool rreg)
G4VPhysicalVolume * GetDaughter(const G4int i) const
#define G4MT_rsaction
Definition: G4Region.cc:47
G4Region * GetRegion() const
G4int CreateSubInstance()
#define G4MT_fsmanager
Definition: G4Region.cc:46
static void DeRegister(G4Region *pRegion)
int G4int
Definition: G4Types.hh:78
static unsigned wp
Definition: csz_inflate.cc:294
virtual G4int GetNumberOfMaterials() const =0
static G4RegionStore * GetInstance()
void SetFastSimulationManager(G4FastSimulationManager *fsm)
Definition: G4Region.cc:128
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:169
const G4String & GetName() const
bool G4bool
Definition: G4Types.hh:79
G4bool IsRootRegion() const
virtual G4VPVParameterisation * GetParameterisation() const =0
static G4LogicalVolumeStore * GetInstance()
void ClearFastSimulationManager()
Definition: G4Region.cc:418
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:398
G4LogicalVolume * GetLogicalVolume() const
void SetWorld(G4VPhysicalVolume *wp)
Definition: G4Region.cc:382
G4Region * GetParentRegion(G4bool &unique) const
Definition: G4Region.cc:453
const G4Material * GetBaseMaterial() const
Definition: G4Material.hh:233
virtual G4int GetMultiplicity() const
#define G4endl
Definition: G4ios.hh:61
virtual ~G4Region()
Definition: G4Region.cc:118
const G4String & GetName() const
void UpdateMaterialList()
Definition: G4Region.cc:360
void SetRegionalSteppingAction(G4UserSteppingAction *rusa)
Definition: G4Region.cc:146
void RemoveRootLogicalVolume(G4LogicalVolume *lv, G4bool scan=true)
Definition: G4Region.cc:319
static const G4RegionManager & GetSubInstanceManager()
Definition: G4Region.cc:58
static void Register(G4Region *pRegion)
G4FastSimulationManager * GetFastSimulationManager() const
Definition: G4Region.cc:137
static const G4double pos
void ClearMaterialList()
Definition: G4Region.cc:349