Problem 284 - G4Navigator fails to rotate surface normals correctly (optical photons)
Summary: G4Navigator fails to rotate surface normals correctly (optical photons)
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: geometry (show other problems)
Version: 3.2
Hardware: PC Linux
: P2 major
Assignee: John Apostolakis
URL:
Depends on:
Blocks:
 
Reported: 2001-08-10 08:34 CEST by tipton
Modified: 2006-04-11 09:08 CEST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description tipton 2001-08-10 08:34:14 CEST
Dear G4folks,
   I am having trouble with optical photons but have isolated
the difficulty to G4Navigator behavior.  G4OpBoundaryProcess needs surface
normals from the Navigator to determine reflections etc. It uses
source/processes/optical/src/G4OpBoundaryProcess.c:248-262
	theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
        theGlobalNormal = theNavigator->GetLocalToGlobalTransform().
	                            TransformAxis(theLocalNormal);
 According to source/geometry/volumes/include/G4Navigator.hh:242
        // (The normal is in the coordinate system of the final volume.)
   for GetLocalExitNormal.
  I have two conditions where this does not happen and optical photon
tracking is affected severely:

  a)  I track optical photons in the interior of a thin cylindrical shell,
G4Tubs.   The inner surface of a tube is not convex so that G4Navigator sets
fValidExitNormal=false, but it still attempts to calculate an
exit normal anyway in G4Navigator.cc:613.  The returned normal
from this calculation is often wrong, though, because it is never
rotated out of the local coordinates of the solid.
    The normals are still useful as not all surfaces can be convex,
and if there is an attempt to calculate them, they should be correct.  The
code seems fixed if the rotation from other normal calculations is adopted.
ie. possibly insert at G4Navigator.cc:613 (borrowed from G4NormalNavigation:150)
       fExitNormal= motherLogical->GetSolid()->SurfaceNormal(FinalPoint);
       // BT-- fix to move out of local coordinates
       const G4RotationMatrix *rot=motherPhysical->GetRotation();
       if (rot)
	 {
	   fExitNormal*=rot->inverse();
	 }


  b) A more general problem concerns the return coordinate system
of GetLocalExitNormal in all cases.  The comments on
G4Navigator::GetLocalExitNormal()
indicate that the returned normal is rotated into the local coordinates
of the current volume.  But in every trace of the code, I see that
the returned normal is in fact in global coordinates, or at least
in the coordinate system of the mother of the surface.
     Hence, the call to
	theGlobalNormal = theNavigator->GetLocalToGlobalTransform().
	                            TransformAxis(theLocalNormal);
can overrotate the normal, depending on whether the current volume
  is rotated.  Incorrect behavior occurs often when
a photon is crosses a boundary and enters a new, rotated
volume which is not in the heirachy of the volume it exited.
Strange optical photon trajectories result.
       I kludge this problem by commenting out the above line
in G4OpBoundaryProcess:260 and substituting
       theGlobalNormal=theLocalNormal;
  A more general solution is needed though...I think other routines
like ray tracing also use the normals.

    I give a concrete example to make this clear:
   http://www.krl.caltech.edu/~tipton/kamland/mc/N06.tgz is
example N06 with visualization.  See N06/vismacro.mac to run.
I added to the default example a symmetric cube of air
with a theta rotation controlled by the environment variable
  EXN06_TANK_ROT_DEG
  By changing this to 0,90,180,270 deg. the path of an optical
photon completely changes, though the cube is symmetric and the
rotations are superficial. (Kudos to Glenn Horton-Smith for setting
most of this example up).

   Thanks for your help!
   Bryan Tipton
Comment 1 Gabriele Cosmo 2001-08-13 04:46:59 CEST
Thanks for the detailed report.
The problem is under investigation.
Comment 2 John Apostolakis 2002-06-06 08:28:59 CEST
Dear Brian,
              Thank once again for your clear report and test case.  These have
proven very helpful in hunting down the contributing factors to this problem.

  We believe that we have now found the different issues contributing to this
problem and resolved them.  A candidate tag including the fixes for this
problem has been created and is under system testing (you should also have
received the fix by email last week).  The fixes should now appear in the
upcoming public release at the end of this month.

In our trial it provides correct behaviour for the test case of this problem
report.

With much appreciation for your excellent report,

  John Apostolakis
Comment 3 erik.kieft 2006-04-11 09:08:59 CEST
Dear Geant4 developers,

Recently I had a problem very similar to the one described here, and I just
stumbled across this old problem report. When comparing the suggestion made by
B.T. under a) with the code that ended up later in G4Navigator.cc (e.g., lines
883-890 in release 8.0.p1), I found that apparently the essential "->inverse()"
part was (wrongfully) omitted.

After I changed
fGrandMotherExitNormal *= (*mRot);
to
fGrandMotherExitNormal *= mRot->inverse();
in my copy of the code, the problem was solved (at least in my case). Perhaps it
is a good idea to include such a modification in the next Geant4 release.

With kind regards,

  Erik Kieft