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