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.

Any physical volume must be allocated using ‘new’ in the user’s program; they get registered to a G4PhysicalVolumeStore at construction, which will also take care to deallocate them at the end of the job, if not done already in the user’s code.

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 explicitly -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 dynamically in his/her own application.

Note

Geant4 does not impose any restriction on the name assigned to volumes; names can be shared. It is however good practice to specify unique names for each physical node in a tree, to allow for easier retrivial from stores for post-processing use.

Placements: single positioned copy

In this case, the Physical Volume is created by associating a Logical Volume with a Transformation that defines the position of the current volume in the mother volume. The solid itself is moved by rotating and translating it to bring it into the system of coordinates of the mother volume. The decomposition of the Transformation must contain only rotation and translation (reflection and scaling are not allowed).

To create a Placement one must construct it using:

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

where:

solidTransform

Position in 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

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 Solids made by Boolean operations 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 is to use a Rotation Matrix and a Translation Vector. If compared with the previous construct, the Rotation Matrix is the inverse of the rotation from the decomposition of the transformation, but the Translation Vector is the same. 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. This passive method can be utilized using the following constructor:

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.

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.

An example demonstrating various ways of placement and constructing the rotation matrix is provided in examples/extended/geometry/transforms.

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 most 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:

  • Cartesian axes (kXAxis,kYAxis,kZAxis)

    The replications, of specified width have coordinates of form (-width*(nReplicas-1)*0.5+n*width,0,0) where n=0.. nReplicas-1 for the case of kXAxis, and are unrotated.

    offset is not used.

  • Radial axis (cylindrical polar) (kRho)

    The replications are cons/tubs sections, centred on the origin and are unrotated.

    They have radii of width*n+offset to width*(n+1)+offset where n=0..nReplicas-1

    Thus, offset should be set to the inner radius of the mother.

  • Phi axis (cylindrical polar) (kPhi)

    The replications are phi sections or wedges, and of cons/tubs form.

    They have phi of offset+n*width to offset+(n+1)*width where n=0..nReplicas-1

    Thus, offset should be set to the starting phi of the mother.

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. For example:

  • 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). The position of a particular replica is computed at display time. Similarly, of course, for Y and Z axis replication.

  • For radial replication, the solid should be of the same type as the mother with radii offset to width+offset. The radii of a particular slice is computed at display time. This is only available for G4Tubs - other radially-replicatable volumes are simply not drawn at present (a message is printed).

  • For phi replication, the solid should have a delta-phi equal to the mother's delta-phi/nReplicas. The start-phi should be minus delta-phi/2 so that the local coordinate system corresponds to that of the replica. The position of a particular slice is computed at display time.

Note that the solid does not actually play any part in replica navigation. The above rules are purely for accurate visualisation.

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

Listing 36 An example of simple replicated volumes with G4PVReplica.
G4PVReplica repX("Linear Array",
                 pRepLogical,
                 pContainingMotherBox,
                 kXAxis, 5, 10*mm);

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

G4PVReplica repZ("ZSlices",
                 pRepZLogical,
                 pContainingMotherTub,
                 kZAxis, 5, 10*mm);

G4PVReplica repPhi("PhiSlices",
                   pRepPhiLogical,
                   pContainingMotherTub,
                   kPhi, 4, M_PI*0.5*rad, 0);

