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