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