#include <G4ParameterisedNavigation.hh>
Inheritance diagram for G4ParameterisedNavigation:
Public Member Functions | |
G4ParameterisedNavigation () | |
~G4ParameterisedNavigation () | |
G4SmartVoxelNode * | ParamVoxelLocate (G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint) |
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 G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo) |
G4double | ComputeSafety (const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX) |
Definition at line 58 of file G4ParameterisedNavigation.hh.
G4ParameterisedNavigation::G4ParameterisedNavigation | ( | ) |
Definition at line 58 of file G4ParameterisedNavigation.cc.
00059 : fVoxelAxis(kUndefined), fVoxelNoSlices(0), fVoxelSliceWidth(0.), 00060 fVoxelNodeNo(0), fVoxelHeader(0) 00061 { 00062 }
G4ParameterisedNavigation::~G4ParameterisedNavigation | ( | ) |
G4double G4ParameterisedNavigation::ComputeSafety | ( | const G4ThreeVector & | localPoint, | |
const G4NavigationHistory & | history, | |||
const G4double | pProposedMaxLength = DBL_MAX | |||
) | [virtual] |
Reimplemented from G4VoxelNavigation.
Definition at line 363 of file G4ParameterisedNavigation.cc.
References G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4VoxelNavigation::fVoxelNode, G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4SmartVoxelHeader::GetMinExtent(), G4SmartVoxelNode::GetNoContained(), G4SmartVoxelProxy::GetNode(), G4VPhysicalVolume::GetParameterisation(), G4VPhysicalVolume::GetReplicationData(), G4VPhysicalVolume::GetRotation(), G4SmartVoxelHeader::GetSlice(), G4LogicalVolume::GetSolid(), G4NavigationHistory::GetTopVolume(), G4VPhysicalVolume::GetTranslation(), G4SmartVoxelNode::GetVolume(), and kUndefined.
Referenced by G4Navigator::ComputeSafety(), and G4ITNavigator::ComputeSafety().
00366 { 00367 G4VPhysicalVolume *motherPhysical, *samplePhysical; 00368 G4VPVParameterisation *sampleParam; 00369 G4LogicalVolume *motherLogical; 00370 G4VSolid *motherSolid, *sampleSolid; 00371 G4double motherSafety, ourSafety; 00372 G4int sampleNo, curVoxelNodeNo; 00373 00374 G4SmartVoxelNode *curVoxelNode; 00375 G4int curNoVolumes, contentNo; 00376 G4double voxelSafety; 00377 00378 // Replication data 00379 // 00380 EAxis axis; 00381 G4int nReplicas; 00382 G4double width, offset; 00383 G4bool consuming; 00384 00385 motherPhysical = history.GetTopVolume(); 00386 motherLogical = motherPhysical->GetLogicalVolume(); 00387 motherSolid = motherLogical->GetSolid(); 00388 00389 // 00390 // Compute mother safety 00391 // 00392 00393 motherSafety = motherSolid->DistanceToOut(localPoint); 00394 ourSafety = motherSafety; // Working isotropic safety 00395 00396 // 00397 // Compute daughter safeties 00398 // 00399 00400 // By definition, parameterised volumes exist as first 00401 // daughter of the mother volume 00402 // 00403 samplePhysical = motherLogical->GetDaughter(0); 00404 samplePhysical->GetReplicationData(axis, nReplicas, 00405 width, offset, consuming); 00406 sampleParam = samplePhysical->GetParameterisation(); 00407 00408 // Look inside the current Voxel only at the current point 00409 // 00410 if ( axis==kUndefined ) // 3D case: current voxel node is retrieved 00411 { // from G4VoxelNavigation. 00412 curVoxelNode = fVoxelNode; 00413 } 00414 else // 1D case: current voxel node is computed here. 00415 { 00416 curVoxelNodeNo = G4int((localPoint(fVoxelAxis) 00417 -fVoxelHeader->GetMinExtent()) / fVoxelSliceWidth ); 00418 curVoxelNode = fVoxelHeader->GetSlice(curVoxelNodeNo)->GetNode(); 00419 fVoxelNodeNo = curVoxelNodeNo; 00420 fVoxelNode = curVoxelNode; 00421 } 00422 curNoVolumes = curVoxelNode->GetNoContained(); 00423 00424 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- ) 00425 { 00426 sampleNo = curVoxelNode->GetVolume(contentNo); 00427 00428 // Call virtual methods, and copy information if needed 00429 // 00430 sampleSolid= IdentifyAndPlaceSolid( sampleNo,samplePhysical,sampleParam ); 00431 00432 G4AffineTransform sampleTf(samplePhysical->GetRotation(), 00433 samplePhysical->GetTranslation()); 00434 sampleTf.Invert(); 00435 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint); 00436 G4double sampleSafety = sampleSolid->DistanceToIn(samplePoint); 00437 if ( sampleSafety<ourSafety ) 00438 { 00439 ourSafety = sampleSafety; 00440 } 00441 } 00442 00443 voxelSafety = ComputeVoxelSafety(localPoint,axis); 00444 if ( voxelSafety<ourSafety ) 00445 { 00446 ourSafety=voxelSafety; 00447 } 00448 00449 return ourSafety; 00450 }
G4double G4ParameterisedNavigation::ComputeStep | ( | const G4ThreeVector & | globalPoint, | |
const G4ThreeVector & | globalDirection, | |||
const G4double | currentProposedStepLength, | |||
G4double & | newSafety, | |||
G4NavigationHistory & | history, | |||
G4bool & | validExitNormal, | |||
G4ThreeVector & | exitNormal, | |||
G4bool & | exiting, | |||
G4bool & | entering, | |||
G4VPhysicalVolume ** | pBlockedPhysical, | |||
G4int & | blockedReplicaNo | |||
) | [virtual] |
Reimplemented from G4VoxelNavigation.
Definition at line 77 of file G4ParameterisedNavigation.cc.
References G4BlockingList::BlockVolume(), G4VSolid::DistanceToIn(), G4VSolid::DistanceToOut(), G4VSolid::DumpInfo(), G4BlockingList::Enlarge(), FatalException, G4VoxelNavigation::fBList, G4VoxelNavigation::fCheck, G4VoxelNavigation::fVoxelNode, G4cerr, G4cout, G4endl, G4Exception(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4VPhysicalVolume::GetName(), G4VSolid::GetName(), G4SmartVoxelNode::GetNoContained(), G4VPhysicalVolume::GetParameterisation(), G4VPhysicalVolume::GetReplicationData(), G4VPhysicalVolume::GetRotation(), G4LogicalVolume::GetSolid(), G4VSolid::GetTolerance(), G4NavigationHistory::GetTopVolume(), G4VPhysicalVolume::GetTranslation(), G4SmartVoxelNode::GetVolume(), G4VSolid::Inside(), G4BlockingList::IsBlocked(), JustWarning, kInside, kOutside, kSurface, and G4BlockingList::Reset().
Referenced by G4Navigator::ComputeStep(), and G4ITNavigator::ComputeStep().
00088 { 00089 G4VPhysicalVolume *motherPhysical, *samplePhysical; 00090 G4VPVParameterisation *sampleParam; 00091 G4LogicalVolume *motherLogical; 00092 G4VSolid *motherSolid, *sampleSolid; 00093 G4ThreeVector sampleDirection; 00094 G4double ourStep=currentProposedStepLength, motherSafety, ourSafety; 00095 G4int sampleNo; 00096 00097 G4bool initialNode, noStep; 00098 G4SmartVoxelNode *curVoxelNode; 00099 G4int curNoVolumes, contentNo; 00100 G4double voxelSafety; 00101 00102 // Replication data 00103 // 00104 EAxis axis; 00105 G4int nReplicas; 00106 G4double width, offset; 00107 G4bool consuming; 00108 00109 motherPhysical = history.GetTopVolume(); 00110 motherLogical = motherPhysical->GetLogicalVolume(); 00111 motherSolid = motherLogical->GetSolid(); 00112 00113 // 00114 // Compute mother safety 00115 // 00116 00117 motherSafety = motherSolid->DistanceToOut(localPoint); 00118 ourSafety = motherSafety; // Working isotropic safety 00119 00120 #ifdef G4VERBOSE 00121 if ( fCheck ) 00122 { 00123 if( motherSafety < 0.0 ) 00124 { 00125 motherSolid->DumpInfo(); 00126 std::ostringstream message; 00127 message << "Negative Safety In Voxel Navigation !" << G4endl 00128 << " Current solid " << motherSolid->GetName() 00129 << " gave negative safety: " << motherSafety << G4endl 00130 << " for the current (local) point " << localPoint; 00131 G4Exception("G4ParameterisedNavigation::ComputeStep()", 00132 "GeomNav0003", FatalException, message); 00133 } 00134 if( motherSolid->Inside(localPoint)==kOutside ) 00135 { 00136 std::ostringstream message; 00137 message << "Point is outside Current Volume !" << G4endl 00138 << " Point " << localPoint 00139 << " is outside current volume " << motherPhysical->GetName() 00140 << G4endl; 00141 G4double estDistToSolid= motherSolid->DistanceToIn(localPoint); 00142 G4cout << " Estimated isotropic distance to solid (distToIn)= " 00143 << estDistToSolid; 00144 if( estDistToSolid > 100.0 * motherSolid->GetTolerance() ) 00145 { 00146 motherSolid->DumpInfo(); 00147 G4Exception("G4ParameterisedNavigation::ComputeStep()", 00148 "GeomNav0003", FatalException, message, 00149 "Point is far outside Current Volume !"); 00150 } 00151 else 00152 G4Exception("G4ParameterisedNavigation::ComputeStep()", 00153 "GeomNav1002", JustWarning, message, 00154 "Point is a little outside Current Volume."); 00155 } 00156 } 00157 #endif 00158 00159 // 00160 // Compute daughter safeties & intersections 00161 // 00162 00163 initialNode = true; 00164 noStep = true; 00165 00166 // By definition, parameterised volumes exist as first 00167 // daughter of the mother volume 00168 // 00169 samplePhysical = motherLogical->GetDaughter(0); 00170 samplePhysical->GetReplicationData(axis,nReplicas,width,offset,consuming); 00171 fBList.Enlarge(nReplicas); 00172 fBList.Reset(); 00173 00174 // Exiting normal optimisation 00175 // 00176 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal) 00177 { 00178 if (localDirection.dot(exitNormal)>=kMinExitingNormalCosine) 00179 { 00180 // Block exited daughter replica; Must be on boundary => zero safety 00181 // 00182 fBList.BlockVolume(blockedReplicaNo); 00183 ourSafety = 0; 00184 } 00185 } 00186 exiting = false; 00187 entering = false; 00188 00189 sampleParam = samplePhysical->GetParameterisation(); 00190 00191 do 00192 { 00193 curVoxelNode = fVoxelNode; 00194 curNoVolumes = curVoxelNode->GetNoContained(); 00195 00196 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- ) 00197 { 00198 sampleNo = curVoxelNode->GetVolume(contentNo); 00199 if ( !fBList.IsBlocked(sampleNo) ) 00200 { 00201 fBList.BlockVolume(sampleNo); 00202 00203 // Call virtual methods, and copy information if needed 00204 // 00205 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical, 00206 sampleParam ); 00207 00208 G4AffineTransform sampleTf(samplePhysical->GetRotation(), 00209 samplePhysical->GetTranslation()); 00210 sampleTf.Invert(); 00211 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint); 00212 const G4double sampleSafety = sampleSolid->DistanceToIn(samplePoint); 00213 if ( sampleSafety<ourSafety ) 00214 { 00215 ourSafety = sampleSafety; 00216 } 00217 if ( sampleSafety<=ourStep ) 00218 { 00219 sampleDirection = sampleTf.TransformAxis(localDirection); 00220 G4double sampleStep = 00221 sampleSolid->DistanceToIn(samplePoint, sampleDirection); 00222 if ( sampleStep<=ourStep ) 00223 { 00224 ourStep = sampleStep; 00225 entering = true; 00226 exiting = false; 00227 *pBlockedPhysical = samplePhysical; 00228 blockedReplicaNo = sampleNo; 00229 #ifdef G4VERBOSE 00230 // Check to see that the resulting point is indeed in/on volume. 00231 // This check could eventually be made only for successful 00232 // candidate. 00233 00234 if ( ( fCheck ) && ( sampleStep < kInfinity ) ) 00235 { 00236 G4ThreeVector intersectionPoint; 00237 intersectionPoint= samplePoint + sampleStep * sampleDirection; 00238 EInside insideIntPt= sampleSolid->Inside(intersectionPoint); 00239 if( insideIntPt != kSurface ) 00240 { 00241 G4int oldcoutPrec = G4cout.precision(16); 00242 std::ostringstream message; 00243 message << "Navigator gets conflicting response from Solid." 00244 << G4endl 00245 << " Inaccurate solid DistanceToIn" 00246 << " for solid " << sampleSolid->GetName() << G4endl 00247 << " Solid gave DistanceToIn = " 00248 << sampleStep << " yet returns " ; 00249 if( insideIntPt == kInside ) 00250 message << "-kInside-"; 00251 else if( insideIntPt == kOutside ) 00252 message << "-kOutside-"; 00253 else 00254 message << "-kSurface-"; 00255 message << " for this point !" << G4endl 00256 << " Point = " << intersectionPoint 00257 << G4endl; 00258 if ( insideIntPt != kInside ) 00259 message << " DistanceToIn(p) = " 00260 << sampleSolid->DistanceToIn(intersectionPoint); 00261 if ( insideIntPt != kOutside ) 00262 message << " DistanceToOut(p) = " 00263 << sampleSolid->DistanceToOut(intersectionPoint); 00264 G4Exception("G4ParameterisedNavigation::ComputeStep()", 00265 "GeomNav1002", JustWarning, message); 00266 G4cout.precision(oldcoutPrec); 00267 } 00268 } 00269 #endif 00270 } 00271 } 00272 } 00273 } 00274 00275 if ( initialNode ) 00276 { 00277 initialNode = false; 00278 voxelSafety = ComputeVoxelSafety(localPoint,axis); 00279 if ( voxelSafety<ourSafety ) 00280 { 00281 ourSafety = voxelSafety; 00282 } 00283 if ( currentProposedStepLength<ourSafety ) 00284 { 00285 // Guaranteed physics limited 00286 // 00287 noStep = false; 00288 entering = false; 00289 exiting = false; 00290 *pBlockedPhysical = 0; 00291 ourStep = kInfinity; 00292 } 00293 else 00294 { 00295 // 00296 // Compute mother intersection if required 00297 // 00298 if ( motherSafety<=ourStep ) 00299 { 00300 G4double motherStep = motherSolid->DistanceToOut(localPoint, 00301 localDirection, 00302 true, 00303 &validExitNormal, 00304 &exitNormal); 00305 #ifdef G4VERBOSE 00306 if ( fCheck ) 00307 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) ) 00308 { 00309 G4int oldPrOut= G4cout.precision(16); 00310 G4int oldPrErr= G4cerr.precision(16); 00311 std::ostringstream message; 00312 message << "Current point is outside the current solid !" 00313 << G4endl 00314 << " Problem in Navigation" << G4endl 00315 << " Point (local coordinates): " 00316 << localPoint << G4endl 00317 << " Local Direction: " 00318 << localDirection << G4endl 00319 << " Solid: " << motherSolid->GetName(); 00320 motherSolid->DumpInfo(); 00321 G4Exception("G4ParameterisedNavigation::ComputeStep()", 00322 "GeomNav0003", FatalException, message); 00323 G4cout.precision(oldPrOut); 00324 G4cerr.precision(oldPrErr); 00325 } 00326 #endif 00327 if ( motherStep<=ourStep ) 00328 { 00329 ourStep = motherStep; 00330 exiting = true; 00331 entering = false; 00332 if ( validExitNormal ) 00333 { 00334 const G4RotationMatrix *rot = motherPhysical->GetRotation(); 00335 if (rot) 00336 { 00337 exitNormal *= rot->inverse(); 00338 } 00339 } 00340 } 00341 else 00342 { 00343 validExitNormal = false; 00344 } 00345 } 00346 } 00347 newSafety=ourSafety; 00348 } 00349 if (noStep) 00350 { 00351 noStep = LocateNextVoxel(localPoint, localDirection, ourStep, axis); 00352 } 00353 } while (noStep); 00354 00355 return ourStep; 00356 }
G4bool G4ParameterisedNavigation::LevelLocate | ( | G4NavigationHistory & | history, | |
const G4VPhysicalVolume * | blockedVol, | |||
const G4int | blockedNum, | |||
const G4ThreeVector & | globalPoint, | |||
const G4ThreeVector * | globalDirection, | |||
const G4bool | pLocatedOnEdge, | |||
G4ThreeVector & | localPoint | |||
) | [virtual] |
Reimplemented from G4VoxelNavigation.
Definition at line 569 of file G4ParameterisedNavigation.cc.
References G4NavigationHistory::BackLevel(), G4AuxiliaryNavServices::CheckPointOnSurface(), G4VPVParameterisation::ComputeMaterial(), G4LogicalVolume::GetDaughter(), G4VPhysicalVolume::GetLogicalVolume(), G4SmartVoxelNode::GetNoContained(), G4VPhysicalVolume::GetParameterisation(), G4NavigationHistory::GetTopTransform(), G4NavigationHistory::GetTopVolume(), G4SmartVoxelNode::GetVolume(), G4LogicalVolume::GetVoxelHeader(), kParameterised, G4NavigationHistory::NewLevel(), ParamVoxelLocate(), G4VPhysicalVolume::SetCopyNo(), G4LogicalVolume::SetSolid(), G4AffineTransform::TransformPoint(), and G4LogicalVolume::UpdateMaterial().
Referenced by G4Navigator::LocateGlobalPointAndSetup(), and G4ITNavigator::LocateGlobalPointAndSetup().
00576 { 00577 G4SmartVoxelHeader *motherVoxelHeader; 00578 G4SmartVoxelNode *motherVoxelNode; 00579 G4VPhysicalVolume *motherPhysical, *pPhysical; 00580 G4VPVParameterisation *pParam; 00581 G4LogicalVolume *motherLogical; 00582 G4VSolid *pSolid; 00583 G4ThreeVector samplePoint; 00584 G4int voxelNoDaughters, replicaNo; 00585 00586 motherPhysical = history.GetTopVolume(); 00587 motherLogical = motherPhysical->GetLogicalVolume(); 00588 motherVoxelHeader = motherLogical->GetVoxelHeader(); 00589 00590 // Find the voxel containing the point 00591 // 00592 motherVoxelNode = ParamVoxelLocate(motherVoxelHeader,localPoint); 00593 00594 voxelNoDaughters = motherVoxelNode->GetNoContained(); 00595 if ( voxelNoDaughters==0 ) { return false; } 00596 00597 pPhysical = motherLogical->GetDaughter(0); 00598 pParam = pPhysical->GetParameterisation(); 00599 00600 // Save parent history in touchable history 00601 // ... for use as parent t-h in ComputeMaterial method of param 00602 // 00603 G4TouchableHistory parentTouchable( history ); 00604 00605 // Search replicated daughter volume 00606 // 00607 for ( register int sampleNo=voxelNoDaughters-1; sampleNo>=0; sampleNo-- ) 00608 { 00609 replicaNo = motherVoxelNode->GetVolume(sampleNo); 00610 if ( (replicaNo!=blockedNum) || (pPhysical!=blockedVol) ) 00611 { 00612 // Obtain solid (as it can vary) and obtain its parameters 00613 // 00614 pSolid = IdentifyAndPlaceSolid( replicaNo, pPhysical, pParam ); 00615 00616 // Setup history 00617 // 00618 history.NewLevel(pPhysical, kParameterised, replicaNo); 00619 samplePoint = history.GetTopTransform().TransformPoint(globalPoint); 00620 if ( !G4AuxiliaryNavServices::CheckPointOnSurface( pSolid, samplePoint, 00621 globalDirection, history.GetTopTransform(), pLocatedOnEdge) ) 00622 { 00623 history.BackLevel(); 00624 } 00625 else 00626 { 00627 // Enter this daughter 00628 // 00629 localPoint = samplePoint; 00630 00631 // Set the correct copy number in physical 00632 // 00633 pPhysical->SetCopyNo(replicaNo); 00634 00635 // Set the correct solid and material in Logical Volume 00636 // 00637 G4LogicalVolume *pLogical = pPhysical->GetLogicalVolume(); 00638 pLogical->SetSolid(pSolid); 00639 pLogical->UpdateMaterial(pParam->ComputeMaterial(replicaNo, 00640 pPhysical, &parentTouchable) ); 00641 return true; 00642 } 00643 } 00644 } 00645 return false; 00646 }
G4SmartVoxelNode * G4ParameterisedNavigation::ParamVoxelLocate | ( | G4SmartVoxelHeader * | pHead, | |
const G4ThreeVector & | localPoint | |||
) | [inline] |
Definition at line 59 of file G4ParameterisedNavigation.icc.
References G4VoxelNavigation::fVoxelNode, G4SmartVoxelHeader::GetAxis(), G4SmartVoxelHeader::GetMaxExtent(), G4SmartVoxelHeader::GetMinExtent(), G4SmartVoxelProxy::GetNode(), G4SmartVoxelHeader::GetNoSlices(), G4SmartVoxelHeader::GetParamAxis(), G4SmartVoxelHeader::GetSlice(), kUndefined, and G4VoxelNavigation::VoxelLocate().
Referenced by LevelLocate(), G4Navigator::LocateGlobalPointWithinVolume(), and G4ITNavigator::LocateGlobalPointWithinVolume().
00061 { 00062 // If no parameterisation axis is specified, adopt default 00063 // location strategy as for placements 00064 // 00065 if ( pHead->GetParamAxis()==kUndefined ) 00066 { 00067 fVoxelNode = G4VoxelNavigation::VoxelLocate(pHead,localPoint); 00068 } 00069 else 00070 { 00071 G4double targetHeaderMin, targetHeaderNodeWidth; 00072 G4int targetHeaderNoSlices, targetNodeNo; 00073 EAxis targetHeaderAxis; 00074 00075 targetHeaderAxis = pHead->GetAxis(); 00076 targetHeaderNoSlices = pHead->GetNoSlices(); 00077 targetHeaderMin = pHead->GetMinExtent(); 00078 targetHeaderNodeWidth = (pHead->GetMaxExtent()-targetHeaderMin) 00079 / targetHeaderNoSlices; 00080 targetNodeNo = G4int ( (localPoint(targetHeaderAxis)-targetHeaderMin) 00081 / targetHeaderNodeWidth ); 00082 // Rounding protection 00083 // 00084 if ( targetNodeNo<0 ) 00085 { 00086 targetNodeNo = 0; 00087 } 00088 else if ( targetNodeNo>=targetHeaderNoSlices ) 00089 { 00090 targetNodeNo = targetHeaderNoSlices-1; 00091 } 00092 fVoxelAxis = targetHeaderAxis; 00093 fVoxelNoSlices = targetHeaderNoSlices; 00094 fVoxelSliceWidth = targetHeaderNodeWidth; 00095 fVoxelNodeNo = targetNodeNo; 00096 fVoxelHeader = pHead; 00097 fVoxelNode = pHead->GetSlice(targetNodeNo)->GetNode(); 00098 } 00099 return fVoxelNode; 00100 }