RepX is an array of 5 replicas of width 10*mm, positioned inside and completely filling the volume pointed by pContainingMotherBox. 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); repZ divides the tube into 5 shorter cylinders (the solid associated with pRepZLogical must be a tube of radius 10*mm, and half Z length 5*mm); finally, repPhi divides the tube into 4 tube segments with full angle of 90 degrees (the solid associated with pRepPhiLogical must be a tube segment of radius 10*mm, half Z length 5*mm, start phi of minus M_PI*0.25*rad 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 basic example B2b. The implementation is provided in the two classes B2b::DetectorConstruction and B2b::ChamberParameterisation.

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

Listing 37 An example of Parameterised volumes.
// Tracker segments

// An example of Parameterised volumes
// Dummy values for G4Tubs -- modified by parameterised volume

G4Tubs* chamberS
  = new G4Tubs("tracker",0, 100*cm, 100*cm, 0.*deg, 360.*deg);
fLogicChamber
  = new G4LogicalVolume(chamberS,fChamberMaterial,"Chamber",0,0,0);

G4double firstPosition = -trackerSize + chamberSpacing;
G4double firstLength   = trackerLength/10;
G4double lastLength    = trackerLength;

G4VPVParameterisation* chamberParam =
  new ChamberParameterisation(NbOfChambers,   // NoChambers
                              firstPosition,  // Z of center of first
                              chamberSpacing, // Z spacing of centers
                              chamberWidth,   // chamber width
                              firstLength,    // initial length
                              lastLength);    // final length

// dummy value : kZAxis -- modified by parameterised volume

new G4PVParameterised("Chamber",       // their name
                      fLogicChamber,   // their logical volume
                      trackerLV,       // Mother logical volume
                      kZAxis,          // Are placed along this axis
                      NbOfChambers,    // Number of chambers
                      chamberParam,    // The parametrisation
                      fCheckOverlaps); // checking overlaps

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:

  • ComputeTransformation defines where one of the copies is placed,

  • ComputeDimensions defines the size of one copy, and

  • a constructor that initializes any member variables that are required.

An example is B2b::ChamberParameterisation that parameterises a series of tubes of different sizes

Listing 38 An example of Parameterised tubes of different sizes.
namespace B2b
{

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

  void ComputeDimensions(G4Tubs&             trackerLayer,
                         const G4int             copyNo,
                         const G4VPhysicalVolume *physVol) const;
  ...
}

}

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 ChamberParameterisation::ComputeTransformation
(const G4int copyNo, G4VPhysicalVolume *physVol) const
{
  // Note: copyNo will start with zero!
  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 ChamberParameterisation::ComputeDimensions
(G4Tubs& trackerChamber, const G4int copyNo, const G4VPhysicalVolume*) const
{
  // Note: copyNo will start with zero!
  G4double rmax = fRmaxFirst + copyNo * fRmaxIncr;
  trackerChamber.SetInnerRadius(0);
  trackerChamber.SetOuterRadius(rmax);
  trackerChamber.SetZHalfLength(fHalfWidth);
  trackerChamber.SetStartPhiAngle(0.*deg);
  trackerChamber.SetDeltaPhiAngle(360.*deg);
}

The user must ensure that the type of the first argument of this method (in this example G4Tubs &) corresponds to the type of object the user give to the logical volume of parameterised physical volume.

More advanced usage allows the user:

  • to change the type of solid by creating a ComputeSolid method, or

  • to change the material of the volume by creating a ComputeMaterial method. This method can also utilise information from a parent or other ancestor volume (see the Nested Parameterisation below.)

for the parameterisation.

Example examples/extended/runAndEvent/RE02 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.

Note

A hierarchy of volumes included in a parameterised volume cannot vary. Therefore, it is not possible to implement a parameterisation which can modify the hierarchy of volumes included inside a specific parameterised copy.

Note

For parameterisations of tubes or cons, where the starting Phi and its DeltaPhi angles vary, it is possible to optimise the regeneration of the trigonometric parameters of the shape, by invoking SetStartPhiAngle(newPhi, false); SetDeltaPhiAngle (newDPhi), i.e. by specifying with false flag to skip the computation of the parameters which will be later on properly initialised with the call for DeltaPhi.

Note

Parameterisations of composed solids like Boolean, Reflected or Displaced solids are not recommended, given the complexity in handling transformations that this might imply, and limitations in making persistent representations (i.e. GDML) of the geometry itself.

Note

For multi-threaded applications, one must be careful in the implementation of the parameterisation functions for the geometrical objects being created in the parameterisation. In particular, when parameterising by the type of a solid, it is assumed that the solids being parameterised are being declared thread-local in the user’s parameterisation class and allocated just once.

Advanced parameterisations for ‘nested’ parameterised volumes

A different 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.

Note

You can also switch the colour of individual volumes by changing the vis attributes in your ComputeMaterial - see examples//extended/medical/DICOM or examples/advanced/ICRP110_HumanPhantoms.

Note

The number of parameterised volumes can become very large, in the 10’s of millions for a medical phantom, for example. This can give the graphics system a headache. See Visualization of a parameterised volume for economical ways of visualising such parameterisations.

Divisions of Volumes

Divisions in Geant4 are repeated volumes and 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 daughters 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

    • the number of divisions (so that the width of each division will be automatically calculated), or

    • the division width (so that the number of divisions will be automatically calculated to fill as much of the mother as possible), or

    • both the number of divisions and the division width (this is especially designed for the case where the copies do not fully fill the mother).

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:

  • Giving only the number of divisions:

    G4PVDivision( const G4String& pName,
                        G4LogicalVolume* pCurrentLogical,
                        G4LogicalVolume* pMotherLogical,
                  const EAxis pAxis,
                  const G4int nDivisions,
                  const G4double offset )
    
  • Giving only the division width:

    G4PVDivision( const G4String& pName,
                        G4LogicalVolume* pCurrentLogical,
                        G4LogicalVolume* pMotherLogical,
                  const EAxis pAxis,
                  const G4double width,
                  const G4double offset )
    
  • Giving the number of divisions and the division width:

    G4PVDivision( const G4String& pName,
                        G4LogicalVolume* pCurrentLogical,
                        G4LogicalVolume* pMotherLogical,
                  const EAxis pAxis,
                  const G4int nDivisions,
                  const G4double width,
                  const G4double offset )
    

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 (*)

(*) - G4Polyhedra:

  • kPhi - the number of divisions has to be the same as solid sides, (i.e. numSides), the width will not be taken into account.

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 Listing 37 and Listing 39.

Listing 39 An example of a box division along different axes, with or without offset.
 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);
  • divBox1 is a division of a box along its X axis in 5 equal copies. Each copy will have a dimension in meters of [0.2, 1., 1.].

  • divBox2 is a division of the same box along its X axis with a width of 0.1 meters and an offset of 0.5 meters. As the mother dimension along X of 1 meter (0.5*m of halflength), the division will be sized in total 1 - 0.45 = 0.55 meters. Therefore, there’s space for 5 copies, the first extending from -0.05 to 0.05 meters in the mother’s frame and the last from 0.35 to 0.45 meters.

  • divBox3 is a division of the same box along its X axis in 3 equal copies of width 0.1 meters and an offset of 0.5 meters. The first copy will extend from 0. to 0.1 meters in the mother’s frame and the last from 0.2 to 0.3 meters.

