def transform_directions(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, local_directions): """ Sequential local/global and back transformation yields original vector. """ system = LocalCoordinates(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global_directions = system.returnLocalToGlobalDirections(local_directions) local_directions2 = system.returnGlobalToLocalDirections(global_directions) assert np.allclose(local_directions2 - local_directions, 0)
def transform_points(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, local_points): """ Sequential local/global and back transformation yields original point. """ coordinate_system = LocalCoordinates(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global_points = coordinate_system.returnLocalToGlobalPoints(local_points) local_points2 = coordinate_system.returnGlobalToLocalPoints(global_points) assert np.allclose(local_points2 - local_points, 0)
def xypolynomials_grad(test_vector): """ Computation of biconic sag equals explicit calculation """ coordinate_system = LocalCoordinates(name="root") maxradius = 1e6 # arbitrary choice values = (2 * test_vector - 1) * maxradius x_coordinate = values[0] y_coordinate = values[1] coefficients_list = [(0, 2, 1.), (4, 5, -1.), (3, 2, 0.1)] shape = XYPolynomials(coordinate_system, coefficients=coefficients_list) gradient = shape.getGrad(x_coordinate, y_coordinate) comparison = np.zeros_like(gradient) for (powx, powy, alpha) in coefficients_list: comparison[0] += -alpha * powx * x_coordinate**(powx - 1) * y_coordinate**powy comparison[1] += -alpha * powy * x_coordinate**powx * y_coordinate**( powy - 1) comparison[2, :] = 1. assert np.allclose(gradient, comparison)
def asphere_sag(test_vector): """ Computation of asphere sag equals explicit calculation. """ coordinate_system = LocalCoordinates(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1. / radius alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 maxradius = (math.sqrt(1. / ((1 + conic_constant) * curvature**2)) if conic_constant > -1 else abs(radius)) values = (2 * test_vector - 1.) * maxradius x_coordinate = values[0] y_coordinate = values[1] shape = Asphere(coordinate_system, curv=curvature, cc=conic_constant, coefficients=[alpha2, alpha4, alpha6]) sag = shape.getSag(x_coordinate, y_coordinate) # comparison with explicitly entered formula comparison = (curvature * (x_coordinate**2 + y_coordinate**2) / (1. + np.sqrt(1. - (1. + conic_constant) * curvature**2 * (x_coordinate**2 + y_coordinate**2))) + alpha2 * (x_coordinate**2 + y_coordinate**2) + alpha4 * (x_coordinate**2 + y_coordinate**2)**2 + alpha6 * (x_coordinate**2 + y_coordinate**2)**3) assert np.allclose(sag, comparison)
def test_anisotropic_xi_eigenvectors(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5): """ Check whether eigenvectors fulfill the QEVP. """ lc = LocalCoordinates("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 # ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ # tuple(myeps) m = AnisotropicMaterial(lc, myeps) n = rnd_data3 n = n / np.sqrt(np.sum(n * n, axis=0)) x = np.zeros((3, 5)) k = rnd_data4 + complex(0, 1) * rnd_data5 kpa = k - np.sum(n * k, axis=0) * n ((_, _), (Mmatrix, Cmatrix, Kmatrix)) \ = m.calcXiQEVMatricesNorm(x, n, kpa) (eigenvalues, eigenvectors) = m.calcXiEigenvectorsNorm(x, n, kpa) #print(eigenvalues) should_be_zero = np.ones((4, 3, 5), dtype=complex) for j in range(5): for k in range(4): should_be_zero[k, :, j] = np.dot( (Mmatrix[:, :, j] * eigenvalues[k, j]**2 + Cmatrix[:, :, j] * eigenvalues[k, j] + Kmatrix[:, :, j]), eigenvectors[k, :, j]) assert np.allclose(should_be_zero, 0)
def test_anisotropic_xi_determinants(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5): """ Check whether xi zeros from polynomial fulfill the QEVP and the associated GLEVP. This also verifies whether A6x6 and B6x6 are constructed correctly. """ lc = LocalCoordinates("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 # ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ # tuple(myeps) m = AnisotropicMaterial(lc, myeps) n = rnd_data3 n = n / np.sqrt(np.sum(n * n, axis=0)) x = np.zeros((3, 5)) k = rnd_data4 + complex(0, 1) * rnd_data5 kpa = k - np.sum(n * k, axis=0) * n xiarray = m.calcXiNormZeros(x, n, kpa) ((Amatrix6x6, Bmatrix6x6), (Mmatrix, Cmatrix, Kmatrix)) \ = m.calcXiQEVMatricesNorm(x, n, kpa) should_be_zero_1 = np.ones((4, 5), dtype=complex) should_be_zero_2 = np.ones((4, 5), dtype=complex) for j in range(5): for xi_num in range(4): should_be_zero_1[xi_num, j] = np.linalg.det( (Mmatrix[:, :, j] * xiarray[xi_num, j]**2 + Cmatrix[:, :, j] * xiarray[xi_num, j] + Kmatrix[:, :, j])) should_be_zero_2[xi_num, j] = np.linalg.det( (Amatrix6x6[:, :, j] - Bmatrix6x6[:, :, j] * xiarray[xi_num, j])) assert np.allclose(should_be_zero_1, 0) assert np.allclose(should_be_zero_2, 0)
def directions_scalarproduct(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, local1, local2): """ Two vectors have same scalar product in two different coordinate systems. """ system = LocalCoordinates(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global1 = system.returnLocalToGlobalDirections(local1) global2 = system.returnLocalToGlobalDirections(local2) scalarproduct_local = np.einsum('i...,i...', local1, local2) scalarproduct_global = np.einsum('i...,i...', global1, global2) assert np.allclose(scalarproduct_local - scalarproduct_global, 0)
def tensors_scalarproduct(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z, directions1, directions2, tensor1, tensor2): """ Vectors/tensors have same contractions in different coordinate systems. """ system = LocalCoordinates(name="1", decx=100. * (2. * dec_x - 1.), decy=100. * (2. * dec_y - 1.), decz=100. * (2. * dec_z - 1.), tiltx=2. * math.pi * tilt_x, tilty=2. * math.pi * tilt_y, tiltz=2. * math.pi * tilt_z) global_directions1 = system.returnLocalToGlobalDirections(directions1) global_directions2 = system.returnLocalToGlobalDirections(directions2) global_tensor1 = system.returnLocalToGlobalTensors(tensor1) global_tensor2 = system.returnLocalToGlobalTensors(tensor2) # check whether a transformation between coordinate # systems changes indeed the components # assert np.any(t1glob - t1loc != 0) FIXME: currently breaks # assert np.any(t2glob - t2loc != 0) FIXME: currently breaks # assert np.any(v1glob - v1loc != 0) FIXME: currently breaks # assert np.any(v2glob - v2loc != 0) FIXME: currently breaks # test trace of tensor assert np.allclose((np.trace(global_tensor1, axis1=0, axis2=1) - np.trace(tensor1, axis1=0, axis2=1)), 0) # test t1 t2 tensor contraction assert np.allclose( (np.einsum('ij...,ij...', global_tensor1, global_tensor2) - np.einsum('ij...,ij...', tensor1, tensor2)), 0) # test v1 t1 v2 assert np.allclose( (np.einsum('i...,ij...,j...', global_directions1, global_tensor1, global_directions2) - np.einsum('i...,ij...,j...', directions1, tensor1, directions2)), 0) # test v1 t1 t2 v2 assert np.allclose( (np.einsum('i...,ij...,jk...,k...', global_directions1, global_tensor1, global_tensor2, global_directions2) - np.einsum('i...,ij...,jk...,k...', directions1, tensor1, tensor2, directions2)), 0)
def initDemoSystem(self): s = OpticalSystem() lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="object", decz=0.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=2.0), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=3.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf3", decz=5.0, tiltx=0.0*math.pi/180.0), refname=lc2.name) lc4 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf4", decz=3.0), refname=lc3.name) lc5 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf5", decz=3.0), refname=lc4.name) lc6 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf6", decz=2.0), refname=lc5.name) lc7 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf7", decz=3.0), refname=lc6.name) lc8 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=19.0), refname=lc7.name) objectsurf = Surface(lc0) surf1 = Surface(lc1, shape=surfShape.Conic(lc1, curv=1/-5.922)) surf2 = Surface(lc2, shape=surfShape.Conic(lc2, curv=1/-3.160)) surf3 = Surface(lc3, shape=surfShape.Conic(lc3, curv=1/15.884)) surf4 = Surface(lc4, shape=surfShape.Conic(lc4, curv=1/-12.756)) stopsurf = Surface(lc5) surf6 = Surface(lc6, shape=surfShape.Conic(lc6, curv=1/3.125)) surf7 = Surface(lc7, shape=surfShape.Conic(lc7, curv=1/1.479)) image = Surface(lc8) elem = OpticalElement(lc0, label="lenssystem") glass = material_isotropic.ConstantIndexGlass(lc0, n=1.7) glass2 = material_isotropic.ConstantIndexGlass(lc0, n=1.5) elem.addMaterial("glass", glass) elem.addMaterial("glass2", glass2) elem.addSurface("object", objectsurf, (None, None)) elem.addSurface("surf1", surf1, (None, "glass")) elem.addSurface("surf2", surf2, ("glass", None)) elem.addSurface("surf3", surf3, (None, "glass")) elem.addSurface("surf4", surf4, ("glass", None)) elem.addSurface("stop", stopsurf, (None, None)) elem.addSurface("surf6", surf6, (None, "glass2")) elem.addSurface("surf7", surf7, ("glass2", None)) elem.addSurface("image", image, (None, None)) s.addElement("lenssys", elem) return s
def biconic_sag(test_vector): """ Computation of biconic sag equals explicit calculation """ coordinate_system = LocalCoordinates(name="root") radiusx = 100.0 radiusy = 120.0 conic_constantx = -0.5 conic_constanty = -1.7 cx = 1. / radiusx cy = 1. / radiusy alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 beta2 = 0.1 beta4 = -0.6 beta6 = 0.2 maxradiusx = (math.sqrt(1. / ((1 + conic_constantx) * cx**2)) if conic_constantx > -1 else abs(radiusx)) maxradiusy = (math.sqrt(1. / ((1 + conic_constanty) * cy**2)) if conic_constanty > -1 else abs(radiusy)) maxradius = min([maxradiusx, maxradiusy]) # choose minimal radius values = (2 * test_vector - 1) * maxradius x_coordinate = values[0] y_coordinate = values[1] shape = Biconic(coordinate_system, curvx=cx, curvy=cy, ccx=conic_constantx, ccy=conic_constanty, coefficients=[(alpha2, beta2), (alpha4, beta4), (alpha6, beta6)]) sag = shape.getSag(x_coordinate, y_coordinate) # comparison with explicitly entered formula comparison = ( (cx * x_coordinate**2 + cy * y_coordinate**2) / (1. + np.sqrt(1. - (1. + conic_constantx) * cx**2 * x_coordinate**2 - (1. + conic_constanty) * cy**2 * y_coordinate**2)) + alpha2 * (x_coordinate**2 + y_coordinate**2 - beta2 * (x_coordinate**2 - y_coordinate**2)) + alpha4 * (x_coordinate**2 + y_coordinate**2 - beta4 * (x_coordinate**2 - y_coordinate**2))**2 + alpha6 * (x_coordinate**2 + y_coordinate**2 - beta6 * (x_coordinate**2 - y_coordinate**2))**3) assert np.allclose(sag, comparison)
def inverse_coordinate(dec_x, dec_y, dec_z, tilt_x, tilt_y, tilt_z): """ TODO """ dec_x = 100. * (2. * dec_x - 1.) dec_y = 100. * (2. * dec_y - 1.) dec_z = 100. * (2. * dec_z - 1.) tilt_x = 2. * math.pi * tilt_x tilt_y = 2. * math.pi * tilt_y tilt_z = 2. * math.pi * tilt_z system1 = LocalCoordinates(name="1") system2 = system1.addChild(LocalCoordinates(name="2")) system3 = system2.addChild( LocalCoordinates(name="3", decx=dec_x, decy=dec_y, decz=dec_z, tiltx=tilt_x, tilty=tilt_y, tiltz=tilt_z, tiltThenDecenter=0)) system4 = system3.addChild( LocalCoordinates(name="4", decx=-dec_x, decy=-dec_y, decz=-dec_z, tiltx=-tilt_x, tilty=-tilt_y, tiltz=-tilt_z, tiltThenDecenter=1)) assert np.allclose(system4.globalcoordinates, 0)
def test_anisotropic_xi_eigenvalues(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5, rnd_data6): """ Comparison of eigenvalue calculation for xi from random complex material data. Comparing polynomial calculation from determinant, from quadratic eigenvalue problem and analytical calculation from sympy. """ lc = LocalCoordinates("1") myeps = np.zeros((3, 3), dtype=complex) myeps[0:2, 0:2] = rnd_data1 + complex(0, 1) * rnd_data2 myeps[2, 2] = rnd_data3 + complex(0, 1) * rnd_data4 #np.random.random((3, 3)) + complex(0, 1)*np.random.random((3, 3)) ((epsxx, epsxy, _), (epsyx, epsyy, _), (_, _, epszz)) = \ tuple(myeps) m = AnisotropicMaterial(lc, myeps) #n = np.random.random((3, 1)) #n = n/np.sqrt(np.sum(n*n, axis=0)) n = np.zeros((3, 1)) n[2, :] = 1 x = np.zeros((3, 1)) k = rnd_data5 + complex(0, 1) * rnd_data6 kpa = k - np.sum(n * k, axis=0) * n (eigenvalues, _) = m.calcXiEigenvectorsNorm(x, n, kpa) xiarray = m.calcXiNormZeros(x, n, kpa) # sympy check with analytical solution kx, ky, xi = sympy.symbols('k_x k_y xi') exx, exy, _, eyx, eyy, _, _, _, ezz \ = sympy.symbols('e_xx e_xy e_xz e_yx e_yy e_yz e_zx e_zy e_zz') #eps = Matrix([[exx, exy, exz], [eyx, eyy, eyz], [ezx, ezy, ezz]]) eps = sympy.Matrix([[exx, exy, 0], [eyx, eyy, 0], [0, 0, ezz]]) v = sympy.Matrix([[kx, ky, xi]]) m = -(v * v.T)[0] * sympy.eye(3) + v.T * v + eps detm = m.det().collect(xi) soldetm = sympy.solve(detm, xi) subsdict = { kx: kpa[0, 0], ky: kpa[1, 0], exx: epsxx, exy: epsxy, eyx: epsyx, eyy: epsyy, ezz: epszz, sympy.I: complex(0, 1) } analytical_solution = np.sort_complex( np.array([sol.evalf(subs=subsdict) for sol in soldetm], dtype=complex)) numerical_solution1 = np.sort_complex(xiarray[:, 0]) numerical_solution2 = np.sort_complex(eigenvalues[:, 0]) assert np.allclose(analytical_solution - numerical_solution1, 0) assert np.allclose(analytical_solution - numerical_solution2, 0)
def test_anisotropic_xi_calculation_polynomial(rnd_data1, rnd_data2, rnd_data3, rnd_data4): """ Random epsilon tensor, Random k vector and n unit vector in z direction. Polynomial coefficients for eigenvalue equation from the numerical calculations via np.einsum and the analytical expressions given below (p4a, ..., p0a) should be identical. The test should work for real and complex epsilon and k values. """ lc = LocalCoordinates("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ tuple(myeps) m = AnisotropicMaterial(lc, myeps) n = np.zeros((3, 5)) n[2, :] = 1. x = np.zeros((3, 5)) k = rnd_data3 + complex(0, 1) * rnd_data4 kpa = k - np.sum(n * k, axis=0) * n kx = kpa[0] ky = kpa[1] (p4v, p3v, p2v, p1v, p0v) = m.calcXiPolynomialNorm(x, n, kpa) # TODO: Maybe generalize to arbitrary n vectors p4a = epszz * np.ones_like(kx) p3a = (epsxz + epszx) * kx + (epsyz + epszy) * ky p2a = epsxz*epszx + epsyz*epszy - (epsxx + epsyy)*epszz \ + (epsxx + epszz)*kx**2 + (epsxy + epsyx)*kx*ky \ + (epsyy + epszz)*ky**2 p1a = (epsxz + epszx)*kx**3 \ + (epsxz*epsyx + epsxy*epszx - epsxx*(epsyz + epszy))*ky \ + (epsyz + epszy)*kx**2*ky + (epsyz + epszy)*ky**3 \ + kx*(-(epsxz*epsyy) + epsxy*epsyz - epsyy*epszx + epsyx*epszy + (epsxz + epszx)*ky**2) p0a = -(epsxz*epsyy*epszx) + epsxy*epsyz*epszx + epsxz*epsyx*epszy \ - epsxx*epsyz*epszy - epsxy*epsyx*epszz + epsxx*epsyy*epszz \ + epsxx*kx**4 + (epsxy + epsyx)*kx**3*ky \ + (epsxy*epsyx - epsxx*epsyy + epsyz*epszy - epsyy*epszz)*ky**2 \ + epsyy*ky**4 + kx**2*(epsxy*epsyx + epsxz*epszx - epsxx*(epsyy + epszz) \ + (epsxx + epsyy)*ky**2) + kx*(\ (epsyz*epszx + epsxz*epszy - (epsxy + epsyx)*epszz)*ky \ + (epsxy + epsyx)*ky**3) should_be_zero_4 = p4a - p4v assert np.allclose(should_be_zero_4, 0) should_be_zero_3 = p3a - p3v assert np.allclose(should_be_zero_3, 0) should_be_zero_2 = p2a - p2v assert np.allclose(should_be_zero_2, 0) should_be_zero_1 = p1a - p1v assert np.allclose(should_be_zero_1, 0) should_be_zero_0 = p0a - p0v assert np.allclose(should_be_zero_0, 0)
def asphere_grad(test_vector): """ Computation of asphere gradient equals explicit calculation. Notice grad is calculated in 3 dimensions by grad F = grad(z - f(x, y)) """ coordinate_system = LocalCoordinates(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1. / radius alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 maxradius = (math.sqrt(1. / ((1 + conic_constant) * curvature**2)) if conic_constant > -1 else abs(radius)) values = (2 * test_vector - 1.) * maxradius x = values[0] y = values[1] shape = Asphere(coordinate_system, curv=curvature, cc=conic_constant, coefficients=[alpha2, alpha4, alpha6]) gradient = shape.getGrad(x, y) comparison = np.zeros_like(gradient) comparison[0] = (-2 * alpha2 * x - 4 * alpha4 * x * (x**2 + y**2) - 6 * alpha6 * x * (x**2 + y**2)**2 - curvature**3 * x * (conic_constant + 1) * (x**2 + y**2) / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) * (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)**2) - 2 * curvature * x / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)) comparison[1] = (-2 * alpha2 * y - 4 * alpha4 * y * (x**2 + y**2) - 6 * alpha6 * y * (x**2 + y**2)**2 - curvature**3 * y * (conic_constant + 1) * (x**2 + y**2) / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) * (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)**2) - 2 * curvature * y / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)) comparison[2, :] = 1.0 assert np.allclose(gradient, comparison)
def test_anisotropic_xi_calculation_det(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5, rnd_data6): """ Random epsilon tensor, Random k vector and n unit vector in z direction. Determinant of the propagator from numerical calculations via np.einsum and from analytical expression given below should coincide. The test should work for real and complex epsilon and k values. """ lc = LocalCoordinates("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ tuple(myeps) m = AnisotropicMaterial(lc, myeps) n = np.zeros((3, 5)) n[2, :] = 1. x = np.zeros((3, 5)) k = rnd_data3 + complex(0, 1) * rnd_data4 xi = rnd_data5 + complex(0, 1) * rnd_data6 kpa = k - np.sum(n * k, axis=0) * n kx = kpa[0] ky = kpa[1] # TODO: Maybe generalize to arbitrary n vectors det_analytical = xi**4*epszz \ + xi**3*((epsxz + epszx)*kx + (epsyz + epszy)*ky)\ + xi**2*(epsxz*epszx + epsyz*epszy - (epsxx + epsyy)*epszz\ + (epsxx + epszz)*kx**2 + (epsxy + epsyx)*kx*ky\ + (epsyy + epszz)*ky**2)\ + xi*((epsxz + epszx)*kx**3\ + (epsxz*epsyx + epsxy*epszx - epsxx*(epsyz + epszy))*ky\ + (epsyz + epszy)*kx**2*ky + (epsyz + epszy)*ky**3\ + kx*(-(epsxz*epsyy) + epsxy*epsyz - epsyy*epszx\ + epsyx*epszy + (epsxz + epszx)*ky**2))\ -(epsxz*epsyy*epszx) + epsxy*epsyz*epszx\ + epsxz*epsyx*epszy - epsxx*epsyz*epszy\ - epsxy*epsyx*epszz + epsxx*epsyy*epszz + epsxx*kx**4\ + (epsxy + epsyx)*kx**3*ky \ + (epsxy*epsyx - epsxx*epsyy + epsyz*epszy - epsyy*epszz)*ky**2 \ + epsyy*ky**4 + kx**2*(epsxy*epsyx + epsxz*epszx \ - epsxx*(epsyy + epszz) + (epsxx + epsyy)*ky**2)\ + kx*((epsyz*epszx + epsxz*epszy \ - (epsxy + epsyx)*epszz)*ky + (epsxy + epsyx)*ky**3) should_be_zero = det_analytical - m.calcXiDetNorm(xi, x, n, kpa) assert np.allclose(should_be_zero, 0)
def conic_sag(test_vector): """ Computation of conic sag equals explicit calculation. """ coordinate_system = LocalCoordinates(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1. / radius maxradius = (math.sqrt(1. / ((1 + conic_constant) * curvature**2)) if conic_constant > -1 else abs(radius)) values = (2 * test_vector - 1.) * maxradius x_coordinate = values[0] y_coordinate = values[1] shape = Conic(coordinate_system, curv=curvature, cc=conic_constant) sag = shape.getSag(x_coordinate, y_coordinate) # comparison with explicitly entered formula assert np.allclose( sag, (curvature * (x_coordinate**2 + y_coordinate**2) / (1. + np.sqrt(1. - (1. + conic_constant) * curvature**2 * (x_coordinate**2 + y_coordinate**2)))))
def conic_grad(test_vector): """ Computation of conic grad equals explicit calculation. """ coordinate_system = LocalCoordinates(name="root") radius = 10.0 conic_constant = -1.5 curvature = 1. / radius maxradius = (math.sqrt(1. / ((1 + conic_constant) * curvature**2)) if conic_constant > -1 else abs(radius)) values = (2 * test_vector - 1.) * maxradius x = values[0] y = values[1] shape = Conic(coordinate_system, curv=curvature, cc=conic_constant) gradient = shape.getGrad(x, y) comparison = np.zeros_like(gradient) comparison[2, :] = 1. comparison[0] = (-curvature**3 * x * (conic_constant + 1) * (x**2 + y**2) / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) * (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)**2) - 2 * curvature * x / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)) comparison[1] = (-curvature**3 * y * (conic_constant + 1) * (x**2 + y**2) / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) * (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)**2) - 2 * curvature * y / (np.sqrt(-curvature**2 * (conic_constant + 1) * (x**2 + y**2) + 1) + 1)) comparison = comparison * gradient[ 2] # comparison and gradient are calculated differently assert np.allclose(gradient, comparison)
def test_anisotropic_xi_calculation_polynomial_zeros(rnd_data1, rnd_data2, rnd_data3, rnd_data4, rnd_data5): """ Random epsilon tensor, random k vector and random n unit vector. Check whether the roots calculated give really zero for the determinant. The test should work for real and complex epsilon and k values. """ lc = LocalCoordinates("1") myeps = rnd_data1 + complex(0, 1) * rnd_data2 # ((epsxx, epsxy, epsxz), (epsyx, epsyy, epsyz), (epszx, epszy, epszz)) = \ # tuple(myeps) m = AnisotropicMaterial(lc, myeps) n = rnd_data3 n = n / np.sqrt(np.sum(n * n, axis=0)) x = np.zeros((3, 5)) k = rnd_data4 + complex(0, 1) * rnd_data5 kpa = k - np.sum(n * k, axis=0) * n should_be_zero = np.ones((4, 5), dtype=complex) xiarray = m.calcXiNormZeros(x, n, kpa) for i in range(4): should_be_zero[i, :] = m.calcXiDetNorm(xiarray[i], x, n, kpa) assert np.allclose(should_be_zero, 0)
import math import core.helpers wavelength = 0.5876e-3 # definition of optical system #v = np.ones(3)# + 0.001*np.random.random(3) #myeps = np.diag(v) s = OpticalSystem() lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="object", decz=0.0), refname=s.rootcoordinatesystem.name) #air = AnisotropicMaterial(lc0, myeps) # tests for anisotropic mirror air = ConstantIndexGlass(lc0, 1.0) s.material_background = air lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="m1", decz=50.0, tiltx=-math.pi/8), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="m2_stop", decz=-50.0, decy=-20, tiltx=math.pi/16), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="m3", decz=50.0, decy=-30, tiltx=3*math.pi/32), refname=lc2.name) lc4 = s.addLocalCoordinateSystem(LocalCoordinates(name="image1", decz=-50, decy=-15, tiltx=-math.pi/16), refname=lc3.name) lc5 = s.addLocalCoordinateSystem(LocalCoordinates(name="oapara", decz=-100, decy=-35), refname=lc4.name) lc5ap = s.addLocalCoordinateSystem(LocalCoordinates(name="oaparaap", decz=0, decy=35), refname=lc5.name) lc6 = s.addLocalCoordinateSystem(LocalCoordinates(name="image2", decz=55, tiltx=1*math.pi/32), refname=lc5.name) lc7 = s.addLocalCoordinateSystem(LocalCoordinates(name="image3", decz=5), refname=lc6.name) objectsurf = Surface(lc0)
from core.aperture import CircularAperture from core.localcoordinates import LocalCoordinates from core.globalconstants import canonical_ey import math import logging logging.basicConfig(level=logging.DEBUG) wavelength = 0.5876e-3 # definition of optical system s = OpticalSystem(name='os') lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=-1.048), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=4.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf3", decz=2.5), refname=lc2.name) lc4 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=97.2), refname=lc3.name) stopsurf = Surface(lc0, name="stopsurf") frontsurf = Surface(lc1, name="frontsurf", shape=surfShape.Conic(lc1, curv=1./62.8, name='conic1'), apert=CircularAperture(lc1, 12.7)) cementsurf = Surface(lc2, name="cementsurf", shape=surfShape.Conic(lc2, curv=-1./45.7, name='conic2'), apert=CircularAperture(lc2, 12.7)) rearsurf = Surface(lc3, name="rearsurf", shape=surfShape.Conic(lc3, curv=-1./128.2, name='conic3'), apert=CircularAperture(lc3, 12.7)) image = Surface(lc4, name="imagesurf") elem = OpticalElement(lc0, name="thorlabs_AC_254-100-A")
from core.globalconstants import canonical_ey import math wavelength = 0.5876e-3 wave_red = 0.700e-3 wave_blue = 0.470e-3 # definition of optical system s = OpticalSystem() deg = math.pi / 180. dropletradius = 0.01 lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lccomprism = s.addLocalCoordinateSystem(LocalCoordinates(name="dropletcenter", decz=2. * dropletradius), refname=lc0.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=-dropletradius), refname=lccomprism.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=dropletradius + 0.0001), refname=lccomprism.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf3", decz=-dropletradius, tiltx=math.pi),
from core.aperture import CircularAperture from core.localcoordinates import LocalCoordinates from core.globalconstants import canonical_ey from core.optimize import Optimizer from core.optimize_backends import ScipyBackend import math wavelength = 0.5876e-3 # definition of optical system s = OpticalSystem() lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=5.0), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=20.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=100.0), refname=lc2.name) stopsurf = Surface(lc0) frontsurf = Surface(lc1, shape=surfShape.Conic(lc1), apert=CircularAperture(lc1, 12.7)) backsurf = Surface(lc2, shape=surfShape.Asphere(lc2, curv=-1. / 50.0,
from core.globalconstants import canonical_ey import math wavelength = 0.5876e-3 wave_red = 0.700e-3 wave_blue = 0.470e-3 # definition of optical system s = OpticalSystem() deg = math.pi / 180. lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lccomprism = s.addLocalCoordinateSystem(LocalCoordinates(name="prismcenter", decz=50.0), refname=lc0.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=-10.0, tiltx=30. * deg), refname=lccomprism.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=10.0, tiltx=-30. * deg), refname=lccomprism.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=50.0), refname=lccomprism.name)
from core.globalconstants import canonical_ey, degree, standard_wavelength import math import core.helpers # definition of optical system # Design: US patent no. 5701202 A, inventor: Koichi Takahashi # and also: Bo Chen, Alois M. Herkommer, Opt. Express 24, 26999 (2016) logging.basicConfig(level=logging.INFO) s = OpticalSystem() lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="object", decz=0.0), refname=s.rootcoordinatesystem.name) air = ConstantIndexGlass(lc0, 1.0) glass = ConstantIndexGlass(lc0, 1.492) s.material_background = air si = -1. lcD1 = s.addLocalCoordinateSystem(LocalCoordinates(name="D1", decz=30.002), refname=lc0.name) lcS1 = s.addLocalCoordinateSystem(LocalCoordinates(name="S1", decy=-24.028, decz=26.360, tiltx=-si * 14.7 * degree, tiltThenDecenter=False),
"python -m demos.demo_zmx file.zmx u|a entrance_pupil_diameter num_rays_for_yfan" ) print("only collimated light") print("file.zmx relative to local directory") print("u for utf16 file; a for ascii file (try both)") exit() file_to_read = sys.argv[1] u_or_a = sys.argv[2] enpd = float(sys.argv[3]) num_rays = int(sys.argv[4]) ascii_read = True if u_or_a == "a" else False p = ZMXParser(file_to_read, ascii=ascii_read) lctmp = LocalCoordinates("tmp") #matdict = {} matdict = {"BK7": ConstantIndexGlass(lctmp, 1.5168)} #matdict = {"LAFN21":ConstantIndexGlass(lctmp, 1.788), "SF53":ConstantIndexGlass(lctmp, 1.72)} (s, seq) = p.createOpticalSystem(matdict) rstobj = raster.MeridionalFan() (px, py) = rstobj.getGrid(num_rays) rpup = enpd * 0.5 #7.5 o = np.vstack((rpup * px, rpup * py, -5. * np.ones_like(px))) k = np.zeros_like(o) k[1, :] = math.sin(0.0)
from core.optical_system import OpticalSystem from core.surface import Surface from core.globalconstants import canonical_ey from core.optical_system_analysis import OpticalSystemAnalysis from core.surfShape_analysis import ShapeAnalysis wavelength = standard_wavelength logging.basicConfig(level=logging.DEBUG) # definition of optical system s = OpticalSystem() # objectDistance = 2.0 lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="object", decz=0.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=2.0), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=3.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf3", decz=5.0, tiltx=2.5 * math.pi / 180.0), refname=lc2.name) lc4 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf4", decz=3.0), refname=lc3.name) lc5 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf5", decz=3.0), refname=lc4.name) lc6 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf6", decz=2.0), refname=lc5.name)
logging.basicConfig(level=logging.DEBUG) wavelength = 0.5876e-3 wave_red = 0.700e-3 wave_blue = 0.470e-3 # definition of optical system s = OpticalSystem() dropletradius = 0.1 lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="stop", decz=0.0), refname=s.rootcoordinatesystem.name) lccomprism = s.addLocalCoordinateSystem(LocalCoordinates(name="dropletcenter", decz=2.*dropletradius), refname=lc0.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=-dropletradius), refname=lccomprism.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=dropletradius), refname=lccomprism.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf3", decz=0), refname=lccomprism.name) lc4 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=-2.*dropletradius), refname=lccomprism.name) stopsurf = Surface(lc0, apert=CircularAperture(lc0, 7*dropletradius)) frontsurf = Surface(lc1, shape=Asphere(lc1, curv=1./dropletradius), apert=CircularAperture(lc1, dropletradius)) rearsurf = Surface(lc2, shape=Asphere(lc2, curv=-1./dropletradius), apert=CircularAperture(lc2, dropletradius)) midsurf = Surface(lc3, shape=Asphere(lc3, curv=0), apert=CircularAperture(lc3, dropletradius)) image = Surface(lc4, apert=CircularAperture(lc4, 7.*dropletradius))
def addChild(self, name=""): ch = self.__lc.addChild(LocalCoordinates(name)) self.createSubgroupForChild(ch)
from core.optical_system import OpticalSystem from core.ray import RayBundle from core.aperture import CircularAperture from core.localcoordinates import LocalCoordinates from core.globalconstants import canonical_ey import math wavelength = 0.5876e-3 # definition of optical system s = OpticalSystem() lc0 = s.addLocalCoordinateSystem(LocalCoordinates(name="stop", decz=1.0), refname=s.rootcoordinatesystem.name) lc1 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf1", decz=10.0), refname=lc0.name) # objectDist lc2 = s.addLocalCoordinateSystem(LocalCoordinates(name="surf2", decz=5.0, tiltx=10 * math.pi / 180.0), refname=lc1.name) lc3 = s.addLocalCoordinateSystem(LocalCoordinates(name="image", decz=-5.0, tiltx=-10 * math.pi / 180.0), refname=lc2.name) stopsurf = Surface(lc0) frontsurf = Surface(lc1, shape=surfShape.Conic(lc1, curv=0),
def biconic_grad(test_vector): """ Computation of biconic gradient equals explicit calculation """ coordinate_system = LocalCoordinates(name="root") radiusx = 100.0 radiusy = 120.0 conic_constantx = -0.5 conic_constanty = -1.7 cx = 1. / radiusx cy = 1. / radiusy alpha2 = 1e-3 alpha4 = -1e-6 alpha6 = 1e-8 beta2 = 0.1 beta4 = -0.6 beta6 = 0.2 maxradiusx = (math.sqrt(1. / ((1 + conic_constantx) * cx**2)) if conic_constantx > -1 else abs(radiusx)) maxradiusy = (math.sqrt(1. / ((1 + conic_constanty) * cy**2)) if conic_constanty > -1 else abs(radiusy)) maxradius = min([maxradiusx, maxradiusy]) # choose minimal radius values = (2 * test_vector - 1) * maxradius x = values[0] y = values[1] shape = Biconic(coordinate_system, curvx=cx, curvy=cy, ccx=conic_constantx, ccy=conic_constanty, coefficients=[(alpha2, beta2), (alpha4, beta4), (alpha6, beta6)]) gradient = shape.getGrad(x, y) comparison = np.zeros_like(gradient) comparison[2, :] = 1. comparison[0, :] = ( -alpha2 * (-2 * beta2 * x + 2 * x) - alpha4 * (-4 * beta4 * x + 4 * x) * (-beta4 * (x**2 - y**2) + x**2 + y**2) - alpha6 * (-6 * beta6 * x + 6 * x) * (-beta6 * (x**2 - y**2) + x**2 + y**2)**2 - cx**2 * x * (conic_constantx + 1) * (cx * x**2 + cy * y**2) / ((np.sqrt(-cx**2 * x**2 * (conic_constantx + 1) - cy**2 * y**2 * (conic_constanty + 1) + 1) + 1)**2 * np.sqrt(-cx**2 * x**2 * (conic_constantx + 1) - cy**2 * y**2 * (conic_constanty + 1) + 1)) - 2 * cx * x / (np.sqrt(-cx**2 * x**2 * (conic_constantx + 1) - cy**2 * y**2 * (conic_constanty + 1) + 1) + 1)) comparison[1, :] = ( -alpha2 * (2 * beta2 * y + 2 * y) - alpha4 * (4 * beta4 * y + 4 * y) * (-beta4 * (x**2 - y**2) + x**2 + y**2) - alpha6 * (6 * beta6 * y + 6 * y) * (-beta6 * (x**2 - y**2) + x**2 + y**2)**2 - cy**2 * y * (conic_constanty + 1) * (cx * x**2 + cy * y**2) / ((np.sqrt(-cx**2 * x**2 * (conic_constantx + 1) - cy**2 * y**2 * (conic_constanty + 1) + 1) + 1)**2 * np.sqrt(-cx**2 * x**2 * (conic_constantx + 1) - cy**2 * y**2 * (conic_constanty + 1) + 1)) - 2 * cy * y / (np.sqrt(-cx**2 * x**2 * (conic_constantx + 1) - cy**2 * y**2 * (conic_constanty + 1) + 1) + 1)) assert np.allclose(gradient, comparison)