Problem 1052 - Infinite loop in G4SubtractionSolid::DistanceToIn()
Summary: Infinite loop in G4SubtractionSolid::DistanceToIn()
Status: RESOLVED INVALID
Alias: None
Product: Geant4
Classification: Unclassified
Component: geometry/solids (show other problems)
Version: 9.2
Hardware: All All
: P5 minor
Assignee: Vladimir.Grichine
URL:
Depends on:
Blocks:
 
Reported: 2009-03-10 10:27 CET by Svetlana Biktemerova
Modified: 2009-09-18 14:10 CEST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description Svetlana Biktemerova 2009-03-10 10:27:13 CET
from http://hypernews.slac.stanford.edu/HyperNews/geant4/get/geometry/956.html

The next code leads Geant4 to the infinite loop. 

//___________________________________________________________________________________________________________________________
void test(){
     const char* nms[]={"kOutside","kSurface","kInside"};

     double t_dz=0.3392505000;
     double t_rad=85.94;
     double p_rmz=85.9400000000;
     double p_rpz=99.2300000000;
     double p_hz=0.3392505000;

     G4Paraboloid* par = new G4Paraboloid("par",p_hz,p_rmz,p_rpz);
     G4DisplacedSolid* pard=new G4DisplacedSolid("disp_par",par,new G4RotationMatrix(0.,180.*deg,0.),G4ThreeVector(0.,0.,0.));
     G4Tubs* t=new G4Tubs("absorber",0.,t_rad,t_dz,0.*deg,360.*deg);
     G4SubtractionSolid* seg1 = new G4SubtractionSolid("par1_i",pard,t,0,0);

     G4ThreeVector v(-82.1262056167, 40.0738142048, 0.0732052691);
     G4ThreeVector dir(-0.00013143732014871606, 0.00006413537198823375,-0.99999998930544242715);
     dir=dir.unit();

     printf("%20.10f %20s %20.10f\n",v.x(),nms[t->Inside(v)],t->DistanceToOut(v,dir));
     printf("%20.10f %20s %20.10f\n",v.x(),nms[pard->Inside(v)],pard->DistanceToIn(v,dir));

     G4ThreeVector v0(-81.97424905536260553163, 39.99966638606156266178, 1156.18746249999981046130);
     printf("infinite_loop...\n");
     seg1->DistanceToIn(v0,dir);
     printf("finished...\n");
}
//___________________________________________________________________________________________________________________________

The reason is printed to the output: both constituents solid say that point "v" is outside, and both of them return 0.0 as distance to in/out. 

G4SubtractionSolid::DistanceToIn() uses the "while" loop:
//___________________________________________________________________________________________________________________________
while( Inside(p+dist*v) == kOutside )  // pushing loop
{
  disTmp = fPtrSolidB->DistanceToOut(p+dist*v,v) ;
  dist += disTmp ;

  if( Inside(p+dist*v) == kOutside ){ 
    disTmp = fPtrSolidA->DistanceToIn(p+dist*v,v) ;
    if(disTmp == kInfinity){return kInfinity;}                 
    dist += disTmp ;
  }
}
//___________________________________________________________________________________________________________________________

as "disTmp" is always 0., this loop is infinite. I suggest to add a simple check: if both "disTmp" are zeroes, move them manually by a small number, like 1.e-9. 

It also seems that other G4BooleanSolids are also "dangerous", but I do not have exact examples for them. 

best regards, Svetlana Biktemerova
Comment 1 tatiana.nikitina 2009-08-04 15:20:19 CEST
Dear Svetlana,

 The infinite loop is caused by the wrong way of using boolean operations.
 In your case two solids have touching surfaces, when you subtract such solids, you will have a inconsistency. To avoid this kind of problem, you can make one solid smaller by a small value(normally 1.e-6 mm), then you will not have a problem with touching surfaces.   

 Best Regards,
 Tatiana Nikitina
Comment 2 Svetlana Biktemerova 2009-09-18 11:16:46 CEST
Dear Tatiana,

I'm sorry for inconvenience  and thank you.

But, am I right that this problem is still can be valid for the 
"intersection part" of volumes which are in G4SubtractionSolid, although 
the infinity loop will be caused much rarely?
Comment 3 tatiana.nikitina 2009-09-18 14:10:47 CEST
Dear Svetlana,

 If a boolean operation is defined correctly and your application still enter in the Infinite Loop, that means the wrong replay of one of the solids used for the boolean operation. This is an error of the solid and not of the boolean operation.
 
 Best Regards,
 Tatiana Nikitina