def compute_fom_and_gradient( self, omega, device_permittivity, focal_point_x_loc, fom_scaling=1.0 ):
		fwd_Ez = self.compute_forward_fields( omega, device_permittivity )
		fom = fom_scaling * np.abs( fwd_Ez[ focal_point_x_loc, self.focal_point_y ] )**2
		
		adj_source = np.zeros( ( self.simulation_width_voxels, self.simulation_height_voxels ), dtype=np.complex )
		adj_source[ focal_point_x_loc, self.focal_point_y ] = np.conj( fwd_Ez[ focal_point_x_loc, self.focal_point_y ] )

		simulation = ceviche.fdfd_ez( omega, self.mesh_size_m, self.rel_eps_simulation, [ self.pml_voxels, self.pml_voxels ] )
		adj_Hx, adj_Hy, adj_Ez = simulation.solve( adj_source )

		gradient = fom_scaling * 2 * np.real( omega * eps_nought * fwd_Ez * adj_Ez / 1j )

		if self.field_blur:
			blur_fwd_Ez_real = gaussian_filter( np.real( fwd_Ez ), sigma=self.field_blur_size_voxels )
			blur_fwd_Ez_imag = gaussian_filter( np.imag( fwd_Ez ), sigma=self.field_blur_size_voxels )

			blur_adj_Ez_real = gaussian_filter( np.real( adj_Ez ), sigma=self.field_blur_size_voxels )
			blur_adj_Ez_imag = gaussian_filter( np.imag( adj_Ez ), sigma=self.field_blur_size_voxels )

			blur_fwd_Ez = blur_fwd_Ez_real + 1j * blur_fwd_Ez_imag
			blur_adj_Ez = blur_adj_Ez_real + 1j * blur_adj_Ez_imag

			gradient = fom_scaling * 2 * np.real( omega * eps_nought * blur_fwd_Ez * blur_adj_Ez / 1j )

		return fom, gradient
def compute_fom_and_gradient(omega, mesh_size_m, relative_permittivity,
                             pml_cells, fwd_src_y_loc, focal_point_x_loc,
                             focal_point_y_loc):
    simulation_width_cells = relative_permittivity.shape[0]
    simulation_height_cells = relative_permittivity.shape[1]
    simulation = ceviche.fdfd_ez(omega, mesh_size_m, relative_permittivity,
                                 pml_cells)

    fwd_src_x = np.arange(0, simulation_width_cells)
    fwd_src_y = fwd_src_y_loc * np.ones(fwd_src_x.shape, dtype=int)

    fwd_source = np.zeros((simulation_width_cells, simulation_height_cells),
                          dtype=np.complex)
    fwd_source[fwd_src_x, fwd_src_y] = 1

    fwd_Hx, fwd_Hy, fwd_Ez = simulation.solve(fwd_source)

    focal_point_y = focal_point_y_loc
    focal_point_x = focal_point_x_loc

    fom = np.abs(fwd_Ez[focal_point_x, focal_point_y])**2

    adj_source = np.zeros((simulation_width_cells, simulation_height_cells),
                          dtype=np.complex)
    adj_source[focal_point_x, focal_point_y] = np.conj(fwd_Ez[focal_point_x,
                                                              focal_point_y])

    adj_Hx, adj_Hy, adj_Ez = simulation.solve(adj_source)

    gradient = 2 * np.real(omega * eps_nought * fwd_Ez * adj_Ez / 1j)

    return fom, gradient
Esempio n. 3
0
    def compute_fom_and_gradient_ez(self, omega_idx, device_permittivity):
        omega = self.omega_values[omega_idx]

        fwd_Hx, fwd_Hy, fwd_Ez = self.compute_forward_fields_ez(
            omega, device_permittivity)

        fom = (1. / self.ez_transmission_normalization[omega_idx]
               ) * self.compute_fom_from_fields_ez(
                   fwd_Hx, fwd_Hy, fwd_Ez,
                   self.src_scattered_Hx_by_omega[omega_idx, :],
                   self.src_scattered_Hy_by_omega[omega_idx, :],
                   self.src_scattered_Ez_by_omega[omega_idx, :])

        scattered_Hx = (
            fwd_Hx[self.transmission_x_bounds[0]:self.transmission_x_bounds[1],
                   self.transmission_y] -
            self.src_scattered_Hx_by_omega[omega_idx, :])

        adj_source = np.zeros(
            (self.simulation_width_voxels, self.simulation_height_voxels),
            dtype=np.complex)
        adj_source[self.transmission_x_bounds[0]:self.transmission_x_bounds[1],
                   self.transmission_y] = np.conj(scattered_Hx)

        simulation = ceviche.fdfd_ez(omega, self.mesh_size_m,
                                     self.rel_eps_simulation,
                                     [self.pml_voxels, self.pml_voxels])
        adj_Hx, adj_Hy, adj_Ez = simulation.solve(adj_source)

        gradient = (1. / self.ez_transmission_normalization[omega_idx]
                    ) * 2 * np.real(omega * eps_nought * fwd_Ez * adj_Ez /
                                    (1j))

        return fom, gradient
	def compute_forward_fields( self, omega, device_permittivity ):
		self.rel_eps_simulation[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] = device_permittivity

		simulation = ceviche.fdfd_ez( omega, self.mesh_size_m, self.rel_eps_simulation, [ self.pml_voxels, self.pml_voxels ] )
		fwd_Hx, fwd_Hy, fwd_Ez = simulation.solve( self.fwd_source )

		return fwd_Ez
