def test_custom_em_source(self): resolution = 20 dpml = 2 pml_layers = [mp.PML(thickness=dpml)] sx = 40 sy = 12 cell_size = mp.Vector3(sx + 2 * dpml, sy) v0 = 0.15 # pulse center frequency a = 0.2 * v0 # Gaussian envelope half-width b = -0.1 # 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) geometry = [ mp.Block(center=mp.Vector3(0, 0, 0), size=mp.Vector3(mp.inf, 1, mp.inf), material=mp.Medium(epsilon=12)) ] kx = 0.4 # initial guess for wavevector in x-direction of eigenmode kpoint = mp.Vector3(kx) bnum = 1 sources = [ mp.EigenModeSource(src=mp.CustomSource(src_func=chirp, center_frequency=v0), center=mp.Vector3(-0.5 * sx + dpml + 1), size=mp.Vector3(y=sy), eig_kpoint=kpoint, eig_band=bnum, eig_parity=mp.EVEN_Y + mp.ODD_Z, eig_match_freq=True) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, resolution=resolution, k_point=mp.Vector3(), sources=sources, geometry=geometry, symmetries=[mp.Mirror(mp.Y)]) t = np.linspace(0, 50, 1000) sim.run(until=t0 + 50)
def test_custom_source(self): n = 3.4 w = 1 r = 1 pad = 4 dpml = 2 sxy = 2 * (r + w + pad + dpml) cell = mp.Vector3(sxy, sxy) geometry = [ mp.Cylinder(r + w, material=mp.Medium(index=n)), mp.Cylinder(r, material=mp.air) ] boundary_layers = [mp.PML(dpml)] resolution = 10 fcen = 0.15 df = 0.1 # Bump function def my_src_func(t): if t > 0 and t < 2: return math.exp(-1 / (1 - ((t - 1)**2))) return 0j sources = [ mp.Source(src=mp.CustomSource(src_func=my_src_func, end_time=100), component=mp.Ez, center=mp.Vector3(r + 0.1)) ] symmetries = [mp.Mirror(mp.Y)] sim = mp.Simulation(cell_size=cell, resolution=resolution, geometry=geometry, boundary_layers=boundary_layers, sources=sources, symmetries=symmetries) h = mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) fp = sim.get_field_point(mp.Ez, mp.Vector3(1)) self.assertAlmostEqual(fp, -0.021997617628500023 + 0j)
def compute_flux(m=1, n=0): if m == 1: sources = [] for n in range(ndipole): sources.append( mp.Source( mp.CustomSource(src_func=lambda t: np.random.randn()), component=mp.Ez, center=mp.Vector3(sx * (-0.5 + n / ndipole), -0.5 * sy + dAg + 0.5 * dsub))) else: sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(sx * (-0.5 + n / ndipole), -0.5 * sy + dAg + 0.5 * dsub)) ] sim = mp.Simulation(cell_size=cell_size, resolution=resolution, k_point=mp.Vector3(), boundary_layers=pml_layers, geometry=geometry, sources=sources) flux_mon = sim.add_flux( fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0, 0.5 * sy - dpml), size=mp.Vector3(sx))) sim.run(until=run_time) flux = mp.get_fluxes(flux_mon) freqs = mp.get_flux_freqs(flux_mon) return freqs, flux
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)
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)
f150 = 150 * (1e-6) / cc fmin = frequency - f150 fmax = frequency + f150 resolution = 10 def fun(t): return math.cos(2 * math.pi * frequency * t) cell = mp.Vector3(12, 12, 12) pml_layers = [mp.PML(1.0)] sources = [ mp.Source(mp.CustomSource(src_func=fun, start_time=0), component=mp.Ez, center=mp.Vector3(-4, 0, 0)) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, sources=sources, resolution=resolution) freqz = sim.add_dft_fields([mp.Ez], fmin, fmax, 11, center=mp.Vector3(1, 2, 2), size=mp.Vector3(0, 2, 2))