Geant4  10.01.p03
G4PVDivision.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: G4PVDivision.cc 95287 2016-02-03 14:37:00Z gcosmo $
28 //
29 // class G4PVDivision Implementation file
30 //
31 // 26.05.03 - P.Arce Initial version
32 // --------------------------------------------------------------------
33 
34 #include "G4PVDivision.hh"
35 #include "G4LogicalVolume.hh"
36 #include "G4VSolid.hh"
37 #include "G4ReflectedSolid.hh"
38 #include "G4ParameterisationBox.hh"
41 #include "G4ParameterisationTrd.hh"
45 
46 //--------------------------------------------------------------------------
48  G4LogicalVolume* pLogical,
49  G4LogicalVolume* pMotherLogical,
50  const EAxis pAxis,
51  const G4int nDivs,
52  const G4double width,
53  const G4double offset )
54  : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0),
55  fcopyNo(-1)
56 {
57  if (!pMotherLogical)
58  {
59  std::ostringstream message;
60  message << "Invalid setup." << G4endl
61  << "NULL pointer specified as mother for volume: " << pName;
62  G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
63  FatalException, message);
64  return;
65  }
66  if (pLogical == pMotherLogical)
67  {
68  std::ostringstream message;
69  message << "Invalid setup." << G4endl
70  << "Cannot place a volume inside itself! Volume: " << pName;
71  G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
72  FatalException, message);
73  }
74  pMotherLogical->AddDaughter(this);
75  SetMotherLogical(pMotherLogical);
76  SetParameterisation(pMotherLogical, pAxis, nDivs,
77  width, offset, DivNDIVandWIDTH);
78  CheckAndSetParameters (pAxis, nDivs, width, offset,
79  DivNDIVandWIDTH, pMotherLogical);
80 }
81 
82 //--------------------------------------------------------------------------
84  G4LogicalVolume* pLogical,
85  G4LogicalVolume* pMotherLogical,
86  const EAxis pAxis,
87  const G4int nDivs,
88  const G4double offset )
89  : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0),
90  fcopyNo(-1)
91 {
92  if (!pMotherLogical)
93  {
94  std::ostringstream message;
95  message << "Invalid setup." << G4endl
96  << "NULL pointer specified as mother! Volume: " << pName;
97  G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
98  FatalException, message);
99  return;
100  }
101  if (pLogical == pMotherLogical)
102  {
103  std::ostringstream message;
104  message << "Invalid setup." << G4endl
105  << "Cannot place a volume inside itself! Volume: " << pName;
106  G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
107  FatalException, message);
108  }
109  pMotherLogical->AddDaughter(this);
110  SetMotherLogical(pMotherLogical);
111  SetParameterisation(pMotherLogical, pAxis, nDivs, 0., offset, DivNDIV);
112  CheckAndSetParameters (pAxis, nDivs, 0., offset, DivNDIV, pMotherLogical);
113 }
114 
115 //--------------------------------------------------------------------------
117  G4LogicalVolume* pLogical,
118  G4LogicalVolume* pMotherLogical,
119  const EAxis pAxis,
120  const G4double width,
121  const G4double offset )
122  : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0),
123  fcopyNo(-1)
124 {
125  if (!pMotherLogical)
126  {
127  std::ostringstream message;
128  message << "Invalid setup." << G4endl
129  << "NULL pointer specified as mother! Volume: " + pName;
130  G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
131  FatalException, message);
132  return;
133  }
134  if (pLogical == pMotherLogical)
135  {
136  std::ostringstream message;
137  message << "Invalid setup." << G4endl
138  << "Cannot place a volume inside itself! Volume: "+ pName;
139  G4Exception("G4PVDivision::G4PVDivision()", "GeomDiv0002",
140  FatalException, message);
141  }
142  pMotherLogical->AddDaughter(this);
143  SetMotherLogical(pMotherLogical);
144  SetParameterisation(pMotherLogical, pAxis, 0, width, offset, DivWIDTH);
145  CheckAndSetParameters (pAxis, 0, width, offset, DivWIDTH, pMotherLogical);
146 }
147 
148 //--------------------------------------------------------------------------
149 void
151  const G4int nDivs,
152  const G4double width,
153  const G4double offset,
154  DivisionType divType,
155  const G4LogicalVolume* pMotherLogical )
156 {
157  if( divType == DivWIDTH )
158  {
160  }
161  else
162  {
163  fnReplicas = nDivs;
164  }
165  if (fnReplicas < 1 )
166  {
167  G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
168  FatalException, "Illegal number of replicas!");
169  }
170 
171  if( divType != DivNDIV)
172  {
173  fwidth = fparam->GetWidth();
174  }
175  else
176  {
177  fwidth = width;
178  }
179  if( fwidth < 0 )
180  {
181  G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
182  FatalException, "Width must be positive!");
183  }
184 
185  foffset = offset;
186  fdivAxis = pAxis;
187 
189  //
190  if( pAxis == kRho || pAxis == kRadial3D || pAxis == kPhi )
191  {
192  faxis = kZAxis;
193  }
194  else
195  {
196  faxis = pAxis;
197  }
198 
199  // Create rotation matrix: for phi axis it will be changed
200  // in G4VPVParameterisation::ComputeTransformation, for others
201  // it will stay the unity
202  //
203  G4RotationMatrix *pRMat = new G4RotationMatrix();
204  SetRotation(pRMat);
205 
206  switch (faxis)
207  {
208  case kPhi:
209  break;
210  case kRho:
211  case kXAxis:
212  case kYAxis:
213  case kZAxis:
214  break;
215  default:
216  G4Exception("G4PVDivision::CheckAndSetParameters()", "GeomDiv0002",
217  FatalException, "Unknown axis of replication.");
218  break;
219  }
220 
221 
222  //----- Check that mother solid is of the same type than
223  // daughter solid (otherwise, the corresponding
224  // Parameterisation::ComputeDimension() will not be called)
225  //
226  G4String msolType = pMotherLogical->GetSolid()->GetEntityType();
227  G4String dsolType = GetLogicalVolume()->GetSolid()->GetEntityType();
228  if( msolType != dsolType && ( msolType != "G4Trd" || dsolType != "G4Trap" ) )
229  {
230  std::ostringstream message;
231  message << "Incorrect solid type for division of volume "
232  << GetName() << "." << G4endl
233  << "It is: " << msolType
234  << ", while it should be: " << dsolType << "!";
235  G4Exception("G4PVDivision::CheckAndSetParameters()",
236  "GeomDiv0002", FatalException, message );
237  }
238 }
239 
240 //--------------------------------------------------------------------------
242 {
243 }
244 
245 //--------------------------------------------------------------------------
247 {
248  return fdivAxis;
249 }
250 
251 //--------------------------------------------------------------------------
253 {
254  return true;
255 }
256 
257 //--------------------------------------------------------------------------
259 {
260  return false;
261 }
262 
263 //--------------------------------------------------------------------------
265 {
266  return fcopyNo;
267 }
268 
269 //--------------------------------------------------------------------------
271 {
272  fcopyNo= newCopyNo;
273 }
274 
275 //--------------------------------------------------------------------------
277 {
278  return true;
279 }
280 
281 //--------------------------------------------------------------------------
283 {
284  return fparam;
285 }
286 
287 //--------------------------------------------------------------------------
289  G4int& nDivs,
290  G4double& width,
291  G4double& offset,
292  G4bool& consuming ) const
293 {
294  axis=faxis;
295  nDivs=fnReplicas;
296  width=fwidth;
297  offset=foffset;
298  consuming=false;
299 }
300 
301 
302 //--------------------------------------------------------------------------
303 //TODO: this method should check that the child lv is of the correct type,
304 // else the ComputeDimensions will never be called
306  const EAxis axis,
307  const G4int nDivs,
308  const G4double width,
309  const G4double offset,
310  DivisionType divType )
311 {
312  // Check that solid is compatible with mother solid and axis of division
313  // CheckSolid( solid, motherSolid );
314  // G4cout << " Axis " << axis << G4endl;
315 
316  G4VSolid* mSolid = motherLogical->GetSolid();
317  G4String mSolidType = mSolid->GetEntityType();
318 
319  // If the solid is a reflected one, update type to its
320  // real constituent solid.
321  //
322  if (mSolidType == "G4ReflectedSolid")
323  {
324  mSolidType = ((G4ReflectedSolid*)mSolid)->GetConstituentMovedSolid()
325  ->GetEntityType();
326  }
327 
328  // Parameterisation type depend of mother solid type and axis of division
329  //
330  if( mSolidType == "G4Box" )
331  {
332  switch( axis )
333  {
334  case kXAxis:
335  fparam = new G4ParameterisationBoxX( axis, nDivs, width,
336  offset, mSolid, divType );
337  break;
338  case kYAxis:
339  fparam = new G4ParameterisationBoxY( axis, nDivs, width,
340  offset, mSolid, divType );
341  break;
342  case kZAxis:
343  fparam = new G4ParameterisationBoxZ( axis, nDivs, width,
344  offset, mSolid, divType );
345  break;
346  default:
347  ErrorInAxis( axis, mSolid );
348  break;
349  }
350  }
351  else if( mSolidType == "G4Tubs" )
352  {
353  switch( axis )
354  {
355  case kRho:
356  fparam = new G4ParameterisationTubsRho( axis, nDivs, width,
357  offset, mSolid, divType );
358  break;
359  case kPhi:
360  fparam = new G4ParameterisationTubsPhi( axis, nDivs, width,
361  offset, mSolid, divType );
362  break;
363  case kZAxis:
364  fparam = new G4ParameterisationTubsZ( axis, nDivs, width,
365  offset, mSolid, divType );
366  break;
367  default:
368  ErrorInAxis( axis, mSolid );
369  break;
370  }
371  }
372  else if( mSolidType == "G4Cons" )
373  {
374  switch( axis )
375  {
376  case kRho:
377  fparam = new G4ParameterisationConsRho( axis, nDivs, width,
378  offset, mSolid, divType );
379  break;
380  case kPhi:
381  fparam = new G4ParameterisationConsPhi( axis, nDivs, width,
382  offset, mSolid, divType );
383  break;
384  case kZAxis:
385  fparam = new G4ParameterisationConsZ( axis, nDivs, width,
386  offset, mSolid, divType );
387  break;
388  default:
389  ErrorInAxis( axis, mSolid );
390  break;
391  }
392  }
393  else if( mSolidType == "G4Trd" )
394  {
395  switch( axis )
396  {
397  case kXAxis:
398  fparam = new G4ParameterisationTrdX( axis, nDivs, width,
399  offset, mSolid, divType );
400  break;
401  case kYAxis:
402  fparam = new G4ParameterisationTrdY( axis, nDivs, width,
403  offset, mSolid, divType );
404  break;
405  case kZAxis:
406  fparam = new G4ParameterisationTrdZ( axis, nDivs, width,
407  offset, mSolid, divType );
408  break;
409  default:
410  ErrorInAxis( axis, mSolid );
411  break;
412  }
413  }
414  else if( mSolidType == "G4Para" )
415  {
416  switch( axis )
417  {
418  case kXAxis:
419  fparam = new G4ParameterisationParaX( axis, nDivs, width,
420  offset, mSolid, divType );
421  break;
422  case kYAxis:
423  fparam = new G4ParameterisationParaY( axis, nDivs, width,
424  offset, mSolid, divType );
425  break;
426  case kZAxis:
427  fparam = new G4ParameterisationParaZ( axis, nDivs, width,
428  offset, mSolid, divType );
429  break;
430  default:
431  ErrorInAxis( axis, mSolid );
432  break;
433  }
434  }
435 // else if( mSolidType == "G4Trap" )
436 // {
437 // }
438  else if( mSolidType == "G4Polycone" )
439  {
440  switch( axis )
441  {
442  case kRho:
443  fparam = new G4ParameterisationPolyconeRho( axis, nDivs, width,
444  offset, mSolid, divType );
445  break;
446  case kPhi:
447  fparam = new G4ParameterisationPolyconePhi( axis, nDivs, width,
448  offset, mSolid, divType );
449  break;
450  case kZAxis:
451  fparam = new G4ParameterisationPolyconeZ( axis, nDivs, width,
452  offset, mSolid, divType );
453  break;
454  default:
455  ErrorInAxis( axis, mSolid );
456  break;
457  }
458  }
459  else if( mSolidType == "G4Polyhedra" )
460  {
461  switch( axis )
462  {
463  case kRho:
464  fparam = new G4ParameterisationPolyhedraRho( axis, nDivs, width,
465  offset, mSolid, divType );
466  break;
467  case kPhi:
468  fparam = new G4ParameterisationPolyhedraPhi( axis, nDivs, width,
469  offset, mSolid, divType );
470  break;
471  case kZAxis:
472  fparam = new G4ParameterisationPolyhedraZ( axis, nDivs, width,
473  offset, mSolid, divType );
474  break;
475  default:
476  ErrorInAxis( axis, mSolid );
477  break;
478  }
479  }
480  else
481  {
482  std::ostringstream message;
483  message << "Solid type " << mSolidType << " not supported!" << G4endl
484  << "Divisions for " << mSolidType << " are not implemented.";
485  G4Exception("G4PVDivision::SetParameterisation()", "GeomDiv0001",
486  FatalException, message);
487  }
488 }
489 
490 //--------------------------------------------------------------------------
492 {
493  G4String error = "Trying to divide solid " + solid->GetName()
494  + " of type " + solid->GetEntityType() + " along axis ";
495  switch( axis )
496  {
497  case kXAxis:
498  error += "X.";
499  break;
500  case kYAxis:
501  error += "Y.";
502  break;
503  case kZAxis:
504  error += "Z.";
505  break;
506  case kRho:
507  error += "Rho.";
508  break;
509  case kRadial3D:
510  error += "Radial3D.";
511  break;
512  case kPhi:
513  error += "Phi.";
514  break;
515  default:
516  break;
517  }
518  G4Exception("G4PVDivision::ErrorInAxis()", "GeomDiv0002",
519  FatalException, error);
520 }
521 // The next methods are for specialised repeated volumes
522 // (replicas, parameterised vol.) which are completely regular.
523 // Currently this is not applicable to divisions ( J.A. Nov 2005 )
524 // ----------------------------------------------------------------------
525 // IsRegularRepeatedStructure()
526 //
528 {
529  return false;
530 }
531 
532 // ----------------------------------------------------------------------
533 // IsRegularRepeatedStructure()
534 //
536 {
537  return 0;
538 }
539 // This is for specialised repeated volumes (replicas, parameterised vol.)
Definition: geomdefs.hh:54
G4String GetName() const
G4bool IsParameterised() const
virtual G4bool IsMany() const
virtual G4bool IsReplicated() const
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepRotation G4RotationMatrix
#define width
EAxis GetDivisionAxis() const
virtual ~G4PVDivision()
G4PVDivision(const G4String &pName, G4LogicalVolume *pLogical, G4LogicalVolume *pMother, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset)
Definition: G4PVDivision.cc:47
virtual G4int GetCopyNo() const
virtual G4GeometryType GetEntityType() const =0
int G4int
Definition: G4Types.hh:78
virtual G4VPVParameterisation * GetParameterisation() const
void SetRotation(G4RotationMatrix *)
G4double GetWidth() const
const G4String & GetName() const
virtual void SetCopyNo(G4int CopyNo)
bool G4bool
Definition: G4Types.hh:79
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool IsRegularStructure() const
void SetParameterisation(G4LogicalVolume *motherLogical, const EAxis pAxis, const G4int nReplicas, const G4double width, const G4double offset, DivisionType divType)
G4VDivisionParameterisation * fparam
void ErrorInAxis(EAxis axis, G4VSolid *solid)
G4LogicalVolume * GetLogicalVolume() const
EAxis
Definition: geomdefs.hh:54
virtual void GetReplicationData(EAxis &axis, G4int &nReplicas, G4double &width, G4double &offset, G4bool &consuming) const
G4double fwidth
#define G4endl
Definition: G4ios.hh:61
static PROLOG_HANDLER error
Definition: xmlrole.cc:108
void SetMotherLogical(G4LogicalVolume *pMother)
G4int GetRegularStructureId() const
void CheckAndSetParameters(const EAxis pAxis, const G4int nDivs, const G4double width, const G4double offset, DivisionType divType, const G4LogicalVolume *pMotherLogical)
double G4double
Definition: G4Types.hh:76
Definition: geomdefs.hh:54
void AddDaughter(G4VPhysicalVolume *p)
G4VSolid * GetSolid() const
G4double foffset