Esempio n. 5
0
    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)
Esempio n. 6
0
    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 eval_loss( self, omega ):
		print( self.max_relative_permittivity )
		self.rel_eps_simulation[ :, : ] = self.max_relative_permittivity

		simulation = ceviche.fdfd_ez( omega, self.mesh_size_m, self.rel_eps_simulation, [ self.pml_voxels, self.pml_voxels ] )
		fwd_Hx, fwd_Hy, fwd_Ez = simulation.solve( self.fwd_source )

		return fwd_Ez
Esempio n. 8
0
    def test_Ez(self):
        print('\ttesting Ez')

        F = fdfd_ez(self.omega, self.dL, self.eps_r, self.npml)
        Hx, Hy, Ez = F.solve(self.source)
        Ez_max = np.max(np.abs(Ez))
        plt.imshow(np.real(Ez), cmap='RdBu', vmin=-Ez_max / 5, vmax=Ez_max / 5)
        plt.show()
Esempio n. 9
0
    def test_Ez(self):
        print('\ttesting Ez')

        F = fdfd_ez(self.omega, self.dL, self.eps_r, self.npml)
        Hx, Hy, Ez = F.solve(self.source)
        plot_component = Ez
        field_max = np.max(np.abs(plot_component))
        plt.imshow(np.real(plot_component),
                   cmap='RdBu',
                   vmin=-field_max / 5,
                   vmax=field_max / 5)
        plt.show()
Esempio n. 10
0
def viz_sim(epsr):
    """Solve and visualize a simulation with permittivity 'epsr'
    """
    simulation = fdfd_ez(omega, dl, epsr, [Npml, Npml])
    Hx, Hy, Ez = simulation.solve(source)
    fig, ax = plt.subplots(1, 2, constrained_layout=True, figsize=(6,3))
    ceviche.viz.real(Ez, outline=epsr, ax=ax[0], cbar=False)
    ax[0].plot(input_slice.x*np.ones(len(input_slice.y)), input_slice.y, 'g-')
    for output_slice in output_slices:
        ax[0].plot(output_slice.x*np.ones(len(output_slice.y)), output_slice.y, 'r-')
    ceviche.viz.abs(epsr, ax=ax[1], cmap='Greys');
    plt.show()
    return (simulation, ax)
	def compute_fom_and_gradient_and_fields( self, omega, device_permittivity, focal_point_x_loc, fom_scaling=1.0 ):
		fwd_Ez = self.compute_forward_fields( omega, device_permittivity )
		fom = fom_scaling * np.abs( fwd_Ez[ focal_point_x_loc, self.focal_point_y ] )**2
		
		adj_source = np.zeros( ( self.simulation_width_voxels, self.simulation_height_voxels ), dtype=np.complex )
		adj_source[ focal_point_x_loc, self.focal_point_y ] = np.conj( fwd_Ez[ focal_point_x_loc, self.focal_point_y ] )

		simulation = ceviche.fdfd_ez( omega, self.mesh_size_m, self.rel_eps_simulation, [ self.pml_voxels, self.pml_voxels ] )
		adj_Hx, adj_Hy, adj_Ez = simulation.solve( adj_source )

		gradient = fom_scaling * 2 * np.real( omega * eps_nought * fwd_Ez * adj_Ez / 1j )

		return fom, gradient, fwd_Ez
