source: trunk/source/geometry/management/src/G4Region.cc@ 1239

Last change on this file since 1239 was 1228, checked in by garnier, 16 years ago

update geant4.9.3 tag

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