Problem 1081 - Problem is DistanceToOut for G4Tubs and G4Torus (At least?)
Summary: Problem is DistanceToOut for G4Tubs and G4Torus (At least?)
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: geometry/solids (show other problems)
Version: other
Hardware: PC Linux
: P5 normal
Assignee: tatiana.nikitina
URL:
: 1086 (view as problem list)
Depends on:
Blocks:
 
Reported: 2009-09-24 02:22 CEST by Pierre
Modified: 2010-10-01 17:12 CEST (History)
1 user (show)

See Also:


Attachments
Modified ExampleN02 (52.95 KB, application/x-gzip)
2009-09-24 17:33 CEST, Pierre
Details

Note You need to log in before you can comment on or make changes to this problem.
Description Pierre 2009-09-24 02:22:01 CEST
I have used G4Tubs and G4Torus (the faulty code is the same) between 0 and Pi.

It happened that I was sending some geantino (RayTracer) almost parallel to the plane X=0. When the solid is within a UnionSolid (See example), GEANT4 found correctly the intersection with the surface, but when it tried to compute the DistanceToOut, the part taking care of the cutting plane messed up, probably because of Round Off errors; the distanceToOut returned is 0.

I propose the following change in G4Tubs.cc:1417 ->1555 by something like that

if (!fPhiFullTube) {
  G4ThreeVector exit = p+sr*v;
  G4double exitPhi = std::atan2(exit.y(),exit.x());
  if (exitPhi < 0) exitPhi + twopi;
  
  G4double srSE[2];
  G4double phi[2] = {fSPhi, fSPhi + fDPhi};
  if (exitPhi < fSPhi - halfAngTolerance  && exitPhi> fSPhi + fDPhi + halfAngTolerance){
    G4double phi;
    for (int i=0 ;i<2 ;++i){
      if (std::cos(phi) == 0.) srSE[i] = (v.x() != 0.) ? - p.x()/v.x() : kInfinity;
      else {
        if (std::sin(phi) == 0.) srSE[i] = (v.y() != 0.) ? - p.x()/v.y() : kInfinity;
        else srSE[i] = (p.x()*std::tan(phi) - p.y())/(v.y() - v.x()*std::tan(phi));
      }
      if (srSE[i] < 0.) srSE[i] = kInfinity;
    }
    if ( srSE[1] < sr) sr = srSE[1];
    if ( srSE[2] < sr) sr = srSE[2];
  }
}

Now I have to admit I did not completly understand the code, and I may have forgotten some particular case (I certainly hope not).

The code in G4Torus is the same, and maybe also in other solids using the limitation (StartPhi, DeltaPhi)

Regards
Comment 1 Gabriele Cosmo 2009-09-24 09:22:17 CEST
Can you please provide a test case where the faulty behavior can be reproduced ?
Also can you please specify the version of Geant4 you're using and the platform (system, compiler) ?
Comment 2 Pierre 2009-09-24 17:33:44 CEST
Created attachment 52 [details]
Modified ExampleN02

Since the problem seems to happen only when the volumes are in a combination of UnionSolid, I recreated the same volume I initially have problem with. The particle are geantino in the correct position/direction to trigger the problem.
Comment 3 Pierre 2009-09-24 17:54:13 CEST
Sorry, I thought I had attached the example already.

Compiled with gcc 4.3.2 and gcc4.1.2 on Scientific Linux, tested on GEANT 4.9.0.p02 and 4.9.2.p02.

The symptoms are different on OSX (Leopard) with g++4.0 : the particle is just stacked.

To my understanding, the fact that the solid is in a UnionSolid makes the matter worse : The program loops infinitely in UnionSolid::DistanceToOut.

Regards.
Comment 4 tatiana.nikitina 2009-09-25 10:45:51 CEST
 Dear Pierre,

 Thank you for sending the example and for your comments.
 By looking in the example, I found that you use a Boolean operations for solids with sharing surfaces(phi planes). Most probably, this causing the problem with tracking.
Boolean operations in Geant4 have to be used with solids with overlaps. 
If the solids have sharing surfaces,   the tracking can be confused, but also the visualisation can be wrong.
 In your case, you can add  small overlaps( 1 micron), in order to avoid sharing surfaces.    
 
 Please, let us know, if this helps.

 Best Regards,
 Tatiana Nikitina
Comment 5 Pierre 2009-09-28 18:27:02 CEST
Thanks for the quick answer.
Unfortunately, having overlapping volume does not seem to solve the problem. I keep looking around to see if I can find some reason to that.
Comment 6 tatiana.nikitina 2009-09-29 14:57:01 CEST
 Dear Pierre,

 Thank you for the message and for the test.
 After your message, I tried to simplify provided example in order to check the replay of the Solids. 
If I use only one Rotated LargeTorus and I shoot the particle along the 
 phi axe, the problem is appears(bouncing between Target and World).
 I think, there is a problem in the Replay of G4Torus for phi section, I will continue to investigate.
  
 I have also tested the G4Tubs in the same configurations. 
 The Replay of G4Tubs is correct. 

 Best Regards,
 Tatiana Nikitina
Comment 7 Pierre 2009-09-29 20:46:25 CEST
Dear Tatiana,

I am sorry, but I am not sure about what the "Replay" is.

I have to correct my previous answer: it seems that the overlapping helps but does not solve the problem. In any case I thought that the tolerance are making to solids put beside each other slightly overlapping... Is it wrong ?

Anyway, in G4Torus::DistanceToIn, something is bothering me:
Lines 965 and 997 there are 

if ( sphi < 0 )  { sphi = 0 ; }

