Specular reflection of neutron

Hi experts!

I am looking to implement specular reflection of low energy neutrons inside a cylinder.

Best regards,

Please fill out the following information to help in answering your question, and also see tips for posting code snippets. If you don’t provide this information it will take more time to help with your problem!

Geant4 Version: 11.03
Operating System: Ubuntu
CMake Version:


Dear Eyvaz,

thank you for raising this question. According to the manual, Geant4 cover neutron transport down to thermal energies (so around 25 meV).

What is the energy of your neutrons?


Thank you for your reply Mr. Alvaro.

I am looking for very cold neutron energy range 3x10^-7 eV up to 5x10^-5 eV.

Best regards,

Geant4 definitely does not cover those energies, which correspond to “cryogenic” neutrons (“temperatures” of uK to nK). You will probably need either a special purpose simulation for neutron reflectors, or you might be able to write your own process for Geant4 if you know, or can derive, the kinematics involved.

Thank you for your response.

We actually have written own simulation process in Geant4 for very cold neutron reflection in diamond nano powder material…

Next, I need to demonstrate specular reflection of low energy neutrons from Mg foils…

Best regards,

You can implement your own process for specular reflection for neutrons. For example, take the G4OpBoundaryProcess process relevant for optical photons, and apply it to neutrons. Search the forum–this has been discussed before.

Also have a look at the UCN (ultra-cold neutrons) example. I don’t recall what’s in there, but it may be relevant.

1 Like

Hello, Dr. Michael.

I’m trying to implement the process of specular reflection of low energy neutrons from MgfoilMat but it doesn’t work. Could you check it, please?
When the effective potential of material is higher than neutron energy the low energy neutrons must specularly reflected (I mean in the code “if (std::sin(IncidentAngle) <= (U_eff / eKin))”…).

void SteppingAction::UserSteppingAction(const G4Step* aStep){
G4double eKin = aStep->GetPreStepPoint()->GetKineticEnergy();

// G4StepPoint* aStepPoint = 0;
if(aStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary && aStep->GetPostStepPoint()->GetPhysicalVolume()->GetName() == "MgfoilMat")
    	G4StepPoint* aStepPoint = aStep->GetPostStepPoint();
	G4ThreeVector pointInSurf = aStepPoint->GetPosition();
	const G4VTouchable *aStepTouchable = aStepPoint->GetTouchable();
	// const G4TouchableHistory* aStepTouchable = static_cast<const G4TouchableHistory*>(aStepPoint->GetTouchable());
	const G4AffineTransform *trans = aStepTouchable->GetHistory()->GetPtrTopTransform();
	G4ThreeVector localPointInSurf = trans->TransformPoint(pointInSurf);
	G4ThreeVector localNormal = aStepTouchable->GetVolume()->GetLogicalVolume()->GetSolid()->SurfaceNormal(localPointInSurf);
	G4ThreeVector localDirection = trans->TransformAxis(aStepPoint->GetMomentumDirection());
	G4double AngleToNormal = localDirection.angle(localNormal);
	G4double IncidentAngle;	
	G4double reflectedAngle;	
	G4double reflectedDirection;
	if (AngleToNormal > pi / 2) {
    IncidentAngle = AngleToNormal - pi / 2;
else {

    IncidentAngle = pi / 2 - AngleToNormal;

    if (std::sin(IncidentAngle) <= (U_eff / eKin)) {

        G4double ReflectedAngle = IncidentAngle;
        G4double n1x = cos(ReflectedAngle);
        G4double n1z = -sin(ReflectedAngle);

        G4ThreeVector reflectedDirection(n1x, 0.0, n1z); 

        G4ThreeVector newPosition = pointInSurf + reflectedDirection;


Don’t use the SteppingAction for this. See what @dsawkey wrote. You should write your own “NeutronBoundary” process, based on (or “inspired by”) G4OpBoundaryProcess, and implement the appropriate physics there. Then you can add that process to your physics list.

1 Like