365 lines
14 KiB
C++
365 lines
14 KiB
C++
//
|
|
// ********************************************************************
|
|
// * License and Disclaimer *
|
|
// * *
|
|
// * The Geant4 software is copyright of the Copyright Holders of *
|
|
// * the Geant4 Collaboration. It is provided under the terms and *
|
|
// * conditions of the Geant4 Software License, included in the file *
|
|
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
|
// * include a list of copyright holders. *
|
|
// * *
|
|
// * Neither the authors of this software system, nor their employing *
|
|
// * institutes,nor the agencies providing financial support for this *
|
|
// * work make any representation or warranty, express or implied, *
|
|
// * regarding this software system or assume any liability for its *
|
|
// * use. Please see the license in the file LICENSE and URL above *
|
|
// * for the full disclaimer and the limitation of liability. *
|
|
// * *
|
|
// * This code implementation is the result of the scientific and *
|
|
// * technical work of the GEANT4 collaboration. *
|
|
// * By using, copying, modifying or distributing the software (or *
|
|
// * any work based on the software) you agree to acknowledge its *
|
|
// * use in resulting scientific publications, and indicate your *
|
|
// * acceptance of all terms of the Geant4 Software license. *
|
|
// ********************************************************************
|
|
//
|
|
// G4VPhysicalVolume
|
|
//
|
|
// Class description:
|
|
//
|
|
// This is an abstract base class for the representation of a positioned volume.
|
|
// The volume is placed within a mother volume, relative to its coordinate
|
|
// system. Either a single positioned volume or many positioned volumes can
|
|
// be represented by a particular G4VPhysicalVolume.
|
|
|
|
// Author: Paul Kent (CERN), 24.07.1995 - First non-stub version
|
|
// --------------------------------------------------------------------
|
|
#ifndef G4VPHYSICALVOLUME_HH
|
|
#define G4VPHYSICALVOLUME_HH
|
|
|
|
#include "G4Types.hh"
|
|
#include "G4String.hh"
|
|
|
|
#include "geomdefs.hh"
|
|
|
|
#include "G4RotationMatrix.hh"
|
|
#include "G4ThreeVector.hh"
|
|
#include "G4GeomSplitter.hh"
|
|
|
|
class G4LogicalVolume;
|
|
class G4VPVParameterisation;
|
|
|
|
/**
|
|
* @brief G4PVData encapsulates the fields associated to G4VPhysicalVolume
|
|
* that are not read-only - they will change during simulation and must have
|
|
* a per-thread state.
|
|
*/
|
|
|
|
class G4PVData
|
|
{
|
|
public:
|
|
|
|
G4PVData() = default;
|
|
|
|
void initialize()
|
|
{
|
|
frot = nullptr;
|
|
tx = 0.; ty = 0.; tz = 0.;
|
|
}
|
|
|
|
G4RotationMatrix* frot = nullptr;
|
|
G4double tx = 0., ty = 0., tz = 0.;
|
|
};
|
|
|
|
/** Type defined for use of G4PVData objects. */
|
|
using G4PVManager = G4GeomSplitter<G4PVData>;
|
|
|
|
/**
|
|
* @brief G4VPhysicalVolume is an abstract base class for the representation
|
|
* of a positioned volume. The volume is placed within a mother volume,
|
|
* relative to its coordinate system. Either a single positioned volume or
|
|
* many positioned volumes can be represented by a particular G4VPhysicalVolume.
|
|
*/
|
|
|
|
class G4VPhysicalVolume
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Constructor for G4VPhysicalVolume; it initialises a volume, positioned
|
|
* in a frame which is rotated by 'pRot', relative to the coordinate system
|
|
* of the mother volume 'pMother'. The center of the object is then placed
|
|
* at 'tlate' in the new coordinates. If 'pRot' is null, the volume is
|
|
* unrotated with respect to its mother. The physical volume is added to
|
|
* the mother's logical volume.
|
|
* The constructor must be called by all subclasses; 'pMother' must point
|
|
* to a valid parent volume, except in the case of the world/top volume,
|
|
* when it can be a null pointer. The constructor also registers the volume
|
|
* within the physical volumes store.
|
|
* @param[in] pRot The pointer to the rotation matrix.
|
|
* @param[in] tlate The translation vector coordinates.
|
|
* @param[in] pName The name of the volume.
|
|
* @param[in] pLogical The pointer to its logical volume.
|
|
* @param[in] pMother The pointer to the mother's physical volume.
|
|
*/
|
|
G4VPhysicalVolume(G4RotationMatrix* pRot,
|
|
const G4ThreeVector& tlate,
|
|
const G4String& pName,
|
|
G4LogicalVolume* pLogical,
|
|
G4VPhysicalVolume* pMother);
|
|
|
|
/**
|
|
* Destructor, will be subclassed. Removes volume from the volume store.
|
|
*/
|
|
virtual ~G4VPhysicalVolume();
|
|
|
|
/**
|
|
* Copy constructor and assignement operator not allowed.
|
|
*/
|
|
G4VPhysicalVolume(const G4VPhysicalVolume&) = delete;
|
|
G4VPhysicalVolume& operator=(const G4VPhysicalVolume&) = delete;
|
|
|
|
/**
|
|
* Equality defined by equal addresses only..
|
|
*/
|
|
inline G4bool operator == (const G4VPhysicalVolume& p) const;
|
|
|
|
// Accessors. They make a distinction between whether the rotation or
|
|
// translation is being made for the frame or the object/volume that is
|
|
// being placed (they are the inverse of each other).
|
|
|
|
/**
|
|
* Accessors returning the rotation/translation of the *object* relative
|
|
* to the mother.
|
|
*/
|
|
G4RotationMatrix* GetObjectRotation() const; // Obsolete
|
|
G4RotationMatrix GetObjectRotationValue() const; // Replacement
|
|
G4ThreeVector GetObjectTranslation() const;
|
|
|
|
/**
|
|
* Accessors returning the rotation/translation of the *frame* used to
|
|
* position this volume in its mother volume (opposite of object rot/trans).
|
|
*/
|
|
const G4RotationMatrix* GetFrameRotation() const;
|
|
G4ThreeVector GetFrameTranslation() const;
|
|
|
|
/**
|
|
* Old access functions, that do not distinguish between frame/object!
|
|
* They simply return the translation/rotation of the volume.
|
|
*/
|
|
const G4ThreeVector GetTranslation() const;
|
|
const G4RotationMatrix* GetRotation() const;
|
|
G4RotationMatrix* GetRotation();
|
|
|
|
// Modifiers for translation and rotation
|
|
|
|
/**
|
|
* Sets the translation vector.
|
|
*/
|
|
void SetTranslation(const G4ThreeVector& v);
|
|
|
|
/**
|
|
* Sets the rotation matrix. NOT INTENDED FOR GENERAL USE.
|
|
* Non constant version, used to change transformation for the
|
|
* replication/parameterisation mechanism.
|
|
*/
|
|
void SetRotation(G4RotationMatrix*);
|
|
|
|
/**
|
|
* Returns the associated logical volume pointer.
|
|
*/
|
|
inline G4LogicalVolume* GetLogicalVolume() const;
|
|
|
|
/**
|
|
* Sets the logical volume pointer. Must not be called when geometry
|
|
* is closed.
|
|
*/
|
|
inline void SetLogicalVolume(G4LogicalVolume* pLogical);
|
|
|
|
inline G4LogicalVolume* GetMotherLogical() const;
|
|
// Return the current mother logical volume pointer.
|
|
inline void SetMotherLogical(G4LogicalVolume* pMother);
|
|
// Set the mother logical volume. Must not be called when geometry closed.
|
|
|
|
/**
|
|
* Getter/setter for the volume's name.
|
|
*/
|
|
inline const G4String& GetName() const;
|
|
void SetName(const G4String& pName);
|
|
|
|
/**
|
|
* Returns the number of object entities (1 for normal placements,
|
|
* n for replicas or parameterised).
|
|
*/
|
|
virtual G4int GetMultiplicity() const;
|
|
|
|
// Functions required of subclasses
|
|
|
|
/**
|
|
* Characterises the type of volume - normal/replicated/parameterised.
|
|
*/
|
|
virtual EVolume VolumeType() const = 0;
|
|
|
|
/**
|
|
* NOT implemented. Should return true if the volume is MANY type.
|
|
*/
|
|
virtual G4bool IsMany() const = 0;
|
|
|
|
/**
|
|
* Accessor/modifier for optional handling of the volume copy-number.
|
|
*/
|
|
virtual G4int GetCopyNo() const = 0;
|
|
virtual void SetCopyNo(G4int CopyNo) = 0;
|
|
|
|
/**
|
|
* Returns true if the volume is replicated (single object instance
|
|
* represents many real volumes), else false.
|
|
*/
|
|
virtual G4bool IsReplicated() const = 0;
|
|
|
|
/**
|
|
* Returns true if the volume is parameterised (single object instance
|
|
* represents many real parameterised volumes), else false.
|
|
*/
|
|
virtual G4bool IsParameterised() const = 0;
|
|
|
|
/**
|
|
* Returns a pointer to the replicas parameterisation object/algorithm
|
|
* (able to compute dimensions and transformations of replicas), or a
|
|
* null pointer if not applicable.
|
|
*/
|
|
virtual G4VPVParameterisation* GetParameterisation() const = 0;
|
|
|
|
/**
|
|
* Returns the replication information. No-op for non replicated volumes.
|
|
* @param[in,out] axis The axis of replication/parameterisation.
|
|
* @param[in,out] nReplicas The number of replicated/parameterised objects.
|
|
* @param[in,out] width The width of replicated object.
|
|
* @param[in,out] offset The optional offset distance from mother's border.
|
|
* @param[in,out] consuming Flag of replica characterisation (always true
|
|
* for pure replicas).
|
|
*/
|
|
virtual void GetReplicationData(EAxis& axis,
|
|
G4int& nReplicas,
|
|
G4double& width,
|
|
G4double& offset,
|
|
G4bool& consuming) const = 0;
|
|
|
|
/**
|
|
* Returns true if the underlying volume structure is regular.
|
|
*/
|
|
virtual G4bool IsRegularStructure() const = 0;
|
|
|
|
/**
|
|
* Returns non-zero code in case the underlying volume structure is regular,
|
|
* voxel-like. The value is an identifier for the structure type.
|
|
* If non-zero the volume is a candidate for specialised navigation such
|
|
* as 'nearest neighbour' directly on volumes.
|
|
*/
|
|
virtual G4int GetRegularStructureId() const = 0;
|
|
|
|
/**
|
|
* Verifies if the placed volume is overlapping with the existing
|
|
* daughters or with the mother volume. It provides a default resolution
|
|
* for the number of points to be generated and verified. A concrete
|
|
* implementation is done and required only for placed and parameterised
|
|
* volumes. Returns true if the volume is overlapping.
|
|
* @param[in] res The number of points to generate on volume's surface.
|
|
* @param[in] tol The precision tolerance for the overlap check, below
|
|
* which to ignore overlaps (default is maximim precision).
|
|
* @param[in] verbose Verbosity mode (default is true).
|
|
* @param[in] errMax Maximum of overlaps errors to report (default is 1).
|
|
* @returns True if an overlap occurs.
|
|
*/
|
|
virtual G4bool CheckOverlaps(G4int res=1000, G4double tol=0.,
|
|
G4bool verbose=true, G4int errMax=1);
|
|
|
|
/**
|
|
* Fake default constructor for usage restricted to direct object
|
|
* persistency for clients requiring preallocation of memory for
|
|
* persistifiable objects.
|
|
*/
|
|
G4VPhysicalVolume(__void__&);
|
|
|
|
/**
|
|
* Returns the instance ID for multi-threading.
|
|
*/
|
|
inline G4int GetInstanceID() const;
|
|
|
|
/**
|
|
* Returns the private data instance manager for multi-threading.
|
|
*/
|
|
static const G4PVManager& GetSubInstanceManager();
|
|
|
|
/**
|
|
* Clears the memory allocated by the MT sub-instance manager.
|
|
*/
|
|
static void Clean();
|
|
|
|
/**
|
|
* Old VolumeType() method, replaced by virtual method, kept for checking.
|
|
*/
|
|
inline EVolume DeduceVolumeType() const;
|
|
|
|
protected:
|
|
|
|
/**
|
|
* This method is similar to the constructor. It is used by each worker
|
|
* thread to achieve the partial effect as that of the master thread.
|
|
*/
|
|
void InitialiseWorker(G4VPhysicalVolume* pMasterObject,
|
|
G4RotationMatrix* pRot, const G4ThreeVector& tlate);
|
|
|
|
/**
|
|
* This method is similar to the destructor. It is used by each worker
|
|
* thread to achieve the partial effect as that of the master thread.
|
|
*/
|
|
void TerminateWorker(G4VPhysicalVolume* pMasterObject);
|
|
|
|
protected:
|
|
|
|
/** For use in implementing the per-thread data.
|
|
It is equivalent to a pointer to a G4PVData object. */
|
|
G4int instanceID;
|
|
|
|
/** Needed to use G4PVManager for the G4PVData per-thread objects. */
|
|
G4GEOM_DLL static G4PVManager subInstanceManager;
|
|
|
|
private:
|
|
|
|
/** The logical volume representing the attributes of the volume. */
|
|
G4LogicalVolume* flogical = nullptr;
|
|
|
|
/** The name of the volume. */
|
|
G4String fname;
|
|
|
|
/** The current mother logical volume. */
|
|
G4LogicalVolume* flmother = nullptr;
|
|
|
|
/** Shadow pointer for use of object persistency. */
|
|
G4PVData* pvdata = nullptr;
|
|
};
|
|
|
|
// NOTE:
|
|
// The type G4PVManager is introduced to encapsulate the methods used by
|
|
// both the master thread and worker threads to allocate memory space for
|
|
// the fields encapsulated by the class G4PVData. When each thread
|
|
// initializes the value for these fields, it refers to them using a macro
|
|
// definition defined below. For every G4VPhysicalVolume instance, there is
|
|
// a corresponding G4PVData instance. All G4PVData instances are organized
|
|
// by the class G4PVManager as an array.
|
|
// The field "int instanceID" is added to the class G4VPhysicalVolume.
|
|
// The value of this field in each G4VPhysicalVolume instance is the subscript
|
|
// of the corresponding G4PVData instance.
|
|
// In order to use the class G4PVManager, we add a static member in the class
|
|
// G4VPhysicalVolume as follows: "static G4PVManager subInstanceManager;".
|
|
// For the master thread, the array for G4PVData instances grows dynamically
|
|
// along with G4VPhysicalVolume instances are created. For each worker thread,
|
|
// it copies the array of G4PVData instances from the master thread.
|
|
// In addition, it invokes a method similiar to the constructor explicitly
|
|
// to achieve the partial effect for each instance in the array.
|
|
|
|
#include "G4VPhysicalVolume.icc"
|
|
|
|
#endif
|