def test_Ez_reverse(self): print('\ttesting reverse-mode Ez in FDFD') f = fdfd_ez(self.omega, self.dL, self.eps_r, self.pml) def J_fdfd(eps_arr): eps_r = eps_arr.reshape((self.Nx, self.Ny)) # set the permittivity f.eps_r = eps_r # set the source amplitude to the permittivity at that point Hx, Hy, Ez = f.solve(eps_r * self.source_ez) return npa.sum(npa.square(npa.abs(Ez))) \ + npa.sum(npa.square(npa.abs(Hx))) \ + npa.sum(npa.square(npa.abs(Hy))) grad_autograd_rev = jacobian(J_fdfd, mode='reverse')(self.eps_arr) grad_numerical = jacobian(J_fdfd, mode='numerical')(self.eps_arr) if VERBOSE: print('\tobjective function value: ', J_fdfd(self.eps_arr)) print('\tgrad (auto): \n\t\t', grad_autograd_rev) print('\tgrad (num): \n\t\t', grad_numerical) self.check_gradient_error(grad_numerical, grad_autograd_rev)
def test_Ez_forward(self): print('\ttesting forward-mode Ez in FDFD') f = fdfd_ez(self.omega, self.dL, self.eps_r, self.pml) def J_fdfd(c): # set the permittivity f.eps_r = c * self.eps_r # set the source amplitude to the permittivity at that point Hx, Hy, Ez = f.solve(c * self.eps_r * self.source_ez) return npa.square(npa.abs(Ez)) \ + npa.square(npa.abs(Hx)) \ + npa.square(npa.abs(Hy)) grad_autograd_for = jacobian(J_fdfd, mode='forward')(1.0) grad_numerical = jacobian(J_fdfd, mode='numerical')(1.0) if VERBOSE: print('\tobjective function value: ', J_fdfd(1.0)) print('\tgrad (auto): \n\t\t', grad_autograd_for) print('\tgrad (num): \n\t\t', grad_numerical) self.check_gradient_error(grad_numerical, grad_autograd_for)
def setUp(self): # basic simulation parameters self.Nx = 100 self.Ny = 100 self.omega = 2 * np.pi * 200e12 self.dL = 5e-8 self.pml = [10, 10] # sources (chosen to have objectives around 1) self.source_amp_ez = 1e3 self.source_amp_hz = 1e3 self.source_ez = np.zeros((self.Nx, self.Ny)) self.source_ez[self.Nx // 2, self.Ny // 2] = self.source_amp_ez # starting relative permittivity (random for debugging) self.eps_lin = np.ones((self.Nx, self.Ny)) self.chi3 = 2000 self.eps_nl = lambda Ez: self.eps_lin + 3 * self.chi3 * np.square( np.abs(Ez)) f = fdfd_ez(self.omega, self.dL, self.eps_lin, self.pml) Hx, Hy, Ez = f.solve(self.source_ez) self.Ez = Ez eps_nl = lambda Ez: self.eps_lin + 3 * self.eps_lin * self.chi3 * npa.square( npa.abs(Ez)) f_nl = fdfd_ez_nl(self.omega, self.dL, self.eps_nl, self.pml) Hx_nl, Hy_nl, Ez_nl = f_nl.solve(self.source_ez) self.Ez_nl = Ez_nl