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