Beispiel #1
0
def driven_dynamics(ham, dip, psi0, pulse, dt=0.001, Nt=1, e_ops=None, nout=1, \
                    t0=0.0):
    '''
    Laser-driven dynamics in the presence of laser pulses

    Parameters
    ----------
    ham : 2d array
        Hamiltonian of the molecule
    dip : TYPE
        transition dipole moment
    psi0: 1d array
        initial wavefunction
    pulse : TYPE
        laser pulse
    dt : TYPE
        time step.
    Nt : TYPE
        timesteps.
    e_ops: list
        observable operators to compute
    nout: int
        Store data every nout steps

    Returns
    -------
    None.

    '''

    # initialize the density matrix
    # wf = csr_matrix(wf0).transpose()
    psi = psi0

    nstates = len(psi0)

    # f = open(fname,'w')
    fmt = '{} ' * (len(e_ops) + 1) + '\n'
    fmt_dm = '{} ' * (nstates + 1) + '\n'

    f_dm = open('psi.dat', 'w')  # wavefunction
    f_obs = open('obs.dat', 'w')  # observables

    t = t0

    # f_dip = open('dipole'+'{:f}'.format(pulse.delay * au2fs)+'.dat', 'w')

    for k1 in range(int(Nt / nout)):

        for k2 in range(nout):
            ht = pulse.field(t) * dip + ham
            psi = rk4(psi, tdse, dt, ht)

        t += dt * nout

        # compute observables
        Aave = np.zeros(len(e_ops), dtype=complex)
        for j, A in enumerate(e_ops):
            Aave[j] = obs(psi, A)

        f_dm.write(fmt_dm.format(t, *psi))
        f_obs.write(fmt.format(t, *Aave))

    f_dm.close()
    f_obs.close()

    return
Beispiel #2
0
def _ode_solver(H,
                psi0,
                dt=0.001,
                Nt=1,
                e_ops=[],
                t0=0.0,
                nout=1,
                store_states=True,
                output='obs.dat'):
    """
    Integrate the TDSE for a multilevel system using Scipy.

    Parameters
    ----------
    e_ops: list of arrays
        expectation values to compute.
    H : 2d array
        Hamiltonian of the molecule
    psi0: 1d array
        initial wavefunction
    dt : float
        time step.
    Nt : int
        timesteps.
    e_ops: list
        observable operators to compute
    nout: int
        Store data every nout steps

    Returns
    -------
    None.

    """

    psi = psi0.copy()
    t_eval = np.arange(Nt // nout) * dt * nout

    def fun(t, psi):
        return -1j * H.dot(psi)

    tf = t0 + Nt * dt
    t_span = (t0, tf)
    sol = scipy.integrate.solve_ivp(fun, t_span=t_span, y0=psi, t_eval=t_eval)

    result = Result(dt=dt, Nt=Nt, psi0=psi0)
    result.times = sol.t
    print(sol.nfev)

    observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex)
    for i in range(len(t_eval)):
        psi = sol.y[:, i]
        observables[i, :] = [obs(psi, e_op) for e_op in e_ops]

    result.observables = observables
    # if store_states:
    #
    #     result = Result(dt=dt, Nt=Nt, psi0=psi0)
    #
    #     observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex)
    #     psilist = [psi0.copy()]
    #
    #     # compute observables for t0
    #     observables[0, :] = [obs(psi, e_op) for e_op in e_ops]
    #
    #     for k1 in range(1, Nt // nout):
    #
    #         for k2 in range(nout):
    #             psi = rk4(psi, tdse, dt, H)
    #
    #         t += dt * nout
    #
    #         # compute observables
    #         observables[k1, :] = [obs(psi, e_op) for e_op in e_ops]
    #         # f_obs.write(fmt.format(t, *e_list))
    #
    #         psilist.append(psi.copy())
    #
    #     # f_obs.close()
    #
    #     result.psilist = psilist
    #     result.observables = observables

    return result
