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