Parallel Geometries

A parallel world

Occasionally, it is not straightforward to define geometries for sensitive detectors, importance geometries or envelopes for shower parameterization to be coherently assigned to volumes in the tracking (mass) geometry. The parallel navigation functionality introduced since release 8.2 of Geant4, allows the user to define more than one world simultaneously. The G4CoupledTransportation process will see all worlds simultaneously; steps will be limited by every boundaries of the mass and parallel geometries. G4Transportation is automatically replaced G4CoupledTransportation.

In a parallel world, the user can define volumes in arbitrary manner with sensitivity, regions, shower parameterization setups, and/or importance weight for biasing. Volumes in different worlds may overlap.

Any kind of G4VSensitiveDetector object can be defined in volumes in a parallel world, exactly at the same manner for the mass geometry. G4Step object given as an argument of ProcessHit() method contains geometrical information of the associated world.

Here are restrictions to be considered for the parallel geometry:

  • Production thresholds and EM field are used only from the mass geometry. Even if such physical quantities are defined in a parallel world, they do not affect to the simulation.

  • Although all worlds will be comprehensively taken care by the G4CoupledTransportation process for the navigation, each parallel world must have its own unique object of G4ParallelWorldProcess process (for instance created with G4ParallelWorldPhysics constructor registered to a modular physics list).

  • Volumes in a parallel world may have materials. Such materials overwrite the materials defined in the mass geometry if the "layered mass geometry" switch of the G4ParallelWorldProcess constructor is set.

Defining a parallel world

A parallel world should be defined in the Construct() virtual method of the user’s class derived from the abstract base class G4VUserParallelWorld. If needed, sensitive detectors must be defined in the ConstructSD() method of the same derived class. Please note that EM field cannot be defined in a parallel world.

Listing 58 An example header file of a concrete user parallel world class.
#ifndef MyParallelWorld_h
#define MyParallelWorld_h 1

#include "globals.hh"
#include "G4VUserParallelWorld.hh"

class MyParallelWorld : public G4VUserParallelWorld
{
  public:
    MyParallelWorld(G4String worldName);
    virtual ~MyParallelWorld();

  public:
    virtual void Construct();
    virtual void ConstructSD();
};

#endif

A parallel world must have its unique name, which should be set to the G4VUserParallelWorld base class as an argument of the base class constructor.

The world physical volume of the parallel world is provided by the G4RunManager as a clone of the mass geometry. In the Construct() virtual method of the user’s class, the pointer to this cloned world physical volume is available through the GetWorld() method defined in the base class. The user should fill the volumes in the parallel world by using this provided world volume. For a logical volume in a parallel world, the material pointer can be nullptr. Even if specified a valid material pointer, unless "layered mass geometry" switch of the G4ParallelWorldProcess constructor is set, it will not be taken into account by any physics process.

Listing 59 An example source code of a concrete user parallel world class.
#include "MyParallelWorld.hh"
#include "G4LogicalVolume.hh"
#include "G4VPhysicalVolume.hh"
#include "G4Box.hh"
#include "G4PVPlacement.hh"

MyParallelWorld::MyParallelWorld(G4String worldName)
:G4VUserParallelWorld(worldName)
{;}

MyParallelWorld::~MyParallelWorld()
{;}

void MyParallelWorld::Construct()
{
  G4VPhysicalVolume* ghostWorld = GetWorld();
  G4LogicalVolume* worldLogical = ghostWorld->GetLogicalVolume();

  // place volumes in the parallel world here. For example ...
  //
  G4Box * ghostSolid = new G4Box("GhostdBox", 60.*cm, 60.*cm, 60.*cm);
  G4LogicalVolume * ghostLogical
        = new G4LogicalVolume(ghostSolid, 0, "GhostLogical", 0, 0, 0);
  new G4PVPlacement(0, G4ThreeVector(), ghostLogical,
                    "GhostPhysical", worldLogical, 0, 0);
}

In case the user needs to define more than one parallel worlds, each of them must be implemented through its dedicated class. Each parallel world should be registered to the mass geometry class using the method RegisterParallelWorld() available through the class G4VUserDetectorConstruction. The registration must be done before the mass world is registered to the G4RunManager. Each parallel world should also have its own G4ParallelWorldPhysics constructor registered to the physics list using the method RegisterPhysics() available through the class G4VModularPhysicsList.

Listing 60 Typical implementation in the main() to define a parallel world.
// RunManager construction
//
G4RunManager* runManager = new G4RunManager;

// mass world
//
MyDetectorConstruction* massWorld = new MyDetectorConstruction;

// parallel world
//
G4String paraWorldName = "ParallelWorld";
massWorld->RegisterParallelWorld(new MyParallelWorld(paraWorldName));

// set mass world to run manager
//
runManager->SetUserInitialization(massWorld);

// physics list
//
G4VModularPhysicsList* physicsList = new FTFP_BERT;
physicsList->RegisterPhysics(new G4ParallelWorldPhysics(paraWorldName));
runManager->SetUserInitialization(physicsList);

Layered mass geometry

If "layered mass geometry" switch of the G4ParallelWorldProcess constructor is set, that parallel world is conceptually layered on top of the mass geometry. If more than one parallel worlds are defined, later-defined world comes on top of others. A track will see the material of the top layer, if it is nullptr, then one layer beneath. Thus, user has to make sure volumes in a parallel world should have nullptr as their materials except for volumes he/she really wants to overwrite.

Listing 61 Typical implementation in the main() to define a layered mass geometry.
// RunManager construction
//
G4RunManager* runManager = new G4RunManager;

// mass world
//
MyDetectorConstruction* massWorld = new MyDetectorConstruction;

// parallel world
//
G4String paraWorldName = "ParallelWorld";
massWorld->RegisterParallelWorld(new MyParallelWorld(paraWorldName));

// set mass world to run manager
//
runManager->SetUserInitialization(massWorld);

// physics list
//
G4VModularPhysicsList* physicsList = new FTFP_BERT;
physicsList->RegisterPhysics(new G4ParallelWorldPhysics(paraWorldName,true));
runManager->SetUserInitialization(physicsList);

For an information to advanced users, instead of using G4ParallelWorldPhysics physics constructor, once can define G4ParallelWorldProcess in his/her physics list and assign it only to some selected kind of particle types. In this case, this parallel world will be seen only by these kinds of particles.