Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4PVReplica.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// class G4PVReplica Implementation
27//
28// 29.07.95, P.Kent - First non-stub version
29// ----------------------------------------------------------------------
30
31#include "G4PVReplica.hh"
32#include "G4LogicalVolume.hh"
33
34// ----------------------------------------------------------------------
35G4PVRManager G4PVReplica::subInstanceManager;
36 // Helping in the use of the class G4PVRManager.
37
38#define G4MT_copyNo ((subInstanceManager.offset[instanceID]).fcopyNo)
39 // This macro changes the references to fields that are now encapsulated
40 // in the class G4ReplicaData.
41
42// ----------------------------------------------------------------------
44 G4LogicalVolume* pLogical,
45 G4VPhysicalVolume* pMother,
46 const EAxis pAxis,
47 const G4int nReplicas,
48 const G4double width,
49 const G4double offset )
50 : G4VPhysicalVolume(nullptr, G4ThreeVector(), pName, pLogical, pMother)
51{
52
53 instanceID = subInstanceManager.CreateSubInstance();
54
55 if ((pMother == nullptr) || (pMother->GetLogicalVolume() == nullptr))
56 {
57 std::ostringstream message;
58 message << "NULL pointer specified as mother volume." << G4endl
59 << "The world volume cannot be sliced or parameterised !";
60 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
61 FatalException, message);
62 return;
63 }
64 G4LogicalVolume* motherLogical = pMother->GetLogicalVolume();
65 if (pLogical == motherLogical)
66 {
67 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
68 FatalException, "Cannot place a volume inside itself!");
69 return;
70 }
71 SetMotherLogical(motherLogical);
72 motherLogical->AddDaughter(this);
73 if (motherLogical->GetNoDaughters() != 1)
74 {
75 std::ostringstream message;
76 message << "Replica or parameterised volume must be the only daughter !"
77 << G4endl
78 << " Mother physical volume: " << pMother->GetName() << G4endl
79 << " Replicated volume: " << pName;
80 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
81 FatalException, message);
82 return;
83 }
84 CheckAndSetParameters (pAxis, nReplicas, width, offset);
85}
86
87// ----------------------------------------------------------------------
89 G4LogicalVolume* pLogical,
90 G4LogicalVolume* pMotherLogical,
91 const EAxis pAxis,
92 const G4int nReplicas,
93 const G4double width,
94 const G4double offset )
95 : G4VPhysicalVolume(nullptr, G4ThreeVector(), pName, pLogical, nullptr)
96{
97
98 instanceID = subInstanceManager.CreateSubInstance();
99
100 if (pMotherLogical == nullptr)
101 {
102 std::ostringstream message;
103 message << "NULL pointer specified as mother volume for "
104 << pName << ".";
105 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
106 FatalException, message);
107 return;
108 }
109 if (pLogical == pMotherLogical)
110 {
111 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
112 FatalException, "Cannot place a volume inside itself!");
113 return;
114 }
115
116 pMotherLogical->AddDaughter(this);
117 SetMotherLogical(pMotherLogical);
118 if (pMotherLogical->GetNoDaughters() != 1)
119 {
120 std::ostringstream message;
121 message << "Replica or parameterised volume must be the only daughter !"
122 << G4endl
123 << " Mother logical volume: " << pMotherLogical->GetName()
124 << G4endl
125 << " Replicated volume: " << pName;
126 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
127 FatalException, message);
128 return;
129 }
130 CheckAndSetParameters (pAxis, nReplicas, width, offset);
131}
132
133// ----------------------------------------------------------------------
135 G4int nReplicas,
136 EAxis pAxis,
137 G4LogicalVolume* pLogical,
138 G4LogicalVolume* pMotherLogical
139 )
140 : G4VPhysicalVolume(nullptr, G4ThreeVector(), pName, pLogical, nullptr)
141{
142 // Constructor for derived type(s)
143 // Does not set mother volume or register this one in mother volume
144 // ( To allow the correct type to be found in mother->AddDaughter )
145
146 instanceID = subInstanceManager.CreateSubInstance();
147
148 if (pMotherLogical == nullptr)
149 {
150 std::ostringstream message;
151 message << "NULL pointer specified as mother volume for "
152 << pName << ".";
153 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
154 FatalException, message);
155 return;
156 }
157 if (pLogical == pMotherLogical)
158 {
159 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
160 FatalException, "Cannot place a volume inside itself!");
161 return;
162 }
163 CheckOnlyDaughter(pMotherLogical);
164 /***
165 if (pMotherLogical->GetNoDaughters() != 0)
166 {
167 std::ostringstream message;
168 message << "Replica or parameterised volume must be the only daughter !"
169 << G4endl
170 << " Mother logical volume: " << pMotherLogical->GetName()
171 << G4endl
172 << " Replicated volume: " << pName;
173 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
174 FatalException, message);
175 return;
176 }
177 **/
178 CheckAndSetParameters (pAxis, nReplicas, 0.0, 0.0);
179}
180
181// ----------------------------------------------------------------------
182void G4PVReplica::CheckOnlyDaughter(G4LogicalVolume* pMotherLogical)
183{
184 if (pMotherLogical->GetNoDaughters() != 0)
185 {
186 std::ostringstream message;
187 message << "Replica or parameterised volume must be the only daughter !"
188 << G4endl
189 << " Mother logical volume: " << pMotherLogical->GetName()
190 << G4endl
191 << " Replicated volume: " << this->GetName() << G4endl
192 << " Existing 'sister': " << pMotherLogical->GetDaughter(0)
193 ->GetName();
194 G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
195 FatalException, message);
196 return;
197 }
198}
199
200// ----------------------------------------------------------------------
201void G4PVReplica::CheckAndSetParameters( const EAxis pAxis,
202 const G4int nReplicas,
203 const G4double width,
204 const G4double offset)
205{
206 if (nReplicas<1)
207 {
208 G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0002",
209 FatalException, "Illegal number of replicas.");
210 }
211 fnReplicas=nReplicas;
212 if (width<0)
213 {
214 G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0002",
215 FatalException, "Width must be positive.");
216 }
217 fwidth = width;
218 foffset = offset;
219 faxis = pAxis;
220
221 // Create rotation matrix for phi axis case & check axis is valid
222 //
223 G4RotationMatrix* pRMat = nullptr;
224 switch (faxis)
225 {
226 case kPhi:
227 pRMat = new G4RotationMatrix();
228 if (pRMat == nullptr)
229 {
230 G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0003",
231 FatalException, "Rotation matrix allocation failed.");
232 }
233 SetRotation(pRMat);
234 break;
235 case kRho:
236 case kXAxis:
237 case kYAxis:
238 case kZAxis:
239 case kUndefined:
240 break;
241 default:
242 G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0002",
243 FatalException, "Unknown axis of replication.");
244 break;
245 }
246}
247
248// ----------------------------------------------------------------------
250 : G4VPhysicalVolume(a), faxis(kZAxis), fnReplicas(0), fwidth(0.), foffset(0.)
251{
252 instanceID = subInstanceManager.CreateSubInstance();
253}
254
255// ----------------------------------------------------------------------
257{
258}
259
260// ----------------------------------------------------------------------
262{
263 return false;
264}
265
266// ----------------------------------------------------------------------
268{
269 return G4MT_copyNo;
270}
271
272// ----------------------------------------------------------------------
274{
275 G4MT_copyNo = newCopyNo;
276}
277
278// ----------------------------------------------------------------------
280{
281 return true;
282}
283
284// ----------------------------------------------------------------------
286{
287 return false;
288}
289
290// ----------------------------------------------------------------------
292{
293 return nullptr;
294}
295
296// ----------------------------------------------------------------------
298{
299 return fnReplicas;
300}
301
302// ----------------------------------------------------------------------
304{
305 return kReplica;
306}
307
308// ----------------------------------------------------------------------
310 G4int& nReplicas,
311 G4double& width,
312 G4double& offset,
313 G4bool& consuming ) const
314{
315 axis = faxis;
316 nReplicas = fnReplicas;
317 width = fwidth;
318 offset = foffset;
319 consuming = true;
320}
321
322// ----------------------------------------------------------------------
324{
325 return (fRegularVolsId != 0);
326}
327
328// ----------------------------------------------------------------------
330{
331 return fRegularVolsId;
332}
333
334// ----------------------------------------------------------------------
336{
337 fRegularVolsId = code;
338}
339
340// ----------------------------------------------------------------------
341// Returns the private data instance manager.
342//
344{
345 return subInstanceManager;
346}
347
348// ----------------------------------------------------------------------
349// This method is similar to the constructor. It is used by each worker
350// thread to achieve the same effect as that of the master thread exept
351// to register the new created instance. This method is invoked explicitly.
352// It does not create a new G4PVReplica instance. It only assigns the value
353// for the fields encapsulated by the class G4ReplicaData.
354//
356{
357
358 G4VPhysicalVolume::InitialiseWorker( pMasterObject, nullptr, G4ThreeVector());
359 subInstanceManager.SlaveCopySubInstanceArray();
360 G4MT_copyNo = -1;
361
362 // This call causes "self-assignment" of the input parameters
363 // Issue reported by DRD since TerminateWorker() below can be called
364 // at the same time by another thread.
365 // What we need here is the split-class component of CheckAndSetParameters()
366 // funciton copied here.
367
368 // Create rotation matrix for phi axis case & check axis is valid
369 //
370 G4RotationMatrix* pRMat = nullptr;
371 switch (faxis)
372 {
373 case kPhi:
374 pRMat = new G4RotationMatrix();
375 if (pRMat == nullptr)
376 {
377 G4Exception("G4PVReplica::InitialiseWorker(...)", "GeomVol0003",
378 FatalException, "Rotation matrix allocation failed.");
379 }
380 SetRotation(pRMat);
381 break;
382 case kRho:
383 case kXAxis:
384 case kYAxis:
385 case kZAxis:
386 case kUndefined:
387 break;
388 default:
389 G4Exception("G4PVReplica::InitialiseWorker(...)", "GeomVol0002",
390 FatalException, "Unknown axis of replication.");
391 break;
392 }
393}
394
395// ----------------------------------------------------------------------
396// This method is similar to the destructor. It is used by each worker
397// thread to achieve the partial effect as that of the master thread.
398// For G4PVReplica instances, it destroys the rotation matrix.
399//
401{
402 if ( faxis==kPhi )
403 {
404 delete GetRotation();
405 }
406}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
#define G4MT_copyNo
Definition: G4PVReplica.cc:38
CLHEP::HepRotation G4RotationMatrix
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4int CreateSubInstance()
void SlaveCopySubInstanceArray()
void AddDaughter(G4VPhysicalVolume *p)
std::size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
const G4String & GetName() const
G4int GetRegularStructureId() const
Definition: G4PVReplica.cc:329
virtual void SetRegularStructureId(G4int code)
Definition: G4PVReplica.cc:335
G4bool IsMany() const
Definition: G4PVReplica.cc:261
G4PVReplica(const G4String &pName, G4LogicalVolume *pLogical, G4LogicalVolume *pMother, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset=0.)
Definition: G4PVReplica.cc:88
G4double fwidth
Definition: G4PVReplica.hh:187
virtual void SetCopyNo(G4int CopyNo)
Definition: G4PVReplica.cc:273
G4bool IsReplicated() const
Definition: G4PVReplica.cc:279
virtual G4int GetMultiplicity() const
Definition: G4PVReplica.cc:297
static const G4PVRManager & GetSubInstanceManager()
Definition: G4PVReplica.cc:343
G4int fnReplicas
Definition: G4PVReplica.hh:186
G4double foffset
Definition: G4PVReplica.hh:187
virtual G4VPVParameterisation * GetParameterisation() const
Definition: G4PVReplica.cc:291
void TerminateWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:400
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const
Definition: G4PVReplica.cc:309
virtual G4bool IsParameterised() const
Definition: G4PVReplica.cc:285
G4bool IsRegularStructure() const
Definition: G4PVReplica.cc:323
void InitialiseWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:355
virtual G4int GetCopyNo() const
Definition: G4PVReplica.cc:267
virtual EVolume VolumeType() const
Definition: G4PVReplica.cc:303
virtual ~G4PVReplica()
Definition: G4PVReplica.cc:256
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
void SetRotation(G4RotationMatrix *)
void SetMotherLogical(G4LogicalVolume *pMother)
void InitialiseWorker(G4VPhysicalVolume *pMasterObject, G4RotationMatrix *pRot, const G4ThreeVector &tlate)
EAxis
Definition: geomdefs.hh:54
@ kPhi
Definition: geomdefs.hh:60
@ kYAxis
Definition: geomdefs.hh:56
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57
@ kUndefined
Definition: geomdefs.hh:61
@ kRho
Definition: geomdefs.hh:58
EVolume
Definition: geomdefs.hh:83
@ kReplica
Definition: geomdefs.hh:85
Definition: inftrees.h:24