Ejemplo n.º 1
0
    def test_Hz_forward(self):

        print('\ttesting forward-mode Hz in FDFD')

        f = fdfd_hz(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
            Ex, Ey, Hz = f.solve(c * self.eps_r * self.source_hz)

            return npa.square(npa.abs(Hz)) \
                 + npa.square(npa.abs(Ex)) \
                 + npa.square(npa.abs(Ey))

        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)
Ejemplo n.º 2
0
    def test_Hz_reverse(self):

        print('\ttesting reverse-mode Hz in FDFD')

        f = fdfd_hz(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
            Ex, Ey, Hz = f.solve(eps_r * self.source_hz, iterative=True)

            return npa.sum(npa.square(npa.abs(Hz))) \
                 + npa.sum(npa.square(npa.abs(Ex))) \
                 + npa.sum(npa.square(npa.abs(Ey)))

        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\n', grad_numerical)

        self.check_gradient_error(grad_numerical, grad_autograd_rev)
Ejemplo n.º 3
0
    omega = 2 * np.pi * 200e12
    dL = 4e-8
    eps_max = 2
    npml = 10
    spc = 10
    L = 3e-6
    Nx, Ny = 2*npml + 4*spc + int(L/dL), 2*npml + 4*spc + int(L/dL)
    eps_r = np.ones((Nx, Ny))

    # make source
    source = np.zeros((Nx, Ny))
    source[npml+spc, Ny//2] = 1

    # make design region
    box_region = np.zeros((Nx, Ny))
    box_region[npml+2*spc:npml+2*spc+int(L/dL), npml+2*spc:npml+2*spc+int(L/dL)] = 1

    probe = np.zeros((Nx, Ny), dtype=np.complex128)
    probe[-npml-spc, Ny//2] = 1

    F = fdfd_hz(omega, dL, eps_r, [npml, npml])

    # define the gradient for autograd
    grad_I = grad(intensity)

    from scipy.optimize import minimize
    bounds = [(1, eps_max) if box_region.flatten()[i] == 1 else (1,1) for i in range(eps_r.size)]
    minimize(intensity, eps_r, args=(), method='L-BFGS-B', jac=grad_I,
        bounds=bounds, tol=None, callback=None,
        options={'disp': True, 'maxcor': 10, 'ftol': 2.220446049250313e-09, 'gtol': 1e-05, 'eps': 1e-08, 'maxfun': 15000, 'maxiter': 150, 'iprint': -1, 'maxls': 20})