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/TestEm11/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 "G4PVReplica.hh" 47 #include "G4PhysicalConstants.hh" 48 #include "G4PhysicalVolumeStore.hh" 49 #include "G4RunManager.hh" 50 #include "G4SolidStore.hh" 51 #include "G4SystemOfUnits.hh" 52 #include "G4UImanager.hh" 53 #include "G4UniformMagField.hh" 54 #include "G4UnitsTable.hh" 55 56 #include <iomanip> 57 58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 59 60 DetectorConstruction::DetectorConstruction() 61 { 62 // default parameter values of the absorbers 63 fNbOfAbsor = 1; 64 fAbsorThickness[0] = 0. * mm; // dummy, for initialization 65 fAbsorThickness[1] = 1. * mm; 66 fAbsorSizeYZ = 1. * mm; 67 for (G4int iAbs = 0; iAbs < kMaxAbsor; iAbs++) { 68 fNbOfDivisions[iAbs] = 1; 69 } 70 ComputeParameters(); 71 72 // materials 73 DefineMaterials(); 74 SetAbsorMaterial(1, "G4_Si"); 75 76 // create commands for interactive definition of the calorimeter 77 fDetectorMessenger = new DetectorMessenger(this); 78 } 79 80 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 81 82 DetectorConstruction::~DetectorConstruction() 83 { 84 delete fDetectorMessenger; 85 } 86 87 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 88 89 G4VPhysicalVolume* DetectorConstruction::Construct() 90 { 91 return ConstructVolumes(); 92 } 93 94 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 95 96 void DetectorConstruction::DefineMaterials() 97 { 98 G4NistManager* man = G4NistManager::Instance(); 99 100 man->FindOrBuildMaterial("G4_Al"); 101 man->FindOrBuildMaterial("G4_Si"); 102 man->FindOrBuildMaterial("G4_Fe"); 103 man->FindOrBuildMaterial("G4_Cu"); 104 man->FindOrBuildMaterial("G4_Ge"); 105 man->FindOrBuildMaterial("G4_Mo"); 106 man->FindOrBuildMaterial("G4_Ta"); 107 man->FindOrBuildMaterial("G4_W"); 108 man->FindOrBuildMaterial("G4_Au"); 109 man->FindOrBuildMaterial("G4_Pb"); 110 man->FindOrBuildMaterial("G4_PbWO4"); 111 man->FindOrBuildMaterial("G4_SODIUM_IODIDE"); 112 113 man->FindOrBuildMaterial("G4_AIR"); 114 man->FindOrBuildMaterial("G4_WATER"); 115 116 G4Element* H = man->FindOrBuildElement("H"); 117 G4Element* O = man->FindOrBuildElement("O"); 118 119 G4Material* H2O = new G4Material("Water", 1.000 * g / cm3, 2); 120 H2O->AddElement(H, 2); 121 H2O->AddElement(O, 1); 122 H2O->GetIonisation()->SetMeanExcitationEnergy(78.0 * eV); 123 124 G4double density = universe_mean_density; // from PhysicalConstants.h 125 G4double pressure = 3.e-18 * pascal; 126 G4double temperature = 2.73 * kelvin; 127 G4Material* Galactic = 128 new G4Material("Galactic", 1., 1.008 * g / mole, density, kStateGas, temperature, pressure); 129 130 fDefaultMaterial = Galactic; 131 132 // G4cout << *(G4Material::GetMaterialTable()) << G4endl; 133 } 134 135 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 136 137 void DetectorConstruction::ComputeParameters() 138 { 139 // Compute total thickness of absorbers 140 fAbsorSizeX = 0.; 141 for (G4int iAbs = 1; iAbs <= fNbOfAbsor; iAbs++) { 142 fAbsorSizeX += fAbsorThickness[iAbs]; 143 } 144 } 145 146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 147 148 G4VPhysicalVolume* DetectorConstruction::ConstructVolumes() 149 { 150 // complete the Calor parameters definition 151 ComputeParameters(); 152 153 // Cleanup old geometry 154 G4GeometryManager::GetInstance()->OpenGeometry(); 155 G4PhysicalVolumeStore::GetInstance()->Clean(); 156 G4LogicalVolumeStore::GetInstance()->Clean(); 157 G4SolidStore::GetInstance()->Clean(); 158 159 // 160 // World 161 // 162 G4Box* solidWorld = new G4Box("World", // name 163 fAbsorSizeX / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2); // size 164 165 G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld, // solid 166 fDefaultMaterial, // material 167 "World"); // name 168 169 fPhysiWorld = new G4PVPlacement(0, // no rotation 170 G4ThreeVector(), // at (0,0,0) 171 logicWorld, // logical volume 172 "World", // name 173 0, // mother volume 174 false, // no boolean operation 175 0); // copy number 176 177 // 178 // Absorbers 179 // 180 fXfront[0] = -0.5 * fAbsorSizeX; 181 // 182 for (G4int k = 1; k <= fNbOfAbsor; k++) { 183 G4Material* material = fAbsorMaterial[k]; 184 G4String matname = material->GetName(); 185 186 G4Box* solidAbsor = 187 new G4Box(matname, fAbsorThickness[k] / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2); 188 189 G4LogicalVolume* logicAbsor = new G4LogicalVolume(solidAbsor, // solid 190 material, // material 191 matname); // name 192 193 fXfront[k] = fXfront[k - 1] + fAbsorThickness[k - 1]; 194 G4double xcenter = fXfront[k] + 0.5 * fAbsorThickness[k]; 195 G4ThreeVector position = G4ThreeVector(xcenter, 0., 0.); 196 197 new G4PVPlacement(0, // no rotation 198 position, // position 199 logicAbsor, // logical volume 200 matname, // name 201 logicWorld, // mother 202 false, // no boulean operat 203 k); // copy number 204 205 // divisions, if any 206 // 207 G4double LayerThickness = fAbsorThickness[k] / fNbOfDivisions[k]; 208 G4Box* solidLayer = new G4Box(matname, LayerThickness / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2); 209 210 G4LogicalVolume* logicLayer = new G4LogicalVolume(solidLayer, // solid 211 material, // material 212 matname); // name 213 214 new G4PVReplica(matname, // name 215 logicLayer, // logical volume 216 logicAbsor, // mother 217 kXAxis, // axis of replication 218 fNbOfDivisions[k], // number of replica 219 LayerThickness); // witdth of replica 220 } 221 222 PrintParameters(); 223 224 // always return the physical World 225 // 226 return fPhysiWorld; 227 } 228 229 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 230 231 void DetectorConstruction::PrintParameters() 232 { 233 G4cout << "\n-------------------------------------------------------------" 234 << "\n ---> The Absorber is " << fNbOfAbsor << " layers of:"; 235 for (G4int i = 1; i <= fNbOfAbsor; i++) { 236 G4cout << "\n \t" << std::setw(16) << fAbsorMaterial[i]->GetName() << ": " << std::setw(6) 237 << G4BestUnit(fAbsorThickness[i], "Length") << " divided in " << fNbOfDivisions[i] 238 << " slices"; 239 } 240 G4cout << "\n-------------------------------------------------------------\n" << G4endl; 241 } 242 243 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 244 245 void DetectorConstruction::SetNbOfAbsor(G4int ival) 246 { 247 // set the number of Absorbers 248 // 249 if (ival < 1 || ival > (kMaxAbsor - 1)) { 250 G4cout << "\n ---> warning from SetfNbOfAbsor: " << ival << " must be at least 1 and and most " 251 << kMaxAbsor - 1 << ". Command refused" << G4endl; 252 return; 253 } 254 fNbOfAbsor = ival; 255 G4RunManager::GetRunManager()->ReinitializeGeometry(); 256 } 257 258 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 259 260 void DetectorConstruction::SetAbsorMaterial(G4int iabs, const G4String& material) 261 { 262 // search the material by its name 263 // 264 if (iabs > fNbOfAbsor || iabs <= 0) { 265 G4cout << "\n --->warning from SetfAbsorMaterial: absor number " << iabs 266 << " out of range. Command refused" << G4endl; 267 return; 268 } 269 270 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(material); 271 if (pttoMaterial) { 272 fAbsorMaterial[iabs] = pttoMaterial; 273 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 274 G4cout << "\n " << pttoMaterial << G4endl; 275 } 276 } 277 278 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 279 280 void DetectorConstruction::SetAbsorThickness(G4int iabs, G4double val) 281 { 282 // change Absorber thickness 283 // 284 if (iabs > fNbOfAbsor || iabs <= 0) { 285 G4cout << "\n --->warning from SetfAbsorThickness: absor number " << iabs 286 << " out of range. Command refused" << G4endl; 287 return; 288 } 289 if (val <= DBL_MIN) { 290 G4cout << "\n --->warning from SetfAbsorThickness: thickness " << val 291 << " out of range. Command refused" << G4endl; 292 return; 293 } 294 fAbsorThickness[iabs] = val; 295 G4RunManager::GetRunManager()->ReinitializeGeometry(); 296 } 297 298 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 299 300 void DetectorConstruction::SetAbsorSizeYZ(G4double val) 301 { 302 // change the transverse size 303 // 304 if (val <= DBL_MIN) { 305 G4cout << "\n --->warning from SetfAbsorSizeYZ: thickness " << val 306 << " out of range. Command refused" << G4endl; 307 return; 308 } 309 fAbsorSizeYZ = val; 310 G4RunManager::GetRunManager()->ReinitializeGeometry(); 311 } 312 313 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 314 315 void DetectorConstruction::SetNbOfDivisions(G4int iabs, G4int ival) 316 { 317 // set the number of divisions 318 // 319 if (iabs > fNbOfAbsor || iabs < 1) { 320 G4cout << "\n --->warning from SetNbOfDivisions: absor number " << iabs 321 << " out of range. Command refused" << G4endl; 322 return; 323 } 324 325 if (ival < 1) { 326 G4cout << "\n --->warning from SetNbOfDivisions: " << ival 327 << " must be at least 1. Command refused" << G4endl; 328 return; 329 } 330 fNbOfDivisions[iabs] = ival; 331 G4RunManager::GetRunManager()->ReinitializeGeometry(); 332 } 333 334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 335 336 void DetectorConstruction::ConstructSDandField() 337 { 338 if (fFieldMessenger.Get() == 0) { 339 // Create global magnetic field messenger. 340 // Uniform magnetic field is then created automatically if 341 // the field value is not zero. 342 G4ThreeVector fieldValue = G4ThreeVector(); 343 G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue); 344 // msg->SetVerboseLevel(1); 345 G4AutoDelete::Register(msg); 346 fFieldMessenger.Put(msg); 347 } 348 } 349 350 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 351