source: trunk/source/geometry/management/src/G4LogicalVolume.cc@ 834

Last change on this file since 834 was 831, checked in by garnier, 17 years ago

import all except CVS

File size: 10.7 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: G4LogicalVolume.cc,v 1.32 2006/11/30 10:39:28 gcosmo Exp $
28// GEANT4 tag $Name: $
29//
30//
31// class G4LogicalVolume Implementation
32//
33// History:
34// 01.03.05 G.Santin: Added flag for optional propagation of GetMass()
35// 17.05.02 G.Cosmo: Added flag for optional optimisation
36// 12.02.99 S.Giani: Default initialization of voxelization quality
37// 04.08.97 P.M.DeFreitas: Added methods for parameterised simulation
38// 19.08.96 P.Kent: Modified for G4VSensitive Detector
39// 11.07.95 P.Kent: Initial version
40// --------------------------------------------------------------------
41
42#include "G4LogicalVolume.hh"
43#include "G4LogicalVolumeStore.hh"
44#include "G4VSolid.hh"
45#include "G4Material.hh"
46#include "G4VPVParameterisation.hh"
47#include "G4VisAttributes.hh"
48
49#include "G4UnitsTable.hh"
50
51// ********************************************************************
52// Constructor - sets member data and adds to logical Store,
53// voxel pointer for optimisation set to 0 by default.
54// Initialises daughter vector to 0 length.
55// ********************************************************************
56//
57G4LogicalVolume::G4LogicalVolume( G4VSolid* pSolid,
58 G4Material* pMaterial,
59 const G4String& name,
60 G4FieldManager* pFieldMgr,
61 G4VSensitiveDetector* pSDetector,
62 G4UserLimits* pULimits,
63 G4bool optimise )
64 : fDaughters(0,(G4VPhysicalVolume*)0), fFieldManager(pFieldMgr),
65 fVoxel(0), fOptimise(optimise), fRootRegion(false), fSmartless(2.),
66 fMass(0.), fVisAttributes(0), fRegion(0), fCutsCouple(0)
67{
68 SetSolid(pSolid);
69 SetMaterial(pMaterial);
70 SetName(name);
71 SetSensitiveDetector(pSDetector);
72 SetUserLimits(pULimits);
73 //
74 // Add to store
75 //
76 G4LogicalVolumeStore::Register(this);
77}
78
79// ********************************************************************
80// Fake default constructor - sets only member data and allocates memory
81// for usage restricted to object persistency.
82// ********************************************************************
83//
84G4LogicalVolume::G4LogicalVolume( __void__& )
85 : fDaughters(0,(G4VPhysicalVolume*)0), fFieldManager(0),
86 fMaterial(0), fName(""), fSensitiveDetector(0), fSolid(0), fUserLimits(0),
87 fVoxel(0), fOptimise(true), fRootRegion(false), fSmartless(2.),
88 fMass(0.), fVisAttributes(0), fRegion(0), fCutsCouple(0), fBiasWeight(0.)
89{
90 // Add to store
91 //
92 G4LogicalVolumeStore::Register(this);
93}
94
95// ********************************************************************
96// Destructor - Removes itself from solid Store
97// NOTE: Not virtual
98// ********************************************************************
99//
100G4LogicalVolume::~G4LogicalVolume()
101{
102 // Avoid de-registration of root region if treating the first world volume
103 //
104 if( (fRootRegion) && (this != (*G4LogicalVolumeStore::GetInstance())[0]) )
105 { fRegion->RemoveRootLogicalVolume(this); }
106
107 G4LogicalVolumeStore::DeRegister(this);
108}
109
110// ********************************************************************
111// SetFieldManager
112// ********************************************************************
113//
114void
115G4LogicalVolume::SetFieldManager(G4FieldManager* pNewFieldMgr,
116 G4bool forceAllDaughters)
117{
118 fFieldManager = pNewFieldMgr;
119
120 G4int NoDaughters = GetNoDaughters();
121 while ( (NoDaughters--)>0 )
122 {
123 G4LogicalVolume* DaughterLogVol;
124 DaughterLogVol = GetDaughter(NoDaughters)->GetLogicalVolume();
125 if ( forceAllDaughters || (DaughterLogVol->GetFieldManager() == 0) )
126 {
127 DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
128 }
129 }
130}
131
132
133// ********************************************************************
134// IsAncestor
135//
136// Finds out if the current logical volume is an ancestor of a given
137// physical volume
138// ********************************************************************
139//
140G4bool
141G4LogicalVolume::IsAncestor(const G4VPhysicalVolume* aVolume) const
142{
143 G4bool isDaughter = IsDaughter(aVolume);
144 if (!isDaughter)
145 {
146 for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
147 itDau != fDaughters.end(); itDau++)
148 {
149 isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
150 if (isDaughter) break;
151 }
152 }
153 return isDaughter;
154}
155
156// ********************************************************************
157// TotalVolumeEntities
158//
159// Returns the total number of physical volumes (replicated or placed)
160// in the tree represented by the current logical volume.
161// ********************************************************************
162//
163G4int G4LogicalVolume::TotalVolumeEntities() const
164{
165 static G4int vols = 0;
166
167 vols++;
168 for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
169 itDau != fDaughters.end(); itDau++)
170 {
171 G4VPhysicalVolume* physDaughter = (*itDau);
172 for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
173 {
174 physDaughter->GetLogicalVolume()->TotalVolumeEntities();
175 }
176 }
177 return vols;
178}
179
180// ********************************************************************
181// GetMass
182//
183// Returns the mass of the logical volume tree computed from the
184// estimated geometrical volume of each solid and material associated
185// to the logical volume and its daughters.
186// NOTE: the computation may require considerable amount of time,
187// depending from the complexity of the geometry tree.
188// The returned value is cached and can be used for successive
189// calls (default), unless recomputation is forced by providing
190// 'true' for the boolean argument in input. Computation should
191// be forced if the geometry setup has changed after the previous
192// call. By setting the 'propagate' boolean flag to 'false' the
193// method returns the mass of the present logical volume only
194// (subtracted for the volume occupied by the daughter volumes).
195// The extra argument 'parMaterial' is internally used to
196// consider cases of geometrical parameterisations by material.
197// ********************************************************************
198//
199G4double G4LogicalVolume::GetMass(G4bool forced,
200 G4bool propagate,
201 G4Material* parMaterial)
202{
203 // Return the cached non-zero value, if not forced
204 //
205 if ( (fMass) && (!forced) ) return fMass;
206
207 // Global density and computed mass associated to the logical
208 // volume without considering its daughters
209 //
210 G4Material* logMaterial = parMaterial ? parMaterial : fMaterial;
211 if (!logMaterial)
212 {
213 G4cerr << "ERROR - G4LogicalVolume::GetMass()" << G4endl
214 << " No material is associated to the logical volume: "
215 << fName << " ! Sorry, cannot compute the mass ..." << G4endl;
216 G4Exception("G4LogicalVolume::GetMass()", "InvalidSetup", FatalException,
217 "No material associated to the logical volume !");
218 }
219 if (!fSolid)
220 {
221 G4cerr << "ERROR - G4LogicalVolume::GetMass()" << G4endl
222 << " No solid is associated to the logical volume: "
223 << fName << " ! Sorry, cannot compute the mass ..." << G4endl;
224 G4Exception("G4LogicalVolume::GetMass()", "InvalidSetup", FatalException,
225 "No solid associated to the logical volume !");
226 }
227 G4double globalDensity = logMaterial->GetDensity();
228 fMass = fSolid->GetCubicVolume() * globalDensity;
229
230 // For each daughter in the tree, subtract the mass occupied
231 // and if required by the propagate flag, add the real daughter's
232 // one computed recursively
233
234 for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
235 itDau != fDaughters.end(); itDau++)
236 {
237 G4VPhysicalVolume* physDaughter = (*itDau);
238 G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
239 G4double subMass=0.;
240 G4VSolid* daughterSolid = 0;
241 G4Material* daughterMaterial = 0;
242
243 // Compute the mass to subtract and to add for each daughter
244 // considering its multiplicity (i.e. replicated or not) and
245 // eventually its parameterisation (by solid and/or by material)
246 //
247 for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
248 {
249 G4VPVParameterisation*
250 physParam = physDaughter->GetParameterisation();
251 if (physParam)
252 {
253 daughterSolid = physParam->ComputeSolid(i, physDaughter);
254 daughterSolid->ComputeDimensions(physParam, i, physDaughter);
255 daughterMaterial = physParam->ComputeMaterial(i, physDaughter);
256 }
257 else
258 {
259 daughterSolid = logDaughter->GetSolid();
260 daughterMaterial = logDaughter->GetMaterial();
261 }
262 subMass = daughterSolid->GetCubicVolume() * globalDensity;
263
264 // Subtract the daughter's portion for the mass and, if required,
265 // add the real daughter's mass computed recursively
266 //
267 fMass -= subMass;
268 if (propagate)
269 {
270 fMass += logDaughter->GetMass(true, true, daughterMaterial);
271 }
272 }
273 }
274
275 return fMass;
276}
277
278void G4LogicalVolume::SetVisAttributes (const G4VisAttributes& VA)
279{
280 fVisAttributes = new G4VisAttributes(VA);
281}
Note: See TracBrowser for help on using the repository browser.