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

Last change on this file since 1198 was 1058, checked in by garnier, 15 years ago

file release beta

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.33 2008/07/10 09:40:09 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-02-ref-02 $
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), fLock(false),
66   fSmartless(2.), 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), fLock(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  if (!fLock && fRootRegion)  // De-register root region first if not locked
103  {                           // and flagged as root logical-volume
104    fRegion->RemoveRootLogicalVolume(this, true);
105  }
106  G4LogicalVolumeStore::DeRegister(this);
107}
108
109// ********************************************************************
110// SetFieldManager
111// ********************************************************************
112//
113void
114G4LogicalVolume::SetFieldManager(G4FieldManager* pNewFieldMgr,
115                                 G4bool          forceAllDaughters) 
116{
117  fFieldManager = pNewFieldMgr;
118
119  G4int NoDaughters = GetNoDaughters();
120  while ( (NoDaughters--)>0 )
121  {
122    G4LogicalVolume* DaughterLogVol; 
123    DaughterLogVol = GetDaughter(NoDaughters)->GetLogicalVolume();
124    if ( forceAllDaughters || (DaughterLogVol->GetFieldManager() == 0) )
125    {
126      DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
127    }
128  }
129}
130
131
132// ********************************************************************
133// IsAncestor
134//
135// Finds out if the current logical volume is an ancestor of a given
136// physical volume
137// ********************************************************************
138//
139G4bool
140G4LogicalVolume::IsAncestor(const G4VPhysicalVolume* aVolume) const
141{
142  G4bool isDaughter = IsDaughter(aVolume);
143  if (!isDaughter)
144  {
145    for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
146         itDau != fDaughters.end(); itDau++)
147    {
148      isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
149      if (isDaughter)  break;
150    }
151  }
152  return isDaughter;
153}
154
155// ********************************************************************
156// TotalVolumeEntities
157//
158// Returns the total number of physical volumes (replicated or placed)
159// in the tree represented by the current logical volume.
160// ********************************************************************
161//
162G4int G4LogicalVolume::TotalVolumeEntities() const
163{
164  static G4int vols = 0;
165
166  vols++;
167  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
168       itDau != fDaughters.end(); itDau++)
169  {
170    G4VPhysicalVolume* physDaughter = (*itDau);
171    for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
172    {
173      physDaughter->GetLogicalVolume()->TotalVolumeEntities();
174    }
175  }
176  return vols;
177}
178
179// ********************************************************************
180// GetMass
181//
182// Returns the mass of the logical volume tree computed from the
183// estimated geometrical volume of each solid and material associated
184// to the logical volume and its daughters.
185// NOTE: the computation may require considerable amount of time,
186//       depending from the complexity of the geometry tree.
187//       The returned value is cached and can be used for successive
188//       calls (default), unless recomputation is forced by providing
189//       'true' for the boolean argument in input. Computation should
190//       be forced if the geometry setup has changed after the previous
191//       call. By setting the 'propagate' boolean flag to 'false' the
192//       method returns the mass of the present logical volume only
193//       (subtracted for the volume occupied by the daughter volumes).
194//       The extra argument 'parMaterial' is internally used to
195//       consider cases of geometrical parameterisations by material.
196// ********************************************************************
197//
198G4double G4LogicalVolume::GetMass(G4bool forced,
199                                  G4bool propagate,
200                                  G4Material* parMaterial)
201{
202  // Return the cached non-zero value, if not forced
203  //
204  if ( (fMass) && (!forced) ) return fMass;
205
206  // Global density and computed mass associated to the logical
207  // volume without considering its daughters
208  //
209  G4Material* logMaterial = parMaterial ? parMaterial : fMaterial;
210  if (!logMaterial)
211  {
212    G4cerr << "ERROR - G4LogicalVolume::GetMass()" << G4endl
213           << "        No material is associated to the logical volume: "
214           << fName << " !  Sorry, cannot compute the mass ..." << G4endl;
215    G4Exception("G4LogicalVolume::GetMass()", "InvalidSetup", FatalException,
216                "No material associated to the logical volume !");
217  }
218  if (!fSolid)
219  {
220    G4cerr << "ERROR - G4LogicalVolume::GetMass()" << G4endl
221           << "        No solid is associated to the logical volume: "
222           << fName << " !  Sorry, cannot compute the mass ..." << G4endl;
223    G4Exception("G4LogicalVolume::GetMass()", "InvalidSetup", FatalException,
224                "No solid associated to the logical volume !");
225  }
226  G4double globalDensity = logMaterial->GetDensity();
227  fMass = fSolid->GetCubicVolume() * globalDensity;
228
229  // For each daughter in the tree, subtract the mass occupied
230  // and if required by the propagate flag, add the real daughter's
231  // one computed recursively
232
233  for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
234       itDau != fDaughters.end(); itDau++)
235  {
236    G4VPhysicalVolume* physDaughter = (*itDau);
237    G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
238    G4double subMass=0.;
239    G4VSolid* daughterSolid = 0;
240    G4Material* daughterMaterial = 0;
241
242    // Compute the mass to subtract and to add for each daughter
243    // considering its multiplicity (i.e. replicated or not) and
244    // eventually its parameterisation (by solid and/or by material)
245    //
246    for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
247    {
248      G4VPVParameterisation*
249        physParam = physDaughter->GetParameterisation();
250      if (physParam)
251      {
252        daughterSolid = physParam->ComputeSolid(i, physDaughter);
253        daughterSolid->ComputeDimensions(physParam, i, physDaughter);
254        daughterMaterial = physParam->ComputeMaterial(i, physDaughter);
255      }
256      else
257      {
258        daughterSolid = logDaughter->GetSolid();
259        daughterMaterial = logDaughter->GetMaterial();
260      }
261      subMass = daughterSolid->GetCubicVolume() * globalDensity;
262
263      // Subtract the daughter's portion for the mass and, if required,
264      // add the real daughter's mass computed recursively
265      //
266      fMass -= subMass;
267      if (propagate)
268      {
269        fMass += logDaughter->GetMass(true, true, daughterMaterial);
270      }
271    }
272  }
273
274  return fMass;
275}
276
277void G4LogicalVolume::SetVisAttributes (const G4VisAttributes& VA)
278{
279  fVisAttributes = new G4VisAttributes(VA);
280}
Note: See TracBrowser for help on using the repository browser.