# Path: gprMax/constants.py

# 
# Path: gprMax/waveforms.py
# class Waveform(object):
#     """Definitions of waveform shapes that can be used with sources."""
# 
#     types = ['gaussian', 'gaussiandot', 'gaussiandotnorm', 'gaussiandotdot', 'gaussiandotdotnorm', 'gaussianprime', 'gaussiandoubleprime', 'ricker', 'sine', 'contsine', 'impulse', 'user']
# 
#     # Information about specific waveforms:
#     #
#     # gaussianprime and gaussiandoubleprime waveforms are the first derivative and second derivative of the 'base' gaussian
#     # waveform, i.e. the centre frequencies of the waveforms will rise for the first and second derivatives.
#     #
#     # gaussiandot, gaussiandotnorm, gaussiandotdot, gaussiandotdotnorm, ricker waveforms have their centre frequencies
#     # specified by the user, i.e. they are not derived from the 'base' gaussian
# 
#     def __init__(self):
#         self.ID = None
#         self.type = None
#         self.amp = 1
#         self.freq = None
#         self.userfunc = None
#         self.chi = 0
#         self.zeta = 0
#         self.delay = 0
# 
#     def calculate_coefficients(self):
#         """Calculates coefficients (used to calculate values) for specific waveforms."""
# 
#         if self.type == 'gaussian' or self.type == 'gaussiandot' or self.type == 'gaussiandotnorm' or self.type == 'gaussianprime' or self.type == 'gaussiandoubleprime':
#             self.chi = 1 / self.freq
#             self.zeta = 2 * np.pi**2 * self.freq**2
#         elif self.type == 'gaussiandotdot' or self.type == 'gaussiandotdotnorm' or self.type == 'ricker':
#             self.chi = np.sqrt(2) / self.freq
#             self.zeta = np.pi**2 * self.freq**2
# 
#     def calculate_value(self, time, dt):
#         """Calculates value of the waveform at a specific time.
# 
#         Args:
#             time (float): Absolute time.
#             dt (float): Absolute time discretisation.
# 
#         Returns:
#             ampvalue (float): Calculated value for waveform.
#         """
# 
#         self.calculate_coefficients()
# 
#         # Waveforms
#         if self.type == 'gaussian':
#             delay = time - self.chi
#             ampvalue = np.exp(-self.zeta * delay**2)
# 
#         elif self.type == 'gaussiandot' or self.type == 'gaussianprime':
#             delay = time - self.chi
#             ampvalue = -2 * self.zeta * delay * np.exp(-self.zeta * delay**2)
# 
#         elif self.type == 'gaussiandotnorm':
#             delay = time - self.chi
#             normalise = np.sqrt(np.exp(1) / (2 * self.zeta))
#             ampvalue = -2 * self.zeta * delay * np.exp(-self.zeta * delay**2) * normalise
# 
#         elif self.type == 'gaussiandotdot' or self.type == 'gaussiandoubleprime':
#             delay = time - self.chi
#             ampvalue = 2 * self.zeta * (2 * self.zeta * delay**2 - 1) * np.exp(-self.zeta * delay**2)
# 
#         elif self.type == 'gaussiandotdotnorm':
#             delay = time - self.chi
#             normalise = 1 / (2 * self.zeta)
#             ampvalue = 2 * self.zeta * (2 * self.zeta * delay**2 - 1) * np.exp(-self.zeta * delay**2) * normalise
# 
#         elif self.type == 'ricker':
#             delay = time - self.chi
#             normalise = 1 / (2 * self.zeta)
#             ampvalue = - (2 * self.zeta * (2 * self.zeta * delay**2 - 1) * np.exp(-self.zeta * delay**2)) * normalise
# 
#         elif self.type == 'sine':
#             ampvalue = np.sin(2 * np.pi * self.freq * time)
#             if time * self.freq > 1:
#                 ampvalue = 0
# 
#         elif self.type == 'contsine':
#             rampamp = 0.25
#             ramp = rampamp * time * self.freq
#             if ramp > 1:
#                 ramp = 1
#             ampvalue = ramp * np.sin(2 * np.pi * self.freq * time)
# 
#         elif self.type == 'impulse':
#             # time < dt condition required to do impulsive magnetic dipole
#             if time == 0 or time < dt:
#                 ampvalue = 1
#             elif time >= dt:
#                 ampvalue = 0
# 
#         elif self.type == 'user':
#             ampvalue = self.userfunc(time)
# 
#         ampvalue *= self.amp
# 
#         return ampvalue


import numpy as np
from gprMax.constants import c, e0
from gprMax.waveforms import Waveform
    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))

# Path: gprMax/constants.py

