Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4LogicalVolumeStore.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4LogicalVolumeStore implementation
27//
28// 10.07.95, P.Kent, G.Cosmo
29// --------------------------------------------------------------------
30
31#include "G4Types.hh"
33#include "G4GeometryManager.hh"
34
35#include "G4AutoLock.hh"
36
37namespace
38{
40}
41
42// ***************************************************************************
43// Static class variables
44// ***************************************************************************
45//
46G4LogicalVolumeStore* G4LogicalVolumeStore::fgInstance = nullptr;
47G4ThreadLocal G4VStoreNotifier* G4LogicalVolumeStore::fgNotifier = nullptr;
48G4ThreadLocal G4bool G4LogicalVolumeStore::locked = false;
49
50// ***************************************************************************
51// Protected constructor: Construct underlying container with
52// initial size of 100 entries
53// ***************************************************************************
54//
56 : std::vector<G4LogicalVolume*>()
57{
58 reserve(100);
59}
60
61// ***************************************************************************
62// Destructor
63// ***************************************************************************
64//
66{
67 Clean(); // Delete all volumes in the store
68 G4LogicalVolume::Clean(); // Delete allocated sub-instance data
69}
70
71// ***************************************************************************
72// Delete all elements from the store
73// ***************************************************************************
74//
76{
77 // Do nothing if geometry is closed
78 //
80 {
81 G4cout << "WARNING - Attempt to delete the logical volume store"
82 << " while geometry closed !" << G4endl;
83 return;
84 }
85
86 // Locks store for deletion of volumes. De-registration will be
87 // performed at this stage. G4LogicalVolumes will not de-register themselves.
88 //
89 locked = true;
90
92
93 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
94 {
95 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
96 if (*pos != nullptr) { (*pos)->Lock(); delete *pos; }
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//
109{
110 GetInstance();
111 fgNotifier = pNotifier;
112}
113
114// ***************************************************************************
115// Bring contents of internal map up to date and reset validity flag
116// ***************************************************************************
117//
119{
120 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
121 if (mvalid) return;
122 bmap.clear();
123 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
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 { *pos };
134 bmap.insert(std::make_pair(vol_name, vol_vec));
135 }
136 }
137 mvalid = true;
138 l.unlock();
139}
140
141// ***************************************************************************
142// Add volume to container
143// ***************************************************************************
144//
146{
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 { pVolume };
158 store->bmap.insert(std::make_pair(vol_name, vol_vec));
159 }
160 if (fgNotifier) { fgNotifier->NotifyRegistration(); }
161 store->mvalid = true;
162}
163
164// ***************************************************************************
165// Remove volume from container
166// ***************************************************************************
167//
169{
171 if (!locked) // Do not de-register if locked !
172 {
173 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
174 for (auto i=store->cbegin(); i!=store->cend(); ++i)
175 {
176 if (**i==*pVolume)
177 {
178 store->erase(i);
179 break;
180 }
181 }
182 const G4String& vol_name = pVolume->GetName();
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->second.cend(); ++i)
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 in the container having that name
207// ***************************************************************************
208//
211 G4bool reverseSearch) const
212{
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 logical volume in store named: "
222 << name << "!" << G4endl
223 << "Returning the first found.";
224 G4Exception("G4LogicalVolumeStore::GetVolume()",
225 "GeomMgt1001", JustWarning, message);
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 !" << G4endl
240 << " Volume " << name << " NOT found in store !" << G4endl
241 << " Returning NULL pointer.";
242 G4Exception("G4LogicalVolumeStore::GetVolume()",
243 "GeomMgt1001", JustWarning, message);
244 }
245 return nullptr;
246}
247
248// ***************************************************************************
249// Return ptr to Store, setting if necessary
250// ***************************************************************************
251//
253{
254 static G4LogicalVolumeStore worldStore;
255 if (fgInstance == nullptr)
256 {
257 fgInstance = &worldStore;
258 }
259 return fgInstance;
260}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4bool IsGeometryClosed()
static void DeRegister(G4LogicalVolume *pVolume)
G4LogicalVolume * GetVolume(const G4String &name, G4bool verbose=true, G4bool reverseSearch=false) const
static void Register(G4LogicalVolume *pVolume)
static G4LogicalVolumeStore * GetInstance()
static void SetNotifier(G4VStoreNotifier *pNotifier)
static void Clean()
const G4String & GetName() const
virtual void NotifyRegistration()=0
virtual void NotifyDeRegistration()=0
#define G4ThreadLocal
Definition: tls.hh:77