Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** >> 22 // >> 23 // >> 24 // $Id: G4Region.cc,v 1.11 2003/11/02 14:01:23 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-06-00 $ >> 26 // 25 // 27 // 26 // G4Region class implementation << 28 // class G4Region Implementation 27 // 29 // 28 // 18.09.02, G.Cosmo - Initial version << 29 // ------------------------------------------- 30 // -------------------------------------------------------------------- 30 31 31 #include "G4Region.hh" << 32 #include "G4RegionStore.hh" 32 #include "G4RegionStore.hh" 33 #include "G4LogicalVolume.hh" 33 #include "G4LogicalVolume.hh" 34 #include "G4VPhysicalVolume.hh" 34 #include "G4VPhysicalVolume.hh" 35 #include "G4LogicalVolumeStore.hh" << 35 #include "G4Region.hh" 36 #include "G4VNestedParameterisation.hh" << 36 #include "G4VPVParameterisation.hh" 37 #include "G4VUserRegionInformation.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 38 60 // ******************************************* 39 // ******************************************************************* 61 // Constructor: 40 // Constructor: 62 // - Adds self to region Store 41 // - Adds self to region Store 63 // ******************************************* 42 // ******************************************************************* 64 // 43 // 65 G4Region::G4Region(const G4String& pName) 44 G4Region::G4Region(const G4String& pName) 66 : fName(pName) << 45 : fName(pName), fRegionMod(true), fCut(0), fUserInfo(0) 67 { 46 { 68 << 69 instanceID = subInstanceManager.CreateSubIns << 70 G4MT_fsmanager = nullptr; << 71 G4MT_rsaction = nullptr; << 72 << 73 G4RegionStore* rStore = G4RegionStore::GetIn 47 G4RegionStore* rStore = G4RegionStore::GetInstance(); 74 if (rStore->GetRegion(pName, false) != nullp << 48 if (rStore->GetRegion(pName,false)) 75 { 49 { 76 std::ostringstream message; << 50 G4cerr << "WARNING - G4Region::G4Region()" << G4endl 77 message << "The region has NOT been regist << 51 << " Region " << pName << " already existing in store !" 78 << " Region " << pName << << 52 << G4endl; 79 << G4endl; << 53 G4Exception("G4Region::G4Region()", "InvalidSetup", JustWarning, 80 G4Exception("G4Region::G4Region()", "GeomM << 54 "The region has NOT been registered !"); 81 JustWarning, message); << 82 } 55 } 83 else 56 else 84 { 57 { 85 rStore->Register(this); 58 rStore->Register(this); 86 } 59 } 87 } 60 } 88 61 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 // ******************************************* 62 // ******************************************************************* 107 // Destructor: 63 // Destructor: 108 // - Removes self from region Store 64 // - Removes self from region Store 109 // ******************************************* 65 // ******************************************************************* 110 // 66 // 111 G4Region::~G4Region() 67 G4Region::~G4Region() 112 { 68 { 113 G4RegionStore::GetInstance()->DeRegister(thi 69 G4RegionStore::GetInstance()->DeRegister(this); 114 delete fUserInfo; << 70 if(fUserInfo) 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 } 71 } 162 72 163 // ******************************************* 73 // ******************************************************************* 164 // ScanVolumeTree: 74 // ScanVolumeTree: 165 // - Scans recursively the 'lv' logical volum 75 // - Scans recursively the 'lv' logical volume tree, retrieves 166 // and places all materials in the list. 76 // and places all materials in the list. 167 // - The boolean flag 'region' identifies if 77 // - The boolean flag 'region' identifies if the volume tree must 168 // have region reset (false) or if the curr 78 // have region reset (false) or if the current region must be 169 // associated to the logical volume 'lv' an 79 // associated to the logical volume 'lv' and its tree (true). 170 // ******************************************* 80 // ******************************************************************* 171 // 81 // 172 void G4Region::ScanVolumeTree(G4LogicalVolume* 82 void G4Region::ScanVolumeTree(G4LogicalVolume* lv, G4bool region) 173 { 83 { 174 // If logical volume is going to become a re 84 // If logical volume is going to become a region, add 175 // its material to the list if not already p 85 // its material to the list if not already present 176 // 86 // 177 G4Region* currentRegion = nullptr; << 87 G4Region* currentRegion = 0; 178 std::size_t noDaughters = lv->GetNoDaughters << 88 size_t noDaughters = lv->GetNoDaughters(); 179 G4Material* volMat = lv->GetMaterial(); 89 G4Material* volMat = lv->GetMaterial(); 180 if((volMat == nullptr) && fInMassGeometry) << 90 G4MaterialList::iterator pos; 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) 91 if (region) 191 { 92 { 192 currentRegion = this; 93 currentRegion = this; 193 if (volMat != nullptr) << 94 pos = std::find(fMaterials.begin(),fMaterials.end(),volMat); 194 { << 95 if (pos == fMaterials.end()) 195 AddMaterial(volMat); << 96 { 196 auto baseMat = const_cast<G4Material*>( << 97 fMaterials.push_back(volMat); 197 if (baseMat != nullptr) { AddMaterial(ba << 98 fRegionMod = true; 198 } 99 } 199 } 100 } 200 101 201 // Set the LV region to be either the curren 102 // Set the LV region to be either the current region or NULL, 202 // according to the boolean selector 103 // according to the boolean selector 203 // 104 // 204 lv->SetRegion(currentRegion); 105 lv->SetRegion(currentRegion); 205 106 206 // Stop recursion here if no further daughte 107 // Stop recursion here if no further daughters are involved 207 // 108 // 208 if(noDaughters==0) return; 109 if(noDaughters==0) return; 209 110 210 G4VPhysicalVolume* daughterPVol = lv->GetDau 111 G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0); 211 if (daughterPVol->IsParameterised()) 112 if (daughterPVol->IsParameterised()) 212 { 113 { 213 // Adopt special treatment in case of para 114 // Adopt special treatment in case of parameterised volumes, 214 // where parameterisation involves a new m 115 // where parameterisation involves a new material scan 215 // 116 // 216 G4VPVParameterisation* pParam = daughterPV 117 G4VPVParameterisation* pParam = daughterPVol->GetParameterisation(); 217 << 118 size_t repNo = daughterPVol->GetMultiplicity(); 218 if (pParam->GetMaterialScanner() != nullpt << 119 for (register size_t rep=0; rep<repNo; rep++) 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 { 120 { 245 std::size_t repNo = daughterPVol->GetMul << 121 volMat = pParam->ComputeMaterial(rep, daughterPVol); 246 for (std::size_t rep=0; rep<repNo; ++rep << 122 pos = std::find(fMaterials.begin(),fMaterials.end(),volMat); >> 123 if (pos == fMaterials.end()) 247 { 124 { 248 volMat = pParam->ComputeMaterial((G4in << 125 fMaterials.push_back(volMat); 249 if((volMat == nullptr) && fInMassGeome << 126 fRegionMod = true; 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 } 127 } 267 } 128 } 268 G4LogicalVolume* daughterLVol = daughterPV 129 G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume(); 269 ScanVolumeTree(daughterLVol, region); 130 ScanVolumeTree(daughterLVol, region); 270 } 131 } 271 else 132 else 272 { 133 { 273 for (std::size_t i=0; i<noDaughters; ++i) << 134 for (register size_t i=0; i<noDaughters; i++) 274 { 135 { 275 G4LogicalVolume* daughterLVol = lv->GetD 136 G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume(); 276 if (!daughterLVol->IsRootRegion()) 137 if (!daughterLVol->IsRootRegion()) 277 { 138 { 278 // Set daughter's LV to be a region an 139 // Set daughter's LV to be a region and store materials in 279 // the materials list, if the LV is no 140 // the materials list, if the LV is not already a root region 280 // 141 // 281 ScanVolumeTree(daughterLVol, region); 142 ScanVolumeTree(daughterLVol, region); 282 } 143 } 283 } 144 } 284 } 145 } 285 } 146 } 286 147 287 // ******************************************* 148 // ******************************************************************* 288 // AddRootLogicalVolume: 149 // AddRootLogicalVolume: 289 // - Adds a root logical volume and sets its 150 // - Adds a root logical volume and sets its daughters flags as 290 // regions. It also recomputes the material 151 // regions. It also recomputes the materials list for the region. 291 // ******************************************* 152 // ******************************************************************* 292 // 153 // 293 void G4Region::AddRootLogicalVolume(G4LogicalV << 154 void G4Region::AddRootLogicalVolume(G4LogicalVolume* lv) 294 { 155 { 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 156 // Check the logical volume is not already in the list 310 // 157 // 311 if (search) << 158 G4RootLVList::iterator pos; >> 159 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv); >> 160 if (pos == fRootVolumes.end()) 312 { 161 { 313 auto pos = std::find(fRootVolumes.cbegin() << 162 // Insert the root volume in the list and set it as root region 314 if (pos == fRootVolumes.cend()) << 163 // 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); 164 fRootVolumes.push_back(lv); 325 lv->SetRegionRootFlag(true); 165 lv->SetRegionRootFlag(true); 326 } 166 } >> 167 327 // Scan recursively the tree of daugther vol 168 // Scan recursively the tree of daugther volumes and set regions 328 // 169 // 329 ScanVolumeTree(lv, true); 170 ScanVolumeTree(lv, true); 330 171 331 // Set region as modified 172 // Set region as modified 332 // 173 // 333 fRegionMod = true; 174 fRegionMod = true; 334 } 175 } 335 176 336 // ******************************************* 177 // ******************************************************************* 337 // RemoveRootLogicalVolume: 178 // RemoveRootLogicalVolume: 338 // - Removes a root logical volume and resets 179 // - Removes a root logical volume and resets its daughters flags as 339 // regions. It also recomputes the material 180 // regions. It also recomputes the materials list for the region. 340 // ******************************************* 181 // ******************************************************************* 341 // 182 // 342 void G4Region::RemoveRootLogicalVolume(G4Logic << 183 void G4Region::RemoveRootLogicalVolume(G4LogicalVolume* lv) 343 { 184 { 344 // Find and remove logical volume from the l 185 // Find and remove logical volume from the list 345 // 186 // 346 auto pos = std::find(fRootVolumes.cbegin(),f << 187 G4RootLVList::iterator pos; 347 if (pos != fRootVolumes.cend()) << 188 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv); >> 189 if (pos != fRootVolumes.end()) 348 { 190 { 349 if (fRootVolumes.size() != 1) // Avoid re << 350 { // volume m << 351 lv->SetRegionRootFlag(false); << 352 } << 353 fRootVolumes.erase(pos); 191 fRootVolumes.erase(pos); >> 192 lv->SetRegionRootFlag(false); 354 } 193 } 355 194 356 if (scan) // Update the materials list << 195 // Scan recursively the tree of daugther volumes and reset regions 357 { << 196 // 358 UpdateMaterialList(); << 197 //ScanVolumeTree(lv, false); 359 } << 198 >> 199 // Update the materials list >> 200 // >> 201 //UpdateMaterialList(); 360 202 361 // Set region as modified 203 // Set region as modified 362 // 204 // 363 fRegionMod = true; 205 fRegionMod = true; 364 } 206 } 365 207 366 // ******************************************* << 367 // Clean << 368 // ******************************************* << 369 // << 370 void G4Region::Clean() << 371 { << 372 subInstanceManager.FreeSlave(); << 373 } << 374 << 375 // ******************************************* 208 // ******************************************************************* 376 // ClearMaterialList: 209 // ClearMaterialList: 377 // - Clears the material list. 210 // - Clears the material list. 378 // ******************************************* 211 // ******************************************************************* 379 // 212 // 380 void G4Region::ClearMaterialList() 213 void G4Region::ClearMaterialList() 381 { 214 { 382 fMaterials.clear(); 215 fMaterials.clear(); 383 } 216 } 384 217 385 // ******************************************* 218 // ******************************************************************* 386 // UpdateMaterialList: 219 // UpdateMaterialList: 387 // - computes material list looping through 220 // - computes material list looping through 388 // each root logical volume in the region. 221 // each root logical volume in the region. 389 // ******************************************* 222 // ******************************************************************* 390 // 223 // 391 void G4Region::UpdateMaterialList() 224 void G4Region::UpdateMaterialList() 392 { 225 { 393 // Reset the materials list 226 // Reset the materials list 394 // 227 // 395 ClearMaterialList(); 228 ClearMaterialList(); 396 229 397 // Loop over the root logical volumes and re 230 // Loop over the root logical volumes and rebuild the list 398 // of materials from scratch 231 // of materials from scratch 399 // 232 // 400 for (auto pLV=fRootVolumes.cbegin(); pLV!=fR << 233 G4RootLVList::iterator pLV; >> 234 for (pLV=fRootVolumes.begin(); pLV!=fRootVolumes.end(); pLV++) 401 { 235 { 402 ScanVolumeTree(*pLV, true); 236 ScanVolumeTree(*pLV, true); 403 } 237 } 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 } 238 } 515 239