G4ReplicatedSlice.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id: G4ReplicatedSlice.cc 69784 2013-05-15 09:16:06Z gcosmo $
00028 //
00029 // --------------------------------------------------------------------
00030 
00031 #include "G4ReplicatedSlice.hh"
00032 #include "G4LogicalVolume.hh"
00033 #include "G4VSolid.hh"
00034 #include "G4ReflectedSolid.hh"
00035 #include "G4ParameterisationBox.hh"
00036 #include "G4ParameterisationTubs.hh"
00037 #include "G4ParameterisationCons.hh"
00038 #include "G4ParameterisationTrd.hh"
00039 #include "G4ParameterisationPara.hh"
00040 #include "G4ParameterisationPolycone.hh"
00041 #include "G4ParameterisationPolyhedra.hh"
00042 
00043 //--------------------------------------------------------------------------
00044 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00045                                            G4LogicalVolume* pLogical,
00046                                            G4LogicalVolume* pMotherLogical,
00047                                      const EAxis pAxis,
00048                                      const G4int nDivs,
00049                                      const G4double width,
00050                                      const G4double half_gap,
00051                                      const G4double offset )
00052   : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00053 {
00054   CheckAndSetParameters(pAxis, nDivs, width, half_gap, offset,
00055                         DivNDIVandWIDTH, pMotherLogical, pLogical);
00056 }
00057 
00058 //--------------------------------------------------------------------------
00059 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00060                                            G4LogicalVolume* pLogical,
00061                                            G4LogicalVolume* pMotherLogical,
00062                                      const EAxis pAxis,
00063                                      const G4int nDivs,
00064                                      const G4double half_gap,
00065                                      const G4double offset )
00066   : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00067 {
00068   CheckAndSetParameters(pAxis, nDivs, 0., half_gap, offset,
00069                         DivNDIV, pMotherLogical, pLogical);
00070 }
00071 
00072 //--------------------------------------------------------------------------
00073 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00074                                            G4LogicalVolume* pLogical,
00075                                            G4LogicalVolume* pMotherLogical,
00076                                      const EAxis pAxis,
00077                                      const G4double width,
00078                                      const G4double half_gap,
00079                                      const G4double offset )
00080   : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00081 {
00082   CheckAndSetParameters(pAxis, 0, width, half_gap, offset,
00083                         DivWIDTH, pMotherLogical, pLogical);
00084 }
00085 
00086 //--------------------------------------------------------------------------
00087 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00088                                            G4LogicalVolume* pLogical,
00089                                            G4VPhysicalVolume* pMotherPhysical,
00090                                      const EAxis pAxis,
00091                                      const G4int nDivs,
00092                                      const G4double width,
00093                                      const G4double half_gap,
00094                                      const G4double offset )
00095   : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00096 {
00097   CheckAndSetParameters(pAxis, nDivs, width, half_gap, offset,
00098       DivNDIVandWIDTH, pMotherPhysical->GetLogicalVolume(), pLogical);
00099 }
00100 
00101 //--------------------------------------------------------------------------
00102 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00103                                            G4LogicalVolume* pLogical,
00104                                            G4VPhysicalVolume* pMotherPhysical,
00105                                      const EAxis pAxis,
00106                                      const G4int nDivs,
00107                                      const G4double half_gap,
00108                                      const G4double offset )
00109   : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00110 {
00111   CheckAndSetParameters(pAxis, nDivs, 0., half_gap, offset,
00112       DivNDIV, pMotherPhysical->GetLogicalVolume(), pLogical);
00113 }
00114 
00115 //--------------------------------------------------------------------------
00116 G4ReplicatedSlice::G4ReplicatedSlice(const G4String& pName,
00117                                            G4LogicalVolume* pLogical,
00118                                            G4VPhysicalVolume* pMotherPhysical,
00119                                      const EAxis pAxis,
00120                                      const G4double width,
00121                                      const G4double half_gap,
00122                                      const G4double offset )
00123   : G4VPhysicalVolume(0,G4ThreeVector(),pName,pLogical,0), fcopyNo(-1)
00124 {
00125   CheckAndSetParameters(pAxis, 0, width, half_gap, offset,
00126       DivWIDTH, pMotherPhysical->GetLogicalVolume(), pLogical);
00127 }
00128 
00129 //--------------------------------------------------------------------------
00130 void
00131 G4ReplicatedSlice::CheckAndSetParameters( const EAxis pAxis,
00132                                           const G4int nDivs,
00133                                           const G4double width,
00134                                           const G4double half_gap,
00135                                           const G4double offset, 
00136                                                 DivisionType divType,
00137                                                 G4LogicalVolume* pMotherLogical,
00138                                           const G4LogicalVolume* pLogical )
00139 {
00140   if(!pMotherLogical)
00141   {
00142     std::ostringstream message;
00143     message << "Invalid setup." << G4endl
00144             << "NULL pointer specified as mother! Volume: " << GetName();
00145     G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00146                 FatalException, message);
00147   }
00148   if(pLogical == pMotherLogical)
00149   {
00150     std::ostringstream message;
00151     message << "Invalid setup." << G4endl
00152             << "Cannot place a volume inside itself! Volume: " << GetName();
00153     G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00154                 FatalException, message);
00155   }
00156 
00157   //----- Check that mother solid is of the same type as
00158   //      daughter solid (otherwise, the corresponding
00159   //      Parameterisation::ComputeDimension() will not be called)
00160   //
00161   G4String msolType = pMotherLogical->GetSolid()->GetEntityType();
00162   G4String dsolType = pLogical->GetSolid()->GetEntityType();
00163   if( msolType != dsolType && ( msolType != "G4Trd" || dsolType != "G4Trap" ) )
00164   {
00165     std::ostringstream message;
00166     message << "Invalid setup." << G4endl
00167             << "Incorrect solid type for division of volume: "
00168             << GetName() << G4endl
00169             << "    It is: " << msolType
00170             << ", while it should be: " << dsolType;
00171     G4Exception("G4ReplicatedSlice::CheckAndSetParameters()",
00172                 "GeomDiv0002", FatalException, message);
00173   }
00174 
00175   pMotherLogical->AddDaughter(this);
00176   SetMotherLogical(pMotherLogical);
00177   SetParameterisation(pMotherLogical, pAxis, nDivs,
00178                       width, half_gap, offset, divType);
00179 
00180   if( divType == DivWIDTH )
00181   {
00182     fnReplicas = fparam->GetNoDiv();
00183   }
00184   else
00185   {
00186     fnReplicas = nDivs;
00187   }
00188   if (fnReplicas < 1 )
00189   {
00190     G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00191                 FatalException, "Illegal number of replicas!");
00192   }
00193   if( divType != DivNDIV)
00194   {
00195     fwidth = fparam->GetWidth();
00196   }
00197   else
00198   {
00199     fwidth = width;
00200   }
00201   if( fwidth < 0 )
00202   {
00203     G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00204                 FatalException, "Width must be positive!");
00205   }
00206   if( fwidth < 2.*half_gap )
00207   {
00208     G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00209                 FatalException, "Half_gap is too large!");
00210   }
00211   
00212   foffset = offset;
00213   fdivAxis = pAxis;
00214 
00216   //
00217   if( pAxis == kRho || pAxis == kRadial3D || pAxis == kPhi )
00218   {
00219     faxis = kZAxis;
00220   }
00221   else
00222   {
00223     faxis = pAxis;
00224   }
00225   
00226   switch (faxis)
00227   {
00228     case kPhi:
00229     case kRho:
00230     case kXAxis:
00231     case kYAxis:
00232     case kZAxis:
00233       break;
00234     default:
00235       G4Exception("G4ReplicatedSlice::CheckAndSetParameters()", "GeomDiv0002",
00236                   FatalException, "Unknown axis of replication.");
00237       break;
00238   }
00239 
00240   // Create rotation matrix: for phi axis it will be changed
00241   // in G4VPVParameterisation::ComputeTransformation, for others
00242   // it will stay the unity
00243   //
00244   G4RotationMatrix *pRMat = new G4RotationMatrix();
00245   SetRotation(pRMat);
00246 }
00247 
00248 //--------------------------------------------------------------------------
00249 G4ReplicatedSlice::~G4ReplicatedSlice()
00250 {
00251   delete GetRotation();
00252 }
00253 
00254 //--------------------------------------------------------------------------
00255 EAxis G4ReplicatedSlice::GetDivisionAxis() const
00256 {
00257   return fdivAxis;
00258 }
00259 
00260 //--------------------------------------------------------------------------
00261 G4bool G4ReplicatedSlice::IsParameterised() const
00262 { 
00263   return true;
00264 }
00265 
00266 //--------------------------------------------------------------------------
00267 G4bool G4ReplicatedSlice::IsMany() const
00268 {
00269   return false; 
00270 }
00271 
00272 //--------------------------------------------------------------------------
00273 G4int G4ReplicatedSlice::GetCopyNo() const
00274 {
00275   return fcopyNo;
00276 }
00277 
00278 //--------------------------------------------------------------------------
00279 void  G4ReplicatedSlice::SetCopyNo(G4int newCopyNo)
00280 {
00281   fcopyNo= newCopyNo;
00282 }
00283 
00284 //--------------------------------------------------------------------------
00285 G4bool G4ReplicatedSlice::IsReplicated() const
00286 {
00287   return true;
00288 }
00289 
00290 //--------------------------------------------------------------------------
00291 G4VPVParameterisation* G4ReplicatedSlice::GetParameterisation() const
00292 {
00293   return fparam;
00294 }
00295 
00296 //--------------------------------------------------------------------------
00297 void G4ReplicatedSlice::GetReplicationData(EAxis& axis,
00298                                            G4int& nDivs,
00299                                            G4double& width,
00300                                            G4double& offset,
00301                                            G4bool& consuming ) const
00302 {
00303   axis=faxis;
00304   nDivs=fnReplicas;
00305   width=fwidth;
00306   offset=foffset;
00307   consuming=false;
00308 }
00309 
00310 
00311 //--------------------------------------------------------------------------
00312 void G4ReplicatedSlice::SetParameterisation( G4LogicalVolume* motherLogical,
00313                                        const EAxis axis,
00314                                        const G4int nDivs,
00315                                        const G4double width,
00316                                        const G4double half_gap,
00317                                        const G4double offset,
00318                                              DivisionType divType )
00319 {
00320   G4VSolid* mSolid = motherLogical->GetSolid();
00321   G4String mSolidType = mSolid->GetEntityType();
00322 
00323   // If the solid is a reflected one, update type to its
00324   // real constituent solid.
00325   // 
00326   if (mSolidType == "G4ReflectedSolid")
00327   {
00328       mSolidType = ((G4ReflectedSolid*)mSolid)->GetConstituentMovedSolid()
00329                  ->GetEntityType(); 
00330   }    
00331 
00332   // Parameterisation type depend of mother solid type and axis of division
00333   //
00334   if( mSolidType == "G4Box" )
00335   {
00336     switch( axis )
00337     {
00338       case kXAxis:
00339         fparam = new G4ParameterisationBoxX( axis, nDivs, width,
00340                                              offset, mSolid, divType );
00341         break;
00342       case kYAxis:
00343         fparam = new G4ParameterisationBoxY( axis, nDivs, width,
00344                                              offset, mSolid, divType );
00345         break;
00346       case kZAxis:
00347         fparam = new G4ParameterisationBoxZ( axis, nDivs, width,
00348                                              offset, mSolid, divType );
00349         break;
00350       default:
00351         ErrorInAxis( axis, mSolid );
00352         break;
00353     }
00354   }
00355   else if( mSolidType == "G4Tubs" )
00356   {
00357     switch( axis )
00358     {
00359       case kRho:
00360         fparam = new G4ParameterisationTubsRho( axis, nDivs, width,
00361                                                 offset, mSolid, divType );
00362         break;
00363       case kPhi:
00364         fparam = new G4ParameterisationTubsPhi( axis, nDivs, width,
00365                                                 offset, mSolid, divType );
00366         break;
00367       case kZAxis:
00368         fparam = new G4ParameterisationTubsZ( axis, nDivs, width,
00369                                               offset, mSolid, divType );
00370         break;
00371       default:
00372         ErrorInAxis( axis, mSolid );
00373         break;
00374     }
00375   }
00376   else if( mSolidType == "G4Cons" )
00377   {
00378     switch( axis )
00379     {
00380       case kRho:
00381         fparam = new G4ParameterisationConsRho( axis, nDivs, width,
00382                                                 offset, mSolid, divType );
00383         break;
00384       case kPhi:
00385         fparam = new G4ParameterisationConsPhi( axis, nDivs, width,
00386                                                 offset, mSolid, divType );
00387         break;
00388       case kZAxis:
00389         fparam = new G4ParameterisationConsZ( axis, nDivs, width,
00390                                               offset, mSolid, divType );
00391         break;
00392       default:
00393         ErrorInAxis( axis, mSolid );
00394         break;
00395     }
00396   }
00397   else if( mSolidType == "G4Trd" )
00398   { 
00399     switch( axis )
00400     {
00401       case kXAxis:
00402         fparam = new G4ParameterisationTrdX( axis, nDivs, width,
00403                                              offset, mSolid, divType );
00404         break;
00405       case kYAxis:
00406         fparam = new G4ParameterisationTrdY( axis, nDivs, width,
00407                                              offset, mSolid, divType );
00408         break;
00409       case kZAxis:
00410         fparam = new G4ParameterisationTrdZ( axis, nDivs, width,
00411                                              offset, mSolid, divType );
00412         break;
00413       default:
00414         ErrorInAxis( axis, mSolid );
00415         break;
00416     }
00417   }
00418   else if( mSolidType == "G4Para" )
00419   { 
00420     switch( axis )
00421     {
00422       case kXAxis:
00423         fparam = new G4ParameterisationParaX( axis, nDivs, width,
00424                                              offset, mSolid, divType );
00425         break;
00426       case kYAxis:
00427         fparam = new G4ParameterisationParaY( axis, nDivs, width,
00428                                              offset, mSolid, divType );
00429         break;
00430       case kZAxis:
00431         fparam = new G4ParameterisationParaZ( axis, nDivs, width,
00432                                              offset, mSolid, divType );
00433         break;
00434       default:
00435         ErrorInAxis( axis, mSolid );
00436         break;
00437     }
00438   }
00439 //  else if( mSolidType == "G4Trap" )
00440 //  {
00441 //  }
00442 //  else if( mSolidType == "G4Polycone" )
00443 //  {
00444 //    switch( axis )
00445 //    {
00446 //      case kRho:
00447 //        fparam = new G4ParameterisationPolyconeRho( axis, nDivs, width,
00448 //                                                    offset, mSolid, divType );
00449 //        break;
00450 //      case kPhi:
00451 //        fparam = new G4ParameterisationPolyconePhi( axis, nDivs, width,
00452 //                                                    offset, mSolid, divType );
00453 //        break;
00454 //      case kZAxis:
00455 //        fparam = new G4ParameterisationPolyconeZ( axis, nDivs, width,
00456 //                                                  offset, mSolid, divType );
00457 //        break;
00458 //      default:
00459 //        ErrorInAxis( axis, mSolid );
00460 //      break;
00461 //    }
00462 //  }
00463 //  else if( mSolidType == "G4Polyhedra" )
00464 //  {
00465 //    switch( axis )
00466 //    {
00467 //      case kRho:
00468 //        fparam = new G4ParameterisationPolyhedraRho( axis, nDivs, width,
00469 //                                                    offset, mSolid, divType );
00470 //        break;
00471 //      case kPhi:
00472 //        fparam = new G4ParameterisationPolyhedraPhi( axis, nDivs, width,
00473 //                                                    offset, mSolid, divType );
00474 //        break;
00475 //      case kZAxis:
00476 //        fparam = new G4ParameterisationPolyhedraZ( axis, nDivs, width,
00477 //                                                  offset, mSolid, divType );
00478 //        break;
00479 //      default:
00480 //        ErrorInAxis( axis, mSolid );
00481 //      break;
00482 //    }
00483 //  }
00484   else
00485   {
00486     std::ostringstream message;
00487     message << "Solid type not supported: " << mSolidType << "." << G4endl
00488             << "Divisions for " << mSolidType << " not implemented.";
00489     G4Exception("G4ReplicatedSlice::SetParameterisation()", "GeomDiv0001",
00490                 FatalException, message);
00491   }
00492 
00493   fparam->SetHalfGap(half_gap);
00494 }
00495 
00496 //--------------------------------------------------------------------------
00497 void G4ReplicatedSlice::ErrorInAxis( EAxis axis, G4VSolid* solid )
00498 {
00499   G4String error = "Trying to divide solid " + solid->GetName()
00500                  + " of type " + solid->GetEntityType() + " along axis ";
00501   switch( axis )
00502   {
00503     case kXAxis:
00504       error += "X.";
00505       break;
00506     case kYAxis:
00507       error += "Y.";
00508       break;
00509     case kZAxis:
00510       error += "Z.";
00511       break;
00512     case kRho:
00513       error += "Rho.";
00514       break;
00515     case kRadial3D:
00516       error += "Radial3D.";
00517       break;
00518     case kPhi:
00519       error += "Phi.";
00520       break;
00521     default:
00522       break;
00523   }
00524   G4Exception("G4ReplicatedSlice::ErrorInAxis()", "GeomDiv0002",
00525               FatalException, error);
00526 }
00527 
00528 // The next methods are for specialised repeated volumes 
00529 //     (replicas, parameterised vol.) which are completely regular.
00530 // Currently this is not applicable to divisions  ( J.A. Nov 2005 )
00531 // ----------------------------------------------------------------------
00532 // IsRegularRepeatedStructure()
00533 //
00534 G4bool G4ReplicatedSlice::IsRegularStructure() const
00535 {
00536   return false;
00537 }           
00538 
00539 // ----------------------------------------------------------------------
00540 // IsRegularRepeatedStructure()
00541 //
00542 G4int G4ReplicatedSlice::GetRegularStructureId() const
00543 {
00544   return 0;  
00545 }           

Generated on Mon May 27 17:49:43 2013 for Geant4 by  doxygen 1.4.7