def ExH(e, h): ev = mp.Vector3(e[0], e[1], e[2]) hv = mp.Vector3(h[0], h[1], h[2]) return ev.conj().cross(hv)
def main(args): print("\nstart time:", datetime.now()) # -------------------------------------------------------------------------- # physical parameters characterizing light source and interface characteris- # tics (must be adjusted - eihter here or via command line interface (CLI)) # -------------------------------------------------------------------------- interface = args.interface s_pol = args.s_pol ref_medium = args.ref_medium n1 = args.n1 n2 = args.n2 kw_0 = args.kw_0 kr_w = args.kr_w kr_c = args.kr_c # angle of incidence chi_deg = args.chi_deg #chi_deg = 1.0*op.critical(n1, n2) #chi_deg = 0.95*op.brewster(n1, n2) # -------------------------------------------------------------------------- # specific Meep parameters (may need to be adjusted) # -------------------------------------------------------------------------- sx = 5 # size of cell including PML in x-direction sy = 5 # size of cell including PML in y-direction pml_thickness = 0.25 # thickness of PML layer freq = 12 # vacuum frequency of source (5 to 12 is good) runtime = 10 # runs simulation for 10 times freq periods # number of pixels per wavelength in the denser medium (at least 10, # 20 to 30 is a good choice) pixel = 10 # source position with respect to the center (point of impact) in Meep # units (-2.15 good); if equal -r_w, then source position coincides with # waist position source_shift = -2.15 # -------------------------------------------------------------------------- # derived (Meep) parameters (do not change) # -------------------------------------------------------------------------- k_vac = 2 * math.pi * freq k1 = n1 * k_vac n_ref = (1 if ref_medium == 0 else n1 if ref_medium == 1 else n2 if ref_medium == 2 else math.nan) r_w = kr_w / (n_ref * k_vac) w_0 = kw_0 / (n_ref * k_vac) r_c = kr_c / (n_ref * k_vac) shift = source_shift + r_w chi_rad = math.radians(chi_deg) params = dict(W_y=w_0, k=k1) # -------------------------------------------------------------------------- # placement of the dielectric interface within the computational cell # -------------------------------------------------------------------------- # helper functions def alpha(chi_rad): """Angle of inclined plane with y-axis in radians.""" return math.pi / 2 - chi_rad def Delta_x(alpha): """Inclined plane offset to the center of the cell.""" sin_alpha = math.sin(alpha) cos_alpha = math.cos(alpha) return (sx / 2) * (( (math.sqrt(2) - cos_alpha) - sin_alpha) / sin_alpha) cell = mp.Vector3(sx, sy, 0) # geometry-lattice if interface == "planar": default_material = mp.Medium(index=n1) # located at lower right edge for 45 degree geometry = [ mp.Block(size=mp.Vector3(mp.inf, sx * math.sqrt(2), mp.inf), center=mp.Vector3(+sx / 2 + Delta_x(alpha(chi_rad)), -sy / 2), e1=mp.Vector3(1 / math.tan(alpha(chi_rad)), 1, 0), e2=mp.Vector3(-1, 1 / math.tan(alpha(chi_rad)), 0), e3=mp.Vector3(0, 0, 1), material=mp.Medium(index=n2)) ] elif interface == "concave": default_material = mp.Medium(index=n2) # move center to the right in order to ensure that the point of impact # is always centrally placed geometry = [ mp.Cylinder(center=mp.Vector3(-r_c * math.cos(chi_rad), +r_c * math.sin(chi_rad)), height=mp.inf, radius=r_c, material=mp.Medium(index=n1)) ] elif interface == "convex": default_material = mp.Medium(index=n1) # move center to the right in order to ensure that the point of impact # is always centrally placed geometry = [ mp.Cylinder(center=mp.Vector3(+r_c * math.cos(chi_rad), -r_c * math.sin(chi_rad)), height=mp.inf, radius=r_c, material=mp.Medium(index=n2)) ] # -------------------------------------------------------------------------- # add absorbing boundary conditions and discretize structure # -------------------------------------------------------------------------- pml_layers = [mp.PML(pml_thickness)] resolution = pixel * (n1 if n1 > n2 else n2) * freq # set Courant factor (mandatory if either n1 or n2 is smaller than 1) Courant = (n1 if n1 < n2 else n2) / 2 # -------------------------------------------------------------------------- # display values of physical variables # -------------------------------------------------------------------------- print() print("Specified variables and derived values:") print("n1:", n1) print("n2:", n2) print("chi: ", chi_deg, " [degree]") print("incl.:", 90 - chi_deg, " [degree]") print("kw_0: ", kw_0) if interface != "planar": print("kr_c: ", kr_c) print("kr_w: ", kr_w) print("k_vac:", k_vac) print("polarisation:", "s" if s_pol else "p") print("interface:", interface) print() # -------------------------------------------------------------------------- # specify current source, output functions and run simulation # -------------------------------------------------------------------------- force_complex_fields = False # default: False eps_averaging = True # default: True filename_prefix = None # specify optical beam beam = op.Gauss2d(x=shift, params=params) sources = [ mp.Source(src=mp.ContinuousSource(frequency=freq, width=0.5), component=mp.Ez if s_pol else mp.Ey, size=mp.Vector3(0, 2, 0), center=mp.Vector3(source_shift, 0, 0), amp_func=beam.profile) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, default_material=default_material, Courant=Courant, geometry=geometry, sources=sources, resolution=resolution, force_complex_fields=force_complex_fields, eps_averaging=eps_averaging, filename_prefix=filename_prefix) sim.use_output_directory( interface) # put output files in a separate folder def eSquared(r, ex, ey, ez): """Calculate |E|^2. With |.| denoting the complex modulus if 'force_complex_fields?' is set to true, otherwise |.| gives the Euclidean norm. """ return mp.Vector3(ex, ey, ez).norm()**2 def output_efield2(sim): """Output E-field intensity.""" name = "e2_s" if s_pol else "e2_p" func = eSquared cs = [mp.Ex, mp.Ey, mp.Ez] return sim.output_field_function(name, cs, func, real_only=True) sim.run(mp.at_beginning(mp.output_epsilon), mp.at_end(mp.output_efield_z if s_pol else mp.output_efield_y), mp.at_end(output_efield2), until=runtime) print("\nend time:", datetime.now())
def main(args): sx = 16 # size of cell in X direction sy = 32 # size of cell in Y direction cell = mp.Vector3(sx, sy, 0) pad = 4 # padding distance between waveguide and cell edge w = 1 # width of waveguide wvg_ycen = -0.5 * (sy - w - (2 * pad)) # y center of horiz. wvg wvg_xcen = 0.5 * (sx - w - (2 * pad)) # x center of vert. wvg if args.no_bend: geometry = [mp.Block(mp.Vector3(mp.inf, w, mp.inf), center=mp.Vector3(0, wvg_ycen), material=mp.Medium(epsilon=12))] else: geometry = [mp.Block(mp.Vector3(sx - pad, w, mp.inf), center=mp.Vector3(-0.5 * pad, wvg_ycen), material=mp.Medium(epsilon=12)), mp.Block(mp.Vector3(w, sy - pad, mp.inf), center=mp.Vector3(wvg_xcen, 0.5 * pad), material=mp.Medium(epsilon=12))] fcen = 0.15 # pulse center frequency df = 0.1 # pulse width (in frequency) sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(1 + (-0.5 * sx), wvg_ycen), size=mp.Vector3(0, w))] pml_layers = [mp.PML(1.0)] resolution = 10 nfreq = 100 # number of frequencies at which to compute flux sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution) if args.no_bend: fr = mp.FluxRegion(center=mp.Vector3((sx / 2) - 1.5, wvg_ycen), size=mp.Vector3(0, w * 2)) else: fr = mp.FluxRegion(center=mp.Vector3(wvg_xcen, (sy / 2) - 1.5), size=mp.Vector3(w * 2, 0)) trans = sim.add_flux(fcen, df, nfreq, fr) refl_fr = mp.FluxRegion(center=mp.Vector3((-0.5 * sx) + 1.5, wvg_ycen), size=mp.Vector3(0, w * 2)) # reflected flux refl = sim.add_flux(fcen, df, nfreq, refl_fr) # for normal run, load negated fields to subtract incident from refl. fields if not args.no_bend: sim.load_minus_flux('refl-flux', refl) if args.no_bend: pt = mp.Vector3((sx / 2) - 1.5, wvg_ycen) else: pt = mp.Vector3(wvg_xcen, (sy / 2) - 1.5) sim.run(mp.at_beginning(mp.output_epsilon), until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-3)) # for normalization run, save flux fields for refl. plane if args.no_bend: sim.save_flux('refl-flux', refl) sim.display_fluxes(trans, refl)
def get_arr2(sim): eps['arr2'] = sim.get_array(mp.Volume(mp.Vector3(), mp.Vector3(10, 10)), component=mp.Dielectric)
import meep as mp import numpy as np import matplotlib.pyplot as plt from meep import materials from sinus import create_vertices sizex = 1 sizey = 2 resolution = 150 pml_th = 30 / resolution fullx = sizex + 2 * pml_th fully = sizey + 2 * pml_th cell = mp.Vector3(fullx, fully, 0) mat = materials.Au ##################### # run modes # geom - show geometry instead of actual simulation # saveref - save the reference file, needed for field enhancement calculations #################### aux_mat = mp.Medium(epsilon=1) geom = False saveref = True #################### #################### # geometry, load AFM profile #################### metal_vert = create_vertices(ampl=0.1, periodicity=0.5, thickness=0.04, resolution=resolution,
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
job = pinboard.pinboard() nm = 1e-9 um = 1e-6 ### Parameters W = 200*nm sep = 330*nm material = meep_ext.material.Au() material = meep.Medium(index=3.5) geometry = [] q = miepy.quaternion.from_spherical_coords(0, np.pi/4) R = miepy.quaternion.as_rotation_matrix(q) geometry.append(meep.Block(center=meep.Vector3(-sep/2, 0, 0), size=meep.Vector3(W, W, W), e1=meep.Vector3(*R[:,0]), e2=meep.Vector3(*R[:,1]), e3=meep.Vector3(*R[:,2]), material=material)) geometry.append(meep.Block(center=meep.Vector3(sep/2, 0, 0), size=meep.Vector3(W, W, W), e1=meep.Vector3(*R[:,0]), e2=meep.Vector3(*R[:,1]), e3=meep.Vector3(*R[:,2]), material=material)) box = [sep + 2**.5*W, 2**.5*W, 2**.5*W] resolution = 1/(8*nm)
import meep as mp import numpy as np import math cell_size = mp.Vector3(2, 2, 2) geometry = [ #mp.Block(center=mp.Vector3(0,0,0), size=cell_size, material=mp.air), mp.Ellipsoid(material=mp.metal, size=mp.Vector3(2, 0.5, 0.5), e1=mp.Vector3(1, 1, 1), e2=mp.Vector3(-1, 1, -1), e3=mp.Vector3(-2, 1, 1)) ] sim = mp.Simulation(resolution=50, cell_size=cell_size, geometry=geometry) sim.init_sim() eps_data = sim.get_epsilon() #eps_data = sim.get_array() #sim.plot3D(eps_data) #from mayavi import mlab #s = mlab.contour3d() #mlab.show() #mlab.savefig(filename='test2.png') from mayavi import mlab s = mlab.contour3d(eps_data, colormap="hsv") #mlab.show()
def get_arr1(sim): eps['arr1'] = sim.get_array( mp.Dielectric, mp.Volume(mp.Vector3(), mp.Vector3(10, 10)))
import meep as mp import math import numpy as np import numpy.matlib import matplotlib.pyplot as plt resolution = 50 # pixels/um dpml = 1.0 # PML thickness sz = 10 + 2 * dpml cell_size = mp.Vector3(z=sz) pml_layers = [mp.PML(dpml)] wvl_min = 0.4 # min wavelength wvl_max = 0.8 # max wavelength fmin = 1 / wvl_max # min frequency fmax = 1 / wvl_min # max frequency fcen = 0.5 * (fmin + fmax) # center frequency df = fmax - fmin # frequency width nfreq = 50 # number of frequency bins def planar_reflectance(theta): # rotation angle (in degrees) of source: CCW around Y axis, 0 degrees along +Z axis theta_r = math.radians(theta) # plane of incidence is XZ; rotate counter clockwise (CCW) about y-axis k = mp.Vector3(z=fmin).rotate(mp.Vector3(y=1), theta_r) # if normal incidence, force number of dimensions to be 1 if theta_r == 0:
def planar_reflectance(theta): # rotation angle (in degrees) of source: CCW around Y axis, 0 degrees along +Z axis theta_r = math.radians(theta) # plane of incidence is XZ; rotate counter clockwise (CCW) about y-axis k = mp.Vector3(z=fmin).rotate(mp.Vector3(y=1), theta_r) # if normal incidence, force number of dimensions to be 1 if theta_r == 0: dimensions = 1 else: dimensions = 3 sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=mp.Vector3(z=-0.5 * sz + dpml)) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, sources=sources, k_point=k, dimensions=dimensions, resolution=resolution) refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25 * sz)) refl = sim.add_flux(fcen, df, nfreq, refl_fr) sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9)) empty_flux = mp.get_fluxes(refl) empty_data = sim.get_flux_data(refl) sim.reset_meep() # add a block with n=3.5 for the air-dielectric interface geometry = [ mp.Block(mp.Vector3(mp.inf, mp.inf, 0.5 * sz), center=mp.Vector3(z=0.25 * sz), material=mp.Medium(index=3.5)) ] sim = mp.Simulation(cell_size=cell_size, geometry=geometry, boundary_layers=pml_layers, sources=sources, k_point=k, dimensions=dimensions, resolution=resolution) refl = sim.add_flux(fcen, df, nfreq, refl_fr) sim.load_minus_flux_data(refl, empty_data) sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9)) refl_flux = mp.get_fluxes(refl) freqs = mp.get_flux_freqs(refl) wvls = np.empty(nfreq) theta_out = np.empty(nfreq) R = np.empty(nfreq) for i in range(nfreq): wvls[i] = 1 / freqs[i] theta_out[i] = math.degrees(math.asin(k.x / freqs[i])) R[i] = -refl_flux[i] / empty_flux[i] print("refl:, {}, {}, {}, {}".format(k.x, wvls[i], theta_out[i], R[i])) return k.x * np.ones(nfreq), wvls, theta_out, R
def __init__(self, resolution): self.block_index = 1.53 self.block_permittivity = self.block_index**2 self.permittivity_bounds = [1.0, self.block_permittivity] self.length_scale_meters = 1e-6 self.length_scale_microns = self.length_scale_meters * 1e6 self.num_wavelengths_per_range = 1 self.num_ranges = 3 self.num_total_wavelengths = self.num_ranges * self.num_wavelengths_per_range self.num_total_frequencies = self.num_total_wavelengths self.blue_lower_lambda_um = .4 self.blue_upper_lambda_um = .5 self.green_lower_lambda_um = self.blue_upper_lambda_um self.green_upper_lambda_um = .6 self.red_lower_lambda_um = self.green_upper_lambda_um self.red_upper_lambda_um = .7 self.source_lower_lambda_um = self.blue_lower_lambda_um self.source_upper_lambda_um = self.red_upper_lambda_um self.source_upper_freq_unitless = self.length_scale_microns / self.source_lower_lambda_um; self.source_lower_freq_unitless = self.length_scale_microns / self.source_upper_lambda_um; self.source_freq_spread_unitless = self.source_upper_freq_unitless - self.source_lower_freq_unitless; self.source_freq_center_unitless = 0.5 * (self.source_lower_freq_unitless + self.source_upper_freq_unitless); self.dft_freq_min = self.source_lower_freq_unitless self.dft_freq_max = self.source_upper_freq_unitless self.dft_freq_spread = self.dft_freq_max - self.dft_freq_min self.dft_freq_center = self.dft_freq_min + 0.5 * self.dft_freq_spread self.frequencies_in_ranges = [[], [], []] self.max_intensity = [0] * self.num_total_frequencies for freq_idx in range(0, self.num_total_frequencies): frequency = ((float(freq_idx) / float(self.num_total_frequencies - 1)) * self.dft_freq_spread) + self.dft_freq_min wavelength_um = self.length_scale_microns / frequency self.max_intensity[freq_idx] = 1.0 / (wavelength_um * wavelength_um) self.frequencies_in_ranges[self.check_frequency_range(frequency)].append(frequency) self.max_frequencies_in_a_range = max(list(map(lambda y: len(y), self.frequencies_in_ranges))) # Maybe... set this by a real length scaled by the length scale? # self.spacing = 0.025 / self.length_scale_microns # self.resolution = int(1 / self.spacing) self.resolution = resolution self.spacing = 1 / resolution self.focal_length = 1.5 / self.length_scale_microns self.side_gap = 0.5 / self.length_scale_microns self.top_bottom_gap = .2 / self.length_scale_microns self.block_dim_x = 2 / self.length_scale_microns; self.block_dim_y = 2 / self.length_scale_microns; self.block_dim_z = 2 / self.length_scale_microns; self.block_size = mp.Vector3(self.block_dim_x, self.block_dim_y, self.block_dim_z) self.source_loc_z_from_pml = 0.0 / self.length_scale_microns; self.t_pml_x = 1.0 / self.length_scale_microns self.t_pml_y = 1.0 / self.length_scale_microns self.t_pml_z = 1.0 / self.length_scale_microns self.cell_dim_x = 2 * self.t_pml_x + 2 * self.side_gap + self.block_dim_x; self.cell_dim_y = 2 * self.t_pml_y + 2 * self.side_gap + self.block_dim_y; self.cell_dim_z = 2 * self.t_pml_z + 2 * self.top_bottom_gap + self.block_dim_z + self.focal_length; self.cell = mp.Vector3(self.cell_dim_x, self.cell_dim_y, self.cell_dim_z) self.block_center = mp.Vector3(0, 0, 0.5 * self.cell_dim_z - self.t_pml_z - self.top_bottom_gap - 0.5 * self.block_dim_z) self.top_source_center = mp.Vector3(0, 0, 0.5 * self.cell_dim_z - self.t_pml_z) self.device = bayer_filter.BayerFilter(self.block_center, self.resolution, self.block_size, self.permittivity_bounds, self.length_scale_meters); self.pml_layers = [mp.PML(thickness = self.t_pml_x, direction = mp.X), mp.PML(thickness = self.t_pml_y, direction = mp.Y), mp.PML(thickness = self.t_pml_z, direction = mp.Z)] # Run all the way up to and through the PML boundary layers self.top_bottom_source_size_x = self.cell_dim_x self.top_bottom_source_size_y = self.cell_dim_y # Surface currenets self.top_bottom_source_size_z = 0; self.top_bottom_source_size = mp.Vector3(self.top_bottom_source_size_x, self.top_bottom_source_size_y, self.top_bottom_source_size_z) # This is the default value for it, but let's be explicit self.gaussian_cutoff = 5.0 self.gaussian_width = 1.0 / self.source_freq_spread_unitless self.gaussian_peak_time = self.gaussian_cutoff * self.gaussian_width top_source_J = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex, amplitude=1.0, center=self.top_source_center, size=self.top_bottom_source_size) self.forward_sources = [top_source_J] self.geometry = [mp.Block(size=self.block_size, center=self.block_center, epsilon_func=lambda loc: self.device.get_permittivity_value(loc))] self.z_measurement_point = self.block_center.z - 0.5 * self.block_dim_z - self.focal_length # Let's set up where we want to measure the figure of merit self.measure_blue_focal = mp.Vector3(self.block_dim_x / 4.0, self.block_dim_y / 4.0, self.z_measurement_point) self.measure_green_xpol_focal = mp.Vector3(-self.block_dim_x / 4.0, self.block_dim_y / 4.0, self.z_measurement_point) self.measure_red_focal = mp.Vector3(-self.block_dim_x / 4.0, -self.block_dim_y / 4.0, self.z_measurement_point) self.measure_green_ypol_focal = mp.Vector3(self.block_dim_x / 4.0, -self.block_dim_y / 4.0, self.z_measurement_point) self.dft_focal_plane_fields_center = mp.Vector3(0, 0, self.z_measurement_point) self.dft_focal_area_fields_size = mp.Vector3(self.block_dim_x, self.block_dim_y, 0); self.interpolate_focal_area_fields = interp.Interpolate(self.dft_focal_plane_fields_center, self.dft_focal_area_fields_size, self.resolution, 2) self.dft_block_fields_center = self.block_center self.dft_block_fields_size = self.block_size self.focal_plane_centers = [self.measure_blue_focal, self.measure_green_xpol_focal, self.measure_red_focal, self.measure_green_ypol_focal] self.xy_symmetry_transformation = [0] * 4 self.xy_symmetry_transformation[BayerOptimization.QUADRANT_TOP_RIGHT] = BayerOptimization.QUADRANT_TOP_RIGHT self.xy_symmetry_transformation[BayerOptimization.QUADRANT_TOP_LEFT] = BayerOptimization.QUADRANT_BOTTOM_RIGHT self.xy_symmetry_transformation[BayerOptimization.QUADRANT_BOTTOM_LEFT] = BayerOptimization.QUADRANT_BOTTOM_LEFT self.xy_symmetry_transformation[BayerOptimization.QUADRANT_BOTTOM_RIGHT] = BayerOptimization.QUADRANT_TOP_LEFT self.range_to_quadrant = [0] * 4 self.range_to_quadrant[BayerOptimization.RANGE_RED] = BayerOptimization.QUADRANT_RED self.range_to_quadrant[BayerOptimization.RANGE_GREEN] = [BayerOptimization.QUADRANT_GREEN_XPOL, BayerOptimization.QUADRANT_GREEN_YPOL] self.range_to_quadrant[BayerOptimization.RANGE_BLUE] = BayerOptimization.QUADRANT_BLUE self.quadrant_to_range = [0] * 4 self.quadrant_to_range[BayerOptimization.QUADRANT_RED] = BayerOptimization.RANGE_RED self.quadrant_to_range[BayerOptimization.QUADRANT_GREEN_XPOL] = BayerOptimization.RANGE_GREEN self.quadrant_to_range[BayerOptimization.QUADRANT_GREEN_YPOL] = BayerOptimization.RANGE_GREEN self.quadrant_to_range[BayerOptimization.QUADRANT_BLUE] = BayerOptimization.RANGE_BLUE # Dipole sources have the following size in Meep dipole_source_size = mp.Vector3(0, 0, 0) # Adjoint source 0 corresponds to the blue quadrant adjoint_source_0 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex, center=self.measure_blue_focal, amplitude=np.complex(0, 1), size=dipole_source_size); # Adjoint source 1 corresponds to the green x-polarized quadrant adjoint_source_1 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex, center=self.measure_green_xpol_focal, amplitude=np.complex(0, 1), size=dipole_source_size); # Adjoint source 2 corresponds to the red quadrant adjoint_source_2 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex, center=self.measure_red_focal, amplitude=np.complex(0, 1), size=dipole_source_size); # Adjoint source 3 corresponds to the green y-polarized quadrant adjoint_source_3 = mp.Source(mp.GaussianSource(self.source_freq_center_unitless, fwidth=self.source_freq_spread_unitless, cutoff=self.gaussian_cutoff, start_time=0), component=mp.Ex, center=self.measure_green_ypol_focal, amplitude=np.complex(0, 1), size=dipole_source_size); self.adjoint_sources = [adjoint_source_0, adjoint_source_1, adjoint_source_2, adjoint_source_3] num_material_points = self.device.interpolation.num_points self.forward_fields_xpol = np.zeros((self.num_ranges, self.max_frequencies_in_a_range, 3, *num_material_points), dtype=np.complex) self.adjoint_fields_xpol = np.zeros((len(self.adjoint_sources), self.num_ranges, self.max_frequencies_in_a_range, 3, *num_material_points), dtype=np.complex)
def find_k(self, p, omega, band_min, band_max, korig_and_kdir, tol, kmag_guess, kmag_min, kmag_max, *band_funcs): num_bands_save = self.num_bands kpoints_save = self.k_points nb = band_max - band_min + 1 kdir = korig_and_kdir[1] if type( korig_and_kdir) is list else korig_and_kdir lat = self.geometry_lattice kdir1 = mp.cartesian_to_reciprocal( mp.reciprocal_to_cartesian(kdir, lat).unit(), lat) if type(korig_and_kdir) is list: korig = korig_and_kdir[0] else: korig = mp.Vector3() # k0s is a list caching the best k value found for each band: if type(kmag_guess) is list: k0s = kmag_guess else: k0s = [kmag_guess] * (band_max - band_min + 1) # dict to memoize all "band: k" results bktab = {} def rootfun(b): def _rootfun(k): # First, look in the cached table tab_val = bktab.get((b, k), None) if tab_val: print("find-k {} at {}: {} (cached)".format( b, k, tab_val[0])) return tab_val # Otherwise, compute bands and cache results else: self.num_bands = b self.k_points = [korig + kdir1.scale(k)] self.run_parity(p, False) v = self.mode_solver.compute_group_velocity_component( kdir1) # Cache computed values for _b, _f, _v in zip(range(band_min, b - band_min + 1, 1), self.freqs[band_min - 1:], v[band_min - 1:]): tabval = bktab.get((_b, k0s[_b - band_min]), None) if not tabval or abs(_f - omega) < abs(tabval[0]): k0s[_b - band_min + 1] = k bktab[(_b, k)] = (_f - omega, _v) fun = self.freqs[-1] - omega print("find-k {} at {}: {}".format(b, k, fun)) return (fun, v[-1]) return _rootfun # Don't let previous computations interfere if self.mode_solver: self.randomize_fields() ks = [] for b in range(band_max, band_max - nb, -1): ks.append( mp.find_root_deriv(rootfun(b), tol, kmag_min, kmag_max, k0s[b - band_min])) if band_funcs: for b, k in zip(range(band_max, band_max - nb, -1), reversed(ks)): self.num_bands = b self.k_points = [korig + kdir1.scale(k)] def bfunc(ms, b_prime): if b_prime == b: for f in band_funcs: apply_band_func_thunk(ms, f, b, True) self.run_parity(p, False, bfunc) self.num_bands = num_bands_save self.k_points = kpoints_save ks = list(reversed(ks)) print("{}kvals:, {}, {}, {}".format(self.parity, omega, band_min, band_max), end='') for k in korig: print(", {}".format(k), end='') for k in kdir1: print(", {}".format(k), end='') for k in ks: print(", {}".format(k), end='') print() return ks
def __init__(self, resolution=10, is_negative_epsilon_ok=False, eigensolver_flops=0, eigensolver_flags=68, use_simple_preconditioner=False, force_mu=False, mu_input_file='', epsilon_input_file='', mesh_size=3, target_freq=0.0, tolerance=1.0e-7, num_bands=1, k_points=[], ensure_periodicity=True, geometry=[], geometry_lattice=mp.Lattice(), geometry_center=mp.Vector3(0, 0, 0), default_material=mp.Medium(epsilon=1), dimensions=3, random_fields=False, filename_prefix='', deterministic=False, verbose=False, optimize_grid_size=True, eigensolver_nwork=3, eigensolver_block_size=-11): self.mode_solver = None self.resolution = resolution self.eigensolver_flags = eigensolver_flags self.k_points = k_points self.geometry = geometry self.geometry_lattice = geometry_lattice self.geometry_center = geometry_center self.default_material = default_material self.random_fields = random_fields self.filename_prefix = filename_prefix self.optimize_grid_size = optimize_grid_size self.parity = '' self.iterations = 0 self.all_freqs = None self.freqs = [] self.band_range_data = [] self.total_run_time = 0 self.current_k = mp.Vector3() self.k_split_num = 1 self.k_split_index = 0 self.eigensolver_iters = [] grid_size = self._adjust_grid_size() if type(self.default_material) is not mp.Medium and callable( self.default_material): self.default_material.eps = False self.mode_solver = mode_solver( num_bands, self.resolution, self.geometry_lattice, tolerance, mesh_size, self.default_material, deterministic, target_freq, dimensions, verbose, ensure_periodicity, eigensolver_flops, is_negative_epsilon_ok, epsilon_input_file, mu_input_file, force_mu, use_simple_preconditioner, grid_size, eigensolver_nwork, eigensolver_block_size, )
def __init__(self, dir_name, wavelength, thy_absorb, cyt_absorb): self.base_directory = base_directory + str(dir_name) self.wavelength = wavelength self.thy_absorb = thy_absorb self.cyt_absorb = cyt_absorb self.frequency = 1 / wavelength # Calculate wavelengths dependent on RI self.wavelength_in_media = wavelength / ri_media self.wavelength_in_cytoplasm = wavelength / ri_cytoplasm self.wavelength_in_thylakoid = wavelength / ri_thylakoid max_freq = self.frequency - 0.01 min_freq = self.frequency + 0.01 self.pulse_width = abs(max_freq - min_freq) cell = mp.Vector3(sxx, sxy, 0) pml_layers = [mp.PML(dpml)] thylakoid_material = mp.Medium(index=ri_thylakoid, D_conductivity=2 * math.pi * self.frequency * (thy_absorb / (ri_thylakoid ** 2))) cytoplasm_material = mp.Medium(index=ri_cytoplasm, D_conductivity=2 * math.pi * self.frequency * (cyt_absorb / (ri_cytoplasm ** 2))) thylakoid_region = mp.Sphere(radius=cell_radius, center=mp.Vector3(0, 0), material=thylakoid_material) cytoplasm_region = mp.Sphere(radius=cell_radius - thylakoid_thickness, center=mp.Vector3(0, 0), material=cytoplasm_material) geometry = [thylakoid_region, cytoplasm_region] # Sources kdir = mp.Vector3(1, 0, 0) # direction of k (length is irrelevant) n = ri_media # refractive index of material containing the source k = kdir.unit().scale(2 * math.pi * self.frequency * n) # k with correct length def pw_amp(k, x0): def _pw_amp(x): return cmath.exp(1j * k.dot(x + x0)) return _pw_amp source = [ mp.Source( mp.ContinuousSource(frequency=self.frequency, fwidth=self.pulse_width), # along x axis component=mp.Ez, center=mp.Vector3(-0.5 * simulation_size, 0), # x, ,y ,z size=mp.Vector3(0, sxy, 0), amp_func=pw_amp(k, mp.Vector3(x=-0.5 * simulation_size)) ) ] sim = mp.Simulation( cell_size=cell, sources=source, boundary_layers=pml_layers, resolution=resolution, geometry=geometry, default_material=mp.Medium(index=ri_media), force_complex_fields=complex_f, eps_averaging=eps_av, ) sim.use_output_directory(self.base_directory) sim.run(mp.at_every(0.6, mp.output_png(mp.Ez, "-Zc/data/home/bt16268/simInput/customColour.txt")), until=t)
def _load_dump_structure(self, chunk_file=False, chunk_sim=False): from meep.materials import Al resolution = 50 cell = mp.Vector3(5, 5) sources = mp.Source(src=mp.GaussianSource(1, fwidth=0.2), center=mp.Vector3(), component=mp.Ez) one_by_one = mp.Vector3(1, 1, mp.inf) geometry = [ mp.Block(material=Al, center=mp.Vector3(), size=one_by_one), mp.Block(material=mp.Medium(epsilon=13), center=mp.Vector3(1), size=one_by_one) ] pml_layers = [mp.PML(0.5)] symmetries = [mp.Mirror(mp.Y)] sim1 = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=pml_layers, geometry=geometry, symmetries=symmetries, sources=[sources]) sample_point = mp.Vector3(0.12, -0.29) ref_field_points = [] def get_ref_field_point(sim): p = sim.get_field_point(mp.Ez, sample_point) ref_field_points.append(p.real) sim1.run(mp.at_every(5, get_ref_field_point), until=50) dump_fn = os.path.join(temp_dir, 'test_load_dump_structure.h5') dump_chunk_fname = None chunk_layout = None sim1.dump_structure(dump_fn) if chunk_file: dump_chunk_fname = os.path.join( temp_dir, 'test_load_dump_structure_chunks.h5') sim1.dump_chunk_layout(dump_chunk_fname) chunk_layout = dump_chunk_fname if chunk_sim: chunk_layout = sim1 sim = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=pml_layers, sources=[sources], symmetries=symmetries, chunk_layout=chunk_layout, load_structure=dump_fn) field_points = [] def get_field_point(sim): p = sim.get_field_point(mp.Ez, sample_point) field_points.append(p.real) sim.run(mp.at_every(5, get_field_point), until=50) for ref_pt, pt in zip(ref_field_points, field_points): self.assertAlmostEqual(ref_pt, pt)
def handle_cvector_dataset(self, in_arr): in_x_re = np.real(in_arr[:, :, 0]).ravel() in_x_im = np.imag(in_arr[:, :, 0]).ravel() in_y_re = np.real(in_arr[:, :, 1]).ravel() in_y_im = np.imag(in_arr[:, :, 1]).ravel() in_z_re = np.real(in_arr[:, :, 2]).ravel() in_z_im = np.imag(in_arr[:, :, 2]).ravel() d_in = [[in_x_re, in_x_im], [in_y_re, in_y_im], [in_z_re, in_z_im]] in_dims = [in_arr.shape[0], in_arr.shape[1], 1] rank = 2 if self.verbose: print("Found complex vector dataset...") if self.verbose: fmt = "Input data is rank {}, size {}x{}x{}." print(fmt.format(rank, in_dims[0], in_dims[1], in_dims[2])) # rotate vector field according to cart_map if self.verbose: fmt1 = "Rotating vectors by matrix [ {:.10g}, {:.10g}, {:.10g}" fmt2 = " {:.10g}, {:.10g}, {:.10g}" fmt3 = " {:.10g}, {:.10g}, {:.10g} ]" print(fmt1.format(self.cart_map.c1.x, self.cart_map.c2.x, self.cart_map.c3.x)) print(fmt2.format(self.cart_map.c1.y, self.cart_map.c2.y, self.cart_map.c3.y)) print(fmt3.format(self.cart_map.c1.z, self.cart_map.c2.z, self.cart_map.c3.z)) N = in_dims[0] * in_dims[1] for ri in range(2): for i in range(N): v = mp.Vector3(d_in[0][ri][i], d_in[1][ri][i], d_in[2][ri][i]) v = self.cart_map * v d_in[0][ri][i] = v.x d_in[1][ri][i] = v.y d_in[2][ri][i] = v.z out_dims = [1, 1, 1] if self.resolution > 0: out_dims[0] = self.Rout.c1.norm() * self.resolution + 0.5 out_dims[1] = self.Rout.c2.norm() * self.resolution + 0.5 out_dims[2] = self.Rout.c3.norm() * self.resolution + 0.5 else: for i in range(3): out_dims[i] = in_dims[i] * self.multiply_size[i] out_dims[2] = 1 N = 1 for i in range(3): out_dims[i] = int(max(out_dims[i], 1)) N *= out_dims[i] if self.verbose: fmt = "Output data {}x{}x{}." print(fmt.format(out_dims[0], out_dims[1], out_dims[2])) if self.kpoint: kvector = [self.kpoint.x, self.kpoint.y, self.kpoint.z] else: kvector = [] converted = [] for dim in range(3): out_arr_re = np.zeros(int(N)) out_arr_im = np.zeros(int(N)) map_data(d_in[dim][0].ravel(), d_in[dim][1].ravel(), np.array(in_dims, dtype=np.intc), out_arr_re, out_arr_im, np.array(out_dims, dtype=np.intc), self.coord_map, kvector, self.pick_nearest, self.verbose) # multiply * scaleby complex_out = np.vectorize(complex)(out_arr_re, out_arr_im) complex_out *= self.scaleby converted.append(complex_out) result = np.zeros(np.prod(out_dims) * 3, np.complex128) result[0::3] = converted[0] result[1::3] = converted[1] result[2::3] = converted[2] return np.reshape(result, (out_dims[0], out_dims[1], 3))
def print_field(sim): result.append(sim.get_field_point(mp.Ez, mp.Vector3(2, -1)))
def main(args): cell_zmax = 0.5 * cell_thickness if args.three_d else 0 cell_zmin = -0.5 * cell_thickness if args.three_d else 0 si_zmax = t_Si if args.three_d else 0 # read cell size, volumes for source region and flux monitors, # and coupler geometry from GDSII file upper_branch = mp.get_GDSII_prisms( silicon, gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax) lower_branch = mp.get_GDSII_prisms( silicon, gdsII_file, LOWER_BRANCH_LAYER, si_zmin, si_zmax) cell = mp.GDSII_vol(gdsII_file, CELL_LAYER, cell_zmin, cell_zmax) p1 = mp.GDSII_vol(gdsII_file, PORT1_LAYER, si_zmin, si_zmax) p2 = mp.GDSII_vol(gdsII_file, PORT2_LAYER, si_zmin, si_zmax) p3 = mp.GDSII_vol(gdsII_file, PORT3_LAYER, si_zmin, si_zmax) p4 = mp.GDSII_vol(gdsII_file, PORT4_LAYER, si_zmin, si_zmax) src_vol = mp.GDSII_vol(gdsII_file, SOURCE_LAYER, si_zmin, si_zmax) # displace upper and lower branches of coupler (as well as source and flux regions) if args.d != default_d: delta_y = 0.5 * (args.d - default_d) delta = mp.Vector3(y=delta_y) p1.center += delta p2.center -= delta p3.center += delta p4.center -= delta src_vol.center += delta cell.size += 2 * delta for np in range(len(lower_branch)): lower_branch[np].center -= delta for nv in range(len(lower_branch[np].vertices)): lower_branch[np].vertices[nv] -= delta for np in range(len(upper_branch)): upper_branch[np].center += delta for nv in range(len(upper_branch[np].vertices)): upper_branch[np].vertices[nv] += delta geometry = upper_branch + lower_branch if args.three_d: oxide_center = mp.Vector3(z=-0.5 * t_oxide) oxide_size = mp.Vector3(cell.size.x, cell.size.y, t_oxide) oxide_layer = [ mp.Block(material=oxide, center=oxide_center, size=oxide_size)] geometry = geometry + oxide_layer sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=df), size=src_vol.size, center=src_vol.center, eig_band=1, eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z, eig_match_freq=True)] sim = mp.Simulation(resolution=args.res, cell_size=cell.size, boundary_layers=[mp.PML(dpml)], sources=sources, geometry=geometry) mode1 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p1)) mode2 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p2)) mode3 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p3)) mode4 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p4)) sim.run(until_after_sources=100) # S parameters p1_coeff = sim.get_eigenmode_coefficients( mode1, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0] p2_coeff = sim.get_eigenmode_coefficients( mode2, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 1] p3_coeff = sim.get_eigenmode_coefficients( mode3, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0] p4_coeff = sim.get_eigenmode_coefficients( mode4, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0] # transmittance p2_trans = abs(p2_coeff)**2 / abs(p1_coeff)**2 p3_trans = abs(p3_coeff)**2 / abs(p1_coeff)**2 p4_trans = abs(p4_coeff)**2 / abs(p1_coeff)**2 print("trans:, {:.2f}, {:.6f}, {:.6f}, {:.6f}".format( args.d, p2_trans, p3_trans, p4_trans))
#dsub = 2.0 # substrate thickness width = 0.25 #环的宽度 r = width * len(ht) #透镜的半径 focal_length = 20.0 #焦距 ff_res = 10.0 h = 5 NA = math.sin(math.atan(r / focal_length)) NA = round(NA, 3) pml_layers = [mp.PML(thickness=dpml)] sr = r + dpad + dpml sz = dpml + dpad + h + dpad + dpml #sz=dpml+dsub+h+dpad+dpml cell_size = mp.Vector3(sr, 0, sz) #geometry = [mp.Block(material=mp.vacuum, # size=mp.Vector3(sr,0,dpml+dpad), # center=mp.Vector3(0.5*sr,0,-0.5*sz+0.5*(dpml+dpad)))] geometry = [ mp.Block(material=photoresist, size=mp.Vector3(width, 0, ht[0]), center=mp.Vector3(0.5 * width, 0, -0.5 * sz + dpml + dpad + 0.5 * ht[0])) ] for n in range(1, len(ht)): geometry.append( mp.Block(material=photoresist, size=mp.Vector3(width, 0, ht[n]),
def test_in_volume(self): sim = self.init_simple_simulation() sim.filename_prefix = 'test_in_volume' vol = mp.Volume(mp.Vector3(), size=mp.Vector3(x=2)) sim.run(mp.at_end(mp.in_volume(vol, mp.output_efield_z)), until=200)
frq_cen = 0.5 * (frq_min + frq_max) dfrq = frq_max - frq_min nfrq = 100 # at least 8 pixels per smallest wavelength, i.e. np.floor(8/wvl_min) resolution = 25 dpml = 0.5 * wvl_max dair = 0.5 * wvl_max pml_layers = [mp.PML(thickness=dpml)] symmetries = [mp.Mirror(mp.Y), mp.Mirror(mp.Z, phase=-1)] s = 2 * (dpml + dair + r) cell_size = mp.Vector3(s, s, s) # is_integrated=True necessary for any planewave source extending into PML sources = [ mp.Source(mp.GaussianSource(frq_cen, fwidth=dfrq, is_integrated=True), center=mp.Vector3(-0.5 * s + dpml), size=mp.Vector3(0, s, s), component=mp.Ez) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, sources=sources, k_point=mp.Vector3(), symmetries=symmetries)
def test_interpolate_vectors(self): expected = [ mp.Vector3(), mp.Vector3(0.024999999999999842), mp.Vector3(0.04999999999999984), mp.Vector3(0.07499999999999984), mp.Vector3(0.09999999999999984), mp.Vector3(0.12499999999999983), mp.Vector3(0.14999999999999983), mp.Vector3(0.17499999999999982), mp.Vector3(0.19999999999999982), mp.Vector3(0.2249999999999998), mp.Vector3(0.2499999999999998), mp.Vector3(0.2749999999999998), mp.Vector3(0.2999999999999998), mp.Vector3(0.32499999999999984), mp.Vector3(0.34999999999999987), mp.Vector3(0.3749999999999999), mp.Vector3(0.3999999999999999), mp.Vector3(0.42499999999999993), mp.Vector3(0.44999999999999996), mp.Vector3(0.475), mp.Vector3(0.5) ] res = mp.interpolate(19, [mp.Vector3(), mp.Vector3(0.5)]) np.testing.assert_allclose([v.x for v in expected], [v.x for v in res]) np.testing.assert_allclose([v.y for v in expected], [v.y for v in res]) np.testing.assert_allclose([v.z for v in expected], [v.z for v in res])
# -*- coding: utf-8 -*- # From the Meep tutorial: plotting permittivity and fields of a straight waveguide from __future__ import division import meep as mp cell = mp.Vector3(16, 8, 0) geometry = [ mp.Block(mp.Vector3(mp.inf, 1, mp.inf), center=mp.Vector3(), material=mp.Medium(epsilon=12)) ] sources = [ mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-7, 0)) ] pml_layers = [mp.PML(1.0)] resolution = 10 sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution)
def record_ex_ey(sim): record_Ex.append(sim.get_field_point(mp.Ex, mp.Vector3(0, 0, zout))) record_Ey.append(sim.get_field_point(mp.Ey, mp.Vector3(0, 0, zout))) record_t.append(sim.meep_time())
f1.write("\n\t" + case + "\n\n\n") f2.write(case + ", ") hu = min(hu, (H - h) / 2) hl = min(hl, (H - h) / 2) n_m = max(n_x, n_y, n_z) n_c = max(n_l, n_u) fcen = 1 / wavelength df = 0.05 default_material = mp.Medium(epsilon=1) upper_material = mp.Medium(epsilon=n_u**2) core_material = mp.Medium(epsilon_diag=mp.Vector3(n_x**2, n_y**2, n_z**2)) lower_material = mp.Medium(epsilon=n_l**2) geometry_lattice = mp.Lattice(size=mp.Vector3(0, monitorheight, 0)) # bandNum = 4 # geometry = [mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material), # mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material), # mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material), # mp.Block(mp.Vector3(mp.inf, h, mp.inf), center=mp.Vector3(0,0,0), material=core_material)] geometrympb = [ mp.Block(mp.Vector3(mp.inf, monitorheight, mp.inf), center=mp.Vector3(0, 0), material=default_material),
import meep as mp import numpy as np from numpy import linalg as LA import matplotlib.pyplot as plt n = 3.4 w = 1 r = 1 pad = 4 dpml = 2 sxy = 2 * (r + w + pad + dpml) vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy - 2 * dpml, sxy - 2 * dpml)) c1 = mp.Cylinder(radius=r + w, material=mp.Medium(index=n)) c2 = mp.Cylinder(radius=r) fcen = 0.118 df = 0.08 src = [ mp.Source(mp.ContinuousSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(r + 0.1)) ] sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy), geometry=[c1, c2], sources=[src], resolution=10, force_complex_fields=True, symmetries=[mp.Mirror(mp.Y)],
def notch(w): print("#----------------------------------------") print("NOTCH WIDTH: %s nanometers" % (w * 1000)) print("#----------------------------------------") # w is the width of the notch in the waveguide angrad = ang * pi / 180 bottomoffset = e * h / tan(angrad) vertices = [ mp.Vector3(w / 2 + bottomoffset, (.5 + e) * h), mp.Vector3(-w / 2 - bottomoffset, (.5 + e) * h), mp.Vector3(-w / 2 + bottomoffset, (.5 - e) * h), mp.Vector3(w / 2 - bottomoffset, (.5 - e) * h) ] if bottomoffset > w / 2: ratio = (w / 2) / bottomoffset vertices = [ mp.Vector3(w / 2, h / 2), mp.Vector3(-w / 2, h / 2), mp.Vector3(0, (.5 - e * ratio) * h) ] print(vertices) #Waveguide Geometry cell = mp.Vector3(a, H) geometry = [ mp.Block(cell, center=mp.Vector3(0, 0), material=default_material), mp.Block(mp.Vector3(a, hu + h / 2), center=mp.Vector3(0, (hu + h / 2) / 2), material=upper_material), mp.Block(mp.Vector3(a, hl + h / 2), center=mp.Vector3(0, -(hl + h / 2) / 2), material=lower_material), mp.Block(mp.Vector3(a, h), center=mp.Vector3(0, 0), material=core_material) ] if w > 0: geometry.append( mp.Prism(vertices, height=1, material=upper_material)) pml_layers = [mp.Absorber(thickness=dpml)] r00 = None r01 = None r10 = None r11 = None t00 = None t01 = None t10 = None t11 = None su0 = None sd0 = None su1 = None sd1 = None modes = [0, 1] if only_fund: modes = [0] # eig_parity_fund = mp.EVEN_Z+mp.EVEN_Y; # eig_parity_first = mp.EVEN_Z+mp.ODD_Y; eig_parity_fund = mp.EVEN_Y eig_parity_first = mp.ODD_Y # for mode in [0, 1]: for mode in modes: if mode == 0: eig_parity = eig_parity_fund # Fundamental print("-----------") print("MODE TYPE: FUNDAMENTAL") else: eig_parity = eig_parity_first # First Order print("-----------") print("MODE TYPE: FIRST ORDER") # sources = [ mp.EigenModeSource( # mp.GaussianSource( frequency = fcen, # fwidth = df), # size = mp.Vector3(0,H), # center = mp.Vector3(Ls, 0), # eig_parity = eig_parity) ] sources = [ mp.EigenModeSource(mp.ContinuousSource(frequency=fcen), size=mp.Vector3(0, monitorheight), center=mp.Vector3(Ls, 0), eig_parity=eig_parity) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution, force_complex_fields=True) ''' #-------------------------------------------------- #FOR DISPLAYING THE GEOMETRY sim.run(until = 200) eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric) plt.figure(dpi=100) plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') #plt.axis('off') plt.show() quit() #---------------------------------------------------- ''' ''' #------------------------------------------------------ #FOR GENERATING THE ELECTRIC FIELD GIF #Note: After running this program, write the following commands in Terminal: # $ source deactivate mp # $ cd notchtest-out/ # $ python ../NotchIP.py sim.use_output_directory() sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended("ez", mp.at_every(0.6, mp.output_efield_z)), until = 200) #sim.run(mp.at_every(0.6 , mp.output_png(mp.Ez, "-Zc dkbluered")), until=200) #--------------------------------------------------------- ''' #--------------------------------------------------------- # FOR GENERATING THE TRANSMITTANCE SPECTRUM # nfreq = 1 # number of frequencies at which to compute flux # # refl_fr1 = mp.FluxRegion(center=mp.Vector3(Lr1,0), size=mp.Vector3(0,monitorheight)) # Reflected flux 1 # refl_fr2 = mp.FluxRegion(center=mp.Vector3(Lr2,0), size=mp.Vector3(0,monitorheight)) # Reflected flux 2 # tran_fr = mp.FluxRegion(center=mp.Vector3(Lt,0), size=mp.Vector3(0,monitorheight)) # Transmitted flux # su_fr = mp.FluxRegion(center=mp.Vector3(0, monitorheight/2), size=mp.Vector3(a,0)) # Flux loss above the waveguide # sd_fr = mp.FluxRegion(center=mp.Vector3(0,-monitorheight/2), size=mp.Vector3(a,0)) # Flux loss below the waveguide # # refl1 = sim.add_flux(fcen, df, nfreq, refl_fr1) # refl2 = sim.add_flux(fcen, df, nfreq, refl_fr2) # tran = sim.add_flux(fcen, df, nfreq, tran_fr) # su = sim.add_flux(fcen, df, nfreq, su_fr) # sd = sim.add_flux(fcen, df, nfreq, sd_fr) # ------------------------ CODE FOR SEPARATING FUND AND FIRST ORDER MODE STARTS HERE ------------------------ refl_vals = [] tran_vals = [] def get_refl_slice(sim): # print(sim.get_array(center=mp.Vector3(Lr1,0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True)) # refl_val = sim.get_array(center=mp.Vector3(Lr1,0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True) refl_vals.append( sim.get_array(center=mp.Vector3(Lr1, 0), size=mp.Vector3( 0, monitorheight - 2 / resolution), component=mp.Ez, cmplx=True)) def get_tran_slice(sim): # print(sim.get_array(center=mp.Vector3(Lt, 0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True)) # tran_val = sim.get_array(center=mp.Vector3(Lt, 0), size=mp.Vector3(0,H), component=mp.Ez, cmplx=True) tran_vals.append( sim.get_array(center=mp.Vector3(Lt, 0), size=mp.Vector3( 0, monitorheight - 2 / resolution), component=mp.Ez, cmplx=True)) gif = True # T = 50*(a-4)/12; T = 60 if resolution == 50: epsform = "eps-000000.00" else: epsform = "eps-000000000" if gif: # and w == 0.1: sim.use_output_directory() sim.run(mp.at_beginning(mp.output_epsilon), mp.at_every( 1, mp.output_png( mp.Ez, "-RZc bluered -A notchtest-out/notchtest-" + epsform + ".h5 -a gray:.2")), mp.at_end(get_refl_slice), mp.at_end(get_tran_slice), until=T) os.system("convert notchtest-out/notchtest-ez-*.png " + casedash + "-" + str(int(w * 1000)) + "-" + str(mode) + "-full.gif") os.system("rm notchtest-out/notchtest-ez-*.png") nfreq = 1 # number of frequencies at which to compute flux refl_fr1 = mp.FluxRegion( center=mp.Vector3(Lr1, 0), size=mp.Vector3(0, monitorheight)) # Reflected flux 1 refl_fr2 = mp.FluxRegion( center=mp.Vector3(Lr2, 0), size=mp.Vector3(0, monitorheight)) # Reflected flux 2 tran_fr = mp.FluxRegion( center=mp.Vector3(Lt, 0), size=mp.Vector3(0, monitorheight)) # Transmitted flux su_fr = mp.FluxRegion( center=mp.Vector3(0, monitorheight / 2), size=mp.Vector3(a, 0)) # Flux loss above the waveguide sd_fr = mp.FluxRegion( center=mp.Vector3(0, -monitorheight / 2), size=mp.Vector3(a, 0)) # Flux loss below the waveguide refl1 = sim.add_flux(fcen, df, nfreq, refl_fr1) refl2 = sim.add_flux(fcen, df, nfreq, refl_fr2) tran = sim.add_flux(fcen, df, nfreq, tran_fr) su = sim.add_flux(fcen, df, nfreq, su_fr) sd = sim.add_flux(fcen, df, nfreq, sd_fr) # sim.run(mp.at_every(wavelength / 20, mp.output_efield_z), until=wavelength) # sim.run(mp.at_every(wavelength/20 , mp.output_png(mp.Ez, "-RZc bluered -A notchtest-out/notchtest-eps-000000000.h5 -a gray:.2")), until=19*wavelength/20) sim.run(mp.at_every( wavelength / 20, mp.output_png( mp.Ez, "-RZc bluered -A notchtest-out/notchtest-" + epsform + ".h5 -a gray:.2")), until=19 * wavelength / 20) sim.run(until=20) # sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5)) else: sim.run(mp.at_beginning(mp.output_epsilon), mp.at_time(T, get_refl_slice), mp.at_time(T, get_tran_slice)) #, # until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5)) os.system("h5topng notchtest-out/notchtest-" + epsform + ".h5; mv notchtest-out/notchtest-" + epsform + ".png " + casedash + "-" + str(int(w * 1000)) + "-" + str(mode) + "-eps.png") # os.system("cp notchtest-out/notchtest-ez-000100.00.png " + case + "-" + str(int(w*1000)) + "-" + str(mode) + ".png") os.system("convert notchtest-out/notchtest-ez-*.png " + casedash + "-" + str(int(w * 1000)) + "-" + str(mode) + ".gif") os.system("rm notchtest-out/notchtest-ez-*.png") # get_eigenmode(fcen, mp., refl_fr1, 1, kpoint) # v = mp.volume(mp.vec(Lr1, -monitorheight/2), mp.vec(Lr1, monitorheight/2)) # mode = get_eigenmode(fcen, mp.X, v, v, 1, mp.vec(0, 0, 0), True, 0, 0, 1e-7, True) # print(mode.amplitude) # coef_refl_fund = mp.get_eigenmode_coefficients_and_kpoints(refl_fr1, 1, eig_parity=eig_parity_fund, eig_resolution=resolution, eig_tolerance=1e-7) # coef_refl_first = mp.get_eigenmode_coefficients_and_kpoints(refl_fr1, 1, eig_parity=eig_parity_first, eig_resolution=resolution, eig_tolerance=1e-7) # # coef_tran_fund = mp.get_eigenmode_coefficients_and_kpoints(tran_fr, 1, eig_parity=eig_parity_fund, eig_resolution=resolution, eig_tolerance=1e-7) # coef_tran_first = mp.get_eigenmode_coefficients_and_kpoints(tran_fr, 1, eig_parity=eig_parity_first, eig_resolution=resolution, eig_tolerance=1e-7) ep = mp.ODD_Z coef_refl_fund, vgrp, kpoints_fund = sim.get_eigenmode_coefficients( refl1, [1], eig_parity=ep, eig_resolution=resolution, eig_tolerance=1e-7) coef_refl_first, vgrp, kpoints_first = sim.get_eigenmode_coefficients( refl1, [2], eig_parity=ep, eig_resolution=resolution, eig_tolerance=1e-7) coef_tran_fund, vgrp, kpoints_fund = sim.get_eigenmode_coefficients( tran, [1], eig_parity=ep, eig_resolution=resolution, eig_tolerance=1e-7) coef_tran_first, vgrp, kpoints_first = sim.get_eigenmode_coefficients( tran, [2], eig_parity=ep, eig_resolution=resolution, eig_tolerance=1e-7) # print(kpoints_fund) # print(kpoints_first) # print(kpoints_fund[0]) # print(type(kpoints_fund[0])) # print(dir(kpoints_fund[0])) n_eff_fund = wavelength * kpoints_fund[0].x n_eff_first = wavelength * kpoints_first[0].x print(n_eff_fund) print(n_eff_first) # print(coef_refl_fund) # print(type(coef_refl_fund)) # print(dir(coef_refl_fund)) # print(coef_refl_fund[0]) # print(coef_refl_fund[0][0,0,:]) # # fund_refl_amp = coef_refl_fund[0][0,0,1]; # first_order_refl_amp = coef_refl_first[0][0,0,1]; # fund_tran_amp = coef_tran_fund[0][0,0,0]; # first_order_tran_amp = coef_tran_first[0][0,0,0]; print("get_eigenmode_coefficients:\n") print(coef_refl_fund) print(coef_refl_first) print(coef_tran_fund) print(coef_tran_first) print("\n") # print(coef_refl_fund[0,0,:]) fund_refl_amp = coef_refl_fund[0, 0, 1] first_order_refl_amp = coef_refl_first[0, 0, 1] fund_tran_amp = coef_tran_fund[0, 0, 0] first_order_tran_amp = coef_tran_first[0, 0, 0] refl_val = refl_vals[0] tran_val = tran_vals[0] # n_eff must satisfy n_e <= n_eff <= n_c for the mode to be bound. def fund_func(n_eff): if n_eff >= n_c and n_eff <= n_e: return sqrt( n_eff**2 - n_c**2) - sqrt(n_e**2 - n_eff**2) * tan( pi * h / wavelength * sqrt(n_e**2 - n_eff**2)) def first_order_func(n_eff): if n_eff >= n_c and n_eff <= n_e: return sqrt(n_eff**2 - n_c**2) - sqrt(n_e**2 - n_eff**2) * tan( pi * h / wavelength * sqrt(n_e**2 - n_eff**2) - pi / 2) initial_guess = (n_c + n_e) / 2 # n_eff_fund = fsolve(fund_func, initial_guess) # n_eff_first = fsolve(first_order_func, n_c) print(n_eff_fund, n_eff_first) assert (n_eff_fund > n_eff_first) if len(n_eff_funds) == 0: n_eff_funds.append(n_eff_fund) if len(n_eff_firsts) == 0: n_eff_firsts.append(n_eff_first) ky0_fund = np.abs(2 * pi / wavelength * sqrt(n_e**2 - n_eff_fund**2)) ky0_first = np.abs(2 * pi / wavelength * sqrt(n_e**2 - n_eff_first**2)) ky1_fund = ky0_fund # np.abs(2 * pi / wavelength * sqrt(n_eff_fund **2 - n_c**2)) ky1_first = ky0_first # np.abs(2 * pi / wavelength * sqrt(n_eff_first**2 - n_c**2)) E_fund = lambda y: cos(ky0_fund * y) if np.abs(y) < h / 2 else cos( ky0_fund * h / 2) * np.exp(-ky1_fund * (np.abs(y) - h / 2)) E_first_order = lambda y: sin(ky0_first * y) if np.abs( y) < h / 2 else sin(ky0_first * h / 2) * np.exp(-ky1_first * ( np.abs(y) - h / 2)) * np.sign(y) # y_list = np.arange(-H/2+.5/resolution, H/2-.5/resolution, 1/resolution) #print("Y LIST: ", y_list) #print("SIZE OF Y LIST: ", y_list.size) E_fund_vec = np.zeros(y_list.size) E_first_order_vec = np.zeros(y_list.size) for index in range(y_list.size): y = y_list[index] E_fund_vec[index] = E_fund(y) E_first_order_vec[index] = E_first_order(y) # print(dir(sim)) # print(type(sim.get_eigenmode_coefficients)) # print(dir(sim.get_eigenmode_coefficients)) # print(type(sim.get_eigenmode)) # print(dir(sim.get_eigenmode)) # print(sim.get_eigenmode.__code__.co_varnames) # print(sim.get_eigenmode.__defaults__) # E1 = sim.get_eigenmode(fcen, mp.X, refl1.where, 1, None) # E2 = sim.get_eigenmode(fcen, mp.X, refl1.where, 2, None) # E3 = sim.get_eigenmode(fcen, mp.X, refl1.where, 3, None) # E4 = sim.get_eigenmode(fcen, mp.X, refl1.where, 4, None) # E1 = sim.get_eigenmode(fcen, mp.X, refl1.where, 1, mp.Vector3(0, 0, 0)) # E2 = sim.get_eigenmode(fcen, mp.X, refl1.where, 2, mp.Vector3(0, 0, 0)) # E3 = sim.get_eigenmode(fcen, mp.X, refl1.where, 3, mp.Vector3(0, 0, 0)) # E4 = sim.get_eigenmode(fcen, mp.X, refl1.where, 4, mp.Vector3(0, 0, 0)) # print(refl1.where) # numEA = 0 # E1 = sim.fields.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 1, mp.vec(0,0,0), True, 0, numEA, 1e-7, True) # print(type(E1)) # print(dir(E1)) # # print(refl1.where) # # print(E1, E2, E3, E4) # print(E1.amplitude, E1.band_num, E1.group_velocity, E1.k) # print(type(E1.amplitude)) # print(dir(E1.amplitude)) # print(doc(E1.amplitude)) # print(self(E1.amplitude)) # print(E1.amplitude(y_list)) # print(type(E1.amplitude(y_list))) # print(dir(E1.amplitude(y_list))) # print(E1.amplitude, E2.amplitude, E3.amplitude, E4.amplitude) # E1 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 1, mp.vec(0, 0, 0)) # E2 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 2, mp.vec(0, 0, 0)) # E3 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 3, mp.vec(0, 0, 0)) # E4 = sim.get_eigenmode(fcen, mp.X, refl1.where, refl1.where, 4, mp.vec(0, 0, 0)) # print(y_list) # # E1a = np.zeros(y_list.size, dtype='Complex128'); # E2a = np.zeros(y_list.size, dtype='Complex128'); # E3a = np.zeros(y_list.size, dtype='Complex128'); # E4a = np.zeros(y_list.size, dtype='Complex128'); # # # print(mp.eigenmode_amplitude.__code__.co_varnames) # # print(mp.eigenmode_amplitude.__defaults__) # # for i in range(y_list.size): # # print(E1) # # print(E1.swigobj) # # print(E1.amplitude) # # print(mp.vec(Lr1, y_list[i], 0)) # # print(mp.Vector3(Lr1, y_list[i], 0)) # # print(mp.Ez) # # E1a[i] = mp.eigenmode_amplitude(E1.swigobj, mp.vec(Lr1, y_list[i], 0), mp.Ez); # eval_point = mp.vec(Lr1, y_list[i], 0) # # print(eval_point) # E1a[i] = mp.eigenmode_amplitude(E1.swigobj, eval_point, mp.Ex) # E2a[i] = mp.eigenmode_amplitude(E2.swigobj, eval_point, mp.Ex) # E3a[i] = mp.eigenmode_amplitude(E3.swigobj, eval_point, mp.Ex) # E4a[i] = mp.eigenmode_amplitude(E4.swigobj, eval_point, mp.Ex) # # E1a[i] = mp.eigenmode_amplitude(E1.amplitude, mp.Vector3(Lr1, y_list[i], 0), mp.Ez); # # plt.plot(y_list, np.abs(E1a)**2, 'bo-', label='E1') # plt.plot(y_list, np.abs(E2a)**2, 'ro-', label='E2') # plt.plot(y_list, np.abs(E3a)**2, 'go-', label='E3') # plt.plot(y_list, np.abs(E4a)**2, 'co-', label='E4') # # plt.axis([40.0, 300.0, 0.0, 100.0]) # plt.xlabel("y (um)") # plt.ylabel("Field (a.u.)") # plt.legend(loc="center right") # plt.show() # print("r VECTOR: ", refl_val) # print("t VECTOR: ", tran_val) # print("E0 VECTOR: ", E_fund_vec) # print("E1 VECTOR: ", E_first_order_vec) # fund_refl_amp_2 = np.conj(np.dot(refl_val, E_fund_vec) / np.dot(E_fund_vec, E_fund_vec)) # Conjugate becasue MEEP uses physics exp(kz-wt) rather than engineering exp(wt-kz) # first_order_refl_amp_2 = np.conj(np.dot(refl_val, E_first_order_vec) / np.dot(E_first_order_vec, E_first_order_vec)) # fund_tran_amp_2 = np.conj(np.dot(tran_val, E_fund_vec) / np.dot(E_fund_vec, E_fund_vec)) # first_order_tran_amp_2 = np.conj(np.dot(tran_val, E_first_order_vec) / np.dot(E_first_order_vec, E_first_order_vec)) fund_refl_amp0 = fund_refl_amp fund_tran_amp0 = fund_tran_amp fund_refl_amp = np.conj( np.dot(refl_val, E0) / np.dot(E0, E0) ) # Conjugate becasue MEEP uses physics exp(kz-wt) rather than engineering exp(wt-kz) first_order_refl_amp = 0 # np.conj(np.dot(refl_val, E1[:,2]) / np.dot(E1[:,2], E1[:,2])) fund_tran_amp = np.conj(np.dot(tran_val, E0) / np.dot(E0, E0)) first_order_tran_amp = 0 # np.conj(np.dot(tran_val, E1[:,2]) / np.dot(E1[:,2], E1[:,2])) fund_refl = np.conj(fund_refl_amp) * E0 not_fund_refl = refl_val - fund_refl fund_tran = np.conj(fund_tran_amp) * E0 not_fund_tran = tran_val - fund_tran fund_refl_power = np.dot(np.conj(fund_refl), fund_refl) not_fund_refl_power = np.dot(np.conj(not_fund_refl), not_fund_refl) fund_tran_power = np.dot(np.conj(fund_tran), fund_tran) not_fund_tran_power = np.dot(np.conj(not_fund_tran), not_fund_tran) f2.write( "%s, " % [fund_refl_amp0, fund_tran_amp0, fund_refl_amp, fund_tran_amp]) # assert(fund_refl_power + not_fund_refl_power == 1) # assert(fund_tran_power + not_fund_tran_power == 1) # f2.write("\n"); fund_refl_ratio = np.abs(fund_refl_power / (fund_refl_power + not_fund_refl_power)) first_order_refl_ratio = 0 fund_tran_ratio = np.abs(fund_tran_power / (fund_tran_power + not_fund_tran_power)) first_order_tran_ratio = 0 f2.write("%s, " % [ fund_refl_ratio, fund_refl_power, not_fund_refl_power, fund_refl_power + not_fund_refl_power, fund_tran_ratio, fund_tran_power, not_fund_tran_power, fund_tran_power + not_fund_tran_power ]) plt.plot(y_list, np.abs(refl_val), 'bo-', label='reflectance') plt.plot(y_list, np.abs(tran_val), 'ro-', label='transmittance') plt.plot(y_list, E0, 'go-', label='E0') plt.plot(y_list, fund_refl, 'co-', label='over') plt.plot(y_list, not_fund_refl, 'ko-', label='over') # plt.axis([40.0, 300.0, 0.0, 100.0]) plt.xlabel("y (um)") plt.ylabel("Field") plt.legend(loc="center right") plt.savefig(case + "fields.png") plt.close() # # print("\n") # # print(tran_val.size, refl_val.size) # # print("\n") # # print(tran_val, refl_val, E0) # # print("\n") # # print(np.conj(tran_val), tran_val, E1[:,2]) # # # # print(np.conj(refl_val), refl_val, E1[:,2]) # # refl_tot_power = np.abs(np.dot(np.conj(refl_val), refl_val)) # tran_tot_power = np.abs(np.dot(np.conj(tran_val), tran_val)) # # print(fund_refl_amp, refl_tot_power, fund_tran_amp, tran_tot_power) # print(fund_refl_amp , fund_refl_amp_2 ) # print(first_order_refl_amp , first_order_refl_amp_2) # print(fund_tran_amp , fund_tran_amp_2 ) # print(first_order_tran_amp , first_order_tran_amp_2) # # print(np.angle(fund_refl_amp), np.angle(fund_refl_amp_2)) # print(np.angle(first_order_refl_amp), np.angle(first_order_refl_amp_2)) # print(np.angle(fund_tran_amp), np.angle(fund_tran_amp_2)) # print(np.angle(first_order_tran_amp), np.angle(first_order_tran_amp_2)) # fund_refl_power = np.abs(fund_tran_amp) ** 2 # fund_refl_power = np.abs(fund_refl_amp) ** 2 # first_order_refl_power = np.abs(first_order_refl_amp) ** 2 # fund_tran_power = np.abs(fund_tran_amp) ** 2 # first_order_tran_power = np.abs(first_order_tran_amp) ** 2 # print(fund_refl_power, first_order_refl_power, fund_tran_power, first_order_tran_power) # fund_refl_ratio = fund_refl_power / (fund_refl_power + first_order_refl_power) # first_order_refl_ratio = first_order_refl_power / (fund_refl_power + first_order_refl_power) # fund_tran_ratio = fund_tran_power / (fund_tran_power + first_order_tran_power) # first_order_tran_ratio = first_order_tran_power / (fund_tran_power + first_order_tran_power) # fund_refl_power = np.abs(fund_refl_amp) ** 2 # first_order_refl_power = np.abs(first_order_refl_amp) ** 2 # fund_tran_power = np.abs(fund_tran_amp) ** 2 # first_order_tran_power = np.abs(first_order_tran_amp) ** 2 # # fund_refl_ratio = fund_refl_power / refl_tot_power # first_order_refl_ratio = first_order_refl_power / refl_tot_power # fund_tran_ratio = fund_tran_power / tran_tot_power # first_order_tran_ratio = first_order_tran_power / tran_tot_power # # fund_refl_ratio = 1 # first_order_refl_ratio = 0 # fund_tran_ratio = 1 # first_order_tran_ratio = 0 print("Percentage of reflected light in fundamental mode: ", fund_refl_ratio * 100) print("Percentage of reflected light in first order mode: ", first_order_refl_ratio * 100) print("Percentage of transmitted light in fundamental mode: ", fund_tran_ratio * 100) print("Percentage of transmitted light in first order mode: ", first_order_tran_ratio * 100) # ------------------------ CODE FOR SEPARATING FUND AND FIRST ORDER MODE ENDS HERE ------------------------ wl = [] #list of wavelengths refl1_flux = mp.get_fluxes(refl1) refl2_flux = mp.get_fluxes(refl2) tran_flux = mp.get_fluxes(tran) su_flux = mp.get_fluxes(su) sd_flux = mp.get_fluxes(sd) flux_freqs = mp.get_flux_freqs(refl1) for i in range(nfreq): wl = np.append(wl, 1 / flux_freqs[i]) print(1 / flux_freqs[i]) # for ind, elt in enumerate(wl): # #print(round(elt, 4)) # if round(elt, 3) == 0.637: # #print("ALERT: MATCH FOUND") # index = ind index = 0 rp = refl1_flux[index] tp = tran_flux[index] # print("rp/tp:\n") # print(rp) # print(tp) # print("\n") R = -refl1_flux[index] / (refl2_flux[index] - refl1_flux[index]) T = tran_flux[index] / (refl2_flux[index] - refl1_flux[index]) S = (refl2_flux[index] - tran_flux[index]) / (refl2_flux[index] - refl1_flux[index]) Su = su_flux[index] / (refl2_flux[index] - refl1_flux[index]) Sd = -sd_flux[index] / (refl2_flux[index] - refl1_flux[index]) S_correction = (1 - R - T) / (Su + Sd) # print(R, T, S, Su, Sd) r = sqrt(R) t = sqrt(T) r_fund = (r * fund_refl_ratio) * np.exp( 1j * np.angle(fund_refl_amp) + 2j * pi * (-Lr1 - w / 2) * n_eff_fund / wavelength ) # Lr1 is negative because it is the (negative) position of the monitor, not the distace from the monitor to the center. r_first = (r * first_order_refl_ratio) * np.exp( 1j * np.angle(first_order_refl_amp) + 2j * pi * (-Lr1 - w / 2) * n_eff_first / wavelength) t_fund = (t * fund_tran_ratio ) * np.exp(1j * np.angle(fund_tran_amp) + 2j * pi * (Lt - w / 2) * n_eff_fund / wavelength) t_first = (t * first_order_tran_ratio) * np.exp( 1j * np.angle(first_order_tran_amp) + 2j * pi * (Lt - w / 2) * n_eff_first / wavelength) if mode == 0: r00 = r_fund r01 = r_first t00 = t_fund t01 = t_first su0 = sqrt(np.abs(Su * S_correction)) sd0 = sqrt(np.abs(Sd * S_correction)) # su0 = sqrt(Su) # sd0 = sqrt(Sd) r00s.append(r00) r01s.append(r01) t00s.append(t00) t01s.append(t01) su0s.append(su0) sd0s.append(sd0) if only_fund: r10s.append(0) r11s.append(0) t10s.append(0) t11s.append(1) su1s.append(0) sd1s.append(0) else: r10 = r_fund r11 = r_first t10 = t_fund t11 = t_first su1 = sqrt(np.abs(Su * S_correction)) sd1 = sqrt(np.abs(Sd * S_correction)) # su1 = sqrt(Su) # sd1 = sqrt(Sd) r10s.append(r10) r11s.append(r11) t10s.append(t10) t11s.append(t11) su1s.append(su1) sd1s.append(sd1) norm_Su = S * Su / (Su + Sd) NET = round((R + T + S) * 100, 0) if NET > 100.0: NET = 100.0 NET_LOSS = round((Su + Sd) / S * 100, 0) if NET_LOSS > 100.0: NET_LOSS = 100.0 ''' np.append(ws, [w * 1000]) np.append(Rs, [R * 100]) np.append(Ts, [T * 100]) np.append(Ss, [S * 100]) np.append(NET_LIST, [NET]) np.append(Sus, [Su * 100]) np.append(Sds, [Sd * 100]) np.append(NET_LOSS_LIST, [NET_LOSS]) np.append(norm_Sus, [norm_Su * 100]) ''' if mode == 0: ws.append(w * 1000) Rs.append(R * 100) Ts.append(T * 100) Ss.append(S * 100) NET_LIST.append(NET) Sus.append(Su * 100) Sds.append(Sd * 100) NET_LOSS_LIST.append(NET_LOSS) norm_Sus.append(norm_Su * 100) if mode == 0: f1.write( "--------------------------------------------------- \n") f1.write("Notch Width: %s nanometers \n" % (w * 1000)) f1.write("Reflection Percentage: %s\n" % (R * 100)) f1.write("Transmission Percentage: %s\n" % (T * 100)) f1.write("Total Loss Percentage: %s\n" % (S * 100)) f1.write("Percentage of Light Accounted For: %s\n" % (NET)) f1.write("Upper Loss Percentage: %s\n" % (Su * 100)) f1.write("Lower Loss Percentage: %s\n" % (Sd * 100)) f1.write("Percentage of Total Loss Accounted For: %s\n" % (NET_LOSS)) f1.write("Normalized Upper Loss Percentage: %s\n" % (norm_Su * 100)) f1.write("\n \n") f1.write("FUNDAMENTAL MODE \n") f1.write("n_eff: %s\n" % (n_eff_fund)) f1.write("Re(r00): %s\n" % (np.real(r00))) f1.write("Im(r00): %s\n" % (np.imag(r00))) f1.write("Re(r01): %s\n" % (np.real(r01))) f1.write("Im(r01): %s\n" % (np.imag(r01))) f1.write("Re(t00): %s\n" % (np.real(t00))) f1.write("Im(t00): %s\n" % (np.imag(t00))) f1.write("Re(t01): %s\n" % (np.real(t01))) f1.write("Im(t01): %s\n" % (np.imag(t01))) f1.write("Re(su0): %s\n" % (np.real(su0))) f1.write("Im(su0): %s\n" % (np.imag(su0))) f1.write("Re(sd0): %s\n" % (np.real(sd0))) f1.write("Im(sd0): %s\n" % (np.imag(sd0))) f1.write("\n") else: f1.write("FIRST ORDER MODE \n") f1.write("n_eff: %s\n" % (n_eff_first)) f1.write("Re(r10): %s\n" % (np.real(r10))) f1.write("Im(r10): %s\n" % (np.imag(r10))) f1.write("Re(r11): %s\n" % (np.real(r11))) f1.write("Im(r11): %s\n" % (np.imag(r11))) f1.write("Re(t10): %s\n" % (np.real(t10))) f1.write("Im(t10): %s\n" % (np.imag(t10))) f1.write("Re(t11): %s\n" % (np.real(t11))) f1.write("Im(t11): %s\n" % (np.imag(t11))) f1.write("Re(su1): %s\n" % (np.real(su1))) f1.write("Im(su1): %s\n" % (np.imag(su1))) f1.write("Re(sd1): %s\n" % (np.real(sd1))) f1.write("Im(sd1): %s\n" % (np.imag(sd1))) f1.write( "--------------------------------------------------- \n") sim.reset_meep()
sigma_dr = (a / c) * (1 / 100) / (eps_r * eps_0) #normalization wavelength = c / fIn f = a / wavelength nPointsPerWavelength = resolution / a * wavelength df = fWidth * a / c tScale = 2 * resolution #initialize the computational cell cellX = bwidth + 2 * buffer cellY = bheight + 2 * buffer cellZ = 0 #bthick + 2; cell = mp.Vector3(cellX, cellY, cellZ) maxPathLength = 2 t = maxPathLength / c tau = t * c / a nTimeSteps = tScale * tau #output normalized values print("Wavelength: ", wavelength) print("Normalized Frequency: ", f) print("Normalized Frequency Width: ", df) print("Number of Points Per Wavelength: ", nPointsPerWavelength) print("Stop Time (seconds): ", t) print("Number of Time Steps: ", nTimeSteps) print("Normalized Stop Time: ", tau)
def _try(k, v): return try_plus(try_plus(k, v), mp.Vector3() - v)