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
G4PhysicalVolumeStore.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// G4PhysicalVolumeStore implementation
27//
28// 25.07.95, P.Kent, G.Cosmo
29// --------------------------------------------------------------------
30
31#include "G4Types.hh"
33#include "G4GeometryManager.hh"
34#include "G4LogicalVolume.hh"
35
36#include "G4AutoLock.hh"
37
38namespace
39{
41}
42
43// ***************************************************************************
44// Static class variables
45// ***************************************************************************
46//
47G4PhysicalVolumeStore* G4PhysicalVolumeStore::fgInstance = nullptr;
48G4ThreadLocal G4VStoreNotifier* G4PhysicalVolumeStore::fgNotifier = nullptr;
49G4ThreadLocal G4bool G4PhysicalVolumeStore::locked = false;
50
51// ***************************************************************************
52// Protected constructor: Construct underlying container with
53// initial size of 100 entries
54// ***************************************************************************
55//
57 : std::vector<G4VPhysicalVolume*>()
58{
59 reserve(100);
60}
61
62// ***************************************************************************
63// Destructor
64// ***************************************************************************
65//
67{
68 Clean(); // Delete all volumes in the store
69 G4VPhysicalVolume::Clean(); // Delete allocated sub-instance data
70}
71
72// ***************************************************************************
73// Delete all elements from the store
74// ***************************************************************************
75//
77{
78 // Do nothing if geometry is closed
79 //
81 {
82 G4cout << "WARNING - Attempt to delete the physical volume store"
83 << " while geometry closed !" << G4endl;
84 return;
85 }
86
87 // Locks store for deletion of volumes. De-registration will be
88 // performed at this stage. G4VPhysicalVolumes will not de-register
89 // themselves.
90 //
91 locked = true;
92
94
95 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
96 {
97 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
98 delete *pos;
99 }
100
101 store->bmap.clear(); store->mvalid = false;
102 locked = false;
103 store->clear();
104}
105
106// ***************************************************************************
107// Associate user notifier to the store
108// ***************************************************************************
109//
111{
112 GetInstance();
113 fgNotifier = pNotifier;
114}
115
116// ***************************************************************************
117// Bring contents of internal map up to date and reset validity flag
118// ***************************************************************************
119//
121{
122 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
123 if (mvalid) return;
124 bmap.clear();
125 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
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 { *pos };
136 bmap.insert(std::make_pair(vol_name, vol_vec));
137 }
138 }
139 mvalid = true;
140 l.unlock();
141}
142
143// ***************************************************************************
144// Add Volume to container
145// ***************************************************************************
146//
148{
150 store->push_back(pVolume);
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 { pVolume };
160 store->bmap.insert(std::make_pair(vol_name, vol_vec));
161 }
162 if (fgNotifier) { fgNotifier->NotifyRegistration(); }
163 store->mvalid = true;
164}
165
166// ***************************************************************************
167// Remove Volume from container and update the list of daughters
168// of the mother's logical volume
169// ***************************************************************************
170//
172{
174 if (!locked) // Do not de-register if locked !
175 {
176 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
177 G4LogicalVolume* motherLogical = pVolume->GetMotherLogical();
178 if (motherLogical != nullptr) { motherLogical->RemoveDaughter(pVolume); }
179 for (auto i=store->cbegin(); i!=store->cend(); ++i)
180 {
181 if (**i==*pVolume)
182 {
183 store->erase(i);
184 break;
185 }
186 }
187 const G4String& vol_name = pVolume->GetName();
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->second.cend(); ++i)
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 in the container having that name
212// ***************************************************************************
213//
216 G4bool reverseSearch) const
217{
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 physical volume in store named: "
227 << name << "!" << G4endl
228 << "Returning the first found.";
229 G4Exception("G4PhysicalVolumeStore::GetVolume()",
230 "GeomMgt1001", JustWarning, message);
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 !" << G4endl
245 << " Volume " << name << " NOT found in store !" << G4endl
246 << " Returning NULL pointer.";
247 G4Exception("G4PhysicalVolumeStore::GetVolume()",
248 "GeomMgt1001", JustWarning, message);
249 }
250 return nullptr;
251}
252
253// ***************************************************************************
254// Return ptr to Store, setting if necessary
255// ***************************************************************************
256//
258{
259 static G4PhysicalVolumeStore worldStore;
260 if (fgInstance == nullptr)
261 {
262 fgInstance = &worldStore;
263 }
264 return fgInstance;
265}
@ 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()
void RemoveDaughter(const G4VPhysicalVolume *p)
static G4PhysicalVolumeStore * GetInstance()
static void Register(G4VPhysicalVolume *pSolid)
static void SetNotifier(G4VStoreNotifier *pNotifier)
static void DeRegister(G4VPhysicalVolume *pSolid)
G4VPhysicalVolume * GetVolume(const G4String &name, G4bool verbose=true, G4bool reverseSearch=false) const
virtual void NotifyRegistration()=0
virtual void NotifyDeRegistration()=0
G4LogicalVolume * GetMotherLogical() const
const G4String & GetName() const
#define G4ThreadLocal
Definition: tls.hh:77