Beispiel #1
0
def plot_spectrum(sys):
    """
    Plot the High Harmonic Generation spectrum
    """
    # Power spectrum emitted is calculated using the Larmor formula
    #   (https://en.wikipedia.org/wiki/Larmor_formula)
    # which says that the power emitted is proportional to the square of the acceleration
    # i.e., the RHS of the second Ehrenfest theorem

    N = len(sys.P_average_RHS)
    k = np.arange(N)

    # frequency range
    omegas = (k - N / 2) * np.pi / (0.5 * sys.t)

    # spectra of the
    spectrum = np.abs(
        # used windows fourier transform to calculate the spectra
        # rhttp://docs.scipy.org/doc/scipy/reference/tutorial/fftpack.html
        fftpack.fft((-1)**k * blackman(N) * sys.P_average_RHS))**2
    spectrum /= spectrum.max()

    plt.semilogy(omegas / sys.omega_laser, spectrum)
    plt.ylabel('spectrum (arbitrary units)')
    plt.xlabel('frequency / $\\omega_L$')
    plt.xlim([0, 45.])
    plt.ylim([1e-15, 1.])
    def test_propagation(sys, t_final):
        """
        Run tests for the specified propagators and plot the probability density
        of the time dependent propagation
        :param sys: class that propagates
        """
        iterations = 748
        steps = int(np.ceil(t_final / sys.dt / iterations))

        # display the propagator
        plt.imshow(
            [np.abs(sys.propagate(steps))**2 for _ in range(iterations)],
            origin='lower',
            norm=LogNorm(vmin=1e-12, vmax=0.1),
            aspect=0.4,  # image aspect ratio
            extent=[sys.x.min(), sys.x.max(), 0., sys.t])
        plt.xlabel('coordinate $x$ (a.u.)')
        plt.ylabel('time $t$ (a.u.)')
        plt.colorbar()
Beispiel #3
0
def test_propagation(sys):
    """
    Run tests for the specified propagators and plot the probability density
    of the time dependent propagation
    :param sys: class that propagates
    """
    # Set the ground state wavefunction as the initial condition
    sys.get_stationary_states(1)
    sys.set_wavefunction(sys.stationary_states[0])

    iterations = 748
    steps = int(round(sys.t_final / sys.dt / iterations))

    # display the propagator
    plt.imshow(
        [np.abs(sys.propagate(steps))**2 for _ in xrange(iterations)],
        origin='lower',
        norm=LogNorm(vmin=1e-12, vmax=0.1),
        aspect=0.4,  # image aspect ratio
        extent=[sys.X.min(), sys.X.max(), 0., sys.t])
    plt.xlabel('coordinate $x$ (a.u.)')
    plt.ylabel('time $t$ (a.u.)')
    plt.colorbar()
    def get_hhg_spectrum(F,
                         omega_0=0.06,
                         omega_1=0.12,
                         omega_2=0.18,
                         data=np.zeros(10),
                         get_omega=False,
                         test_mode=False):
        """
        Evaluate the HHG spectrum
        :param F: the amplitude of the laser field strength
        :param get_omega: boolean flag whether to return the omegas
        :param coords: tuple of data to be encoded into laser

        :return:
        """

        ####################################################################################################################
        #
        # Define parameters of an atom (a single-electron model of Ar) in the external laser field
        #
        ####################################################################################################################
        # laser field frequency
        omega_laser = omega_0
        omegas = np.linspace(omega_1, omega_2, len(data))

        # the final time of propagation (= 8 periods of laser oscillations)
        t_final = 12 * 2. * np.pi / omega_laser
        # the amplitude of grid
        x_amplitude = 300.

        # the time step
        dt = 0.05

        @njit
        def laser(t):
            """
            The strength of the laser field.
            Always add an envelop to the laser field to avoid all sorts of artifacts.
            We use a sin**2 envelope, which resembles the Blackman filter
            """
            # laser = 2*np.sin(omega_laser * t)
            laser = np.sin(omega_laser * t)
            for freq, dat in zip(omegas, data):
                laser += dat * np.sin(freq * t)
            laser *= F * np.sin(np.pi * t / t_final)**2
            return laser

        @njit
        def v(x, t=0.):
            """
            Potential energy.

            Define the  potential energy as a sum of the soft core Columb potential
            and the laser field interaction in the dipole approximation.
            """
            return -1. / np.sqrt(x**2 + 2.37) + x * laser(t)

        @njit
        def diff_v(x, t=0.):
            """
            the derivative of the potential energy
            """
            return x * (x**2 + 2.37)**(-1.5) + laser(t)

        @njit
        def k(p, t=0.):
            """
            Non-relativistic kinetic energy
            """
            return 0.5 * p**2

        @njit
        def diff_k(p, t=0.):
            """
            the derivative of the kinetic energy for Ehrenfest theorem evaluation
            """
            return p

        @njit
        def abs_boundary(x):
            """
            Absorbing boundary similar to the Blackman filter
            """
            return np.sin(0.5 * np.pi * (x + x_amplitude) /
                          x_amplitude)**(0.05 * dt)

        sys_params = dict(
            dt=dt,
            x_grid_dim=2 * 1024,
            x_amplitude=x_amplitude,
            k=k,
            diff_k=diff_k,
            v=v,
            diff_v=diff_v,
            abs_boundary=abs_boundary,
        )

        ####################################################################################################################
        #
        # propagate
        #
        ####################################################################################################################

        sys = ImgTimePropagation(**sys_params)

        # Set the ground state wavefunction as the initial condition
        sys.get_stationary_states(1)
        sys.set_wavefunction(sys.stationary_states[0])

        if test_mode:
            plt.title("No absorbing boundary, $|\\Psi(x, t)|^2$")
            test_propagation(sys, t_final)
            plt.show()

            plt.subplot(121)
            print("\nError in the first Ehrenfest relation: ")
            test_Ehrenfest1(sys)

            plt.subplot(122)
            print("\nError in the second Ehrenfest relation: ")
            test_Ehrenfest2(sys)

            plt.show()
        else:
            steps = int(np.ceil(t_final / sys.dt))
            sys.propagate(steps)
            print("F = {} Completed!".format(F))

        ####################################################################################################################
        #
        # Evaluate the spectrum
        #
        ####################################################################################################################

        # N = len(sys.x_average)
        # k = np.arange(N)
        #
        # # frequency range
        # omega = (k - N / 2) * np.pi / (0.5 * sys.t)
        #
        # # spectra of the
        # spectrum = np.abs(
        #     # used windows fourier transform to calculate the spectra
        #     # rhttp://docs.scipy.org/doc/scipy/reference/tutorial/fftpack.html
        #     fftpack.fft((-1) ** k * blackman(N) * sys.x_average)
        # ) ** 2
        # spectrum /= spectrum.max()

        N = len(sys.p_average_rhs)
        k = np.arange(N)

        # generate the desired momentum grid
        omega_amplitude = 2.

        domega = 2. * omega_amplitude / N
        omega = (k - N / 2) * domega

        delta = sys.dt * domega / (2. * np.pi)

        spectrum = np.abs(
            frft(
                blackman(N) * sys.p_average_rhs *
                np.exp(np.pi * 1j * k * N * delta), delta))**2
        spectrum /= spectrum.max()

        return (spectrum, omega / omega_laser) if get_omega else spectrum