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 // 27 /// \file field/field04/src/F04DetectorConstruction.cc 28 /// \brief Implementation of the F04DetectorConstruction class 29 // 30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 32 33 #include "F04DetectorConstruction.hh" 34 35 #include "F04DetectorMessenger.hh" 36 #include "F04FocusSolenoid.hh" 37 #include "F04GlobalField.hh" 38 #include "F04Materials.hh" 39 #include "F04SimpleSolenoid.hh" 40 41 #include "G4AutoDelete.hh" 42 #include "G4GeometryManager.hh" 43 #include "G4LogicalVolume.hh" 44 #include "G4LogicalVolumeStore.hh" 45 #include "G4Material.hh" 46 #include "G4NistManager.hh" 47 #include "G4PVPlacement.hh" 48 #include "G4PhysicalConstants.hh" 49 #include "G4PhysicalVolumeStore.hh" 50 #include "G4RotationMatrix.hh" 51 #include "G4RunManager.hh" 52 #include "G4SolidStore.hh" 53 #include "G4StateManager.hh" 54 #include "G4SystemOfUnits.hh" 55 #include "G4Tubs.hh" 56 #include "globals.hh" 57 58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 59 60 F04DetectorConstruction::F04DetectorConstruction() 61 { 62 SetTargetAngle(170); 63 SetCaptureMgntB1(2.5 * tesla); 64 SetCaptureMgntB2(5.0 * tesla); 65 SetTransferMgntB(5.0 * tesla); 66 67 fDegraderPos = -fTransferMgntLength / 2. + fDegraderThickness / 2.; 68 69 fDetectorMessenger = new F04DetectorMessenger(this); 70 } 71 72 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 73 74 F04DetectorConstruction::~F04DetectorConstruction() 75 { 76 delete fDetectorMessenger; 77 } 78 79 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 80 81 G4VPhysicalVolume* F04DetectorConstruction::Construct() 82 { 83 if (fPhysiWorld) { 84 G4GeometryManager::GetInstance()->OpenGeometry(); 85 G4PhysicalVolumeStore::GetInstance()->Clean(); 86 G4LogicalVolumeStore::GetInstance()->Clean(); 87 G4SolidStore::GetInstance()->Clean(); 88 } 89 90 fMaterials = F04Materials::GetInstance(); 91 92 DefineMaterials(); 93 94 return ConstructDetector(); 95 } 96 97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 98 99 void F04DetectorConstruction::DefineMaterials() 100 { 101 // define materials for the experiment 102 103 fVacuum = fMaterials->GetMaterial("G4_Galactic"); 104 105 fWorldMaterial = fMaterials->GetMaterial("G4_AIR"); 106 fDegraderMaterial = fMaterials->GetMaterial("G4_Pb"); 107 fTargetMaterial = fMaterials->GetMaterial("G4_W"); 108 } 109 110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 111 112 G4VPhysicalVolume* F04DetectorConstruction::ConstructDetector() 113 { 114 fSolidWorld = new G4Tubs("World", 0., GetWorldSizeR(), GetWorldSizeZ() / 2., 0., twopi); 115 116 fLogicWorld = new G4LogicalVolume(fSolidWorld, GetWorldMaterial(), "World"); 117 118 fPhysiWorld = 119 new G4PVPlacement(nullptr, G4ThreeVector(), "World", fLogicWorld, nullptr, false, 0); 120 121 // Capture Magnet 122 123 fSolidCaptureMgnt = 124 new G4Tubs("CaptureMgnt", 0., GetCaptureMgntRadius(), GetCaptureMgntLength() / 2., 0., twopi); 125 126 fLogicCaptureMgnt = new G4LogicalVolume(fSolidCaptureMgnt, fVacuum, "CaptureMgnt"); 127 128 fCaptureMgntCenter = G4ThreeVector(); 129 130 fPhysiCaptureMgnt = new G4PVPlacement(nullptr, fCaptureMgntCenter, "CaptureMgnt", 131 fLogicCaptureMgnt, fPhysiWorld, false, 0); 132 133 // Transfer Magnet 134 135 fSolidTransferMgnt = new G4Tubs("TransferMgnt", 0., GetTransferMgntRadius(), 136 GetTransferMgntLength() / 2., 0., twopi); 137 138 fLogicTransferMgnt = new G4LogicalVolume(fSolidTransferMgnt, fVacuum, "TransferMgnt"); 139 140 G4double z = GetCaptureMgntLength() / 2. + GetTransferMgntLength() / 2. + GetTransferMgntPos(); 141 G4double x = GetTransferMgntPos() / 2.; 142 143 fTransferMgntCenter = G4ThreeVector(x, 0., z); 144 145 auto g4rot = new G4RotationMatrix(); 146 *g4rot = StringToRotationMatrix("Y30,X10"); 147 *g4rot = g4rot->inverse(); 148 if (*g4rot == G4RotationMatrix()) g4rot = nullptr; 149 150 fPhysiTransferMgnt = new G4PVPlacement(g4rot, fTransferMgntCenter, "TransferMgnt", 151 fLogicTransferMgnt, fPhysiWorld, false, 0); 152 153 // Test Plane 154 155 auto solidTestPlane = new G4Tubs("TestPlane", 0., GetTransferMgntRadius(), 1. * mm, 0., twopi); 156 157 auto logicTestPlane = new G4LogicalVolume(solidTestPlane, fVacuum, "TestPlane"); 158 159 z = GetTransferMgntLength() / 2. - 1. * mm; 160 161 G4ThreeVector testPlaneCenter = G4ThreeVector(0., 0., z); 162 163 new G4PVPlacement(nullptr, testPlaneCenter, "TestPlane", logicTestPlane, fPhysiTransferMgnt, 164 false, 0); 165 166 // Target 167 168 if (GetTargetThickness() > 0.) { 169 fSolidTarget = 170 new G4Tubs("Target", 0., GetTargetRadius(), GetTargetThickness() / 2., 0., twopi); 171 172 fLogicTarget = new G4LogicalVolume(fSolidTarget, GetTargetMaterial(), "Target"); 173 174 G4int i = GetTargetAngle(); 175 176 G4String angle = std::to_string(i); 177 G4StrUtil::strip(angle); 178 angle = "Y" + angle; 179 180 g4rot = new G4RotationMatrix(); 181 *g4rot = StringToRotationMatrix(angle); 182 *g4rot = g4rot->inverse(); 183 if (*g4rot == G4RotationMatrix()) g4rot = nullptr; 184 185 G4ThreeVector targetCenter(0., 0., GetTargetPos()); 186 187 fPhysiTarget = 188 new G4PVPlacement(g4rot, targetCenter, "Target", fLogicTarget, fPhysiCaptureMgnt, false, 0); 189 } 190 191 // Degrader 192 193 if (GetDegraderThickness() > 0.) { 194 fSolidDegrader = 195 new G4Tubs("Degrader", 0., GetDegraderRadius(), GetDegraderThickness() / 2., 0., twopi); 196 197 fLogicDegrader = new G4LogicalVolume(fSolidDegrader, GetDegraderMaterial(), "Degrader"); 198 199 G4ThreeVector degraderCenter = G4ThreeVector(0., 0., GetDegraderPos()); 200 201 fPhysiDegrader = new G4PVPlacement(nullptr, degraderCenter, "Degrader", fLogicDegrader, 202 fPhysiTransferMgnt, false, 0); 203 } 204 205 return fPhysiWorld; 206 } 207 208 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 209 210 void F04DetectorConstruction::SetWorldMaterial(const G4String materialChoice) 211 { 212 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 213 214 if (pttoMaterial != fWorldMaterial) { 215 if (pttoMaterial) { 216 fWorldMaterial = pttoMaterial; 217 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 218 } 219 else { 220 G4cout << "\n--> WARNING from SetWorldMaterial : " << materialChoice << " not found" 221 << G4endl; 222 } 223 } 224 } 225 226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 227 228 void F04DetectorConstruction::SetTargetMaterial(const G4String materialChoice) 229 { 230 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 231 232 if (pttoMaterial != fTargetMaterial) { 233 if (pttoMaterial) { 234 fTargetMaterial = pttoMaterial; 235 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 236 } 237 else { 238 G4cout << "\n--> WARNING from SetTargetMaterial : " << materialChoice << " not found" 239 << G4endl; 240 } 241 } 242 } 243 244 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 245 246 void F04DetectorConstruction::SetDegraderMaterial(const G4String materialChoice) 247 248 { 249 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); 250 251 if (pttoMaterial != fDegraderMaterial) { 252 if (pttoMaterial) { 253 fDegraderMaterial = pttoMaterial; 254 G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 255 } 256 else { 257 G4cout << "\n--> WARNING from SetDegraderMaterial : " << materialChoice << " not found" 258 << G4endl; 259 } 260 } 261 } 262 263 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 264 265 void F04DetectorConstruction::SetWorldSizeZ(G4double val) 266 { 267 fWorldSizeZ = val; 268 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 269 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 270 } 271 272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 273 274 void F04DetectorConstruction::SetWorldSizeR(G4double val) 275 { 276 fWorldSizeR = val; 277 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 278 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 279 } 280 281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 282 283 void F04DetectorConstruction::SetCaptureMgntRadius(G4double val) 284 { 285 fCaptureMgntRadius = val; 286 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 287 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 288 } 289 290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 291 292 void F04DetectorConstruction::SetCaptureMgntLength(G4double val) 293 { 294 fCaptureMgntLength = val; 295 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 296 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 297 } 298 299 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 300 301 void F04DetectorConstruction::SetCaptureMgntB1(G4double val) 302 { 303 fCaptureMgntB1 = val; 304 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 305 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 306 } 307 308 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 309 310 void F04DetectorConstruction::SetCaptureMgntB2(G4double val) 311 { 312 fCaptureMgntB2 = val; 313 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 314 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 315 } 316 317 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 318 319 void F04DetectorConstruction::SetTransferMgntRadius(G4double val) 320 { 321 fTransferMgntRadius = val; 322 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 323 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 324 } 325 326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 327 328 void F04DetectorConstruction::SetTransferMgntLength(G4double val) 329 { 330 fTransferMgntLength = val; 331 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 332 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 333 } 334 335 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 336 337 void F04DetectorConstruction::SetTransferMgntB(G4double val) 338 { 339 fTransferMgntB = val; 340 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 341 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 342 } 343 344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 345 346 void F04DetectorConstruction::SetTransferMgntPos(G4double val) 347 { 348 fTransferMgntPos = val; 349 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 350 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 351 } 352 353 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 354 355 void F04DetectorConstruction::SetTargetRadius(G4double val) 356 { 357 fTargetRadius = val; 358 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 359 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 360 } 361 362 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 363 364 void F04DetectorConstruction::SetTargetThickness(G4double val) 365 { 366 fTargetThickness = val; 367 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 368 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 369 } 370 371 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 372 373 void F04DetectorConstruction::SetTargetPos(G4double val) 374 { 375 fTargetPos = val; 376 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 377 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 378 } 379 380 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 381 382 void F04DetectorConstruction::SetTargetAngle(G4int val) 383 { 384 fTargetAngle = val; 385 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 386 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 387 } 388 389 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 390 391 void F04DetectorConstruction::SetDegraderRadius(G4double val) 392 { 393 fDegraderRadius = val; 394 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 395 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 396 } 397 398 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 399 400 void F04DetectorConstruction::SetDegraderThickness(G4double val) 401 { 402 fDegraderThickness = val; 403 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 404 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 405 } 406 407 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 408 409 void F04DetectorConstruction::SetDegraderPos(G4double val) 410 { 411 fDegraderPos = val; 412 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) 413 G4RunManager::GetRunManager()->GeometryHasBeenModified(); 414 } 415 416 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 417 418 void F04DetectorConstruction::ConstructSDandField() 419 { 420 if (!fFieldSetUp.Get()) { 421 F04GlobalField* field = F04GlobalField::GetObject(this); 422 G4AutoDelete::Register(field); // Kernel will delete the F04GlobalField 423 fFieldSetUp.Put(field); 424 } 425 } 426 427 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 428 429 G4RotationMatrix F04DetectorConstruction::StringToRotationMatrix(G4String rotation) 430 { 431 // We apply successive rotations OF THE OBJECT around the FIXED 432 // axes of the parent's local coordinates; rotations are applied 433 // left-to-right (rotation="r1,r2,r3" => r1 then r2 then r3). 434 435 G4RotationMatrix rot; 436 437 unsigned int place = 0; 438 439 while (place < rotation.size()) { 440 G4double angle; 441 char* p(nullptr); 442 G4String current = rotation.substr(place + 1); 443 angle = strtod(current.c_str(), &p) * deg; 444 445 if (!p || (*p != ',' && *p != '\0')) { 446 G4cerr << "Invalid rotation specification: " << rotation.c_str() << G4endl; 447 448 return rot; 449 } 450 451 G4RotationMatrix thisRotation; 452 453 switch (rotation.substr(place, 1).c_str()[0]) { 454 case 'X': 455 case 'x': 456 thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle)); 457 break; 458 case 'Y': 459 case 'y': 460 thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle)); 461 break; 462 case 'Z': 463 case 'z': 464 thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle)); 465 break; 466 default: 467 G4cerr << " Invalid rotation specification: " << rotation << G4endl; 468 return rot; 469 } 470 471 rot = thisRotation * rot; 472 place = rotation.find(',', place); 473 if (place > rotation.size()) break; 474 ++place; 475 } 476 477 return rot; 478 } 479