Geant4-11
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// ----------------------------------------------------------------------
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
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
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
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// ----------------------------------------------------------------------
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// ----------------------------------------------------------------------
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{
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{
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());
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:35
#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)
size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
const G4String & GetName() const
G4int GetRegularStructureId() const
Definition: G4PVReplica.cc:329
virtual void SetRegularStructureId(G4int code)
Definition: G4PVReplica.cc:335
void CheckAndSetParameters(const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset)
Definition: G4PVReplica.cc:201
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
G4int instanceID
Definition: G4PVReplica.hh:193
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
void CheckOnlyDaughter(G4LogicalVolume *pMotherLogical)
Definition: G4PVReplica.cc:182
G4bool IsRegularStructure() const
Definition: G4PVReplica.cc:323
void InitialiseWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:355
virtual G4int GetCopyNo() const
Definition: G4PVReplica.cc:267
G4int fRegularVolsId
Definition: G4PVReplica.hh:191
virtual EVolume VolumeType() const
Definition: G4PVReplica.cc:303
static G4GEOM_DLL G4PVRManager subInstanceManager
Definition: G4PVReplica.hh:195
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