G4NormalNavigation.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$
00028 //
00029 //
00030 // class G4NormalNavigation Implementation
00031 //
00032 // Author: P.Kent, 1996
00033 //
00034 // --------------------------------------------------------------------
00035 
00036 #include "G4NormalNavigation.hh"
00037 #include "G4AffineTransform.hh"
00038 
00039 // ********************************************************************
00040 // Constructor
00041 // ********************************************************************
00042 //
00043 G4NormalNavigation::G4NormalNavigation()
00044   : fCheck(false)
00045 {
00046   fLogger = new G4NavigationLogger("G4NormalNavigation");
00047 }
00048 
00049 // ********************************************************************
00050 // Destructor
00051 // ********************************************************************
00052 //
00053 G4NormalNavigation::~G4NormalNavigation()
00054 {
00055   delete fLogger;
00056 }
00057 
00058 // ********************************************************************
00059 // ComputeStep
00060 // ********************************************************************
00061 //
00062 G4double
00063 G4NormalNavigation::ComputeStep(const G4ThreeVector &localPoint,
00064                                 const G4ThreeVector &localDirection,
00065                                 const G4double currentProposedStepLength,
00066                                       G4double &newSafety,
00067                                       G4NavigationHistory &history,
00068                                       G4bool &validExitNormal,
00069                                       G4ThreeVector &exitNormal,
00070                                       G4bool &exiting,
00071                                       G4bool &entering,
00072                                       G4VPhysicalVolume *(*pBlockedPhysical),
00073                                       G4int &blockedReplicaNo)
00074 {
00075   G4VPhysicalVolume *motherPhysical, *samplePhysical, *blockedExitedVol=0;
00076   G4LogicalVolume *motherLogical;
00077   G4VSolid *motherSolid;
00078   G4ThreeVector sampleDirection;
00079   G4double ourStep=currentProposedStepLength, motherSafety, ourSafety;
00080   G4int localNoDaughters, sampleNo;
00081 
00082   motherPhysical = history.GetTopVolume();
00083   motherLogical  = motherPhysical->GetLogicalVolume();
00084   motherSolid    = motherLogical->GetSolid();
00085 
00086   // Compute mother safety
00087   //
00088   motherSafety = motherSolid->DistanceToOut(localPoint);
00089   ourSafety = motherSafety; // Working isotropic safety
00090   
00091 #ifdef G4VERBOSE
00092   if ( fCheck )
00093   {
00094     fLogger->PreComputeStepLog(motherPhysical, motherSafety, localPoint);
00095   }
00096 #endif
00097 
00098   //
00099   // Compute daughter safeties & intersections
00100   //
00101 
00102   // Exiting normal optimisation
00103   //
00104   if ( exiting&&validExitNormal )
00105   {
00106     if ( localDirection.dot(exitNormal)>=kMinExitingNormalCosine )
00107     {
00108       // Block exited daughter volume
00109       //
00110       blockedExitedVol =* pBlockedPhysical;
00111       ourSafety = 0;
00112     }
00113   }
00114   exiting  = false;
00115   entering = false;
00116 
00117   localNoDaughters = motherLogical->GetNoDaughters();
00118   for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo--)
00119   {
00120     samplePhysical = motherLogical->GetDaughter(sampleNo);
00121     if ( samplePhysical!=blockedExitedVol )
00122     {
00123       G4AffineTransform sampleTf(samplePhysical->GetRotation(),
00124                                  samplePhysical->GetTranslation());
00125       sampleTf.Invert();
00126       const G4ThreeVector samplePoint =
00127               sampleTf.TransformPoint(localPoint);
00128       const G4VSolid *sampleSolid =
00129               samplePhysical->GetLogicalVolume()->GetSolid();
00130       const G4double sampleSafety =
00131               sampleSolid->DistanceToIn(samplePoint);
00132 #ifdef G4VERBOSE
00133       if( fCheck )
00134       {
00135         fLogger->PrintDaughterLog(sampleSolid, samplePoint, sampleSafety, 0);
00136       }
00137 #endif
00138       if ( sampleSafety<ourSafety )
00139       {
00140         ourSafety=sampleSafety;
00141       }
00142       if ( sampleSafety<=ourStep )
00143       {
00144         sampleDirection = sampleTf.TransformAxis(localDirection);
00145         const G4double sampleStep =
00146                 sampleSolid->DistanceToIn(samplePoint,sampleDirection);
00147 
00148 #ifdef G4VERBOSE
00149         if( fCheck )
00150         {
00151           fLogger->PrintDaughterLog(sampleSolid, samplePoint,
00152                                     sampleSafety, sampleStep);
00153         }
00154 #endif
00155         if ( sampleStep<=ourStep )
00156         {
00157           ourStep  = sampleStep;
00158           entering = true;
00159           exiting  = false;
00160           *pBlockedPhysical = samplePhysical;
00161           blockedReplicaNo  = -1;
00162 #ifdef G4VERBOSE
00163           if( fCheck )
00164           {
00165             fLogger->AlongComputeStepLog(sampleSolid, samplePoint,
00166               sampleDirection, localDirection, sampleSafety, sampleStep);
00167           }
00168 #endif
00169         }
00170       }
00171     }
00172   }
00173   if ( currentProposedStepLength<ourSafety )
00174   {
00175     // Guaranteed physics limited
00176     //
00177     entering = false;
00178     exiting  = false;
00179     *pBlockedPhysical = 0;
00180     ourStep = kInfinity;
00181   }
00182   else
00183   {
00184     // Compute mother intersection if required
00185     //
00186     if ( motherSafety<=ourStep )
00187     {
00188       G4double motherStep = motherSolid->DistanceToOut(localPoint,
00189                                                        localDirection,
00190                                                        true,
00191                                                        &validExitNormal,
00192                                                        &exitNormal);
00193 #ifdef G4VERBOSE
00194       if ( fCheck )
00195       {
00196         fLogger->PostComputeStepLog(motherSolid, localPoint, localDirection,
00197                                     motherStep, motherSafety);
00198       }
00199 #endif
00200 
00201       if ( motherStep<=ourStep )
00202       {
00203         ourStep  = motherStep;
00204         exiting  = true;
00205         entering = false;
00206         if ( validExitNormal )
00207         {
00208           const G4RotationMatrix *rot = motherPhysical->GetRotation();
00209           if (rot)
00210           {
00211             exitNormal *= rot->inverse();
00212           }
00213         }
00214       }
00215       else
00216       {
00217         validExitNormal = false;
00218       }
00219     }
00220   }
00221   newSafety = ourSafety;
00222   return ourStep;
00223 }
00224 
00225 // ********************************************************************
00226 // ComputeSafety
00227 // ********************************************************************
00228 //
00229 G4double G4NormalNavigation::ComputeSafety(const G4ThreeVector &localPoint,
00230                                            const G4NavigationHistory &history,
00231                                            const G4double)
00232 {
00233   G4VPhysicalVolume *motherPhysical, *samplePhysical;
00234   G4LogicalVolume *motherLogical;
00235   G4VSolid *motherSolid;
00236   G4double motherSafety, ourSafety;
00237   G4int localNoDaughters, sampleNo;
00238 
00239   motherPhysical = history.GetTopVolume();
00240   motherLogical  = motherPhysical->GetLogicalVolume();
00241   motherSolid    = motherLogical->GetSolid();
00242 
00243   // Compute mother safety
00244   //
00245   motherSafety = motherSolid->DistanceToOut(localPoint);
00246   ourSafety = motherSafety; // Working isotropic safety
00247 
00248 #ifdef G4VERBOSE
00249   if( fCheck )
00250   {
00251     fLogger->ComputeSafetyLog(motherSolid, localPoint, motherSafety, true);
00252   }
00253 #endif
00254 
00255   // Compute daughter safeties 
00256   //
00257   localNoDaughters = motherLogical->GetNoDaughters();
00258   for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
00259   {
00260     samplePhysical = motherLogical->GetDaughter(sampleNo);
00261     G4AffineTransform sampleTf(samplePhysical->GetRotation(),
00262                                samplePhysical->GetTranslation());
00263     sampleTf.Invert();
00264     const G4ThreeVector samplePoint =
00265             sampleTf.TransformPoint(localPoint);
00266     const G4VSolid *sampleSolid =
00267             samplePhysical->GetLogicalVolume()->GetSolid();
00268     const G4double sampleSafety =
00269             sampleSolid->DistanceToIn(samplePoint);
00270     if ( sampleSafety<ourSafety )
00271     {
00272       ourSafety = sampleSafety;
00273     }
00274 #ifdef G4VERBOSE
00275     if(fCheck)
00276     {
00277       fLogger->ComputeSafetyLog(sampleSolid, samplePoint, sampleSafety, false);
00278     }
00279 #endif
00280   }
00281   return ourSafety;
00282 }

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