Surface Normal in Complex Geometry

Dear experts,

Dealing with a simulation of synchrotron radiation, I’m interested in creating an artificial x-ray reflection. Artificial in a sense that normal, not optical photons shall be reflected, given their incident angle matches a certain condition.

For this to work, the surface normal of a volume is required in order to determine the incident angle once a photon hits a surface. This post was already very helpful in getting started.

But I’m lacking the deeper understanding of the SurfaceNormal which is retrieved in the example via the solid:

G4StepPoint * preStep = aStep->GetPreStepPoint();
G4ThreeVector gammaDir = preStep->GetMomentum()/preStep->GetMomentum().mag(); 
G4ThreeVector stepPos = preStep->GetPosition();

const G4VTouchable * touchable = preStep->GetTouchable();

const G4RotationMatrix * rot = touchable->GetRotation();
G4RotationMatrix rotInv = rot->inverse();
G4ThreeVector transl = touchable->GetTranslation();
G4VSolid * sector = touchable->GetSolid();
G4String name = touchable->GetVolume()->GetName();
G4ThreeVector posLoc = *rot * (stepPos - transl);
G4ThreeVector norm = -sector->SurfaceNormal(posLoc);

G4ThreeVector gammDirLoc = *rot*gammaDir;

G4double incidentAngle = acos( norm.dot(gammDirLoc) );

return incidentAngle;

Based on the actual position in local coordinates, the surface normal is calculated and gives a G4ThreeVector. My specific problem deals with a geometry that includes a torus. An electron beam propagates through the torus and emits photons. The transformation to local coordinates is already not very obvious for this geometry.

But how can I image the surface normal in that case … is it always perpendicular to the surface of the torus, here the inner surface? Such that, if a photon hits the surface, the angle from the function above would return this incident angle?

I’d be very grateful for any further insight - thanks in advance!

The surface normal is always perpendicular to the nearest surface of the volume (i.e., normal to the tangent plane at the point), and directed outward from the bulk of the volume. For a torus, that means that normals in the region around the “donut hole” will be pointed toward the center of that hole. That is still outward from the torus’ bulk (i.e., where the material is).

Thanks a lot for your explanation. Given a geometry as in the picture attached

(red track electron, green photons; torus center towards the lower left).
Would that mean, the normal at the outward directed surface (where the photon tracks end) is also directed towards the center of the torus?

No. For the photons (green) travelling inside the torus bulk that impact the outward surface, the surface normal there would be pointed outward (toward world-volume infinity).

However, I notice that in the code you quoted, the actual outward surface normal returned by the solid is reversed:

G4ThreeVector norm = -sector->SurfaceNormal(posLoc);

I have written similar code myself to deal with reflections or refractions at a volume boundary. The reversal above is what you need if the photon is passing from the world (or wherever) into the volume of interest (the angle of incidence is computed relative to a normal pointed in the same direction as propagation).

In your drawing, the photon is passing outward from the volume of interest to the world, so the normal shouldn’t be inverted. You’ll likely need some logic in your code to decide whether the vector flip is needed or not.

Thanks again - this is valuable input. I will look a bit further into it in order to understand these angles better. It would be excellent to have a way for displaying them. But I guess this might prove to be difficult?

One way I could think of, is to transform the coordinates of the normal back to the mother volume (global EU coordinate system). Would that make any sense?
Using the surface normal as derived with (not inverted)

G4ThreeVector norm = sector->SurfaceNormal(posLoc);

And transforming them to the global reference frame via

G4ThreeVector normGlob = rotInv*norm + transl;

It seems, for instance, that all normals for track2 would point to the center at (0,-1.59)