Geant4-11
G4RegionStore.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// G4RegionStore implementation
27//
28// 18.09.02, G.Cosmo - Initial version
29// --------------------------------------------------------------------
30
31#include "G4Region.hh"
32#include "G4RegionStore.hh"
33#include "G4GeometryManager.hh"
34#include "G4VPhysicalVolume.hh"
36
37#include "G4ios.hh"
38#include "G4AutoLock.hh"
39
40namespace
41{
43}
44
45// ***************************************************************************
46// Static class variables
47// ***************************************************************************
48//
52
53// ***************************************************************************
54// Protected constructor: Construct underlying container with
55// initial size of 20 entries
56// ***************************************************************************
57//
59 : std::vector<G4Region*>()
60{
61 reserve(20);
62}
63
64// ***************************************************************************
65// Destructor
66// ***************************************************************************
67//
69{
70 Clean(); // Delete all regions in the store
71 G4Region::Clean(); // Delete allocated sub-instance data
72}
73
74// ***************************************************************************
75// Delete all regions from the store except for the world region
76// ***************************************************************************
77//
79{
80 // Do nothing if geometry is closed
81 //
83 {
84 G4cout << "WARNING - Attempt to delete the region store"
85 << " while geometry closed !" << G4endl;
86 return;
87 }
88
89 // Locks store for deletion of regions. De-registration will be
90 // performed at this stage. G4Regions will not de-register themselves.
91 //
92 locked = true;
93
94 std::size_t i=0;
95 G4RegionStore* store = GetInstance();
96
97#ifdef G4GEOMETRY_VOXELDEBUG
98 G4cout << "Deleting Regions ... ";
99#endif
100
101 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
102 {
103 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
104 delete *pos; ++i;
105 }
106
107#ifdef G4GEOMETRY_VOXELDEBUG
108 if (store->size() < i-1)
109 { G4cout << "No regions deleted. Already deleted by user ?" << G4endl; }
110 else
111 { G4cout << i-1 << " regions deleted !" << G4endl; }
112#endif
113
114 store->bmap.clear(); store->mvalid = false;
115 locked = false;
116 store->clear();
117}
118
119// ***************************************************************************
120// Associate user notifier to the store
121// ***************************************************************************
122//
124{
125 GetInstance();
126 fgNotifier = pNotifier;
127}
128
129// ***************************************************************************
130// Bring contents of internal map up to date and reset validity flag
131// ***************************************************************************
132//
134{
135 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
136 if (mvalid) return;
137 bmap.clear();
138 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
139 {
140 const G4String& reg_name = (*pos)->GetName();
141 auto it = bmap.find(reg_name);
142 if (it != bmap.cend())
143 {
144 it->second.push_back(*pos);
145 }
146 else
147 {
148 std::vector<G4Region*> reg_vec { *pos };
149 bmap.insert(std::make_pair(reg_name, reg_vec));
150 }
151 }
152 mvalid = true;
153 l.unlock();
154}
155
156// ***************************************************************************
157// Add Region to container
158// ***************************************************************************
159//
161{
162 G4RegionStore* store = GetInstance();
163 store->push_back(pRegion);
164 const G4String& reg_name = pRegion->GetName();
165 auto it = store->bmap.find(reg_name);
166 if (it != store->bmap.cend())
167 {
168 it->second.push_back(pRegion);
169 }
170 else
171 {
172 std::vector<G4Region*> reg_vec { pRegion };
173 store->bmap.insert(std::make_pair(reg_name, reg_vec));
174 }
176 store->mvalid = true;
177}
178
179// ***************************************************************************
180// Remove Region from container
181// ***************************************************************************
182//
184{
185 G4RegionStore* store = GetInstance();
186 if (!locked) // Do not de-register if locked !
187 {
188 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
189 for (auto i=store->cbegin(); i!=store->cend(); ++i)
190 {
191 if (**i==*pRegion)
192 {
193 store->erase(i);
194 break;
195 }
196 }
197 const G4String& reg_name = pRegion->GetName();
198 auto it = store->bmap.find(reg_name);
199 if (it != store->bmap.cend())
200 {
201 if (it->second.size() > 1)
202 {
203 for (auto i=it->second.cbegin(); i!=it->second.cend(); ++i)
204 {
205 if (**i==*pRegion)
206 {
207 it->second.erase(i);
208 break;
209 }
210 }
211 }
212 else
213 {
214 store->bmap.erase(it);
215 }
216 }
217 }
218}
219
220// ***************************************************************************
221// Return ptr to Store, setting if necessary
222// ***************************************************************************
223//
225{
226 static G4RegionStore worldStore;
227 if (fgInstance == nullptr)
228 {
229 fgInstance = &worldStore;
230 }
231 return fgInstance;
232}
233
234// ***************************************************************************
235// Loops through all regions to verify if a region has been modified.
236// It returns TRUE if just one region is modified.
237// ***************************************************************************
238//
240{
241 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
242 {
243 if ((*i)->IsModified()) { return true; }
244 }
245 return false;
246}
247
248// ***************************************************************************
249// Loops through all regions to reset flag for modification to FALSE.
250// Used by the run manager to notify that the physics table has been updated.
251// ***************************************************************************
252//
254{
255 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
256 {
257 (*i)->RegionModified(false);
258 }
259}
260
261// ***************************************************************************
262// Forces recomputation of material lists in all regions in the store.
263// ***************************************************************************
264//
266{
267 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
268 {
269 if((*i)->IsInMassGeometry() || (*i)->IsInParallelGeometry()
270 || (currentWorld != nullptr))
271 { (*i)->UpdateMaterialList(); }
272 }
273}
274
275// ***************************************************************************
276// Returns a region through its name specification.
277// ***************************************************************************
278//
280{
281 G4RegionStore* store = GetInstance();
282 if (!store->mvalid) { store->UpdateMap(); }
283 auto pos = store->bmap.find(name);
284 if(pos != store->bmap.cend())
285 {
286 if ((verbose) && (pos->second.size()>1))
287 {
288 std::ostringstream message;
289 message << "There exists more than ONE region in store named: "
290 << name << "!" << G4endl
291 << "Returning the first found.";
292 G4Exception("G4RegionStore::GetSolid()",
293 "GeomMgt1001", JustWarning, message);
294 }
295 return pos->second[0];
296 }
297 if (verbose)
298 {
299 std::ostringstream message;
300 message << "Region NOT found in store !" << G4endl
301 << " Region " << name << " NOT found in store !" << G4endl
302 << " Returning NULL pointer.";
303 G4Exception("G4RegionStore::GetRegion()",
304 "GeomMgt1001", JustWarning, message);
305 }
306 return nullptr;
307}
308
309// ***************************************************************************
310// Returns a region through its name specification, if it exists.
311// If it does not exist it will allocate a new region with the given
312// name, delegating the ownership to the caller client.
313// ***************************************************************************
314//
316{
317 G4Region* target = GetRegion(name,false);
318 if (target == nullptr)
319 {
320 target = new G4Region(name);
321 }
322 return target;
323}
324
325// **************************************************************************
326// Set a world physical volume pointer to a region that belongs to it.
327// Scan over all world volumes.
328// **************************************************************************
329//
331{
332 // Reset all pointers first
333 //
334 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
335 { (*i)->SetWorld(nullptr); }
336
337 // Find world volumes
338 //
339 G4PhysicalVolumeStore* fPhysicalVolumeStore
341 size_t nPhys = fPhysicalVolumeStore->size();
342 for(size_t iPhys=0; iPhys<nPhys; ++iPhys)
343 {
344 G4VPhysicalVolume* fPhys = (*fPhysicalVolumeStore)[iPhys];
345 if(fPhys->GetMotherLogical() != nullptr) { continue; } // not a world volume
346
347 // Now 'fPhys' is a world volume, set it to regions that belong to it.
348 //
349 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
350 { (*i)->SetWorld(fPhys); }
351 }
352}
353
static const G4double pos
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
#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 G4PhysicalVolumeStore * GetInstance()
static void DeRegister(G4Region *pRegion)
static void Register(G4Region *pRegion)
static G4RegionStore * GetInstance()
static G4ThreadLocal G4bool locked
static void SetNotifier(G4VStoreNotifier *pNotifier)
void UpdateMaterialList(G4VPhysicalVolume *currentWorld=nullptr)
static G4RegionStore * fgInstance
static G4ThreadLocal G4VStoreNotifier * fgNotifier
virtual ~G4RegionStore()
static void Clean()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
std::map< G4String, std::vector< G4Region * > > bmap
G4Region * FindOrCreateRegion(const G4String &name)
void ResetRegionModified()
G4bool IsModified() const
void SetWorldVolume()
const G4String & GetName() const
static void Clean()
Definition: G4Region.cc:356
virtual void NotifyRegistration()=0
virtual void NotifyDeRegistration()=0
G4LogicalVolume * GetMotherLogical() const
const char * name(G4int ptype)
#define G4ThreadLocal
Definition: tls.hh:77