Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /// \file electromagnetic/TestEm5/src/DetectorConstruction.cc 27 /// \brief Implementation of the DetectorConstruction class 28 // 29 // 30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 32 33 #include "DetectorConstruction.hh" 34 35 #include "DetectorMessenger.hh" 36 37 #include "G4AutoDelete.hh" 38 #include "G4Box.hh" 39 #include "G4GeometryManager.hh" 40 #include "G4GlobalMagFieldMessenger.hh" 41 #include "G4LogicalVolume.hh" 42 #include "G4LogicalVolumeStore.hh" 43 #include "G4Material.hh" 44 #include "G4NistManager.hh" 45 #include "G4PVPlacement.hh" 46 #include "G4PhysicalConstants.hh" 47 #include "G4PhysicalVolumeStore.hh" 48 #include "G4RunManager.hh" 49 #include "G4SolidStore.hh" 50 #include "G4SystemOfUnits.hh" 51 #include "G4UniformMagField.hh" 52 #include "G4UnitsTable.hh" 53 54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 56 DetectorConstruction::DetectorConstruction() 57 { 58 // default parameter values of the calorimeter 59 fAbsorberThickness = 1. * cm; 60 fAbsorberSizeYZ = 2. * cm; 61 fXposAbs = 0. * cm; 62 ComputeGeomParameters(); 63 64 // materials 65 DefineMaterials(); 66 SetWorldMaterial("G4_Galactic"); 67 SetAbsorberMaterial("G4_Si"); 68 69 // create commands for interactive definition of the calorimeter 70 fDetectorMessenger = new DetectorMessenger(this); 71 } 72 73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 74 75 DetectorConstruction::~DetectorConstruction() 76 { 77 delete fDetectorMessenger; 78 } 79 80 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 81 82 void DetectorConstruction::DefineMaterials() 83 { 84 // This function illustrates the possible ways to define materials 85 86 G4String symbol; // a=mass of a mole; 87 G4double a, z, density; // z=mean number of protons; 88 89 G4int ncomponents, natoms; 90 G4double fractionmass; 91 G4double temperature, pressure; 92 93 // 94 // define Elements 95 // 96 97 G4Element* H = new G4Element("Hydrogen", symbol = "H", z = 1, a = 1.01 * g / mole); 98 G4Element* C = new G4Element("Carbon", symbol = "C", z = 6, a = 12.01 * g / mole); 99 G4Element* N = new G4Element("Nitrogen", symbol = "N", z = 7, a = 14.01 * g / mole); 100 G4Element* O = new G4Element("Oxygen", symbol = "O", z = 8, a = 16.00 * g / mole); 101 G4Element* Na = new G4Element("Sodium", symbol = "Na", z = 11, a = 22.99 * g / mole); 102 G4Element* Ar = new G4Element("Argon", symbol = "Ar", z = 18, a = 39.95 * g / mole); 103 G4Element* I = new G4Element("Iodine", symbol = "I", z = 53, a = 126.90 * g / mole); 104 G4Element* Xe = new G4Element("Xenon", symbol = "Xe", z = 54, a = 131.29 * g / mole); 105 106 // 107 // define simple materials 108 // 109 110 new G4Material("H2Liq", z = 1, a = 1.01 * g / mole, density = 70.8 * mg / cm3); 111 new G4Material("Beryllium", z = 4, a = 9.01 * g / mole, density = 1.848 * g / cm3); 112 new G4Material("Aluminium", z = 13, a = 26.98 * g / mole, density = 2.700 * g / cm3); 113 new G4Material("Silicon", z = 14, a = 28.09 * g / mole, density = 2.330 * g / cm3); 114 115 G4Material* lAr = new G4Material("liquidArgon", density = 1.390 * g / cm3, ncomponents = 1); 116 lAr->AddElement(Ar, natoms = 1); 117 118 new G4Material("Iron", z = 26, a = 55.85 * g / mole, density = 7.870 * g / cm3); 119 new G4Material("Copper", z = 29, a = 63.55 * g / mole, density = 8.960 * g / cm3); 120 new G4Material("Germanium", z = 32, a = 72.61 * g / mole, density = 5.323 * g / cm3); 121 new G4Material("Silver", z = 47, a = 107.87 * g / mole, density = 10.50 * g / cm3); 122 new G4Material("Tungsten", z = 74, a = 183.85 * g / mole, density = 19.30 * g / cm3); 123 new G4Material("Gold", z = 79, a = 196.97 * g / mole, density = 19.32 * g / cm3); 124 new G4Material("Lead", z = 82, a = 207.19 * g / mole, density = 11.35 * g / cm3); 125 126 // 127 // define a material from elements. case 1: chemical molecule 128 // 129 130 G4Material* H2O = new G4Material("Water", density = 1.000 * g / cm3, ncomponents = 2); 131 H2O->AddElement(H, natoms = 2); 132 H2O->AddElement(O, natoms = 1); 133 H2O->GetIonisation()->SetMeanExcitationEnergy(78 * eV); 134 135 G4Material* CH = new G4Material("Plastic", density = 1.04 * g / cm3, ncomponents = 2); 136 CH->AddElement(C, natoms = 1); 137 CH->AddElement(H, natoms = 1); 138 139 G4Material* NaI = new G4Material("NaI", density = 3.67 * g / cm3, ncomponents = 2); 140 NaI->AddElement(Na, natoms = 1); 141 NaI->AddElement(I, natoms = 1); 142 NaI->GetIonisation()->SetMeanExcitationEnergy(452 * eV); 143 144 // 145 // define a material from elements. case 2: mixture by fractional mass 146 // 147 148 G4Material* Air = new G4Material("Air", density = 1.290 * mg / cm3, ncomponents = 2); 149 Air->AddElement(N, fractionmass = 0.7); 150 Air->AddElement(O, fractionmass = 0.3); 151 152 G4Material* Air20 = new G4Material("Air20", density = 1.205 * mg / cm3, ncomponents = 2, 153 kStateGas, 293. * kelvin, 1. * atmosphere); 154 Air20->AddElement(N, fractionmass = 0.7); 155 Air20->AddElement(O, fractionmass = 0.3); 156 157 // Graphite 158 // 159 G4Material* Graphite = new G4Material("Graphite", density = 1.7 * g / cm3, ncomponents = 1); 160 Graphite->AddElement(C, fractionmass = 1.); 161 162 // Havar 163 // 164 G4Element* Cr = new G4Element("Chrome", "Cr", z = 24, a = 51.996 * g / mole); 165 G4Element* Fe = new G4Element("Iron", "Fe", z = 26, a = 55.845 * g / mole); 166 G4Element* Co = new G4Element("Cobalt", "Co", z = 27, a = 58.933 * g / mole); 167 G4Element* Ni = new G4Element("Nickel", "Ni", z = 28, a = 58.693 * g / mole); 168 G4Element* W = new G4Element("Tungsten", "W", z = 74, a = 183.850 * g / mole); 169 170 G4Material* Havar = new G4Material("Havar", density = 8.3 * g / cm3, ncomponents = 5); 171 Havar->AddElement(Cr, fractionmass = 0.1785); 172 Havar->AddElement(Fe, fractionmass = 0.1822); 173 Havar->AddElement(Co, fractionmass = 0.4452); 174 Havar->AddElement(Ni, fractionmass = 0.1310); 175 Havar->AddElement(W, fractionmass = 0.0631); 176 177 // 178 // examples of gas 179 // 180 new G4Material("ArgonGas", z = 18, a = 39.948 * g / mole, density = 1.782 * mg / cm3, kStateGas, 181 273.15 * kelvin, 1 * atmosphere); 182 183 new G4Material("XenonGas", z = 54, a = 131.29 * g / mole, density = 5.458 * mg / cm3, kStateGas, 184 293.15 * kelvin, 1 * atmosphere); 185 186 G4Material* CO2 = new G4Material("CarbonicGas", density = 1.977 * mg / cm3, ncomponents = 2); 187 CO2->AddElement(C, natoms = 1); 188 CO2->AddElement(O, natoms = 2); 189 190 G4Material* ArCO2 = new G4Material("ArgonCO2", density = 1.8223 * mg / cm3, ncomponents = 2); 191 ArCO2->AddElement(Ar, fractionmass = 0.7844); 192 ArCO2->AddMaterial(CO2, fractionmass = 0.2156); 193 194 // another way to define mixture of gas per volume 195 G4Material* NewArCO2 = 196 new G4Material("NewArgonCO2", density = 1.8223 * mg / cm3, ncomponents = 3); 197 NewArCO2->AddElement(Ar, natoms = 8); 198 NewArCO2->AddElement(C, natoms = 2); 199 NewArCO2->AddElement(O, natoms = 4); 200 201 G4Material* ArCH4 = new G4Material("ArgonCH4", density = 1.709 * mg / cm3, ncomponents = 3); 202 ArCH4->AddElement(Ar, natoms = 93); 203 ArCH4->AddElement(C, natoms = 7); 204 ArCH4->AddElement(H, natoms = 28); 205 206 G4Material* XeCH = new G4Material("XenonMethanePropane", density = 4.9196 * mg / cm3, 207 ncomponents = 3, kStateGas, 293.15 * kelvin, 1 * atmosphere); 208 XeCH->AddElement(Xe, natoms = 875); 209 XeCH->AddElement(C, natoms = 225); 210 XeCH->AddElement(H, natoms = 700); 211 212 G4Material* steam = new G4Material("WaterSteam", density = 1.0 * mg / cm3, ncomponents = 1); 213 steam->AddMaterial(H2O, fractionmass = 1.); 214 steam->GetIonisation()->SetMeanExcitationEnergy(71.6 * eV); 215 216 G4Material* rock1 = new G4Material("StandardRock", 2.65 * CLHEP::g / CLHEP::cm3, 1, kStateSolid); 217 rock1->AddElement(Na, 1); 218 219 // 220 // example of vacuum 221 // 222 density = universe_mean_density; // from PhysicalConstants.h 223 pressure = 3.e-18 * pascal; 224 temperature = 2.73 * kelvin; 225 new G4Material("Galactic", z = 1, a = 1.01 * g / mole, density, kStateGas, temperature, pressure); 226 } 227 228 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 229 230 void DetectorConstruction::ComputeGeomParameters() 231 { 232 // Compute derived parameters of the calorimeter 233 fXstartAbs = fXposAbs - 0.5 * fAbsorberThickness; 234 fXendAbs = fXposAbs + 0.5 * fAbsorberThickness; 235 236 G4double xmax = std::max(std::abs(fXstartAbs), std::abs(fXendAbs)); 237 fWorldSizeX = 2.4 * xmax; 238 fWorldSizeYZ = 1.2 * fAbsorberSizeYZ; 239 if (nullptr != fPhysiWorld) { 240 ChangeGeometry(); 241 } 242 } 243 244 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 245 246 G4VPhysicalVolume* DetectorConstruction::Construct() 247 { 248 if (nullptr != fPhysiWorld) { 249 return fPhysiWorld; 250 } 251 // World 252 // 253 fSolidWorld = new G4Box("World", // its name 254 fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2); // its size 255 256 fLogicWorld = new G4LogicalVolume(fSolidWorld, // its solid 257 fWorldMaterial, // its material 258 "World"); // its name 259 260 fPhysiWorld = new G4PVPlacement(0, // no rotation 261 G4ThreeVector(0., 0., 0.), // at (0,0,0) 262 fLogicWorld, // its logical volume 263 "World", // its name 264 0, // its mother volume 265 false, // no boolean operation 266 0); // copy number 267 268 // Absorber 269 // 270 fSolidAbsorber = 271 new G4Box("Absorber", fAbsorberThickness / 2, fAbsorberSizeYZ / 2, fAbsorberSizeYZ / 2); 272 273 fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, // its solid 274 fAbsorberMaterial, // its material 275 "Absorber"); // its name 276 277 fPhysiAbsorber = new G4PVPlacement(0, // no rotation 278 G4ThreeVector(fXposAbs, 0., 0.), // its position 279 fLogicAbsorber, // its logical volume 280 "Absorber", // its name 281 fLogicWorld, // its mother 282 false, // no boulean operat 283 0); // copy number 284 285 PrintGeomParameters(); 286 287 // always return the physical World 288 // 289 return fPhysiWorld; 290 } 291 292 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 293 294 void DetectorConstruction::PrintGeomParameters() 295 { 296 G4cout << "\n" << fWorldMaterial << G4endl; 297 G4cout << "\n" << fAbsorberMaterial << G4endl; 298 299 G4cout << "\n The WORLD is made of " << G4BestUnit(fWorldSizeX, "Length") << " of " 300 << fWorldMaterial->GetName(); 301 G4cout << ". The transverse size (YZ) of the world is " << G4BestUnit(fWorldSizeYZ, "Length") 302 << G4endl; 303 G4cout << " The ABSORBER is made of " << G4BestUnit(fAbsorberThickness, "Length") << " of " 304 << fAbsorberMaterial->GetName(); 305 G4cout << ". The transverse size (YZ) is " << G4BestUnit(fAbsorberSizeYZ, "Length") << G4endl; 306 G4cout << " X position of the middle of the absorber " << G4BestUnit(fXposAbs, "Length"); 307 G4cout << G4endl; 308 } 309 310 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 311 312 void DetectorConstruction::SetAbsorberMaterial(const G4String& materialChoice) 313 { 314 // search the material by its name 315 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 316 317 if (pttoMaterial && fAbsorberMaterial != pttoMaterial) { 318 fAbsorberMaterial = pttoMaterial; 319 if (fLogicAbsorber) { 320 fLogicAbsorber->SetMaterial(fAbsorberMaterial); 321 } 322 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 323 } 324 } 325 326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 327 328 void DetectorConstruction::SetWorldMaterial(const G4String& materialChoice) 329 { 330 // search the material by its name 331 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 332 333 if (pttoMaterial && fWorldMaterial != pttoMaterial) { 334 fWorldMaterial = pttoMaterial; 335 if (fLogicWorld) { 336 fLogicWorld->SetMaterial(fWorldMaterial); 337 } 338 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 339 } 340 } 341 342 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 343 344 void DetectorConstruction::SetAbsorberThickness(G4double val) 345 { 346 fAbsorberThickness = val; 347 ComputeGeomParameters(); 348 } 349 350 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 351 352 void DetectorConstruction::SetAbsorberSizeYZ(G4double val) 353 { 354 fAbsorberSizeYZ = val; 355 ComputeGeomParameters(); 356 } 357 358 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 359 360 void DetectorConstruction::SetWorldSizeX(G4double val) 361 { 362 fWorldSizeX = val; 363 ComputeGeomParameters(); 364 } 365 366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 367 368 void DetectorConstruction::SetWorldSizeYZ(G4double val) 369 { 370 fWorldSizeYZ = val; 371 ComputeGeomParameters(); 372 } 373 374 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 375 376 void DetectorConstruction::SetAbsorberXpos(G4double val) 377 { 378 fXposAbs = val; 379 ComputeGeomParameters(); 380 } 381 382 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 383 384 void DetectorConstruction::ConstructSDandField() 385 { 386 if (fFieldMessenger.Get() == 0) { 387 // Create global magnetic field messenger. 388 // Uniform magnetic field is then created automatically if 389 // the field value is not zero. 390 G4ThreeVector fieldValue = G4ThreeVector(); 391 G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue); 392 // msg->SetVerboseLevel(1); 393 G4AutoDelete::Register(msg); 394 fFieldMessenger.Put(msg); 395 } 396 } 397 398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 399 400 void DetectorConstruction::ChangeGeometry() 401 { 402 fSolidWorld->SetXHalfLength(fWorldSizeX * 0.5); 403 fSolidWorld->SetYHalfLength(fWorldSizeYZ * 0.5); 404 fSolidWorld->SetZHalfLength(fWorldSizeYZ * 0.5); 405 406 fSolidAbsorber->SetXHalfLength(fAbsorberThickness * 0.5); 407 fSolidAbsorber->SetYHalfLength(fAbsorberSizeYZ * 0.5); 408 fSolidAbsorber->SetZHalfLength(fAbsorberSizeYZ * 0.5); 409 } 410 411 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 412