# 
# Path: gprMax/waveforms.py
# class Waveform(object):
#     """Definitions of waveform shapes that can be used with sources."""
# 
#     types = ['gaussian', 'gaussiandot', 'gaussiandotnorm', 'gaussiandotdot', 'gaussiandotdotnorm', 'gaussianprime', 'gaussiandoubleprime', 'ricker', 'sine', 'contsine', 'impulse', 'user']
# 
#     # Information about specific waveforms:
#     #
#     # gaussianprime and gaussiandoubleprime waveforms are the first derivative and second derivative of the 'base' gaussian
#     # waveform, i.e. the centre frequencies of the waveforms will rise for the first and second derivatives.
#     #
#     # gaussiandot, gaussiandotnorm, gaussiandotdot, gaussiandotdotnorm, ricker waveforms have their centre frequencies
#     # specified by the user, i.e. they are not derived from the 'base' gaussian
# 
#     def __init__(self):
#         self.ID = None
#         self.type = None
#         self.amp = 1
#         self.freq = None
#         self.userfunc = None
#         self.chi = 0
#         self.zeta = 0
#         self.delay = 0
# 
#     def calculate_coefficients(self):
#         """Calculates coefficients (used to calculate values) for specific waveforms."""
# 
#         if self.type == 'gaussian' or self.type == 'gaussiandot' or self.type == 'gaussiandotnorm' or self.type == 'gaussianprime' or self.type == 'gaussiandoubleprime':
#             self.chi = 1 / self.freq
#             self.zeta = 2 * np.pi**2 * self.freq**2
#         elif self.type == 'gaussiandotdot' or self.type == 'gaussiandotdotnorm' or self.type == 'ricker':
#             self.chi = np.sqrt(2) / self.freq
#             self.zeta = np.pi**2 * self.freq**2
# 
#     def calculate_value(self, time, dt):
#         """Calculates value of the waveform at a specific time.
# 
#         Args:
#             time (float): Absolute time.
#             dt (float): Absolute time discretisation.
# 
#         Returns:
#             ampvalue (float): Calculated value for waveform.
#         """
# 
#         self.calculate_coefficients()
# 
#         # Waveforms
#         if self.type == 'gaussian':
#             delay = time - self.chi
#             ampvalue = np.exp(-self.zeta * delay**2)
# 
#         elif self.type == 'gaussiandot' or self.type == 'gaussianprime':
#             delay = time - self.chi
#             ampvalue = -2 * self.zeta * delay * np.exp(-self.zeta * delay**2)
# 
#         elif self.type == 'gaussiandotnorm':
#             delay = time - self.chi
#             normalise = np.sqrt(np.exp(1) / (2 * self.zeta))
#             ampvalue = -2 * self.zeta * delay * np.exp(-self.zeta * delay**2) * normalise
# 
#         elif self.type == 'gaussiandotdot' or self.type == 'gaussiandoubleprime':
#             delay = time - self.chi
#             ampvalue = 2 * self.zeta * (2 * self.zeta * delay**2 - 1) * np.exp(-self.zeta * delay**2)
# 
#         elif self.type == 'gaussiandotdotnorm':
#             delay = time - self.chi
#             normalise = 1 / (2 * self.zeta)
#             ampvalue = 2 * self.zeta * (2 * self.zeta * delay**2 - 1) * np.exp(-self.zeta * delay**2) * normalise
# 
#         elif self.type == 'ricker':
#             delay = time - self.chi
#             normalise = 1 / (2 * self.zeta)
#             ampvalue = - (2 * self.zeta * (2 * self.zeta * delay**2 - 1) * np.exp(-self.zeta * delay**2)) * normalise
# 
#         elif self.type == 'sine':
#             ampvalue = np.sin(2 * np.pi * self.freq * time)
#             if time * self.freq > 1:
#                 ampvalue = 0
# 
#         elif self.type == 'contsine':
#             rampamp = 0.25
#             ramp = rampamp * time * self.freq
#             if ramp > 1:
#                 ramp = 1
#             ampvalue = ramp * np.sin(2 * np.pi * self.freq * time)
# 
#         elif self.type == 'impulse':
#             # time < dt condition required to do impulsive magnetic dipole
#             if time == 0 or time < dt:
#                 ampvalue = 1
#             elif time >= dt:
#                 ampvalue = 0
# 
#         elif self.type == 'user':
#             ampvalue = self.userfunc(time)
# 
#         ampvalue *= self.amp
# 
#         return ampvalue


# Path: tests/analytical_solutions.py
import numpy as np
from gprMax.constants import c, e0
from gprMax.waveforms import Waveform

    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