Esempio n. 12
0
    def compute_forward_fields_ez(self,
                                  omega,
                                  device_permittivity,
                                  normalization_permittivity=False):
        self.rel_eps_simulation[self.device_width_start:self.device_width_end,
                                self.device_height_start:self.
                                device_height_end] = device_permittivity

        choose_permittivity = self.rel_eps_simulation

        if normalization_permittivity:
            choose_permittivity = np.ones(self.rel_eps_simulation.shape)

        simulation = ceviche.fdfd_ez(omega, self.mesh_size_m,
                                     choose_permittivity,
                                     [self.pml_voxels, self.pml_voxels])
        fwd_Hx, fwd_Hy, fwd_Ez = simulation.solve(self.fwd_source_ez)

        return fwd_Hx, fwd_Hy, fwd_Ez
Esempio n. 13
0
def compute_fom(omega, mesh_size_m, relative_permittivity, pml_cells,
                fwd_src_y_loc, focal_point_x_loc, focal_point_y_loc):
    simulation_width_cells = relative_permittivity.shape[0]
    simulation_height_cells = relative_permittivity.shape[1]
    simulation = ceviche.fdfd_ez(omega, mesh_size_m, relative_permittivity,
                                 pml_cells)

    fwd_src_x = np.arange(0, simulation_width_cells)
    fwd_src_y = fwd_src_y_loc * np.ones(fwd_src_x.shape, dtype=int)

    fwd_source = np.zeros((simulation_width_cells, simulation_height_cells),
                          dtype=np.complex)
    fwd_source[fwd_src_x, fwd_src_y] = 1

    fwd_Hx, fwd_Hy, fwd_Ez = simulation.solve(fwd_source)

    focal_point_y = focal_point_y_loc
    focal_point_x = focal_point_x_loc

    fom = np.abs(fwd_Ez[focal_point_x, focal_point_y])**2

    return fom
	def plot_subcell_gradient_variations( self, omega_idx, factor ):
		import matplotlib.pyplot as plt
		import_density = upsample( self.design_density, self.coarsen_factor )
		device_permittivity = self.density_to_permittivity( import_density )

		device_width_array = np.linspace( 0, 1, self.device_width_voxels )
		device_height_array = np.linspace( 0, 1, self.device_height_voxels )

		interp_width_array = np.linspace( 0, 1, factor * self.device_width_voxels )
		interp_height_array = np.linspace( 0, 1, factor * self.device_height_voxels )

		omega = self.omega_values[ omega_idx ]

		fwd_Ez = self.compute_forward_fields( omega, device_permittivity )
		
		focal_point_x_loc = self.focal_spots_x_voxels[ 0 ]

		interp_spline_fwd_real = RectBivariateSpline(
			device_width_array, device_height_array, np.real( fwd_Ez[
				self.device_width_start : self.device_width_end,
				self.device_height_start : self.device_height_end
		] ) )

		interp_spline_fwd_imag = RectBivariateSpline(
			device_width_array, device_height_array, np.imag( fwd_Ez[
				self.device_width_start : self.device_width_end,
				self.device_height_start : self.device_height_end
		] ) )


		adj_source = np.zeros( ( self.simulation_width_voxels, self.simulation_height_voxels ), dtype=np.complex )
		adj_source[ focal_point_x_loc, self.focal_point_y ] = np.conj( fwd_Ez[ focal_point_x_loc, self.focal_point_y ] )

		simulation = ceviche.fdfd_ez( omega, self.mesh_size_m, self.rel_eps_simulation, [ self.pml_voxels, self.pml_voxels ] )
		adj_Hx, adj_Hy, adj_Ez = simulation.solve( adj_source )

		interp_spline_adj_real = RectBivariateSpline(
			device_width_array, device_height_array, np.real( adj_Ez[
				self.device_width_start : self.device_width_end,
				self.device_height_start : self.device_height_end
		] ) )

		interp_spline_adj_imag = RectBivariateSpline(
			device_width_array, device_height_array, np.imag( adj_Ez[
				self.device_width_start : self.device_width_end,
				self.device_height_start : self.device_height_end
		] ) )


		interpolated_fwd_real = interp_spline_fwd_real( interp_width_array, interp_height_array )
		interpolated_adj_real = interp_spline_adj_real( interp_width_array, interp_height_array )
		interpolated_fwd_imag = interp_spline_fwd_imag( interp_width_array, interp_height_array )
		interpolated_adj_imag = interp_spline_adj_imag( interp_width_array, interp_height_array )

		interpolated_fwd = interpolated_fwd_real + 1j * interpolated_fwd_imag
		interpolated_adj = interpolated_adj_real + 1j * interpolated_adj_imag

		interp_grad = 2 * np.real( interpolated_fwd * interpolated_adj )

		averaged_grad = np.zeros( ( self.device_width_voxels, self.device_height_voxels ) )
		middle_grad = 2 * np.real(
			fwd_Ez[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] *
			adj_Ez[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] )

		for x_idx in range( 0, self.device_width_voxels ):
			for y_idx in range( 0, self.device_height_voxels ):
				for off_x in range( 0, factor ):
					start_x = x_idx * factor
					for off_y in range( 0, factor ):
						start_y = y_idx * factor

						averaged_grad[ x_idx, y_idx ] += (
							( 1. / ( factor * factor ) ) *
							interp_grad[ start_x + off_x, start_y + off_y ]
						)

		plt.subplot( 1, 3, 1 )
		plt.imshow( middle_grad, cmap='Blues' )
		plt.colorbar()
		plt.subplot( 1, 3, 2 )
		plt.imshow( averaged_grad, cmap='Blues' )
		plt.colorbar()
		plt.subplot( 1, 3, 3 )
		plt.imshow( ( middle_grad - averaged_grad ), cmap='Greens' )
		plt.colorbar()
		plt.show()





		half_width = int( factor * 0.5 * self.device_width_voxels )
		half_height = int( factor * 0.5 * self.device_height_voxels )

		plt.subplot( 1, 3, 1 )
		plt.imshow( np.abs( interpolated_fwd[ half_width : ( half_width + self.coarsen_factor * 2 * factor ), half_height : ( half_height + self.coarsen_factor * 2 * factor) ] ), cmap='Reds' )
		plt.colorbar()
		plt.subplot( 1, 3, 2 )
		plt.imshow( np.abs( interpolated_adj[ half_width : ( half_width + self.coarsen_factor * 2 * factor ), half_height : ( half_height + self.coarsen_factor * 2 * factor) ] ), cmap='Reds' )
		plt.colorbar()
		plt.subplot( 1, 3, 3 )
		plt.imshow(
			np.real(
				interpolated_fwd[ half_width : ( half_width + self.coarsen_factor * 2 * factor ), half_height : ( half_height + self.coarsen_factor * 2 * factor ) ] *
				interpolated_adj[ half_width : ( half_width + self.coarsen_factor * 2 * factor ), half_height : ( half_height + self.coarsen_factor * 2 * factor ) ] ),
			cmap='Reds' )
		plt.colorbar()
		plt.show()
