Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/divisions/src/G4ReplicatedSlice.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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