Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4LogicalVolumeStore implementation 27 // 28 // 10.07.95, P.Kent, G.Cosmo 29 // ------------------------------------------- 30 31 #include "G4Types.hh" 32 #include "G4LogicalVolumeStore.hh" 33 #include "G4GeometryManager.hh" 34 35 #include "G4AutoLock.hh" 36 37 namespace 38 { 39 G4Mutex mapMutex = G4MUTEX_INITIALIZER; 40 } 41 42 // ******************************************* 43 // Static class variables 44 // ******************************************* 45 // 46 G4LogicalVolumeStore* G4LogicalVolumeStore::fg 47 G4ThreadLocal G4VStoreNotifier* G4LogicalVolum 48 G4ThreadLocal G4bool G4LogicalVolumeStore::loc 49 50 // ******************************************* 51 // Protected constructor: Construct underlying 52 // initial size of 100 entries 53 // ******************************************* 54 // 55 G4LogicalVolumeStore::G4LogicalVolumeStore() 56 57 { 58 reserve(100); 59 } 60 61 // ******************************************* 62 // Destructor 63 // ******************************************* 64 // 65 G4LogicalVolumeStore::~G4LogicalVolumeStore() 66 { 67 Clean(); // Delete all volumes in the store 68 G4LogicalVolume::Clean(); // Delete allocat 69 } 70 71 // ******************************************* 72 // Delete all elements from the store 73 // ******************************************* 74 // 75 void G4LogicalVolumeStore::Clean() 76 { 77 // Do nothing if geometry is closed 78 // 79 if (G4GeometryManager::GetInstance()->IsGeom 80 { 81 G4cout << "WARNING - Attempt to delete the 82 << " while geometry closed !" << G4 83 return; 84 } 85 86 // Locks store for deletion of volumes. De-r 87 // performed at this stage. G4LogicalVolumes 88 // 89 locked = true; 90 91 G4LogicalVolumeStore* store = GetInstance(); 92 93 for(auto pos=store->cbegin(); pos!=store->ce 94 { 95 if (fgNotifier != nullptr) { fgNotifier->N 96 if (*pos != nullptr) { (*pos)->Lock(); del 97 } 98 99 store->bmap.clear(); store->mvalid = false; 100 locked = false; 101 store->clear(); 102 } 103 104 // ******************************************* 105 // Associate user notifier to the store 106 // ******************************************* 107 // 108 void G4LogicalVolumeStore::SetNotifier(G4VStor 109 { 110 GetInstance(); 111 fgNotifier = pNotifier; 112 } 113 114 // ******************************************* 115 // Bring contents of internal map up to date a 116 // ******************************************* 117 // 118 void G4LogicalVolumeStore::UpdateMap() 119 { 120 G4AutoLock l(&mapMutex); // to avoid thread 121 if (mvalid) return; 122 bmap.clear(); 123 for(auto pos=GetInstance()->cbegin(); pos!=G 124 { 125 const G4String& vol_name = (*pos)->GetName 126 auto it = bmap.find(vol_name); 127 if (it != bmap.cend()) 128 { 129 it->second.push_back(*pos); 130 } 131 else 132 { 133 std::vector<G4LogicalVolume*> vol_vec { 134 bmap.insert(std::make_pair(vol_name, vol 135 } 136 } 137 mvalid = true; 138 l.unlock(); 139 } 140 141 // ******************************************* 142 // Add volume to container 143 // ******************************************* 144 // 145 void G4LogicalVolumeStore::Register(G4LogicalV 146 { 147 G4LogicalVolumeStore* store = GetInstance(); 148 store->push_back(pVolume); 149 const G4String& vol_name = pVolume->GetName( 150 auto it = store->bmap.find(vol_name); 151 if (it != store->bmap.cend()) 152 { 153 it->second.push_back(pVolume); 154 } 155 else 156 { 157 std::vector<G4LogicalVolume*> vol_vec { pV 158 store->bmap.insert(std::make_pair(vol_name 159 } 160 if (fgNotifier != nullptr) { fgNotifier->Not 161 store->mvalid = true; 162 } 163 164 // ******************************************* 165 // Remove volume from container 166 // ******************************************* 167 // 168 void G4LogicalVolumeStore::DeRegister(G4Logica 169 { 170 G4LogicalVolumeStore* store = GetInstance(); 171 if (!locked) // Do not de-register if loc 172 { 173 if (fgNotifier != nullptr) { fgNotifier->N 174 for (auto i=store->cbegin(); i!=store->cen 175 { 176 if (**i==*pVolume) 177 { 178 store->erase(i); 179 break; 180 } 181 } 182 const G4String& vol_name = pVolume->GetNam 183 auto it = store->bmap.find(vol_name); 184 if (it != store->bmap.cend()) 185 { 186 if (it->second.size() > 1) 187 { 188 for (auto i=it->second.cbegin(); i!=it 189 { 190 if (**i==*pVolume) 191 { 192 it->second.erase(i); 193 break; 194 } 195 } 196 } 197 else 198 { 199 store->bmap.erase(it); 200 } 201 } 202 } 203 } 204 205 // ******************************************* 206 // Retrieve the first or last volume pointer i 207 // ******************************************* 208 // 209 G4LogicalVolume* 210 G4LogicalVolumeStore::GetVolume(const G4String 211 G4bool reverse 212 { 213 G4LogicalVolumeStore* store = GetInstance(); 214 if (!store->mvalid) { store->UpdateMap(); } 215 auto pos = store->bmap.find(name); 216 if(pos != store->bmap.cend()) 217 { 218 if ((verbose) && (pos->second.size()>1)) 219 { 220 std::ostringstream message; 221 message << "There exists more than ONE l 222 << name << "!" << G4endl 223 << "Returning the first found."; 224 G4Exception("G4LogicalVolumeStore::GetVo 225 "GeomMgt1001", JustWarning, 226 } 227 if(reverseSearch) 228 { 229 return pos->second[pos->second.size()-1] 230 } 231 else 232 { 233 return pos->second[0]; 234 } 235 } 236 if (verbose) 237 { 238 std::ostringstream message; 239 message << "Volume NOT found in store !" 240 << " Volume " << name << " 241 << " Returning NULL pointe 242 G4Exception("G4LogicalVolumeStore::GetVol 243 "GeomMgt1001", JustWarning, m 244 } 245 return nullptr; 246 } 247 248 // ******************************************* 249 // Return ptr to Store, setting if necessary 250 // ******************************************* 251 // 252 G4LogicalVolumeStore* G4LogicalVolumeStore::Ge 253 { 254 static G4LogicalVolumeStore worldStore; 255 if (fgInstance == nullptr) 256 { 257 fgInstance = &worldStore; 258 } 259 return fgInstance; 260 } 261