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
G4SolidStore.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// G4SolidStore implementation
27//
28// 10.07.95, P.Kent, G.Cosmo
29// --------------------------------------------------------------------
30
31#include "globals.hh"
32#include "G4SolidStore.hh"
33#include "G4GeometryManager.hh"
34
35#include "G4AutoLock.hh"
36
37namespace
38{
40}
41
42// ***************************************************************************
43// Static class variables
44// ***************************************************************************
45//
46G4SolidStore* G4SolidStore::fgInstance = nullptr;
47G4ThreadLocal G4VStoreNotifier* G4SolidStore::fgNotifier = nullptr;
48G4ThreadLocal G4bool G4SolidStore::locked = false;
49
50// ***************************************************************************
51// Protected constructor: Construct underlying container with
52// initial size of 100 entries
53// ***************************************************************************
54//
56 : std::vector<G4VSolid*>()
57{
58 reserve(100);
59}
60
61// ***************************************************************************
62// Destructor
63// ***************************************************************************
64//
66{
67 Clean();
68}
69
70// ***************************************************************************
71// Delete all elements from the store
72// ***************************************************************************
73//
75{
76 // Do nothing if geometry is closed
77 //
79 {
80 G4cout << "WARNING - Attempt to delete the solid store"
81 << " while geometry closed !" << G4endl;
82 return;
83 }
84
85 // Locks store for deletion of solids. De-registration will be
86 // performed at this stage. G4VSolids will not de-register themselves.
87 //
88 locked = true;
89
90 G4SolidStore* store = GetInstance();
91
92 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
93 {
94 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
95 delete *pos;
96 }
97
98 store->bmap.clear(); store->mvalid = false;
99 locked = false;
100 store->clear();
101}
102
103// ***************************************************************************
104// Associate user notifier to the store
105// ***************************************************************************
106//
108{
109 GetInstance();
110 fgNotifier = pNotifier;
111}
112
113// ***************************************************************************
114// Bring contents of internal map up to date and reset validity flag
115// ***************************************************************************
116//
118{
119 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
120 if (mvalid) return;
121 bmap.clear();
122 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
123 {
124 const G4String& sol_name = (*pos)->GetName();
125 auto it = bmap.find(sol_name);
126 if (it != bmap.cend())
127 {
128 it->second.push_back(*pos);
129 }
130 else
131 {
132 std::vector<G4VSolid*> sol_vec { *pos };
133 bmap.insert(std::make_pair(sol_name, sol_vec));
134 }
135 }
136 mvalid = true;
137 l.unlock();
138}
139
140// ***************************************************************************
141// Add Solid to container
142// ***************************************************************************
143//
145{
146 G4SolidStore* store = GetInstance();
147 store->push_back(pSolid);
148 const G4String& sol_name = pSolid->GetName();
149 auto it = store->bmap.find(sol_name);
150 if (it != store->bmap.cend())
151 {
152 it->second.push_back(pSolid);
153 }
154 else
155 {
156 std::vector<G4VSolid*> sol_vec { pSolid };
157 store->bmap.insert(std::make_pair(sol_name, sol_vec));
158 }
159 if (fgNotifier) { fgNotifier->NotifyRegistration(); }
160 store->mvalid = true;
161}
162
163// ***************************************************************************
164// Remove Solid from container
165// ***************************************************************************
166//
168{
169 G4SolidStore* store = GetInstance();
170 if (!locked) // Do not de-register if locked !
171 {
172 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
173 for (auto i=store->crbegin(); i!=store->crend(); ++i)
174 {
175 if (**i==*pSolid)
176 {
177 store->erase(std::next(i).base());
178 store->mvalid = false;
179 break;
180 }
181 }
182 const G4String& sol_name = pSolid->GetName();
183 auto it = store->bmap.find(sol_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==*pSolid)
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 solid pointer in the container having that name
207// ***************************************************************************
208//
210 G4bool reverseSearch) const
211{
212 G4SolidStore* store = GetInstance();
213 if (!store->mvalid) { store->UpdateMap(); }
214 auto pos = store->bmap.find(name);
215 if(pos != store->bmap.cend())
216 {
217 if ((verbose) && (pos->second.size()>1))
218 {
219 std::ostringstream message;
220 message << "There exists more than ONE solid in store named: "
221 << name << "!" << G4endl
222 << "Returning the first found.";
223 G4Exception("G4SolidStore::GetSolid()",
224 "GeomMgt1001", JustWarning, message);
225 }
226 if(reverseSearch)
227 {
228 return pos->second[pos->second.size()-1];
229 }
230 else
231 {
232 return pos->second[0];
233 }
234 }
235 if (verbose)
236 {
237 std::ostringstream message;
238 message << "Solid " << name << " not found in store !" << G4endl
239 << "Returning NULL pointer.";
240 G4Exception("G4SolidStore::GetSolid()",
241 "GeomMgt1001", JustWarning, message);
242 }
243 return nullptr;
244}
245
246// ***************************************************************************
247// Return ptr to Store, setting if necessary
248// ***************************************************************************
249//
251{
252 static G4SolidStore worldStore;
253 if (fgInstance == nullptr)
254 {
255 fgInstance = &worldStore;
256 }
257 return fgInstance;
258}
@ 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 Register(G4VSolid *pSolid)
static void Clean()
Definition: G4SolidStore.cc:74
static void SetNotifier(G4VStoreNotifier *pNotifier)
void UpdateMap()
static void DeRegister(G4VSolid *pSolid)
G4VSolid * GetSolid(const G4String &name, G4bool verbose=true, G4bool reverseSearch=false) const
static G4SolidStore * GetInstance()
virtual ~G4SolidStore()
Definition: G4SolidStore.cc:65
virtual void NotifyRegistration()=0
virtual void NotifyDeRegistration()=0
G4String GetName() const
#define G4ThreadLocal
Definition: tls.hh:77