EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4SolidStore.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4SolidStore.cc
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 
37 namespace
38 {
39  G4Mutex mapMutex = G4MUTEX_INITIALIZER;
40 }
41 
42 // ***************************************************************************
43 // Static class variables
44 // ***************************************************************************
45 //
47 G4ThreadLocal G4VStoreNotifier* G4SolidStore::fgNotifier = nullptr;
48 G4ThreadLocal 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  //
78  if (G4GeometryManager::IsGeometryClosed())
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  std::size_t i = 0;
91  G4SolidStore* store = GetInstance();
92 
93 #ifdef G4GEOMETRY_VOXELDEBUG
94  G4cout << "Deleting Solids ... ";
95 #endif
96 
97  for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
98  {
99  if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
100  delete *pos; ++i;
101  }
102 
103 #ifdef G4GEOMETRY_VOXELDEBUG
104  if (store->size() < i-1)
105  { G4cout << "No solids deleted. Already deleted by user ?" << G4endl; }
106  else
107  { G4cout << i-1 << " solids deleted !" << G4endl; }
108 #endif
109 
110  store->bmap.clear(); store->mvalid = false;
111  locked = false;
112  store->clear();
113 }
114 
115 // ***************************************************************************
116 // Associate user notifier to the store
117 // ***************************************************************************
118 //
119 void G4SolidStore::SetNotifier(G4VStoreNotifier* pNotifier)
120 {
121  GetInstance();
122  fgNotifier = pNotifier;
123 }
124 
125 // ***************************************************************************
126 // Bring contents of internal map up to date and reset validity flag
127 // ***************************************************************************
128 //
130 {
131  G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
132  if (mvalid) return;
133  bmap.clear();
134  for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
135  {
136  const G4String& sol_name = (*pos)->GetName();
137  auto it = bmap.find(sol_name);
138  if (it != bmap.cend())
139  {
140  it->second.push_back(*pos);
141  }
142  else
143  {
144  std::vector<G4VSolid*> sol_vec { *pos };
145  bmap.insert(std::make_pair(sol_name, sol_vec));
146  }
147  }
148  mvalid = true;
149  l.unlock();
150 }
151 
152 // ***************************************************************************
153 // Add Solid to container
154 // ***************************************************************************
155 //
156 void G4SolidStore::Register(G4VSolid* pSolid)
157 {
158  G4SolidStore* store = GetInstance();
159  store->push_back(pSolid);
160  const G4String& sol_name = pSolid->GetName();
161  auto it = store->bmap.find(sol_name);
162  if (it != store->bmap.cend())
163  {
164  it->second.push_back(pSolid);
165  }
166  else
167  {
168  std::vector<G4VSolid*> sol_vec { pSolid };
169  store->bmap.insert(std::make_pair(sol_name, sol_vec));
170  }
171  if (fgNotifier) { fgNotifier->NotifyRegistration(); }
172  store->mvalid = true;
173 }
174 
175 // ***************************************************************************
176 // Remove Solid from container
177 // ***************************************************************************
178 //
179 void G4SolidStore::DeRegister(G4VSolid* pSolid)
180 {
181  G4SolidStore* store = GetInstance();
182  if (!locked) // Do not de-register if locked !
183  {
184  if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
185  for (auto i=store->crbegin(); i!=store->crend(); ++i)
186  {
187  if (**i==*pSolid)
188  {
189  store->erase(std::next(i).base());
190  store->mvalid = false;
191  break;
192  }
193  }
194  const G4String& sol_name = pSolid->GetName();
195  auto it = store->bmap.find(sol_name);
196  if (it != store->bmap.cend())
197  {
198  if (it->second.size() > 1)
199  {
200  for (auto i=it->second.cbegin(); i!=it->second.cend(); ++i)
201  {
202  if (**i==*pSolid)
203  {
204  it->second.erase(i);
205  break;
206  }
207  }
208  }
209  else
210  {
211  store->bmap.erase(it);
212  }
213  }
214  }
215 }
216 
217 // ***************************************************************************
218 // Retrieve the first or last solid pointer in the container having that name
219 // ***************************************************************************
220 //
221 G4VSolid* G4SolidStore::GetSolid(const G4String& name, G4bool verbose,
222  G4bool reverseSearch) const
223 {
224  G4SolidStore* store = GetInstance();
225  if (!store->mvalid) { store->UpdateMap(); }
226  auto pos = store->bmap.find(name);
227  if(pos != store->bmap.cend())
228  {
229  if ((verbose) && (pos->second.size()>1))
230  {
231  std::ostringstream message;
232  message << "There exists more than ONE solid in store named: "
233  << name << "!" << G4endl
234  << "Returning the first found.";
235  G4Exception("G4SolidStore::GetSolid()",
236  "GeomMgt1001", JustWarning, message);
237  }
238  if(reverseSearch)
239  {
240  return pos->second[pos->second.size()-1];
241  }
242  else
243  {
244  return pos->second[0];
245  }
246  }
247  if (verbose)
248  {
249  std::ostringstream message;
250  message << "Solid " << name << " not found in store !" << G4endl
251  << "Returning NULL pointer.";
252  G4Exception("G4SolidStore::GetSolid()",
253  "GeomMgt1001", JustWarning, message);
254  }
255  return nullptr;
256 }
257 
258 // ***************************************************************************
259 // Return ptr to Store, setting if necessary
260 // ***************************************************************************
261 //
263 {
264  static G4SolidStore worldStore;
265  if (fgInstance == nullptr)
266  {
267  fgInstance = &worldStore;
268  }
269  return fgInstance;
270 }