Creating the Simulation Environment
Summary[edit | edit source]
A good starting point for any simulation is coding the environment in which the simulation will take place. This happens in two places: the Detector Construction class, and the Primary Generator Action class. The Detector Construction class handles all the objects of the world, like tables, detector components, the atmosphere, etc. The Primary Generator Action class generates particles in the simulation.
Detector Construction[edit | edit source]
The World[edit | edit source]
The world is home to all our physics process. Graciously, Geant's developers have implemented and included known materials and physics processes to be used inside of these virtual worlds. Seen in the diagram above, the world can be thought of as Luter Hall which houses many different rooms (envelopes) within it. Since Luter Hall is our fictitious creation, ideally we would like to model it closely to a real world building that is filled with air. But we are at liberty to abstract our world in any way to augment the current experimental configuration. For Luter Hall to exist we need three essential components:
- G4VSolid: To describe a shape, we use a solid volume. The geometry of choice is up to the user. Here we chose to use a G4Box object.
- G4LogicalVolume: To characterize a volume's properties we use a logical volume. It includes the geometrical properties of the solid and adds physical characteristics: the material of the volume; whether it contains any sensitive detector elements; the magnetic field; etc.
- G4PVPlacement: To position the volume, create a physical volume. This places a copy of the logical volume inside a larger containing volume that includes the coordinate system of the world.
Below is an example on how to generate the world volume in the Detector Construction Class:
G4double world_sizeXY = <SCALE_FACTOR*envelope_sizeXY>; G4double world_sizeZ = <SCALE_FACTOR*envelope_sizeZ>; G4Material* world_mat = nist->FindOrBuildMaterial(<"MATERIAL">); G4Box* solidWorld = new G4Box("World", //its name 0.5*world_sizeXY, 0.5*world_sizeXY, 0.5*world_sizeZ); //its size G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld, //its solid world_mat, //its material "World"); //its name G4VPhysicalVolume* physWorld = new G4PVPlacement(0, //no rotation G4ThreeVector(), //at (0,0,0) logicWorld, //its logical volume "World", //its name 0, //its mother volume false, //no boolean operation 0, //copy number checkOverlaps); //overlaps checking
The Envelope[edit | edit source]
The envelope is a smaller volume that exists within the world. While the world volume is created to house all inner volumes, the envelope is where the experiment occurs. In our case, the envelope can be thought of as Lab 345 that exists within Luter Hall. Inside of the envelope, other volumes can be placed and interacted with. Typically, these volumes are detectors or materials that the experiment will be centered around.
- Below is an example on how to generate the envelope volume in the Detector Construction Class:
G4Box* solidEnv = new G4Box(<"Envelope_Name">, 0.5*env_sizeXY, 0.5*env_sizeXY, 0.5*env_sizeZ); G4LogicalVolume* logicEnv = new G4LogicalVolume(solidEnv, env_mat, "Envelope"); new G4PVPlacement(0, //no rotation G4ThreeVector(), //at (0,0,0) logicEnv, //its logical volume <"Envelope_Name">, //its name logicWorld, //its mother volume false, //no boolean operation 0, //copy number checkOverlaps); //overlaps checking
Different Types of Volumes[edit | edit source]
Inside the envelope you may place many different types of volumes to interact with. These volumes act as detectors or materials inside of our Lab in Luter 345. Similar to the world and the envelope, each volume is created by describing its shape and its physical characteristics, but the volumes also inherit the property of scoring. Scoring allows various physical quantities to be tracked while a particle is interacting with the volume.
- Below is an example on how to generate a volume in the Detector Construction Class:
//MATERIAL & POSITION G4Material* shape1_mat = nist->FindOrBuildMaterial(<"MATERIAL">); G4ThreeVector pos1 = G4ThreeVector(<xPOS>,<yPOS>,<zPOS>); // SHAPE 1 CREATION G4Box* solidShape1 = new G4Box("Bottom Scintillator", //its name <Variables->getScintX()*0.5*cm>, //its x length <Variables->getScintY()*0.5*cm>, //its y length <Variables->getScintZ()*0.5*cm>); //its z length //LOGICAL VOLUME G4LogicalVolume* logicShape1 = new G4LogicalVolume(solidShape1, //its solid shape1_mat, //its material "Bottom Scintillator"); //its name new G4PVPlacement(0, //no rotation pos1, //at position logicShape1, //its logical volume "Bottom Scintillator", //its name logicEnv, //its mother volume false, //no boolean operation 0, //copy number checkOverlaps); //overlaps checking // SHAPE 1 SCORING VOLUME fScoringVolume = logicShape1;
Particle Generation[edit | edit source]
Required Definitions for Each Particle[edit | edit source]
Geant4 provides its users with various types of particles for its simulations. These various types of particles include ordinary particles such as electrons, protons,and gammas. It also lets you define more complex particles such as resonant particles, nuclei and quarks. Each of these particles are represented by their own class which is derived from G4ParticleDefinition. This G4ParticleDefinition class is basically a library that holds all of the details required for each particle. Before you do an action you must specify which particle you are using during that action. An example code that is defining a gamma particle
G4ParticleDefinition* particle = particleTable->FindParticle(particleName="gamma");
As you can see, we call the class G4ParticleDefinition and we go through this library looking for "gamma", we then set "gamma" to particleName by this code
fParticleGun->SetParticleDefinition(particle);
After we clarify which particle we want to work with, we then have to set the particles momentum direction and energy level. Here is an example code of us setting the particles momentum and energy level
fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0.,0.,1.)); fParticleGun->SetParticleEnergy(6.*MeV);
Finally, after you pick and clarify which particle you want to use and set its momentum direction and energy level, then you can start an action.
Algorithm for an Arbitrary Probability Distribution[edit | edit source]
Often when generating particles in a simulation, particle energies, directions, and other properties are governed by a probability distribution. This being the case, a simple algorithm for applying arbitrary probability functions in a program is presented below. It should be noted that there are other methods to apply probability distributions and this is not a particularly efficient one, so if a simulation is large it may be beneficial to find another method. However, the method presented is very simple to apply, and thus is a good option for projects when efficiency is not a major concern.
(0) Begin loop (1) Choose a random x value (2) Calculate P(x) of the randomly chosen value (must be adjusted, see note below) (3) Choose a random value between zero and one (uniformRand() function) (4) Compare the random number with the probability of the x value in question (4.a) If P(x) > uniRand : keep the value x (exit loop) (4.b) If P(x) < uniRand : discard the value of x (repeat the loop)
It is of great important the maximum value of P(x), where x is the classical variable, is one. To achieve this, find the value of x where P(x) is at its maximum, x_max, and divide each P(x) in the algorithm by P(x_max).
Using this method the algorithm will return x values in accordance with the defined probability distribution.