G4LogicalVolume.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // class G4LogicalVolume Implementation
00031 //
00032 // History:
00033 // 01.03.05 G.Santin: Added flag for optional propagation of GetMass()
00034 // 17.05.02 G.Cosmo: Added flag for optional optimisation
00035 // 12.02.99 S.Giani: Default initialization of voxelization quality
00036 // 04.08.97 P.M.DeFreitas: Added methods for parameterised simulation 
00037 // 19.08.96 P.Kent: Modified for G4VSensitive Detector
00038 // 11.07.95 P.Kent: Initial version
00039 // --------------------------------------------------------------------
00040 
00041 #include "G4LogicalVolume.hh"
00042 #include "G4LogicalVolumeStore.hh"
00043 #include "G4VSolid.hh"
00044 #include "G4Material.hh"
00045 #include "G4VPVParameterisation.hh"
00046 #include "G4VisAttributes.hh"
00047 
00048 #include "G4UnitsTable.hh"
00049 
00050 // ********************************************************************
00051 // Constructor - sets member data and adds to logical Store,
00052 //               voxel pointer for optimisation set to 0 by default.
00053 //               Initialises daughter vector to 0 length.
00054 // ********************************************************************
00055 //
00056 G4LogicalVolume::G4LogicalVolume( G4VSolid* pSolid,
00057                                   G4Material* pMaterial,
00058                             const G4String& name,
00059                                   G4FieldManager* pFieldMgr,
00060                                   G4VSensitiveDetector* pSDetector,
00061                                   G4UserLimits* pULimits,
00062                                   G4bool optimise )
00063  : fDaughters(0,(G4VPhysicalVolume*)0), fFieldManager(pFieldMgr),
00064    fVoxel(0), fOptimise(optimise), fRootRegion(false), fLock(false),
00065    fSmartless(2.), fMass(0.), fVisAttributes(0), fRegion(0), fCutsCouple(0)
00066 {
00067   SetSolid(pSolid);
00068   SetMaterial(pMaterial);
00069   SetName(name);
00070   SetSensitiveDetector(pSDetector);
00071   SetUserLimits(pULimits);    
00072   //
00073   // Add to store
00074   //
00075   G4LogicalVolumeStore::Register(this);
00076 }
00077 
00078 // ********************************************************************
00079 // Fake default constructor - sets only member data and allocates memory
00080 //                            for usage restricted to object persistency.
00081 // ********************************************************************
00082 //
00083 G4LogicalVolume::G4LogicalVolume( __void__& )
00084  : fDaughters(0,(G4VPhysicalVolume*)0), fFieldManager(0),
00085    fMaterial(0), fName(""), fSensitiveDetector(0), fSolid(0), fUserLimits(0),
00086    fVoxel(0), fOptimise(true), fRootRegion(false), fLock(false), fSmartless(2.),
00087    fMass(0.), fVisAttributes(0), fRegion(0), fCutsCouple(0), fBiasWeight(0.)
00088 {
00089   // Add to store
00090   //
00091   G4LogicalVolumeStore::Register(this);
00092 }
00093 
00094 // ********************************************************************
00095 // Destructor - Removes itself from solid Store
00096 // NOTE: Not virtual
00097 // ********************************************************************
00098 //
00099 G4LogicalVolume::~G4LogicalVolume()
00100 {
00101   if (!fLock && fRootRegion)  // De-register root region first if not locked
00102   {                           // and flagged as root logical-volume
00103     fRegion->RemoveRootLogicalVolume(this, true);
00104   }
00105   G4LogicalVolumeStore::DeRegister(this);
00106 }
00107 
00108 // ********************************************************************
00109 // SetFieldManager
00110 // ********************************************************************
00111 //
00112 void
00113 G4LogicalVolume::SetFieldManager(G4FieldManager* pNewFieldMgr,
00114                                  G4bool          forceAllDaughters) 
00115 {
00116   fFieldManager = pNewFieldMgr;
00117 
00118   G4int NoDaughters = GetNoDaughters();
00119   while ( (NoDaughters--)>0 )
00120   {
00121     G4LogicalVolume* DaughterLogVol; 
00122     DaughterLogVol = GetDaughter(NoDaughters)->GetLogicalVolume();
00123     if ( forceAllDaughters || (DaughterLogVol->GetFieldManager() == 0) )
00124     {
00125       DaughterLogVol->SetFieldManager(pNewFieldMgr, forceAllDaughters);
00126     }
00127   }
00128 }
00129 
00130 
00131 // ********************************************************************
00132 // IsAncestor
00133 //
00134 // Finds out if the current logical volume is an ancestor of a given 
00135 // physical volume
00136 // ********************************************************************
00137 //
00138 G4bool
00139 G4LogicalVolume::IsAncestor(const G4VPhysicalVolume* aVolume) const
00140 {
00141   G4bool isDaughter = IsDaughter(aVolume);
00142   if (!isDaughter)
00143   {
00144     for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
00145          itDau != fDaughters.end(); itDau++)
00146     {
00147       isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
00148       if (isDaughter)  break;
00149     }
00150   }
00151   return isDaughter;
00152 }
00153 
00154 // ********************************************************************
00155 // TotalVolumeEntities
00156 //
00157 // Returns the total number of physical volumes (replicated or placed)
00158 // in the tree represented by the current logical volume.
00159 // ********************************************************************
00160 //
00161 G4int G4LogicalVolume::TotalVolumeEntities() const
00162 {
00163   G4int vols = 1;
00164   for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
00165        itDau != fDaughters.end(); itDau++)
00166   {
00167     G4VPhysicalVolume* physDaughter = (*itDau);
00168     vols += physDaughter->GetMultiplicity()
00169            *physDaughter->GetLogicalVolume()->TotalVolumeEntities();
00170   }
00171   return vols;
00172 }
00173 
00174 // ********************************************************************
00175 // GetMass
00176 //
00177 // Returns the mass of the logical volume tree computed from the
00178 // estimated geometrical volume of each solid and material associated
00179 // to the logical volume and its daughters.
00180 // NOTE: the computation may require considerable amount of time,
00181 //       depending from the complexity of the geometry tree.
00182 //       The returned value is cached and can be used for successive
00183 //       calls (default), unless recomputation is forced by providing
00184 //       'true' for the boolean argument in input. Computation should
00185 //       be forced if the geometry setup has changed after the previous
00186 //       call. By setting the 'propagate' boolean flag to 'false' the 
00187 //       method returns the mass of the present logical volume only 
00188 //       (subtracted for the volume occupied by the daughter volumes).
00189 //       The extra argument 'parMaterial' is internally used to
00190 //       consider cases of geometrical parameterisations by material.
00191 // ********************************************************************
00192 //
00193 G4double G4LogicalVolume::GetMass(G4bool forced,
00194                                   G4bool propagate,
00195                                   G4Material* parMaterial)
00196 {
00197   // Return the cached non-zero value, if not forced
00198   //
00199   if ( (fMass) && (!forced) ) return fMass;
00200 
00201   // Global density and computed mass associated to the logical
00202   // volume without considering its daughters
00203   //
00204   G4Material* logMaterial = parMaterial ? parMaterial : fMaterial;
00205   if (!logMaterial)
00206   {
00207     std::ostringstream message;
00208     message << "No material associated to the logical volume: " << fName << " !"
00209             << G4endl
00210             << "Sorry, cannot compute the mass ...";
00211     G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
00212                 FatalException, message);
00213     return 0;
00214   }
00215   if (!fSolid)
00216   {
00217     std::ostringstream message;
00218     message << "No solid is associated to the logical volume: " << fName << " !"
00219             << G4endl
00220             << "Sorry, cannot compute the mass ...";
00221     G4Exception("G4LogicalVolume::GetMass()", "GeomMgt0002",
00222                 FatalException, message);
00223     return 0;
00224   }
00225   G4double globalDensity = logMaterial->GetDensity();
00226   fMass = fSolid->GetCubicVolume() * globalDensity;
00227 
00228   // For each daughter in the tree, subtract the mass occupied
00229   // and if required by the propagate flag, add the real daughter's
00230   // one computed recursively
00231 
00232   for (G4PhysicalVolumeList::const_iterator itDau = fDaughters.begin();
00233        itDau != fDaughters.end(); itDau++)
00234   {
00235     G4VPhysicalVolume* physDaughter = (*itDau);
00236     G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
00237     G4double subMass=0.;
00238     G4VSolid* daughterSolid = 0;
00239     G4Material* daughterMaterial = 0;
00240 
00241     // Compute the mass to subtract and to add for each daughter
00242     // considering its multiplicity (i.e. replicated or not) and
00243     // eventually its parameterisation (by solid and/or by material)
00244     //
00245     for (G4int i=0; i<physDaughter->GetMultiplicity(); i++)
00246     {
00247       G4VPVParameterisation*
00248         physParam = physDaughter->GetParameterisation();
00249       if (physParam)
00250       {
00251         daughterSolid = physParam->ComputeSolid(i, physDaughter);
00252         daughterSolid->ComputeDimensions(physParam, i, physDaughter);
00253         daughterMaterial = physParam->ComputeMaterial(i, physDaughter);
00254       }
00255       else
00256       {
00257         daughterSolid = logDaughter->GetSolid();
00258         daughterMaterial = logDaughter->GetMaterial();
00259       }
00260       subMass = daughterSolid->GetCubicVolume() * globalDensity;
00261 
00262       // Subtract the daughter's portion for the mass and, if required,
00263       // add the real daughter's mass computed recursively
00264       //
00265       fMass -= subMass;
00266       if (propagate)
00267       {
00268         fMass += logDaughter->GetMass(true, true, daughterMaterial);
00269       }
00270     }
00271   }
00272 
00273   return fMass;
00274 }
00275 
00276 void G4LogicalVolume::SetVisAttributes (const G4VisAttributes& VA)
00277 {
00278   fVisAttributes = new G4VisAttributes(VA);
00279 }

Generated on Mon May 27 17:48:49 2013 for Geant4 by  doxygen 1.4.7