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