Listing 40 An example of division of a polycone.
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);
  • divPconePhiW is a division of a polycone along its phi axis in equal copies of width 30 degrees with an offset of 60 degrees. As the mother extends from 0 to 180 degrees, there’s space for 4 copies. All the copies have a starting angle of 20 degrees (as for the mother) and a phi extension of 30 degrees. They are rotated around the Z axis by 60 and 30 degrees, so that the first copy will extend from 80 to 110 and the last from 170 to 200 degrees.

  • divPconeZN is a division of the same polycone along its Z axis. As the mother polycone has two sections, it will be divided in two one-section polycones, the first one extending from -1 to -0.25 meters, the second from -0.25 to 1 meters. Although specified, the offset will not be used.

Replicated Slices

A special kind of divided volume is represented by G4ReplicatedSlice, a division allowing for gaps inbetween divided volumes.

Three constructors, corresponding to three input possibilities are provided:

  • Giving only the number of divisions:

    G4ReplicatedSlice( const G4String& pName,
                             G4LogicalVolume* pCurrentLogical,
                             G4LogicalVolume* pMotherLogical,
                       const EAxis pAxis,
                       const G4int nDivisions,
                       const G4double half_gap,
                       const G4double offset )
    
  • Giving only the division width:

    G4ReplicatedSlice( const G4String& pName,
                             G4LogicalVolume* pCurrentLogical,
                             G4LogicalVolume* pMotherLogical,
                       const EAxis pAxis,
                       const G4double width,
                       const G4double half_gap,
                       const G4double offset )
    
  • Giving the number of divisions and the division width:

    G4ReplicatedSlice( const G4String& pName,
                             G4LogicalVolume* pCurrentLogical,
                             G4LogicalVolume* pMotherLogical,
                       const EAxis pAxis,
                       const G4int nDivisions,
                       const G4double width,
                       const G4double half_gap,
                       const G4double offset )
    

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

half_gap

The half width of the gap to be considered inbetween division slices

offset

Possible offset associated to the mother along the axis of division

As for G4PVDivision, the parameterisation is calculated automatically using the values provided in input.