I believe the Optical Boundary Process defined in G4OpBoundaryProcess doesn't do what is said it does in the manual. Namely, if you define an optical surface with an index of refraction, the manual says that there will be 2 boundary effects: "This allows the simulation of boundary effects at the intersection between the medium and the surface layer, as well as at the far side of the thin layer". This doesn't work. The index of the thin layer is used only if the index of the second material has not been defined (line 203-208) and in any case I believe only 1 boundary effect is simulated (I'm not 100% sure of that fact though but after a quick look at the code it looks like that). Also, at the moment if the second material doesn't have an index of refraction, the only thing checked to decide whether or not to carry on is the existence of an optical surface (line 180-191). If the user didn't define an index for the surface, Rindex2 is undefined and the boundary process shouldn't carry on. This is not checked at the moment. At last, could I make a suggestion. At the moment, it not possible to simulate a boundary effect between 2 volumes made of the same material even if an optical surface between those 2 volumes is defined (line 124-125). You have to define the same material twice to be able to do that. It would be nice to allow a boundary effect between 2 volumes made of the same material to be simulated if and only if an optical surface is defined. Therefore complex object geometry (with therefore no boundary effect between the different volumes describing that object) could be implemented if no optical surface is defined. But at the same time, boundary effects between crystals (array of crystals in a calorimeter for instance) could be forced to be simulated simply by defining an optical surface (with a different refraction index) without having to define 2 materials. This is what has to be done at the moment and one has to make sure 2 direct neighbour crystals are defined with different "version" of the same material.
(1) If you specify the UNIFIED model, define an optical surface with an index of refraction, and the "backpainted" surface finish, two boundary effects are simulated. The first is between the original medium and the thin surface layer. The second is Lambertian reflection off the 'paint' at the far side of the thin layer. It is not possible to simulate a thin film between two dielectric media by simply specifying an optical surface. In such a case, the thin film has to be defined as a true G4 volume and give it an index of refraction. The G4Navigator will then track the optical photon across two boundaries: n1 | n_layer | n2 (or again n1). For example, if you wanted to simulate the silicon oil between the PMT glass and your scintillator, you'd have to define the silicon oil film as a true G4 volume. I agree, the documentation should be more precise and clearly state that 'backpainted' finish assumes that a metallic paint (Lambertian Reflection) is the second boundary. (2) It is true that the thin layer index is only used when the second material has no index define, else the second material's index is used. I agree, the optical surface index could probably take precedence instead without ill effect. (3) I also agree that by requiring the index of refraction be different on both sides of an intersection, an unnecessary complication arises when an array of crystals touch, each of which is wrapped but the wrapping and thin layer are not implemented as physical G4 volumes but as part of an optical surface. - The check is there to bypass the process in cases where the index of refraction is equal on both sides of the boundary. Unless I can think of a problem, I shall change the code so that the process returns only if, in addition, no optical surface was defined as you have suggested. (4) Thanks for pointing out that Rindex2 can be undefined if the user didn't specify an index for the second medium and didn't specify one for the thin layer. As a general comment, another solution to your present problem would be to allow for a thin air space between your different (wrapped) crystals by placing slightly smaller volumes into an array. In this case, the G4Navigator would find the air space with no index defined, and use the optical surface as expected. Down to the allowed precision of the G4Navigator, there probably is a thin air space between crystal cases.
I have adopted the following logic: Material1 -> Rindex1 if(!Rindex1) kill the photon - return (as before) Defaults (as before) -------------------- theModel = glisur; theFinish = polished; G4OpticalSurfaceType type = dielectric_dielectric; if(OpticalSurface){ type = OpticalSurface->GetType(); theModel = OpticalSurface->GetModel(); theFinish = OpticalSurface->GetFinish(); if(theFinish == ...backpainted){ OpticalSurface -> Rindex2 if(!Rindex2) kill the photon - return } } if (type == dielectric_dielectric){ if(theFinish == 'polished' || 'ground') { // e.g. no 'paint' and not 'dielectric_metal' if(Material1 == Material2)return Material2 -> Rindex2 if(!Rindex2)kill photon - return } }