def grid(): grid = fdtd.Grid( shape=(10, 10, 10), grid_spacing=100e-9, permittivity=1.0, permeability=1.0, courant_number=None, # calculate the courant number ) return grid
E = np.exp(1j * (w_0 * t + M * np.sin(w_m * t))) # E = np.exp(1j*(w_0*t)) # plt.plot(t, np.abs(E)**2) plt.figure(1) plt.plot(t, E.real) plt.figure(2) plt.plot(np.fft.fft(E.real)) #%% import fdtd grid = fdtd.Grid( shape=(25e-6, 15e-6, 1), # 25um x 15um x 1 (grid_spacing) --> 2D FDTD ) print(grid) grid[11:32, 30:84, 0] = fdtd.Object(permittivity=1.7**2, name="object") grid[13e-6:18e-6, 5e-6:8e-6, 0] = fdtd.Object(permittivity=1.5**2) grid[7.5e-6:8.0e-6, 11.8e-6:13.0e-6, 0] = fdtd.LineSource(period=1550e-9 / (3e8), name="source") grid[12e-6, :, 0] = fdtd.LineDetector(name="detector") # x boundaries grid[0:10, :, :] = fdtd.PML(name="pml_xlow") grid[-10:, :, :] = fdtd.PML(name="pml_xhigh")
def create_patch_antenna(normalized_probe_position): # [Samaras 2004] # Probe fed microstrip antenna # probe in middle and translated along X # designed f = 2.3 GHz, # excited with gaussian pulse # centered at 2.3 GHz, harmonics up to 4 GHz # 6-layer thick PML # A non-uniform grid was used in the Samaras' model. # The maximum cell size was 2 mm. # other tests should be physically smaller if possible; # performance limitation here seems to be # the discretization size, not the timestep border_cells = 6 patch_width = 59.4e-3 # m patch_length = 40.4e-3 # m substrate_thickness = 1.27e-3 # m dielectric_constant = 2.42 # m loss_tangent = 0.0019 # N_substrate_cells = 3 spacing = substrate_thickness / N_substrate_cells # 1 / (((1.27e-3 / 10) meters) / c) ≈ 100x f, A-ok Nx = int(patch_width/spacing)+(2*border_cells) Ny = int(patch_length/spacing)+(2*border_cells) Nz = int(substrate_thickness/spacing)+(2*border_cells) + 2 # finite thickness of copper planes grid = fdtd.Grid( shape=(Nx, Ny, Nz), grid_spacing=spacing, permittivity=1.0, permeability=1.0, courant_number=None, # calculate the courant number ) pulse_fwhm = 2.3e-9 simulation_steps = int(5 * (pulse_fwhm / grid.time_step)) pulse_center_time = (simulation_steps * grid.time_step) / 5.0 DomainBorderPML(grid, border_cells=border_cells) sl = slice(border_cells, -border_cells) copper_object = AbsorbingObject(permittivity=1.0, conductivity=1e8) grid[sl, sl, border_cells:border_cells+1] = copper_object # ground plane bottom_copper_plane = border_cells top_copper_plane = (border_cells+1+N_substrate_cells) grid[sl, sl, top_copper_plane:top_copper_plane+1] = copper_object #top plane probe_Nx = int(patch_width/spacing)//2 + border_cells probe_Ny = int(normalized_probe_position*(int(patch_length/spacing)//2)) + border_cells times = np.arange(0,simulation_steps) * grid.time_step waveform_array = normalized_gaussian_pulse(times, pulse_fwhm, center=pulse_center_time) source = SoftArbitraryPointSource(waveform_array=waveform_array, impedance=50.0) grid[probe_Nx,probe_Ny,border_cells+1] = source grid[probe_Nx:probe_Nx+1, probe_Ny:probe_Ny+1, border_cells+2:top_copper_plane+1] = copper_object # probe feed via substrate = Object(permittivity=dielectric_constant) grid[border_cells:probe_Nx, sl, bottom_copper_plane+1:top_copper_plane] = substrate grid[probe_Nx+1:-border_cells, sl, bottom_copper_plane+1:top_copper_plane] = substrate grid[sl, border_cells:probe_Ny, bottom_copper_plane+1:top_copper_plane] = substrate grid[sl, probe_Ny+1:-border_cells, bottom_copper_plane+1:top_copper_plane] = substrate # don't overlap with the source port! return grid, source, simulation_steps
## Set Backend fdtd.set_backend("numpy") ## Constants WAVELENGTH = 1550e-9 SPEED_LIGHT: float = 299_792_458.0 # [m/s] speed of light ## Simulation # create FDTD Grid grid = fdtd.Grid( (2.5e-5, 1.5e-5, 1), grid_spacing=0.1 * WAVELENGTH, permittivity=1.0, permeability=1.0, ) # sources grid[50:55, 70:75, 0] = fdtd.LineSource( period=WAVELENGTH / SPEED_LIGHT, name="linesource" ) grid[100, 60, 0] = fdtd.PointSource( period=WAVELENGTH / SPEED_LIGHT, name="pointsource", ) # detectors grid[12e-6, :, 0] = fdtd.LineDetector(name="detector") # x boundaries
def test_default_courant_number_3d(): grid = fdtd.Grid(shape=(3, 3, 3)) assert grid.courant_number == pytest.approx((1.0 / 3.0) ** 0.5, rel=0.02)
def test_default_courant_number_1d(): grid = fdtd.Grid(shape=(3, 1, 1)) assert grid.courant_number == pytest.approx(1.0, rel=0.02)
def test_grid_shape_mix_of_floats_and_ints(): grid = fdtd.Grid(shape=(10.0e-9, 10.0e-9, 3), grid_spacing=5.0e-9) assert (grid.Nx, grid.Ny, grid.Nz) == (2, 2, 3)
def test_grid_shape_of_ints(): grid = fdtd.Grid(shape=(3, 3, 3)) assert (grid.Nx, grid.Ny, grid.Nz) == (3, 3, 3)
fdtd.set_backend("numpy") ## Constants WAVELENGTH = 1550e-9 SPEED_LIGHT: float = 299_792_458.0 # [m/s] speed of light ## Grid setup # create FDTD Grid grid = fdtd.Grid( (1.5e-5, 1.5e-5, 1), # 2D grid grid_spacing=0.1 * WAVELENGTH, permittivity=2.5, # same as object ) # sources grid[15, :] = fdtd.LineSource(period=WAVELENGTH / SPEED_LIGHT, name="source") # detectors grid[-15, :, 0] = fdtd.LineDetector(name="detector") # x boundaries # grid[0, :, :] = fdtd.PeriodicBoundary(name="xbounds") grid[0:10, :, :] = fdtd.PML(name="pml_xlow") grid[-10:, :, :] = fdtd.PML(name="pml_xhigh") # y boundaries