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