Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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$
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 // *******************************************************************
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 //
75 G4Region::G4Region( __void__& )
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 }