Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/navigation/src/G4VoxelNavigation.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/navigation/src/G4VoxelNavigation.cc (Version 11.3.0) and /geometry/navigation/src/G4VoxelNavigation.cc (Version 4.1)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // class G4VoxelNavigation Implementation         
 27 //                                                
 28 // Author: P.Kent, 1996                           
 29 //                                                
 30 // -------------------------------------------    
 31 #include "G4VoxelNavigation.hh"                   
 32 #include "G4GeometryTolerance.hh"                 
 33 #include "G4VoxelSafety.hh"                       
 34                                                   
 35 #include "G4AuxiliaryNavServices.hh"              
 36                                                   
 37 #include <cassert>                                
 38 #include <ostream>                                
 39                                                   
 40 // *******************************************    
 41 // Constructor                                    
 42 // *******************************************    
 43 //                                                
 44 G4VoxelNavigation::G4VoxelNavigation()            
 45   : fVoxelAxisStack(kNavigatorVoxelStackMax,kX    
 46     fVoxelNoSlicesStack(kNavigatorVoxelStackMa    
 47     fVoxelSliceWidthStack(kNavigatorVoxelStack    
 48     fVoxelNodeNoStack(kNavigatorVoxelStackMax,    
 49     fVoxelHeaderStack(kNavigatorVoxelStackMax,    
 50 {                                                 
 51   fLogger= new G4NavigationLogger("G4VoxelNavi    
 52   fpVoxelSafety= new G4VoxelSafety();             
 53   fHalfTolerance= 0.5*G4GeometryTolerance::Get    
 54                                                   
 55 #ifdef G4DEBUG_NAVIGATION                         
 56   SetVerboseLevel(5);   // Reports most about     
 57 #endif                                            
 58 }                                                 
 59                                                   
 60 // *******************************************    
 61 // Destructor                                     
 62 // *******************************************    
 63 //                                                
 64 G4VoxelNavigation::~G4VoxelNavigation()           
 65 {                                                 
 66   delete fpVoxelSafety;                           
 67   delete fLogger;                                 
 68 }                                                 
 69                                                   
 70 // -------------------------------------------    
 71 // Input:                                         
 72 //    exiting:         : last step exited         
 73 //    blockedPhysical  : phys volume last exit    
 74 //    blockedReplicaNo : copy/replica number o    
 75 // Output:                                        
 76 //    entering         : if true, found candid    
 77 //    blockedPhysical  : candidate phys volume    
 78 //    blockedReplicaNo : copy/replica number      
 79 //    exiting:         : will exit current (mo    
 80 // In/Out                                         
 81 // -------------------------------------------    
 82                                                   
 83 // *******************************************    
 84 // ComputeStep                                    
 85 // *******************************************    
 86 //                                                
 87 G4double                                          
 88 G4VoxelNavigation::ComputeStep( const G4ThreeV    
 89                                 const G4ThreeV    
 90                                 const G4double    
 91                                       G4double    
 92                           /* const */ G4Naviga    
 93                                       G4bool&     
 94                                       G4ThreeV    
 95                                       G4bool&     
 96                                       G4bool&     
 97                                       G4VPhysi    
 98                                       G4int& b    
 99 {                                                 
100   G4VPhysicalVolume *motherPhysical, *samplePh    
101   G4LogicalVolume *motherLogical;                 
102   G4VSolid *motherSolid;                          
103   G4ThreeVector sampleDirection;                  
104   G4double ourStep=currentProposedStepLength,     
105   G4double motherSafety, motherStep = DBL_MAX;    
106   G4int localNoDaughters, sampleNo;               
107                                                   
108   G4bool initialNode, noStep;                     
109   G4SmartVoxelNode *curVoxelNode;                 
110   G4long curNoVolumes, contentNo;                 
111   G4double voxelSafety;                           
112                                                   
113   motherPhysical = history.GetTopVolume();        
114   motherLogical = motherPhysical->GetLogicalVo    
115   motherSolid = motherLogical->GetSolid();        
116                                                   
117   //                                              
118   // Compute mother safety                        
119   //                                              
120                                                   
121   motherSafety = motherSolid->DistanceToOut(lo    
122   ourSafety = motherSafety;                 //    
123                                                   
124 #ifdef G4VERBOSE                                  
125   if ( fCheck )                                   
126   {                                               
127     fLogger->PreComputeStepLog (motherPhysical    
128   }                                               
129 #endif                                            
130                                                   
131   //                                              
132   // Compute daughter safeties & intersections    
133   //                                              
134                                                   
135   // Exiting normal optimisation                  
136   //                                              
137   if ( exiting && validExitNormal )               
138   {                                               
139     if ( localDirection.dot(exitNormal)>=kMinE    
140     {                                             
141       // Block exited daughter volume             
142       //                                          
143       blockedExitedVol = *pBlockedPhysical;       
144       ourSafety = 0;                              
145     }                                             
146   }                                               
147   exiting = false;                                
148   entering = false;                               
149                                                   
150   // For extra checking,  get the distance to     
151   G4bool motherValidExitNormal = false;           
152   G4ThreeVector motherExitNormal(0.0, 0.0, 0.0    
153                                                   
154 #ifdef G4VERBOSE                                  
155   if ( fCheck )                                   
156   {                                               
157     // Compute early -- a) for validity           
158     //                  b) to check against an    
159     motherStep = motherSolid->DistanceToOut(lo    
160                                             lo    
161                                             tr    
162                                            &mo    
163                                            &mo    
164   }                                               
165 #endif                                            
166                                                   
167   localNoDaughters = (G4int)motherLogical->Get    
168                                                   
169   fBList.Enlarge(localNoDaughters);               
170   fBList.Reset();                                 
171                                                   
172   initialNode = true;                             
173   noStep = true;                                  
174                                                   
175   while (noStep)                                  
176   {                                               
177     curVoxelNode = fVoxelNode;                    
178     curNoVolumes = curVoxelNode->GetNoContaine    
179     for (contentNo=curNoVolumes-1; contentNo>=    
180     {                                             
181       sampleNo = curVoxelNode->GetVolume((G4in    
182       if ( !fBList.IsBlocked(sampleNo) )          
183       {                                           
184         fBList.BlockVolume(sampleNo);             
185         samplePhysical = motherLogical->GetDau    
186         if ( samplePhysical!=blockedExitedVol     
187         {                                         
188           G4AffineTransform sampleTf(samplePhy    
189                                      samplePhy    
190           sampleTf.Invert();                      
191           const G4ThreeVector samplePoint =       
192                      sampleTf.TransformPoint(l    
193           const G4VSolid *sampleSolid     =       
194                      samplePhysical->GetLogica    
195           const G4double sampleSafety     =       
196                      sampleSolid->DistanceToIn    
197                                                   
198           if ( sampleSafety<ourSafety )           
199           {                                       
200             ourSafety = sampleSafety;             
201           }                                       
202           if ( sampleSafety<=ourStep )            
203           {                                       
204             sampleDirection = sampleTf.Transfo    
205             G4double sampleStep =                 
206                      sampleSolid->DistanceToIn    
207 #ifdef G4VERBOSE                                  
208             if( fCheck )                          
209             {                                     
210               fLogger->PrintDaughterLog(sample    
211                                         sample    
212                                         sample    
213             }                                     
214 #endif                                            
215             if ( sampleStep<=ourStep )            
216             {                                     
217               ourStep = sampleStep;               
218               entering = true;                    
219               exiting = false;                    
220               *pBlockedPhysical = samplePhysic    
221               blockedReplicaNo = -1;              
222 #ifdef G4VERBOSE                                  
223               // Check to see that the resulti    
224               // This could be done only for s    
225               if ( fCheck )                       
226               {                                   
227                 fLogger->AlongComputeStepLog (    
228                   sampleDirection, localDirect    
229               }                                   
230 #endif                                            
231             }                                     
232 #ifdef G4VERBOSE                                  
233             if ( fCheck && ( sampleStep < kInf    
234                         && ( sampleStep >= mot    
235             {                                     
236                // The intersection point with     
237                // point from the mother volume    
238                fLogger->CheckDaughterEntryPoin    
239                                                   
240                                                   
241                                                   
242                                                   
243             }                                     
244 #endif                                            
245           }                                       
246 #ifdef G4VERBOSE                                  
247           else // ie if sampleSafety > outStep    
248           {                                       
249             if( fCheck )                          
250             {                                     
251               fLogger->PrintDaughterLog(sample    
252                                         sample    
253                                         G4Thre    
254             }                                     
255           }                                       
256 #endif                                            
257         }                                         
258       }                                           
259     }                                             
260     if (initialNode)                              
261     {                                             
262       initialNode = false;                        
263       voxelSafety = ComputeVoxelSafety(localPo    
264       if ( voxelSafety<ourSafety )                
265       {                                           
266         ourSafety = voxelSafety;                  
267       }                                           
268       if ( currentProposedStepLength<ourSafety    
269       {                                           
270         // Guaranteed physics limited             
271         //                                        
272         noStep = false;                           
273         entering = false;                         
274         exiting = false;                          
275         *pBlockedPhysical = nullptr;              
276         ourStep = kInfinity;                      
277       }                                           
278       else                                        
279       {                                           
280         //                                        
281         // Compute mother intersection if requ    
282         //                                        
283         if ( motherSafety<=ourStep )              
284         {                                         
285           // In case of check mode this is a d    
286           motherStep = motherSolid->DistanceTo    
287                               true, &motherVal    
288 #ifdef G4VERBOSE                                  
289           if ( fCheck )                           
290           {                                       
291             fLogger->PostComputeStepLog(mother    
292                                         mother    
293             if( motherValidExitNormal )           
294             {                                     
295               fLogger->CheckAndReportBadNormal    
296                                                   
297                                                   
298                                         "From     
299             }                                     
300           }                                       
301 #endif                                            
302           if( (motherStep >= kInfinity) || (mo    
303           {                                       
304 #ifdef G4VERBOSE                                  
305             if( fCheck ) // Error - indication    
306             {                                     
307               fLogger->ReportOutsideMother(loc    
308                                            mot    
309             }                                     
310 #endif                                            
311             motherStep = 0.0;                     
312             ourStep = 0.0;                        
313             exiting = true;                       
314             entering = false;                     
315                                                   
316             // validExitNormal= motherValidExi    
317             // exitNormal= motherExitNormal;      
318             // Useful only if the point is ver    
319             // => but it would need to be rota    
320             validExitNormal= false;               
321                                                   
322             *pBlockedPhysical = nullptr; // or    
323             blockedReplicaNo = 0;  // or mothe    
324                                                   
325             newSafety = 0.0;                      
326             return ourStep;                       
327           }                                       
328                                                   
329           if ( motherStep<=ourStep )              
330           {                                       
331             ourStep = motherStep;                 
332             exiting = true;                       
333             entering = false;                     
334                                                   
335             // Exit normal: Natural location t    
336             //                                    
337             validExitNormal = motherValidExitN    
338             exitNormal = motherExitNormal;        
339                                                   
340             if ( validExitNormal )                
341             {                                     
342               const G4RotationMatrix *rot = mo    
343               if (rot != nullptr)                 
344               {                                   
345                 exitNormal *= rot->inverse();     
346 #ifdef G4VERBOSE                                  
347                 if( fCheck )                      
348                 {                                 
349                   fLogger->CheckAndReportBadNo    
350                                                   
351                                                   
352                                                   
353                 }                                 
354 #endif                                            
355               }                                   
356             }                                     
357           }                                       
358           else                                    
359           {                                       
360             validExitNormal = false;              
361           }                                       
362         }                                         
363       }                                           
364       newSafety = ourSafety;                      
365     }                                             
366     if (noStep)                                   
367     {                                             
368       noStep = LocateNextVoxel(localPoint, loc    
369     }                                             
370   }  // end -while (noStep)- loop                 
371                                                   
372   return ourStep;                                 
373 }                                                 
374                                                   
375 // *******************************************    
376 // ComputeVoxelSafety                             
377 //                                                
378 // Computes safety from specified point to vox    
379 // using already located point                    
380 // o collected boundaries for most derived lev    
381 // o adjacent boundaries for previous levels      
382 // *******************************************    
383 //                                                
384 G4double                                          
385 G4VoxelNavigation::ComputeVoxelSafety(const G4    
386 {                                                 
387   G4SmartVoxelHeader *curHeader;                  
388   G4double voxelSafety, curNodeWidth;             
389   G4double curNodeOffset, minCurCommonDelta, m    
390   G4int minCurNodeNoDelta, maxCurNodeNoDelta;     
391   G4int localVoxelDepth, curNodeNo;               
392   EAxis curHeaderAxis;                            
393                                                   
394   localVoxelDepth = fVoxelDepth;                  
395                                                   
396   curHeader = fVoxelHeaderStack[localVoxelDept    
397   curHeaderAxis = fVoxelAxisStack[localVoxelDe    
398   curNodeNo = fVoxelNodeNoStack[localVoxelDept    
399   curNodeWidth = fVoxelSliceWidthStack[localVo    
400                                                   
401   // Compute linear intersection distance to b    
402   // to collected nodes at current level          
403   //                                              
404   curNodeOffset = curNodeNo*curNodeWidth;         
405   maxCurNodeNoDelta = fVoxelNode->GetMaxEquiva    
406   minCurNodeNoDelta = curNodeNo-fVoxelNode->Ge    
407   minCurCommonDelta = localPoint(curHeaderAxis    
408                       - curHeader->GetMinExten    
409   maxCurCommonDelta = curNodeWidth-minCurCommo    
410                                                   
411   if ( minCurNodeNoDelta<maxCurNodeNoDelta )      
412   {                                               
413     voxelSafety = minCurNodeNoDelta*curNodeWid    
414     voxelSafety += minCurCommonDelta;             
415   }                                               
416   else if (maxCurNodeNoDelta < minCurNodeNoDel    
417   {                                               
418     voxelSafety = maxCurNodeNoDelta*curNodeWid    
419     voxelSafety += maxCurCommonDelta;             
420   }                                               
421   else    // (maxCurNodeNoDelta == minCurNodeN    
422   {                                               
423     voxelSafety = minCurNodeNoDelta*curNodeWid    
424     voxelSafety += std::min(minCurCommonDelta,    
425   }                                               
426                                                   
427   // Compute isotropic safety to boundaries of    
428   // [NOT to collected boundaries]                
429                                                   
430   // Loop checking, 07.10.2016, JA                
431   while ( (localVoxelDepth>0) && (voxelSafety>    
432   {                                               
433     localVoxelDepth--;                            
434     curHeader = fVoxelHeaderStack[localVoxelDe    
435     curHeaderAxis = fVoxelAxisStack[localVoxel    
436     curNodeNo = fVoxelNodeNoStack[localVoxelDe    
437     curNodeWidth = fVoxelSliceWidthStack[local    
438     curNodeOffset = curNodeNo*curNodeWidth;       
439     minCurCommonDelta = localPoint(curHeaderAx    
440                         - curHeader->GetMinExt    
441     maxCurCommonDelta = curNodeWidth-minCurCom    
442                                                   
443     if ( minCurCommonDelta<voxelSafety )          
444     {                                             
445       voxelSafety = minCurCommonDelta;            
446     }                                             
447     if ( maxCurCommonDelta<voxelSafety )          
448     {                                             
449       voxelSafety = maxCurCommonDelta;            
450     }                                             
451   }                                               
452   if ( voxelSafety<0 )                            
453   {                                               
454     voxelSafety = 0;                              
455   }                                               
456                                                   
457   return voxelSafety;                             
458 }                                                 
459                                                   
460 // *******************************************    
461 // LocateNextVoxel                                
462 //                                                
463 // Finds the next voxel from the current voxel    
464 // in the specified direction                     
465 //                                                
466 // Returns false if all voxels considered         
467 //              [current Step ends inside same    
468 //         true  otherwise                        
469 //              [the information on the next v    
470 //               fVoxel* variables & "stacks"]    
471 // *******************************************    
472 //                                                
473 G4bool                                            
474 G4VoxelNavigation::LocateNextVoxel(const G4Thr    
475                                    const G4Thr    
476                                    const G4dou    
477 {                                                 
478   G4SmartVoxelHeader *workHeader=nullptr, *new    
479   G4SmartVoxelProxy *newProxy=nullptr;            
480   G4SmartVoxelNode *newVoxelNode=nullptr;         
481   G4ThreeVector targetPoint, voxelPoint;          
482   G4double workNodeWidth, workMinExtent, workC    
483   G4double minVal, maxVal, newDistance=0.;        
484   G4double newHeaderMin, newHeaderNodeWidth;      
485   G4int depth=0, newDepth=0, workNodeNo=0, new    
486   EAxis workHeaderAxis, newHeaderAxis;            
487   G4bool isNewVoxel = false;                      
488                                                   
489   G4double currentDistance = currentStep;         
490                                                   
491   // Determine if end of Step within current v    
492   //                                              
493   for (depth=0; depth<fVoxelDepth; ++depth)       
494   {                                               
495     targetPoint = localPoint+localDirection*cu    
496     newDistance = currentDistance;                
497     workHeader = fVoxelHeaderStack[depth];        
498     workHeaderAxis = fVoxelAxisStack[depth];      
499     workNodeNo = fVoxelNodeNoStack[depth];        
500     workNodeWidth = fVoxelSliceWidthStack[dept    
501     workMinExtent = workHeader->GetMinExtent()    
502     workCoord = targetPoint(workHeaderAxis);      
503     minVal = workMinExtent+workNodeNo*workNode    
504                                                   
505     if ( minVal<=workCoord+fHalfTolerance )       
506     {                                             
507       maxVal = minVal+workNodeWidth;              
508       if ( maxVal<=workCoord-fHalfTolerance )     
509       {                                           
510         // Must consider next voxel               
511         //                                        
512         newNodeNo = workNodeNo+1;                 
513         newHeader = workHeader;                   
514         newDistance = (maxVal-localPoint(workH    
515                     / localDirection(workHeade    
516         isNewVoxel = true;                        
517         newDepth = depth;                         
518       }                                           
519     }                                             
520     else                                          
521     {                                             
522       newNodeNo = workNodeNo-1;                   
523       newHeader = workHeader;                     
524       newDistance = (minVal-localPoint(workHea    
525                   / localDirection(workHeaderA    
526       isNewVoxel = true;                          
527       newDepth = depth;                           
528     }                                             
529     currentDistance = newDistance;                
530   }                                               
531   targetPoint = localPoint+localDirection*curr    
532                                                   
533   // Check if end of Step within collected bou    
534   //                                              
535   depth = fVoxelDepth;                            
536   {                                               
537     workHeader = fVoxelHeaderStack[depth];        
538     workHeaderAxis = fVoxelAxisStack[depth];      
539     workNodeNo = fVoxelNodeNoStack[depth];        
540     workNodeWidth = fVoxelSliceWidthStack[dept    
541     workMinExtent = workHeader->GetMinExtent()    
542     workCoord = targetPoint(workHeaderAxis);      
543     minVal = workMinExtent+fVoxelNode->GetMinE    
544                                                   
545     if ( minVal<=workCoord+fHalfTolerance )       
546     {                                             
547       maxVal = workMinExtent+(fVoxelNode->GetM    
548                             *workNodeWidth;       
549       if ( maxVal<=workCoord-fHalfTolerance )     
550       {                                           
551         newNodeNo = fVoxelNode->GetMaxEquivale    
552         newHeader = workHeader;                   
553         newDistance = (maxVal-localPoint(workH    
554                     / localDirection(workHeade    
555         isNewVoxel = true;                        
556         newDepth = depth;                         
557       }                                           
558     }                                             
559     else                                          
560     {                                             
561       newNodeNo = fVoxelNode->GetMinEquivalent    
562       newHeader = workHeader;                     
563       newDistance = (minVal-localPoint(workHea    
564                   / localDirection(workHeaderA    
565       isNewVoxel = true;                          
566       newDepth = depth;                           
567     }                                             
568     currentDistance = newDistance;                
569   }                                               
570   if (isNewVoxel)                                 
571   {                                               
572     // Compute new voxel & adjust voxel stack     
573     //                                            
574     // newNodeNo=Candidate node no at             
575     // newDepth =refinement depth of crossed v    
576     // newHeader=Header for crossed voxel         
577     // newDistance=distance to crossed voxel b    
578     //                                            
579     if ( (newNodeNo<0) || (newNodeNo>=G4int(ne    
580     {                                             
581       // Leaving mother volume                    
582       //                                          
583       isNewVoxel = false;                         
584     }                                             
585     else                                          
586     {                                             
587       // Compute intersection point on the lea    
588       // voxel boundary that is hit               
589       //                                          
590       voxelPoint = localPoint+localDirection*n    
591       fVoxelNodeNoStack[newDepth] = newNodeNo;    
592       fVoxelDepth = newDepth;                     
593       newVoxelNode = nullptr;                     
594       while ( newVoxelNode == nullptr )           
595       {                                           
596         newProxy = newHeader->GetSlice(newNode    
597         if (newProxy->IsNode())                   
598         {                                         
599           newVoxelNode = newProxy->GetNode();     
600         }                                         
601         else                                      
602         {                                         
603           ++fVoxelDepth;                          
604           newHeader = newProxy->GetHeader();      
605           newHeaderAxis = newHeader->GetAxis()    
606           newHeaderNoSlices = (G4int)newHeader    
607           newHeaderMin = newHeader->GetMinExte    
608           newHeaderNodeWidth = (newHeader->Get    
609                              / newHeaderNoSlic    
610           newNodeNo = G4int( (voxelPoint(newHe    
611                              / newHeaderNodeWi    
612           // Rounding protection                  
613           //                                      
614           if ( newNodeNo<0 )                      
615           {                                       
616             newNodeNo=0;                          
617           }                                       
618           else if ( newNodeNo>=newHeaderNoSlic    
619           {                                       
620             newNodeNo = newHeaderNoSlices-1;      
621           }                                       
622           // Stack info for stepping              
623           //                                      
624           fVoxelAxisStack[fVoxelDepth] = newHe    
625           fVoxelNoSlicesStack[fVoxelDepth] = n    
626           fVoxelSliceWidthStack[fVoxelDepth] =    
627           fVoxelNodeNoStack[fVoxelDepth] = new    
628           fVoxelHeaderStack[fVoxelDepth] = new    
629         }                                         
630       }                                           
631       fVoxelNode = newVoxelNode;                  
632     }                                             
633   }                                               
634   return isNewVoxel;                              
635 }                                                 
636                                                   
637 // *******************************************    
638 // ComputeSafety                                  
639 //                                                
640 // Calculates the isotropic distance to the ne    
641 // specified point in the local coordinate sys    
642 // The localpoint utilised must be within the     
643 // *******************************************    
644 //                                                
645 G4double                                          
646 G4VoxelNavigation::ComputeSafety(const G4Three    
647                                  const G4Navig    
648                                  const G4doubl    
649 {                                                 
650   G4VPhysicalVolume *motherPhysical, *samplePh    
651   G4LogicalVolume *motherLogical;                 
652   G4VSolid *motherSolid;                          
653   G4double motherSafety, ourSafety;               
654   G4int sampleNo;                                 
655   G4SmartVoxelNode *curVoxelNode;                 
656   G4long curNoVolumes, contentNo;                 
657   G4double voxelSafety;                           
658                                                   
659   motherPhysical = history.GetTopVolume();        
660   motherLogical = motherPhysical->GetLogicalVo    
661   motherSolid = motherLogical->GetSolid();        
662                                                   
663   if( fBestSafety )                               
664   {                                               
665     return fpVoxelSafety->ComputeSafety( local    
666   }                                               
667                                                   
668   //                                              
669   // Compute mother safety                        
670   //                                              
671                                                   
672   motherSafety = motherSolid->DistanceToOut(lo    
673   ourSafety = motherSafety;                 //    
674                                                   
675   if( motherSafety == 0.0 )                       
676   {                                               
677 #ifdef G4DEBUG_NAVIGATION                         
678     // Check that point is inside mother volum    
679     EInside  insideMother = motherSolid->Insid    
680                                                   
681     if( insideMother == kOutside )                
682     {                                             
683       G4ExceptionDescription message;             
684       message << "Safety method called for loc    
685          << "Location for safety is Outside th    
686          << "The approximate distance to the s    
687          << "(safety from outside) is: "          
688          << motherSolid->DistanceToIn( localPo    
689       message << "  Problem occurred with phys    
690          << " Name: " << motherPhysical->GetNa    
691          << " Copy No: " << motherPhysical->Ge    
692          << "    Local Point = " << localPoint    
693       message << "  Description of solid: " <<    
694             << *motherSolid << G4endl;            
695       G4Exception("G4VoxelNavigation::ComputeS    
696                   JustWarning, message);          
697     }                                             
698                                                   
699     // Following check is NOT for an issue - i    
700     //  It is allowed that a solid gives appro    
701     //                                            
702     if( insideMother == kInside ) // && fVerbo    
703     {                                             
704       G4ExceptionDescription messageIn;           
705                                                   
706       messageIn << " Point is Inside, but safe    
707       messageIn << " Inexact safety for volume    
708              << "  Solid: Name= " << motherSol    
709              << "   Type= " << motherSolid->Ge    
710       messageIn << "  Local point= " << localP    
711       messageIn << "  Solid parameters: " << G    
712       G4Exception("G4VoxelNavigation::ComputeS    
713                   JustWarning, messageIn);        
714     }                                             
715 #endif                                            
716     // if( insideMother != kInside )              
717     return 0.0;                                   
718   }                                               
719                                                   
720 #ifdef G4VERBOSE                                  
721   if( fCheck )                                    
722   {                                               
723     fLogger->ComputeSafetyLog (motherSolid,loc    
724   }                                               
725 #endif                                            
726   //                                              
727   // Compute daughter safeties                    
728   //                                              
729   // Look only inside the current Voxel only (    
730   //                                              
731   curVoxelNode = fVoxelNode;                      
732   curNoVolumes = curVoxelNode->GetNoContained(    
733                                                   
734   for ( contentNo=curNoVolumes-1; contentNo>=0    
735   {                                               
736     sampleNo = curVoxelNode->GetVolume((G4int)    
737     samplePhysical = motherLogical->GetDaughte    
738                                                   
739     G4AffineTransform sampleTf(samplePhysical-    
740                                samplePhysical-    
741     sampleTf.Invert();                            
742     const G4ThreeVector samplePoint = sampleTf    
743     const G4VSolid* sampleSolid= samplePhysica    
744     G4double sampleSafety = sampleSolid->Dista    
745     if ( sampleSafety<ourSafety )                 
746     {                                             
747       ourSafety = sampleSafety;                   
748     }                                             
749 #ifdef G4VERBOSE                                  
750     if( fCheck )                                  
751     {                                             
752       fLogger->ComputeSafetyLog(sampleSolid, s    
753                                 sampleSafety,     
754     }                                             
755 #endif                                            
756   }                                               
757   voxelSafety = ComputeVoxelSafety(localPoint)    
758   if ( voxelSafety<ourSafety )                    
759   {                                               
760     ourSafety = voxelSafety;                      
761   }                                               
762   return ourSafety;                               
763 }                                                 
764                                                   
765 void G4VoxelNavigation::RelocateWithinVolume(     
766                                                   
767 {                                                 
768   auto motherLogical = motherPhysical->GetLogi    
769                                                   
770   assert(motherLogical != nullptr);               
771                                                   
772   if ( auto pVoxelHeader = motherLogical->GetV    
773     VoxelLocate( pVoxelHeader, localPoint );      
774 }                                                 
775                                                   
776 // *******************************************    
777 // SetVerboseLevel                                
778 // *******************************************    
779 //                                                
780 void  G4VoxelNavigation::SetVerboseLevel(G4int    
781 {                                                 
782   if( fLogger != nullptr ) { fLogger->SetVerbo    
783   if( fpVoxelSafety != nullptr) { fpVoxelSafet    
784 }                                                 
785