Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:59:02

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 // G4ReflectionFactory
0027 //
0028 // Class description:
0029 //
0030 // Class providing functions for volumes placements with a general
0031 // transfomation that can contain reflection.
0032 // Reflection is then applied to a solid: a new G4ReflectedSolid
0033 // instance is created and is placed with a transformation containing
0034 // pure rotation and translation only.
0035 // The pair of constituent and reflected logical volumes is
0036 // considered as a generalized logical volume that is addressed
0037 // by user specifying the constituent logical volume.
0038 //
0039 // Decomposition of a general transformation that can include reflection
0040 // in a "reflection-free" transformation:
0041 // 
0042 // x(inM') = TG*x(inM)         TG - general transformation
0043 //         = T*(R*x(inM))      T  - "reflection-free" transformation
0044 //         = T* x(inReflM)   
0045 //
0046 // Daughters transformation:
0047 // When a volume V containing daughter D with transformation TD
0048 // is placed in mother M with a general tranformation TGV,
0049 // the TGV is decomposed. New reflected volume ReflV containing
0050 // a new daughter ReflD with reflected transformation ReflTD is created:
0051 // 
0052 // x(inV) = TD * x(inD);
0053 // x(inM) = TGV * x(inV) 
0054 //        = TV * R * x(inV) 
0055 //        = TV * R * TD * x(inD)
0056 //        = TV * R*TD*R-1 * R*x(inD)
0057 //        = TV * ReflTD * x(inReflD)
0058 
0059 // Author: Ivana Hrivnacova (Ivana.Hrivnacova@cern.ch), 16.10.2001
0060 // --------------------------------------------------------------------
0061 #ifndef G4_REFLECTION_FACTORY_HH
0062 #define G4_REFLECTION_FACTORY_HH
0063 
0064 #include "G4Types.hh"
0065 #include "G4Transform3D.hh"
0066 #include "geomdefs.hh"
0067 
0068 #include <map>
0069 
0070 class G4VPhysicalVolume;
0071 class G4LogicalVolume;
0072 class G4VSolid;
0073 class G4VPVDivisionFactory;
0074 
0075 using G4PhysicalVolumesPair = std::pair<G4VPhysicalVolume*, G4VPhysicalVolume*>;
0076 using G4ReflectedVolumesMap = std::map<G4LogicalVolume*, G4LogicalVolume*,  
0077                                        std::less<G4LogicalVolume*> >;
0078 class G4ReflectionFactory 
0079 {
0080   using LogicalVolumesMapIterator = G4ReflectedVolumesMap::const_iterator;
0081 
0082   public:
0083   
0084     virtual ~G4ReflectionFactory();
0085       // Virtual destructor.
0086 
0087     static G4ReflectionFactory* Instance();
0088       // Gets pointer to the instance of the singleton.
0089 
0090     G4PhysicalVolumesPair Place(const G4Transform3D& transform3D,
0091                                 const G4String&  name,
0092                                       G4LogicalVolume* LV,
0093                                       G4LogicalVolume* motherLV,
0094                                       G4bool isMany, 
0095                                       G4int  copyNo,
0096                                       G4bool surfCheck = false);
0097       // Evaluates the passed transformation; if it contains reflection
0098       // it performs its decomposition, creates new reflected solid and
0099       // logical volume (or retrieves them from a map if the reflected
0100       // objects were already created), transforms the daughters (if present)
0101       // and place it in the given mother.
0102       // The result is a pair of physical volumes;
0103       // the second physical volume is a placement in a reflected mother
0104       // or 0 if mother LV was not reflected.
0105 
0106     G4PhysicalVolumesPair Replicate(const G4String& name, 
0107                                           G4LogicalVolume* LV,
0108                                           G4LogicalVolume* motherLV,
0109                                           EAxis axis, 
0110                                           G4int nofReplicas, 
0111                                           G4double width,
0112                                           G4double offset = 0.);
0113       // Creates replica in the given mother.
0114       // The result is a pair of physical volumes;
0115       // the second physical volume is a replica in a reflected mother
0116       // or 0 if mother LV was not reflected.
0117 
0118     G4PhysicalVolumesPair Divide(const G4String& name, 
0119                                        G4LogicalVolume* LV,
0120                                        G4LogicalVolume* motherLV,
0121                                        EAxis axis, 
0122                                        G4int nofDivisions, 
0123                                        G4double width,
0124                                        G4double offset);
0125     G4PhysicalVolumesPair Divide(const G4String& name, 
0126                                        G4LogicalVolume* LV,
0127                                        G4LogicalVolume* motherLV,
0128                                        EAxis axis, 
0129                                        G4int nofDivisions, 
0130                                        G4double offset);
0131     G4PhysicalVolumesPair Divide(const G4String& name, 
0132                                        G4LogicalVolume* LV,
0133                                        G4LogicalVolume* motherLV,
0134                                        EAxis axis, 
0135                                        G4double width,
0136                                        G4double offset);
0137       // Creates division in the given mother.
0138       // The result is a pair of physical volumes;
0139       // the second physical volume is a division in a reflected mother
0140       // or nullptr if mother LV was not reflected.
0141 
0142     void  SetVerboseLevel(G4int verboseLevel);
0143     G4int GetVerboseLevel() const;
0144       // Sets/gets verbosity level.
0145 
0146     void     SetVolumesNameExtension(const G4String& nameExtension);
0147     const G4String& GetVolumesNameExtension() const;
0148       // Returns the name extension for the reflected solids
0149       // and logical volumes.
0150 
0151     void     SetScalePrecision(G4double scaleValue);
0152     G4double GetScalePrecision() const;
0153       // Sets/gets precision factor for the scale consistency check
0154       // The default value is set to 10*kCarTolerance.
0155 
0156     G4LogicalVolume* GetConstituentLV(G4LogicalVolume* reflLV) const;
0157       // Returns the consituent volume of the given reflected volume,
0158       // nullptr if the given reflected volume was not found.
0159 
0160     G4LogicalVolume* GetReflectedLV(G4LogicalVolume* lv) const;
0161       // Returns the reflected volume of the given consituent volume,
0162       // nullptr if the given volume was not reflected.
0163 
0164     G4bool IsConstituent(G4LogicalVolume* lv) const;
0165       // Returns true if the given volume has been already reflected
0166       // (is in the map of constituent volumes).
0167 
0168     G4bool IsReflected(G4LogicalVolume* lv) const;
0169       // Returns true if the given volume is a reflected volume
0170       // (is in the map reflected  volumes).
0171 
0172     const G4ReflectedVolumesMap& GetReflectedVolumesMap() const;
0173       // Returns a handle to the internal map of volumes which have
0174       // been reflected, after that placement or replication is performed.
0175 
0176     void Clean();
0177       // Clear maps of constituent and reflected volumes.
0178       // To be used exclusively when volumes are removed from the stores.
0179 
0180     G4ReflectionFactory(const G4ReflectionFactory&) = delete;
0181     G4ReflectionFactory& operator=(const G4ReflectionFactory&) = delete;
0182       // Disabled copy constructor and assignment operator.
0183  
0184   protected:  
0185 
0186     G4ReflectionFactory();
0187       // Protected singleton constructor.
0188 
0189   private:  
0190 
0191     G4LogicalVolume* ReflectLV(G4LogicalVolume* LV, G4bool surfCheck = false);
0192       // Gets/creates the reflected solid and logical volume
0193       // and copies + transforms LV daughters.
0194 
0195     G4LogicalVolume* CreateReflectedLV(G4LogicalVolume* LV);
0196       // Creates the reflected solid and logical volume
0197       // and add the logical volumes pair in the maps.
0198 
0199     void ReflectDaughters(G4LogicalVolume* LV,
0200                           G4LogicalVolume* refLV, G4bool surfCheck = false);
0201       // Reflects daughters recursively.
0202 
0203     void ReflectPVPlacement(G4VPhysicalVolume* PV,
0204                             G4LogicalVolume* refLV, G4bool surfCheck = false);
0205       // Copies and transforms daughter of PVPlacement type of
0206       // a constituent volume into a reflected volume. 
0207 
0208     void ReflectPVReplica(G4VPhysicalVolume* PV, G4LogicalVolume* refLV);
0209       // Copies and transforms daughter of PVReplica type of
0210       // a constituent volume into a reflected volume. 
0211 
0212     void ReflectPVDivision(G4VPhysicalVolume* PV, G4LogicalVolume* refLV);
0213       // Copies and transforms daughter of PVDivision type of
0214       // a constituent volume into a reflected volume. 
0215 
0216     void ReflectPVParameterised(G4VPhysicalVolume* PV,
0217                                 G4LogicalVolume* refLV, G4bool surfChk = false);
0218       // Not implemented yet.
0219       // Should copy and transform daughter of PVReplica type of
0220       // a constituent volume into a reflected volume. 
0221 
0222     G4bool IsReflection(const G4Scale3D& scale) const;
0223       // Returns true if the scale is negative, false otherwise.
0224 
0225     void CheckScale(const G4Scale3D& scale) const;
0226       // Checks if scale correspond to fScale, if not gives exception.
0227 
0228     G4VPVDivisionFactory* GetPVDivisionFactory() const;
0229       // Checks if the division factory is instanciated,
0230       // if not gives exception.
0231 
0232     void PrintConstituentLVMap();  
0233       // Temporary - for debugging purpose.
0234   
0235   private:
0236 
0237     static G4ThreadLocal G4ReflectionFactory* fInstance;
0238     static const G4String       fDefaultNameExtension;
0239     static const G4Scale3D      fScale;
0240     G4double                    fScalePrecision;
0241 
0242     G4int              fVerboseLevel = 0;
0243     G4String           fNameExtension;
0244     G4ReflectedVolumesMap  fConstituentLVMap;
0245     G4ReflectedVolumesMap  fReflectedLVMap;
0246 };
0247 
0248 #endif