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.14 2005/04/04 09:28:45 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-07-01-patch-01 $ >> 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), fUserLimits(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 if(!volMat) 181 { 91 { 182 std::ostringstream message; << 92 G4String errmsg = "Logical volume <"; 183 message << "Logical volume <" << lv->GetNa << 93 errmsg += lv->GetName(); 184 << "does not have a valid material << 94 errmsg += "> does not have a valid material pointer.\n"; 185 << "A logical volume belonging to << 95 errmsg += "A logical volume belonging to the (tracking) world volume "; 186 << "must have a valid material."; << 96 errmsg += "must have a valid material.\nCheck your geometry construction."; 187 G4Exception("G4Region::ScanVolumeTree()", << 97 G4Exception("G4Region::ScanVolumeTree()", "SetupError", 188 FatalException, message, "Chec << 98 FatalException, errmsg); 189 } 99 } >> 100 G4MaterialList::iterator pos; 190 if (region) 101 if (region) 191 { 102 { 192 currentRegion = this; 103 currentRegion = this; 193 if (volMat != nullptr) << 104 pos = std::find(fMaterials.begin(),fMaterials.end(),volMat); 194 { << 105 if (pos == fMaterials.end()) 195 AddMaterial(volMat); << 106 { 196 auto baseMat = const_cast<G4Material*>( << 107 fMaterials.push_back(volMat); 197 if (baseMat != nullptr) { AddMaterial(ba << 108 fRegionMod = true; 198 } 109 } 199 } 110 } 200 111 201 // Set the LV region to be either the curren 112 // Set the LV region to be either the current region or NULL, 202 // according to the boolean selector 113 // according to the boolean selector 203 // 114 // 204 lv->SetRegion(currentRegion); 115 lv->SetRegion(currentRegion); 205 116 206 // Stop recursion here if no further daughte 117 // Stop recursion here if no further daughters are involved 207 // 118 // 208 if(noDaughters==0) return; 119 if(noDaughters==0) return; 209 120 210 G4VPhysicalVolume* daughterPVol = lv->GetDau 121 G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0); 211 if (daughterPVol->IsParameterised()) 122 if (daughterPVol->IsParameterised()) 212 { 123 { 213 // Adopt special treatment in case of para 124 // Adopt special treatment in case of parameterised volumes, 214 // where parameterisation involves a new m 125 // where parameterisation involves a new material scan 215 // 126 // 216 G4VPVParameterisation* pParam = daughterPV 127 G4VPVParameterisation* pParam = daughterPVol->GetParameterisation(); 217 << 128 size_t repNo = daughterPVol->GetMultiplicity(); 218 if (pParam->GetMaterialScanner() != nullpt << 129 for (register size_t rep=0; rep<repNo; rep++) 219 { 130 { 220 std::size_t matNo = pParam->GetMaterialS << 131 volMat = pParam->ComputeMaterial(rep, daughterPVol); 221 for (std::size_t mat=0; mat<matNo; ++mat << 132 if(!volMat) 222 { 133 { 223 volMat = pParam->GetMaterialScanner()- << 134 G4String errmsg = "The parameterisation for the physical volume <"; 224 if((volMat == nullptr) && fInMassGeome << 135 errmsg += daughterPVol->GetName(); 225 { << 136 errmsg += ">\n does not return a valid material pointer.\n"; 226 std::ostringstream message; << 137 errmsg += "A volume belonging to the (tracking) world volume must have "; 227 message << "The parameterisation for << 138 errmsg += "a valid material.\nCheck your parameterisation."; 228 << daughterPVol->GetName() < << 139 G4Exception("G4Region::ScanVolumeTree()", 229 << "does not return a valid << 140 "SetupError", FatalException, errmsg); 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 } 141 } 242 } << 142 pos = std::find(fMaterials.begin(),fMaterials.end(),volMat); 243 else << 143 if (pos == fMaterials.end()) 244 { << 245 std::size_t repNo = daughterPVol->GetMul << 246 for (std::size_t rep=0; rep<repNo; ++rep << 247 { 144 { 248 volMat = pParam->ComputeMaterial((G4in << 145 fMaterials.push_back(volMat); 249 if((volMat == nullptr) && fInMassGeome << 146 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 } 147 } 267 } 148 } 268 G4LogicalVolume* daughterLVol = daughterPV 149 G4LogicalVolume* daughterLVol = daughterPVol->GetLogicalVolume(); 269 ScanVolumeTree(daughterLVol, region); 150 ScanVolumeTree(daughterLVol, region); 270 } 151 } 271 else 152 else 272 { 153 { 273 for (std::size_t i=0; i<noDaughters; ++i) << 154 for (register size_t i=0; i<noDaughters; i++) 274 { 155 { 275 G4LogicalVolume* daughterLVol = lv->GetD 156 G4LogicalVolume* daughterLVol = lv->GetDaughter(i)->GetLogicalVolume(); 276 if (!daughterLVol->IsRootRegion()) 157 if (!daughterLVol->IsRootRegion()) 277 { 158 { 278 // Set daughter's LV to be a region an 159 // Set daughter's LV to be a region and store materials in 279 // the materials list, if the LV is no 160 // the materials list, if the LV is not already a root region 280 // 161 // 281 ScanVolumeTree(daughterLVol, region); 162 ScanVolumeTree(daughterLVol, region); 282 } 163 } 283 } 164 } 284 } 165 } 285 } 166 } 286 167 287 // ******************************************* 168 // ******************************************************************* 288 // AddRootLogicalVolume: 169 // AddRootLogicalVolume: 289 // - Adds a root logical volume and sets its 170 // - Adds a root logical volume and sets its daughters flags as 290 // regions. It also recomputes the material 171 // regions. It also recomputes the materials list for the region. 291 // ******************************************* 172 // ******************************************************************* 292 // 173 // 293 void G4Region::AddRootLogicalVolume(G4LogicalV << 174 void G4Region::AddRootLogicalVolume(G4LogicalVolume* lv) 294 { 175 { 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 176 // Check the logical volume is not already in the list 310 // 177 // 311 if (search) << 178 G4RootLVList::iterator pos; >> 179 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv); >> 180 if (pos == fRootVolumes.end()) 312 { 181 { 313 auto pos = std::find(fRootVolumes.cbegin() << 182 // Insert the root volume in the list and set it as root region 314 if (pos == fRootVolumes.cend()) << 183 // 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); 184 fRootVolumes.push_back(lv); 325 lv->SetRegionRootFlag(true); 185 lv->SetRegionRootFlag(true); 326 } 186 } >> 187 327 // Scan recursively the tree of daugther vol 188 // Scan recursively the tree of daugther volumes and set regions 328 // 189 // 329 ScanVolumeTree(lv, true); 190 ScanVolumeTree(lv, true); 330 191 331 // Set region as modified 192 // Set region as modified 332 // 193 // 333 fRegionMod = true; 194 fRegionMod = true; 334 } 195 } 335 196 336 // ******************************************* 197 // ******************************************************************* 337 // RemoveRootLogicalVolume: 198 // RemoveRootLogicalVolume: 338 // - Removes a root logical volume and resets 199 // - Removes a root logical volume and resets its daughters flags as 339 // regions. It also recomputes the material 200 // regions. It also recomputes the materials list for the region. 340 // ******************************************* 201 // ******************************************************************* 341 // 202 // 342 void G4Region::RemoveRootLogicalVolume(G4Logic << 203 void G4Region::RemoveRootLogicalVolume(G4LogicalVolume* lv) 343 { 204 { 344 // Find and remove logical volume from the l 205 // Find and remove logical volume from the list 345 // 206 // 346 auto pos = std::find(fRootVolumes.cbegin(),f << 207 G4RootLVList::iterator pos; 347 if (pos != fRootVolumes.cend()) << 208 pos = std::find(fRootVolumes.begin(),fRootVolumes.end(),lv); >> 209 if (pos != fRootVolumes.end()) 348 { 210 { 349 if (fRootVolumes.size() != 1) // Avoid re << 350 { // volume m << 351 lv->SetRegionRootFlag(false); << 352 } << 353 fRootVolumes.erase(pos); 211 fRootVolumes.erase(pos); >> 212 lv->SetRegionRootFlag(false); 354 } 213 } 355 214 356 if (scan) // Update the materials list << 215 // Scan recursively the tree of daugther volumes and reset regions 357 { << 216 // 358 UpdateMaterialList(); << 217 //ScanVolumeTree(lv, false); 359 } << 218 >> 219 // Update the materials list >> 220 // >> 221 //UpdateMaterialList(); 360 222 361 // Set region as modified 223 // Set region as modified 362 // 224 // 363 fRegionMod = true; 225 fRegionMod = true; 364 } 226 } 365 227 366 // ******************************************* << 367 // Clean << 368 // ******************************************* << 369 // << 370 void G4Region::Clean() << 371 { << 372 subInstanceManager.FreeSlave(); << 373 } << 374 << 375 // ******************************************* 228 // ******************************************************************* 376 // ClearMaterialList: 229 // ClearMaterialList: 377 // - Clears the material list. 230 // - Clears the material list. 378 // ******************************************* 231 // ******************************************************************* 379 // 232 // 380 void G4Region::ClearMaterialList() 233 void G4Region::ClearMaterialList() 381 { 234 { 382 fMaterials.clear(); 235 fMaterials.clear(); 383 } 236 } 384 237 385 // ******************************************* 238 // ******************************************************************* 386 // UpdateMaterialList: 239 // UpdateMaterialList: 387 // - computes material list looping through 240 // - computes material list looping through 388 // each root logical volume in the region. 241 // each root logical volume in the region. 389 // ******************************************* 242 // ******************************************************************* 390 // 243 // 391 void G4Region::UpdateMaterialList() 244 void G4Region::UpdateMaterialList() 392 { 245 { 393 // Reset the materials list 246 // Reset the materials list 394 // 247 // 395 ClearMaterialList(); 248 ClearMaterialList(); 396 249 397 // Loop over the root logical volumes and re 250 // Loop over the root logical volumes and rebuild the list 398 // of materials from scratch 251 // of materials from scratch 399 // 252 // 400 for (auto pLV=fRootVolumes.cbegin(); pLV!=fR << 253 G4RootLVList::iterator pLV; >> 254 for (pLV=fRootVolumes.begin(); pLV!=fRootVolumes.end(); pLV++) 401 { 255 { 402 ScanVolumeTree(*pLV, true); 256 ScanVolumeTree(*pLV, true); 403 } 257 } 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 } 258 } 515 259