Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-15 08:28:22

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file DetectorConstruction.cc
0027 /// \brief Implementation of the DetectorConstruction class
0028 
0029 #include "DetectorConstruction.hh"
0030 
0031 #include "DetectorMessenger.hh"
0032 
0033 #include "G4AutoDelete.hh"
0034 #include "G4Box.hh"
0035 #include "G4GeometryManager.hh"
0036 #include "G4GlobalMagFieldMessenger.hh"
0037 #include "G4LogicalVolume.hh"
0038 #include "G4LogicalVolumeStore.hh"
0039 #include "G4Material.hh"
0040 #include "G4NistManager.hh"
0041 #include "G4PVPlacement.hh"
0042 #include "G4PhysicalConstants.hh"
0043 #include "G4PhysicalVolumeStore.hh"
0044 #include "G4RunManager.hh"
0045 #include "G4SolidStore.hh"
0046 #include "G4SystemOfUnits.hh"
0047 #include "G4UniformMagField.hh"
0048 #include "G4UnitsTable.hh"
0049 
0050 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0051 
0052 DetectorConstruction::DetectorConstruction()
0053 {
0054   // default parameter values of the calorimeter
0055   fAbsorberThickness = 1. * cm;
0056   fAbsorberSizeYZ = 2. * cm;
0057   fXposAbs = 0. * cm;
0058   ComputeGeomParameters();
0059 
0060   // materials
0061   DefineMaterials();
0062   SetWorldMaterial("G4_Galactic");
0063   SetAbsorberMaterial("G4_Si");
0064 
0065   // create commands for interactive definition of the calorimeter
0066   fDetectorMessenger = new DetectorMessenger(this);
0067 }
0068 
0069 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0070 
0071 DetectorConstruction::~DetectorConstruction()
0072 {
0073   delete fDetectorMessenger;
0074 }
0075 
0076 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0077 
0078 void DetectorConstruction::DefineMaterials()
0079 {
0080   // This function illustrates the possible ways to define materials
0081 
0082   G4String symbol;  // a=mass of a mole;
0083   G4double a, z, density;  // z=mean number of protons;
0084 
0085   G4int ncomponents, natoms;
0086   G4double fractionmass;
0087   G4double temperature, pressure;
0088 
0089   //
0090   // define Elements
0091   //
0092 
0093   G4Element* H = new G4Element("Hydrogen", symbol = "H", z = 1, a = 1.01 * g / mole);
0094   G4Element* C = new G4Element("Carbon", symbol = "C", z = 6, a = 12.01 * g / mole);
0095   G4Element* N = new G4Element("Nitrogen", symbol = "N", z = 7, a = 14.01 * g / mole);
0096   G4Element* O = new G4Element("Oxygen", symbol = "O", z = 8, a = 16.00 * g / mole);
0097   G4Element* Na = new G4Element("Sodium", symbol = "Na", z = 11, a = 22.99 * g / mole);
0098   G4Element* Ar = new G4Element("Argon", symbol = "Ar", z = 18, a = 39.95 * g / mole);
0099   G4Element* I = new G4Element("Iodine", symbol = "I", z = 53, a = 126.90 * g / mole);
0100   G4Element* Xe = new G4Element("Xenon", symbol = "Xe", z = 54, a = 131.29 * g / mole);
0101 
0102   //
0103   // define simple materials
0104   //
0105 
0106   new G4Material("H2Liq", z = 1, a = 1.01 * g / mole, density = 70.8 * mg / cm3);
0107   new G4Material("Beryllium", z = 4, a = 9.01 * g / mole, density = 1.848 * g / cm3);
0108   new G4Material("Aluminium", z = 13, a = 26.98 * g / mole, density = 2.700 * g / cm3);
0109   new G4Material("Silicon", z = 14, a = 28.09 * g / mole, density = 2.330 * g / cm3);
0110 
0111   G4Material* lAr = new G4Material("liquidArgon", density = 1.390 * g / cm3, ncomponents = 1);
0112   lAr->AddElement(Ar, natoms = 1);
0113 
0114   new G4Material("Iron", z = 26, a = 55.85 * g / mole, density = 7.870 * g / cm3);
0115   new G4Material("Copper", z = 29, a = 63.55 * g / mole, density = 8.960 * g / cm3);
0116   new G4Material("Germanium", z = 32, a = 72.61 * g / mole, density = 5.323 * g / cm3);
0117   new G4Material("Silver", z = 47, a = 107.87 * g / mole, density = 10.50 * g / cm3);
0118   new G4Material("Tungsten", z = 74, a = 183.85 * g / mole, density = 19.30 * g / cm3);
0119   new G4Material("Gold", z = 79, a = 196.97 * g / mole, density = 19.32 * g / cm3);
0120   new G4Material("Lead", z = 82, a = 207.19 * g / mole, density = 11.35 * g / cm3);
0121 
0122   //
0123   // define a material from elements.   case 1: chemical molecule
0124   //
0125 
0126   G4Material* H2O = new G4Material("Water", density = 1.000 * g / cm3, ncomponents = 2);
0127   H2O->AddElement(H, natoms = 2);
0128   H2O->AddElement(O, natoms = 1);
0129   H2O->GetIonisation()->SetMeanExcitationEnergy(78 * eV);
0130 
0131   G4Material* CH = new G4Material("Plastic", density = 1.04 * g / cm3, ncomponents = 2);
0132   CH->AddElement(C, natoms = 1);
0133   CH->AddElement(H, natoms = 1);
0134 
0135   G4Material* NaI = new G4Material("NaI", density = 3.67 * g / cm3, ncomponents = 2);
0136   NaI->AddElement(Na, natoms = 1);
0137   NaI->AddElement(I, natoms = 1);
0138   NaI->GetIonisation()->SetMeanExcitationEnergy(452 * eV);
0139 
0140   //
0141   // define a material from elements.   case 2: mixture by fractional mass
0142   //
0143 
0144   G4Material* Air = new G4Material("Air", density = 1.290 * mg / cm3, ncomponents = 2);
0145   Air->AddElement(N, fractionmass = 0.7);
0146   Air->AddElement(O, fractionmass = 0.3);
0147 
0148   G4Material* Air20 = new G4Material("Air20", density = 1.205 * mg / cm3, ncomponents = 2,
0149                                      kStateGas, 293. * kelvin, 1. * atmosphere);
0150   Air20->AddElement(N, fractionmass = 0.7);
0151   Air20->AddElement(O, fractionmass = 0.3);
0152 
0153   // Graphite
0154   //
0155   G4Material* Graphite = new G4Material("Graphite", density = 1.7 * g / cm3, ncomponents = 1);
0156   Graphite->AddElement(C, fractionmass = 1.);
0157 
0158   // Havar
0159   //
0160   G4Element* Cr = new G4Element("Chrome", "Cr", z = 24, a = 51.996 * g / mole);
0161   G4Element* Fe = new G4Element("Iron", "Fe", z = 26, a = 55.845 * g / mole);
0162   G4Element* Co = new G4Element("Cobalt", "Co", z = 27, a = 58.933 * g / mole);
0163   G4Element* Ni = new G4Element("Nickel", "Ni", z = 28, a = 58.693 * g / mole);
0164   G4Element* W = new G4Element("Tungsten", "W", z = 74, a = 183.850 * g / mole);
0165 
0166   G4Material* Havar = new G4Material("Havar", density = 8.3 * g / cm3, ncomponents = 5);
0167   Havar->AddElement(Cr, fractionmass = 0.1785);
0168   Havar->AddElement(Fe, fractionmass = 0.1822);
0169   Havar->AddElement(Co, fractionmass = 0.4452);
0170   Havar->AddElement(Ni, fractionmass = 0.1310);
0171   Havar->AddElement(W, fractionmass = 0.0631);
0172 
0173   //
0174   // examples of gas
0175   //
0176   new G4Material("ArgonGas", z = 18, a = 39.948 * g / mole, density = 1.782 * mg / cm3, kStateGas,
0177                  273.15 * kelvin, 1 * atmosphere);
0178 
0179   new G4Material("XenonGas", z = 54, a = 131.29 * g / mole, density = 5.458 * mg / cm3, kStateGas,
0180                  293.15 * kelvin, 1 * atmosphere);
0181 
0182   G4Material* CO2 = new G4Material("CarbonicGas", density = 1.977 * mg / cm3, ncomponents = 2);
0183   CO2->AddElement(C, natoms = 1);
0184   CO2->AddElement(O, natoms = 2);
0185 
0186   G4Material* ArCO2 = new G4Material("ArgonCO2", density = 1.8223 * mg / cm3, ncomponents = 2);
0187   ArCO2->AddElement(Ar, fractionmass = 0.7844);
0188   ArCO2->AddMaterial(CO2, fractionmass = 0.2156);
0189 
0190   // another way to define mixture of gas per volume
0191   G4Material* NewArCO2 =
0192     new G4Material("NewArgonCO2", density = 1.8223 * mg / cm3, ncomponents = 3);
0193   NewArCO2->AddElement(Ar, natoms = 8);
0194   NewArCO2->AddElement(C, natoms = 2);
0195   NewArCO2->AddElement(O, natoms = 4);
0196 
0197   G4Material* ArCH4 = new G4Material("ArgonCH4", density = 1.709 * mg / cm3, ncomponents = 3);
0198   ArCH4->AddElement(Ar, natoms = 93);
0199   ArCH4->AddElement(C, natoms = 7);
0200   ArCH4->AddElement(H, natoms = 28);
0201 
0202   G4Material* XeCH = new G4Material("XenonMethanePropane", density = 4.9196 * mg / cm3,
0203                                     ncomponents = 3, kStateGas, 293.15 * kelvin, 1 * atmosphere);
0204   XeCH->AddElement(Xe, natoms = 875);
0205   XeCH->AddElement(C, natoms = 225);
0206   XeCH->AddElement(H, natoms = 700);
0207 
0208   G4Material* steam = new G4Material("WaterSteam", density = 1.0 * mg / cm3, ncomponents = 1);
0209   steam->AddMaterial(H2O, fractionmass = 1.);
0210   steam->GetIonisation()->SetMeanExcitationEnergy(71.6 * eV);
0211 
0212   G4Material* rock1 = new G4Material("StandardRock", 2.65 * CLHEP::g / CLHEP::cm3, 1, kStateSolid);
0213   rock1->AddElement(Na, 1);
0214 
0215   //
0216   // example of vacuum
0217   //
0218   density = universe_mean_density;  // from PhysicalConstants.h
0219   pressure = 3.e-18 * pascal;
0220   temperature = 2.73 * kelvin;
0221   new G4Material("Galactic", z = 1, a = 1.01 * g / mole, density, kStateGas, temperature, pressure);
0222 }
0223 
0224 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0225 
0226 void DetectorConstruction::ComputeGeomParameters()
0227 {
0228   // Compute derived parameters of the calorimeter
0229   fXstartAbs = fXposAbs - 0.5 * fAbsorberThickness;
0230   fXendAbs = fXposAbs + 0.5 * fAbsorberThickness;
0231 
0232   G4double xmax = std::max(std::abs(fXstartAbs), std::abs(fXendAbs));
0233   fWorldSizeX = 2.4 * xmax;
0234   fWorldSizeYZ = 1.2 * fAbsorberSizeYZ;
0235   if (nullptr != fPhysiWorld) {
0236     ChangeGeometry();
0237   }
0238 }
0239 
0240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0241 
0242 G4VPhysicalVolume* DetectorConstruction::Construct()
0243 {
0244   if (nullptr != fPhysiWorld) {
0245     return fPhysiWorld;
0246   }
0247   // World
0248   //
0249   fSolidWorld = new G4Box("World",  // its name
0250                           fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2);  // its size
0251 
0252   fLogicWorld = new G4LogicalVolume(fSolidWorld,  // its solid
0253                                     fWorldMaterial,  // its material
0254                                     "World");  // its name
0255 
0256   fPhysiWorld = new G4PVPlacement(0,  // no rotation
0257                                   G4ThreeVector(0., 0., 0.),  // at (0,0,0)
0258                                   fLogicWorld,  // its logical volume
0259                                   "World",  // its name
0260                                   0,  // its mother  volume
0261                                   false,  // no boolean operation
0262                                   0);  // copy number
0263 
0264   // Absorber
0265   //
0266   fSolidAbsorber =
0267     new G4Box("Absorber", fAbsorberThickness / 2, fAbsorberSizeYZ / 2, fAbsorberSizeYZ / 2);
0268 
0269   fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber,  // its solid
0270                                        fAbsorberMaterial,  // its material
0271                                        "Absorber");  // its name
0272 
0273   fPhysiAbsorber = new G4PVPlacement(0,  // no rotation
0274                                      G4ThreeVector(fXposAbs, 0., 0.),  // its position
0275                                      fLogicAbsorber,  // its logical volume
0276                                      "Absorber",  // its name
0277                                      fLogicWorld,  // its mother
0278                                      false,  // no boulean operat
0279                                      0);  // copy number
0280 
0281   PrintGeomParameters();
0282 
0283   // always return the physical World
0284   //
0285   return fPhysiWorld;
0286 }
0287 
0288 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0289 
0290 void DetectorConstruction::PrintGeomParameters()
0291 {
0292   G4cout << "\n" << fWorldMaterial << G4endl;
0293   G4cout << "\n" << fAbsorberMaterial << G4endl;
0294 
0295   G4cout << "\n The  WORLD   is made of " << G4BestUnit(fWorldSizeX, "Length") << " of "
0296          << fWorldMaterial->GetName();
0297   G4cout << ". The transverse size (YZ) of the world is " << G4BestUnit(fWorldSizeYZ, "Length")
0298          << G4endl;
0299   G4cout << " The ABSORBER is made of " << G4BestUnit(fAbsorberThickness, "Length") << " of "
0300          << fAbsorberMaterial->GetName();
0301   G4cout << ". The transverse size (YZ) is " << G4BestUnit(fAbsorberSizeYZ, "Length") << G4endl;
0302   G4cout << " X position of the middle of the absorber " << G4BestUnit(fXposAbs, "Length");
0303   G4cout << G4endl;
0304 }
0305 
0306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0307 
0308 void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice)
0309 {
0310   // search the material by its name
0311   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0312 
0313   if (pttoMaterial && fAbsorberMaterial != pttoMaterial) {
0314     fAbsorberMaterial = pttoMaterial;
0315     if (fLogicAbsorber) {
0316       fLogicAbsorber->SetMaterial(fAbsorberMaterial);
0317     }
0318     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0319   }
0320 }
0321 
0322 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0323 
0324 void DetectorConstruction::SetWorldMaterial(const G4String& materialChoice)
0325 {
0326   // search the material by its name
0327   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0328 
0329   if (pttoMaterial && fWorldMaterial != pttoMaterial) {
0330     fWorldMaterial = pttoMaterial;
0331     if (fLogicWorld) {
0332       fLogicWorld->SetMaterial(fWorldMaterial);
0333     }
0334     G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0335   }
0336 }
0337 
0338 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0339 
0340 void DetectorConstruction::SetAbsorberThickness(G4double val)
0341 {
0342   fAbsorberThickness = val;
0343   ComputeGeomParameters();
0344 }
0345 
0346 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0347 
0348 void DetectorConstruction::SetAbsorberSizeYZ(G4double val)
0349 {
0350   fAbsorberSizeYZ = val;
0351   ComputeGeomParameters();
0352 }
0353 
0354 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0355 
0356 void DetectorConstruction::SetWorldSizeX(G4double val)
0357 {
0358   fWorldSizeX = val;
0359   ComputeGeomParameters();
0360 }
0361 
0362 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0363 
0364 void DetectorConstruction::SetWorldSizeYZ(G4double val)
0365 {
0366   fWorldSizeYZ = val;
0367   ComputeGeomParameters();
0368 }
0369 
0370 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0371 
0372 void DetectorConstruction::SetAbsorberXpos(G4double val)
0373 {
0374   fXposAbs = val;
0375   ComputeGeomParameters();
0376 }
0377 
0378 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
0379 
0380 void DetectorConstruction::ConstructSDandField()
0381 {
0382   if (fFieldMessenger.Get() == 0) {
0383     // Create global magnetic field messenger.
0384     // Uniform magnetic field is then created automatically if
0385     // the field value is not zero.
0386     G4ThreeVector fieldValue = G4ThreeVector();
0387     G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue);
0388     // msg->SetVerboseLevel(1);
0389     G4AutoDelete::Register(msg);
0390     fFieldMessenger.Put(msg);
0391   }
0392 }
0393 
0394 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0395 
0396 void DetectorConstruction::ChangeGeometry()
0397 {
0398   fSolidWorld->SetXHalfLength(fWorldSizeX * 0.5);
0399   fSolidWorld->SetYHalfLength(fWorldSizeYZ * 0.5);
0400   fSolidWorld->SetZHalfLength(fWorldSizeYZ * 0.5);
0401 
0402   fSolidAbsorber->SetXHalfLength(fAbsorberThickness * 0.5);
0403   fSolidAbsorber->SetYHalfLength(fAbsorberSizeYZ * 0.5);
0404   fSolidAbsorber->SetZHalfLength(fAbsorberSizeYZ * 0.5);
0405 }
0406 
0407 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......