Closed ElliotB256 closed 3 months ago
The behavior is also visible in the check_thorlabs_aspheric
example configuration. Here I have modified the ray source to have only one ray per ring, and a larger number of rings, so I can see a fan of rays from the side:
Interaction of rays outside the extent of the optic is visible:
This can lead to surprising effects far from the optics, presumably as a result of the asphere function hitting some divergence:
I'm also seeing the behavior on PlanoConicLens
but not for PlanoConvexLens
lenses, which leads me to assume the issue is in SurfaceOfRotationLens
CircularFace
seems to explicitly test diameter in core/cfaces.pyx:
X = p1.x + h*(p2.x-p1.x) - self.offset
Y = p1.y + h*(p2.y-p1.y)
if is_base_ray and (X*X + Y*Y) > (d*d/4):
#print "X", X, "Y", Y
return NO_INTERSECTION
ConicRevolutionFace
uses the following routine:
if is_base_ray and not (<Shape>(self.shape)).point_inside_c(pt1.x, pt1.y):
return NO_INTERSECTION
As does AsphericFace
:
if is_base_ray and not (<Shape>(self.shape)).point_inside_c(pt1.x, pt1.y):
return NO_INTERSECTION
Both of these faces inherit from ShapedFace
, which specifies the shape
parameter:
def __cinit__(self, **kwds):
self.shape = kwds.get("shape", Shape())
However, as far as I can see nowhere in the Aspheric or PlanoConicLens code ever actually sets the shape. For example, this is how faces are defined in AsphericLens
:
AsphericFace(owner=self, diameter=self.diameter,
material=self.material,
conic_const=self.A_conic,
z_height=0.0, curvature=self.A_curvature,
A4=-self.A4, A6=-self.A6, A8=-self.A8, A10=-self.A10,
A12=-self.A12, A14=-self.A14, A16=-self.A16,
invert_normals=True,
atol=1e-16)
My understanding is that no shape is set for these lenses, and so they have no extent.
After making the following change to AsphericFace
's definition so that it includes a circular shape, I find that the ray tracing works as expected:
def make_faces(self):
fl = [AsphericFace(owner=self, diameter=self.diameter,
material=self.material,
conic_const=self.A_conic,
z_height=0.0, curvature=self.A_curvature,
A4=-self.A4, A6=-self.A6, A8=-self.A8, A10=-self.A10,
A12=-self.A12, A14=-self.A14, A16=-self.A16,
invert_normals=True,
shape=cCircleShape(radius=self.diameter/2),
atol=1e-16),
AsphericFace(owner=self, diameter=self.diameter,
material=self.material,
conic_const=self.B_conic,
z_height=self.CT, curvature=self.B_curvature,
A4=-self.B4, A6=-self.B6, A8=-self.B8, A10=-self.B10,
A12=-self.B12, A14=-self.B14, A16=-self.B16,
shape=cCircleShape(radius=self.diameter/2),
atol=1e-16)]
(If you are happy with this fix, I can raise a PR to fix AsphericFace
and ConicRevolutionFace
. It's probably sensible to put this into SurfaceOfRotationLens
).
I guess my email replies didn't make it to github so we ended up fixing this in parallel. Anyway, I've pushed some changes which are equivalent to yours (on Master). Hence, closing this issue. Thanks for the input and finding the bug. BTW. SurfaceOfRotationLens is an abstract base-class so it doesn't define any faces, hence there's nowhere to put a Shape object in it.
Thanks for the resolution!
Hello,
I'm attempting to use raypier to simulate some coupling optics based on aspheres. I had some surprising results, and after visualising I can see that the rays seem to ignore the physical extent of the asphere. In the image below, you can see the rays refracting off non-existent surfaces:
I have defined my aspheres using a definition analogous to those used in the aspheres module for other Thorlabs lenses (see, for example, the definition here):
The phantom refractions I am seeing clearly trace the continued surface of the asphere past the diameter - it is as if the diameter is only used for drawing the mesh and ignored for ray tracing: