Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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//
49G4RegionStore* G4RegionStore::fgInstance = nullptr;
50G4ThreadLocal G4VStoreNotifier* G4RegionStore::fgNotifier = nullptr;
51G4ThreadLocal G4bool G4RegionStore::locked = false;
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 G4RegionStore* store = GetInstance();
95
96 for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
97 {
98 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
99 delete *pos;
100 }
101
102 store->bmap.clear(); store->mvalid = false;
103 locked = false;
104 store->clear();
105}
106
107// ***************************************************************************
108// Associate user notifier to the store
109// ***************************************************************************
110//
112{
113 GetInstance();
114 fgNotifier = pNotifier;
115}
116
117// ***************************************************************************
118// Bring contents of internal map up to date and reset validity flag
119// ***************************************************************************
120//
122{
123 G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
124 if (mvalid) return;
125 bmap.clear();
126 for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
127 {
128 const G4String& reg_name = (*pos)->GetName();
129 auto it = bmap.find(reg_name);
130 if (it != bmap.cend())
131 {
132 it->second.push_back(*pos);
133 }
134 else
135 {
136 std::vector<G4Region*> reg_vec { *pos };
137 bmap.insert(std::make_pair(reg_name, reg_vec));
138 }
139 }
140 mvalid = true;
141 l.unlock();
142}
143
144// ***************************************************************************
145// Add Region to container
146// ***************************************************************************
147//
149{
150 G4RegionStore* store = GetInstance();
151 store->push_back(pRegion);
152 const G4String& reg_name = pRegion->GetName();
153 auto it = store->bmap.find(reg_name);
154 if (it != store->bmap.cend())
155 {
156 it->second.push_back(pRegion);
157 }
158 else
159 {
160 std::vector<G4Region*> reg_vec { pRegion };
161 store->bmap.insert(std::make_pair(reg_name, reg_vec));
162 }
163 if (fgNotifier) { fgNotifier->NotifyRegistration(); }
164 store->mvalid = true;
165}
166
167// ***************************************************************************
168// Remove Region from container
169// ***************************************************************************
170//
172{
173 G4RegionStore* store = GetInstance();
174 if (!locked) // Do not de-register if locked !
175 {
176 if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
177 for (auto i=store->cbegin(); i!=store->cend(); ++i)
178 {
179 if (**i==*pRegion)
180 {
181 store->erase(i);
182 break;
183 }
184 }
185 const G4String& reg_name = pRegion->GetName();
186 auto it = store->bmap.find(reg_name);
187 if (it != store->bmap.cend())
188 {
189 if (it->second.size() > 1)
190 {
191 for (auto i=it->second.cbegin(); i!=it->second.cend(); ++i)
192 {
193 if (**i==*pRegion)
194 {
195 it->second.erase(i);
196 break;
197 }
198 }
199 }
200 else
201 {
202 store->bmap.erase(it);
203 }
204 }
205 }
206}
207
208// ***************************************************************************
209// Return ptr to Store, setting if necessary
210// ***************************************************************************
211//
213{
214 static G4RegionStore worldStore;
215 if (fgInstance == nullptr)
216 {
217 fgInstance = &worldStore;
218 }
219 return fgInstance;
220}
221
222// ***************************************************************************
223// Loops through all regions to verify if a region has been modified.
224// It returns TRUE if just one region is modified.
225// ***************************************************************************
226//
228{
229 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
230 {
231 if ((*i)->IsModified()) { return true; }
232 }
233 return false;
234}
235
236// ***************************************************************************
237// Loops through all regions to reset flag for modification to FALSE.
238// Used by the run manager to notify that the physics table has been updated.
239// ***************************************************************************
240//
242{
243 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
244 {
245 (*i)->RegionModified(false);
246 }
247}
248
249// ***************************************************************************
250// Forces recomputation of material lists in all regions in the store.
251// ***************************************************************************
252//
254{
255 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
256 {
257 if((*i)->IsInMassGeometry() || (*i)->IsInParallelGeometry()
258 || (currentWorld != nullptr))
259 { (*i)->UpdateMaterialList(); }
260 }
261}
262
263// ***************************************************************************
264// Returns a region through its name specification.
265// ***************************************************************************
266//
268{
269 G4RegionStore* store = GetInstance();
270 if (!store->mvalid) { store->UpdateMap(); }
271 auto pos = store->bmap.find(name);
272 if(pos != store->bmap.cend())
273 {
274 if ((verbose) && (pos->second.size()>1))
275 {
276 std::ostringstream message;
277 message << "There exists more than ONE region in store named: "
278 << name << "!" << G4endl
279 << "Returning the first found.";
280 G4Exception("G4RegionStore::GetSolid()",
281 "GeomMgt1001", JustWarning, message);
282 }
283 return pos->second[0];
284 }
285 if (verbose)
286 {
287 std::ostringstream message;
288 message << "Region NOT found in store !" << G4endl
289 << " Region " << name << " NOT found in store !" << G4endl
290 << " Returning NULL pointer.";
291 G4Exception("G4RegionStore::GetRegion()",
292 "GeomMgt1001", JustWarning, message);
293 }
294 return nullptr;
295}
296
297// ***************************************************************************
298// Returns a region through its name specification, if it exists.
299// If it does not exist it will allocate a new region with the given
300// name, delegating the ownership to the caller client.
301// ***************************************************************************
302//
304{
305 G4Region* target = GetRegion(name,false);
306 if (target == nullptr)
307 {
308 target = new G4Region(name);
309 }
310 return target;
311}
312
313// **************************************************************************
314// Set a world physical volume pointer to a region that belongs to it.
315// Scan over all world volumes.
316// **************************************************************************
317//
319{
320 // Reset all pointers first
321 //
322 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
323 { (*i)->SetWorld(nullptr); }
324
325 // Find world volumes
326 //
327 G4PhysicalVolumeStore* fPhysicalVolumeStore
329 std::size_t nPhys = fPhysicalVolumeStore->size();
330 for(std::size_t iPhys=0; iPhys<nPhys; ++iPhys)
331 {
332 G4VPhysicalVolume* fPhys = (*fPhysicalVolumeStore)[iPhys];
333 if(fPhys->GetMotherLogical() != nullptr) { continue; } // not a world volume
334
335 // Now 'fPhys' is a world volume, set it to regions that belong to it.
336 //
337 for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
338 { (*i)->SetWorld(fPhys); }
339 }
340}
341
@ 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 G4PhysicalVolumeStore * GetInstance()
static void DeRegister(G4Region *pRegion)
static void Register(G4Region *pRegion)
static G4RegionStore * GetInstance()
static void SetNotifier(G4VStoreNotifier *pNotifier)
void UpdateMaterialList(G4VPhysicalVolume *currentWorld=nullptr)
virtual ~G4RegionStore()
static void Clean()
G4Region * GetRegion(const G4String &name, G4bool verbose=true) const
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
#define G4ThreadLocal
Definition: tls.hh:77