ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ReplicatedSlice.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4ReplicatedSlice.cc
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 // G4ReplicatedSlice implementation
27 //
28 // Author: M.Asai (SLAC), 20/04/2010 - Extended from G4PVDivision
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(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
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(nullptr,G4ThreeVector(),pName,pLogical,nullptr)
124 {
125  CheckAndSetParameters(pAxis, 0, width, half_gap, offset,
126  DivWIDTH, pMotherPhysical->GetLogicalVolume(), pLogical);
127 }
128 
129 //--------------------------------------------------------------------------
130 void
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 == nullptr)
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 fnReplicas;
294 }
295 
296 //--------------------------------------------------------------------------
298 {
299  return fparam;
300 }
301 
302 //--------------------------------------------------------------------------
304 {
305  return kParameterised;
306 }
307 
308 //--------------------------------------------------------------------------
310  G4int& nDivs,
311  G4double& width,
312  G4double& offset,
313  G4bool& consuming ) const
314 {
315  axis = faxis;
316  nDivs = fnReplicas;
317  width = fwidth;
318  offset = foffset;
319  consuming = false;
320 }
321 
322 
323 //--------------------------------------------------------------------------
325  const EAxis axis,
326  const G4int nDivs,
327  const G4double width,
328  const G4double half_gap,
329  const G4double offset,
330  DivisionType divType )
331 {
332  G4VSolid* mSolid = motherLogical->GetSolid();
333  G4String mSolidType = mSolid->GetEntityType();
334  fparam = nullptr;
335 
336  // If the solid is a reflected one, update type to its
337  // real constituent solid.
338  //
339  if (mSolidType == "G4ReflectedSolid")
340  {
341  mSolidType = ((G4ReflectedSolid*)mSolid)->GetConstituentMovedSolid()
342  ->GetEntityType();
343  }
344 
345  // Parameterisation type depend of mother solid type and axis of division
346  //
347  if( mSolidType == "G4Box" )
348  {
349  switch( axis )
350  {
351  case kXAxis:
352  fparam = new G4ParameterisationBoxX( axis, nDivs, width,
353  offset, mSolid, divType );
354  break;
355  case kYAxis:
356  fparam = new G4ParameterisationBoxY( axis, nDivs, width,
357  offset, mSolid, divType );
358  break;
359  case kZAxis:
360  fparam = new G4ParameterisationBoxZ( axis, nDivs, width,
361  offset, mSolid, divType );
362  break;
363  default:
364  ErrorInAxis( axis, mSolid );
365  break;
366  }
367  }
368  else if( mSolidType == "G4Tubs" )
369  {
370  switch( axis )
371  {
372  case kRho:
373  fparam = new G4ParameterisationTubsRho( axis, nDivs, width,
374  offset, mSolid, divType );
375  break;
376  case kPhi:
377  fparam = new G4ParameterisationTubsPhi( axis, nDivs, width,
378  offset, mSolid, divType );
379  break;
380  case kZAxis:
381  fparam = new G4ParameterisationTubsZ( axis, nDivs, width,
382  offset, mSolid, divType );
383  break;
384  default:
385  ErrorInAxis( axis, mSolid );
386  break;
387  }
388  }
389  else if( mSolidType == "G4Cons" )
390  {
391  switch( axis )
392  {
393  case kRho:
394  fparam = new G4ParameterisationConsRho( axis, nDivs, width,
395  offset, mSolid, divType );
396  break;
397  case kPhi:
398  fparam = new G4ParameterisationConsPhi( axis, nDivs, width,
399  offset, mSolid, divType );
400  break;
401  case kZAxis:
402  fparam = new G4ParameterisationConsZ( axis, nDivs, width,
403  offset, mSolid, divType );
404  break;
405  default:
406  ErrorInAxis( axis, mSolid );
407  break;
408  }
409  }
410  else if( mSolidType == "G4Trd" )
411  {
412  switch( axis )
413  {
414  case kXAxis:
415  fparam = new G4ParameterisationTrdX( axis, nDivs, width,
416  offset, mSolid, divType );
417  break;
418  case kYAxis:
419  fparam = new G4ParameterisationTrdY( axis, nDivs, width,
420  offset, mSolid, divType );
421  break;
422  case kZAxis:
423  fparam = new G4ParameterisationTrdZ( axis, nDivs, width,
424  offset, mSolid, divType );
425  break;
426  default:
427  ErrorInAxis( axis, mSolid );
428  break;
429  }
430  }
431  else if( mSolidType == "G4Para" )
432  {
433  switch( axis )
434  {
435  case kXAxis:
436  fparam = new G4ParameterisationParaX( axis, nDivs, width,
437  offset, mSolid, divType );
438  break;
439  case kYAxis:
440  fparam = new G4ParameterisationParaY( axis, nDivs, width,
441  offset, mSolid, divType );
442  break;
443  case kZAxis:
444  fparam = new G4ParameterisationParaZ( axis, nDivs, width,
445  offset, mSolid, divType );
446  break;
447  default:
448  ErrorInAxis( axis, mSolid );
449  break;
450  }
451  }
452 // else if( mSolidType == "G4Trap" )
453 // {
454 // }
455 // else if( mSolidType == "G4Polycone" )
456 // {
457 // switch( axis )
458 // {
459 // case kRho:
460 // fparam = new G4ParameterisationPolyconeRho( axis, nDivs, width,
461 // offset, mSolid, divType );
462 // break;
463 // case kPhi:
464 // fparam = new G4ParameterisationPolyconePhi( axis, nDivs, width,
465 // offset, mSolid, divType );
466 // break;
467 // case kZAxis:
468 // fparam = new G4ParameterisationPolyconeZ( axis, nDivs, width,
469 // offset, mSolid, divType );
470 // break;
471 // default:
472 // ErrorInAxis( axis, mSolid );
473 // break;
474 // }
475 // }
476 // else if( mSolidType == "G4Polyhedra" )
477 // {
478 // switch( axis )
479 // {
480 // case kRho:
481 // fparam = new G4ParameterisationPolyhedraRho( axis, nDivs, width,
482 // offset, mSolid, divType );
483 // break;
484 // case kPhi:
485 // fparam = new G4ParameterisationPolyhedraPhi( axis, nDivs, width,
486 // offset, mSolid, divType );
487 // break;
488 // case kZAxis:
489 // fparam = new G4ParameterisationPolyhedraZ( axis, nDivs, width,
490 // offset, mSolid, divType );
491 // break;
492 // default:
493 // ErrorInAxis( axis, mSolid );
494 // break;
495 // }
496 // }
497  else
498  {
499  std::ostringstream message;
500  message << "Solid type not supported: " << mSolidType << "." << G4endl
501  << "Divisions for " << mSolidType << " not implemented.";
502  G4Exception("G4ReplicatedSlice::SetParameterisation()", "GeomDiv0001",
503  FatalException, message);
504  }
505 
506  fparam->SetHalfGap(half_gap);
507 }
508 
509 //--------------------------------------------------------------------------
511 {
512  G4String error = "Trying to divide solid " + solid->GetName()
513  + " of type " + solid->GetEntityType() + " along axis ";
514  switch( axis )
515  {
516  case kXAxis:
517  error += "X.";
518  break;
519  case kYAxis:
520  error += "Y.";
521  break;
522  case kZAxis:
523  error += "Z.";
524  break;
525  case kRho:
526  error += "Rho.";
527  break;
528  case kRadial3D:
529  error += "Radial3D.";
530  break;
531  case kPhi:
532  error += "Phi.";
533  break;
534  default:
535  break;
536  }
537  G4Exception("G4ReplicatedSlice::ErrorInAxis()", "GeomDiv0002",
538  FatalException, error);
539 }
540 
541 // The next methods are for specialised repeated volumes
542 // (replicas, parameterised vol.) which are completely regular.
543 // Currently this is not applicable to divisions ( J.A. Nov 2005 )
544 
545 // ----------------------------------------------------------------------
546 // IsRegularStructure()
547 //
549 {
550  return false;
551 }
552 
553 // ----------------------------------------------------------------------
554 // GetRegularStructureId()
555 //
557 {
558  return 0;
559 }