#include <G4ReplicaNavigation.hh>
Public Member Functions | |
G4ReplicaNavigation () | |
~G4ReplicaNavigation () | |
G4bool | LevelLocate (G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint) |
G4double | ComputeStep (const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4bool &calculatedExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) |
G4double | ComputeSafety (const G4ThreeVector &globalPoint, const G4ThreeVector &localPoint, G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX) |
EInside | BackLocate (G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool ¬KnownInside) const |
void | ComputeTransformation (const G4int replicaNo, G4VPhysicalVolume *pVol, G4ThreeVector &point) const |
void | ComputeTransformation (const G4int replicaNo, G4VPhysicalVolume *pVol) const |
EInside | Inside (const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const |
G4double | DistanceToOut (const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint) const |
G4double | DistanceToOut (const G4VPhysicalVolume *pVol, const G4int replicaNo, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4ExitNormal &candidateNormal) const |
G4int | GetVerboseLevel () const |
void | SetVerboseLevel (G4int level) |
void | CheckMode (G4bool mode) |
Definition at line 82 of file G4ReplicaNavigation.hh.
G4ReplicaNavigation::G4ReplicaNavigation | ( | ) |
Definition at line 48 of file G4ReplicaNavigation.cc.
References G4GeometryTolerance::GetAngularTolerance(), G4GeometryTolerance::GetInstance(), G4GeometryTolerance::GetRadialTolerance(), and G4GeometryTolerance::GetSurfaceTolerance().
00049 : fCheck(false), fVerbose(0) 00050 { 00051 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); 00052 kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance(); 00053 kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance(); 00054 }
G4ReplicaNavigation::~G4ReplicaNavigation | ( | ) |
EInside G4ReplicaNavigation::BackLocate | ( | G4NavigationHistory & | history, | |
const G4ThreeVector & | globalPoint, | |||
G4ThreeVector & | localPoint, | |||
const G4bool & | exiting, | |||
G4bool & | notKnownInside | |||
) | const |
Definition at line 1229 of file G4ReplicaNavigation.cc.
References G4NavigationHistory::BackLevel(), FatalException, G4Exception(), G4NavigationHistory::GetDepth(), G4VPhysicalVolume::GetLogicalVolume(), G4NavigationHistory::GetReplicaNo(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTransform(), G4NavigationHistory::GetVolume(), G4NavigationHistory::GetVolumeType(), Inside(), G4VSolid::Inside(), kInside, kOutside, kReplica, kSurface, and G4AffineTransform::TransformPoint().
Referenced by G4Navigator::LocateGlobalPointAndSetup(), and G4ITNavigator::LocateGlobalPointAndSetup().
01234 { 01235 G4VPhysicalVolume *pNRMother=0; 01236 G4VSolid *motherSolid; 01237 G4ThreeVector repPoint, goodPoint; 01238 G4int mdepth, depth, cdepth; 01239 EInside insideCode; 01240 01241 cdepth = history.GetDepth(); 01242 01243 // Find non replicated mother 01244 // 01245 for ( mdepth=cdepth-1; mdepth>=0; mdepth-- ) 01246 { 01247 if ( history.GetVolumeType(mdepth)!=kReplica ) 01248 { 01249 pNRMother = history.GetVolume(mdepth); 01250 break; 01251 } 01252 } 01253 01254 if( pNRMother==0 ) 01255 { 01256 // All the tree of mother volumes were Replicas. 01257 // This is an error, as the World volume must be a Placement 01258 // 01259 G4Exception("G4ReplicaNavigation::BackLocate()", "GeomNav0002", 01260 FatalException, "The World volume must be a Placement!"); 01261 return kInside; 01262 } 01263 01264 motherSolid = pNRMother->GetLogicalVolume()->GetSolid(); 01265 goodPoint = history.GetTransform(mdepth).TransformPoint(globalPoint); 01266 insideCode = motherSolid->Inside(goodPoint); 01267 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) ) 01268 { 01269 // Outside mother -> back up to mother level 01270 // Locate.. in Navigator will back up one more level 01271 // localPoint not required 01272 // 01273 history.BackLevel(cdepth-mdepth); 01274 // localPoint = goodPoint; 01275 } 01276 else 01277 { 01278 notKnownInside = false; 01279 01280 // Still within replications 01281 // Check down: if on outside stop at this level 01282 // 01283 for ( depth=mdepth+1; depth<cdepth; depth++) 01284 { 01285 repPoint = history.GetTransform(depth).TransformPoint(globalPoint); 01286 insideCode = Inside(history.GetVolume(depth), 01287 history.GetReplicaNo(depth), 01288 repPoint); 01289 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) ) 01290 { 01291 localPoint = goodPoint; 01292 history.BackLevel(cdepth-depth); 01293 return insideCode; 01294 } 01295 else 01296 { 01297 goodPoint = repPoint; 01298 } 01299 } 01300 localPoint = history.GetTransform(depth).TransformPoint(globalPoint); 01301 insideCode = Inside(history.GetVolume(depth), 01302 history.GetReplicaNo(depth), 01303 localPoint); 01304 // If outside level, set localPoint = coordinates in reference system 01305 // of *previous* level - location code in navigator will back up one 01306 // level [And also manage blocking] 01307 // 01308 if ( (insideCode==kOutside)||((insideCode==kSurface)&&exiting) ) 01309 { 01310 localPoint = goodPoint; 01311 } 01312 } 01313 return insideCode; 01314 }
void G4ReplicaNavigation::CheckMode | ( | G4bool | mode | ) | [inline] |
Definition at line 219 of file G4ReplicaNavigation.icc.
Referenced by G4Navigator::CheckMode(), and G4ITNavigator::CheckMode().
G4double G4ReplicaNavigation::ComputeSafety | ( | const G4ThreeVector & | globalPoint, | |
const G4ThreeVector & | localPoint, | |||
G4NavigationHistory & | history, | |||
const G4double | pProposedMaxLength = DBL_MAX | |||
) |
Definition at line 1142 of file G4ReplicaNavigation.cc.
References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), DistanceToOut(), G4LogicalVolume::GetDaughter(), G4NavigationHistory::GetDepth(), G4VPhysicalVolume::GetLogicalVolume(), G4LogicalVolume::GetNoDaughters(), G4NavigationHistory::GetReplicaNo(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopReplicaNo(), G4NavigationHistory::GetTopVolume(), G4NavigationHistory::GetTransform(), G4VPhysicalVolume::GetTranslation(), G4NavigationHistory::GetVolume(), G4NavigationHistory::GetVolumeType(), kReplica, and G4AffineTransform::TransformPoint().
Referenced by G4Navigator::ComputeSafety(), and G4ITNavigator::ComputeSafety().
01146 { 01147 G4VPhysicalVolume *repPhysical, *motherPhysical; 01148 G4VPhysicalVolume *samplePhysical, *blockedExitedVol=0; 01149 G4LogicalVolume *repLogical; 01150 G4VSolid *motherSolid; 01151 G4ThreeVector repPoint; 01152 G4double ourSafety=kInfinity; 01153 G4double sampleSafety; 01154 G4int localNoDaughters, sampleNo; 01155 G4int depth; 01156 01157 repPhysical = history.GetTopVolume(); 01158 repLogical = repPhysical->GetLogicalVolume(); 01159 01160 // 01161 // Compute intersection with replica boundaries & replica safety 01162 // 01163 01164 sampleSafety = DistanceToOut(history.GetTopVolume(), 01165 history.GetTopReplicaNo(), 01166 localPoint); 01167 if ( sampleSafety<ourSafety ) 01168 { 01169 ourSafety = sampleSafety; 01170 } 01171 01172 depth = history.GetDepth()-1; 01173 while ( history.GetVolumeType(depth)==kReplica ) 01174 { 01175 repPoint = history.GetTransform(depth).TransformPoint(globalPoint); 01176 sampleSafety = DistanceToOut(history.GetVolume(depth), 01177 history.GetReplicaNo(depth), 01178 repPoint); 01179 if ( sampleSafety<ourSafety ) 01180 { 01181 ourSafety = sampleSafety; 01182 } 01183 depth--; 01184 } 01185 01186 // Compute mother safety & intersection 01187 // 01188 repPoint = history.GetTransform(depth).TransformPoint(globalPoint); 01189 motherPhysical = history.GetVolume(depth); 01190 motherSolid = motherPhysical->GetLogicalVolume()->GetSolid(); 01191 sampleSafety = motherSolid->DistanceToOut(repPoint); 01192 01193 if ( sampleSafety<ourSafety ) 01194 { 01195 ourSafety = sampleSafety; 01196 } 01197 01198 // Compute daughter safeties & intersections 01199 // 01200 localNoDaughters = repLogical->GetNoDaughters(); 01201 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- ) 01202 { 01203 samplePhysical = repLogical->GetDaughter(sampleNo); 01204 if ( samplePhysical!=blockedExitedVol ) 01205 { 01206 G4AffineTransform sampleTf(samplePhysical->GetRotation(), 01207 samplePhysical->GetTranslation()); 01208 sampleTf.Invert(); 01209 const G4ThreeVector samplePoint = 01210 sampleTf.TransformPoint(localPoint); 01211 const G4VSolid *sampleSolid = 01212 samplePhysical->GetLogicalVolume()->GetSolid(); 01213 const G4double sampleSafetyDistance = 01214 sampleSolid->DistanceToIn(samplePoint); 01215 if ( sampleSafetyDistance<ourSafety ) 01216 { 01217 ourSafety = sampleSafetyDistance; 01218 } 01219 } 01220 } 01221 return ourSafety; 01222 }
G4double G4ReplicaNavigation::ComputeStep | ( | const G4ThreeVector & | globalPoint, | |
const G4ThreeVector & | globalDirection, | |||
const G4ThreeVector & | localPoint, | |||
const G4ThreeVector & | localDirection, | |||
const G4double | currentProposedStepLength, | |||
G4double & | newSafety, | |||
G4NavigationHistory & | history, | |||
G4bool & | validExitNormal, | |||
G4bool & | calculatedExitNormal, | |||
G4ThreeVector & | exitNormal, | |||
G4bool & | exiting, | |||
G4bool & | entering, | |||
G4VPhysicalVolume ** | pBlockedPhysical, | |||
G4int & | blockedReplicaNo | |||
) |
Definition at line 740 of file G4ReplicaNavigation.cc.
References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), DistanceToOut(), G4VSolid::DumpInfo(), G4ExitNormal::exitNormal, FatalException, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4NavigationHistory::GetDepth(), G4VPhysicalVolume::GetLogicalVolume(), G4VSolid::GetName(), G4VPhysicalVolume::GetName(), G4LogicalVolume::GetNoDaughters(), G4NavigationHistory::GetReplicaNo(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopReplicaNo(), G4NavigationHistory::GetTopTransform(), G4NavigationHistory::GetTopVolume(), G4NavigationHistory::GetTransform(), G4VPhysicalVolume::GetTranslation(), G4NavigationHistory::GetVolume(), G4NavigationHistory::GetVolumeType(), G4VSolid::Inside(), G4AffineTransform::Inverse(), JustWarning, kInside, G4ExitNormal::kMother, kOutside, kReplica, kSurface, G4VSolid::SurfaceNormal(), G4AffineTransform::TransformAxis(), and G4AffineTransform::TransformPoint().
Referenced by G4Navigator::ComputeStep(), and G4ITNavigator::ComputeStep().
00755 { 00756 G4VPhysicalVolume *repPhysical, *motherPhysical; 00757 G4VPhysicalVolume *samplePhysical, *blockedExitedVol=0; 00758 G4LogicalVolume *repLogical; 00759 G4VSolid *motherSolid; 00760 G4ThreeVector repPoint, repDirection, sampleDirection; 00761 G4double ourStep=currentProposedStepLength; 00762 G4double ourSafety=kInfinity; 00763 G4double sampleStep, sampleSafety, motherStep, motherSafety; 00764 G4int localNoDaughters, sampleNo; 00765 G4int depth; 00766 G4ExitNormal exitNormalStc; 00767 // G4int depthDeterminingStep= -1; // Useful only for debugging - for now 00768 00769 calculatedExitNormal= false; 00770 00771 // Exiting normal optimisation 00772 // 00773 if ( exiting&&validExitNormal ) 00774 { 00775 if ( localDirection.dot(exitNormalVector)>=kMinExitingNormalCosine ) 00776 { 00777 // Block exited daughter volume 00778 // 00779 blockedExitedVol = *pBlockedPhysical; 00780 ourSafety = 0; 00781 } 00782 } 00783 exiting = false; 00784 entering = false; 00785 00786 repPhysical = history.GetTopVolume(); 00787 repLogical = repPhysical->GetLogicalVolume(); 00788 00789 // 00790 // Compute intersection with replica boundaries & replica safety 00791 // 00792 00793 sampleSafety = DistanceToOut(repPhysical, 00794 history.GetTopReplicaNo(), 00795 localPoint); 00796 G4ExitNormal normalOutStc; 00797 const G4int topDepth= history.GetDepth(); 00798 00799 if ( sampleSafety<ourSafety ) 00800 { 00801 ourSafety = sampleSafety; 00802 } 00803 if ( sampleSafety<ourStep ) 00804 { 00805 00806 sampleStep = DistanceToOut(repPhysical, 00807 history.GetTopReplicaNo(), 00808 localPoint, 00809 localDirection, 00810 normalOutStc); 00811 if ( sampleStep<ourStep ) 00812 { 00813 ourStep = sampleStep; 00814 exiting = true; 00815 validExitNormal = normalOutStc.validConvex; // false; -> Old,Conservative 00816 00817 exitNormalStc= normalOutStc; 00818 exitNormalStc.exitNormal= history.GetTopTransform().Inverse(). 00819 TransformAxis(normalOutStc.exitNormal); 00820 calculatedExitNormal= true; 00821 } 00822 } 00823 const G4int secondDepth= topDepth; 00824 depth = secondDepth; 00825 00826 while ( history.GetVolumeType(depth)==kReplica ) 00827 { 00828 const G4AffineTransform& GlobalToLocal= history.GetTransform(depth); 00829 repPoint = GlobalToLocal.TransformPoint(globalPoint); 00830 // repPoint = history.GetTransform(depth).TransformPoint(globalPoint); 00831 00832 sampleSafety = DistanceToOut(history.GetVolume(depth), 00833 history.GetReplicaNo(depth), 00834 repPoint); 00835 if ( sampleSafety < ourSafety ) 00836 { 00837 ourSafety = sampleSafety; 00838 } 00839 if ( sampleSafety < ourStep ) 00840 { 00841 G4ThreeVector newLocalDirection = GlobalToLocal.TransformAxis(globalDirection); 00842 sampleStep = DistanceToOut(history.GetVolume(depth), 00843 history.GetReplicaNo(depth), 00844 repPoint, 00845 newLocalDirection, 00846 normalOutStc); 00847 if ( sampleStep < ourStep ) 00848 { 00849 ourStep = sampleStep; 00850 exiting = true; 00851 00852 // As step is limited by this level, must set Exit Normal 00853 // 00854 G4ThreeVector localExitNorm= normalOutStc.exitNormal; 00855 G4ThreeVector globalExitNorm= 00856 GlobalToLocal.Inverse().TransformAxis(localExitNorm); 00857 00858 exitNormalStc= normalOutStc; // Normal, convex, calculated, side 00859 exitNormalStc.exitNormal= globalExitNorm; 00860 calculatedExitNormal= true; 00861 } 00862 } 00863 depth--; 00864 } 00865 00866 // Compute mother safety & intersection 00867 // 00868 G4ThreeVector exitVectorMother; 00869 G4bool exitConvex= false; // Value obtained in DistanceToOut(p,v) call 00870 G4ExitNormal motherNormalStc; 00871 00872 repPoint = history.GetTransform(depth).TransformPoint(globalPoint); 00873 motherPhysical = history.GetVolume(depth); 00874 motherSolid = motherPhysical->GetLogicalVolume()->GetSolid(); 00875 motherSafety = motherSolid->DistanceToOut(repPoint); 00876 repDirection = history.GetTransform(depth).TransformAxis(globalDirection); 00877 00878 motherStep = motherSolid->DistanceToOut(repPoint,repDirection,true, 00879 &exitConvex,&exitVectorMother); 00880 if( exitConvex ) 00881 { 00882 motherNormalStc = G4ExitNormal( exitVectorMother, true, false, 00883 G4ExitNormal::kMother); 00884 calculatedExitNormal= true; 00885 } 00886 const G4AffineTransform& globalToLocalTop = history.GetTopTransform(); 00887 00888 G4bool motherDeterminedStep= (motherStep<ourStep); 00889 00890 if( (!exitConvex) && motherDeterminedStep ) 00891 { 00892 exitVectorMother= motherSolid->SurfaceNormal( repPoint ); 00893 motherNormalStc= G4ExitNormal( exitVectorMother, true, false, 00894 G4ExitNormal::kMother); 00895 // CalculatedExitNormal -> true; 00896 // Convex -> false: do not know value 00897 // ExitSide -> kMother (or kNull) 00898 00899 calculatedExitNormal= true; 00900 } 00901 if( motherDeterminedStep) 00902 { 00903 G4ThreeVector globalExitNormalTop= 00904 globalToLocalTop.Inverse().TransformAxis(exitVectorMother); 00905 00906 exitNormalStc= motherNormalStc; 00907 exitNormalStc.exitNormal= globalExitNormalTop; 00908 } 00909 00910 // Push in principle no longer necessary. G4Navigator now takes care of ... 00911 // Removing this will however generate warnings for pushed particles from 00912 // G4Navigator, particularly for the case of 3D replicas (Cartesian or 00913 // combined Radial/Phi cases). 00914 // Requires further investigation and eventually reimplementation of 00915 // LevelLocate() to take into account point and direction ... 00916 // 00917 if ( ( !ourStep && (sampleSafety<0.5*kCarTolerance) ) 00918 && ( repLogical->GetSolid()->Inside(localPoint)==kSurface ) ) 00919 { 00920 ourStep += kCarTolerance; 00921 } 00922 00923 if ( motherSafety<ourSafety ) 00924 { 00925 ourSafety = motherSafety; 00926 } 00927 00928 #ifdef G4VERBOSE 00929 if ( fCheck ) 00930 { 00931 if( motherSolid->Inside(localPoint)==kOutside ) 00932 { 00933 std::ostringstream message; 00934 message << "Point outside volume !" << G4endl 00935 << " Point " << localPoint 00936 << " is outside current volume " << motherPhysical->GetName() 00937 << G4endl; 00938 G4double estDistToSolid= motherSolid->DistanceToIn(localPoint); 00939 message << " Estimated isotropic distance to solid (distToIn)= " 00940 << estDistToSolid << G4endl; 00941 if( estDistToSolid > 100.0 * kCarTolerance ) 00942 { 00943 motherSolid->DumpInfo(); 00944 G4Exception("G4ReplicaNavigation::ComputeStep()", 00945 "GeomNav0003", FatalException, message, 00946 "Point is far outside Current Volume !" ); 00947 } 00948 else 00949 G4Exception("G4ReplicaNavigation::ComputeStep()", 00950 "GeomNav1002", JustWarning, message, 00951 "Point is a little outside Current Volume."); 00952 } 00953 } 00954 #endif 00955 00956 // Comparison of steps may need precision protection 00957 // 00958 #if 1 00959 if( motherDeterminedStep) 00960 { 00961 ourStep = motherStep; 00962 exiting = true; 00963 } 00964 00965 // Transform it to the Grand-Mother Reference Frame (current convention) 00966 // 00967 if ( calculatedExitNormal ) 00968 { 00969 if ( motherDeterminedStep ) 00970 { 00971 exitNormalVector= motherNormalStc.exitNormal; 00972 }else{ 00973 G4ThreeVector exitNormalGlobal= exitNormalStc.exitNormal; 00974 exitNormalVector= globalToLocalTop.TransformAxis(exitNormalGlobal); 00975 // exitNormalVector= globalToLocal2nd.TransformAxis(exitNormalGlobal); 00976 // Alt Make it in one go to Grand-Mother, avoiding transform below 00977 } 00978 // Transform to Grand-mother reference frame 00979 const G4RotationMatrix* rot = motherPhysical->GetRotation(); 00980 if ( rot ) 00981 { 00982 exitNormalVector *= rot->inverse(); 00983 } 00984 00985 } 00986 else 00987 { 00988 validExitNormal = false; 00989 } 00990 00991 #else 00992 if ( motherSafety<=ourStep ) 00993 { 00994 if ( motherStep<=ourStep ) 00995 { 00996 ourStep = motherStep; 00997 exiting = true; 00998 if ( validExitNormal ) 00999 { 01000 const G4RotationMatrix* rot = motherPhysical->GetRotation(); 01001 if ( rot ) 01002 { 01003 exitNormal *= rot->inverse(); 01004 } 01005 } 01006 } 01007 else 01008 { 01009 validExitNormal = false; 01010 // calculatedExitNormal= false; 01011 } 01012 } 01013 #endif 01014 01015 01016 G4bool daughterDeterminedStep=false; 01017 G4ThreeVector daughtNormRepCrd; 01018 // Exit normal of daughter transformed to 01019 // the coordinate system of Replica (i.e. last depth) 01020 01021 // 01022 // Compute daughter safeties & intersections 01023 // 01024 localNoDaughters = repLogical->GetNoDaughters(); 01025 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- ) 01026 { 01027 samplePhysical = repLogical->GetDaughter(sampleNo); 01028 if ( samplePhysical!=blockedExitedVol ) 01029 { 01030 G4ThreeVector localExitNorm; 01031 G4ThreeVector normReplicaCoord; 01032 01033 G4AffineTransform sampleTf(samplePhysical->GetRotation(), 01034 samplePhysical->GetTranslation()); 01035 sampleTf.Invert(); 01036 const G4ThreeVector samplePoint = 01037 sampleTf.TransformPoint(localPoint); 01038 const G4VSolid* sampleSolid = 01039 samplePhysical->GetLogicalVolume()->GetSolid(); 01040 const G4double sampleSafetyDistance = 01041 sampleSolid->DistanceToIn(samplePoint); 01042 if ( sampleSafetyDistance<ourSafety ) 01043 { 01044 ourSafety = sampleSafetyDistance; 01045 } 01046 if ( sampleSafetyDistance<=ourStep ) 01047 { 01048 sampleDirection = sampleTf.TransformAxis(localDirection); 01049 const G4double sampleStepDistance = 01050 sampleSolid->DistanceToIn(samplePoint,sampleDirection); 01051 if ( sampleStepDistance<=ourStep ) 01052 { 01053 daughterDeterminedStep= true; 01054 01055 ourStep = sampleStepDistance; 01056 entering = true; 01057 exiting = false; 01058 *pBlockedPhysical = samplePhysical; 01059 blockedReplicaNo = -1; 01060 01061 #ifdef DAUGHTER_NORMAL_ALSO 01062 // This norm can be calculated later, if needed daughter is available 01063 localExitNorm = sampleSolid->SurfaceNormal(samplePoint); 01064 daughtNormRepCrd = sampleTf.Inverse().TransformAxis(localExitNorm); 01065 #endif 01066 01067 #ifdef G4VERBOSE 01068 // Check to see that the resulting point is indeed in/on volume. 01069 // This check could eventually be made only for successful candidate. 01070 01071 if ( ( fCheck ) && ( sampleStepDistance < kInfinity ) ) 01072 { 01073 G4ThreeVector intersectionPoint; 01074 intersectionPoint= samplePoint 01075 + sampleStepDistance * sampleDirection; 01076 EInside insideIntPt= sampleSolid->Inside(intersectionPoint); 01077 if ( insideIntPt != kSurface ) 01078 { 01079 G4int oldcoutPrec = G4cout.precision(16); 01080 std::ostringstream message; 01081 message << "Navigator gets conflicting response from Solid." 01082 << G4endl 01083 << " Inaccurate DistanceToIn for solid " 01084 << sampleSolid->GetName() << G4endl 01085 << " Solid gave DistanceToIn = " 01086 << sampleStepDistance << " yet returns " ; 01087 if ( insideIntPt == kInside ) 01088 message << "-kInside-"; 01089 else if ( insideIntPt == kOutside ) 01090 message << "-kOutside-"; 01091 else 01092 message << "-kSurface-"; 01093 message << " for this point !" << G4endl 01094 << " Point = " << intersectionPoint << G4endl; 01095 if ( insideIntPt != kInside ) 01096 message << " DistanceToIn(p) = " 01097 << sampleSolid->DistanceToIn(intersectionPoint) 01098 << G4endl; 01099 if ( insideIntPt != kOutside ) 01100 message << " DistanceToOut(p) = " 01101 << sampleSolid->DistanceToOut(intersectionPoint); 01102 G4Exception("G4ReplicaNavigation::ComputeStep()", 01103 "GeomNav1002", JustWarning, message); 01104 G4cout.precision(oldcoutPrec); 01105 } 01106 } 01107 #endif 01108 } 01109 } 01110 } 01111 } 01112 01113 calculatedExitNormal &= (!daughterDeterminedStep); 01114 01115 #ifdef DAUGHTER_NORMAL_ALSO 01116 if( daughterDeterminedStep ) 01117 { 01118 // G4ThreeVector daughtNormGlobal = 01119 // GlobalToLastDepth.Inverse().TransformAxis(daughtNormRepCrd); 01120 // ==> Can calculate it, but have no way to transmit it to caller (for now) 01121 01122 exitNormalVector=globalToLocalTop.Inverse().TransformAxis(daughtNormGlobal); 01123 validExitNormal= false; // Entering daughter - never convex for parent 01124 01125 calculatedExitNormal= true; 01126 } 01127 // calculatedExitNormal= true; // Force it to true -- dubious 01128 #endif 01129 01130 newSafety = ourSafety; 01131 return ourStep; 01132 }
void G4ReplicaNavigation::ComputeTransformation | ( | const G4int | replicaNo, | |
G4VPhysicalVolume * | pVol | |||
) | const |
Definition at line 696 of file G4ReplicaNavigation.cc.
References G4VPhysicalVolume::GetReplicationData(), kPhi, kRho, kXAxis, kYAxis, kZAxis, and G4VPhysicalVolume::SetTranslation().
00698 { 00699 G4double val; 00700 00701 // Replication data 00702 // 00703 EAxis axis; 00704 G4int nReplicas; 00705 G4double width, offset; 00706 G4bool consuming; 00707 00708 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming); 00709 00710 switch (axis) 00711 { 00712 case kXAxis: 00713 val = -width*0.5*(nReplicas-1)+width*replicaNo; 00714 pVol->SetTranslation(G4ThreeVector(val,0,0)); 00715 break; 00716 case kYAxis: 00717 val = -width*0.5*(nReplicas-1)+width*replicaNo; 00718 pVol->SetTranslation(G4ThreeVector(0,val,0)); 00719 break; 00720 case kZAxis: 00721 val = -width*0.5*(nReplicas-1)+width*replicaNo; 00722 pVol->SetTranslation(G4ThreeVector(0,0,val)); 00723 break; 00724 case kPhi: 00725 val = -(offset+width*(replicaNo+0.5)); 00726 SetPhiTransformation(val,pVol); 00727 break; 00728 case kRho: 00729 // No setup required for radial case 00730 default: 00731 break; 00732 } 00733 }
void G4ReplicaNavigation::ComputeTransformation | ( | const G4int | replicaNo, | |
G4VPhysicalVolume * | pVol, | |||
G4ThreeVector & | point | |||
) | const |
Definition at line 640 of file G4ReplicaNavigation.cc.
References G4VPhysicalVolume::GetReplicationData(), kPhi, kRho, kXAxis, kYAxis, kZAxis, and G4VPhysicalVolume::SetTranslation().
Referenced by LevelLocate(), G4Navigator::LocateGlobalPointAndSetup(), G4ITNavigator::LocateGlobalPointAndSetup(), G4Navigator::SetupHierarchy(), and G4ITNavigator::SetupHierarchy().
00643 { 00644 G4double val,cosv,sinv,tmpx,tmpy; 00645 00646 // Replication data 00647 // 00648 EAxis axis; 00649 G4int nReplicas; 00650 G4double width,offset; 00651 G4bool consuming; 00652 00653 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming); 00654 00655 switch (axis) 00656 { 00657 case kXAxis: 00658 val = -width*0.5*(nReplicas-1)+width*replicaNo; 00659 pVol->SetTranslation(G4ThreeVector(val,0,0)); 00660 point.setX(point.x()-val); 00661 break; 00662 case kYAxis: 00663 val = -width*0.5*(nReplicas-1)+width*replicaNo; 00664 pVol->SetTranslation(G4ThreeVector(0,val,0)); 00665 point.setY(point.y()-val); 00666 break; 00667 case kZAxis: 00668 val = -width*0.5*(nReplicas-1)+width*replicaNo; 00669 pVol->SetTranslation(G4ThreeVector(0,0,val)); 00670 point.setZ(point.z()-val); 00671 break; 00672 case kPhi: 00673 val = -(offset+width*(replicaNo+0.5)); 00674 SetPhiTransformation(val,pVol); 00675 cosv = std::cos(val); 00676 sinv = std::sin(val); 00677 tmpx = point.x()*cosv-point.y()*sinv; 00678 tmpy = point.x()*sinv+point.y()*cosv; 00679 point.setY(tmpy); 00680 point.setX(tmpx); 00681 break; 00682 case kRho: 00683 // No setup required for radial case 00684 default: 00685 break; 00686 } 00687 }
G4double G4ReplicaNavigation::DistanceToOut | ( | const G4VPhysicalVolume * | pVol, | |
const G4int | replicaNo, | |||
const G4ThreeVector & | localPoint, | |||
const G4ThreeVector & | localDirection, | |||
G4ExitNormal & | candidateNormal | |||
) | const |
Definition at line 241 of file G4ReplicaNavigation.cc.
References G4ExitNormal::calculated, G4ExitNormal::exitNormal, G4ExitNormal::exitSide, FatalException, G4Exception(), G4VPhysicalVolume::GetReplicationData(), G4ExitNormal::kMX, G4ExitNormal::kMY, G4ExitNormal::kMZ, kPhi, G4ExitNormal::kPX, G4ExitNormal::kPY, G4ExitNormal::kPZ, kRho, kXAxis, kYAxis, kZAxis, and G4ExitNormal::validConvex.
00246 { 00247 // Replication data 00248 // 00249 EAxis axis; 00250 G4int nReplicas; 00251 G4double width, offset; 00252 G4bool consuming; 00253 00254 G4double Dist=kInfinity; 00255 G4double coord, Comp, lindist; 00256 G4double signC = 0.0; 00257 G4ExitNormal candidateNormal; 00258 00259 static const G4ThreeVector VecCartAxes[3]= 00260 { G4ThreeVector(1.,0.,0.),G4ThreeVector(0.,1.,0.),G4ThreeVector(0.,0.,1.) }; 00261 static G4ExitNormal::ESide SideCartAxesPlus [3]= 00262 { G4ExitNormal::kPX, G4ExitNormal::kPY, G4ExitNormal::kPZ }; 00263 static G4ExitNormal::ESide SideCartAxesMinus[3]= 00264 { G4ExitNormal::kMX, G4ExitNormal::kMY, G4ExitNormal::kMZ }; 00265 00266 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming); 00267 switch(axis) 00268 { 00269 case kXAxis: 00270 case kYAxis: 00271 case kZAxis: 00272 coord = localPoint(axis); 00273 Comp = localDirection(axis); 00274 if ( Comp>0 ) 00275 { 00276 lindist = width*0.5-coord; 00277 Dist = (lindist>0) ? lindist/Comp : 0; 00278 signC= 1.0; 00279 } 00280 else if ( Comp<0 ) 00281 { 00282 lindist = width*0.5+coord; 00283 Dist = (lindist>0) ? -lindist/Comp : 0; 00284 signC= -1.0; 00285 } 00286 else 00287 { 00288 Dist = kInfinity; 00289 } 00290 // signC = sign<G4double>(Comp) 00291 candidateNormal.exitNormal = ( signC * VecCartAxes[axis]); 00292 candidateNormal.calculated = true; 00293 candidateNormal.validConvex = true; 00294 candidateNormal.exitSide = 00295 (Comp>0) ? SideCartAxesPlus[axis] : SideCartAxesMinus[axis]; 00296 break; 00297 case kPhi: 00298 Dist = DistanceToOutPhi(localPoint,localDirection,width,candidateNormal); 00299 // candidateNormal set in call 00300 break; 00301 case kRho: 00302 Dist = DistanceToOutRad(localPoint,localDirection,width,offset, 00303 replicaNo,candidateNormal); 00304 // candidateNormal set in call 00305 break; 00306 default: 00307 G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002", 00308 FatalException, "Unknown axis!"); 00309 break; 00310 } 00311 00312 arExitNormal= candidateNormal; // .exitNormal; 00313 00314 return Dist; 00315 }
G4double G4ReplicaNavigation::DistanceToOut | ( | const G4VPhysicalVolume * | pVol, | |
const G4int | replicaNo, | |||
const G4ThreeVector & | localPoint | |||
) | const |
Definition at line 175 of file G4ReplicaNavigation.cc.
References FatalException, G4Exception(), G4VPhysicalVolume::GetReplicationData(), kPhi, kRho, kXAxis, kYAxis, and kZAxis.
Referenced by ComputeSafety(), and ComputeStep().
00178 { 00179 // Replication data 00180 // 00181 EAxis axis; 00182 G4int nReplicas; 00183 G4double width,offset; 00184 G4bool consuming; 00185 00186 G4double safety=0.; 00187 G4double safe1,safe2; 00188 G4double coord, rho, rmin, rmax; 00189 00190 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming); 00191 switch(axis) 00192 { 00193 case kXAxis: 00194 case kYAxis: 00195 case kZAxis: 00196 coord = localPoint(axis); 00197 safe1 = width*0.5-coord; 00198 safe2 = width*0.5+coord; 00199 safety = (safe1<=safe2) ? safe1 : safe2; 00200 break; 00201 case kPhi: 00202 if ( localPoint.y()<=0 ) 00203 { 00204 safety = localPoint.x()*std::sin(width*0.5) 00205 + localPoint.y()*std::cos(width*0.5); 00206 } 00207 else 00208 { 00209 safety = localPoint.x()*std::sin(width*0.5) 00210 - localPoint.y()*std::cos(width*0.5); 00211 } 00212 break; 00213 case kRho: 00214 rho = localPoint.perp(); 00215 rmax = width*(replicaNo+1)+offset; 00216 if ( replicaNo||offset ) 00217 { 00218 rmin = rmax-width; 00219 safe1 = rho-rmin; 00220 safe2 = rmax-rho; 00221 safety = (safe1<=safe2) ? safe1 : safe2; 00222 } 00223 else 00224 { 00225 safety = rmax-rho; 00226 } 00227 break; 00228 default: 00229 G4Exception("G4ReplicaNavigation::DistanceToOut()", "GeomNav0002", 00230 FatalException, "Unknown axis!"); 00231 break; 00232 } 00233 return (safety >= kCarTolerance) ? safety : 0; 00234 }
G4int G4ReplicaNavigation::GetVerboseLevel | ( | ) | const [inline] |
EInside G4ReplicaNavigation::Inside | ( | const G4VPhysicalVolume * | pVol, | |
const G4int | replicaNo, | |||
const G4ThreeVector & | localPoint | |||
) | const |
Definition at line 69 of file G4ReplicaNavigation.cc.
References FatalException, G4Exception(), G4VPhysicalVolume::GetReplicationData(), kInside, kOutside, kPhi, kRho, kSurface, kXAxis, kYAxis, and kZAxis.
Referenced by BackLocate().
00072 { 00073 EInside in = kOutside; 00074 00075 // Replication data 00076 // 00077 EAxis axis; 00078 G4int nReplicas; 00079 G4double width, offset; 00080 G4bool consuming; 00081 00082 G4double coord, rad2, rmin, tolRMax2, rmax, tolRMin2; 00083 00084 pVol->GetReplicationData(axis, nReplicas, width, offset, consuming); 00085 00086 switch (axis) 00087 { 00088 case kXAxis: 00089 case kYAxis: 00090 case kZAxis: 00091 coord = std::fabs(localPoint(axis))-width*0.5; 00092 if ( coord<=-kCarTolerance*0.5 ) 00093 { 00094 in = kInside; 00095 } 00096 else if ( coord<=kCarTolerance*0.5 ) 00097 { 00098 in = kSurface; 00099 } 00100 break; 00101 case kPhi: 00102 if ( localPoint.y()||localPoint.x() ) 00103 { 00104 coord = std::fabs(std::atan2(localPoint.y(),localPoint.x()))-width*0.5; 00105 if ( coord<=-kAngTolerance*0.5 ) 00106 { 00107 in = kInside; 00108 } 00109 else if ( coord<=kAngTolerance*0.5 ) 00110 { 00111 in = kSurface; 00112 } 00113 } 00114 else 00115 { 00116 in = kSurface; 00117 } 00118 break; 00119 case kRho: 00120 rad2 = localPoint.perp2(); 00121 rmax = (replicaNo+1)*width+offset; 00122 tolRMax2 = rmax-kRadTolerance*0.5; 00123 tolRMax2 *= tolRMax2; 00124 if ( rad2>tolRMax2 ) 00125 { 00126 tolRMax2 = rmax+kRadTolerance*0.5; 00127 tolRMax2 *= tolRMax2; 00128 if ( rad2<=tolRMax2 ) 00129 { 00130 in = kSurface; 00131 } 00132 } 00133 else 00134 { 00135 // Known to be inside outer radius 00136 // 00137 if ( replicaNo||offset ) 00138 { 00139 rmin = rmax-width; 00140 tolRMin2 = rmin-kRadTolerance*0.5; 00141 tolRMin2 *= tolRMin2; 00142 if ( rad2>tolRMin2 ) 00143 { 00144 tolRMin2 = rmin+kRadTolerance*0.5; 00145 tolRMin2 *= tolRMin2; 00146 if ( rad2>=tolRMin2 ) 00147 { 00148 in = kInside; 00149 } 00150 else 00151 { 00152 in = kSurface; 00153 } 00154 } 00155 } 00156 else 00157 { 00158 in = kInside; 00159 } 00160 } 00161 break; 00162 default: 00163 G4Exception("G4ReplicaNavigation::Inside()", "GeomNav0002", 00164 FatalException, "Unknown axis!"); 00165 break; 00166 } 00167 return in; 00168 }
G4bool G4ReplicaNavigation::LevelLocate | ( | G4NavigationHistory & | history, | |
const G4VPhysicalVolume * | blockedVol, | |||
const G4int | blockedNum, | |||
const G4ThreeVector & | globalPoint, | |||
const G4ThreeVector * | globalDirection, | |||
const G4bool | pLocatedOnEdge, | |||
G4ThreeVector & | localPoint | |||
) | [inline] |
Definition at line 145 of file G4ReplicaNavigation.icc.
References ComputeTransformation(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4NavigationHistory::GetTopVolume(), G4LogicalVolume::GetVoxelHeader(), kReplica, G4NavigationHistory::NewLevel(), and G4VPhysicalVolume::SetCopyNo().
Referenced by G4Navigator::LocateGlobalPointAndSetup(), and G4ITNavigator::LocateGlobalPointAndSetup().
00152 { 00153 G4VPhysicalVolume *motherPhysical, *pPhysical; 00154 G4LogicalVolume *motherLogical; 00155 G4SmartVoxelHeader *motherVoxelHeader; 00156 G4int nodeNo; 00157 00158 motherPhysical = history.GetTopVolume(); 00159 motherLogical = motherPhysical->GetLogicalVolume(); 00160 motherVoxelHeader = motherLogical->GetVoxelHeader(); 00161 pPhysical = motherLogical->GetDaughter(0); 00162 00163 if ( blockedVol==pPhysical ) 00164 { 00165 nodeNo = VoxelLocate(motherVoxelHeader, localPoint, blockedNum); 00166 } 00167 else 00168 { 00169 nodeNo = VoxelLocate(motherVoxelHeader, localPoint); 00170 } 00171 00172 ComputeTransformation(nodeNo, pPhysical, localPoint); 00173 history.NewLevel(pPhysical, kReplica, nodeNo); 00174 pPhysical->SetCopyNo(nodeNo); 00175 00176 return true; 00177 }
void G4ReplicaNavigation::SetVerboseLevel | ( | G4int | level | ) | [inline] |
Definition at line 209 of file G4ReplicaNavigation.icc.
Referenced by G4Navigator::SetVerboseLevel(), and G4ITNavigator::SetVerboseLevel().