def test_hex(self): ''' Test a hexagonal-lattice PhC with a circular hole and gmode_compute = 'interp' ''' lattice = Lattice('hexagonal') phc = PhotCryst(lattice, eps_l=5.) phc.add_layer(d=0.5, eps_b=12.) phc.add_shape(Circle(r=0.2, x_cent=0.1, y_cent=0.2)) gme = GuidedModeExp(phc, gmax=6) # gme.plot_overview_ft(cladding=True) options = { 'gmode_inds': [1, 2, 3], 'numeig': 10, 'verbose': False, 'gmode_compute': 'interp' } gme.run(kpoints=np.array([[0.1], [0.1]]), **options) dat = scipy.io.loadmat('./tests/data/gme_hex.mat') diff_real = np.sum(np.abs(gme.freqs - dat['Eks']/2/np.pi) / \ (gme.freqs+1e-10)) diff_imag = np.sum(np.abs(gme.freqs_im - dat['Pks']/2/np.pi) / \ (np.abs(gme.freqs_im)+1e-10)) # Lower tolerance allowed because the MATLAB reciprocal space is # hexagonal while the legume one is a parallelogram self.assertLessEqual(diff_real, 1e-3) self.assertLessEqual(diff_imag, 1e-1)
def test_square(self): ''' Test a square-lattice PhC with a triangular hole ''' lattice = Lattice('square') phc = PhotCryst(lattice, eps_u=5.) phc.add_layer(d=0.5, eps_b=12.) poly = Poly(eps=3, x_edges=[-0.1, 0.2, 0], y_edges=[-0.1, -0.1, 0.3]) phc.add_shape(poly) # Find the modes of the structure and compare to the saved .mat file gme = GuidedModeExp(phc, gmax=4) options = { 'gmode_inds': [0, 1, 2, 3], 'numeig': 10, 'verbose': False, 'gmode_npts': 2000 } gme.run(kpoints=np.array([[0.1], [0.2]]), **options) dat = scipy.io.loadmat('./tests/data/gme_square.mat') diff_real = np.sum(np.abs(gme.freqs - dat['Eks']/2/np.pi) / \ (gme.freqs+1e-10)) diff_imag = np.sum(np.abs(gme.freqs_im - dat['Pks']/2/np.pi) / \ (np.abs(gme.freqs_im)+1e-10)) self.assertLessEqual(diff_real, 1e-4) self.assertLessEqual(diff_imag, 1e-3)
def test_square(self): ''' Test a square-lattice PhC with a circular hole ''' lattice = Lattice('square') phc = PhotCryst(lattice, eps_l=5.) phc.add_layer(d=0.5, eps_b=12.) phc.add_shape(Circle(r=0.2)) # Find the modes of the structure and compare to the saved .mat file gme = GuidedModeExp(phc, gmax=5) options = {'gmode_inds': [0], 'numeig': 10, 'verbose': False} gme.run(kpoints=np.array([[0., 0.1], [0., 0.2]]), **options) dat = scipy.io.loadmat('./tests/data/gme_square_te.mat') # Check real and imaginary parts for k = [0, 0] diff_real_k0 = np.sum(np.abs(gme.freqs[0, 1:] - dat['Eks'][0, 1:]/2/np.pi) / (gme.freqs[0, 1:]+1e-10)) diff_imag_k0 = np.sum(np.abs(gme.freqs_im[0, 1:] - dat['Pks'][0, 1:]/2/np.pi) / (gme.freqs_im[0, 1:]+1e-10)) # Check real and imaginary parts for k = [0.1, 0.2] diff_real_k1 = np.sum(np.abs(gme.freqs[1, 1:] - dat['Eks'][1, 1:]/2/np.pi) / (gme.freqs[1, 1:]+1e-10)) diff_imag_k1 = np.sum(np.abs(gme.freqs_im[1, 1:] - dat['Pks'][1, 1:]/2/np.pi) / (gme.freqs_im[1, 1:]+1e-10)) self.assertLessEqual(diff_real_k0, 1e-4) self.assertLessEqual(diff_imag_k0, 1e-3) self.assertLessEqual(diff_real_k1, 1e-4) self.assertLessEqual(diff_imag_k1, 1e-3)
def test_rect(self): ''' Test the gradient for a rectangular-lattice PhC with a circular hole ''' try: import autograd.numpy as npa from autograd import grad except: return 0 lattice = Lattice([1., 0], [0., .5]) def of(params): '''Define and solve a phc''' d = params[0] r = params[1] x = params[2] # Asymmetric claddings phc = PhotCryst(lattice, eps_u=5.) # First layer with a circular hole phc.add_layer(d=d, eps_b=12.) phc.add_shape(Circle(eps=1, r=r, x_cent=0, y_cent=0)) # Second layer with a triangular hole phc.add_layer(d=d, eps_b=10.) poly = Poly(eps=3, x_edges=[x, 0.2, 0], y_edges=[-0.1, -0.1, 0.3]) phc.add_shape(poly) # Define and run the GME gme = GuidedModeExp(phc, gmax=3) options = {'gmode_inds': [0, 1, 2], 'numeig': 5, 'verbose': False} gme.run(kpoints=np.array([[0., 0.1], [0., 0.2]]), **options) return npa.sum(gme.freqs / 2 / gme.freqs_im) # Define d, r, x params = npa.array([0.5, 0.2, -0.1]) # Autograd gradients legume.set_backend('autograd') gr_ag = grad(of)(params) # Numerical gradients gr_num = legume.utils.grad_num(of, params) diff_d = np.abs(gr_num[0] - gr_ag[0]) / gr_num[0] diff_r = np.abs(gr_num[1] - gr_ag[1]) / gr_num[1] diff_x = np.abs(gr_num[2] - gr_ag[2]) / gr_num[2] # Check grad w.r.t. layer thickness self.assertLessEqual(diff_d, 1e-1) # Check grad w.r.t. circle radius self.assertLessEqual(diff_r, 1e-1) # Check grad w.r.t. triangle vertex position self.assertLessEqual(diff_x, 1e-1)
def test_rect(self): ''' Test a rectangular-lattice PhC with a circular hole ''' lattice = Lattice([1., 0], [0., .5]) phc = PhotCryst(lattice, eps_u=5.) phc.add_layer(d=0.5, eps_b=12.) phc.add_shape(Circle(eps=1, r=0.2, x_cent=0, y_cent=0)) gme = GuidedModeExp(phc, gmax=3) options = {'gmode_inds': [0, 1, 2, 3], 'numeig': 10, 'verbose': False} gme.run(kpoints=np.array([[0., 0.1], [0., 0.2]]), **options) dat = scipy.io.loadmat('./tests/data/gme_rect.mat') diff_real = np.sum(np.abs(gme.freqs - dat['Eks']/2/np.pi) / \ (gme.freqs+1e-10)) diff_imag = np.sum(np.abs(gme.freqs_im - dat['Pks']/2/np.pi) / \ (np.abs(gme.freqs_im)+1e-10)) self.assertLessEqual(diff_real, 1e-4) self.assertLessEqual(diff_imag, 1e-3)