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/TestEm7/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 "G4Box.hh" 38 #include "G4FieldManager.hh" 39 #include "G4GeometryManager.hh" 40 #include "G4LogicalVolume.hh" 41 #include "G4LogicalVolumeStore.hh" 42 #include "G4Material.hh" 43 #include "G4NistManager.hh" 44 #include "G4PVPlacement.hh" 45 #include "G4PhysicalConstants.hh" 46 #include "G4PhysicalVolumeStore.hh" 47 #include "G4RunManager.hh" 48 #include "G4SolidStore.hh" 49 #include "G4SystemOfUnits.hh" 50 #include "G4TransportationManager.hh" 51 #include "G4UniformMagField.hh" 52 #include "G4UnitsTable.hh" 53 54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 56 DetectorConstruction::DetectorConstruction() 57 : G4VUserDetectorConstruction(), fMagField(nullptr), fLAbsor(nullptr), fLWorld(nullptr) 58 { 59 // default parameter values 60 fAbsorSizeX = fAbsorSizeYZ = 20 * cm; 61 fWorldSizeX = fWorldSizeYZ = 1.2 * fAbsorSizeX; 62 63 fTallyNumber = 0; 64 for (G4int j = 0; j < kMaxTally; j++) { 65 fTallySize[j] = fTallyPosition[j] = G4ThreeVector(0., 0., 0.); 66 fTallyMass[j] = 0.; 67 fLTally[j] = nullptr; 68 } 69 70 DefineMaterials(); 71 72 // create commands for interactive definition of the detector 73 fDetectorMessenger = new DetectorMessenger(this); 74 } 75 76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 77 78 DetectorConstruction::~DetectorConstruction() 79 { 80 delete fDetectorMessenger; 81 } 82 83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 84 85 void DetectorConstruction::DefineMaterials() 86 { 87 // 88 // define Elements 89 // 90 G4double z, a; 91 92 G4Element* H = new G4Element("Hydrogen", "H", z = 1, a = 1.008 * g / mole); 93 G4Element* N = new G4Element("Nitrogen", "N", z = 7, a = 14.01 * g / mole); 94 G4Element* O = new G4Element("Oxygen", "O", z = 8, a = 16.00 * g / mole); 95 96 // 97 // define Materials. 98 // 99 G4double density, temperature, pressure; 100 G4int ncomponents, natoms; 101 G4double fractionmass; 102 103 G4Material* H2O = new G4Material("Water", density = 1.0 * g / cm3, ncomponents = 2); 104 H2O->AddElement(H, natoms = 2); 105 H2O->AddElement(O, natoms = 1); 106 H2O->GetIonisation()->SetMeanExcitationEnergy(78.0 * eV); 107 108 // In this line both G4_WATER and Water_1.05 will be constructed 109 G4NistManager::Instance()->BuildMaterialWithNewDensity("Water_1.05", "G4_WATER", 1.05 * g / cm3); 110 111 G4Material* Air = new G4Material("Air", density = 1.290 * mg / cm3, ncomponents = 2); 112 Air->AddElement(N, fractionmass = 0.7); 113 Air->AddElement(O, fractionmass = 0.3); 114 115 density = 1.e-5 * g / cm3; 116 pressure = 2.e-2 * bar; 117 temperature = STP_Temperature; // From PhysicalConstants.h . 118 G4Material* vac = new G4Material("TechVacuum", density, 1, kStateGas, temperature, pressure); 119 vac->AddMaterial(Air, 1.); 120 121 density = universe_mean_density; // from PhysicalConstants.h 122 pressure = 3.e-18 * pascal; 123 temperature = 2.73 * kelvin; 124 G4Material* vacuum = new G4Material("Galactic", z = 1, a = 1.008 * g / mole, density, kStateGas, 125 temperature, pressure); 126 127 // default materials 128 fAbsorMaterial = H2O; 129 fWorldMaterial = vacuum; 130 } 131 132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 133 134 G4VPhysicalVolume* DetectorConstruction::Construct() 135 { 136 // World 137 // 138 G4Box* sWorld = new G4Box("World", // name 139 fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2); // dimensions 140 141 fLWorld = new G4LogicalVolume(sWorld, // shape 142 fWorldMaterial, // material 143 "World"); // name 144 145 G4VPhysicalVolume* pWorld = new G4PVPlacement(0, // no rotation 146 G4ThreeVector(0., 0., 0.), // at (0,0,0) 147 fLWorld, // logical volume 148 "World", // name 149 0, // mother volume 150 false, // no boolean operation 151 0); // copy number 152 // 153 // Absorber 154 // 155 G4Box* sAbsor = new G4Box("Absorber", // name 156 fAbsorSizeX / 2, fAbsorSizeYZ / 2, fAbsorSizeYZ / 2); // dimensions 157 158 fLAbsor = new G4LogicalVolume(sAbsor, // shape 159 fAbsorMaterial, // material 160 "Absorber"); // name 161 162 new G4PVPlacement(0, // no rotation 163 G4ThreeVector(0., 0., 0.), // at (0,0,0) 164 fLAbsor, // logical volume 165 "Absorber", // name 166 fLWorld, // mother volume 167 false, // no boolean operation 168 0); // copy number 169 // 170 // Tallies (optional) 171 // 172 if (fTallyNumber > 0) { 173 for (G4int j = 0; j < fTallyNumber; ++j) { 174 G4Box* sTally = 175 new G4Box("Tally", fTallySize[j].x() / 2, fTallySize[j].y() / 2, fTallySize[j].z() / 2); 176 177 fLTally[j] = new G4LogicalVolume(sTally, fAbsorMaterial, "Tally"); 178 179 new G4PVPlacement(0, // no rotation 180 fTallyPosition[j], // position 181 fLTally[j], // logical volume 182 "Tally", // name 183 fLAbsor, // mother volume 184 false, // no boolean operation 185 j + 1); // copy number 186 187 fTallyMass[j] = 188 fTallySize[j].x() * fTallySize[j].y() * fTallySize[j].z() * (fAbsorMaterial->GetDensity()); 189 } 190 } 191 192 PrintParameters(); 193 194 // 195 // always return the World volume 196 // 197 return pWorld; 198 } 199 200 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 201 202 void DetectorConstruction::PrintParameters() const 203 { 204 G4cout << *(G4Material::GetMaterialTable()) << G4endl; 205 G4cout << "\n---------------------------------------------------------\n"; 206 G4cout << "---> The Absorber is " << G4BestUnit(fAbsorSizeX, "Length") << " of " 207 << fAbsorMaterial->GetName() << G4endl; 208 G4cout << "\n---------------------------------------------------------\n"; 209 210 if (fTallyNumber > 0) { 211 G4cout << "---> There are " << fTallyNumber << " tallies : " << G4endl; 212 for (G4int j = 0; j < fTallyNumber; ++j) { 213 G4cout << "fTally " << j << ": " << fAbsorMaterial->GetName() 214 << ", mass = " << G4BestUnit(fTallyMass[j], "Mass") 215 << " size = " << G4BestUnit(fTallySize[j], "Length") 216 << " position = " << G4BestUnit(fTallyPosition[j], "Length") << G4endl; 217 } 218 G4cout << "\n---------------------------------------------------------\n"; 219 } 220 } 221 222 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 223 224 void DetectorConstruction::SetSizeX(G4double value) 225 { 226 fAbsorSizeX = value; 227 fWorldSizeX = 1.2 * fAbsorSizeX; 228 } 229 230 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 231 232 void DetectorConstruction::SetSizeYZ(G4double value) 233 { 234 fAbsorSizeYZ = value; 235 fWorldSizeYZ = 1.2 * fAbsorSizeYZ; 236 } 237 238 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 239 240 void DetectorConstruction::SetMaterial(const G4String& materialChoice) 241 { 242 // search the material by its name 243 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 244 if (pttoMaterial && pttoMaterial != fAbsorMaterial) { 245 // change target material everywhere 246 fAbsorMaterial = pttoMaterial; 247 for (G4int j = 0; j < fTallyNumber; ++j) { 248 if (fLTally[j]) { 249 fLTally[j]->SetMaterial(pttoMaterial); 250 fTallyMass[j] = 251 fTallySize[j].x() * fTallySize[j].y() * fTallySize[j].z() * (pttoMaterial->GetDensity()); 252 } 253 } 254 if (fLAbsor) { 255 fLAbsor->SetMaterial(fAbsorMaterial); 256 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 257 } 258 } 259 } 260 261 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 262 263 void DetectorConstruction::SetWorldMaterial(const G4String& materialChoice) 264 { 265 // search the material by its name 266 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 267 if (pttoMaterial && pttoMaterial != fWorldMaterial) { 268 fWorldMaterial = pttoMaterial; 269 if (fLWorld) { 270 fLWorld->SetMaterial(fAbsorMaterial); 271 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 272 } 273 } 274 } 275 276 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 277 278 void DetectorConstruction::SetMagField(G4double fieldValue) 279 { 280 // apply a global uniform magnetic field along Z axis 281 G4FieldManager* fieldMgr = G4TransportationManager::GetTransportationManager()->GetFieldManager(); 282 283 if (fMagField) delete fMagField; // delete the existing magn field 284 285 if (fieldValue != 0.) // create a new one if non nul 286 { 287 fMagField = new G4UniformMagField(G4ThreeVector(0., 0., fieldValue)); 288 fieldMgr->SetDetectorField(fMagField); 289 fieldMgr->CreateChordFinder(fMagField); 290 } 291 else { 292 fMagField = nullptr; 293 fieldMgr->SetDetectorField(fMagField); 294 } 295 } 296 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 297 298 void DetectorConstruction::SetTallyNumber(G4int value) 299 { 300 if (value >= 0 && value < kMaxTally) { 301 fTallyNumber = value; 302 } 303 else { 304 G4cout << "### DetectorConstruction::SetTallyNumber WARNING: wrong tally " 305 << "number " << value << " is ignored" << G4endl; 306 } 307 } 308 309 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 310 311 void DetectorConstruction::SetTallySize(G4int j, const G4ThreeVector& value) 312 { 313 if (j >= 0 && j < kMaxTally) { 314 fTallySize[j] = value; 315 } 316 else { 317 G4cout << "### DetectorConstruction::SetTallyNumber WARNING: wrong tally " 318 << "number " << j << " is ignored" << G4endl; 319 } 320 } 321 322 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 323 324 void DetectorConstruction::SetTallyPosition(G4int j, const G4ThreeVector& value) 325 { 326 if (j >= 0 && j < kMaxTally) { 327 fTallyPosition[j] = value; 328 } 329 else { 330 G4cout << "### DetectorConstruction::SetTallyPosition WARNING: wrong tally " 331 << "number " << j << " is ignored" << G4endl; 332 } 333 } 334 335 G4double DetectorConstruction::GetTallyMass(G4int j) const 336 { 337 if (j >= 0 && j < kMaxTally) { 338 return fTallyMass[j]; 339 } 340 else { 341 G4cout << "### DetectorConstruction::GetTallyMass WARNING: wrong tally " 342 << "number " << j << " is ignored" << G4endl; 343 return 0.0; 344 } 345 } 346 347 const G4LogicalVolume* DetectorConstruction::GetLogicalTally(G4int j) const 348 { 349 if (j >= 0 && j < kMaxTally) { 350 return fLTally[j]; 351 } 352 else { 353 G4cout << "### DetectorConstruction::GetLOgicalTally WARNING: wrong tally " 354 << "number " << j << " is ignored" << G4endl; 355 return nullptr; 356 } 357 } 358 359 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 360