I do not understand that test. It would be more logical to me if instead of having
if (sphi < snxt)

we had :
if (0 < sphi && nsphi < snxt)
which would reflect the fact that we are close to the limit and we have a possibility to cross the phi plane.

For sure that modification makes my problem disappear...

Cheers,
Pierre
Comment 8 Pierre 2009-09-30 03:25:04 CEST
Hello again (the last one today I hope)

In the case SPhi<0, the RayTracer shows only the part of the Torus which has Phi>0. I think it comes from SolveNumericJT at the line 287

if (theta < 0)  { theta += twopi; }

In the case SPhi < 0, the following condition cannot be true

if ( (theta - fSPhi >= - kAngTolerance*0.5)
      && (theta - (fSPhi + fDPhi) <=  kAngTolerance*0.5) )

Since the constructor is taking care of the case where fSPhi < -Pi, then I guess it would be enough to have

if (fSPhi >=0 && theta < 0)  { theta += twopi; }

Cheers,
Pierre
Comment 9 Pierre 2009-09-30 03:28:06 CEST
Once again me (I forgot to commit that message before)

in G4Torus::DistanceToOut(p,v) if I understand correctly, there can be an intersection between the track and the phi-planes only if the "pDistX" (X=E or S) and "compX" have the same sign. If it is the case. I believe that the lines 1356 and 1424 are incorrect and sphi should receive kInfinity instead of "0".

I also wonder about the case managed line 1283
          if ( (compS>=0) && (compE>=0) )
          {
            sphi=kInfinity;
          }
          else
          {
            sphi=0;
          }
I have a feeling that it is wrong but I cannot be sure.

Cheers,
Pierre
Comment 10 tatiana.nikitina 2009-10-01 10:13:19 CEST
 Dear Pierre,

 "Replay" of the solid is what replaying  DistanceToIn(), DistanceToOut() or SurfaceNormal() for given points, directions.
 I case of the G4Torus it seems to be a problem with DistanceToIn() or DistanceToOut() when the point is On phi surface. It can be a problem with use of kAngTolerance, specialy for Torus of (0,pi), beacause 'angle' becomming a plane.
Thank you for the comments about the code, I will have a look.

Yes, overlapping is what you did.

 Best Regards,
 Tatiana
Comment 11 tatiana.nikitina 2009-11-19 11:01:46 CET
*** Problem 1086 has been marked as a duplicate of this problem. ***
Comment 12 tatiana.nikitina 2009-11-27 10:59:07 CET
Dear Pierre,

 Thank very much you for usefull comments and suggestions.
 You are right(comment#8) there is a problem with theta.
 Your proposal is correct, only the kAngTolerance has to be added due to numerical
 accupacy. Also case with Sphi<-pi has to be added with theta=-twopi;

 This fix will be available in the next december release.

 The other problem is the wrong 'Replay' (DistanceToIn=DistanceToOut=0) for the geantinos on the Phi Surface and going almost parallel to PhiSection. These errors are due to the incorrect use of kAngTolerance.
It has to be carrefully added and tested.

 Best Regards,
 Tatiana Nikitina
Comment 13 Pierre 2010-07-08 18:07:13 CEST
Hi Tatiana,

I am sorry to come back with it, but several versions of GEANT later, I still have bugs in G4Torus and G4Tubs when I have rays grazing the Phi-planes. I think I localized the problem, at least for G4Torus.

In G4Torus::DistanceToOut( const G4ThreeVector& p, const G4ThreeVector& v,
                           const G4bool calcNorm, G4bool *validNorm,
                           G4ThreeVector  *n  ) const

when we are testing the Phi-planes, we are comparing pDist (shortest distance between the point and the plane) (E/S) to the tolerance (lines 1232, 1259, 1237 and 1395 of G4Torus.cc). This makes little sense, considering that we just calculated sphi which is the distance to the phi-plane in the direction of the momentum. On the other hand, I agree that if sphi < Tolerance/2, then it can be approximate to zero. 
DistanceToIn seems to follow that policy, even if sphi is calculated only if Dist>Tolerance/2. Which means that if we are very close to the phi-plane, the phi-plane is not taken into account for DistToIn... Is that logic?

I have the feeling that we have a similar problem with G4Tubs, although since the code is rather different I am not yet sure.

By the way, is it wise to have so many different codes for the solids of revolution? The phi-plane calculations for instance should be very similar for the yub, sphere, torus... Well, I guess you ruled that out for a good reason.

regards,
Pierre
Comment 14 tatiana.nikitina 2010-07-09 09:20:39 CEST
Dear Pierre,

 Thank you for your comments.

 The problem in Phi section was not solved yet.
 I agree with you that it will be good make code in Tubs and Torus similar, where it is possible. I was working on it. When it is ready, I will let you know.

 Best Regards,

 Tatiana Nikitina
Comment 15 tatiana.nikitina 2010-08-03 17:05:20 CEST
 Dear Pierre,

 Thank you again for your remarques.
 You was right to pointing out the code in DistanceToOut(p,v,...) with
...
 if(pDistS>-kCarTolerance*0.5){sphi = 0;}
...
 This is causing a problem. 
 This condition (pDistS>-kCarTolerance*0.5) means only that the point p is situated almost on Phi plane.  But the distance to out is depending on direction v, it is NOT always zero.

 I'm testing a fix for this problem. It will be available in the next release.
 If you are interested, I can send you the fix already.

 Best Regards,

 Tatiana Nikitina
Comment 16 Gabriele Cosmo 2010-10-01 17:12:08 CEST
The fix is now available in the patched release 9.3.p02.