Overview Contents Previous Next Geant4 User's Guide
For Application Developers
Geometry


4.1.4 Physical Volumes

Physical volumes represent the spatial positioning of the volumes describing the detector elements. Several techniques can be used. They range from the simple placement of a single copy to the repeated positioning using either a simple linear formula or a user specified function.

The simple placement involves the definition of a transformation matrix for the volume to be positioned. Repeated positioning is defined using the number of times a volume should be replicated at a given distance along a given direction. Finally it is possible to define a parameterised formula to specify the position of multiple copies of a volume. Details about these methods are given below.

Note - For geometries which vary between runs and for which components of the old geometry setup are explicitely -deleted-, it is required to consider the proper order of deletion (which is the exact inverse of the actual construction, i.e., first delete physical volumes and then logical volumes). Deleting a logical volume does NOT delete its daughter volumes.
It is not necessary to delete the geometry setup at the end of a job, the system will take care to free the volume and solid stores at the end of the job. The user has to take care of the deletion of any additional transformation or rotation matrices allocated dinamically in his/her own application.

4.1.4.1 Placements: single positioned copy

In this case, the Physical Volume is created by associating a Logical Volume with a Rotation Matrix and a Translation vector. The Rotation Matrix represents the rotation of the reference frame of the considered volume relatively to its mother volume's reference frame. The Translation Vector represents the translation of the current volume in the reference frame of its mother volume.
Transformations including reflections are not allowed.

To create a Placement one must construct it using:

    G4PVPlacement(       G4RotationMatrix*  pRot,
                   const G4ThreeVector&     tlate,
                         G4LogicalVolume*   pCurrentLogical,
                   const G4String&          pName,
                         G4LogicalVolume*   pMotherLogical,
                         G4bool             pMany,
                         G4int              pCopyNo,
                         G4bool             pSurfChk=false )
where:

pRot Rotation with respect to its mother volume
tlate Translation with respect to its mother volume
pCurrentLogical The associated Logical Volume
pName String identifier for this placement
pMotherLogical The associated mother volume
pMany For future use. Can be set to false
pCopyNo Integer which identifies this placement
pSurfChk if true activates check for overlaps with existing volumes

Care must be taken because the rotation matrix is not copied by a G4PVPlacement. So the user must not modify it after creating a Placement that uses it. However the same rotation matrix can be re-used for many volumes.

Currently boolean operations are not implemented at the level of physical volume. So pMany must be false. However, an alternative implementation of boolean operations exists. In this approach a solid can be created from the union, intersection or subtraction of two solids. See Section 4.1.2.2 above for an explanation of this.

The mother volume must be specified for all volumes except the world volume.

An alternative way to specify a Placement utilizes a different method to place the volume. The solid itself is moved by rotating and translating it to bring it into the system of coordinates of the mother volume. This active method can be utilized using the following constructor:

    G4PVPlacement(       G4Transform3D      solidTransform,
                         G4LogicalVolume*   pCurrentLogical,
                   const G4String&          pName,
                         G4LogicalVolume*   pMotherLogical,
                         G4bool             pMany,
                         G4int              pCopyNo,
                         G4bool             pSurfChk=false )

An alternative method to specify the mother volume is to specify its placed physical volume. It can be used in either of the above methods of specifying the placement's position and rotation. The effect will be exactly the same as for using the mother logical volume.

Note that a Placement Volume can still represent multiple detector elements. This can happen if several copies exist of the mother logical volume. Then different detector elements will belong to different branches of the tree of the hierarchy of geometrical volumes.

4.1.4.2 Repeated volumes

In this case, a single Physical Volume represents multiple copies of a volume within its mother volume, allowing to save memory. This is normally done when the volumes to be positioned follow a well defined rotational or translational symmetry along a Cartesian or cylindrical coordinate. The Repeated Volumes technique is available for volumes described by CSG solids.

Replicas

Replicas are repeated volumes in the case when the multiple copies of the volume are all identical. The coordinate axis and the number of replicas need to be specified for the program to compute at run time the transformation matrix corresponding to each copy.

    G4PVReplica( const G4String&          pName,
                       G4LogicalVolume*   pCurrentLogical,
                       G4LogicalVolume*   pMotherLogical, // OR G4VPhysicalVolume*
                 const EAxis              pAxis,
                 const G4int              nReplicas,
                 const G4double           width,
                 const G4double           offset=0 )