Beispiel #3
0
def _quantum_dynamics(H,
                      psi0,
                      dt=0.001,
                      Nt=1,
                      e_ops=[],
                      t0=0.0,
                      nout=1,
                      store_states=True,
                      output='obs.dat'):
    """
    Quantum dynamics for a multilevel system.

    Parameters
    ----------
    e_ops: list of arrays
        expectation values to compute.
    H : 2d array
        Hamiltonian of the molecule
    psi0: 1d array
        initial wavefunction
    dt : float
        time step.
    Nt : int
        timesteps.
    e_ops: list
        observable operators to compute
    nout: int
        Store data every nout steps

    Returns
    -------
    None.

    """

    psi = psi0

    if e_ops is not None:
        fmt = '{} ' * (len(e_ops) + 1) + '\n'

    f_obs = open(output, 'w')  # observables

    t = t0

    # f_obs.close()

    if store_states:

        result = Result(dt=dt, Nt=Nt, psi0=psi0)

        observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex)
        psilist = [psi0.copy()]

        # compute observables for t0
        observables[0, :] = [obs(psi, e_op) for e_op in e_ops]

        for k1 in range(1, Nt // nout):

            for k2 in range(nout):
                psi = rk4(psi, tdse, dt, H)

            t += dt * nout

            # compute observables
            observables[k1, :] = [obs(psi, e_op) for e_op in e_ops]
            # f_obs.write(fmt.format(t, *e_list))

            psilist.append(psi.copy())

        # f_obs.close()

        result.psilist = psilist
        result.observables = observables

        return result

    else:  # not save states
        for k1 in range(int(Nt / nout)):
            for k2 in range(nout):
                psi = rk4(psi, tdse, dt, H)

            t += dt * nout

            # compute observables
            e_list = [obs(psi, e_op) for e_op in e_ops]
            f_obs.write(fmt.format(t, *e_list))

        f_obs.close()

        return psi
Beispiel #4
0
def driven_dynamics(H, edip, psi0, pulse, dt=0.001, Nt=1, e_ops=None, nout=1, \
                    t0=0.0, return_result=True):
    '''
    Laser-driven dynamics in the presence of laser pulses

    Parameters
    ----------
    ham : 2d array
        Hamiltonian of the molecule
    dip : TYPE
        transition dipole moment
    psi0: 1d array
        initial wavefunction
    pulse : TYPE
        laser pulse
    dt : TYPE
        time step.
    Nt : TYPE
        timesteps.
    e_ops: list
        observable operators to compute
    nout: int
        Store data every nout steps

    Returns
    -------
    None.

    '''

    # initialize the density matrix
    # wf = csr_matrix(wf0).transpose()
    psi = psi0.astype(complex)

    nstates = len(psi0)

    # f = open(fname,'w')

    if e_ops is None:
        e_ops = []

    t = t0

    # f_dip = open('dipole'+'{:f}'.format(pulse.delay * au2fs)+'.dat', 'w')
    if return_result:

        result = Result(dt=dt, Nt=Nt, psi0=psi0)

        observables = np.zeros((Nt // nout, len(e_ops)), dtype=complex)
        psilist = [psi0.copy()]

        # compute observables for t0
        observables[0, :] = [obs(psi, e_op) for e_op in e_ops]

        for k1 in range(1, Nt // nout):

            for k2 in range(nout):

                ht = -pulse.field(t) * edip + H
                psi = rk4(psi, tdse, dt, ht)

            t += dt * nout

            # compute observables
            observables[k1, :] = [obs(psi, e_op) for e_op in e_ops]
            # f_obs.write(fmt.format(t, *e_list))

            psilist.append(psi.copy())

        # f_obs.close()

        result.psilist = psilist
        result.observables = observables

        return result

    else:

        fmt = '{} ' * (len(e_ops) + 1) + '\n'
        fmt_dm = '{} ' * (nstates + 1) + '\n'

        f_dm = open('psi.dat', 'w')  # wavefunction
        f_obs = open('obs.dat', 'w')  # observables

        for k1 in range(int(Nt / nout)):

            for k2 in range(nout):
                ht = pulse.field(t) * edip + H
                psi = rk4(psi, tdse, dt, ht)

            t += dt * nout

            # compute observables
            Aave = np.zeros(len(e_ops), dtype=complex)
            for j, A in enumerate(e_ops):
                Aave[j] = obs(psi, A)

            f_dm.write(fmt_dm.format(t, *psi))
            f_obs.write(fmt.format(t, *Aave))

        f_dm.close()
        f_obs.close()

        return