def main(args): n = 3.4 # index of waveguide w = 1 # width of waveguide r = 1 # inner radius of ring pad = 4 # padding between waveguide and edge of PML dpml = 32 # thickness of PML sr = r + w + pad + dpml # radial size (cell is from 0 to sr) dimensions = mp.CYLINDRICAL cell = mp.Vector3(sr, 0, 0) # in cylindrical coordinates, the phi (angular) dependence of the fields # is given by exp(i m phi), where m is given by: m = args.m geometry = [ mp.Block(center=mp.Vector3(r + (w / 2)), size=mp.Vector3(w, 1e20, 1e20), material=mp.Medium(index=n)) ] pml_layers = [mp.PML(dpml)] resolution = 20 # If we don't want to excite a specific mode symmetry, we can just # put a single point source at some arbitrary place, pointing in some # arbitrary direction. We will only look for TM modes (E out of the plane). fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width sources = [ mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(r + 0.1)) ] # note that the r -> -r mirror symmetry is exploited automatically sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) sim.run(mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)), until_after_sources=200) # Output fields for one period at the end. (If we output # at a single time, we might accidentally catch the Ez field when it is # almost zero and get a distorted view.) We'll append the fields # to a file to get an r-by-t picture. We'll also output from -sr to -sr # instead of from 0 to sr. sim.run(mp.in_volume( mp.Volume(center=mp.Vector3(), size=mp.Vector3(2 * sr)), mp.at_beginning(mp.output_epsilon), mp.to_appended("ez", mp.at_every(1 / fcen / 20, mp.output_efield_z))), until=1 / fcen)
def get_step_funcs(self): sf = {self._get_meep_output_comp(f) for f in self.static_fields} sf = (mp.at_beginning(f) for f in sf) df = {self._get_meep_output_comp(f) for f in self.dynamic_fields} df = (mp.at_every(self.dt, f) for f in df) volume = mp.in_volume(mp.Volume(center=self.size / 2, size=self.size)) fields = mp.with_prefix(f'{results_dir}/', *sf, *df) return volume, fields
def test_in_volume(self): sim = self.init_simple_simulation() sim.use_output_directory(self.temp_dir) 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) fn = os.path.join(self.temp_dir, 'test_in_volume-ez-000200.00.h5') self.assertTrue(os.path.exists(fn))
def test_animation_output(self): # ------------------------- # # Check over 2D domain # ------------------------- # sim = setup_sim() # generate 2D simulation Animate = mp.Animate2D(sim,fields=mp.Ez, realtime=False, normalize=False) # Check without normalization Animate_norm = mp.Animate2D(sim,mp.Ez,realtime=False,normalize=True) # Check with normalization # test both animation objects during same run sim.run( mp.at_every(1,Animate), mp.at_every(1,Animate_norm), until=5) # Test outputs Animate.to_mp4(5,'test_2D.mp4') # Check mp4 output Animate.to_gif(150,'test_2D.gif') # Check gif output Animate.to_jshtml(10) # Check jshtml output Animate_norm.to_mp4(5,'test_2D_norm.mp4') # Check mp4 output Animate_norm.to_gif(150,'test_2D_norm.gif') # Check gif output Animate_norm.to_jshtml(10) # Check jshtml output # ------------------------- # # Check over 3D domain # ------------------------- # sim = setup_sim(5) # generate 2D simulation Animate_xy = mp.Animate2D(sim,fields=mp.Ey, realtime=False, normalize=True) # Check without normalization Animate_xz = mp.Animate2D(sim,mp.Ey,realtime=False,normalize=True) # Check with normalization # test both animation objects during same run sim.run( mp.at_every(1,mp.in_volume(mp.Volume(center=mp.Vector3(),size=mp.Vector3(sim.cell_size.x,sim.cell_size.y)),Animate_xy)), mp.at_every(1,mp.in_volume(mp.Volume(center=mp.Vector3(),size=mp.Vector3(sim.cell_size.x,0,sim.cell_size.z)),Animate_xz)), until=5) # Test outputs Animate_xy.to_mp4(5,'test_3D_xy.mp4') # Check mp4 output Animate_xy.to_gif(150,'test_3D_xy.gif') # Check gif output Animate_xy.to_jshtml(10) # Check jshtml output Animate_xz.to_mp4(5,'test_3D_xz.mp4') # Check mp4 output Animate_xz.to_gif(150,'test_3D_xz.gif') # Check gif output Animate_xz.to_jshtml(10) # Check jshtml output
def main(args): n = 3.4 # index of waveguide w = 1 # width of waveguide r = 1 # inner radius of ring pad = 4 # padding between waveguide and edge of PML dpml = 32 # thickness of PML sr = r + w + pad + dpml # radial size (cell is from 0 to sr) dimensions = mp.CYLINDRICAL cell = mp.Vector3(sr, 0, 0) # in cylindrical coordinates, the phi (angular) dependence of the fields # is given by exp(i m phi), where m is given by: m = args.m geometry = [mp.Block(center=mp.Vector3(r + (w / 2)), size=mp.Vector3(w, mp.inf, mp.inf), material=mp.Medium(index=n))] pml_layers = [mp.PML(dpml)] resolution = 20 # If we don't want to excite a specific mode symmetry, we can just # put a single point source at some arbitrary place, pointing in some # arbitrary direction. We will only look for Ez-polarized modes. fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(r + 0.1))] # note that the r -> -r mirror symmetry is exploited automatically sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) sim.run(mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)), until_after_sources=200) # Output fields for one period at the end. (If we output # at a single time, we might accidentally catch the Ez field when it is # almost zero and get a distorted view.) We'll append the fields # to a file to get an r-by-t picture. We'll also output from -sr to -sr # instead of from 0 to sr. sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(2 * sr)), mp.at_beginning(mp.output_epsilon), mp.to_appended("ez", mp.at_every(1 / fcen / 20, mp.output_efield_z))), until=1 / fcen)
def run(self, duration): boundary_layers = self._create_boundary_layers() self.sim = mp.Simulation(cell_size=self.cell_size, geometry_center=self.center, default_material=self.dev.default_material, geometry=self.dev.geometry, resolution=self.resolution, sources=self.sources, boundary_layers=boundary_layers, force_complex_fields=True) # adding flux regions for k, v in self.profilers.items(): v.flux = self.sim.add_flux(1 / 1.55, 1, 256, v.get_flux_region()) self.sim.run(mp.in_volume(self.dev.volume), until=duration) mp.all_wait()
def main(args): resolution = 20 # 20 pixels per unit 1 um eps = 80 # epsilon of cylinder medium Mat1 = mp.Medium(epsilon=eps) # definition of the material dimensions = mp.CYLINDRICAL r = args.r # the value of cylinder radius rl = args.rl # the r/l ration is given, to obtain the l value l=r/rl x = args.x dpml = args.dpml dair = args.dair m=args.m w=1*x h = r/rl # the height of the cylinder sr = r + dair + dpml sz = h + 2*dair + 2*dpml w_max=1.8 w_min=0.2 dw=w_max-w_min boundary_layers = [mp.PML(dpml)] Cyl = mp.Cylinder(material=Mat1, radius=r, height=h, center=mp.Vector3(0,0,0)) # make a cylinder with given parameters geometry = [Cyl] cell_size = mp.Vector3(sr,0,sz) #sources = [ mp.Source(mp.ContinuousSource(frequency = w), component=mp.Hz, center=mp.Vector3(r+dair,0,0)) ] sources = [mp.Source(mp.GaussianSource(w, fwidth=dw), component=mp.Hz, center=mp.Vector3(r+dair,0,0))] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=geometry, sources=sources, dimensions=dimensions, m=m) sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(sr,0,sz)), mp.at_end(mp.output_epsilon, mp.output_efield_z)), mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), w, dw)), until_after_sources=100)
def main(): # Prefix all output files with the command line argument file_prefix = sys.argv[1] # Number of pixels per micron resolution = 150 # Simulation volume (um) cell_x = 2 cell_y = 2 cell_z = 2.5 # Refractive indicies index_si = 3.6 # previously 3.4467 index_sio2 = 1.444 # Durations in units of micron/c duration = round(1.5 * cell_x + 2) num_timesteps = duration * resolution # Absorbing layer on boundary pml = 0.5 # Geometry src_buffer = pml / 16 nbn_buffer = src_buffer nbn_length = cell_x - 2 * pml - src_buffer - nbn_buffer nbn_center_x = (src_buffer + nbn_buffer) / 2 wavelength = 1.55 waveguide_width = 0.750 # 750 nm waveguide_height = 0.110 # 110 nm plane_shift_y = 0 # nbn is 10/8 times thicker than in reality to have enough simulation pixels # so we reduce its absorption by a factor of 5/4 to compensate nbn_thickness_comp = 250 / resolution nbn_thickness = 0.008 * nbn_thickness_comp # Actually 8 nm, but simulating this for 2 grid points nbn_width = 0.100 # 100 nm nbn_spacing = 0.120 # 120 nm # Also compensate the difference in index by the same amount nbn_base_index = 5.23 # Taken from Hu thesis p86 nbn_index = (5.23 - index_si) / nbn_thickness_comp + index_si nbn_base_k = 5.82 # Taken from Hu thesis p86 nbn_k = nbn_base_k / nbn_thickness_comp conductivity = 2 * math.pi * wavelength * nbn_k / nbn_index flux_length = cell_x - 2 * pml - 4 * src_buffer # Generate simulation obejcts cell = mp.Vector3(cell_x, cell_y, cell_z) freq = 1 / wavelength src_pt = mp.Vector3(-cell_x / 2 + pml + src_buffer, 0, 0) output_slice = mp.Volume(center=mp.Vector3(y=(3 * waveguide_height / 4) + plane_shift_y), size=(cell_x, 0, cell_z)) # Log important quantities print('ABSORBING RUN') print('File prefix: {}'.format(file_prefix)) print('Duration: {}'.format(duration)) print('Resolution: {}'.format(resolution)) print('Dimensions: {} um, {} um, {} um'.format(cell_x, cell_y, cell_z)) print('Wavelength: {} um'.format(wavelength)) print('Si thickness: {} um'.format(waveguide_height)) print('NbN thickness: {} um'.format(nbn_thickness)) print('Si index: {}; SiO2 index: {}'.format(index_si, index_sio2)) print('Absorber dimensions: {} um, {} um, {} um'.format( nbn_length, nbn_thickness, nbn_width)) print('Absorber n (base value): {} ({}), k: {} ({})'.format( nbn_index, nbn_base_index, nbn_k, nbn_base_k)) print('Absorber compensation for thickness: {}'.format(nbn_thickness_comp)) print('Flux length: {} um'.format(flux_length)) print('\n\n**********\n\n') default_material = mp.Medium(epsilon=1) # Physical geometry of the simulation geometry = [ mp.Block(mp.Vector3(mp.inf, cell_y, mp.inf), center=mp.Vector3(0, -cell_y / 2 + plane_shift_y, 0), material=mp.Medium(epsilon=index_sio2)), mp.Block(mp.Vector3(mp.inf, waveguide_height, waveguide_width), center=mp.Vector3(0, waveguide_height / 2 + plane_shift_y, 0), material=mp.Medium(epsilon=index_si)) ] # Absorber will only be appended to geometry for the second simulation absorber = [ mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width), center=mp.Vector3( nbn_center_x, waveguide_height + nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y, nbn_spacing / 2), material=mp.Medium(epsilon=nbn_index, D_conductivity=conductivity)), mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width), center=mp.Vector3( nbn_center_x, waveguide_height + nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y, -nbn_spacing / 2), material=mp.Medium(epsilon=nbn_index, D_conductivity=conductivity)), ] # geometry += absorber # Calculate eigenmode source src_max_y = cell_y - 2 * pml src_max_z = cell_z - 2 * pml src_y = src_max_y src_z = src_max_z # min(3 * waveguide_width, src_max_z) src_center_y = 0 # plane_shift_y sources = [ mp.EigenModeSource(src=mp.ContinuousSource(frequency=freq), center=mp.Vector3(-cell_x / 2 + pml + src_buffer, src_center_y, 0), size=mp.Vector3(0, src_y, src_z), eig_match_freq=True, eig_parity=mp.ODD_Z, eig_band=1) ] pml_layers = [mp.PML(pml)] # Pass all simulation parameters to meep sim = mp.Simulation( cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution, # eps_averaging=False, default_material=default_material, symmetries=[mp.Mirror(mp.Z, phase=-1)]) # Create flux monitors to calculate transmission and absorption fr_y = cell_y - 2 * pml fr_z = cell_z - 2 * pml # Reflected flux refl_fr = mp.FluxRegion(center=mp.Vector3( -0.5 * cell_x + pml + 2 * src_buffer, 0, 0), size=mp.Vector3(0, fr_y, fr_z)) refl = sim.add_flux(freq, 0, 1, refl_fr) # Transmitted flux tran_fr = mp.FluxRegion(center=mp.Vector3( 0.5 * cell_x - pml - 2 * src_buffer, 0, 0), size=mp.Vector3(0, fr_y, fr_z)) tran = sim.add_flux(freq, 0, 1, tran_fr) # Run simulation, outputting the epsilon distribution and the fields in the # x-y plane every 0.25 microns/c sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended( "ez_z0", mp.in_volume(output_slice, mp.at_every(2 / resolution, mp.output_efield_z))), until=duration) print('\n\n**********\n\n') sim.fields.synchronize_magnetic_fields() # For normalization run, save flux fields data for reflection plane no_absorber_refl_data = sim.get_flux_data(refl) # Save incident power for transmission plane no_absorber_tran_flux = mp.get_fluxes(tran) print("Flux: {}".format(no_absorber_tran_flux[0])) eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) / 2), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Dielectric) eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x / 4), size=mp.Vector3(0, cell_y, cell_z), component=mp.Dielectric) max_field = 1.5 # Plot epsilon distribution if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.axis('off') plt.savefig(file_prefix + '_Eps_A.png', dpi=300) print('Saved ' + file_prefix + '_Eps_A.png') # Plot field on x-y plane ez_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Ez) if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Ez_A.png', dpi=300) print('Saved ' + file_prefix + '_Ez_A.png') energy_side_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.EnergyDensity) if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(energy_side_data.transpose(), interpolation='spline36', cmap='hot', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Pwr0_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr0_A.png') # Plot energy density on y-z plane energy_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity) if mp.am_master(): plt.figure() plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary') plt.imshow(energy_data, interpolation='spline36', cmap='hot', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Pwr1_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr1_A.png') energy_data = sim.get_array(center=mp.Vector3(x=cell_x / 4), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity) if mp.am_master(): plt.figure() plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary') plt.imshow(energy_data, interpolation='spline36', cmap='hot', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Pwr2_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr2_A.png') # Plot cross-sectional fields at several locations to ensure seeing nonzero fields num_x = 4 num_y = 3 fig, ax = plt.subplots(num_x, num_y) fig.suptitle('Cross Sectional Ez Fields') for i in range(num_x * num_y): monitor_x = i * (cell_x / 4) / (num_x * num_y) ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez) ax_num = i // num_y, i % num_y if mp.am_master(): ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary') ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field))) ax[ax_num].axis('off') ax[ax_num].set_title('x = {}'.format( round(cell_x / 4 + i / resolution, 3))) if mp.am_master(): plt.savefig(file_prefix + '_Ez_CS_A.png', dpi=300) print('Saved ' + file_prefix + '_Ez_CS_A.png') fig_e, ax_e = plt.subplots(num_x, num_y) fig_e.suptitle('Cross Sectional Energy Density') for i in range(num_x * num_y): monitor_x = i * (cell_x / 4) / (num_x * num_y) energy_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity) ax_num = i // num_y, i % num_y if mp.am_master(): ax_e[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary') ax_e[ax_num].imshow(energy_cross_data, interpolation='spline36', cmap='hot', alpha=0.9) ax_e[ax_num].axis('off') ax_e[ax_num].set_title('x = {}'.format( round(cell_x / 4 + i / resolution, 3))) if mp.am_master(): plt.savefig(file_prefix + '_Pwr_CS_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr_CS_A.png') print('\n\n**********\n\n') # Reset simulation for absorption run """ sim.reset_meep() geometry += absorber sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution, eps_averaging=False, default_material=default_material, symmetries=[mp.Mirror(mp.Z, phase=-1)]) refl = sim.add_flux(freq, 0, 1, refl_fr) tran = sim.add_flux(freq, 0, 1, tran_fr) sim.load_minus_flux_data(refl, no_absorber_refl_data) # Run simulation with absorber sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended("ez_z0", mp.in_volume(output_slice, mp.at_every(0.25, mp.output_efield_z))), until=duration) print('\n\n**********\n\n') # Calculate transmission and absorption absorber_refl_flux = mp.get_fluxes(refl) absorber_tran_flux = mp.get_fluxes(tran) transmittance = absorber_tran_flux[0] / no_absorber_tran_flux[0] reflectance = absorber_refl_flux[0] / no_absorber_tran_flux[0] absorption = 1 - transmittance penetration_depth = - nbn_length / math.log(transmittance) print('Flux: {}'.format(absorber_tran_flux[0])) print("Transmittance: %f" % transmittance) print("Reflectance: %f" % reflectance) print("Absorption: {} over {} um".format(absorption, nbn_length)) print("lambda = {} mm".format(penetration_depth / 1000)) eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) / 2), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Dielectric) max_field = 1 # Plot epsilon distribution with absorber if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.axis('off') plt.savefig(file_prefix + '_Eps_B.png', dpi=300) print('Saved ' + file_prefix + '_Eps_B.png') # Plot fields in x-y plane with absorber ez_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Ez) if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Ez_B.png', dpi=300) print('Saved ' + file_prefix + '_Ez_B.png') # Plot field cross sections with absorber eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x/4), size=mp.Vector3(0, cell_y, cell_z), component=mp.Dielectric) num_x = 4 num_y = 3 fig, ax = plt.subplots(num_x, num_y) fig.suptitle('Cross Sectional Ez Fields') for i in range(num_x * num_y): monitor_x = cell_x/4 + i / resolution ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez) ax_num = i // num_y, i % num_y if mp.am_master(): ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary') ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field))) ax[ax_num].axis('off') ax[ax_num].set_title('x = {}'.format(round(cell_x/4 + i / resolution, 3))) if mp.am_master(): plt.savefig(file_prefix + '_Ez_CS_B.png', dpi=300) print('Saved ' + file_prefix + '_Ez_CS_B.png') print('\n\n**********\n\n') """ print('Program finished.')
def simulation(plotMe, plotDir='simulationData/', jobSpecifier='direct-', mat=None): if os.getenv("X_USE_MPI") != "1": jobName = jobSpecifier + randomString() else: jobName = jobSpecifier start = time.time() if str(plotMe) == '1': os.makedirs(plotDir) import matplotlib #matplotlib.use('Agg') from matplotlib import pyplot as plt print('will plot') else: mp.quiet(True) __author__ = 'Marco Butz' pixelSize = mat['pixelSize'] spectralWidth = 300 / mat['wavelength'] modeFrequencyResolution = 1 normOffset = pixelSize / 1000 * 10 if mat['dims'][2] == 1: cell = mp.Vector3(mat['dims'][0]*pixelSize/1000, \ mat['dims'][1]*pixelSize/1000, 0) else: cell = mp.Vector3(mat['dims'][0]*pixelSize/1000, \ mat['dims'][1]*pixelSize/1000, mat['dims'][2]*pixelSize/1000) #generate hdf5 epsilon file if mp.am_master(): h5f = h5py.File(jobName + '_eps.h5', 'a') h5f.create_dataset('epsilon', data=mat['epsilon']) h5f.close() sourceCenter = [ (mat['modeSourcePos'][0][0] + mat['modeSourcePos'][1][0]) / 2, (mat['modeSourcePos'][0][1] + mat['modeSourcePos'][1][1]) / 2, (mat['modeSourcePos'][0][2] + mat['modeSourcePos'][1][2]) / 2 ] sourceSize = [(mat['modeSourcePos'][1][0] - mat['modeSourcePos'][0][0]), (mat['modeSourcePos'][1][1] - mat['modeSourcePos'][0][1]), (mat['modeSourcePos'][1][2] - mat['modeSourcePos'][0][2])] modeNumModesToMeasure = [] posModesToMeasure = [] if not isinstance(mat['modeNumModesToMeasure'], Iterable): #this wraps stuff into an array if it has been squeezed before posModesToMeasure = [mat['posModesToMeasure']] modeNumModesToMeasure = [mat['modeNumModesToMeasure']] print('transformed') else: posModesToMeasure = mat['posModesToMeasure'] modeNumModesToMeasure = mat['modeNumModesToMeasure'] outputsModeNum = [] outputsCenter = [] outputsSize = [] for i in range(0, mat['numModesToMeasure']): outputsCenter.append([ (posModesToMeasure[i][0][0] + posModesToMeasure[i][1][0]) / 2, (posModesToMeasure[i][0][1] + posModesToMeasure[i][1][1]) / 2, (posModesToMeasure[i][0][2] + posModesToMeasure[i][1][2]) / 2 ]) outputsSize.append([ (posModesToMeasure[i][1][0] - posModesToMeasure[i][0][0]), (posModesToMeasure[i][1][1] - posModesToMeasure[i][0][1]), (posModesToMeasure[i][1][2] - posModesToMeasure[i][0][2]) ]) outputsModeNum.append(modeNumModesToMeasure[i]) for i in range(0, len(sourceCenter)): sourceCenter[i] = sourceCenter[i] * pixelSize / 1000 - cell[i] / 2 sourceSize[i] = sourceSize[i] * pixelSize / 1000 for i in range(0, len(outputsCenter)): for j in range(0, len(outputsCenter[i])): outputsCenter[i][ j] = outputsCenter[i][j] * pixelSize / 1000 - cell[j] / 2 outputsSize[i][j] = outputsSize[i][j] * pixelSize / 1000 sources = [ mp.EigenModeSource( src=mp.GaussianSource(wavelength=mat['wavelength'] / 1000, fwidth=spectralWidth), eig_band=mat['modeSourceNum'] + 1, center=mp.Vector3(sourceCenter[0], sourceCenter[1], sourceCenter[2]), size=mp.Vector3(sourceSize[0], sourceSize[1], sourceSize[2])) ] """ sources = [mp.EigenModeSource(src=mp.ContinuousSource(wavelength=mat['wavelength']/1000), eig_band=mat['modeSourceNum']+1, center=mp.Vector3(sourceCenter[0],sourceCenter[1],sourceCenter[2]), size=mp.Vector3(sourceSize[0],sourceSize[1],sourceSize[2]))] """ resolution = 1000 / pixelSize #pixels per micrometer pmlLayers = [mp.PML(pixelSize * 10 / 1000)] sim = mp.Simulation(cell_size=cell, boundary_layers=pmlLayers, geometry=[], epsilon_input_file=jobName + '_eps.h5', sources=sources, resolution=resolution) #force_complex_fields=True) #needed for fdfd solver transmissionFluxes = [] transmissionModes = [] normFluxRegion = mp.FluxRegion( center=mp.Vector3(sourceCenter[0] + normOffset, sourceCenter[1], sourceCenter[2]), size=mp.Vector3(sourceSize[0], sourceSize[1], sourceSize[2]), direction=mp.X) normMode = sim.add_mode_monitor(1000 / mat['wavelength'], spectralWidth, modeFrequencyResolution, normFluxRegion) normFlux = sim.add_flux(1000 / mat['wavelength'], spectralWidth, modeFrequencyResolution, normFluxRegion) for i in range(0, len(outputsCenter)): transmissionFluxRegion = mp.FluxRegion( center=mp.Vector3(outputsCenter[i][0], outputsCenter[i][1], outputsCenter[i][2]), size=mp.Vector3(outputsSize[i][0], outputsSize[i][1], outputsSize[i][2]), direction=mp.X) transmissionFluxes.append( sim.add_flux(1000 / mat['wavelength'], spectralWidth, modeFrequencyResolution, transmissionFluxRegion)) transmissionModes.append( sim.add_mode_monitor(1000 / mat['wavelength'], spectralWidth, modeFrequencyResolution, transmissionFluxRegion)) if str(plotMe) == '1': animation = mp.Animate2D(sim, fields=mp.Ey, realtime=False, normalize=True, field_parameters={ 'alpha': 0.8, 'cmap': 'RdBu', 'interpolation': 'none' }, boundary_parameters={ 'hatch': 'o', 'linewidth': 1.5, 'facecolor': 'y', 'edgecolor': 'b', 'alpha': 0.3 }) sim.run(mp.at_every(0.5,mp.in_volume(mp.Volume(center=mp.Vector3(),size=mp.Vector3(sim.cell_size.x,sim.cell_size.y)),animation)), \ until_after_sources=mp.stop_when_fields_decayed(20,mp.Ey,mp.Vector3(outputsCenter[0][0],outputsCenter[0][1],outputsCenter[0][2]),1e-5)) #sim.init_sim() #sim.solve_cw(tol=10**-5,L=20) print('saving animation to ' + str(os.path.join(plotDir + 'animation.gif'))) animation.to_gif( 10, os.path.join(plotDir + 'inputMode_' + str(mat['modeSourceNum']) + '_' + 'animation.gif')) else: sim.run(until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ey, mp.Vector3(outputsCenter[0][0], outputsCenter[0][1], outputsCenter[0][2]), 1e-5)) normModeCoefficients = sim.get_eigenmode_coefficients( normMode, [mat['modeSourceNum'] + 1], direction=mp.X) #print('input norm coefficients TE00: ', numpy.abs(sim.get_eigenmode_coefficients(normMode, [1], direction=mp.X).alpha[0][0][0])**2) #print('input norm coefficients TE10: ', numpy.abs(sim.get_eigenmode_coefficients(normMode, [3], direction=mp.X).alpha[0][0][0])**2) #print('input norm coefficients TE20: ', numpy.abs(sim.get_eigenmode_coefficients(normMode, [5], direction=mp.X).alpha[0][0][0])**2) #normFluxes = sim.get resultingModes = [] resultingOverlaps = [] for i in range(0, len(outputsCenter)): resultingModes.append( sim.get_eigenmode_coefficients(transmissionModes[i], [outputsModeNum[i] + 1], direction=mp.X)) resultingOverlaps.append([ numpy.abs(resultingModes[i].alpha[0][j][0])**2 / numpy.abs(normModeCoefficients.alpha[0][j][0])**2 for j in range(modeFrequencyResolution) ]) #resultingFluxes.append(sim.get_flux_data(transmissionFluxes[i]) / inputFlux) if str(plotMe) == '1': eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric) plt.figure() for i in range(0, len(resultingModes)): frequencys = numpy.linspace( 1000 / mat['wavelength'] - spectralWidth / 2, 1000 / mat['wavelength'] + spectralWidth / 2, modeFrequencyResolution) plt.plot(1000 / frequencys, resultingOverlaps[i], label='Transmission TE' + str(int(outputsModeNum[i] / 2)) + '0') print('mode coefficients: ' + str(resultingOverlaps[i]) + ' for mode number ' + str(outputsModeNum[i])) print('mode coefficients: ' + str(resultingModes[i].alpha[0]) + ' for mode number ' + str(outputsModeNum[i])) plt.legend() plt.xlabel('Wavelength [nm]') plt.savefig( os.path.join(plotDir + 'inputMode_' + str(mat['modeSourceNum']) + '_' + 'mode_coefficients.png')) plt.close() if mat['dims'][2] == 1: plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.axis('off') plt.savefig( os.path.join(plotDir + 'inputMode_' + str(mat['modeSourceNum']) + '_' + 'debug_structure.png')) plt.close() inputFourier = [ sources[0].src.fourier_transform(1000 / f) for f in range(1, 1000) ] plt.figure() plt.plot(inputFourier) plt.savefig( os.path.join(plotDir + 'inputMode_' + str(mat['modeSourceNum']) + '_' + 'debug_input_fourier.png')) plt.close() ez_data = numpy.real( sim.get_array(center=mp.Vector3(), size=cell, component=mp.Ez)) plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9) plt.axis('off') plt.savefig( os.path.join(plotDir + 'inputMode_' + str(mat['modeSourceNum']) + '_' + 'debug_overlay.png')) plt.close() #it might be possible to just reset the structure. will result in speedup mp.all_wait() sim.reset_meep() end = time.time() if mp.am_master(): os.remove(jobName + '_eps.h5') print('simulation took ' + str(end - start)) if __name__ == "__main__": jobNameWithoutPath = jobName.split('/')[len(jobName.split('/')) - 1] sio.savemat( "results_" + jobNameWithoutPath, { 'pos': posModesToMeasure, 'modeNum': modeNumModesToMeasure, 'overlap': resultingOverlaps, 'inputModeNum': mat['modeSourceNum'], 'inputModePos': mat['modeSourcePos'] }) else: return { 'pos': posModesToMeasure, 'modeNum': modeNumModesToMeasure, 'overlap': resultingOverlaps, 'inputModeNum': mat['modeSourceNum'], 'inputModePos': mat['modeSourcePos'] }
sx = 40 sy = 6 cell_size = mp.Vector3(sx + 2 * dpml, sy) v0 = 1.0 # pulse center frequency a = 0.2 # Gaussian envelope half-width b = -0.5 # linear chirp rate (positive: up-chirp, negative: down-chirp) t0 = 15 # peak time def chirp(t): return np.exp(1j * 2 * np.pi * v0 * (t - t0)) * \ np.exp(-a * (t - t0)**2 + 1j * b * (t - t0)**2) sources = [mp.Source(src=mp.CustomSource(src_func=chirp), center=mp.Vector3(-0.5 * sx), size=mp.Vector3(y=sy), component=mp.Ez)] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, resolution=resolution, k_point=mp.Vector3(), sources=sources, symmetries=[mp.Mirror(mp.Y)]) sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx, sy)), mp.at_every(2.7, mp.output_efield_z)), until=t0 + 50)
def main(args): # Some parameters to describe the geometry: eps = 13 # dielectric constant of waveguide w = 1.2 # width of waveguide r = 0.36 # radius of holes d = 1.4 # defect spacing (ordinary spacing = 1) N = args.N # number of holes on either side of defect # The cell dimensions sy = args.sy # size of cell in y direction (perpendicular to wvg.) pad = 2 # padding between last hole and PML edge dpml = 1 # PML thickness sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction cell = mp.Vector3(sx, sy, 0) blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps)) geometry = [blk] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i)))) fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width nfreq = 500 # number of frequencies at which to compute flux sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=[], boundary_layers=[mp.PML(dpml)], resolution=20) if args.resonant_modes: sim.sources.append( mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3())) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) sim.symmetries.append(mp.Mirror(mp.X, phase=-1)) sim.run( # mp.at_beginning(mp.output_epsilon), mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)), until_after_sources=400) # sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen) else: sim.sources.append( mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ey, mp.Vector3(dpml + (-0.5 * sx)), size=mp.Vector3(0, w))) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) freg = mp.FluxRegion(center=mp.Vector3((0.5 * sx) - dpml - 0.5), size=mp.Vector3(0, 2 * w)) # transmitted flux trans = sim.add_flux(fcen, df, nfreq, freg) vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sx)) sim.run(mp.at_beginning(mp.output_epsilon), mp.during_sources( mp.in_volume( vol, mp.to_appended("hz-slice", mp.at_every(0.4, mp.output_hfield_z)))), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ey, mp.Vector3((0.5 * sx) - dpml - 0.5, 0), 1e-3)) sim.display_fluxes(trans) # print out the flux spectrum
def run_simulation(save_prefix, tip_radius=0.007, cone_height=0.364, trunk_radius=0.275, n_tip=3.694, k_tip=0.0, fcen=1.25, waves=7.5, theta_deg=10, sample=20, sx=0.8, sy=1.5, sz=1.0, dpml=0.1, res=1000, res_factor=0.2, X_1=-0.2, X_2=0.2, Y_1=-0.2, Y_2=0.2, Z_1=-0.2, Z_2=0.2, x_mon_rat=1.0, y_mon_rat=1.0, z_mon_rat=1.0): #Interpolate to next resolution step for high-res region dx = 1 / res X_1 = np.floor(X_1 / dx) * dx X_2 = np.ceil(X_2 / dx) * dx Y_1 = np.floor(Y_1 / dx) * dx Y_2 = np.ceil(Y_2 / dx) * dx Z_1 = np.floor(Z_1 / dx) * dx Z_2 = np.ceil(Z_2 / dx) * dx #Dump all the settings to a file: settings_file = h5py.File( Path(sys.argv[0]).stem + '-' + save_prefix + '_settings.h5', 'w') settings_file.create_dataset('tip_radius', data=tip_radius) settings_file.create_dataset('cone_height', data=cone_height) settings_file.create_dataset('trunk_radius', data=trunk_radius) settings_file.create_dataset('n_tip', data=n_tip) settings_file.create_dataset('k_tip', data=k_tip) settings_file.create_dataset('fcen', data=fcen) settings_file.create_dataset('waves', data=waves) settings_file.create_dataset('theta_deg', data=theta_deg) settings_file.create_dataset('sample', data=sample) settings_file.create_dataset('sx', data=sx) settings_file.create_dataset('sy', data=sy) settings_file.create_dataset('sz', data=sz) settings_file.create_dataset('dpml', data=dpml) settings_file.create_dataset('res', data=res) settings_file.create_dataset('res_factor', data=res_factor) settings_file.create_dataset('X_1', data=X_1) settings_file.create_dataset('X_2', data=X_2) settings_file.create_dataset('Y_1', data=Y_1) settings_file.create_dataset('Y_2', data=Y_2) settings_file.create_dataset('Z_1', data=Z_1) settings_file.create_dataset('Z_2', data=Z_2) settings_file.create_dataset('x_mon_rat', data=x_mon_rat) settings_file.create_dataset('y_mon_rat', data=y_mon_rat) settings_file.create_dataset('z_mon_rat', data=z_mon_rat) settings_file.close() #Convert theta to radians theta = theta_deg * np.pi / 180 eps_tip = calc_eps_r(n_tip, k_tip) sig_d_tip = calc_sig_d(n_tip, k_tip, fcen) #Create the cell size sX = 2 * dpml + sx sY = 2 * dpml + sy sZ = 2 * dpml + sz #Monitor sizes x_mon = sx * x_mon_rat y_mon = sx * y_mon_rat z_mon = sx * z_mon_rat #Calculate values in prime-space: sx_prime = sx * res_factor + (X_2 - X_1) * (1 - res_factor) sy_prime = sy * res_factor + (Y_2 - Y_1) * (1 - res_factor) sz_prime = sz * res_factor + (Z_2 - Z_1) * (1 - res_factor) dpml_prime = dpml * res_factor sX_prime = 2 * dpml_prime + sx_prime sY_prime = 2 * dpml_prime + sy_prime sZ_prime = 2 * dpml_prime + sz_prime x_mon_prime = (x_mon/2.0 > X_2)*((x_mon/2.0 - X_2)*res_factor + X_2) +\ (x_mon/2.0)*(x_mon/2.0 <= X_2) -\ (-1*x_mon/2.0 < X_1)*((-1*x_mon/2.0 - X_1)*res_factor + X_1) -\ (-1*x_mon/2.0)*(-1*x_mon/2.0 >= X_1) y_mon_prime = (y_mon/2.0 > Y_2)*((y_mon/2.0 - Y_2)*res_factor + Y_2) +\ (y_mon/2.0)*(y_mon/2.0 <= Y_2) -\ (-1*y_mon/2.0 < Y_1)*((-1*y_mon/2.0 - Y_1)*res_factor + Y_1) -\ (-1*y_mon/2.0)*(-1*y_mon/2.0 >= Y_1) z_mon_prime = (z_mon/2.0 > Z_2)*((z_mon/2.0 - Z_2)*res_factor + Z_2) +\ (z_mon/2.0)*(z_mon/2.0 <= Z_2) -\ (-1*z_mon/2.0 < Z_1)*((-1*z_mon/2.0 - Z_1)*res_factor + Z_1) -\ (-1*z_mon/2.0)*(-1*z_mon/2.0 >= Z_1) cell = mp.Vector3(sX_prime, sY_prime, sZ_prime) tip = [ mp.Cylinder(radius=trunk_radius, center=mp.Vector3( 0.0, -1 * sY / 4.0 - cone_height / 2.0 - tip_radius, 0.0), height=(sY / 2.0 - cone_height), axis=mp.Vector3(0.0, 1.0, 0.0)), mp.Cone(center=mp.Vector3(0, -1 * cone_height / 2 - tip_radius, 0), height=cone_height, radius=trunk_radius, radius2=tip_radius, axis=mp.Vector3(0, 1, 0)), mp.Sphere(center=mp.Vector3(0, -1 * tip_radius, 0), radius=tip_radius) ] def mat_func(r_prime): r_x = r_prime.x r_y = r_prime.y r_z = r_prime.z x_fac = 1 y_fac = 1 z_fac = 1 if (r_prime.x < X_1): x_fac = res_factor r_x = X_1 + (r_prime.x - X_1) / res_factor elif (r_prime.x > X_2): x_fac = res_factor r_x = X_2 + (r_prime.x - X_2) / res_factor if (r_prime.y < Y_1): y_fac = res_factor r_y = Y_1 + (r_prime.y - Y_1) / res_factor elif (r_prime.y > Y_2): y_fac = res_factor r_y = Y_2 + (r_prime.y - Y_2) / res_factor if (r_prime.z < Z_1): z_fac = res_factor r_z = Z_1 + (r_prime.z - Z_1) / res_factor elif (r_prime.z > Z_2): z_fac = res_factor r_z = Z_2 + (r_prime.z - Z_2) / res_factor r = mp.Vector3(r_x, r_y, r_z) J = np.matrix([[x_fac, 0, 0], [0, y_fac, 0], [0, 0, z_fac]]) #Loop through all objects inside of tip and see if point is inside. # if yes -- then set eps_point to tip eps # if no -- then leave it as air eps_point = 1.0 for kk in range(len(tip)): if (mp.is_point_in_object(r, tip[kk])): eps_point = eps_tip eps_transform = eps_point * J * J.transpose() / np.linalg.det(J) mu_transform = J * J.transpose() / np.linalg.det(J) eps_diag = eps_transform.diagonal() mu_diag = mu_transform.diagonal() mat = mp.Medium(epsilon_diag=mp.Vector3(eps_diag[0, 0], eps_diag[0, 1], eps_diag[0, 2]), mu_diag=mp.Vector3(mu_diag[0, 0], mu_diag[0, 1], mu_diag[0, 2]), D_conductivity=sig_d_tip) return mat #Create source amplitude function: ky = fcen * np.sin(theta) ky_prime = ky * sY / sY_prime def my_amp_func_y(r_prime): r_y = r_prime.y y_fac = 1 / res_factor if ((r_prime.x >= X_1) and (r_prime.x <= X_2)): x_fac = 1.0 / res_factor else: x_fac = 1.0 if (r_prime.y < Y_1): y_fac = 1.0 r_y = Y_1 + (r_prime.y - Y_1) / res_factor elif (r_prime.y > Y_2): y_fac = 1.0 r_y = Y_2 + (r_prime.y - Y_2) / res_factor if ((r_prime.z >= Z_1) and (r_prime.z <= Z_2)): z_fac = 1.0 / res_factor else: z_fac = 1.0 J = np.matrix([[x_fac, 0, 0], [0, y_fac, 0], [0, 0, z_fac]]) transform = J / np.linalg.det(J) phase_factor = np.exp(-1 * 2 * 1j * np.pi * ky * r_y) amp_factor = transform.diagonal()[0, 1] return amp_factor * phase_factor def my_amp_func_z(r_prime): r_y = r_prime.y y_fac = 1.0 / res_factor if ((r_prime.x >= X_1) and (r_prime.x <= X_2)): x_fac = 1.0 / res_factor else: x_fac = 1.0 if (r_prime.y < Y_1): y_fac = 1.0 r_y = Y_1 + (r_prime.y - Y_1) / res_factor elif (r_prime.y > Y_2): y_fac = 1.0 r_y = Y_2 + (r_prime.y - Y_2) / res_factor if ((r_prime.z >= Z_1) and (r_prime.z <= Z_2)): z_fac = 1.0 / res_factor else: z_fac = 1.0 J = np.matrix([[x_fac, 0, 0], [0, y_fac, 0], [0, 0, z_fac]]) transform = J / np.linalg.det(J) phase_factor = np.exp(-1 * 2 * 1j * np.pi * ky * r_y) amp_factor = transform.diagonal()[0, 2] return amp_factor * phase_factor #Create PMLs pml_layers = [ mp.PML(thickness=dpml_prime, direction=mp.X), mp.PML(thickness=dpml_prime, direction=mp.Y), mp.PML(thickness=dpml_prime, direction=mp.Z) ] symmetry = [mp.Mirror(direction=mp.X)] #Sources Ey_source = mp.Source(mp.ContinuousSource(frequency=fcen), component=mp.Ey, center=mp.Vector3(0, 0, -1 * sz_prime * 0.5), size=mp.Vector3(sX_prime, sY_prime, 0), amp_func=my_amp_func_y, amplitude=np.cos(theta)) Ez_source = mp.Source(mp.ContinuousSource(frequency=fcen), component=mp.Ez, center=mp.Vector3(0, 0, -1 * sz_prime * 0.5), size=mp.Vector3(sX_prime, sY_prime, 0), amp_func=my_amp_func_z, amplitude=np.sin(theta)) sources = [Ey_source, Ez_source] monitor_xy = mp.Volume(center=mp.Vector3(0, 0, 0), size=mp.Vector3(x_mon_prime, y_mon_prime, 0)) monitor_yz = mp.Volume(center=mp.Vector3(0, 0, 0), size=mp.Vector3(0, y_mon_prime, z_mon_prime)) #Now make the simulation sim = mp.Simulation( cell_size=cell, boundary_layers=pml_layers, geometry=[], sources=sources, resolution=res, symmetries=symmetry, dimensions=3, k_point=mp.Vector3(0, -1 * ky_prime, 0), material_function=mat_func, extra_materials=[mp.Medium(epsilon=eps_tip, mu=4, D_conductivity=1)], verbose=True) sim.run(mp.in_volume( monitor_xy, mp.to_appended(save_prefix + "E_xy", mp.at_every(1 / fcen / sample, mp.output_efield))), mp.in_volume( monitor_yz, mp.to_appended( save_prefix + "E_yz", mp.at_every(1 / fcen / sample, mp.output_efield))), until=waves / fcen)
dpml = 2 pml_layers = [mp.PML(thickness=dpml,direction=mp.X)] sx = 40 sy = 6 cell_size = mp.Vector3(sx+2*dpml,sy) v0 = 1.0 # pulse center frequency a = 0.2 # Gaussian envelope half-width b = -0.5 # linear chirp rate (positive: up-chirp, negative: down-chirp) t0 = 15 # peak time chirp = lambda t: np.exp(1j*2*np.pi*v0*(t-t0)) * np.exp(-a*(t-t0)**2+1j*b*(t-t0)**2) sources = [mp.Source(src=mp.CustomSource(src_func=chirp), center=mp.Vector3(-0.5*sx), size=mp.Vector3(y=sy), component=mp.Ez)] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, resolution=resolution, k_point=mp.Vector3(), sources=sources, symmetries=[mp.Mirror(mp.Y)]) sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx,sy)), mp.at_every(2.7, mp.output_efield_z)), until=t0+50)
mp.Source(mp.GaussianSource(fcen, fwidth=df), size=mp.Vector3(0, 0, 0.8), component=mp.Ez, center=mp.Vector3(-14, 5.)) ] #-14,5.,0.8 #sources = [mp.Source(mp.ContinuousSource(frequency=fcen, width=20), component=mp.Ez, center=mp.Vector3(-14,5.))] sim = mp.Simulation( cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=res) #geometry=geometry, boundary_layers=pml_layers sim.run(mp.at_beginning(mp.output_epsilon), mp.in_volume( mp.Volume(center=mp.Vector3(0, 0, 0), size=mp.Vector3(sx, sy, 0)), mp.to_appended("ez", mp.at_every(0.6, mp.output_efield_z))), mp.in_volume( mp.Volume(center=mp.Vector3(-14, 5., 0), size=mp.Vector3(0, 0, 0)), mp.to_appended("EzTr", mp.at_every(0.6, mp.output_efield_z))), mp.in_volume( mp.Volume(center=mp.Vector3(14., -5., 0), size=mp.Vector3(0, 0, 0)), mp.to_appended("EzR2", mp.at_every(0.6, mp.output_efield_z))), mp.in_volume( mp.Volume(center=mp.Vector3(10., 5., 0), size=mp.Vector3(0, 0, 0)), mp.to_appended("EzR3", mp.at_every(0.6, mp.output_efield_z))), mp.in_volume( mp.Volume(center=mp.Vector3(10., -5., 0), size=mp.Vector3(0, 0, 0)), mp.to_appended("EzR4", mp.at_every(0.6, mp.output_efield_z))),
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)
def main(args): resolution = 20 # pixels/um eps = 13 # dielectric constant of waveguide w = 1.2 # width of waveguide r = 0.36 # radius of holes d = 1.4 # defect spacing (ordinary spacing = 1) N = args.N # number of holes on either side of defect sy = args.sy # size of cell in y direction (perpendicular to wvg.) pad = 2 # padding between last hole and PML edge dpml = 1 # PML thickness sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction cell = mp.Vector3(sx, sy, 0) blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps)) geometry = [blk] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i)))) pml_layers = [mp.PML(1.0)] fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width src = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3(-0.5 * sx + dpml), size=mp.Vector3(0, w)) ] sym = [mp.Mirror(mp.Y, phase=-1)] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, sources=src, symmetries=sym, resolution=resolution) freg = mp.FluxRegion(center=mp.Vector3(0.5 * sx - dpml - 0.5), size=mp.Vector3(0, 2 * w)) nfreq = 500 # number of frequencies at which to compute flux # transmitted flux trans = sim.add_flux(fcen, df, nfreq, freg) vol = mp.Volume(mp.Vector3(0), size=mp.Vector3(sx)) plt.figure(dpi=150) sim.plot2D() #plt.show() plt.savefig('2Dstructure.png') sim.run(mp.at_beginning(mp.output_epsilon), mp.during_sources( mp.in_volume( vol, mp.to_appended("hz-slice", mp.at_every(0.4, mp.output_hfield_z)))), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ey, mp.Vector3(0.5 * sx - dpml - 0.5), 1e-3)) sim.display_fluxes(trans) # print out the flux spectrum
def main(args): resolution = 20 # pixels/um eps = 13 # dielectric constant of waveguide w = 1.2 # width of waveguide r = 0.36 # radius of holes d = 1.4 # defect spacing (ordinary spacing = 1) N = args.N # number of holes on either side of defect sy = args.sy # size of cell in y direction (perpendicular to wvg.) pad = 2 # padding between last hole and PML edge dpml = 1 # PML thickness sx = 2*(pad+dpml+N)+d-1 # size of cell in x direction cell = mp.Vector3(sx,sy,0) blk = mp.Block(size=mp.Vector3(mp.inf,w,mp.inf), material=mp.Medium(epsilon=eps)) geometry = [blk] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d/2+i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d/2+i)))) fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width nfreq = 500 # number of frequencies at which to compute flux sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=[], boundary_layers=[mp.PML(dpml)], resolution=20) if args.resonant_modes: sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3())) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) sim.symmetries.append(mp.Mirror(mp.X, phase=-1)) sim.run(mp.at_beginning(mp.output_epsilon), mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)), until_after_sources=400) sim.run(mp.at_every(1/fcen/20, mp.output_hfield_z), until=1/fcen) else: sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3(-0.5*sx+dpml), size=mp.Vector3(0,w))) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) freg = mp.FluxRegion(center=mp.Vector3(0.5*sx-dpml-0.5), size=mp.Vector3(0,2*w)) # transmitted flux trans = sim.add_flux(fcen, df, nfreq, freg) vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sx)) sim.run(mp.at_beginning(mp.output_epsilon), mp.during_sources(mp.in_volume(vol, mp.to_appended("hz-slice", mp.at_every(0.4, mp.output_hfield_z)))), until_after_sources=mp.stop_when_fields_decayed(50, mp.Ey, mp.Vector3(0.5*sx-dpml-0.5), 1e-3)) sim.display_fluxes(trans) # print out the flux spectrum
sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) sim.symmetries.append(mp.Mirror(mp.X, phase=-1)) sim.run(mp.at_beginning(mp.output_epsilon), mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)), until_after_sources=400) sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen) else: sim.sources.append(mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3(-0.5 * sx + dpml), size=mp.Vector3(0, w))) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) freg = mp.FluxRegion(center=mp.Vector3(0.5 * sx - dpml - 0.5), size=mp.Vector3(0, 2 * w)) # transmitted flux trans = sim.add_flux(fcen, df, nfreq, freg) vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sx)) sim.run(mp.at_beginning(mp.output_epsilon), mp.during_sources(mp.in_volume(vol, mp.to_appended( "hz-slice", mp.at_every(0.4, mp.output_hfield_z)))), until_after_sources=mp.stop_when_fields_decayed(50, mp.Ey, mp.Vector3(0.5 * sx - dpml - 0.5), 1e-3)) sim.display_fluxes(trans) # print out the flux spectrum
def generateData(i, resolution=5, total_time=10000, dT=10, length=500., pml_thickness=10., outer_radius=10., chi3=0.0, half=False, shift=200): ### Generate data using MEEP print('Run ' + str(i + 1) + ' of ' + str(data_size)) while True: dr1 = np.random.normal(scale=0.05) dr2 = np.random.normal(scale=0.02) de1 = np.random.normal(scale=1) de2 = np.random.normal(scale=2) inner_core_radius = 0.5 + dr2 core_radius = 1.0 + dr1 if core_radius > inner_core_radius: break output_dir = f"out-{i:05d}" cell_size = mp.Vector3(outer_radius + pml_thickness, 0, length + 2 * pml_thickness) pml_layers = [mp.PML(thickness=pml_thickness)] default_material = mp.Medium(index=1, chi3=chi3) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(2 * core_radius, mp.inf, mp.inf), material=mp.Medium(epsilon=8 + de1, chi3=chi3)), mp.Block(center=mp.Vector3(), size=mp.Vector3(2 * inner_core_radius, mp.inf, mp.inf), material=mp.Medium(epsilon=30 + de2, chi3=chi3)) ] fsrc = 0.1 if not half: u0, f = get_f(total_time, dT, fsrc=fsrc, batch_size=1) else: u0, f = get_f_half(total_time, dT, fsrc=fsrc, batch_size=1) sources = [ mp.Source(src=mp.CustomSource(src_func=lambda t: f(t)[0]), center=mp.Vector3(0, 0, -length / 2.), size=mp.Vector3(2 * (3)), component=mp.Er) ] sim = mp.Simulation(cell_size=cell_size, resolution=resolution, boundary_layers=pml_layers, sources=sources, geometry=geometry, dimensions=mp.CYLINDRICAL, m=1) flux_total = sim.add_flux( fsrc, 1. * fsrc, int(fsrc * total_time) + 1, mp.FluxRegion(center=mp.Vector3(0, 0, -length / 2. + pml_thickness), size=mp.Vector3(2 * outer_radius))) sim.use_output_directory(output_dir) sim.run(mp.at_every( dT, mp.in_volume( mp.Volume(center=mp.Vector3(), size=mp.Vector3(0, 0, length)), mp.output_efield_r)), until=total_time) files = sorted(glob.glob(output_dir + "/*er-*.h5")) data = [] for file in files: f = h5py.File(file, "r") data.append(np.array(f['er.r']) + 1j * np.array(f['er.i'])) data = np.stack(data) # Normalize by flux freqs = np.array(mp.get_flux_freqs(flux_total)) flux = np.array(mp.get_fluxes(flux_total)) integrated_flux = np.sum(flux) * (freqs[1] - freqs[0]) integrated_efield = np.sum( np.abs(data[:, int(resolution * pml_thickness) + 1])**2) * dT norm_factor = np.sqrt(integrated_flux / integrated_efield) data *= norm_factor mean_norm2 = np.mean( np.abs(data[:, int(resolution * pml_thickness) + 1])**2) # Remove carrier frequency/wavelength k = np.fft.fftfreq(data.shape[-1], d=1. / resolution) k0 = k[np.argmax(np.abs(np.mean(np.fft.fft(data), 0)))] psi = data * np.exp( 1j * 2 * np.pi * (fsrc * dT * np.expand_dims(np.arange(data.shape[0]), 1) - k0 * np.arange(data.shape[1]) / resolution)) psi = psi[shift:, int(resolution * pml_thickness) + 1:-1:int( resolution)] # drop region near PML and initial time 200*dT psi = psi.transpose() # swap t and z axis shutil.rmtree(output_dir) return np.expand_dims(np.stack([np.real(psi), np.imag(psi)], axis=-3), 0).astype(np.float32), np.array( [[dr1, dr2, de1, de2, k0, mean_norm2]]).astype(np.float32)
def main(args): """ Args: * **fields** (boolean): If true, outputs the fields at the relevant waveguide cross-sections (top-down and side-view) * **output_directory** (string): Name of the output directory (for storing the fields) * **eps_input_file** (string): Name of the hdf5 file that defines the geometry through prisms * **input_pol** (string): Either "TE", or "TM", corresponding to the desired input mode. Defaults to "TE" * **res** (int): Resolution of the MEEP simulation * **nfreq** (int): The number of wavelength points to record in the transmission/reflection spectra * **input_direction** (1 or -1): Direction of propagation for the input eigenmode. If +1, goes in +x, else if -1, goes in -x. Defaults to +1. * **dpml** (float): Length (in microns) of the perfectly-matched layer (PML) at simulation boundaries. Defaults to 0.5 um. * **wl_center** (float): Center wavelength (in microns) * **wl_span** (float): Wavelength span (determines the pulse width) * **port_vcenter** (float): Vertical center of the waveguide * **port_height** (float): Height of the port cross-section (flux plane) * **port_width** (float): Width of the port cross-section (flux plane) * **source_offset** (float): Offset (in x-direction) between reflection monitor and source. Defaults to 0.1 um. * **center_x** (float): x-coordinate of the center of the simulation region * **center_y** (float): y-coordinate of the center of the simulation region * **center_z** (float): z-coordinate of the center of the simulation region * **sx** (float): Size of the simulation region in x-direction * **sx** (float): Size of the simulation region in y-direction * **sz** (float): Size of the simulation region in z-direction * **port_coords** (list): List of the port coordinates (variable length), in the format [x1, y1, x2, y2, x3, y3, ...] (*must* be even) """ #Boolean inputs fields = args.fields #String inputs output_directory = args.output_directory eps_input_file = args.eps_input_file input_pol = args.input_pol #Int inputs res = args.res nfreq = args.nfreq input_direction = args.input_direction #Float inputs dpml = args.dpml wl_center = args.wl_center wl_span = args.wl_span port_vcenter = args.port_vcenter port_height = args.port_height port_width = args.port_width source_offset = args.source_offset center_x, center_y, center_z = args.center_x, args.center_y, args.center_z sx, sy, sz = args.sx, args.sy, args.sz #List of floats port_coords = [float(x) for x in args.port_coords[0].split(" ")] ports = [(port_coords[2 * i], port_coords[2 * i + 1]) for i in range(int(len(port_coords) / 2))] if input_pol == "TE": parity = mp.ODD_Z elif input_pol == "TM": parity = mp.EVEN_Z else: raise ValueError( "Warning! Improper value of 'input_pol' was passed to mcts.py (input_pol given =" + str(input_pol) + ")") if len(port_coords) % 2 != 0: raise ValueError( "Warning! Improper port_coords was passed to `meep_compute_transmission_spectra`. Must be even number of port_coords in [x1, y1, x2, y2, ..] format." ) # Setup the simulation geometries prism_objects = get_prism_objects(eps_input_file) geometry = [] for p in prism_objects: # print('vertices='+str(p['vlist'])) # print('axis = '+str(mp.Vector3(0,1,0))) # print('height = '+str(p['height'])) print('material = ' + str(p['eps'])) # print('\n') geometry.append( mp.Prism(p['vlist'], axis=mp.Vector3(0, 1, 0), height=p['height'], material=mp.Medium(epsilon=p['eps']))) # Setup the simulation sources fmax = 1.0 / (wl_center - 0.5 * wl_span) fmin = 1.0 / (wl_center + 0.5 * wl_span) fcen = (fmax + fmin) / 2.0 df = fmax - fmin if abs(abs(input_direction) - 1) > 1E-6: print(input_direction) raise ValueError("Warning! input_direction is not +1 or -1.") # Use first port in 'ports' as the location of the eigenmode source sources = [ mp.EigenModeSource( src=mp.GaussianSource(fcen, fwidth=df, cutoff=30), component=mp.ALL_COMPONENTS, size=mp.Vector3(0, 3 * float(port_height), 3 * float(port_width)), center=mp.Vector3(ports[0][0] + source_offset - center_x, float(port_vcenter) - center_y, ports[0][1] - center_z), eig_match_freq=True, eig_parity=parity, eig_kpoint=mp.Vector3(float(input_direction) * wl_center, 0, 0), eig_resolution=2 * res if res > 16 else 32, ) ] # Setup the simulation sim = mp.Simulation(cell_size=mp.Vector3(sx, sy, sz), boundary_layers=[mp.PML(dpml)], geometry=geometry, sources=sources, dimensions=3, resolution=res, filename_prefix=False) """ Add power flux monitors """ print("ADDING FLUX MONITORS") flux_plane_objects = [] for port in ports: flux_region = mp.FluxRegion(size=mp.Vector3(0, float(port_height), float(port_width)), center=mp.Vector3( float(port[0]) - center_x, float(port_vcenter) - center_y, float(port[1]) - center_z)) fpo = sim.add_flux(fcen, df, nfreq, flux_region) flux_plane_objects.append(fpo) sim.use_output_directory(str(output_directory)) """ Run the simulation """ """ Monitor the amplitude in the center of the structure """ decay_pt = mp.Vector3(0, port_vcenter, 0) sv = mp.Volume(size=mp.Vector3(sx, sy, 0), center=mp.Vector3(0, 0, 0)) tv = mp.Volume(size=mp.Vector3(sx, 0, sz), center=mp.Vector3(0, port_vcenter, 0)) print("RUNNING SIMULATION") if fields: sim.run(mp.at_beginning(mp.output_epsilon), mp.at_beginning( mp.with_prefix(str("sideview-"), mp.in_volume(sv, mp.output_epsilon))), mp.at_beginning( mp.with_prefix(str("topview-"), mp.in_volume(tv, mp.output_epsilon))), mp.at_every( 1.0, mp.to_appended(str("ez-sideview"), mp.in_volume(sv, mp.output_efield_z))), mp.at_every( 1.0, mp.to_appended(str("ez-topview"), mp.in_volume(tv, mp.output_efield_z))), until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ez, decay_pt, 1e-4)) else: sim.run(until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ez, decay_pt, 1e-4)) sim.display_fluxes(*flux_plane_objects) print("FINISHED SIMULATION")
def main(args): resolution = 30 # pixels/um a_start = args.a_start # starting periodicity a_end = args.a_end # ending periodicity s_cav = args.s_cav # cavity length r = args.r # hole radius (units of a) h = args.hh # waveguide height w = args.w # waveguide width dair = 1.00 # air padding dpml = 1.00 # PML thickness Ndef = args.Ndef # number of defect periods a_taper = mp.interpolate(Ndef, [a_start, a_end]) dgap = a_end - 2 * r * a_end Nwvg = args.Nwvg # number of waveguide periods sx = 2 * (Nwvg * a_start + sum(a_taper)) - dgap + s_cav sy = dpml + dair + w + dair + dpml sz = dpml + dair + h + dair + dpml cell_size = mp.Vector3(sx, sy, sz) boundary_layers = [mp.PML(dpml)] nSi = 3.45 Si = mp.Medium(index=nSi) geometry = [ mp.Block(material=Si, center=mp.Vector3(), size=mp.Vector3(mp.inf, w, h)) ] for mm in range(Nwvg): geometry.append( mp.Cylinder(material=mp.air, radius=r * a_start, height=mp.inf, center=mp.Vector3( -0.5 * sx + 0.5 * a_start + mm * a_start, 0, 0))) geometry.append( mp.Cylinder(material=mp.air, radius=r * a_start, height=mp.inf, center=mp.Vector3( +0.5 * sx - 0.5 * a_start - mm * a_start, 0, 0))) for mm in range(Ndef + 2): geometry.append( mp.Cylinder(material=mp.air, radius=r * a_taper[mm], height=mp.inf, center=mp.Vector3( -0.5 * sx + Nwvg * a_start + (sum(a_taper[:mm]) if mm > 0 else 0) + 0.5 * a_taper[mm], 0, 0))) geometry.append( mp.Cylinder(material=mp.air, radius=r * a_taper[mm], height=mp.inf, center=mp.Vector3( +0.5 * sx - Nwvg * a_start - (sum(a_taper[:mm]) if mm > 0 else 0) - 0.5 * a_taper[mm], 0, 0))) lambda_min = 1.46 # minimum source wavelength lambda_max = 1.66 # maximum source wavelength fmin = 1 / lambda_max fmax = 1 / lambda_min fcen = 0.5 * (fmin + fmax) df = fmax - fmin sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3()) ] symmetries = [ mp.Mirror(mp.X, +1), mp.Mirror(mp.Y, -1), mp.Mirror(mp.Z, +1) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=geometry, sources=sources, dimensions=3, symmetries=symmetries) sim.run(mp.in_volume( mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx, sy, 0)), mp.at_end(mp.output_epsilon, mp.output_efield_y)), mp.after_sources(mp.Harminv(mp.Ey, mp.Vector3(), fcen, df)), until_after_sources=500)
# dft_objx = [] for i in range(len(flux_freqsX)): dft_objx = np.append( dft_objx, sim.add_dft_fields([polarisation], flux_freqsX[i], flux_freqsX[i], 1, where=monitor)) dft_obj = sim.add_dft_fields([polarisation], fcen, fcen, 1, where=monitor) sim.use_output_directory('flux-out_1') sim.run(mp.in_volume(monitor, mp.at_beginning(mp.output_epsilon)), mp.in_volume( monitor, mp.to_appended("ez", mp.at_every(time_step, mp.output_efield_x))), until_after_sources=mp.stop_when_fields_decayed( add_time, polarisation, pt, decay)) ''' sim.run(until_after_sources=mp.stop_when_fields_decayed(add_time,polarisation,pt,decay)) ''' #save scattered reflected flux from the surfaces scat_refl_data_t = mp.get_fluxes(refl_t) scat_refl_data_b = mp.get_fluxes(refl_b) scat_refl_data_l = mp.get_fluxes(refl_l) scat_refl_data_r = mp.get_fluxes(refl_r)
def generate_model(params, args): cell = mp.Vector3(params.cell_width, params.cell_height, 0) spheres = mplib.geo2D_spherical_pc(params.ps_n, params.si_n, params.ps_thickness, params.si_thickness, params.cell_height, params.num_layers, params.cell_width/2-200, params.sph_radius, params.sph_spacing, params.offset, params.xoffset) thin_film = mplib.geo2D_thin_film(params.ps_n, params.ps_thickness, params.cell_height, params.cell_width/2-100) pc_ideal = mplib.geo2D_photonic_crystal(params.ps_n, params.other_n, params.ps_thickness, params.cell_height, params.si_thickness, params.si_n, 5, params.cell_width/2-200, 50) geometry = pc_ideal if args.background: geometry = [] ## Gaussian source source_pos = -1*params.cell_width/2 + params.dpml+5 sources = [mp.Source(mp.GaussianSource(frequency=params.freq, fwidth=params.df), mp.Ez, center=mp.Vector3(source_pos,0,0), size=mp.Vector3(0,params.cell_height,0))] pml_layers = [mp.PML(params.dpml, direction=mp.X)] sim = mp.Simulation(cell_size = cell, boundary_layers = pml_layers, geometry = geometry, filename_prefix=args.filename, sources = sources, k_point = mp.Vector3(0,0,0), resolution = params.resolution) freg_trans = mp.FluxRegion(center = mp.Vector3(0.5*params.cell_width - params.dpml - 1,0,0), size = mp.Vector3(0, params.cell_height, 0)) freg_ref = mp.FluxRegion(center = mp.Vector3(source_pos + 10, 0, 0), size = mp.Vector3(0, params.cell_height), weight=1.0) trans_flux = sim.add_flux(params.freq, params.df , 500, freg_trans) ref_flux = sim.add_flux(params.freq, params.df, 500, freg_ref) vol = mp.Volume(mp.Vector3(0), size = mp.Vector3(params.cell_width,0,0)) if not args.reflectflux: sim.load_minus_flux("pulse_bg_flux_{:d}".format(params.wavelength),ref_flux) if args.outdir: print("Output directory: {:s}".format(args.outdir)) sim.use_output_directory(args.outdir) if args.geometry: sim.run(mp.at_beginning(mp.output_epsilon), until=1) else: sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended("ez", mp.at_every(params.dt, mp.output_efield_z)), #mp.to_appended("ep", mp.at_every(params.dt, mp.output_dpwr)), mp.in_volume(vol, mp.to_appended("ez_slice", mp.at_every(params.dt, mp.output_efield_z))), until=params.time) if args.reflectflux: sim.save_flux("pulse_bg_flux_{:d}".format(params.wavelength),ref_flux) #sim.save_flux("bg_flux_other", trans_flux) sim.display_fluxes(trans_flux, ref_flux)
def main(args): resolution = 20 # pixels/um eps = 13 # epsilon of waveguide cols = 3 # metade da quantidade de colunas no cristal lines = 1 #7 é valor anterior # metade da quantidade de linhas no cristal w = 1.2 # width of the waveguide r = 0.2 # radius of holes N = args.N # number of holes on either side of defect #pad = 1 # padding between last hole and PML dpml = 1 # PML thickness sy = 2 * (dpml + lines) # tamanho da celula em Y (perpend ao guia) #sy = args.sy # size of cell in Y (perpend to wvg) fcen = args.fcen # pulse centger frequency df = args.df # pulse frequency width #sx = 2*(pad + dpml ) + lines # size of cell in X sx = 2 * (dpml + cols) cell = mp.Vector3(sx, sy, 0) blk = mp.Block(size=mp.Vector3(mp.inf, mp.inf, mp.inf), material=mp.Medium(epsilon=eps)) geometry = [blk] for i in range(lines): geometry.append(mp.Cylinder(r, center=mp.Vector3(0, i))) for j in range(cols): geometry.append(mp.Cylinder(r, center=mp.Vector3(i, j))) # j,i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(-i, j))) # j,-i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(i, -j))) # -j,i))) geometry.append(mp.Cylinder(r, center=mp.Vector3( -i, -j))) # -j,-i))) geometry.append( mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))) pml_layers = [mp.PML(1.0)] src = [ mp.Source( mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3( -0.5 * sx + dpml ), # fonte na esquerda; para colocar na direita usar 0.5*sx - dpml size=mp.Vector3(0, w)) ] sim = mp.Simulation( cell_size=cell, geometry=geometry, boundary_layers=pml_layers, sources=src, #symmetries=sym, resolution=resolution) freg = mp.FluxRegion( center=mp.Vector3( 0.5 * sx - dpml - 0.5 ), # fluxo na direita; para colocar na esquerda usar -0.5*sx+dpml+0.5 size=mp.Vector3(0, 2 * w)) nfreq = 500 # number of frequencies computed fluxes trans = sim.add_flux(fcen, df, nfreq, freg) # transmitted flux vol = mp.Volume(mp.Vector3(0), size=mp.Vector3(sx)) volTime = mp.Volume(mp.Vector3(((sx) / 2 - dpml), 0), size=mp.Vector3( 0, 1, 0)) # dados para pulso no tempo no final do guia hvals = [] def gethvals(sim): hvals.append( sim.get_array(center=mp.Vector3(), size=cell, component=mp.Hz)) sim.run(mp.at_beginning(mp.output_epsilon), mp.in_volume( volTime, mp.to_appended("TimeVsE2", mp.at_every(0.4, mp.output_dpwr))), mp.in_volume( vol, mp.to_appended("hz-slice", mp.at_every(0.4, gethvals, mp.output_hfield_z))), until=300) sim.display_fluxes( trans) # print flux spectrum - linha realocada, ver abaixo epsilon0 = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric) plt.figure() plt.imshow(epsilon0.transpose(), interpolation='spline36', cmap='RdBu') plt.axis('off') plt.savefig('epsilon.png', format='png') plt.show()