Geant4  10.01
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 //
27 // $Id: G4PVReplica.cc 85846 2014-11-05 15:45:28Z gcosmo $
28 //
29 //
30 // class G4PVReplica Implementation
31 //
32 // ----------------------------------------------------------------------
33 
34 #include "G4PVReplica.hh"
35 #include "G4LogicalVolume.hh"
36 
37 // This static member is thread local. For each thread, it points to the
38 // array of G4ReplicaData instances.
39 //
40 template <class G4ReplicaData> G4ThreadLocal
43  // Helping in the use of the class G4PVRManager.
44 
46  G4LogicalVolume* pLogical,
47  G4VPhysicalVolume* pMother,
48  const EAxis pAxis,
49  const G4int nReplicas,
50  const G4double width,
51  const G4double offset )
52  : G4VPhysicalVolume(0, G4ThreeVector(), pName, pLogical, pMother),
53  fRegularVolsId(0)
54 {
55 
57 
58  G4MT_copyNo = -1;
59 
60  if ((!pMother) || (!pMother->GetLogicalVolume()))
61  {
62  std::ostringstream message;
63  message << "NULL pointer specified as mother volume." << G4endl
64  << "The world volume cannot be sliced or parameterised !";
65  G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
66  FatalException, message);
67  return;
68  }
69  G4LogicalVolume* motherLogical = pMother->GetLogicalVolume();
70  if (pLogical == motherLogical)
71  {
72  G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
73  FatalException, "Cannot place a volume inside itself!");
74  return;
75  }
76  SetMotherLogical(motherLogical);
77  motherLogical->AddDaughter(this);
78  if (motherLogical->GetNoDaughters() != 1)
79  {
80  std::ostringstream message;
81  message << "Replica or parameterised volume must be the only daughter !"
82  << G4endl
83  << " Mother physical volume: " << pMother->GetName() << G4endl
84  << " Replicated volume: " << pName;
85  G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
86  FatalException, message);
87  return;
88  }
89  CheckAndSetParameters (pAxis, nReplicas, width, offset);
90 }
91 
93  G4LogicalVolume* pLogical,
94  G4LogicalVolume* pMotherLogical,
95  const EAxis pAxis,
96  const G4int nReplicas,
97  const G4double width,
98  const G4double offset )
99  : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fRegularVolsId(0)
100 {
101 
103  G4MT_copyNo = -1;
104 
105  if (!pMotherLogical)
106  {
107  std::ostringstream message;
108  message << "NULL pointer specified as mother volume for "
109  << pName << ".";
110  G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
111  FatalException, message);
112  return;
113  }
114  if (pLogical == pMotherLogical)
115  {
116  G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
117  FatalException, "Cannot place a volume inside itself!");
118  return;
119  }
120  pMotherLogical->AddDaughter(this);
121  SetMotherLogical(pMotherLogical);
122  if (pMotherLogical->GetNoDaughters() != 1)
123  {
124  std::ostringstream message;
125  message << "Replica or parameterised volume must be the only daughter !"
126  << G4endl
127  << " Mother logical volume: " << pMotherLogical->GetName()
128  << G4endl
129  << " Replicated volume: " << pName;
130  G4Exception("G4PVReplica::G4PVReplica()", "GeomVol0002",
131  FatalException, message);
132  return;
133  }
134  CheckAndSetParameters (pAxis, nReplicas, width, offset);
135 }
136 
138  const G4int nReplicas,
139  const G4double width,
140  const G4double offset)
141 {
142  if (nReplicas<1)
143  {
144  G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0002",
145  FatalException, "Illegal number of replicas.");
146  }
147  fnReplicas=nReplicas;
148  if (width<0)
149  {
150  G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0002",
151  FatalException, "Width must be positive.");
152  }
153  fwidth = width;
154  foffset = offset;
155  faxis = pAxis;
156 
157  // Create rotation matrix for phi axis case & check axis is valid
158  //
159  G4RotationMatrix* pRMat=0;
160  switch (faxis)
161  {
162  case kPhi:
163  pRMat=new G4RotationMatrix();
164  if (!pRMat)
165  {
166  G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0003",
167  FatalException, "Rotation matrix allocation failed.");
168  }
169  SetRotation(pRMat);
170  break;
171  case kRho:
172  case kXAxis:
173  case kYAxis:
174  case kZAxis:
175  case kUndefined:
176  break;
177  default:
178  G4Exception("G4PVReplica::CheckAndSetParameters()", "GeomVol0002",
179  FatalException, "Unknown axis of replication.");
180  break;
181  }
182 }
183 
185  : G4VPhysicalVolume(a), faxis(kZAxis), fnReplicas(0), fwidth(0.),
186  foffset(0.), fRegularStructureCode(0), fRegularVolsId(0)
187 {
189  G4MT_copyNo = -1;
190 }
191 
193 {
194  if ( faxis==kPhi )
195  {
196  delete GetRotation();
197  }
198 }
199 
201 {
202  return false;
203 }
204 
206 {
207  return G4MT_copyNo;
208 }
209 
211 {
212  G4MT_copyNo = newCopyNo;
213 }
214 
216 {
217  return true;
218 }
219 
221 {
222  return false;
223 }
224 
226 {
227  return 0;
228 }
229 
231 {
232  return fnReplicas;
233 }
234 
236  G4int& nReplicas,
237  G4double& width,
238  G4double& offset,
239  G4bool& consuming ) const
240 {
241  axis = faxis;
242  nReplicas = fnReplicas;
243  width = fwidth;
244  offset = foffset;
245  consuming = true;
246 }
247 
249 {
250  return (fRegularVolsId!=0);
251 }
252 
254 {
255  return fRegularVolsId;
256 }
257 
259 {
260  fRegularVolsId= Code;
261 }
262 
263 // Returns the private data instance manager.
264 //
266 {
267  return subInstanceManager;
268 }
269 
270 // This method is similar to the constructor. It is used by each worker
271 // thread to achieve the same effect as that of the master thread exept
272 // to register the new created instance. This method is invoked explicitly.
273 // It does not create a new G4PVReplica instance. It only assigns the value
274 // for the fields encapsulated by the class G4ReplicaData.
275 //
277 {
278 
281  G4MT_copyNo = -1;
282 
283  // This call causes "self-assignment" of the input paramters
284  // Issue reported by DRD since TerminateWorker below can be called
285  // at the same time by another thread
286  // What we need here is the splic-class component of this funciton
287  // that is copied here
288  // CheckAndSetParameters (faxis, fnReplicas, fwidth, foffset);
289 
290  // Create rotation matrix for phi axis case & check axis is valid
291  //
292  G4RotationMatrix* pRMat=0;
293  switch (faxis)
294  {
295  case kPhi:
296  pRMat=new G4RotationMatrix();
297  if (!pRMat)
298  {
299  G4Exception("G4PVReplica::InitialiseWorker(...)", "GeomVol0003",
300  FatalException, "Rotation matrix allocation failed.");
301  }
302  SetRotation(pRMat);
303  break;
304  case kRho:
305  case kXAxis:
306  case kYAxis:
307  case kZAxis:
308  case kUndefined:
309  break;
310  default:
311  G4Exception("G4PVReplica::InitialiseWorker(...)", "GeomVol0002",
312  FatalException, "Unknown axis of replication.");
313  break;
314  }
315 }
316 
317 // This method is similar to the destructor. It is used by each worker
318 // thread to achieve the partial effect as that of the master thread.
319 // For G4PVReplica instances, it destories the rotation matrix.
320 //
322 {
323  if ( faxis==kPhi )
324  {
325  delete GetRotation();
326  }
327 }
Definition: geomdefs.hh:54
void TerminateWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:321
G4PVReplica(const G4String &pName, G4LogicalVolume *pLogical, G4LogicalVolume *pMother, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset=0)
Definition: G4PVReplica.cc:92
virtual ~G4PVReplica()
Definition: G4PVReplica.cc:192
G4String GetName() const
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepRotation G4RotationMatrix
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const
Definition: G4PVReplica.cc:235
virtual void SetRegularStructureId(G4int Code)
Definition: G4PVReplica.cc:258
#define width
G4double fwidth
Definition: G4PVReplica.hh:201
G4bool IsRegularStructure() const
Definition: G4PVReplica.cc:248
G4double a
Definition: TRTMaterials.hh:39
static G4GEOM_DLL G4PVRManager subInstanceManager
Definition: G4PVReplica.hh:210
#define G4ThreadLocal
Definition: tls.hh:84
G4int CreateSubInstance()
int G4int
Definition: G4Types.hh:78
virtual G4int GetCopyNo() const
Definition: G4PVReplica.cc:205
G4bool IsReplicated() const
Definition: G4PVReplica.cc:215
void SetRotation(G4RotationMatrix *)
static const G4PVRManager & GetSubInstanceManager()
Definition: G4PVReplica.cc:265
virtual G4bool IsParameterised() const
Definition: G4PVReplica.cc:220
G4double foffset
Definition: G4PVReplica.hh:201
void InitialiseWorker(G4VPhysicalVolume *pMasterObject, G4RotationMatrix *pRot, const G4ThreeVector &tlate)
G4int fRegularVolsId
Definition: G4PVReplica.hh:206
const G4String & GetName() const
void InitialiseWorker(G4PVReplica *pMasterObject)
Definition: G4PVReplica.cc:276
virtual G4VPVParameterisation * GetParameterisation() const
Definition: G4PVReplica.cc:225
G4int fnReplicas
Definition: G4PVReplica.hh:200
bool G4bool
Definition: G4Types.hh:79
void SlaveCopySubInstanceArray()
G4bool IsMany() const
Definition: G4PVReplica.cc:200
G4int GetNoDaughters() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4int instanceID
Definition: G4PVReplica.hh:208
G4LogicalVolume * GetLogicalVolume() const
EAxis
Definition: geomdefs.hh:54
void CheckAndSetParameters(const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset)
Definition: G4PVReplica.cc:137
virtual G4int GetMultiplicity() const
Definition: G4PVReplica.cc:230
const G4RotationMatrix * GetRotation() const
virtual void SetCopyNo(G4int CopyNo)
Definition: G4PVReplica.cc:210
#define G4endl
Definition: G4ios.hh:61
void SetMotherLogical(G4LogicalVolume *pMother)
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
#define G4MT_copyNo
Definition: G4PVReplica.hh:117
void AddDaughter(G4VPhysicalVolume *p)
G4int GetRegularStructureId() const
Definition: G4PVReplica.cc:253