Beispiel #1
0
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
Beispiel #3
0
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
Beispiel #4
0
        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