Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4Region class implementation 27 // 28 // 18.09.02, G.Cosmo - Initial version 29 // ------------------------------------------- 30 31 #include "G4Region.hh" 32 #include "G4RegionStore.hh" 33 #include "G4LogicalVolume.hh" 34 #include "G4VPhysicalVolume.hh" 35 #include "G4LogicalVolumeStore.hh" 36 #include "G4VNestedParameterisation.hh" 37 #include "G4VUserRegionInformation.hh" 38 #include "G4Material.hh" 39 40 // These macros changes the references to fiel 41 // in the class G4RegionData. 42 // 43 #define G4MT_fsmanager ((subInstanceManager.of 44 #define G4MT_rsaction ((subInstanceManager.off 45 46 // This new field helps to use the class G4Reg 47 // 48 G4RegionManager G4Region::subInstanceManager; 49 50 // ******************************************* 51 // GetSubInstanceManager: 52 // - Returns the private data instance manage 53 // ******************************************* 54 // 55 const G4RegionManager& G4Region::GetSubInstanc 56 { 57 return subInstanceManager; 58 } 59 60 // ******************************************* 61 // Constructor: 62 // - Adds self to region Store 63 // ******************************************* 64 // 65 G4Region::G4Region(const G4String& pName) 66 : fName(pName) 67 { 68 69 instanceID = subInstanceManager.CreateSubIns 70 G4MT_fsmanager = nullptr; 71 G4MT_rsaction = nullptr; 72 73 G4RegionStore* rStore = G4RegionStore::GetIn 74 if (rStore->GetRegion(pName, false) != nullp 75 { 76 std::ostringstream message; 77 message << "The region has NOT been regist 78 << " Region " << pName << 79 << G4endl; 80 G4Exception("G4Region::G4Region()", "GeomM 81 JustWarning, message); 82 } 83 else 84 { 85 rStore->Register(this); 86 } 87 } 88 89 // ******************************************* 90 // Fake default constructor - sets only member 91 // for usage restri 92 // ******************************************* 93 // 94 G4Region::G4Region( __void__& ) 95 : fName("") 96 { 97 instanceID = subInstanceManager.CreateSubIns 98 G4MT_fsmanager = nullptr; 99 G4MT_rsaction = nullptr; 100 101 // Register to store 102 // 103 G4RegionStore::GetInstance()->Register(this) 104 } 105 106 // ******************************************* 107 // Destructor: 108 // - Removes self from region Store 109 // ******************************************* 110 // 111 G4Region::~G4Region() 112 { 113 G4RegionStore::GetInstance()->DeRegister(thi 114 delete fUserInfo; 115 } 116 117 // ******************************************* 118 // SetName - Set region name and notify store 119 // ******************************************* 120 // 121 void G4Region::SetName(const G4String& pName) 122 { 123 fName = pName; 124 G4RegionStore::GetInstance()->SetMapValid(fa 125 } 126 127 // ******************************************* 128 // SetFastSimulationManager 129 // ******************************************* 130 // 131 void G4Region::SetFastSimulationManager(G4Fast 132 { 133 G4MT_fsmanager = fsm; 134 } 135 136 // ******************************************* 137 // GetFastSimulationManager 138 // ******************************************* 139 // 140 G4FastSimulationManager* G4Region::GetFastSimu 141 { 142 return G4MT_fsmanager; 143 } 144 145 // ******************************************* 146 // SetRegionalSteppingAction 147 // ******************************************* 148 // 149 void G4Region::SetRegionalSteppingAction(G4Use 150 { 151 G4MT_rsaction = rusa; 152 } 153 154 // ******************************************* 155 // GetRegionalSteppingAction 156 // ******************************************* 157 // 158 G4UserSteppingAction* G4Region::GetRegionalSte 159 { 160 return G4MT_rsaction; 161 } 162 163 // ******************************************* 164 // ScanVolumeTree: 165 // - Scans recursively the 'lv' logical volum 166 // and places all materials in the list. 167 // - The boolean flag 'region' identifies if 168 // have region reset (false) or if the curr 169 // associated to the logical volume 'lv' an 170 // ******************************************* 171 // 172 void G4Region::ScanVolumeTree(G4LogicalVolume* 173 { 174 // If logical volume is going to become a re 175 // its material to the list if not already p 176 // 177 G4Region* currentRegion = nullptr; 178 std::size_t noDaughters = lv->GetNoDaughters 179 G4Material* volMat = lv->GetMaterial(); 180 if((volMat == nullptr) && fInMassGeometry) 181 { 182 std::ostringstream message; 183 message << "Logical volume <" << lv->GetNa 184 << "does not have a valid material 185 << "A logical volume belonging to 186 << "must have a valid material."; 187 G4Exception("G4Region::ScanVolumeTree()", 188 FatalException, message, "Chec 189 } 190 if (region) 191 { 192 currentRegion = this; 193 if (volMat != nullptr) 194 { 195 AddMaterial(volMat); 196 auto baseMat = const_cast<G4Material*>( 197 if (baseMat != nullptr) { AddMaterial(ba 198 } 199 } 200 201 // Set the LV region to be either the curren 202 // according to the boolean selector 203 // 204 lv->SetRegion(currentRegion); 205 206 // Stop recursion here if no further daughte 207 // 208 if(noDaughters==0) return; 209 210 G4VPhysicalVolume* daughterPVol = lv->GetDau 211 if (daughterPVol->IsParameterised()) 212 { 213 // Adopt special treatment in case of para 214 // where parameterisation involves a new m 215 // 216 G4VPVParameterisation* pParam = daughterPV 217 218 if (pParam->GetMaterialScanner() != nullpt 219 { 220 std::size_t matNo = pParam->GetMaterialS 221 for (std::size_t mat=0; mat<matNo; ++mat 222 { 223 volMat = pParam->GetMaterialScanner()- 224 if((volMat == nullptr) && fInMassGeome 225 { 226 std::ostringstream message; 227 message << "The parameterisation for 228 << daughterPVol->GetName() < 229 << "does not return a valid 230 << "A volume belonging to th 231 << "have a valid material."; 232 G4Exception("G4Region::ScanVolumeTre 233 FatalException, message, 234 } 235 if (volMat != nullptr) 236 { 237 AddMaterial(volMat); 238 auto baseMat = const_cast<G4Materia 239 if (baseMat != nullptr) { AddMateria 240 } 241 } 242 } 243 else 244 { 245 std::size_t repNo = daughterPVol->GetMul 246 for (std::size_t rep=0; rep<repNo; ++rep 247 { 248 volMat = pParam->ComputeMaterial((G4in 249 if((volMat == nullptr) && fInMassGeome 250 { 251 std::ostringstream message; 252 message << "The parameterisation for 253 << daughterPVol->GetName() < 254 << "does not return a valid 255 << "A volume belonging to th 256 << "have a valid material."; 257 G4Exception("G4Region::ScanVolumeTre 258 FatalException, message, 259 } 260 if(volMat != nullptr) 261 { 262 AddMaterial(volMat); 263 auto baseMat = const_cast<G4Materia 264 if (baseMat != nullptr) { AddMateria 265 } 266 } 267 } 268 G4LogicalVolume* daughterLVol = daughterPV 269 ScanVolumeTree(daughterLVol, region); 270 } 271 else 272 { 273 for (std::size_t i=0; i<noDaughters; ++i) 274 { 275 G4LogicalVolume* daughterLVol = lv->GetD 276 if (!daughterLVol->IsRootRegion()) 277 { 278 // Set daughter's LV to be a region an 279 // the materials list, if the LV is no 280 // 281 ScanVolumeTree(daughterLVol, region); 282 } 283 } 284 } 285 } 286 287 // ******************************************* 288 // AddRootLogicalVolume: 289 // - Adds a root logical volume and sets its 290 // regions. It also recomputes the material 291 // ******************************************* 292 // 293 void G4Region::AddRootLogicalVolume(G4LogicalV 294 { 295 // Check if logical volume is already belong 296 // 297 if ((lv->IsRootRegion()) && (lv->GetRegion() 298 { 299 std::ostringstream message; 300 message << "Logical volume <" << lv->GetNa 301 << "root for region <" << lv->GetR 302 << "It cannot be root logical volu 303 << ">" << G4endl; 304 G4Exception("G4Region::AddRootLogicalVolum 305 message, "A logical volume can 306 return; 307 } 308 309 // Check the logical volume is not already i 310 // 311 if (search) 312 { 313 auto pos = std::find(fRootVolumes.cbegin() 314 if (pos == fRootVolumes.cend()) 315 { 316 // Insert the root volume in the list an 317 // 318 fRootVolumes.push_back(lv); 319 lv->SetRegionRootFlag(true); 320 } 321 } 322 else // WARNING: user *MUST* guarantee lv i 323 { // Providing speedup for very complex 324 fRootVolumes.push_back(lv); 325 lv->SetRegionRootFlag(true); 326 } 327 // Scan recursively the tree of daugther vol 328 // 329 ScanVolumeTree(lv, true); 330 331 // Set region as modified 332 // 333 fRegionMod = true; 334 } 335 336 // ******************************************* 337 // RemoveRootLogicalVolume: 338 // - Removes a root logical volume and resets 339 // regions. It also recomputes the material 340 // ******************************************* 341 // 342 void G4Region::RemoveRootLogicalVolume(G4Logic 343 { 344 // Find and remove logical volume from the l 345 // 346 auto pos = std::find(fRootVolumes.cbegin(),f 347 if (pos != fRootVolumes.cend()) 348 { 349 if (fRootVolumes.size() != 1) // Avoid re 350 { // volume m 351 lv->SetRegionRootFlag(false); 352 } 353 fRootVolumes.erase(pos); 354 } 355 356 if (scan) // Update the materials list 357 { 358 UpdateMaterialList(); 359 } 360 361 // Set region as modified 362 // 363 fRegionMod = true; 364 } 365 366 // ******************************************* 367 // Clean 368 // ******************************************* 369 // 370 void G4Region::Clean() 371 { 372 subInstanceManager.FreeSlave(); 373 } 374 375 // ******************************************* 376 // ClearMaterialList: 377 // - Clears the material list. 378 // ******************************************* 379 // 380 void G4Region::ClearMaterialList() 381 { 382 fMaterials.clear(); 383 } 384 385 // ******************************************* 386 // UpdateMaterialList: 387 // - computes material list looping through 388 // each root logical volume in the region. 389 // ******************************************* 390 // 391 void G4Region::UpdateMaterialList() 392 { 393 // Reset the materials list 394 // 395 ClearMaterialList(); 396 397 // Loop over the root logical volumes and re 398 // of materials from scratch 399 // 400 for (auto pLV=fRootVolumes.cbegin(); pLV!=fR 401 { 402 ScanVolumeTree(*pLV, true); 403 } 404 } 405 406 // ******************************************* 407 // SetWorld: 408 // - Set the world physical volume if this re 409 // world. If the given pointer is null, res 410 // ******************************************* 411 // 412 void G4Region::SetWorld(G4VPhysicalVolume* wp) 413 { 414 if(wp == nullptr) 415 { fWorldPhys = nullptr; } 416 else 417 { if(BelongsTo(wp)) fWorldPhys = wp; } 418 419 return; 420 } 421 422 // ******************************************* 423 // BelongsTo: 424 // - Returns whether this region belongs to t 425 // (recursively scanned to the bottom of th 426 // ******************************************* 427 // 428 G4bool G4Region::BelongsTo(G4VPhysicalVolume* 429 { 430 G4LogicalVolume* currLog = thePhys->GetLogic 431 if (currLog->GetRegion()==this) {return true 432 433 std::size_t nDaughters = currLog->GetNoDaugh 434 while ((nDaughters--) != 0) // Loop checkin 435 { 436 if (BelongsTo(currLog->GetDaughter(nDaught 437 } 438 439 return false; 440 } 441 442 // ******************************************* 443 // ClearFastSimulationManager: 444 // - Set G4FastSimulationManager pointer to t 445 // if it exists. Otherwise set to null. 446 // ******************************************* 447 // 448 void G4Region::ClearFastSimulationManager() 449 { 450 G4bool isUnique; 451 G4Region* parent = GetParentRegion(isUnique) 452 if(parent != nullptr) 453 { 454 if (isUnique) 455 { 456 G4MT_fsmanager = parent->GetFastSimulati 457 } 458 else 459 { 460 std::ostringstream message; 461 message << "Region <" << fName << "> bel 462 << " one parent region !" << G4e 463 << "A region cannot belong to mo 464 << G4endl 465 << "to have fast-simulation assi 466 G4Exception("G4Region::ClearFastSimulati 467 "GeomMgt1002", JustWarning, 468 G4MT_fsmanager = nullptr; 469 } 470 } 471 else 472 { 473 G4MT_fsmanager = nullptr; 474 } 475 } 476 477 // ******************************************* 478 // GetParentRegion: 479 // - Returns a region that contains this regi 480 // Otherwise null is returned. 481 // ******************************************* 482 // 483 G4Region* G4Region::GetParentRegion(G4bool& un 484 { 485 G4Region* parent = nullptr; unique = true; 486 G4LogicalVolumeStore* lvStore = G4LogicalVol 487 488 // Loop over all logical volumes in the stor 489 // 490 for(auto lvItr=lvStore->cbegin(); lvItr!=lvS 491 { 492 std::size_t nD = (*lvItr)->GetNoDaughters( 493 G4Region* aR = (*lvItr)->GetRegion(); 494 495 // Loop over all daughters of each logical 496 // 497 for(std::size_t iD=0; iD<nD; ++iD) 498 { 499 if((*lvItr)->GetDaughter(iD)->GetLogical 500 { 501 if(parent != nullptr) 502 { 503 if(parent!=aR) { unique = false; } 504 } 505 else // Cache LV parent region which 506 // with the same associated regi 507 { 508 parent = aR; 509 } 510 } 511 } 512 } 513 return parent; 514 } 515