Optical photons incorrectly propagate at the phase velocity v_phase= c/n. They should propagate at the group velocity, v_group= c/(n+dn/d(log E_phot)). This problem is easily traced to G4Track::GetVelocity(), where the velocity for optical photons is found by simply dividing the speed of light by the value of the material property RINDEX at the photon's energy. Note RINDEX _must_ be the conventional index of refraction c/v_phase, not some unconventional "group index" c/v_group, because RINDEX is used as c/v_phase in G4OpBoundaryProcess. The only clean solution I can think of would be to automatically build "GROUPVEL" material property vectors from the "RINDEX" data as needed, and return GROUPVEL(E) from G4Track::GetVelocity() instead of c_light/RINDEX(E). I can provide code for this.
An unofficial patch to fix this problem can be found at http://neutrino.phys.ksu.edu/~gahs/G4_GROUPVEL_fix/
Dear Dr. Horton-Smith, Thank you very much for not only pointing out the issue with group velocity vs phase velocity, but also providing me with a solution to the problem. The group velocity: vg= c_light/(n0+(n1-n0)/log(E1/E0)); depends on the input for E and n provided by the user and (n1-n0)/log(E1/E0) can, in general, become large and/or negative. To protect against this case I added the following statement to your new method - SetGROUPVEL: // add entry at first photon energy vg = c_light/(n0+(n1-n0)/log(E1/E0)); // allow only for 'normal dispersion' -> dn/d(logE) > 0 if(vg<0 || vg>c_light/n0)vg = c_light/n0; and equivalent at the three places. I have also made this method a private member of the G4MaterialPropertiesTable class instead of, as you proposed, a static member function of G4Track. The method is called at the first request fromG4Track::GetVelocity() for a given medium. G4MaterialPropertyVector* G4MaterialPropertiesTable::GetProperty(const char *key) { // Returns a Material Property Vector corresponding to a key if(MPT[G4String(key)] != 0) { return MPT[G4String(key)]; }else{ if(G4String(key) == "GROUPVEL") { return SetGROUPVEL(); }else{ return MPT[G4String(key)]; } } } The fix(es) have been tagged: materials-V07-00-05 and track-V07-00-01