Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GeometryWorkspace.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// G4GeometryWorkspace - implementation
27//
28// Authors: John Apostolakis (CERN), Andrea Dotti (SLAC), July 2013
29// --------------------------------------------------------------------
30
33#include "G4AutoLock.hh"
34
35namespace
36{
37 G4Mutex mutex_init = G4MUTEX_INITIALIZER;
39}
40
41// ----------------------------------------------------------------------
42//
44{
45 return &thePool;
46}
47
48// ----------------------------------------------------------------------
49//
51{
52 fpLogicalVolumeSIM=
54 fpPhysicalVolumeSIM=
56 fpReplicaSIM=
58 fpRegionSIM=
60
61 // Create a work area for Logical Volumes in this thread
62 // then capture its address
63 //
65
66 fLogicalVolumeOffset = fpLogicalVolumeSIM->GetOffset();
67
68 fPhysicalVolumeOffset = fpPhysicalVolumeSIM->GetOffset();
69
70 fReplicaOffset = fpReplicaSIM->GetOffset();
71
72 fRegionOffset = fpRegionSIM->GetOffset();
73}
74
75// ----------------------------------------------------------------------
76//
78{
79}
80
81// ----------------------------------------------------------------------
82//
83void
85{
86 // Geometry related, split classes mechanism: instantiate sub-instance
87 // for this thread
88 //
89 fpLogicalVolumeSIM->UseWorkArea(fLogicalVolumeOffset);
90 fpPhysicalVolumeSIM->UseWorkArea(fPhysicalVolumeOffset);
91
92 fpReplicaSIM->UseWorkArea(fReplicaOffset);
93 fpRegionSIM->UseWorkArea(fRegionOffset);
94
95 // When recycling a workspace
96 // - it must be a lightweight operation, to reuse a valid work area
97 // - so it must NOT Initialise anything!
98 // Do not call InitialisePhysicalVolumes();
99}
100
101// ----------------------------------------------------------------------
102//
104{
105 fpLogicalVolumeSIM->UseWorkArea(nullptr);
106 fpPhysicalVolumeSIM->UseWorkArea(nullptr);
107
108 fpReplicaSIM->UseWorkArea(nullptr);
109 fpRegionSIM->UseWorkArea(nullptr);
110}
111
112// ----------------------------------------------------------------------
113//
115{
117 for (std::size_t ip=0; ip<physVolStore->size(); ++ip)
118 {
119 G4VPhysicalVolume* physVol = (*physVolStore)[ip];
120 G4LogicalVolume *logicalVol = physVol->GetLogicalVolume();
121
122 // Use shadow pointer
123 //
124 G4VSolid* solid = logicalVol->GetMasterSolid();
125 G4PVReplica* g4PVReplica = dynamic_cast<G4PVReplica*>(physVol);
126 if (g4PVReplica == nullptr)
127 {
128 // Placement volume
129 //
130 logicalVol->InitialiseWorker(logicalVol,solid,nullptr);
131 }
132 else
133 {
134 g4PVReplica->InitialiseWorker(g4PVReplica);
135 logicalVol->InitialiseWorker(logicalVol,solid,nullptr);
136
137 // If the replica's solid (in LV) is changed during navigation,
138 // it must be thread-private
139 //
140 CloneReplicaSolid( g4PVReplica );
141 }
142 }
143}
144
145// ----------------------------------------------------------------------
146// Create a clone of the solid for this replica in this thread
147//
149{
150 G4LogicalVolume* logicalV = replicaPV->GetLogicalVolume();
151 G4VSolid* solid = logicalV->GetSolid();
152
153 G4AutoLock aLock(&mutex_init);
154 G4VSolid* workerSolid = solid->Clone();
155 aLock.unlock();
156
157 if( workerSolid != nullptr )
158 {
159 logicalV->InitialiseWorker(logicalV,workerSolid,nullptr);
160 }
161 else
162 {
163 // In the case that not all solids support(ed) the Clone()
164 // method, we do similar thing here to dynamically cast
165 // and then get the clone method
166 //
168 ed << "ERROR - Unable to initialise geometry for worker node." << "\n"
169 << "A solid lacks the Clone() method - or Clone() failed." << "\n"
170 << " Type of solid: " << solid->GetEntityType() << "\n"
171 << " Parameters: " << *solid;
172 G4Exception("G4GeometryWorkspace::CloneReplicaSolid()",
173 "GeomVol0003", FatalException, ed);
174 return false;
175 }
176 return true; // It Worked
177}
178
179// ----------------------------------------------------------------------
180//
182{
183 // Geometry related, split classes mechanism:
184 // Do *NOT* instantiate sub-instance for this thread, just copy the contents!
185 //
186 fpLogicalVolumeSIM->SlaveCopySubInstanceArray();
187 fpPhysicalVolumeSIM->SlaveCopySubInstanceArray();
188 fpReplicaSIM->SlaveCopySubInstanceArray();
189 fpRegionSIM->SlaveInitializeSubInstance();
190
192}
193
194// ----------------------------------------------------------------------
195//
197{
199 for (std::size_t ip=0; ip<physVolStore->size(); ++ip)
200 {
201 G4VPhysicalVolume* physVol = (*physVolStore)[ip];
202 G4LogicalVolume* logicalVol = physVol->GetLogicalVolume();
203 G4PVReplica* g4PVReplica = dynamic_cast<G4PVReplica*>(physVol);
204 if (g4PVReplica != nullptr)
205 {
206 g4PVReplica->TerminateWorker(g4PVReplica);
207 }
208 logicalVol->TerminateWorker(logicalVol);
209 }
210
211 // Threads may attempt to free memory simultaneously.
212 // Need a lock to guarantee thread safety
213 //
214 G4AutoLock aLock(&mutex_init);
215 fpLogicalVolumeSIM->FreeSlave();
216 fpPhysicalVolumeSIM->FreeSlave();
217 fpReplicaSIM->FreeSlave();
218 fpRegionSIM->FreeSlave();
219 aLock.unlock();
220}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
void SlaveInitializeSubInstance()
void SlaveCopySubInstanceArray()
void UseWorkArea(T *newOffset)
G4bool CloneReplicaSolid(G4PVReplica *)
static pool_type * GetPool()
G4VSolid * GetSolid() const
void TerminateWorker(G4LogicalVolume *ptrMasterObject)
static const G4LVManager & GetSubInstanceManager()
void InitialiseWorker(G4LogicalVolume *ptrMasterObject, G4VSolid *pSolid, G4VSensitiveDetector *pSDetector)
G4VSolid * GetMasterSolid() const
static const G4PVRManager & GetSubInstanceManager()
Definition: G4PVReplica.cc:343
void TerminateWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:400
void InitialiseWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:355
static G4PhysicalVolumeStore * GetInstance()
static const G4RegionManager & GetSubInstanceManager()
Definition: G4Region.cc:55
G4LogicalVolume * GetLogicalVolume() const
static const G4PVManager & GetSubInstanceManager()
virtual G4VSolid * Clone() const
Definition: G4VSolid.cc:391
virtual G4GeometryType GetEntityType() const =0