Geant4 11.2.2
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//
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//
77void
79{
80 // Geometry related, split classes mechanism: instantiate sub-instance
81 // for this thread
82 //
83 fpLogicalVolumeSIM->UseWorkArea(fLogicalVolumeOffset);
84 fpPhysicalVolumeSIM->UseWorkArea(fPhysicalVolumeOffset);
85
86 fpReplicaSIM->UseWorkArea(fReplicaOffset);
87 fpRegionSIM->UseWorkArea(fRegionOffset);
88
89 // When recycling a workspace
90 // - it must be a lightweight operation, to reuse a valid work area
91 // - so it must NOT Initialise anything!
92 // Do not call InitialisePhysicalVolumes();
93}
94
95// ----------------------------------------------------------------------
96//
98{
99 fpLogicalVolumeSIM->UseWorkArea(nullptr);
100 fpPhysicalVolumeSIM->UseWorkArea(nullptr);
101
102 fpReplicaSIM->UseWorkArea(nullptr);
103 fpRegionSIM->UseWorkArea(nullptr);
104}
105
106// ----------------------------------------------------------------------
107//
109{
111 for (auto physVol : *physVolStore)
112 {
113 G4LogicalVolume *logicalVol = physVol->GetLogicalVolume();
114
115 // Use shadow pointer
116 //
117 G4VSolid* solid = logicalVol->GetMasterSolid();
118 auto g4PVReplica = dynamic_cast<G4PVReplica*>(physVol);
119 if (g4PVReplica == nullptr)
120 {
121 // Placement volume
122 //
123 logicalVol->InitialiseWorker(logicalVol,solid,nullptr);
124 }
125 else
126 {
127 g4PVReplica->InitialiseWorker(g4PVReplica);
128 logicalVol->InitialiseWorker(logicalVol,solid,nullptr);
129
130 // If the replica's solid (in LV) is changed during navigation,
131 // it must be thread-private
132 //
133 CloneReplicaSolid( g4PVReplica );
134 }
135 }
136}
137
138// ----------------------------------------------------------------------
139// Create a clone of the solid for this replica in this thread
140//
142{
143 G4LogicalVolume* logicalV = replicaPV->GetLogicalVolume();
144 G4VSolid* solid = logicalV->GetSolid();
145
146 G4AutoLock aLock(&mutex_init);
147 G4VSolid* workerSolid = solid->Clone();
148 aLock.unlock();
149
150 if( workerSolid != nullptr )
151 {
152 logicalV->InitialiseWorker(logicalV,workerSolid,nullptr);
153 }
154 else
155 {
156 // In the case that not all solids support(ed) the Clone()
157 // method, we do similar thing here to dynamically cast
158 // and then get the clone method
159 //
161 ed << "ERROR - Unable to initialise geometry for worker node." << "\n"
162 << "A solid lacks the Clone() method - or Clone() failed." << "\n"
163 << " Type of solid: " << solid->GetEntityType() << "\n"
164 << " Parameters: " << *solid;
165 G4Exception("G4GeometryWorkspace::CloneReplicaSolid()",
166 "GeomVol0003", FatalException, ed);
167 return false;
168 }
169 return true; // It Worked
170}
171
172// ----------------------------------------------------------------------
173//
175{
176 // Geometry related, split classes mechanism:
177 // Do *NOT* instantiate sub-instance for this thread, just copy the contents!
178 //
179 fpLogicalVolumeSIM->SlaveCopySubInstanceArray();
180 fpPhysicalVolumeSIM->SlaveCopySubInstanceArray();
181 fpReplicaSIM->SlaveCopySubInstanceArray();
182 fpRegionSIM->SlaveInitializeSubInstance();
183
185}
186
187// ----------------------------------------------------------------------
188//
190{
192 for (auto physVol : *physVolStore)
193 {
194 G4LogicalVolume* logicalVol = physVol->GetLogicalVolume();
195 auto g4PVReplica = dynamic_cast<G4PVReplica*>(physVol);
196 if (g4PVReplica != nullptr)
197 {
198 g4PVReplica->TerminateWorker(g4PVReplica);
199 }
200 logicalVol->TerminateWorker(logicalVol);
201 }
202
203 // Threads may attempt to free memory simultaneously.
204 // Need a lock to guarantee thread safety
205 //
206 G4AutoLock aLock(&mutex_init);
207 fpLogicalVolumeSIM->FreeSlave();
208 fpPhysicalVolumeSIM->FreeSlave();
209 fpReplicaSIM->FreeSlave();
210 fpRegionSIM->FreeSlave();
211 aLock.unlock();
212}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
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()
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