def test_transpose(self): m = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) exp = mp.Matrix(mp.Vector3(1, 4, 7), mp.Vector3(2, 5, 8), mp.Vector3(3, 6, 9)) self.matrix_eq(exp, m.transpose())
def test_determinant(self): m = mp.Matrix(mp.Vector3(2), mp.Vector3(y=2), mp.Vector3(z=2)) m1 = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) self.assertEqual(8, m.determinant()) self.assertEqual(0, m1.determinant())
def test_scale(self): m = mp.Matrix(mp.Vector3(90.0, 114.0, 138.0), mp.Vector3(54.0, 69.0, 84.0), mp.Vector3(18.0, 24.0, 30.0)) res = m.scale(0.5) exp = mp.Matrix(mp.Vector3(45.0, 57.0, 69.0), mp.Vector3(27.0, 34.5, 42.0), mp.Vector3(9.0, 12.0, 15.0)) self.matrix_eq(exp, res)
def test_mm_mult(self): m1 = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) m2 = mp.Matrix(mp.Vector3(9, 8, 7), mp.Vector3(6, 5, 4), mp.Vector3(3, 2, 1)) res = m1 * m2 exp = mp.Matrix(mp.Vector3(90.0, 114.0, 138.0), mp.Vector3(54.0, 69.0, 84.0), mp.Vector3(18.0, 24.0, 30.0)) self.matrix_eq(exp, res)
def test_conj(self): m = mp.Matrix(mp.Vector3(x=1 + 1j), mp.Vector3(y=1 + 1j), mp.Vector3(z=1 + 1j)) result = m.conj() self.assertEqual(result.c1, mp.Vector3(x=1 - 1j)) self.assertEqual(result.c2, mp.Vector3(y=1 - 1j)) self.assertEqual(result.c3, mp.Vector3(z=1 - 1j))
def test_transform(self): e_sus = [mp.LorentzianSusceptibility(sigma_diag=mp.Vector3(1, 2, 3), sigma_offdiag=mp.Vector3(12, 13, 14)), mp.DrudeSusceptibility(sigma_diag=mp.Vector3(1, 2, 3), sigma_offdiag=mp.Vector3(12, 13, 14))] mat = mp.Medium(epsilon_diag=mp.Vector3(1, 2, 3), epsilon_offdiag=mp.Vector3(12, 13, 14), E_susceptibilities=e_sus) rot_angle = math.radians(23.9) rot_matrix = mp.Matrix(mp.Vector3(math.cos(rot_angle), math.sin(rot_angle), 0), mp.Vector3(-math.sin(rot_angle), math.cos(rot_angle), 0), mp.Vector3(0, 0, 1)) mat.transform(rot_matrix) expected_diag = mp.Vector3(-7.72552, 10.72552, 3) expected_offdiag = mp.Vector3(7.69024, 6.21332, 18.06640) self.assertTrue(mat.epsilon_diag.close(expected_diag, tol=4)) self.assertTrue(mat.epsilon_offdiag.close(expected_offdiag, tol=4)) self.assertEqual(mat.mu_diag, mp.Vector3(1, 1, 1)) self.assertEqual(mat.mu_offdiag, mp.Vector3()) self.assertEqual(len(mat.E_susceptibilities), 2) self.assertTrue(mat.E_susceptibilities[0].sigma_diag.close(expected_diag, tol=4)) self.assertTrue(mat.E_susceptibilities[0].sigma_offdiag.close(expected_offdiag, tol=4)) self.assertTrue(mat.E_susceptibilities[1].sigma_diag.close(expected_diag, tol=4)) self.assertTrue(mat.E_susceptibilities[1].sigma_offdiag.close(expected_offdiag, tol=4))
def test_to_numpy_array(self): m = mp.Matrix(mp.Vector3(1 + 1j), mp.Vector3(1 + 1j), mp.Vector3(1 + 1j)) adjoint = m.H m_arr = np.matrix(m) np_adjoint = m_arr.H np.testing.assert_allclose(adjoint, np_adjoint)
def lc_mat(p): # rotation matrix for rotation around x axis Rx = mp.Matrix(mp.Vector3(1,0,0),mp.Vector3(0,math.cos(phi(p)),math.sin(phi(p))),mp.Vector3(0,-math.sin(phi(p)),math.cos(phi(p)))) lc_epsilon = Rx * epsilon_diag * Rx.transpose() lc_epsilon_diag = mp.Vector3(lc_epsilon[0].x,lc_epsilon[1].y,lc_epsilon[2].z) lc_epsilon_offdiag = mp.Vector3(lc_epsilon[1].x,lc_epsilon[2].x,lc_epsilon[2].y) return mp.Medium(epsilon_diag=lc_epsilon_diag,epsilon_offdiag=lc_epsilon_offdiag)
def test_adjoint(self): m = mp.Matrix(mp.Vector3(1+1j), mp.Vector3(1+1j), mp.Vector3(1+1j)) getH_result = m.getH() H_result = m.H self.assertEqual(getH_result.c1, mp.Vector3(1-1j, 1-1j, 1-1j)) self.assertEqual(getH_result.c2, mp.Vector3()) self.assertEqual(getH_result.c3, mp.Vector3()) np.testing.assert_allclose(getH_result, H_result)
def test_basis(self): lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) b = lattice.basis exp = mp.Matrix(mp.Vector3(0.8660254037844388, 0.5000000000000001), mp.Vector3(0.8660254037844388, -0.5000000000000001), mp.Vector3(z=1.0)) for e, r in zip([exp.c1, exp.c2, exp.c3], [b.c1, b.c2, b.c3]): self.assertTrue(e.close(r))
def _get_mu(self, diag, offdiag, susceptibilities, conductivity_diag, conductivity_offdiag, freq): self._log_string("Inside mu") # Clean the input if np.isscalar(freq): freqs = np.array(freq)[np.newaxis, np.newaxis, np.newaxis] else: freqs = np.squeeze(freq) freqs = freqs[:, np.newaxis, np.newaxis] # Check for values outside of allowed ranges if np.min(np.squeeze(freqs)) < self.valid_freq_range.min: raise ValueError( 'User specified frequency {} is below the Medium\'s limit, {}.' .format(np.min(np.squeeze(freqs)), self.valid_freq_range.min)) if np.max(np.squeeze(freqs)) > self.valid_freq_range.max: raise ValueError( 'User specified frequency {} is above the Medium\'s limit, {}.' .format(np.max(np.squeeze(freqs)), self.valid_freq_range.max)) # Initialize with instantaneous dielectric tensor epsmu = np.expand_dims(mp.Matrix(diag=diag, offdiag=offdiag), axis=0) # Use function for mu if freq == 0: epsmu = epsmu * self.mu_function(mp.inf) else: epsmu = epsmu * self.mu_function(1 / freq) # Account for conductivity term (only multiply if nonzero to avoid unnecessary complex numbers) conductivity = np.expand_dims(mp.Matrix(diag=conductivity_diag, offdiag=conductivity_offdiag), axis=0) if np.count_nonzero(conductivity) > 0: epsmu = (1 + 1j / freqs * conductivity) * epsmu # Convert list matrix to 3D numpy array size [freqs,3,3] return np.squeeze(epsmu)
def test_inverse(self): self.matrix_eq(self.identity, self.identity.inverse()) lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) res = lattice.basis.inverse() exp = mp.Matrix(mp.Vector3(0.5773502691896256, 0.5773502691896256, -0.0), mp.Vector3(0.9999999999999998, -0.9999999999999998, -0.0), mp.Vector3(-0.0, -0.0, 1.0)) self.matrix_close(exp, res)
def test_compute_field_energy(self): ms = self.init_solver() ms.run_te() ms.get_dfield(8) field_pt = ms.get_field_point(mp.Vector3(0.5, 0.5)) bloch_field_pt = ms.get_bloch_field_point(mp.Vector3(0.5, 0.5)) eps_inv_tensor = ms.get_epsilon_inverse_tensor_point( mp.Vector3(0.5, 0.5)) energy = ms.compute_field_energy() pt = ms.get_energy_point(mp.Vector3(0.5, 0.5)) self.assertAlmostEqual(pt, 1.330368347216153e-9) expected_fp = mp.Vector3( 2.5823356723958247e-5 + 6.713243287584132e-12j, -2.575955745071957e-5 - 6.696552990958943e-12j, 0.0 - 0.0j) expected_bloch_fp = mp.Vector3( 2.5823356723958247e-5 + 6.713243287584132e-12j, -2.575955745071957e-5 - 6.696552990958943e-12j, -0.0 - 0.0j) expected_eps_inv_tensor = mp.Matrix( mp.Vector3(1.0 + 0.0j, 0.0 - 0.0j, 0.0 - 0.0j), mp.Vector3(0.0 + 0.0j, 1.0 + 0.0j, 0.0 - 0.0j), mp.Vector3(0.0 + 0.0j, 0.0 + 0.0j, 1.0 + 0.0j)) self.assertTrue(expected_fp.close(field_pt)) self.assertTrue(expected_bloch_fp.close(bloch_field_pt)) self.assertEqual(expected_eps_inv_tensor.c1, eps_inv_tensor.c1) self.assertEqual(expected_eps_inv_tensor.c2, eps_inv_tensor.c2) self.assertEqual(expected_eps_inv_tensor.c3, eps_inv_tensor.c3) energy_in_dielectric = ms.compute_energy_in_dielectric(0, 1) expected_energy = [ 1.0000000000000002, 1.726755206037815e-5, 0.4999827324479414, 1.7267552060375955e-5, 0.4999827324479377, 0.0, 0.0 ] expected_energy_in_dielectric = 0.6990769686037558 self.compare_arrays(np.array(expected_energy), np.array(energy)) self.assertAlmostEqual(expected_energy_in_dielectric, energy_in_dielectric, places=3)
def eval_susceptibility(self, freq): self._log_string("Called eval susceptibility") sigma = np.expand_dims(mp.Matrix(diag=self.sigma_diag, offdiag=self.sigma_offdiag), axis=0) return self.epsilon_function(1 / freq) * sigma
## Define material susceptibility # Drude drude_range = mp.FreqRange(min=um_scale/(wvl_max*2), max=um_scale/(wvl_min/2)) # Valid frequency range um_scale/wavelength drude_frq = Omega_p*eV_um_scale # converts energy to meep frequency drude_gam = Gama*eV_um_scale # converts energy to meep frequency drude_sig = Sigma drude_sig_diag=Sigma_diag epsilon = epsilon_inf # epsilon infinity drude_susc = [mp.DrudeSusceptibility(frequency=drude_frq, gamma=drude_gam, sigma=drude_sig, sigma_diag=drude_sig_diag)] drude = mp.Medium(epsilon_diag=mp.Vector3(epsilon, epsilon, epsilon), E_susceptibilities=drude_susc, valid_freq_range=drude_range) c1=mp.Vector3(tr_x, 0.0, 0.0) c2=mp.Vector3(0.0, tr_y, 0.0) c3=mp.Vector3(0.0, 0.0, tr_z) m_tr=mp.Matrix(c1,c2,c3) drude.transform(m_tr) material_set=drude ## Create geometry lx=lx*tr_x ly=ly*tr_y lz=lz*tr_z material_ref=mp.Medium(epsilon_diag=mp.Vector3(1, 1, 1),mu_diag=mp.Vector3(1,1,1)) material_ref.transform(m_tr) geometry_ref = [mp.Block(size=mp.Vector3(gref_x,gref_y,gref_d), material=material_ref)] geometry = [mp.Block(size=mp.Vector3(gref_x,gref_y,gref_d), material=material_ref), mp.Block(size=mp.Vector3(lx,ly,lz), material=material_set)] ## Create cell pml_layers = [mp.PML(thickness=dpml)]
fullx = sizex + 2 * pml_th fully = sizey + 2 * pml_th cell = mp.Vector3(fullx, fully, 0) mat = mp.Medium(epsilon=2) supp_mat = mp.Medium(epsilon=1) aux_mat = mp.Medium(epsilon=1) # set to True to plot instead of run simulation geom = False ################### # X-compression ratio x_comp = 2 ################### trf = mp.Matrix(diag=mp.Vector3(x_comp, 1, 1)) mat.transform(trf) aux_mat.transform(trf) slab_thickness = sizex / 10 geometry = [ mp.Block(size=mp.Vector3(2 * x_comp * slab_thickness, fully, mp.inf), center=mp.Vector3(0, 0, 0), material=aux_mat) ] #################### # source params cfreq = 1.25 fwidth = 1.5
import meep as mp import numpy as np freq = 2 freqs = np.array(freq)[np.newaxis, np.newaxis, np.newaxis] diag = mp.Vector3(1, 1, 1) offdiag = mp.Vector3() a = np.expand_dims(mp.Matrix(diag=diag, offdiag=offdiag), axis=0) # print(a) # print(freqs) um_scale = 1 eV_um_scale = um_scale / 1.23984193 Au_plasma_frq = 9.03 * eV_um_scale Au_f3 = 0.071 Au_frq3 = 2.969 * eV_um_scale # 0.418 um Au_gam3 = 0.870 * eV_um_scale Au_sig3 = Au_f3 * Au_plasma_frq**2 / Au_frq3**2 c = mp.LorentzianSusceptibility(frequency=Au_frq3, gamma=Au_gam3, sigma=Au_sig3) d = c.eval_susceptibility(freqs) print(d) print(np.squeeze(d + a)) t = Au_frq3 * Au_frq3 / (Au_frq3 * Au_frq3 - freq * freq - 1j * Au_gam3 * freq) * Au_sig3 print(t)
def test_sub(self): ones_matrix = mp.Matrix(ones(), ones(), ones()) result = ones_matrix - ones_matrix self.assertEqual(result.row(0), zeros()) self.assertEqual(result.row(1), zeros()) self.assertEqual(result.row(2), zeros())
class TestMatrix(unittest.TestCase): identity = mp.Matrix(mp.Vector3(1), mp.Vector3(y=1), mp.Vector3(z=1)) def matrix_eq(self, exp, res): for e, r in zip([exp.c1, exp.c2, exp.c3], [res.c1, res.c2, res.c3]): self.assertEqual(e, r) def matrix_close(self, exp, res): for e, r in zip([exp.c1, exp.c2, exp.c3], [res.c1, res.c2, res.c3]): self.assertTrue(e.close(r)) def test_indexing(self): self.assertEqual(self.identity[0][0], 1) self.assertEqual(self.identity[1][1], 1) self.assertEqual(self.identity[2][2], 1) self.assertEqual(self.identity[0][1], 0) def test_row(self): self.assertEqual(self.identity.row(0), self.identity.c1) self.assertEqual(self.identity.row(1), self.identity.c2) self.assertEqual(self.identity.row(2), self.identity.c3) def test_mm_mult(self): m1 = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) m2 = mp.Matrix(mp.Vector3(9, 8, 7), mp.Vector3(6, 5, 4), mp.Vector3(3, 2, 1)) res = m1 * m2 exp = mp.Matrix(mp.Vector3(90.0, 114.0, 138.0), mp.Vector3(54.0, 69.0, 84.0), mp.Vector3(18.0, 24.0, 30.0)) self.matrix_eq(exp, res) def test_mv_mult(self): lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) res = lattice.basis * mp.Vector3(1) exp = mp.Vector3(0.8660254037844388, 0.5000000000000001) self.assertTrue(res.close(exp)) def test_scale(self): m = mp.Matrix(mp.Vector3(90.0, 114.0, 138.0), mp.Vector3(54.0, 69.0, 84.0), mp.Vector3(18.0, 24.0, 30.0)) res = m.scale(0.5) exp = mp.Matrix(mp.Vector3(45.0, 57.0, 69.0), mp.Vector3(27.0, 34.5, 42.0), mp.Vector3(9.0, 12.0, 15.0)) self.matrix_eq(exp, res) def test_determinant(self): m = mp.Matrix(mp.Vector3(2), mp.Vector3(y=2), mp.Vector3(z=2)) m1 = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) self.assertEqual(8, m.determinant()) self.assertEqual(0, m1.determinant()) def test_transpose(self): m = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) exp = mp.Matrix(mp.Vector3(1, 4, 7), mp.Vector3(2, 5, 8), mp.Vector3(3, 6, 9)) self.matrix_eq(exp, m.transpose()) def test_inverse(self): self.matrix_eq(self.identity, self.identity.inverse()) lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) res = lattice.basis.inverse() exp = mp.Matrix( mp.Vector3(0.5773502691896256, 0.5773502691896256, -0.0), mp.Vector3(0.9999999999999998, -0.9999999999999998, -0.0), mp.Vector3(-0.0, -0.0, 1.0)) self.matrix_close(exp, res)
class TestMatrix(unittest.TestCase): identity = mp.Matrix(mp.Vector3(1), mp.Vector3(y=1), mp.Vector3(z=1)) def matrix_eq(self, exp, res): for e, r in zip([exp.c1, exp.c2, exp.c3], [res.c1, res.c2, res.c3]): self.assertEqual(e, r) def matrix_close(self, exp, res): for e, r in zip([exp.c1, exp.c2, exp.c3], [res.c1, res.c2, res.c3]): self.assertTrue(e.close(r)) def test_indexing(self): self.assertEqual(self.identity[0][0], 1) self.assertEqual(self.identity[1][1], 1) self.assertEqual(self.identity[2][2], 1) self.assertEqual(self.identity[0][1], 0) def test_row(self): self.assertEqual(self.identity.row(0), self.identity.c1) self.assertEqual(self.identity.row(1), self.identity.c2) self.assertEqual(self.identity.row(2), self.identity.c3) def test_mm_mult(self): m1 = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) m2 = mp.Matrix(mp.Vector3(9, 8, 7), mp.Vector3(6, 5, 4), mp.Vector3(3, 2, 1)) res = m1 * m2 exp = mp.Matrix(mp.Vector3(90.0, 114.0, 138.0), mp.Vector3(54.0, 69.0, 84.0), mp.Vector3(18.0, 24.0, 30.0)) self.matrix_eq(exp, res) def test_add(self): result = self.identity + self.identity self.assertEqual(result.row(0), mp.Vector3(x=2)) self.assertEqual(result.row(1), mp.Vector3(y=2)) self.assertEqual(result.row(2), mp.Vector3(z=2)) def test_sub(self): ones_matrix = mp.Matrix(ones(), ones(), ones()) result = ones_matrix - ones_matrix self.assertEqual(result.row(0), zeros()) self.assertEqual(result.row(1), zeros()) self.assertEqual(result.row(2), zeros()) def test_mv_mult(self): lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) res = lattice.basis * mp.Vector3(1) exp = mp.Vector3(0.8660254037844388, 0.5000000000000001) self.assertTrue(res.close(exp)) def test_scale(self): m = mp.Matrix(mp.Vector3(90.0, 114.0, 138.0), mp.Vector3(54.0, 69.0, 84.0), mp.Vector3(18.0, 24.0, 30.0)) res = m.scale(0.5) exp = mp.Matrix(mp.Vector3(45.0, 57.0, 69.0), mp.Vector3(27.0, 34.5, 42.0), mp.Vector3(9.0, 12.0, 15.0)) self.matrix_eq(exp, res) self.matrix_eq(exp, m * 0.5) self.matrix_eq(exp, 0.5 * m) def test_determinant(self): m = mp.Matrix(mp.Vector3(2), mp.Vector3(y=2), mp.Vector3(z=2)) m1 = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) self.assertEqual(8, m.determinant()) self.assertEqual(0, m1.determinant()) def test_transpose(self): m = mp.Matrix(mp.Vector3(1, 2, 3), mp.Vector3(4, 5, 6), mp.Vector3(7, 8, 9)) exp = mp.Matrix(mp.Vector3(1, 4, 7), mp.Vector3(2, 5, 8), mp.Vector3(3, 6, 9)) self.matrix_eq(exp, m.transpose()) def test_inverse(self): self.matrix_eq(self.identity, self.identity.inverse()) lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) res = lattice.basis.inverse() exp = mp.Matrix( mp.Vector3(0.5773502691896256, 0.5773502691896256, -0.0), mp.Vector3(0.9999999999999998, -0.9999999999999998, -0.0), mp.Vector3(-0.0, -0.0, 1.0)) self.matrix_close(exp, res) def test_get_rotation_matrix(self): result = mp.get_rotation_matrix(ones(), 5) self.assertTrue( result.c1.close( mp.Vector3(0.5224414569754843, -0.3148559165969717, 0.7924144596214877))) self.assertTrue( result.c2.close( mp.Vector3(0.7924144596214877, 0.5224414569754843, -0.3148559165969717))) self.assertTrue( result.c3.close( mp.Vector3(-0.3148559165969717, 0.7924144596214877, 0.5224414569754843))) def test_conj(self): m = mp.Matrix(mp.Vector3(x=1 + 1j), mp.Vector3(y=1 + 1j), mp.Vector3(z=1 + 1j)) result = m.conj() self.assertEqual(result.c1, mp.Vector3(x=1 - 1j)) self.assertEqual(result.c2, mp.Vector3(y=1 - 1j)) self.assertEqual(result.c3, mp.Vector3(z=1 - 1j)) def test_adjoint(self): m = mp.Matrix(mp.Vector3(1 + 1j), mp.Vector3(1 + 1j), mp.Vector3(1 + 1j)) getH_result = m.getH() H_result = m.H self.assertEqual(getH_result.c1, mp.Vector3(1 - 1j, 1 - 1j, 1 - 1j)) self.assertEqual(getH_result.c2, mp.Vector3()) self.assertEqual(getH_result.c3, mp.Vector3()) np.testing.assert_allclose(getH_result, H_result) def test_to_numpy_array(self): m = mp.Matrix(mp.Vector3(1 + 1j), mp.Vector3(1 + 1j), mp.Vector3(1 + 1j)) adjoint = m.H m_arr = np.matrix(m) np_adjoint = m_arr.H np.testing.assert_allclose(adjoint, np_adjoint)
import meep as mp import math import argparse resolution = 50 # pixels/μm dpml = 1.0 # PML thickness dsub = 1.0 # substrate thickness dpad = 1.0 # padding thickness k_point = mp.Vector3(0,0,0) n_0 = 1.55 delta_n = 0.159 epsilon_diag = mp.Matrix(mp.Vector3(n_0**2,0,0),mp.Vector3(0,n_0**2,0),mp.Vector3(0,0,(n_0+delta_n)**2)) wvl = 0.54 # center wavelength fcen = 1/wvl # center frequency def pol_grating(d,ph,gp,nmode): sx = dpml+dsub+d+d+dpad+dpml sy = gp cell_size = mp.Vector3(sx,sy,0) pml_layers = [mp.PML(thickness=dpml,direction=mp.X)] # twist angle of nematic director; from equation 1b def phi(p): xx = p.x-(-0.5*sx+dpml+dsub) if (xx >= 0) and (xx <= d):
def init_output_lattice(self): cart_map = mp.Matrix( mp.Vector3(1, 0, 0), mp.Vector3(0, 1, 0), mp.Vector3(0, 0, 1) ) Rin = mp.Matrix( mp.Vector3(*self.lattice[0]), mp.Vector3(*self.lattice[1]), mp.Vector3(*self.lattice[2]) ) if self.verbose: print("Read lattice vectors") if self.kpoint: fmt = "Read Bloch wavevector ({:.6g}, {:.6g}, {:.6g})" print(fmt.format(self.kpoint.x, self.kpoint.y, self.kpoint.z)) fmt = "Input lattice = ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g})" print(fmt.format(Rin.c1.x, Rin.c1.y, Rin.c1.z, Rin.c2.x, Rin.c2.y, Rin.c2.z, Rin.c3.x, Rin.c3.y, Rin.c3.z)) Rout = mp.Matrix(Rin.c1, Rin.c2, Rin.c3) if self.rectify: # Orthogonalize the output lattice vectors. If have_ve is true, # then the first new lattice vector should be in the direction # of the ve unit vector; otherwise, the first new lattice vector # is the first original lattice vector. Note that we do this in # such a way as to preserve the volume of the unit cell, and so # that our first vector (in the direction of ve) smoothly # interpolates between the original lattice vectors. if self.have_ve: ve = self.ve.unit() else: ve = Rout.c1.unit() # First, compute c1 in the direction of ve by smoothly # interpolating the old c1/c2/c3 (formula is slightly tricky) V = Rout.c1.cross(Rout.c2).dot(Rout.c3) Rout.c2 = Rout.c2 - Rout.c1 Rout.c3 = Rout.c3 - Rout.c1 Rout.c1 = ve.scale(V / Rout.c2.cross(Rout.c3).dot(ve)) # Now, orthogonalize c2 and c3 Rout.c2 = Rout.c2 - ve.scale(ve.dot(Rout.c2)) Rout.c3 = Rout.c3 - ve.scale(ve.dot(Rout.c3)) Rout.c3 = Rout.c3 - Rout.c2.scale(Rout.c2.dot(Rout.c3) / Rout.c2.dot(Rout.c2)) cart_map.c1 = Rout.c1.unit() cart_map.c2 = Rout.c2.unit() cart_map.c3 = Rout.c3.unit() cart_map = cart_map.inverse() Rout.c1 = Rout.c1.scale(self.multiply_size[0]) Rout.c2 = Rout.c2.scale(self.multiply_size[1]) Rout.c3 = Rout.c3.scale(self.multiply_size[2]) if self.verbose: fmt = "Output lattice = ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g}), ({:.6g}, {:.6g}, {:.6g})" print(fmt.format(Rout.c1.x, Rout.c1.y, Rout.c1.z, Rout.c2.x, Rout.c2.y, Rout.c2.z, Rout.c3.x, Rout.c3.y, Rout.c3.z)) self.coord_map = Rin.inverse() * Rout self.Rout = Rout self.cart_map = cart_map