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 // G4RegionStore implementation 26 // G4RegionStore 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 "G4GeometryManager.hh" 33 #include "G4GeometryManager.hh" 34 #include "G4VPhysicalVolume.hh" 34 #include "G4VPhysicalVolume.hh" 35 #include "G4PhysicalVolumeStore.hh" 35 #include "G4PhysicalVolumeStore.hh" 36 36 37 #include "G4ios.hh" 37 #include "G4ios.hh" 38 #include "G4AutoLock.hh" 38 #include "G4AutoLock.hh" 39 39 40 namespace 40 namespace 41 { 41 { 42 G4Mutex mapMutex = G4MUTEX_INITIALIZER; 42 G4Mutex mapMutex = G4MUTEX_INITIALIZER; 43 } 43 } 44 44 45 // ******************************************* 45 // *************************************************************************** 46 // Static class variables 46 // Static class variables 47 // ******************************************* 47 // *************************************************************************** 48 // 48 // 49 G4RegionStore* G4RegionStore::fgInstance = nul 49 G4RegionStore* G4RegionStore::fgInstance = nullptr; 50 G4ThreadLocal G4VStoreNotifier* G4RegionStore: 50 G4ThreadLocal G4VStoreNotifier* G4RegionStore::fgNotifier = nullptr; 51 G4ThreadLocal G4bool G4RegionStore::locked = f 51 G4ThreadLocal G4bool G4RegionStore::locked = false; 52 52 53 // ******************************************* 53 // *************************************************************************** 54 // Protected constructor: Construct underlying 54 // Protected constructor: Construct underlying container with 55 // initial size of 20 entries 55 // initial size of 20 entries 56 // ******************************************* 56 // *************************************************************************** 57 // 57 // 58 G4RegionStore::G4RegionStore() 58 G4RegionStore::G4RegionStore() 59 << 59 : std::vector<G4Region*>() 60 { 60 { 61 reserve(20); 61 reserve(20); 62 } 62 } 63 63 64 // ******************************************* 64 // *************************************************************************** 65 // Destructor 65 // Destructor 66 // ******************************************* 66 // *************************************************************************** 67 // 67 // 68 G4RegionStore::~G4RegionStore() 68 G4RegionStore::~G4RegionStore() 69 { 69 { 70 Clean(); // Delete all regions in the store 70 Clean(); // Delete all regions in the store 71 G4Region::Clean(); // Delete allocated sub- 71 G4Region::Clean(); // Delete allocated sub-instance data 72 } 72 } 73 73 74 // ******************************************* 74 // *************************************************************************** 75 // Delete all regions from the store except fo 75 // Delete all regions from the store except for the world region 76 // ******************************************* 76 // *************************************************************************** 77 // 77 // 78 void G4RegionStore::Clean() 78 void G4RegionStore::Clean() 79 { 79 { 80 // Do nothing if geometry is closed 80 // Do nothing if geometry is closed 81 // 81 // 82 if (G4GeometryManager::GetInstance()->IsGeom << 82 if (G4GeometryManager::IsGeometryClosed()) 83 { 83 { 84 G4cout << "WARNING - Attempt to delete the 84 G4cout << "WARNING - Attempt to delete the region store" 85 << " while geometry closed !" << G4 85 << " while geometry closed !" << G4endl; 86 return; 86 return; 87 } 87 } 88 88 89 // Locks store for deletion of regions. De-r 89 // Locks store for deletion of regions. De-registration will be 90 // performed at this stage. G4Regions will n 90 // performed at this stage. G4Regions will not de-register themselves. 91 // 91 // 92 locked = true; 92 locked = true; 93 93 >> 94 std::size_t i=0; 94 G4RegionStore* store = GetInstance(); 95 G4RegionStore* store = GetInstance(); 95 96 >> 97 #ifdef G4GEOMETRY_VOXELDEBUG >> 98 G4cout << "Deleting Regions ... "; >> 99 #endif >> 100 96 for(auto pos=store->cbegin(); pos!=store->ce 101 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos) 97 { 102 { 98 if (fgNotifier != nullptr) { fgNotifier->N 103 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); } 99 delete *pos; << 104 delete *pos; ++i; 100 } 105 } 101 106 >> 107 #ifdef G4GEOMETRY_VOXELDEBUG >> 108 if (store->size() < i-1) >> 109 { G4cout << "No regions deleted. Already deleted by user ?" << G4endl; } >> 110 else >> 111 { G4cout << i-1 << " regions deleted !" << G4endl; } >> 112 #endif >> 113 102 store->bmap.clear(); store->mvalid = false; 114 store->bmap.clear(); store->mvalid = false; 103 locked = false; 115 locked = false; 104 store->clear(); 116 store->clear(); 105 } 117 } 106 118 107 // ******************************************* 119 // *************************************************************************** 108 // Associate user notifier to the store 120 // Associate user notifier to the store 109 // ******************************************* 121 // *************************************************************************** 110 // 122 // 111 void G4RegionStore::SetNotifier(G4VStoreNotifi 123 void G4RegionStore::SetNotifier(G4VStoreNotifier* pNotifier) 112 { 124 { 113 GetInstance(); 125 GetInstance(); 114 fgNotifier = pNotifier; 126 fgNotifier = pNotifier; 115 } 127 } 116 128 117 // ******************************************* 129 // *************************************************************************** 118 // Bring contents of internal map up to date a 130 // Bring contents of internal map up to date and reset validity flag 119 // ******************************************* 131 // *************************************************************************** 120 // 132 // 121 void G4RegionStore::UpdateMap() 133 void G4RegionStore::UpdateMap() 122 { 134 { 123 G4AutoLock l(&mapMutex); // to avoid thread 135 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation 124 if (mvalid) return; 136 if (mvalid) return; 125 bmap.clear(); 137 bmap.clear(); 126 for(auto pos=GetInstance()->cbegin(); pos!=G 138 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos) 127 { 139 { 128 const G4String& reg_name = (*pos)->GetName 140 const G4String& reg_name = (*pos)->GetName(); 129 auto it = bmap.find(reg_name); 141 auto it = bmap.find(reg_name); 130 if (it != bmap.cend()) 142 if (it != bmap.cend()) 131 { 143 { 132 it->second.push_back(*pos); 144 it->second.push_back(*pos); 133 } 145 } 134 else 146 else 135 { 147 { 136 std::vector<G4Region*> reg_vec { *pos }; 148 std::vector<G4Region*> reg_vec { *pos }; 137 bmap.insert(std::make_pair(reg_name, reg 149 bmap.insert(std::make_pair(reg_name, reg_vec)); 138 } 150 } 139 } 151 } 140 mvalid = true; 152 mvalid = true; 141 l.unlock(); 153 l.unlock(); 142 } 154 } 143 155 144 // ******************************************* 156 // *************************************************************************** 145 // Add Region to container 157 // Add Region to container 146 // ******************************************* 158 // *************************************************************************** 147 // 159 // 148 void G4RegionStore::Register(G4Region* pRegion 160 void G4RegionStore::Register(G4Region* pRegion) 149 { 161 { 150 G4RegionStore* store = GetInstance(); 162 G4RegionStore* store = GetInstance(); 151 store->push_back(pRegion); 163 store->push_back(pRegion); 152 const G4String& reg_name = pRegion->GetName( 164 const G4String& reg_name = pRegion->GetName(); 153 auto it = store->bmap.find(reg_name); 165 auto it = store->bmap.find(reg_name); 154 if (it != store->bmap.cend()) 166 if (it != store->bmap.cend()) 155 { 167 { 156 it->second.push_back(pRegion); 168 it->second.push_back(pRegion); 157 } 169 } 158 else 170 else 159 { 171 { 160 std::vector<G4Region*> reg_vec { pRegion } 172 std::vector<G4Region*> reg_vec { pRegion }; 161 store->bmap.insert(std::make_pair(reg_name 173 store->bmap.insert(std::make_pair(reg_name, reg_vec)); 162 } 174 } 163 if (fgNotifier != nullptr) { fgNotifier->Not << 175 if (fgNotifier) { fgNotifier->NotifyRegistration(); } 164 store->mvalid = true; 176 store->mvalid = true; 165 } 177 } 166 178 167 // ******************************************* 179 // *************************************************************************** 168 // Remove Region from container 180 // Remove Region from container 169 // ******************************************* 181 // *************************************************************************** 170 // 182 // 171 void G4RegionStore::DeRegister(G4Region* pRegi 183 void G4RegionStore::DeRegister(G4Region* pRegion) 172 { 184 { 173 G4RegionStore* store = GetInstance(); 185 G4RegionStore* store = GetInstance(); 174 if (!locked) // Do not de-register if loc 186 if (!locked) // Do not de-register if locked ! 175 { 187 { 176 if (fgNotifier != nullptr) { fgNotifier-> 188 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); } 177 for (auto i=store->cbegin(); i!=store->cen 189 for (auto i=store->cbegin(); i!=store->cend(); ++i) 178 { 190 { 179 if (**i==*pRegion) 191 if (**i==*pRegion) 180 { 192 { 181 store->erase(i); 193 store->erase(i); 182 break; 194 break; 183 } 195 } 184 } 196 } 185 const G4String& reg_name = pRegion->GetNam 197 const G4String& reg_name = pRegion->GetName(); 186 auto it = store->bmap.find(reg_name); 198 auto it = store->bmap.find(reg_name); 187 if (it != store->bmap.cend()) 199 if (it != store->bmap.cend()) 188 { 200 { 189 if (it->second.size() > 1) 201 if (it->second.size() > 1) 190 { 202 { 191 for (auto i=it->second.cbegin(); i!=it 203 for (auto i=it->second.cbegin(); i!=it->second.cend(); ++i) 192 { 204 { 193 if (**i==*pRegion) 205 if (**i==*pRegion) 194 { 206 { 195 it->second.erase(i); 207 it->second.erase(i); 196 break; 208 break; 197 } 209 } 198 } 210 } 199 } 211 } 200 else 212 else 201 { 213 { 202 store->bmap.erase(it); 214 store->bmap.erase(it); 203 } 215 } 204 } 216 } 205 } 217 } 206 } 218 } 207 219 208 // ******************************************* 220 // *************************************************************************** 209 // Return ptr to Store, setting if necessary 221 // Return ptr to Store, setting if necessary 210 // ******************************************* 222 // *************************************************************************** 211 // 223 // 212 G4RegionStore* G4RegionStore::GetInstance() 224 G4RegionStore* G4RegionStore::GetInstance() 213 { 225 { 214 static G4RegionStore worldStore; 226 static G4RegionStore worldStore; 215 if (fgInstance == nullptr) 227 if (fgInstance == nullptr) 216 { 228 { 217 fgInstance = &worldStore; 229 fgInstance = &worldStore; 218 } 230 } 219 return fgInstance; 231 return fgInstance; 220 } 232 } 221 233 222 // ******************************************* 234 // *************************************************************************** 223 // Loops through all regions to verify if a re 235 // Loops through all regions to verify if a region has been modified. 224 // It returns TRUE if just one region is modif 236 // It returns TRUE if just one region is modified. 225 // ******************************************* 237 // *************************************************************************** 226 // 238 // 227 G4bool G4RegionStore::IsModified() const 239 G4bool G4RegionStore::IsModified() const 228 { 240 { 229 for (auto i=GetInstance()->cbegin(); i!=GetI 241 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i) 230 { 242 { 231 if ((*i)->IsModified()) { return true; } 243 if ((*i)->IsModified()) { return true; } 232 } 244 } 233 return false; 245 return false; 234 } 246 } 235 247 236 // ******************************************* 248 // *************************************************************************** 237 // Loops through all regions to reset flag for 249 // Loops through all regions to reset flag for modification to FALSE. 238 // Used by the run manager to notify that the 250 // Used by the run manager to notify that the physics table has been updated. 239 // ******************************************* 251 // *************************************************************************** 240 // 252 // 241 void G4RegionStore::ResetRegionModified() 253 void G4RegionStore::ResetRegionModified() 242 { 254 { 243 for (auto i=GetInstance()->cbegin(); i!=GetI 255 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i) 244 { 256 { 245 (*i)->RegionModified(false); 257 (*i)->RegionModified(false); 246 } 258 } 247 } 259 } 248 260 249 // ******************************************* 261 // *************************************************************************** 250 // Forces recomputation of material lists in a 262 // Forces recomputation of material lists in all regions in the store. 251 // ******************************************* 263 // *************************************************************************** 252 // 264 // 253 void G4RegionStore::UpdateMaterialList(G4VPhys 265 void G4RegionStore::UpdateMaterialList(G4VPhysicalVolume* currentWorld) 254 { 266 { 255 for (auto i=GetInstance()->cbegin(); i!=GetI 267 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i) 256 { 268 { 257 if((*i)->IsInMassGeometry() || (*i)->IsInP 269 if((*i)->IsInMassGeometry() || (*i)->IsInParallelGeometry() 258 || (currentWor 270 || (currentWorld != nullptr)) 259 { (*i)->UpdateMaterialList(); } 271 { (*i)->UpdateMaterialList(); } 260 } 272 } 261 } 273 } 262 274 263 // ******************************************* 275 // *************************************************************************** 264 // Returns a region through its name specifica 276 // Returns a region through its name specification. 265 // ******************************************* 277 // *************************************************************************** 266 // 278 // 267 G4Region* G4RegionStore::GetRegion(const G4Str 279 G4Region* G4RegionStore::GetRegion(const G4String& name, G4bool verbose) const 268 { 280 { 269 G4RegionStore* store = GetInstance(); 281 G4RegionStore* store = GetInstance(); 270 if (!store->mvalid) { store->UpdateMap(); } 282 if (!store->mvalid) { store->UpdateMap(); } 271 auto pos = store->bmap.find(name); 283 auto pos = store->bmap.find(name); 272 if(pos != store->bmap.cend()) 284 if(pos != store->bmap.cend()) 273 { 285 { 274 if ((verbose) && (pos->second.size()>1)) 286 if ((verbose) && (pos->second.size()>1)) 275 { 287 { 276 std::ostringstream message; 288 std::ostringstream message; 277 message << "There exists more than ONE r 289 message << "There exists more than ONE region in store named: " 278 << name << "!" << G4endl 290 << name << "!" << G4endl 279 << "Returning the first found."; 291 << "Returning the first found."; 280 G4Exception("G4RegionStore::GetSolid()", 292 G4Exception("G4RegionStore::GetSolid()", 281 "GeomMgt1001", JustWarning, 293 "GeomMgt1001", JustWarning, message); 282 } 294 } 283 return pos->second[0]; 295 return pos->second[0]; 284 } 296 } 285 if (verbose) 297 if (verbose) 286 { 298 { 287 std::ostringstream message; 299 std::ostringstream message; 288 message << "Region NOT found in store !" < 300 message << "Region NOT found in store !" << G4endl 289 << " Region " << name << " 301 << " Region " << name << " NOT found in store !" << G4endl 290 << " Returning NULL pointer 302 << " Returning NULL pointer."; 291 G4Exception("G4RegionStore::GetRegion()", 303 G4Exception("G4RegionStore::GetRegion()", 292 "GeomMgt1001", JustWarning, me 304 "GeomMgt1001", JustWarning, message); 293 } 305 } 294 return nullptr; 306 return nullptr; 295 } 307 } 296 308 297 // ******************************************* 309 // *************************************************************************** 298 // Returns a region through its name specifica 310 // Returns a region through its name specification, if it exists. 299 // If it does not exist it will allocate a new 311 // If it does not exist it will allocate a new region with the given 300 // name, delegating the ownership to the calle 312 // name, delegating the ownership to the caller client. 301 // ******************************************* 313 // *************************************************************************** 302 // 314 // 303 G4Region* G4RegionStore::FindOrCreateRegion(co 315 G4Region* G4RegionStore::FindOrCreateRegion(const G4String& name) 304 { 316 { 305 G4Region* target = GetRegion(name,false); 317 G4Region* target = GetRegion(name,false); 306 if (target == nullptr) 318 if (target == nullptr) 307 { 319 { 308 target = new G4Region(name); 320 target = new G4Region(name); 309 } 321 } 310 return target; 322 return target; 311 } 323 } 312 324 313 // ******************************************* 325 // ************************************************************************** 314 // Set a world physical volume pointer to a re 326 // Set a world physical volume pointer to a region that belongs to it. 315 // Scan over all world volumes. 327 // Scan over all world volumes. 316 // ******************************************* 328 // ************************************************************************** 317 // 329 // 318 void G4RegionStore::SetWorldVolume() 330 void G4RegionStore::SetWorldVolume() 319 { 331 { 320 // Reset all pointers first 332 // Reset all pointers first 321 // 333 // 322 for (auto i=GetInstance()->cbegin(); i!=GetI 334 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i) 323 { (*i)->SetWorld(nullptr); } 335 { (*i)->SetWorld(nullptr); } 324 336 325 // Find world volumes 337 // Find world volumes 326 // 338 // 327 G4PhysicalVolumeStore* fPhysicalVolumeStore 339 G4PhysicalVolumeStore* fPhysicalVolumeStore 328 = G4PhysicalVolumeStore::GetInstance(); 340 = G4PhysicalVolumeStore::GetInstance(); 329 std::size_t nPhys = fPhysicalVolumeStore->si << 341 size_t nPhys = fPhysicalVolumeStore->size(); 330 for(std::size_t iPhys=0; iPhys<nPhys; ++iPhy << 342 for(size_t iPhys=0; iPhys<nPhys; ++iPhys) 331 { 343 { 332 G4VPhysicalVolume* fPhys = (*fPhysicalVolu 344 G4VPhysicalVolume* fPhys = (*fPhysicalVolumeStore)[iPhys]; 333 if(fPhys->GetMotherLogical() != nullptr) { 345 if(fPhys->GetMotherLogical() != nullptr) { continue; } // not a world volume 334 346 335 // Now 'fPhys' is a world volume, set it t 347 // Now 'fPhys' is a world volume, set it to regions that belong to it. 336 // 348 // 337 for (auto i=GetInstance()->cbegin(); i!=Ge 349 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i) 338 { (*i)->SetWorld(fPhys); } 350 { (*i)->SetWorld(fPhys); } 339 } 351 } 340 } 352 } 341 353 342 354