parser.add_argument('dt', type=float, help='time step to view waveform') args = parser.parse_args() w = Waveform() w.type = args.type w.amp = args.amp w.freq = args.freq timewindow = args.timewindow dt = args.dt time = np.arange(0, timewindow, dt) waveform = np.zeros(len(time)) timeiter = np.nditer(time, flags=['c_index']) while not timeiter.finished: waveform[timeiter.index] = w.calculate_value(timeiter[0], dt) timeiter.iternext() # Calculate frequency spectra of waveform power = 20 * np.log10(np.abs(np.fft.fft(waveform))**2) f = np.fft.fftfreq(power.size, d=dt) # Shift powers so any spectra with negative DC component will start at zero power -= np.amax(power) # Set plotting range to 4 * centre frequency pltrange = np.where(f > (4 * w.freq))[0][0] # Plot waveform fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, num=w.type, figsize=(20, 10), facecolor='w', edgecolor='w') ax1.plot(time, waveform, 'r', lw=2)
def hertzian_dipole_fs(iterations, dt, dxdydz, rx): """Analytical solution of a z-directed Hertzian dipole in free space with a Gaussian current waveform (http://dx.doi.org/10.1016/0021-9991(83)90103-1). Args: iterations (int): Number of time steps. dt (float): Time step (seconds). dxdydz (float): Tuple of spatial resolution (metres). rx (float): Tuple of coordinates of receiver position relative to transmitter position (metres). Returns: fields (float): Array contain electric and magnetic field components. """ # Waveform w = Waveform() w.type = 'gaussiandot' w.amp = 1 w.freq = 1e9 # Waveform integral wint = Waveform() wint.type = 'gaussian' wint.amp = w.amp wint.freq = w.freq # Waveform first derivative wdot = Waveform() wdot.type = 'gaussiandotdot' wdot.amp = w.amp wdot.freq = w.freq # Time time = np.linspace(0, 1, iterations) time *= (iterations * dt) # Spatial resolution dx = dxdydz[0] dy = dxdydz[1] dz = dxdydz[2] # Coordinates of Rx relative to Tx x = rx[0] y = rx[1] z = rx[2] if z == 0: sign_z = 1 else: sign_z = np.sign(z) # Coordinates of Rx for Ex FDTD component Ex_x = x + 0.5 * dx Ex_y = y Ex_z = z - 0.5 * dz Er_x = np.sqrt((Ex_x**2 + Ex_y**2 + Ex_z**2)) tau_Ex = Er_x / c # Coordinates of Rx for Ey FDTD component Ey_x = x Ey_y = y + 0.5 * dy Ey_z = z - 0.5 * dz Er_y = np.sqrt((Ey_x**2 + Ey_y**2 + Ey_z**2)) tau_Ey = Er_y / c # Coordinates of Rx for Ez FDTD component Ez_x = x Ez_y = y Ez_z = z Er_z = np.sqrt((Ez_x**2 + Ez_y**2 + Ez_z**2)) tau_Ez = Er_z / c # Coordinates of Rx for Hx FDTD component Hx_x = x Hx_y = y + 0.5 * dy Hx_z = z Hr_x = np.sqrt((Hx_x**2 + Hx_y**2 + Hx_z**2)) tau_Hx = Hr_x / c # Coordinates of Rx for Hy FDTD component Hy_x = x + 0.5 * dx Hy_y = y Hy_z = z Hr_y = np.sqrt((Hy_x**2 + Hy_y**2 + Hy_z**2)) tau_Hy = Hr_y / c # Coordinates of Rx for Hz FDTD component Hz_x = x + 0.5 * dx Hz_y = y + 0.5 * dy Hz_z = z - 0.5 * dz Hr_z = np.sqrt((Hz_x**2 + Hz_y**2 + Hz_z**2)) tau_Hz = Hr_z / c # Initialise fields fields = np.zeros((iterations, 6)) # Calculate fields for timestep in range(iterations): # Calculate values for waveform fint_Ex = wint.calculate_value((timestep * dt) - tau_Ex, dt) * dx f_Ex = w.calculate_value((timestep * dt) - tau_Ex, dt) * dx fdot_Ex = wdot.calculate_value((timestep * dt) - tau_Ex, dt) * dx fint_Ey = wint.calculate_value((timestep * dt) - tau_Ey, dt) * dy f_Ey = w.calculate_value((timestep * dt) - tau_Ey, dt) * dy fdot_Ey = wdot.calculate_value((timestep * dt) - tau_Ey, dt) * dy fint_Ez = wint.calculate_value((timestep * dt) - tau_Ez, dt) * dz f_Ez = w.calculate_value((timestep * dt) - tau_Ez, dt) * dz fdot_Ez = wdot.calculate_value((timestep * dt) - tau_Ez, dt) * dz fint_Hx = wint.calculate_value((timestep * dt) - tau_Hx, dt) * dx f_Hx = w.calculate_value((timestep * dt) - tau_Hx, dt) * dx fdot_Hx = wdot.calculate_value((timestep * dt) - tau_Hx, dt) * dx fint_Hy = wint.calculate_value((timestep * dt) - tau_Hy, dt) * dy f_Hy = w.calculate_value((timestep * dt) - tau_Hy, dt) * dy fdot_Hy = wdot.calculate_value((timestep * dt) - tau_Hy, dt) * dy fint_Hz = wint.calculate_value((timestep * dt) - tau_Hz, dt) * dz f_Hz = w.calculate_value((timestep * dt) - tau_Hz, dt) * dz fdot_Hz = wdot.calculate_value((timestep * dt) - tau_Hz, dt) * dz # Ex fields[timestep, 0] = ((Ex_x * Ex_z) / (4 * np.pi * e0 * Er_x**5)) * (3 * (fint_Ex + (tau_Ex * f_Ex)) + (tau_Ex**2 * fdot_Ex)) # Ey try: tmp = Ey_y / Ey_x except ZeroDivisionError: tmp = 0 fields[timestep, 1] = tmp * ( (Ey_x * Ey_z) / (4 * np.pi * e0 * Er_y**5)) * (3 * (fint_Ey + (tau_Ey * f_Ey)) + (tau_Ey**2 * fdot_Ey)) # Ez fields[timestep, 2] = (1 / (4 * np.pi * e0 * Er_z**5)) * ( (2 * Ez_z**2 - (Ez_x**2 + Ez_y**2)) * (fint_Ez + (tau_Ez * f_Ez)) - (Ez_x**2 + Ez_y**2) * tau_Ez**2 * fdot_Ez) # Hx fields[timestep, 3] = -(Hx_y / (4 * np.pi * Hr_x**3)) * (f_Hx + (tau_Hx * fdot_Hx)) # Hy try: tmp = Hy_x / Hy_y except ZeroDivisionError: tmp = 0 fields[timestep, 4] = -tmp * (-(Hy_y / (4 * np.pi * Hr_y**3)) * (f_Hy + (tau_Hy * fdot_Hy))) # Hz fields[timestep, 5] = 0 return fields
def hertzian_dipole_fs(iterations, dt, dxdydz, rx): """Analytical solution of a z-directed Hertzian dipole in free space with a Gaussian current waveform (http://dx.doi.org/10.1016/0021-9991(83)90103-1). Args: iterations (int): Number of time steps. dt (float): Time step (seconds). dxdydz (float): Tuple of spatial resolution (metres). rx (float): Tuple of coordinates of receiver position relative to transmitter position (metres). Returns: fields (float): Array contain electric and magnetic field components. """ # Waveform w = Waveform() w.type = 'gaussiandot' w.amp = 1 w.freq = 1e9 # Waveform integral wint = Waveform() wint.type = 'gaussian' wint.amp = w.amp wint.freq = w.freq # Waveform first derivative wdot = Waveform() wdot.type = 'gaussiandotdot' wdot.amp = w.amp wdot.freq = w.freq # Time time = np.linspace(0, 1, iterations) time *= (iterations * dt) # Spatial resolution dx = dxdydz[0] dy = dxdydz[1] dz = dxdydz[2] # Length of Hertzian dipole dl = dz # Coordinates of Rx relative to Tx x = rx[0] y = rx[1] z = rx[2] if z == 0: sign_z = 1 else: sign_z = np.sign(z) # Coordinates of Rx for Ex FDTD component Ex_x = x + 0.5 * dx Ex_y = y Ex_z = z - 0.5 * dz Er_x = np.sqrt((Ex_x**2 + Ex_y**2 + Ex_z**2)) tau_Ex = Er_x / c # Coordinates of Rx for Ey FDTD component Ey_x = x Ey_y = y + 0.5 * dy Ey_z = z - 0.5 * dz Er_y = np.sqrt((Ey_x**2 + Ey_y**2 + Ey_z**2)) tau_Ey = Er_y / c # Coordinates of Rx for Ez FDTD component Ez_x = x Ez_y = y Ez_z = z Er_z = np.sqrt((Ez_x**2 + Ez_y**2 + Ez_z**2)) tau_Ez = Er_z / c # Coordinates of Rx for Hx FDTD component Hx_x = x Hx_y = y + 0.5 * dy Hx_z = z Hr_x = np.sqrt((Hx_x**2 + Hx_y**2 + Hx_z**2)) tau_Hx = Hr_x / c # Coordinates of Rx for Hy FDTD component Hy_x = x + 0.5 * dx Hy_y = y Hy_z = z Hr_y = np.sqrt((Hy_x**2 + Hy_y**2 + Hy_z**2)) tau_Hy = Hr_y / c # Coordinates of Rx for Hz FDTD component Hz_x = x + 0.5 * dx Hz_y = y + 0.5 * dy Hz_z = z - 0.5 * dz Hr_z = np.sqrt((Hz_x**2 + Hz_y**2 + Hz_z**2)) tau_Hz = Hr_z / c # Initialise fields fields = np.zeros((iterations, 6)) # Calculate fields for timestep in range(iterations): # Calculate values for waveform, I * dl (current multiplied by dipole length) to match gprMax behaviour fint_Ex = wint.calculate_value((timestep * dt) - tau_Ex, dt) * dl f_Ex = w.calculate_value((timestep * dt) - tau_Ex, dt) * dl fdot_Ex = wdot.calculate_value((timestep * dt) - tau_Ex, dt) * dl fint_Ey = wint.calculate_value((timestep * dt) - tau_Ey, dt) * dl f_Ey= w.calculate_value((timestep * dt) - tau_Ey, dt) * dl fdot_Ey = wdot.calculate_value((timestep * dt) - tau_Ey, dt) * dl fint_Ez = wint.calculate_value((timestep * dt) - tau_Ez, dt) * dl f_Ez = w.calculate_value((timestep * dt) - tau_Ez, dt) * dl fdot_Ez = wdot.calculate_value((timestep * dt) - tau_Ez, dt) * dl fint_Hx = wint.calculate_value((timestep * dt) - tau_Hx, dt) * dl f_Hx = w.calculate_value((timestep * dt) - tau_Hx, dt) * dl fdot_Hx = wdot.calculate_value((timestep * dt) - tau_Hx, dt) * dl fint_Hy = wint.calculate_value((timestep * dt) - tau_Hy, dt) * dl f_Hy= w.calculate_value((timestep * dt) - tau_Hy, dt) * dl fdot_Hy = wdot.calculate_value((timestep * dt) - tau_Hy, dt) * dl fint_Hz = wint.calculate_value((timestep * dt) - tau_Hz, dt) * dl f_Hz = w.calculate_value((timestep * dt) - tau_Hz, dt) * dl fdot_Hz = wdot.calculate_value((timestep * dt) - tau_Hz, dt) * dl # Ex fields[timestep, 0] = ((Ex_x * Ex_z) / (4 * np.pi * e0 * Er_x**5)) * (3 * (fint_Ex + (tau_Ex * f_Ex)) + (tau_Ex**2 * fdot_Ex)) # Ey try: tmp = Ey_y / Ey_x except ZeroDivisionError: tmp = 0 fields[timestep, 1] = tmp * ((Ey_x * Ey_z) / (4 * np.pi * e0 * Er_y**5)) * (3 * (fint_Ey + (tau_Ey * f_Ey)) + (tau_Ey**2 * fdot_Ey)) # Ez fields[timestep, 2] = (1 / (4 * np.pi * e0 * Er_z**5)) * ((2 * Ez_z**2 - (Ez_x**2 + Ez_y**2)) * (fint_Ez + (tau_Ez * f_Ez)) - (Ez_x**2 + Ez_y**2) * tau_Ez**2 * fdot_Ez) # Hx fields[timestep, 3] = - (Hx_y / (4 * np.pi * Hr_x**3)) * (f_Hx + (tau_Hx * fdot_Hx)) # Hy try: tmp = Hy_x / Hy_y except ZeroDivisionError: tmp = 0 fields[timestep, 4] = - tmp * (- (Hy_y / (4 * np.pi * Hr_y**3)) * (f_Hy + (tau_Hy * fdot_Hy))) # Hz fields[timestep, 5] = 0 return fields
timewindow = float(args.timewindow) iterations = round_value((float(args.timewindow) / dt)) + 1 else: raise CmdInputError('Time window must have a value greater than zero') # If number of iterations given else: timewindow = (int(args.timewindow) - 1) * dt iterations = int(args.timewindow) time = np.linspace(0, 1, iterations) time *= (iterations * dt) waveform = np.zeros(len(time)) timeiter = np.nditer(time, flags=['c_index']) while not timeiter.finished: waveform[timeiter.index] = w.calculate_value(timeiter[0], dt) timeiter.iternext() print('Waveform characteristics...') print('Type: {}'.format(w.type)) print('Amplitude: {:g}'.format(w.amp)) print('Centre frequency: {:g} Hz'.format(w.freq)) print('Time to centre of pulse: {:g} s'.format(1 / w.freq)) # Calculate pulse width for gaussian if w.type == 'gaussian': powerdrop = -3 #dB start = np.where( (10 * np.log10(waveform / np.amax(waveform))) > powerdrop)[0][0] stop = np.where((10 * np.log10(waveform[start:] / np.amax(waveform)) ) < powerdrop)[0][0] + start