Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
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 //
82 if (G4GeometryManager::GetInstance()->IsGeometryClosed())
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 != nullptr) { 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
G4TemplateAutoLock< G4Mutex > G4AutoLock
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
bool G4bool
Definition G4Types.hh:86
G4VNotifier G4VStoreNotifier
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
static G4GeometryManager * GetInstance()
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()
G4RegionStore(const G4RegionStore &)=delete
G4bool IsModified() const
const G4String & GetName() const
static void Clean()
Definition G4Region.cc:370
G4LogicalVolume * GetMotherLogical() const
#define G4ThreadLocal
Definition tls.hh:77