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

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