def reflect(self, raybundle, actualSurface, splitup=False): k1 = self.lc.returnGlobalToLocalDirections(raybundle.k[-1]) normal = raybundle.getLocalSurfaceNormal(actualSurface, self, raybundle.x[-1]) xlocal = self.lc.returnGlobalToLocalPoints(raybundle.x[-1]) valid_x = helpers_math.checkfinite(xlocal) valid_normals = helpers_math.checkfinite(normal) #xlocal[:, valid_x ^ True] = 0.0 #normal[:, valid_normals ^ True] = 0.0 #normal[2, valid_normals ^ True] = 1.0 k_inplane = k1 - np.sum(k1 * normal, axis=0) * normal (k2_sorted, e2_sorted) = self.sortKnormEField(xlocal, normal, k_inplane, normal, wave=raybundle.wave) # 2 vectors with smallest scalarproduct of S with n # TODO: negative sign due to compatibility with z-direction of # coordinate decenter if not splitup: k2 = -np.hstack((k2_sorted[0], k2_sorted[1])) e2 = -np.hstack((e2_sorted[0], e2_sorted[1])) newids = np.hstack((raybundle.rayID, raybundle.rayID)) orig = np.hstack((raybundle.x[-1], raybundle.x[-1])) newk = self.lc.returnLocalToGlobalDirections(k2) newe = self.lc.returnLocalToGlobalDirections(e2) return (RayBundle(orig, newk, newe, newids, raybundle.wave, splitted=True), ) else: k2_1 = self.lc.returnLocalToGlobalDirections(-k2_sorted[0]) k2_2 = self.lc.returnLocalToGlobalDirections(-k2_sorted[1]) e2_1 = self.lc.returnLocalToGlobalDirections(-e2_sorted[0]) e2_2 = self.lc.returnLocalToGlobalDirections(-e2_sorted[1]) orig = raybundle.x[-1] return (RayBundle(orig, k2_1, e2_1, raybundle.rayID, raybundle.wave), RayBundle(orig, k2_2, e2_2, raybundle.rayID, raybundle.wave))
def refract(self, raybundle, actualSurface, splitup=False): k1 = self.lc.returnGlobalToLocalDirections(raybundle.k[-1]) normal = raybundle.getLocalSurfaceNormal(actualSurface, self, raybundle.x[-1]) xlocal = self.lc.returnGlobalToLocalPoints(raybundle.x[-1]) valid_normals = helpers_math.checkfinite(normal) k_inplane = k1 - np.sum(k1 * normal, axis=0) * normal (xi, valid_refraction) = self.calcXiIsotropic(xlocal, normal, k_inplane, wave=raybundle.wave) valid = raybundle.valid[-1] * valid_refraction * valid_normals k2 = k_inplane + xi * normal # return ray with new direction and properties of old ray # return only valid rays orig = raybundle.x[-1][:, valid] newk = self.lc.returnLocalToGlobalDirections(k2[:, valid]) # E field calculation wrong: xlocal, normal, newk in different # coordinate systems Efield = self.calcEfield(xlocal, normal, newk, wave=raybundle.wave) return (RayBundle(orig, newk, Efield, raybundle.rayID[valid], raybundle.wave), )
def reflect(self, raybundle, actualSurface, splitup=False): k1 = self.lc.returnGlobalToLocalDirections(raybundle.k[-1]) normal = raybundle.getLocalSurfaceNormal(actualSurface, self, raybundle.x[-1]) xlocal = self.lc.returnGlobalToLocalPoints(raybundle.x[-1]) valid_normals = helpers_math.checkfinite(normal) # normals or sag values could either be nan or infinite # TODO: remove those normals from calculation k_inplane = k1 - np.sum(k1 * normal, axis=0) * normal (xi, valid_refraction) = self.calcXiIsotropic(xlocal, normal, k_inplane, wave=raybundle.wave) valid = raybundle.valid[-1] * valid_refraction * valid_normals k2 = -k_inplane + xi * normal # changed for mirror, all other code is doubled # return ray with new direction and properties of old ray # return only valid rays orig = raybundle.x[-1][:, valid] newk = self.lc.returnLocalToGlobalDirections(k2[:, valid]) Efield = self.calcEfield(xlocal, normal, newk, wave=raybundle.wave) return (RayBundle(orig, newk, Efield, raybundle.rayID[valid], raybundle.wave), )