2 // ********************************************************************
 
    3 // * License and Disclaimer                                           *
 
    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.                             *
 
   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.         *
 
   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 // ********************************************************************
 
   27 // $Id: G4LogicalVolume.icc 78050 2013-12-03 08:17:33Z gcosmo $
 
   30 // class G4LogicalVolume Inline Implementation file
 
   32 // 15.01.13 - G.Cosmo, A.Dotti: Modified for thread-safety for MT
 
   33 // 10.20.97 - P. MoraDeFreitas : Added SetFastSimulation method
 
   34 // 05.11.98 - M. Verderi: Add Get/Set methods for fBiasWeight
 
   35 // 09.11.98 - J. Apostolakis:  Changed MagneticField to FieldManager
 
   36 // 12.02.99 - S.Giani: Added set/get methods for voxelization quality
 
   37 // 18.04.01 - G.Cosmo: Migrated to STL vector
 
   38 // 17.05.02 - G.Cosmo: Added IsToOptimise() method
 
   39 // --------------------------------------------------------------------
 
   42 // These macros change the references to fields that are now encapsulated
 
   43 // in the class G4LVData.
 
   45 #define G4MT_solid     ((subInstanceManager.offset[instanceID]).fSolid)
 
   46 #define G4MT_sdetector ((subInstanceManager.offset[instanceID]).fSensitiveDetector)
 
   47 #define G4MT_fmanager  ((subInstanceManager.offset[instanceID]).fFieldManager)
 
   48 #define G4MT_material  ((subInstanceManager.offset[instanceID]).fMaterial)
 
   49 #define G4MT_mass      ((subInstanceManager.offset[instanceID]).fMass)
 
   50 #define G4MT_ccouple   ((subInstanceManager.offset[instanceID]).fCutsCouple)
 
   51 #define G4MT_instance  (subInstanceManager.offset[instanceID])
 
   53 #include "G4Threading.hh"
 
   54 // ********************************************************************
 
   56 // ********************************************************************
 
   59 G4String G4LogicalVolume::GetName() const
 
   64 // ********************************************************************
 
   66 // ********************************************************************
 
   69 void G4LogicalVolume::SetName(const G4String& pName)
 
   74 // ********************************************************************
 
   76 // ********************************************************************
 
   79 G4int G4LogicalVolume::GetInstanceID() const
 
   84 // ********************************************************************
 
   86 // ********************************************************************
 
   89 G4FieldManager* G4LogicalVolume::GetFieldManager() const
 
   94 inline void G4LogicalVolume::AssignFieldManager( G4FieldManager *fldMgr)
 
   96   G4MT_fmanager= fldMgr;
 
   97   if(!G4Threading::IsWorkerThread()) fFieldManager = fldMgr;
 
  101 // ********************************************************************
 
  102 // GetMasterFieldManager
 
  103 // ********************************************************************
 
  106 G4FieldManager* G4LogicalVolume::GetMasterFieldManager() const
 
  108   return fFieldManager;
 
  111 // ********************************************************************
 
  113 // ********************************************************************
 
  116 G4int G4LogicalVolume::GetNoDaughters() const
 
  118   return fDaughters.size();
 
  121 // ********************************************************************
 
  123 // ********************************************************************
 
  126 G4VPhysicalVolume* G4LogicalVolume::GetDaughter(const G4int i) const
 
  128   return fDaughters[i];
 
  131 // ********************************************************************
 
  132 // GetFastSimulationManager
 
  133 // ********************************************************************
 
  136 G4FastSimulationManager* G4LogicalVolume::GetFastSimulationManager () const 
 
  138   G4FastSimulationManager* fFSM = 0;
 
  139   if(fRegion) fFSM = fRegion->GetFastSimulationManager();
 
  143 // ********************************************************************
 
  145 // ********************************************************************
 
  148 void G4LogicalVolume::AddDaughter(G4VPhysicalVolume* pNewDaughter)
 
  150   if( !fDaughters.empty() && fDaughters[0]->IsReplicated() )
 
  152     std::ostringstream message;
 
  153     message << "ERROR - Attempt to place a volume in a mother volume" << G4endl
 
  154             << "        already containing a replicated volume." << G4endl
 
  155             << "        A volume can either contain several placements" << G4endl
 
  156             << "        or a unique replica or parameterised volume !" << G4endl
 
  157             << "           Mother logical volume: " << GetName() << G4endl
 
  158             << "           Placing volume: " << pNewDaughter->GetName() << G4endl;
 
  159     G4Exception("G4LogicalVolume::AddDaughter()", "GeomMgt0002",
 
  160                 FatalException, message,
 
  161                 "Replica or parameterised volume must be the only daughter !");
 
  164   // Invalidate previous calculation of mass - if any - for all threads
 
  166   // SignalVolumeChange();  // fVolumeChanged= true;
 
  167   fDaughters.push_back(pNewDaughter);
 
  169   G4LogicalVolume* pDaughterLogical = pNewDaughter->GetLogicalVolume();
 
  171   // Propagate the Field Manager, if the daughter has no field Manager.
 
  173   G4FieldManager* pDaughterFieldManager = pDaughterLogical->GetFieldManager();
 
  175   if( pDaughterFieldManager == 0 )
 
  177     pDaughterLogical->SetFieldManager(G4MT_fmanager, false);
 
  182     fRegion->RegionModified(true);
 
  186 // ********************************************************************
 
  188 // ********************************************************************
 
  191 G4bool G4LogicalVolume::IsDaughter(const G4VPhysicalVolume* p) const
 
  193   G4PhysicalVolumeList::const_iterator i;
 
  194   for ( i=fDaughters.begin(); i!=fDaughters.end(); ++i )
 
  196     if (**i==*p) return true;
 
  201 // ********************************************************************
 
  203 // ********************************************************************
 
  206 void G4LogicalVolume::RemoveDaughter(const G4VPhysicalVolume* p)
 
  208   G4PhysicalVolumeList::iterator i;
 
  209   for ( i=fDaughters.begin(); i!=fDaughters.end(); ++i )
 
  219     fRegion->RegionModified(true);
 
  224 // ********************************************************************
 
  226 // ********************************************************************
 
  229 void G4LogicalVolume::ClearDaughters()
 
  231   G4PhysicalVolumeList::iterator i;
 
  232   for ( i=fDaughters.begin(); i!=fDaughters.end(); ++i )
 
  238     fRegion->RegionModified(true);
 
  243 // ********************************************************************
 
  244 // CharacteriseDaughters
 
  245 // ********************************************************************
 
  248 EVolume G4LogicalVolume::CharacteriseDaughters() const
 
  251   G4VPhysicalVolume *pVol;
 
  253   if ( GetNoDaughters()==1 )
 
  255     pVol = GetDaughter(0);
 
  256     type = pVol->VolumeType();
 
  266 void G4LogicalVolume::ResetMass()
 
  269   // Do not fChangedState= 1; 
 
  272 // ********************************************************************
 
  274 // ********************************************************************
 
  277 G4VSolid* G4LogicalVolume::GetSolid(G4LVData &instLVdata) // const
 
  279   return instLVdata.fSolid;
 
  283 G4VSolid* G4LogicalVolume::GetSolid() const
 
  285   // return G4MT_solid;
 
  286   // return ((subInstanceManager.offset[instanceID]).fSolid);
 
  287   return this->GetSolid( subInstanceManager.offset[instanceID] ); 
 
  290 // ********************************************************************
 
  292 // ********************************************************************
 
  295 G4VSolid* G4LogicalVolume::GetMasterSolid() const
 
  300 // ********************************************************************
 
  302 // ********************************************************************
 
  305 void G4LogicalVolume::SetSolid(G4VSolid *pSolid)
 
  308   // ((subInstanceManager.offset[instanceID]).fSolid) = pSolid;
 
  315 void G4LogicalVolume::SetSolid(G4LVData &instLVdata, G4VSolid *pSolid)
 
  317   instLVdata.fSolid = pSolid;
 
  318   // G4MT_solid=pSolid;
 
  320   // A fast way to reset the mass ... ie G4MT_mass = 0.;
 
  323 // ********************************************************************
 
  325 // ********************************************************************
 
  328 G4Material* G4LogicalVolume::GetMaterial() const
 
  330   return G4MT_material;
 
  333 // ********************************************************************
 
  335 // ********************************************************************
 
  338 void G4LogicalVolume::SetMaterial(G4Material *pMaterial)
 
  340   G4MT_material=pMaterial;
 
  344 // ********************************************************************
 
  346 // ********************************************************************
 
  349 void G4LogicalVolume::UpdateMaterial(G4Material *pMaterial)
 
  351   G4MT_material=pMaterial;
 
  352   if(fRegion) { G4MT_ccouple = fRegion->FindCouple(pMaterial); }
 
  356 // ********************************************************************
 
  357 // GetSensitiveDetector
 
  358 // ********************************************************************
 
  361 G4VSensitiveDetector* G4LogicalVolume::GetSensitiveDetector() const
 
  363   return G4MT_sdetector;
 
  366 // ********************************************************************
 
  367 // GetMasterSensitiveDetector
 
  368 // ********************************************************************
 
  371 G4VSensitiveDetector* G4LogicalVolume::GetMasterSensitiveDetector() const
 
  373   return fSensitiveDetector;
 
  376 // ********************************************************************
 
  377 // SetSensitiveDetector
 
  378 // ********************************************************************
 
  381 void G4LogicalVolume::SetSensitiveDetector(G4VSensitiveDetector* pSDetector)
 
  383   G4MT_sdetector = pSDetector;
 
  384   if(!G4Threading::IsWorkerThread()) fSensitiveDetector = pSDetector;
 
  387 // ********************************************************************
 
  389 // ********************************************************************
 
  392 G4UserLimits* G4LogicalVolume::GetUserLimits() const
 
  394   if(fUserLimits) return fUserLimits;
 
  395   if(fRegion) return fRegion->GetUserLimits();
 
  399 // ********************************************************************
 
  401 // ********************************************************************
 
  404 void G4LogicalVolume::SetUserLimits(G4UserLimits* pULimits)
 
  406   fUserLimits = pULimits;
 
  409 // ********************************************************************
 
  411 // ********************************************************************
 
  414 G4SmartVoxelHeader* G4LogicalVolume::GetVoxelHeader() const
 
  419 // ********************************************************************
 
  421 // ********************************************************************
 
  424 void G4LogicalVolume::SetVoxelHeader(G4SmartVoxelHeader* pVoxel)
 
  429 // ********************************************************************
 
  431 // ********************************************************************
 
  434 G4double G4LogicalVolume::GetSmartless() const
 
  439 // ********************************************************************
 
  441 // ********************************************************************
 
  444 void G4LogicalVolume::SetSmartless(G4double smt)
 
  449 // ********************************************************************
 
  451 // ********************************************************************
 
  454 G4bool G4LogicalVolume::IsToOptimise() const
 
  459 // ********************************************************************
 
  461 // ********************************************************************
 
  464 void G4LogicalVolume::SetOptimisation(G4bool optim)
 
  469 // ********************************************************************
 
  471 // ********************************************************************
 
  474 G4bool G4LogicalVolume::IsRootRegion() const
 
  479 // ********************************************************************
 
  481 // ********************************************************************
 
  484 void G4LogicalVolume::SetRegionRootFlag(G4bool rreg)
 
  489 // ********************************************************************
 
  491 // ********************************************************************
 
  494 G4bool G4LogicalVolume::IsRegion() const
 
  497   if (fRegion) reg = true;
 
  501 // ********************************************************************
 
  503 // ********************************************************************
 
  506 void G4LogicalVolume::SetRegion(G4Region* reg)
 
  511 // ********************************************************************
 
  513 // ********************************************************************
 
  516 G4Region* G4LogicalVolume::GetRegion() const
 
  521 // ********************************************************************
 
  523 // ********************************************************************
 
  526 void G4LogicalVolume::PropagateRegion()
 
  528   fRegion->ScanVolumeTree(this, true);
 
  531 // ********************************************************************
 
  532 // GetMaterialCutsCouple
 
  533 // ********************************************************************
 
  536 const G4MaterialCutsCouple* G4LogicalVolume::GetMaterialCutsCouple() const
 
  541 // ********************************************************************
 
  542 // SetMaterialCutsCouple
 
  543 // ********************************************************************
 
  546 void G4LogicalVolume::SetMaterialCutsCouple(G4MaterialCutsCouple* cuts)
 
  551 // ********************************************************************
 
  553 // ********************************************************************
 
  556 void G4LogicalVolume::Lock()
 
  561 // ********************************************************************
 
  563 // ********************************************************************
 
  566 G4bool G4LogicalVolume::operator == ( const G4LogicalVolume& lv) const
 
  568   return (this==&lv) ? true : false;
 
  571 // ********************************************************************
 
  573 // ********************************************************************
 
  576 const G4VisAttributes* G4LogicalVolume::GetVisAttributes () const
 
  578   return fVisAttributes;
 
  581 // ********************************************************************
 
  583 // ********************************************************************
 
  586 void G4LogicalVolume::SetVisAttributes (const G4VisAttributes* pVA)
 
  588   fVisAttributes = pVA;
 
  591 // ********************************************************************
 
  593 // ********************************************************************
 
  596 void G4LogicalVolume::SetBiasWeight(G4double weight)
 
  598   fBiasWeight = weight;
 
  601 // ********************************************************************
 
  603 // ********************************************************************
 
  606 G4double G4LogicalVolume::GetBiasWeight() const
 
  611 #undef G4MT_sdetector
 
  615 // #undef G4MT_ccouple