def verify_output_and_slice(self, material, frequency): # Since the slice routines average the diagonals, we need to do that too: chi1 = material.epsilon(frequency).astype(np.complex128) chi1inv = np.linalg.inv(chi1) chi1inv = np.diag(chi1inv) N = chi1inv.size n = np.sqrt(N / np.sum(chi1inv)) sim = mp.Simulation(cell_size=mp.Vector3(2, 2, 2), default_material=material, resolution=20, eps_averaging=False) sim.use_output_directory(self.temp_dir) sim.init_sim() # Check to make sure the get_slice routine is working with frequency n_slice = np.sqrt(np.max(sim.get_epsilon(frequency))) self.assertAlmostEqual(n, n_slice, places=4) # Check to make sure h5 output is working with frequency filename = os.path.join(self.temp_dir, 'dispersive_eigenmode-eps-000000.00.h5') mp.output_epsilon(sim, frequency=frequency) n_h5 = 0 mp.all_wait() with h5py.File(filename, 'r') as f: n_h5 = np.sqrt( np.max(mp.complexarray(f['eps.r'][()], f['eps.i'][()]))) self.assertAlmostEqual(n, n_h5, places=4)
def verify_output_and_slice(self, material, omega): # Since the slice routines average the diagonals, we need to do that too: chi1 = material.epsilon(omega).astype(np.complex128) if np.any(np.imag(chi1) != 0): chi1 = np.square(np.real(np.sqrt(chi1))) chi1inv = np.linalg.inv(chi1) chi1inv = np.diag(chi1inv) N = chi1inv.size n = np.sqrt(N / np.sum(chi1inv)) sim = mp.Simulation(cell_size=mp.Vector3(2, 2, 2), default_material=material, resolution=20, eps_averaging=False) sim.init_sim() # Check to make sure the get_slice routine is working with omega n_slice = np.sqrt(np.max(sim.get_epsilon(omega))) self.assertAlmostEqual(n, n_slice, places=4) # Check to make sure h5 output is working with omega filename = 'dispersive_eigenmode-eps-000000.00.h5' mp.output_epsilon(sim, omega=omega) n_h5 = 0 mp.all_wait() with h5py.File(filename, 'r') as f: n_h5 = np.sqrt(np.mean(f['eps'][()])) self.assertAlmostEqual(n, n_h5, places=4)
def test_at_time(self): sim = self.init_simple_simulation() sim.run(mp.at_time(100, mp.output_efield_z), until=200) fname = 'simulation-ez-000100.00.h5' self.assertTrue(os.path.exists(fname)) mp.all_wait() if mp.am_master(): os.remove(fname)
def test_in_point(self): sim = self.init_simple_simulation(filename_prefix='test_in_point') fn = sim.filename_prefix + '-ez-000200.00.h5' pt = mp.Vector3() sim.run(mp.at_end(mp.in_point(pt, mp.output_efield_z)), until=200) self.assertTrue(os.path.exists(fn)) mp.all_wait() if mp.am_master(): os.remove(fn)
def test_with_prefix(self): sim = self.init_simple_simulation() sim.run(mp.with_prefix('test_prefix-', mp.at_end(mp.output_efield_z)), until=200) fname = 'test_prefix-simulation-ez-000200.00.h5' self.assertTrue(os.path.exists(fname)) mp.all_wait() if mp.am_master(): os.remove(fname)
def test_load_dump_structure(self): 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(-1.5, -1.5), size=one_by_one), mp.Block(material=mp.Medium(epsilon=13), center=mp.Vector3(1.5, 1.5), size=one_by_one) ] pml_layers = [mp.PML(0.5)] sim = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=pml_layers, geometry=geometry, 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) sim.run(mp.at_every(5, get_ref_field_point), until=50) dump_fn = 'test_load_dump_structure.h5' sim.dump_structure(dump_fn) sim = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=pml_layers, sources=[sources], 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) mp.all_wait() if mp.am_master(): os.remove(dump_fn)
def compare_h5_files(self, ref_path, res_path, tol=1e-3): mp.all_wait() with h5py.File(ref_path) as ref: with h5py.File(res_path, 'r') as res: for k in ref.keys(): if k == 'description': self.assertEqual(ref[k].value, res[k].value) else: self.compare_arrays(ref[k].value, res[k].value, tol=tol)
def test_use_output_directory_custom(self): sim = self.init_simple_simulation() sim.use_output_directory('custom_dir') sim.run(mp.at_end(mp.output_efield_z), until=200) output_dir = 'custom_dir' self.assertTrue(os.path.exists(os.path.join(output_dir, self.fname))) mp.all_wait() if mp.am_master(): shutil.rmtree(output_dir)
def test_use_output_directory_default(self): sim = self.init_simple_simulation() output_dir = os.path.join(temp_dir, 'simulation-out') sim.use_output_directory(output_dir) sim.run(mp.at_end(mp.output_efield_z), until=200) self.assertTrue(os.path.exists(os.path.join(output_dir, self.fname))) mp.all_wait() if mp.am_master(): shutil.rmtree(output_dir)
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 test_load_dump_structure(self): resolution = 10 cell = mp.Vector3(10, 10) pml_layers = mp.PML(1.0) fcen = 1.0 df = 1.0 sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), center=mp.Vector3(), component=mp.Hz) geometry = mp.Cylinder(0.2, material=mp.Medium(index=3)) sim = mp.Simulation(resolution=resolution, cell_size=cell, default_material=mp.Medium(index=1), geometry=[geometry], boundary_layers=[pml_layers], sources=[sources]) sim.run(until=200) ref_field = sim.get_field_point(mp.Hz, mp.Vector3(z=2)) dump_fn = 'test_load_dump_structure.h5' sim.dump_structure(dump_fn) sim = mp.Simulation(resolution=resolution, cell_size=cell, default_material=mp.Medium(index=1), geometry=[], boundary_layers=[pml_layers], sources=[sources], load_structure=dump_fn) sim.run(until=200) field = sim.get_field_point(mp.Hz, mp.Vector3(z=2)) self.assertAlmostEqual(ref_field, field) mp.all_wait() if mp.am_master(): os.remove(dump_fn)
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 = 'test_load_dump_structure.h5' dump_chunk_fname = None chunk_layout = None sim1.dump_structure(dump_fn) if chunk_file: dump_chunk_fname = '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) mp.all_wait() if mp.am_master(): os.remove(dump_fn) if dump_chunk_fname: os.remove(dump_chunk_fname)
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 = 'test_load_dump_structure.h5' dump_chunk_fname = None chunk_layout = None sim1.dump_structure(dump_fn) if chunk_file: dump_chunk_fname = '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) mp.all_wait() if mp.am_master(): os.remove(dump_fn) if dump_chunk_fname: os.remove(dump_chunk_fname)
def rm_h5(): mp.all_wait() if mp.am_master(): for f in glob.glob("{}*.h5".format(self.filename_prefix)): os.remove(f)
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'] }