diff --git a/docs/source/input.rst b/docs/source/input.rst index 96ff9a0c..ecf14276 100644 --- a/docs/source/input.rst +++ b/docs/source/input.rst @@ -661,6 +661,8 @@ Allows you to specify waveforms to use with sources in the model. The syntax of * ``gaussiandotdot`` which is the second derivative of a Gaussian waveform. * ``gaussiandotdotnorm`` which is the normalised second derivative of a Gaussian waveform. * ``ricker`` which is a Ricker (or Mexican hat) waveform, i.e. the negative, normalised second derivative of a Gaussian waveform. + * ``gaussianprime`` which is the first derivative of a Gaussian waveform, directly derived from the aforementioned ``gaussian`` (see notes below). + * ``gaussiandoubleprime`` which is the second derivative of a Gaussian waveform, directly derived from the aforementioned ``gaussian`` (see notes below). * ``sine`` which is a single cycle of a sine waveform. * ``contsine`` which is a continuous sine waveform. In order to avoid introducing noise into the calculation the amplitude of the waveform is modulated for the first cycle of the sine wave (ramp excitation). * ``f1`` is the scaling of the maximum amplitude of the waveform (for a ``#hertzian_dipole`` the units will be Amps, for a ``#voltage_source`` or ``#transmission_line`` the units will be Volts). @@ -672,6 +674,9 @@ For example, to specify the normalised first derivate of a Gaussian waveform wit .. note:: * The functions used to create the waveforms can be found in the :ref:`tools section `. + * ``gaussiandot``, ``gaussiandotnorm``, ``gaussiandotdot``, ``gaussiandotdotnorm``, ``ricker`` waveforms have their centre frequencies specified by the user, i.e. they are not derived to the 'base' ``gaussian`` + * ``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. + #excitation_file: ----------------- diff --git a/gprMax/waveforms.py b/gprMax/waveforms.py index f6bff0f6..c89dfc46 100644 --- a/gprMax/waveforms.py +++ b/gprMax/waveforms.py @@ -24,7 +24,15 @@ from gprMax.utilities import round_value class Waveform(object): """Definitions of waveform shapes that can be used with sources.""" - types = ['gaussian', 'gaussiandot', 'gaussiandotnorm', 'gaussiandotdot', 'gaussiandotdotnorm', 'ricker', 'sine', 'contsine', 'impulse', 'user'] + 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 @@ -44,8 +52,8 @@ class Waveform(object): ampvalue (float): Calculated value for waveform. """ - # Coefficients for certain waveforms - if self.type == 'gaussian' or self.type == 'gaussiandot' or self.type == 'gaussiandotnorm': + # Coefficients for specific waveforms + if self.type == 'gaussian' or self.type == 'gaussiandot' or self.type == 'gaussiandotnorm' or self.type == 'gaussianprime' or self.type == 'gaussiandoubleprime': chi = 1 / self.freq zeta = 2 * np.pi**2 * self.freq**2 delay = time - chi @@ -58,14 +66,14 @@ class Waveform(object): if self.type == 'gaussian': ampvalue = np.exp(-zeta * delay**2) - elif self.type == 'gaussiandot': + elif self.type == 'gaussiandot' or self.type == 'gaussianprime': ampvalue = -2 * zeta * delay * np.exp(-zeta * delay**2) elif self.type == 'gaussiandotnorm': normalise = np.sqrt(np.exp(1) / (2 * zeta)) ampvalue = -2 * zeta * delay * np.exp(-zeta * delay**2) * normalise - elif self.type == 'gaussiandotdot': + elif self.type == 'gaussiandotdot' or self.type == 'gaussiandoubleprime': ampvalue = 2 * zeta * (2 * zeta * delay**2 - 1) * np.exp(-zeta * delay**2) elif self.type == 'gaussiandotdotnorm': diff --git a/tests/analytical_solutions.py b/tests/analytical_solutions.py index 84028abe..77d27f3b 100644 --- a/tests/analytical_solutions.py +++ b/tests/analytical_solutions.py @@ -19,7 +19,7 @@ def hertzian_dipole_fs(iterations, dt, dxdydz, rx): # Waveform w = Waveform() - w.type = 'gaussiandot' + w.type = 'gaussianprime' w.amp = 1 w.freq = 1e9 @@ -31,7 +31,7 @@ def hertzian_dipole_fs(iterations, dt, dxdydz, rx): # Waveform first derivative wdot = Waveform() - wdot.type = 'gaussiandotdot' + wdot.type = 'gaussiandoubleprime' wdot.amp = w.amp wdot.freq = w.freq diff --git a/tools/plot_source_wave.py b/tools/plot_source_wave.py index 4e84f6c0..8959a099 100644 --- a/tools/plot_source_wave.py +++ b/tools/plot_source_wave.py @@ -95,7 +95,7 @@ def mpl_plot(w, timewindow, dt, iterations, fft=False): if w.freq and not w.type == 'gaussian': print('Centre frequency: {:g} Hz'.format(w.freq)) - if w.type == 'gaussian' or w.type == 'gaussiandot' or w.type == 'gaussiandotnorm': + if w.type == 'gaussian' or w.type == 'gaussiandot' or w.type == 'gaussiandotnorm' or w.type == 'gaussianprime' or w.type == 'gaussiandoubleprime': delay = 1 / w.freq print('Time to centre of pulse: {:g} s'.format(delay)) elif w.type == 'gaussiandotdot' or w.type == 'gaussiandotdotnorm' or w.type == 'ricker':