where:

pName String identifier for the replicated volume
pCurrentLogical The associated Logical Volume
pMotherLogical The associated mother volume
pAxis The axis along with the replication is applied
nReplicas The number of replicated volumes
width The width of a single replica along the axis of replication
offset Possible offset associated to mother offset along the axis of replication

G4PVReplica represents nReplicas volumes differing only in their positioning, and completely filling the containing mother volume. Consequently if a G4PVReplica is 'positioned' inside a given mother it MUST be the mother's only daughter volume. Replica's correspond to divisions or slices that completely fill the mother volume and have no offsets. For Cartesian axes, slices are considered perpendicular to the axis of replication.

The replica's positions are calculated by means of a linear formula. Replication may occur along:

The coordinate system of the replicas is at the centre of each replica for the cartesian axis. For the radial case, the coordinate system is unchanged from the mother. For the phi axis, the new coordinate system is rotated such that the X axis bisects the angle made by each wedge, and Z remains parallel to the mother's Z axis.

The solid associated via the replicas' logical volume should have the dimensions of the first volume created and must be of the correct symmetry/type, in order to assist in good visualisation.
ex. For X axis replicas in a box, the solid should be another box with the dimensions of the replications. (same Y & Z dimensions as mother box, X dimension = mother's X dimension/nReplicas).

Replicas may be placed inside other replicas, provided the above rule is observed. Normal placement volumes may be placed inside replicas, provided that they do not intersect the mother's or any previous replica's boundaries. Parameterised volumes may not be placed inside.
Because of these rules, it is not possible to place any other volume inside a replication in radius.
The world volume cannot act as a replica, therefore it cannot be sliced.

During tracking, the translation + rotation associated with each G4PVReplica object is modified according to the currently 'active' replication. The solid is not modified and consequently has the wrong parameters for the cases of phi and r replication and for when the cross-section of the mother is not constant along the replication.

Example:

           G4PVReplica repX("Linear Array",
                            pRepLogical,
                            pContainingMother,
                            kXAxis, 5, 10*mm);

           G4PVReplica repR("RSlices",
                            pRepRLogical,
                            pContainingMother,
                            kRho, 5, 10*mm, 0);

           G4PVReplica repRZ("RZSlices",
                             pRepRZLogical,
                             &repR,
                             kZAxis, 5, 10*mm);

           G4PVReplica repRZPhi("RZPhiSlices",
                                pRepRZPhiLogical,
                                &repRZ,
                                kPhi, 4, M_PI*0.5*rad, 0);
 
Source listing 4.1.2
An example of simple replicated volumes with G4PVReplica.

RepX is an array of 5 replicas of width 10*mm, positioned inside and completely filling the volume pointed by pContainingMother. The mother's X length must be 5*10*mm=50*mm (for example, if the mother's solid were a Box of half lengths [25,25,25] then the replica's solid must be a box of half lengths [25,25,5]).

If the containing mother's solid is a tube of radius 50*mm and half Z length of 25*mm, RepR divides the mother tube into 5 cylinders (hence the solid associated with pRepRLogical must be a tube of radius 10*mm, and half Z length 25*mm); repRZ divides it into 5 shorter cylinders (the solid associated with pRepRZLogical must be a tube of radius 10*mm, and half Z length 5*mm); finally, repRZPhi divides it into 4 tube segments with full angle of 90 degrees (the solid associated with pRepRZPhiLogical must be a tube segment of radius 10*mm, half Z length 5*mm and delta phi of M_PI*0.5*rad).
No further volumes may be placed inside these replicas. To do so would result in intersecting boundaries due to the r replications.

Parameterised Volumes

Parameterised Volumes are repeated volumes in the case in which the multiple copies of a volume can be different in size, solid type, or material. The solid's type, its dimensions, the material and the transformation matrix can all be parameterised in function of the copy number, both when a strong symmetry exist and when it does not. The user implements the desired parameterisation function and the program computes and updates automatically at run time the information associated to the Physical Volume.

An example of creating a parameterised volume (by dimension and position) exists in novice example N02. The implementation is provided in the two classes ExN02DetectorConstruction and ExN02ChamberParameterisation.

To create a parameterised volume, one must first create its logical volume like trackerChamberLV below. Then one must create his own parameterisation class (ExN02ChamberParameterisation) and instantiate an object of this class (chamberParam). We will see how to create the parameterisation below.

  //------------------------------
  // Tracker segments
  //------------------------------
  // An example of Parameterised volumes
  // dummy values for G4Box -- modified by parameterised volume
  G4VSolid * solidChamber =
                new G4Box("chamberBox", 10.*cm, 10.*cm, 10.*cm);

  G4LogicalVolume * trackerChamberLV
    = new G4LogicalVolume(solidChamber, Aluminum, "trackerChamberLV");
  G4VPVParameterisation * chamberParam
    = new ExN02ChamberParameterisation(
                         6,           //  NoChambers,
                        -240.*cm,     //  Z of centre of first
                        80*cm,        //  Z spacing of centres
                        20*cm,        //  Width Chamber,
                        50*cm,        //  lengthInitial,
                        trackerSize*2.); //  lengthFinal

  G4VPhysicalVolume *trackerChamber_phys
    = new G4PVParameterised("TrackerChamber_parameterisedPV",
                       trackerChamberLV, // Its logical volume
                       logicTracker,     // Mother logical volume
                       kUndefined,       // Allow default voxelising -- no axis
                       6,                // Number of chambers
                       chamberParam);    // The parameterisation
  // "kUndefined" is the suggested choice, giving 3D voxelisation (i.e. along the three 
  // cartesian axes, as is applied for placements.
  //
  // Note:  In some cases where volume have clear separation along a single axis, 
  // this axis (eg kZAxis) can be used to choose (force) optimisation only along
  // this axis in geometrical calculations.
  // When an axis is given it forces the use of one-dimensional voxelisation.
Source listing 4.1.3
An example of Parameterised volumes.
The general constructor is:
    G4PVParameterised( const G4String&              pName,
                             G4LogicalVolume*       pCurrentLogical,
                             G4LogicalVolume*       pMotherLogical, // OR G4VPhysicalVolume*
                       const EAxis                  pAxis,
                       const G4int                  nReplicas,
                             G4VPVParameterisation* pParam,
                             G4bool                 pSurfChk=false )
 

Note that for a parameterised volume the user must always specify a mother volume. So the world volume can never be a parameterised volume, nor it can be sliced. The mother volume can be specified either as a physical or a logical volume.

pAxis specifies the tracking optimisation algorithm to apply: if a valid axis (the axis along which the parameterisation is performed) is specified, a simple one-dimensional voxelisation algorithm is applied; if "kUndefined" is specified instead, the default three-dimensional voxelisation algorithm applied for normal placements will be activated. In the latter case, more voxels will be generated, therefore a greater amount of memory will be consumed by the optimisation algorithm.

pSurfChk if true activates a check for overlaps with existing volumes or paramaterised instances.

The parameterisation mechanism associated to a parameterised volume is defined in the parameterisation class and its methods. Every parameterisation must create two methods:

An example is ExN02ChamberParameterisation that parameterises a series of boxes of different sizes

 class ExN02ChamberParameterisation : public G4VPVParameterisation
 {
   ...
   void ComputeTransformation(const G4int       copyNo,
                              G4VPhysicalVolume *physVol) const;

   void ComputeDimensions(G4Box&              trackerLayer,
                          const G4int             copyNo,
                          const G4VPhysicalVolume *physVol) const;
   ...
 }
 
Source listing 4.1.4
An example of Parameterised boxes of different sizes.

These methods works as follows:

The ComputeTransformation method is called with a copy number for the instance of the parameterisation under consideration. It must compute the transformation for this copy, and set the physical volume to utilize this transformation:

 void ExN02ChamberParameterisation::ComputeTransformation
 (const G4int copyNo,G4VPhysicalVolume *physVol) const
 {
   G4double      Zposition= fStartZ + copyNo * fSpacing;
   G4ThreeVector origin(0,0,Zposition);
   physVol->SetTranslation(origin);
   physVol->SetRotation(0);
 }
 
Note that the translation and rotation given in this scheme are those for the frame of coordinates (the passive method). They are not for the active method, in which the solid is rotated into the mother frame of coordinates.

Similarly the ComputeDimensions method is used to set the size of that copy.

 void ExN02ChamberParameterisation::ComputeDimensions
 (G4Box & trackerChamber, const G4int copyNo,
  const G4VPhysicalVolume * physVol) const
 {
   G4double  halfLength= fHalfLengthFirst + (copyNo-1) * fHalfLengthIncr;
   trackerChamber.SetXHalfLength(halfLength);
   trackerChamber.SetYHalfLength(halfLength);
   trackerChamber.SetZHalfLength(fHalfWidth);
 }
 
The user must ensure that the type of the first argument of this method (in this example G4Box &) corresponds to the type of object the user give to the logical volume of parameterised physical volume.

More advanced usage allows the user:

for the parameterisation.
Example N07 shows a simple parameterisation by material. A more complex example is provided in examples/extended/medical/DICOM, where a phantom grid of cells is built using a parameterisation by material defined through a map.

Note - Currently for many cases it is not possible to add daughter volumes to a parameterised volume. Only parameterised volumes all of whose solids have the same size are allowed to contain daughter volumes. When the size or type of solid varies, adding daughters is not supported.
So the full power of parameterised volumes can be used only for "leaf" volumes, which contain no other volumes.

Advanced parameterisations for 'nested' parameterised volumes

A new type of parameterisation enables a user to have the daughter's material also depend on the copy number of the parent when a parameterised volume (daughter) is located inside another (parent) repeated volume. The parent volume can be a replica, a parameterised volume, or a division if the key feature of modifying its contents is utilised. (Note: a 'nested' parameterisation inside a placement volume is not supported, because all copies of a placement volume must be identical at all levels.)

In such a " nested" parameterisation , the user must provide a ComputeMaterial method that utilises the new argument that represents the touchable history of the parent volume:

// Sample Parameterisation
class SampleNestedParameterisation : public G4VNestedParameterisation
{
 public:
   // .. other methods ...
    // Mandatory method, required and reason for this class
    virtual G4Material* ComputeMaterial(G4VPhysicalVolume *currentVol,
				                         const G4int no_lev, 
				                         const G4VTouchable *parentTouch);
 private:
    G4Material *material1, *material2;  
};
  

The implementation of the method can utilise any information from a parent or other ancestor volume of its parameterised physical volume, but typically it will use only the copy number:

 G4Material* 
 SampleNestedParameterisation::ComputeMaterial(G4VPhysicalVolume *currentVol,
  	                                            const G4int no_lev, 
					                            const G4VTouchable *parentTouchable)
 {
    G4Material *material=0;
	
    // Get the information about the parent volume
    G4int no_parent= parentTouchable->GetReplicaNumber(); 
    G4int no_total= no_parent + no_lev; 
    // A simple 'checkerboard' pattern of two materials 
    if( no_total / 2 == 1 ) material= material1;
    else  material= material2; 
    // Set the material to the current logical volume 
    G4LogicalVolume* currentLogVol= currentVol->GetLogicalVolume(); 
    currentLogVol->SetMaterial( material ); 
    return material;
 }

Nested parameterisations are suitable for the case of regular, 'voxel' geometries in which a large number of 'equal' volumes are required, and their only difference is in their material. By creating two (or more) levels of parameterised physical volumes it is possible to divide space, while requiring only limited additional memory for very fine-level optimisation. This provides fast navigation. Alternative implementations, taking into account the regular structure of such geometries in navigation are under study.

Divisions of Volumes

Divisions in Geant4 are implemented as a specialized type of parameterised volumes.
They serve to divide a volume into identical copies along one of its axes, providing the possibility to define an offset, and without the limitation that the daugthers have to fill the mother volume as it is the case for the replicas. In the case, for example, of a tube divided along its radial axis, the copies are not strictly identical, but have increasing radii, although their widths are constant.

To divide a volume it will be necessary to provide:

  1. the axis of division, and
  2. either

An offset can be defined so that the first copy will start at some distance from the mother wall. The dividing copies will be then distributed to occupy the rest of the volume.

There are three constructors, corresponding to the three input possibilities described above:

where:

pName String identifier for the replicated volume
pCurrentLogical The associated Logical Volume
pMotherLogical The associated mother Logical Volume
pAxis The axis along which the division is applied
nDivisions The number of divisions
width The width of a single division along the axis
offset Possible offset associated to the mother along the axis of division

The parameterisation is calculated automatically using the values provided in input. Therefore the dimensions of the solid associated with pCurrentLogical will not be used, but recomputed through the G4VParameterisation::ComputeDimension() method.

Since G4VPVParameterisation may have different ComputeDimension() methods for each solid type, the user must provide a solid that is of the same type as of the one associated to the mother volume.

As for any replica, the coordinate system of the divisions is related to the centre of each division for the cartesian axis. For the radial axis, the coordinate system is the same of the mother volume. For the phi axis, the new coordinate system is rotated such that the X axis bisects the angle made by each wedge, and Z remains parallel to the mother's Z axis.

As divisions are parameterised volumes with constant dimensions, they may be placed inside other divisions, except in the case of divisions along the radial axis.
It is also possible to place other volumes inside a volume where a division is placed.

The list of volumes that currently support divisioning and the possible division axis are summarised below:

G4Box kXAxis, kYAxis, kZAxis
G4Tubs kRho, kPhi, kZAxis
G4Cons kRho, kPhi, kZAxis
G4Trd kXAxis, kYAxis, kZAxis
G4Para kXAxis, kYAxis, kZAxis
G4Polycone kRho, kPhi, kZAxis (*)
G4Polyhedra kRho, kPhi, kZAxis (**)

(*) - G4Polycone:

(**) - G4Polyhedra:

In the case of division along kRho of G4Cons, G4Polycone, G4Polyhedra, if width is provided, it is taken as the width at the -Z radius; the width at other radii will be scaled to this one.
Examples are given below in listings 4.1.4 and 4.1.5.

 G4Box* motherSolid = new G4Box("motherSolid", 0.5*m, 0.5*m, 0.5*m);
 G4LogicalVolume* motherLog = new G4LogicalVolume(motherSolid, material, "mother",0,0,0);
 G4Para* divSolid = new G4Para("divSolid", 0.512*m, 1.21*m, 1.43*m);
 G4LogicalVolume* childLog = new G4LogicalVolume(divSolid, material, "child",0,0,0);

 G4PVDivision divBox1("division along X giving nDiv",
                      childLog, motherLog, kXAxis, 5, 0.);

 G4PVDivision divBox2("division along X giving width and offset",
                      childLog, motherLog, kXAxis, 0.1*m, 0.45*m);

 G4PVDivision divBox3("division along X giving nDiv, width and offset",
                      childLog, motherLog, kXAxis, 3, 0.1*m, 0.5*m);
 
Source listing 4.1.5
An example of a box division along different axes, with or without offset.

  G4double* zPlanem = new G4double[3];
            zPlanem[0]= -1.*m;
            zPlanem[1]= -0.25*m;
            zPlanem[2]=  1.*m;
  G4double* rInnerm = new G4double[3];
            rInnerm[0]=0.;
            rInnerm[1]=0.1*m;
            rInnerm[2]=0.5*m;
  G4double* rOuterm  = new G4double[3];
            rOuterm[0]=0.2*m;
            rOuterm[1]=0.4*m;
            rOuterm[2]=1.*m;
  G4Polycone* motherSolid = new G4Polycone("motherSolid", 20.*deg, 180.*deg,
                                           3, zPlanem, rInnerm, rOuterm);
  G4LogicalVolume* motherLog = new G4LogicalVolume(motherSolid, material, "mother",0,0,0);

  G4double* zPlaned = new G4double[3];
            zPlaned[0]= -3.*m;
            zPlaned[1]= -0.*m;
            zPlaned[2]=  1.*m;
  G4double* rInnerd = new G4double[3];
            rInnerd[0]=0.2;
            rInnerd[1]=0.4*m;
            rInnerd[2]=0.5*m;
  G4double* rOuterd  = new G4double[3];
            rOuterd[0]=0.5*m;
            rOuterd[1]=0.8*m;
            rOuterd[2]=2.*m;
  G4Polycone* divSolid = new G4Polycone("divSolid", 0.*deg, 10.*deg,
                                        3, zPlaned, rInnerd, rOuterd);
  G4LogicalVolume* childLog = new G4LogicalVolume(divSolid, material, "child",0,0,0);

  G4PVDivision divPconePhiW("division along phi giving width and offset",
                            childLog, motherLog, kPhi, 30.*deg, 60.*deg);

  G4PVDivision divPconeZN("division along Z giving nDiv and offset",
                          childLog, motherLog, kZAxis, 2, 0.1*m);
 
Source listing 4.1.6
An example of division of a polycone.


About the authors