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 // G4LogicalVolumeStore implementation 26 // G4LogicalVolumeStore implementation 27 // 27 // 28 // 10.07.95, P.Kent, G.Cosmo 28 // 10.07.95, P.Kent, G.Cosmo 29 // ------------------------------------------- 29 // -------------------------------------------------------------------- 30 30 31 #include "G4Types.hh" 31 #include "G4Types.hh" 32 #include "G4LogicalVolumeStore.hh" 32 #include "G4LogicalVolumeStore.hh" 33 #include "G4GeometryManager.hh" 33 #include "G4GeometryManager.hh" 34 34 35 #include "G4AutoLock.hh" 35 #include "G4AutoLock.hh" 36 36 37 namespace 37 namespace 38 { 38 { 39 G4Mutex mapMutex = G4MUTEX_INITIALIZER; 39 G4Mutex mapMutex = G4MUTEX_INITIALIZER; 40 } 40 } 41 41 42 // ******************************************* 42 // *************************************************************************** 43 // Static class variables 43 // Static class variables 44 // ******************************************* 44 // *************************************************************************** 45 // 45 // 46 G4LogicalVolumeStore* G4LogicalVolumeStore::fg 46 G4LogicalVolumeStore* G4LogicalVolumeStore::fgInstance = nullptr; 47 G4ThreadLocal G4VStoreNotifier* G4LogicalVolum 47 G4ThreadLocal G4VStoreNotifier* G4LogicalVolumeStore::fgNotifier = nullptr; 48 G4ThreadLocal G4bool G4LogicalVolumeStore::loc 48 G4ThreadLocal G4bool G4LogicalVolumeStore::locked = false; 49 49 50 // ******************************************* 50 // *************************************************************************** 51 // Protected constructor: Construct underlying 51 // Protected constructor: Construct underlying container with 52 // initial size of 100 entries 52 // initial size of 100 entries 53 // ******************************************* 53 // *************************************************************************** 54 // 54 // 55 G4LogicalVolumeStore::G4LogicalVolumeStore() 55 G4LogicalVolumeStore::G4LogicalVolumeStore() 56 << 56 : std::vector<G4LogicalVolume*>() 57 { 57 { 58 reserve(100); 58 reserve(100); 59 } 59 } 60 60 61 // ******************************************* 61 // *************************************************************************** 62 // Destructor 62 // Destructor 63 // ******************************************* 63 // *************************************************************************** 64 // 64 // 65 G4LogicalVolumeStore::~G4LogicalVolumeStore() 65 G4LogicalVolumeStore::~G4LogicalVolumeStore() 66 { 66 { 67 Clean(); // Delete all volumes in the store 67 Clean(); // Delete all volumes in the store 68 G4LogicalVolume::Clean(); // Delete allocat 68 G4LogicalVolume::Clean(); // Delete allocated sub-instance data 69 } 69 } 70 70 71 // ******************************************* 71 // *************************************************************************** 72 // Delete all elements from the store 72 // Delete all elements from the store 73 // ******************************************* 73 // *************************************************************************** 74 // 74 // 75 void G4LogicalVolumeStore::Clean() 75 void G4LogicalVolumeStore::Clean() 76 { 76 { 77 // Do nothing if geometry is closed 77 // Do nothing if geometry is closed 78 // 78 // 79 if (G4GeometryManager::GetInstance()->IsGeom << 79 if (G4GeometryManager::IsGeometryClosed()) 80 { 80 { 81 G4cout << "WARNING - Attempt to delete the 81 G4cout << "WARNING - Attempt to delete the logical volume store" 82 << " while geometry closed !" << G4 82 << " while geometry closed !" << G4endl; 83 return; 83 return; 84 } 84 } 85 85 86 // Locks store for deletion of volumes. De-r 86 // Locks store for deletion of volumes. De-registration will be 87 // performed at this stage. G4LogicalVolumes 87 // performed at this stage. G4LogicalVolumes will not de-register themselves. 88 // 88 // 89 locked = true; 89 locked = true; 90 90 91 G4LogicalVolumeStore* store = GetInstance(); 91 G4LogicalVolumeStore* store = GetInstance(); 92 92 93 for(auto pos=store->cbegin(); pos!=store->ce 93 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos) 94 { 94 { 95 if (fgNotifier != nullptr) { fgNotifier->N 95 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); } 96 if (*pos != nullptr) { (*pos)->Lock(); del 96 if (*pos != nullptr) { (*pos)->Lock(); delete *pos; } 97 } 97 } 98 98 99 store->bmap.clear(); store->mvalid = false; 99 store->bmap.clear(); store->mvalid = false; 100 locked = false; 100 locked = false; 101 store->clear(); 101 store->clear(); 102 } 102 } 103 103 104 // ******************************************* 104 // *************************************************************************** 105 // Associate user notifier to the store 105 // Associate user notifier to the store 106 // ******************************************* 106 // *************************************************************************** 107 // 107 // 108 void G4LogicalVolumeStore::SetNotifier(G4VStor 108 void G4LogicalVolumeStore::SetNotifier(G4VStoreNotifier* pNotifier) 109 { 109 { 110 GetInstance(); 110 GetInstance(); 111 fgNotifier = pNotifier; 111 fgNotifier = pNotifier; 112 } 112 } 113 113 114 // ******************************************* 114 // *************************************************************************** 115 // Bring contents of internal map up to date a 115 // Bring contents of internal map up to date and reset validity flag 116 // ******************************************* 116 // *************************************************************************** 117 // 117 // 118 void G4LogicalVolumeStore::UpdateMap() 118 void G4LogicalVolumeStore::UpdateMap() 119 { 119 { 120 G4AutoLock l(&mapMutex); // to avoid thread 120 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation 121 if (mvalid) return; 121 if (mvalid) return; 122 bmap.clear(); 122 bmap.clear(); 123 for(auto pos=GetInstance()->cbegin(); pos!=G 123 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos) 124 { 124 { 125 const G4String& vol_name = (*pos)->GetName 125 const G4String& vol_name = (*pos)->GetName(); 126 auto it = bmap.find(vol_name); 126 auto it = bmap.find(vol_name); 127 if (it != bmap.cend()) 127 if (it != bmap.cend()) 128 { 128 { 129 it->second.push_back(*pos); 129 it->second.push_back(*pos); 130 } 130 } 131 else 131 else 132 { 132 { 133 std::vector<G4LogicalVolume*> vol_vec { 133 std::vector<G4LogicalVolume*> vol_vec { *pos }; 134 bmap.insert(std::make_pair(vol_name, vol 134 bmap.insert(std::make_pair(vol_name, vol_vec)); 135 } 135 } 136 } 136 } 137 mvalid = true; 137 mvalid = true; 138 l.unlock(); 138 l.unlock(); 139 } 139 } 140 140 141 // ******************************************* 141 // *************************************************************************** 142 // Add volume to container 142 // Add volume to container 143 // ******************************************* 143 // *************************************************************************** 144 // 144 // 145 void G4LogicalVolumeStore::Register(G4LogicalV 145 void G4LogicalVolumeStore::Register(G4LogicalVolume* pVolume) 146 { 146 { 147 G4LogicalVolumeStore* store = GetInstance(); 147 G4LogicalVolumeStore* store = GetInstance(); 148 store->push_back(pVolume); 148 store->push_back(pVolume); 149 const G4String& vol_name = pVolume->GetName( 149 const G4String& vol_name = pVolume->GetName(); 150 auto it = store->bmap.find(vol_name); 150 auto it = store->bmap.find(vol_name); 151 if (it != store->bmap.cend()) 151 if (it != store->bmap.cend()) 152 { 152 { 153 it->second.push_back(pVolume); 153 it->second.push_back(pVolume); 154 } 154 } 155 else 155 else 156 { 156 { 157 std::vector<G4LogicalVolume*> vol_vec { pV 157 std::vector<G4LogicalVolume*> vol_vec { pVolume }; 158 store->bmap.insert(std::make_pair(vol_name 158 store->bmap.insert(std::make_pair(vol_name, vol_vec)); 159 } 159 } 160 if (fgNotifier != nullptr) { fgNotifier->Not << 160 if (fgNotifier) { fgNotifier->NotifyRegistration(); } 161 store->mvalid = true; 161 store->mvalid = true; 162 } 162 } 163 163 164 // ******************************************* 164 // *************************************************************************** 165 // Remove volume from container 165 // Remove volume from container 166 // ******************************************* 166 // *************************************************************************** 167 // 167 // 168 void G4LogicalVolumeStore::DeRegister(G4Logica 168 void G4LogicalVolumeStore::DeRegister(G4LogicalVolume* pVolume) 169 { 169 { 170 G4LogicalVolumeStore* store = GetInstance(); 170 G4LogicalVolumeStore* store = GetInstance(); 171 if (!locked) // Do not de-register if loc 171 if (!locked) // Do not de-register if locked ! 172 { 172 { 173 if (fgNotifier != nullptr) { fgNotifier->N 173 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); } 174 for (auto i=store->cbegin(); i!=store->cen 174 for (auto i=store->cbegin(); i!=store->cend(); ++i) 175 { 175 { 176 if (**i==*pVolume) 176 if (**i==*pVolume) 177 { 177 { 178 store->erase(i); 178 store->erase(i); 179 break; 179 break; 180 } 180 } 181 } 181 } 182 const G4String& vol_name = pVolume->GetNam 182 const G4String& vol_name = pVolume->GetName(); 183 auto it = store->bmap.find(vol_name); 183 auto it = store->bmap.find(vol_name); 184 if (it != store->bmap.cend()) 184 if (it != store->bmap.cend()) 185 { 185 { 186 if (it->second.size() > 1) 186 if (it->second.size() > 1) 187 { 187 { 188 for (auto i=it->second.cbegin(); i!=it 188 for (auto i=it->second.cbegin(); i!=it->second.cend(); ++i) 189 { 189 { 190 if (**i==*pVolume) 190 if (**i==*pVolume) 191 { 191 { 192 it->second.erase(i); 192 it->second.erase(i); 193 break; 193 break; 194 } 194 } 195 } 195 } 196 } 196 } 197 else 197 else 198 { 198 { 199 store->bmap.erase(it); 199 store->bmap.erase(it); 200 } 200 } 201 } 201 } 202 } 202 } 203 } 203 } 204 204 205 // ******************************************* 205 // *************************************************************************** 206 // Retrieve the first or last volume pointer i 206 // Retrieve the first or last volume pointer in the container having that name 207 // ******************************************* 207 // *************************************************************************** 208 // 208 // 209 G4LogicalVolume* 209 G4LogicalVolume* 210 G4LogicalVolumeStore::GetVolume(const G4String 210 G4LogicalVolumeStore::GetVolume(const G4String& name, G4bool verbose, 211 G4bool reverse 211 G4bool reverseSearch) const 212 { 212 { 213 G4LogicalVolumeStore* store = GetInstance(); 213 G4LogicalVolumeStore* store = GetInstance(); 214 if (!store->mvalid) { store->UpdateMap(); } 214 if (!store->mvalid) { store->UpdateMap(); } 215 auto pos = store->bmap.find(name); 215 auto pos = store->bmap.find(name); 216 if(pos != store->bmap.cend()) 216 if(pos != store->bmap.cend()) 217 { 217 { 218 if ((verbose) && (pos->second.size()>1)) 218 if ((verbose) && (pos->second.size()>1)) 219 { 219 { 220 std::ostringstream message; 220 std::ostringstream message; 221 message << "There exists more than ONE l 221 message << "There exists more than ONE logical volume in store named: " 222 << name << "!" << G4endl 222 << name << "!" << G4endl 223 << "Returning the first found."; 223 << "Returning the first found."; 224 G4Exception("G4LogicalVolumeStore::GetVo 224 G4Exception("G4LogicalVolumeStore::GetVolume()", 225 "GeomMgt1001", JustWarning, 225 "GeomMgt1001", JustWarning, message); 226 } 226 } 227 if(reverseSearch) 227 if(reverseSearch) 228 { 228 { 229 return pos->second[pos->second.size()-1] 229 return pos->second[pos->second.size()-1]; 230 } 230 } 231 else 231 else 232 { 232 { 233 return pos->second[0]; 233 return pos->second[0]; 234 } 234 } 235 } 235 } 236 if (verbose) 236 if (verbose) 237 { 237 { 238 std::ostringstream message; 238 std::ostringstream message; 239 message << "Volume NOT found in store !" 239 message << "Volume NOT found in store !" << G4endl 240 << " Volume " << name << " 240 << " Volume " << name << " NOT found in store !" << G4endl 241 << " Returning NULL pointe 241 << " Returning NULL pointer."; 242 G4Exception("G4LogicalVolumeStore::GetVol 242 G4Exception("G4LogicalVolumeStore::GetVolume()", 243 "GeomMgt1001", JustWarning, m 243 "GeomMgt1001", JustWarning, message); 244 } 244 } 245 return nullptr; 245 return nullptr; 246 } 246 } 247 247 248 // ******************************************* 248 // *************************************************************************** 249 // Return ptr to Store, setting if necessary 249 // Return ptr to Store, setting if necessary 250 // ******************************************* 250 // *************************************************************************** 251 // 251 // 252 G4LogicalVolumeStore* G4LogicalVolumeStore::Ge 252 G4LogicalVolumeStore* G4LogicalVolumeStore::GetInstance() 253 { 253 { 254 static G4LogicalVolumeStore worldStore; 254 static G4LogicalVolumeStore worldStore; 255 if (fgInstance == nullptr) 255 if (fgInstance == nullptr) 256 { 256 { 257 fgInstance = &worldStore; 257 fgInstance = &worldStore; 258 } 258 } 259 return fgInstance; 259 return fgInstance; 260 } 260 } 261 261