Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-21 09:10:39

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4LogicalVolume
0027 //
0028 // Class description:
0029 //
0030 // Represents a leaf node or unpositioned subtree in the geometry hierarchy.
0031 // Logical volumes are named, and may have daughters ascribed to them.
0032 // They are responsible for retrieval of the physical and tracking attributes
0033 // of the physical volume that it represents: solid, material, magnetic field,
0034 // and optionally, user limits, sensitive detectors, regions, biasing weights.
0035 //
0036 // Get and Set functionality is provided for all attributes, but note that
0037 // most set functions should not be used  when the geometry is `closed'.
0038 // As a  further development, `Guard' checks can be added to ensure
0039 // only legal operations at tracking time.
0040 //
0041 // On construction, solid, material and name must be specified.
0042 //
0043 // Daughters are ascribed and managed by means of a simple
0044 // GetNoDaughters,Get/SetDaughter(n),AddDaughter interface.
0045 //
0046 // Smart voxels as used for tracking optimisation. They're also an attribute.
0047 //
0048 // Logical volumes self register to the logical volume Store on construction,
0049 // and deregister on destruction.
0050 //
0051 // NOTE: This class is NOT meant to act as base class, except for exceptional
0052 //       circumstances of extended types used in the kernel.
0053 //
0054 // Data members:
0055 //
0056 //    std::vector<G4VPhysicalVolume*> fDaughters
0057 //    - Vector of daughters. Given initial size of 0.
0058 //    G4FieldManager* fFieldManager
0059 //    - Pointer (possibly 0) to (magnetic or other) field manager object.
0060 //    G4Material* fMaterial
0061 //    - Pointer to material at this node.
0062 //    G4String fName
0063 //    - Name of logical volume.
0064 //    G4VSensitiveDetector *fSensitiveDetector
0065 //    - Pointer (possibly 0) to `Hit' object.
0066 //    G4VSolid* fSolid
0067 //    - Pointer to solid.
0068 //    G4UserLimits* fUserLimits
0069 //    - Pointer (possibly 0) to user Step limit object for this node.
0070 //    G4SmartVoxelHeader* fVoxel
0071 //    - Pointer (possibly 0) to optimisation info objects.
0072 //    G4bool fOptimise
0073 //    - Flag to identify if optimisation should be applied or not.
0074 //    G4bool fRootRegion
0075 //    - Flag to identify if the logical volume is a root region.
0076 //    G4double fSmartless
0077 //    - Quality for optimisation, average number of voxels to be spent
0078 //      per content.
0079 //    const G4VisAttributes* fVisAttributes
0080 //    - Pointer (possibly 0) to visualization attributes.
0081 //    G4Region* fRegion
0082 //    - Pointer to the cuts region (if any)
0083 //    G4MaterialCutsCouple* fCutsCouple
0084 //    - Pointer (possibly 0) to associated production cuts.
0085 //    G4double fBiasWeight
0086 //    - Weight used in the event biasing technique.
0087 //
0088 // Following data members has been moved to G4Region - M.Asai (Aug/18/2005)
0089 //    G4FastSimulationManager* fFastSimulationManager
0090 //    - Pointer (possibly 0) to G4FastSimulationManager object.
0091 //    G4bool fIsEnvelope
0092 //    - Flags if the Logical Volume is an envelope for a FastSimulationManager.
0093 
0094 // Author: Paul Kent (CERN), 11.07.1995 - Initial version
0095 // ------------------------------------------------------------------------
0096 #ifndef G4LOGICALVOLUME_HH
0097 #define G4LOGICALVOLUME_HH
0098 
0099 #include <vector>
0100 #include <memory>
0101 
0102 #include "G4Types.hh"
0103 #include "G4Region.hh"           // Required by inline methods
0104 #include "G4VPhysicalVolume.hh"  // Need operator == for vector fdaughters
0105 #include "G4GeomSplitter.hh"     // Needed for MT RW data splitting
0106 #include "G4Threading.hh"
0107 
0108 // Forward declarations
0109 //
0110 class G4FieldManager;
0111 class G4Material;
0112 class G4VSensitiveDetector;
0113 class G4VSolid;
0114 class G4UserLimits;
0115 class G4SmartVoxelHeader;
0116 class G4FastSimulationManager;
0117 class G4MaterialCutsCouple;
0118 class G4VisAttributes;
0119 
0120 /**
0121  * @brief G4LVData encapsulates the fields associated to the class
0122  * G4LogicalVolume that may not be read-only. 
0123  */
0124 
0125 class G4LVData
0126 {
0127   public:
0128 
0129     G4LVData();
0130     void initialize()
0131     {
0132       fSolid = nullptr;
0133       fSensitiveDetector = nullptr;
0134       fFieldManager = nullptr;
0135       fMaterial = nullptr;
0136       fMass = 0.0;
0137       fCutsCouple = nullptr;
0138     }
0139 
0140   public:
0141 
0142     G4VSolid* fSolid = nullptr;
0143       // Pointer to solid.
0144     G4VSensitiveDetector* fSensitiveDetector = nullptr;
0145       // Pointer to sensitive detector.
0146     G4FieldManager* fFieldManager = nullptr;
0147       // Pointer (possibly nullptr) to (magnetic or other) field manager object.
0148     G4Material* fMaterial = nullptr;
0149       // Pointer to material at this node.
0150     G4double fMass = 0.0;
0151       // Mass of the logical volume tree.
0152     G4MaterialCutsCouple* fCutsCouple = nullptr;
0153       // Pointer (possibly nullptr) to associated production cuts.
0154 };
0155 
0156 /** G4LVManager encapsulates the methods used by both the master thread and
0157     worker threads to allocate memory space for the fields encapsulated by the
0158     class G4LVData. */
0159 using G4LVManager = G4GeomSplitter<G4LVData>;
0160 
0161 /**
0162  * @brief G4LogicalVolume represents a leaf node or unpositioned subtree in the
0163  * geometry hierarchy. Logical volumes are named, and may have daughters
0164  * ascribed to them. They are responsible for retrieval of the physical and
0165  * tracking attributes of the physical volume that it represents: solid,
0166  * material, magnetic field, and optionally, user limits, sensitive detectors,
0167  * regions, biasing weights.
0168  */
0169 
0170 class G4LogicalVolume
0171 {
0172   public:
0173     
0174     /**
0175      * Constructor for G4LogicalVolume. The solid and material pointer must be
0176      * non null. The parameters for field, detector and user limits are optional.
0177      * The volume also enters itself into the logical volume Store.
0178      * Optimisation of the geometry (voxelisation) for the volume hierarchy is
0179      * applied by default. For parameterised volumes in the hierarchy,
0180      * optimisation is -always- applied.
0181      *  @param[in] pSolid Pointer to the associated solid primitive.
0182      *  @param[in] pMaterial Pointer to the associated material.
0183      *  @param[in] name The volume name.
0184      *  @param[in] pFieldMgr Pointer to optional magnetic field manager.
0185      *  @param[in] pSDetector Pointer to optional associated sensitive detector.
0186      *  @param[in] pULimits Pointer to optional user limits.
0187      *  @param[in] optimise Flag to enable/disable optimisation structure.
0188      */
0189     G4LogicalVolume(G4VSolid* pSolid,
0190                     G4Material* pMaterial,
0191               const G4String& name,
0192                     G4FieldManager* pFieldMgr = nullptr,
0193                     G4VSensitiveDetector* pSDetector = nullptr,
0194                     G4UserLimits* pULimits = nullptr,
0195                     G4bool optimise = true);
0196 
0197     /**
0198      * Destructor. Removes the logical volume from the logical volume Store.
0199      * This class is NOT meant to act as base class, except for exceptional
0200      * circumstances of extended types used in the kernel.
0201      */
0202     virtual ~G4LogicalVolume();
0203 
0204     /**
0205      * Copy-constructor and assignment operator not allowed.
0206      */
0207     G4LogicalVolume(const G4LogicalVolume&) = delete;
0208     G4LogicalVolume& operator=(const G4LogicalVolume&) = delete;
0209 
0210     /**
0211      * Returns and sets the name of the logical volume.
0212      */
0213     inline const G4String& GetName() const;
0214     void SetName(const G4String& pName);
0215 
0216     /**
0217      * Returns the number of daughters (0 to n).
0218      */
0219     inline std::size_t GetNoDaughters() const;
0220 
0221     /**
0222      * Returns the ith daughter. Note numbering starts from 0,
0223      * and no bounds checking is performed.
0224      */
0225     inline G4VPhysicalVolume* GetDaughter(const std::size_t i) const;
0226 
0227     /**
0228      * Adds the volume 'p' as a daughter of the current logical volume.
0229      */
0230     void AddDaughter(G4VPhysicalVolume* p);
0231 
0232     /**
0233      * Returns true if the volume 'p' is a daughter of the current
0234      * logical volume.
0235      */
0236     inline G4bool IsDaughter(const G4VPhysicalVolume* p) const;
0237 
0238     /**
0239      * Returns true if the volume 'p' is part of the hierarchy of volumes
0240      * established by the current logical volume. Scans recursively the volume
0241      * tree.
0242      */
0243     G4bool IsAncestor(const G4VPhysicalVolume* p) const;
0244 
0245     /**
0246      * Removes the volume 'p' from the list of daughters of the current
0247      * logical volume.
0248      */
0249     void RemoveDaughter(const G4VPhysicalVolume* p);
0250 
0251     /**
0252      * Clears the list of daughters. Used by the physical volume store when
0253      * the geometry tree is cleared, since modified at run-time.
0254      */
0255     void ClearDaughters();
0256 
0257     /**
0258      * Returns the total number of physical volumes (replicated or placed)
0259      * in the tree represented by the current logical volume.
0260      */
0261     G4int TotalVolumeEntities() const;
0262 
0263     /**
0264      * Characterises the daughters of this logical volume.
0265      */
0266     inline EVolume CharacteriseDaughters() const;
0267 
0268     /**
0269      * Utility method used by CharacteriseDaughters().
0270      */
0271     inline EVolume DeduceDaughtersType() const;
0272    
0273     /**
0274      * Gets and sets the current solid.
0275      */
0276     G4VSolid* GetSolid() const;
0277     void SetSolid(G4VSolid* pSolid);
0278 
0279     /**
0280      * Gets and sets the current material.
0281      */
0282     G4Material* GetMaterial() const;
0283     void SetMaterial(G4Material* pMaterial);
0284 
0285     /**
0286      * Sets the material and corresponding Material-Cuts-Couple.
0287      * This method is invoked by G4Navigator while it is navigating through 
0288      * material parameterisation.
0289      */
0290     void UpdateMaterial(G4Material* pMaterial);
0291 
0292     /**
0293      * Returns the mass of the logical volume tree computed from the
0294      * estimated geometrical volume of each solid and material associated
0295      * to the logical volume and (by default) to its daughters.
0296      *  @note The computation may require a considerable amount of time,
0297      *        depending from the complexity of the geometry tree.
0298      *        The returned value is cached and can be used for successive
0299      *        calls (default), unless recomputation is forced by providing
0300      *        'true' for the Boolean argument in input. Computation should
0301      *        be forced if the geometry setup has changed after the previous
0302      *        call. By setting the 'propagate' Boolean flag to 'false' the 
0303      *        method returns the mass of the present logical volume only 
0304      *        (subtracted for the volume occupied by the daughter volumes).
0305      *        An optional argument to specify a material is also provided.
0306      *  @param[in] forced Flag to force recomputation or use cached value.
0307      *  @param[in] propagate Flag to limit or not computation to daughters.
0308      *  @param[in] parMaterial Optional pointer to a custom material, usually
0309      *             used in parameterisations.
0310      */
0311     G4double GetMass(G4bool forced = false, G4bool propagate = true,
0312                      G4Material* parMaterial = nullptr);
0313 
0314     /**
0315      * Resets the cached value of mass. Ensures that cached value of mass is
0316      * invalidated due to change in  state, e.g. change of the size of the
0317      * solid, change of the type of solid, or the addition/deletion of a
0318      * daughter volume.
0319      */
0320     void ResetMass(); 
0321  
0322     /**
0323      * Gets current Field Manager pointer.
0324      */
0325     G4FieldManager* GetFieldManager() const;
0326 
0327     /**
0328      * Sets the Field Manager and propagates it.
0329      *  @param[in] pFieldMgr Pointer to the field manager.
0330      *  @param[in] forceToAllDaughters Flag to force propagation to all
0331      *             daughters (true), or only to daughters having null pointer
0332      *             to the field manager (false).
0333      */
0334     void SetFieldManager(G4FieldManager* pFieldMgr, G4bool forceToAllDaughters); 
0335  
0336     /**
0337      * Gets and sets the current sensitive detector (can be a null pointer).
0338      */
0339     G4VSensitiveDetector* GetSensitiveDetector() const;
0340     void SetSensitiveDetector(G4VSensitiveDetector* pSDetector);
0341 
0342     /**
0343      * Gets and sets the current User Limits.
0344      */
0345     inline G4UserLimits* GetUserLimits() const;
0346     inline void SetUserLimits(G4UserLimits *pULimits);
0347 
0348     /**
0349      * Gets and sets the current Voxel Header.
0350      */
0351     inline G4SmartVoxelHeader* GetVoxelHeader() const;
0352     inline void SetVoxelHeader(G4SmartVoxelHeader *pVoxel);
0353     
0354     /**
0355      * Gets and sets the user defined optimisation quality associated to
0356      * the volume.
0357      */
0358     inline G4double GetSmartless() const;
0359     inline void SetSmartless(G4double s);
0360 
0361     /**
0362      * Replies if the geometry optimisation (voxelisation) is to be applied
0363      * for this volume hierarchy.
0364      */
0365     inline G4bool IsToOptimise() const;
0366 
0367     /**
0368      * Specifies if to apply or not geometry optimisation to the volume
0369      * hierarchy. For parameterised volumes in the hierarchy, optimisation is
0370      * always applied.
0371      */
0372     inline void SetOptimisation(G4bool optim);
0373 
0374     /**
0375      * Replies if the logical volume represents a root region or not.
0376      */
0377     inline G4bool IsRootRegion() const;
0378 
0379     /**
0380      * Sets/unsets the volume as a root region for cuts.
0381      */
0382     inline void SetRegionRootFlag(G4bool rreg);
0383 
0384     /**
0385      * Replies if the logical volume is part of a cuts region or not.
0386      */
0387     inline G4bool IsRegion() const;
0388 
0389     /**
0390      * Sets/unsets the volume as cuts region.
0391      */
0392     inline void SetRegion(G4Region* reg);
0393 
0394     /**
0395      * Returns the region to which the volume belongs, if any.
0396      */
0397     inline G4Region* GetRegion() const;
0398 
0399     /**
0400      * Propagates region pointer to daughters.
0401      */
0402     inline void PropagateRegion();
0403 
0404     /**
0405      * Accessor and modifier for production cuts.
0406      */
0407     const G4MaterialCutsCouple* GetMaterialCutsCouple() const;
0408     void SetMaterialCutsCouple(G4MaterialCutsCouple* cuts);
0409 
0410     /**
0411      * Equality defined by address only.
0412      * Returns true if objects are at same address, else false.
0413      */
0414     G4bool operator == (const G4LogicalVolume& lv) const;
0415 
0416     /**
0417      * Accessor and modifiers for visualization attributes.
0418      * Arguments are converted to shared_ptr.
0419      */
0420     const G4VisAttributes* GetVisAttributes () const;
0421     void SetVisAttributes (const G4VisAttributes* pVA);
0422     void SetVisAttributes (const G4VisAttributes& VA);
0423 
0424     /**
0425      * Gets the current FastSimulationManager pointer if existing,
0426      * otherwise null.
0427      */
0428     inline G4FastSimulationManager* GetFastSimulationManager () const;
0429 
0430     /**
0431      * Sets and gets the bias weight.
0432      */
0433     inline void SetBiasWeight (G4double w);
0434     inline G4double GetBiasWeight() const;
0435 
0436     /**
0437      * Returns true if it is not a base-class object.
0438      */
0439     virtual G4bool IsExtended() const;
0440 
0441     /**
0442      * Returns current Field Manager for the master thread.
0443      */
0444     inline G4FieldManager* GetMasterFieldManager() const;
0445 
0446     /**
0447      * Returns current Sensitive Detector for the master thread.
0448      */
0449     inline G4VSensitiveDetector* GetMasterSensitiveDetector() const;
0450 
0451     /**
0452      * Returns current Solid for the master thread.
0453      */
0454     inline G4VSolid* GetMasterSolid() const;
0455   
0456     /**
0457      * Returns the instance ID.
0458      */
0459     inline G4int GetInstanceID() const;
0460 
0461     /**
0462      * Returns the private data instance manager.
0463      */
0464     static const G4LVManager& GetSubInstanceManager();
0465 
0466     /**
0467      * Clears memory allocated by sub-instance manager.
0468      */
0469     static void Clean();
0470 
0471     /**
0472      * Sets lock identifier for final deletion of entity.
0473      */
0474     inline void Lock();
0475 
0476     /**
0477      * This method is similar to the constructor. It is used by each worker
0478      * thread to achieve the partial effect as that of the master thread.
0479      */
0480     void InitialiseWorker(G4LogicalVolume* ptrMasterObject,
0481                           G4VSolid* pSolid, G4VSensitiveDetector* pSDetector);
0482 
0483     /**
0484      * This method is similar to the destructor. It is used by each worker
0485      * thread to achieve the partial effect as that of the master thread.
0486      */
0487     void TerminateWorker(G4LogicalVolume* ptrMasterObject);
0488 
0489     /**
0490      * Sets the Field Manager only at this level (does not push down hierarchy)
0491      */
0492     void AssignFieldManager(G4FieldManager* fldMgr);
0493   
0494     /**
0495      * Optimised methods, passing thread instance of worker data.
0496      */
0497     static G4VSolid* GetSolid(G4LVData& instLVdata);
0498     static void SetSolid(G4LVData& instLVdata, G4VSolid* pSolid);
0499 
0500     /**
0501      * Changes the type of the daughters volume to be of type 'atype'.
0502      * Meant for the user adopting an external navigator for the contents
0503      * of a volume.
0504      *  @returns Success (true) or failure (false).
0505      */
0506     G4bool ChangeDaughtersType(EVolume atype);
0507 
0508     /**
0509      * Fake default constructor for usage restricted to direct object
0510      * persistency for clients requiring preallocation of memory for
0511      * persistifiable objects.
0512      */
0513     G4LogicalVolume(__void__&);
0514 
0515   private:
0516 
0517     using G4PhysicalVolumeList = std::vector<G4VPhysicalVolume *>;
0518 
0519     /** This field helps in the use of the class G4LVManager. */
0520     G4GEOM_DLL static G4LVManager subInstanceManager;
0521 
0522     /** Vector of daughters. Given initial size of 0. */
0523     G4PhysicalVolumeList fDaughters;
0524 
0525     /** Name of logical volume. */
0526     G4String fName;
0527 
0528     /** Pointer (possibly nullptr) to user step limit object for this node. */
0529     G4UserLimits* fUserLimits = nullptr;
0530 
0531     /** Pointer (possibly nullptr) to optimisation info objects. */
0532     G4SmartVoxelHeader* fVoxel = nullptr;
0533 
0534     /** Optimisation quality, average number of voxels to be spent per content. */
0535     G4double fSmartless = 2.0;
0536 
0537     /** Pointer to the cuts region (if any). */
0538     G4Region* fRegion = nullptr;
0539 
0540     /** Weight used in the event biasing technique. */
0541     G4double fBiasWeight = 1.0;
0542 
0543     /** Pointer to visualization attributes. */
0544     std::shared_ptr<const G4VisAttributes> fVisAttributes;
0545 
0546     // Shadow of master pointers.
0547     // Each worker thread can access this field from the master thread
0548     // through these pointers.
0549     //
0550     G4VSolid* fSolid = nullptr;
0551     G4VSensitiveDetector* fSensitiveDetector = nullptr;
0552     G4FieldManager* fFieldManager = nullptr;
0553     G4LVData* lvdata = nullptr;  // For use of object persistency
0554 
0555     /** This new field is used as instance ID. */
0556     G4int instanceID;
0557 
0558     /** Are contents of volume placements, replica, parameterised or external? */
0559     EVolume fDaughtersVolumeType;
0560 
0561     /** Flag to identify if optimisation should be applied or not. */
0562     G4bool fOptimise = true;
0563 
0564     /** Flag to identify if the logical volume is a root region. */
0565     G4bool fRootRegion = false;
0566 
0567     /** Flag to identify if entity is locked for final deletion. */
0568     G4bool fLock = false;
0569 };
0570 
0571 #include "G4LogicalVolume.icc"
0572 
0573 // NOTE:
0574 //
0575 // The type G4LVManager is introduced to encapsulate the methods used by
0576 // both the master thread and worker threads to allocate memory space for
0577 // the fields encapsulated by the class G4LVData. When each thread
0578 // initializes the value for these fields, it refers to them using a macro
0579 // definition defined below. For every G4LogicalVolume instance, there is
0580 // a corresponding G4LVData instance. All G4LVData instances are organized
0581 // by the class G4LVManager as an array.
0582 // The field "int instanceID" is added to the class G4LogicalVolume.
0583 // The value of this field in each G4LogicalVolume instance is the subscript
0584 // of the corresponding G4LVData instance.
0585 // In order to use the class G4LVManager, we add a static member in the class
0586 // G4LogicalVolume as follows: "static G4LVManager subInstanceManager".
0587 // For the master thread, the array for G4LVData instances grows dynamically
0588 // along with G4LogicalVolume instances are created. For each worker thread,
0589 // it copies the array of G4LVData instances from the master thread.
0590 // In addition, it invokes a method similiar to the constructor explicitly
0591 // to achieve the partial effect for each instance in the array.
0592 
0593 #endif