00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "G4NormalNavigation.hh"
00037 #include "G4AffineTransform.hh"
00038
00039
00040
00041
00042
00043 G4NormalNavigation::G4NormalNavigation()
00044 : fCheck(false)
00045 {
00046 fLogger = new G4NavigationLogger("G4NormalNavigation");
00047 }
00048
00049
00050
00051
00052
00053 G4NormalNavigation::~G4NormalNavigation()
00054 {
00055 delete fLogger;
00056 }
00057
00058
00059
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
00087
00088 motherSafety = motherSolid->DistanceToOut(localPoint);
00089 ourSafety = motherSafety;
00090
00091 #ifdef G4VERBOSE
00092 if ( fCheck )
00093 {
00094 fLogger->PreComputeStepLog(motherPhysical, motherSafety, localPoint);
00095 }
00096 #endif
00097
00098
00099
00100
00101
00102
00103
00104 if ( exiting&&validExitNormal )
00105 {
00106 if ( localDirection.dot(exitNormal)>=kMinExitingNormalCosine )
00107 {
00108
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
00176
00177 entering = false;
00178 exiting = false;
00179 *pBlockedPhysical = 0;
00180 ourStep = kInfinity;
00181 }
00182 else
00183 {
00184
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
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
00244
00245 motherSafety = motherSolid->DistanceToOut(localPoint);
00246 ourSafety = motherSafety;
00247
00248 #ifdef G4VERBOSE
00249 if( fCheck )
00250 {
00251 fLogger->ComputeSafetyLog(motherSolid, localPoint, motherSafety, true);
00252 }
00253 #endif
00254
00255
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 }