Esempio n. 15
0
# 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

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

# plot the probe through channel
if PLOT:
    plt.imshow(np.abs(probe + box_region + source).T)
    plt.show()

# vacuum test, get normalization
F_lin = fdfd_ez(omega, dL, eps_r, [npml, npml])
F_nl = fdfd_ez_nl(omega, dL, eps_nl, [npml, npml])

Hx, Hy, Ez = F_lin.solve(source)
H_mag = np.sqrt(np.square(np.abs(Hx)) + np.square(np.abs(Hy)))
E_mag = np.abs(Ez)
I_H0 = np.abs(np.square(np.sum(H_mag * probe)))
I_E0 = np.abs(np.square(np.sum(E_mag * probe)))

print('I_E0 = {}'.format(I_E0))

# plot the vacuum fields
if PLOT:
    plt.imshow(np.real(Ez).T, cmap='RdBu')
    plt.title('real(Hz)')
    plt.xlabel('y')
Esempio n. 16
0
focal_points_x = [
    int(device_width_start + 0.25 * device_width_voxels),
    int(device_width_start + 0.75 * device_width_voxels)
]

device_density = np.random.random(
    (int(device_width_voxels / density_coarsen_factor),
     int(device_height_voxels / density_coarsen_factor)))
upsampled_density = upsample(device_density, density_coarsen_factor)
device_permittivity = density_to_permittivity(upsampled_density)
rel_eps_simulation[device_width_start:device_width_end,
                   device_height_start:device_height_end] = device_permittivity

omega = omega_values[int(0.5 * num_lambda_values)]

simulation = ceviche.fdfd_ez(omega, mesh_size_m, rel_eps_simulation,
                             [pml_voxels, pml_voxels])

fwd_src_x = np.arange(0, simulation_width_voxels)
fwd_src_y_line = fwd_src_y * np.ones(fwd_src_x.shape, dtype=int)

fwd_source = np.zeros((simulation_width_voxels, simulation_height_voxels),
                      dtype=np.complex)
fwd_source[fwd_src_x, fwd_src_y_line] = 1

import time

start = time.time()
fwd_Hx, fwd_Hy, fwd_Ez = simulation.solve(fwd_source)
elapsed = time.time() - start

print("The elapsed time was " + str(elapsed))