Example #1
0
    def evolve(self,
               psi0,
               dt=0.001,
               Nt=1,
               t0=0.,
               nout=1,
               coordinates='linear'):

        psi = psi0
        t = t0
        x = self.x

        nx = len(x)
        dx = x[1] - x[0]

        vmat = self.v
        nac = self.nac

        # momentum k-space
        k = 2.0 * np.pi * scipy.fftpack.fftfreq(nx, dx)

        if coordinates == 'linear':
            print('The nuclear coordinate is linear.')

        elif coordinates == 'curvilinear':

            raise NotImplementedError('Kinetic energy operator for curvilinear\
                                      coordinates has not been implemented.')

        fig, ax = plt.subplots()

        for j in range(Nt // nout):
            for i in range(nout):

                t += dt
                psi = rk4(psi, hpsi, dt, x, k, vmat, nac)
                #output_tmp = density_matrix(psi)

                #f.write('{} {} {} {} {} \n'.format(t, *rho))
                #purity[i] = output_tmp

            # ax.plot(x, np.abs(psi[:,0]) + 0.1 * j)
            ax.plot(x, np.abs(psi[:, 1]))

        return psi
Example #2
0
def _propagator(H, dt, Nt):
    """
    compute the resolvent for the multi-point correlation function signals
    U(t) = e^{-i H t}
    Parameters
    -----------
    t: float or list
        times
    """

    # propagator
    U = identity(H.shape[-1], dtype=complex)

    # set the ground state energy to 0
    print('Computing the propagator. '
          'Please make sure that the ground-state energy is 0.')
    Ulist = []
    for k in range(Nt):
        Ulist.append(U)
        U = rk4(U, tdse, dt, H)

    return Ulist
Example #3
0
def _lindblad(H, rho0, c_ops, Nt, dt, e_ops=[], return_result=True):
    """
    time propagation of the lindblad quantum master equation
    with second-order differencing

    Input
    -------
    h0: 2d array
            system Hamiltonian
    Nt: total number of time steps

    dt: time step
        c_ops: list of collapse operators
        e_ops: list of observable operators
        rho0: initial density matrix

    Returns
    =========
    rho: 2D array
        density matrix at time t = Nt * dt
    """

    nstates = H.shape[-1]
    # initialize the density matrix
    rho = rho0

    t = 0.0
    # first-step
    # rho_half = rho0 + liouvillian(rho0, h0, c_ops) * dt2
    # rho1 = rho0 + liouvillian(rho_half, h0, c_ops) * dt

    # rho_old = rho0
    # rho = rho1
    if return_result == False:

        f_dm = open('den_mat.dat', 'w')
        fmt_dm = '{} ' * (nstates**2 + 1) + '\n'

        f_obs = open('obs.dat', 'w')
        fmt = '{} ' * (len(e_ops) + 1) + '\n'

        for k in range(Nt):

            t += dt

            # rho_new = rho_old + liouvillian(rho, h0, c_ops) * 2. * dt
            # # update rho_old
            # rho_old = rho
            # rho = rho_new

            rho = rk4(rho, liouvillian, dt, H, c_ops)

            # dipole-dipole auto-corrlation function
            #cor = np.trace(np.matmul(d, rho))

            # take a partial trace to obtain the rho_el
            # compute observables
            observables = np.zeros(len(e_ops), dtype=complex)

            for i, obs_op in enumerate(e_ops):
                observables[i] = obs_dm(rho, obs_op)

            f_obs.write(fmt.format(t, *observables))

        f_obs.close()
        f_dm.close()

        return rho

    else:

        rholist = []  # store density matries

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

        observables = np.zeros((Nt, len(e_ops)), dtype=complex)

        for k in range(Nt):

            t += dt
            rho = rk4(rho, liouvillian, dt, H, c_ops)

            rholist.append(rho)

            observables[k, :] = [obs_dm(rho, op) for op in e_ops]

        result.observables = observables
        result.rholist = rholist

        return result
Example #4
0
def _correlation_2p_1t(H,
                       rho0,
                       ops,
                       c_ops,
                       dt,
                       Nt,
                       method='lindblad',
                       output='cor.dat'):
    """
    compute the time-translation invariant two-point correlation function in the
    density matrix formalism using quantum regression theorem

        <A(t)B> = Tr[ A U(t) (B rho0)  U^\dag(t)]

    input:
    ========
    H: 2d array
        full Hamiltonian

    rho0: initial density matrix

    ops: list of operators [A, B] for computing the correlation functions

    method: str
        dynamics method e.g. lindblad, redfield, heom

    args: dictionary of parameters for dynamics

    Returns
    ========
    the density matrix is stored in 'dm.dat'
    'cor.dat': the correlation function is stored
    """
    #nstates =  H.shape[-1] # number of states in the system

    # initialize the density matrix
    A, B = ops
    rho = B.dot(rho0)

    f = open(output, 'w')
    # f_dm = open('dm.dat', 'w')
    # fmt = '{} ' * (H.size + 1) + '\n' # format to store the density matrix

    # dynamics

    t = 0.0
    cor = np.zeros(Nt, dtype=complex)

    # sparse matrix
    H = csr_matrix(H)
    rho = csr_matrix(rho)

    A = csr_matrix(A)

    c_ops_sparse = [csr_matrix(c_op) for c_op in c_ops]

    if method == 'lindblad':

        for k in range(Nt):

            t += dt

            rho = rk4(rho, liouvillian, dt, H, c_ops_sparse)

            # cor = A.dot(rho).diagonal().sum()
            tmp = obs_dm(rho, A)
            cor[k] = tmp
            # store the reduced density matrix
            f.write('{} {} \n'.format(t, tmp))

            # f_dm.write(fmt.format(t, *np.ravel(rho)))

            # f_dm.write(fmt.format(t, *np.ravel(rho.toarray())))

    else:
        sys.exit('The method {} has not been implemented yet! Please \
                 try lindblad.'.format(method))

    f.close()
    # f_dm.close()

    return cor
Example #5
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
Example #6
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
Example #7
0
File: mol.py Project: binggu56/lime
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
Example #8
0
File: wpd.py Project: kubo4/lime
def adiabatic_2d(x, y, psi0, v, dt, Nt=0, coords='linear', mass=None, G=None):
    """
    propagate the adiabatic dynamics at a single surface

    :param dt: time step
    :param v: 2d array
                potential matrices in 2D
    :param psi: list
                the initial state
    mass: list of 2 elements
        reduced mass

    Nt: int
        the number of the time steps, Nt=0 indicates that no propagation has been done,
                   only the initial state and the initial purity would be
                   the output

    G: 4D array nx, ny, ndim, ndim
        G-matrix

    :return: psi_end: list
                      the final state

    G: 2d array
        G matrix only used for curvilinear coordinates
    """
    #f = open('density_matrix.dat', 'w')
    t = 0.0
    dt2 = dt * 0.5

    psi = psi0.copy()

    nx, ny = psi.shape

    dx = x[1] - x[0]
    dy = y[1] - y[0]

    kx = 2. * np.pi * fftfreq(nx, dx)
    ky = 2. * np.pi * fftfreq(ny, dy)

    if coords == 'linear':
        # Split-operator method for linear coordinates

        psi = x_evolve_2d(dt2, psi, v)

        for i in range(Nt):
            t += dt
            psi = k_evolve_2d(dt, kx, ky, psi)
            psi = x_evolve_2d(dt, psi, v)

    elif coords == 'curvilinear':

        # kxpsi = np.einsum('i, ijn -> ijn', kx, psi_k)
        # kypsi = np.einsum('j, ijn -> ijn', ky, psi_k)

        # tpsi = np.zeros((nx, ny, nstates), dtype=complex)
        # dxpsi = np.zeros((nx, ny, nstates), dtype=complex)
        # dypsi = np.zeros((nx, ny, nstates), dtype=complex)

        # for i in range(nstates):

        #     dxpsi[:,:,i] = ifft2(kxpsi[:,:,i])
        #     dypsi[:,:,i] = ifft2(kypsi[:,:,i])

        for k in range(Nt):
            t += dt
            psi = rk4(psi, hpsi, dt, kx, ky, v, G)

        #f.write('{} {} {} {} {} \n'.format(t, *rho))
        #purity[i] = output_tmp[4]

    # t += dt
    #f.close()

    return psi
Example #9
0
nac = get_nac(x)

k = 2.0 * np.pi * scipy.fftpack.fftfreq(nx, dx)

psi = np.zeros((nx, nstates), dtype=complex)

psi[:, 0] = gwp(x, a=1.0, x0=1.0, k0=0.0)

print('Propagation starts ...\n')
fig, ax = plt.subplots()

for j in range(10):
    for i in range(nsteps):
        t += dt
        psi = rk4(psi, hpsi, dt, x, k, vmat)
        #output_tmp = density_matrix(psi)

        #f.write('{} {} {} {} {} \n'.format(t, *rho))
        #purity[i] = output_tmp

    ax.plot(x, np.abs(psi[:,0]) + 0.1 * j)
    ax.plot(x, psi[:,1].real)







Example #10
0
File: oqs.py Project: binggu56/lime
def _redfield(R,
              rho0,
              evecs=None,
              Nt=1,
              dt=0.005,
              t0=0,
              e_ops=[],
              return_result=True):
    """
    time propagation of the Redfield quantum master equation with RK4

    Input
    -------
    R: 2d array
        Redfield tensor

    rho0: 2d array
        initial density matrix

    Nt: total number of time steps

    dt: time step
    e_ops: list of observable operators

    Returns
    =========
    rho: 2D array
        density matrix at time t = Nt * dt
    """

    N = rho0.shape[0]
    # initialize the density matrix
    if e_ops is None:
        e_ops = []

    # basis transformation
    if evecs is not None:
        rho0 = transform(rho0, evecs)
        e_ops = [transform(e, evecs) for e in e_ops]

    rho = rho0.copy()
    rho = dm2vec(rho).astype(complex)

    # tf = t0 + dt * Nt
    # result = solve_ivp(rhs, t_span=(t0, tf), y0=rho0, vectorized=True, args=(R, ))

    t = t0

    if return_result == False:

        f_obs = open('obs.dat', 'w')
        fmt = '{} ' * (len(e_ops) + 1) + '\n'

        for k in range(Nt):

            # compute observables
            # observables = np.zeros(len(e_ops), dtype=complex)
            # for i, obs_op in enumerate(e_ops):

            observables = [obs_dm(rho, e) for e in e_ops]

            t += dt
            rho = rk4(rho, rhs, dt, R)

            # dipole-dipole auto-corrlation function
            #cor = np.trace(np.matmul(d, rho))

            # take a partial trace to obtain the rho_el

            f_obs.write(fmt.format(t, *observables))

        f_obs.close()
        # f_dm.close()

        return rho

    else:

        rholist = []  # store density matries

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

        observables = np.zeros((Nt, len(e_ops)), dtype=complex)

        for k in range(Nt):

            t += dt
            rho = rk4(rho, rhs, dt, R)

            tmp = np.reshape(rho, (N, N))
            rholist.append(transform(tmp, dag(evecs)))

            observables[k, :] = [obs_dm(tmp, e) for e in e_ops]

        result.observables = observables
        result.rholist = rholist

        return result
Example #11
0
File: oqs.py Project: binggu56/lime
def _lindblad_driven(H,
                     rho0,
                     c_ops=None,
                     e_ops=None,
                     Nt=1,
                     dt=0.005,
                     t0=0.,
                     return_result=True):
    """
    time propagation of the lindblad quantum master equation with time-dependent Hamiltonian
    H = H0 + f(t) * H1 - ...

    Input
    -------
    H:  list [H0, [H1, f1(t)]]
            system Hamiltonian
    pulse: Pulse object
        externel pulse
    Nt: total number of time steps

    dt: time step
    c_ops: list of collapse operators
    e_ops: list of observable operators
    rho0: initial density matrix

    Returns
    =========
    rho: 2D array
        density matrix at time t = Nt * dt
    """
    def calculateH(t):

        Ht = H[0]

        for i in range(1, len(H)):
            Ht += -H[i][1](t) * H[i][0]

        return Ht

    nstates = H[0].shape[-1]

    if c_ops is None:
        c_ops = []
    if e_ops is None:
        e_ops = []

    # initialize the density matrix
    rho = rho0.copy()
    rho = rho.astype(complex)

    t = t0

    if return_result == False:

        f_dm = open('den_mat.dat', 'w')
        fmt_dm = '{} ' * (nstates**2 + 1) + '\n'

        f_obs = open('obs.dat', 'w')
        fmt = '{} ' * (len(e_ops) + 1) + '\n'

        for k in range(Nt):

            t += dt

            Ht = calculateH(t)

            rho = rk4(rho, liouvillian, dt, Ht, c_ops)

            # dipole-dipole auto-corrlation function
            #cor = np.trace(np.matmul(d, rho))

            # take a partial trace to obtain the rho_el
            # compute observables
            observables = np.zeros(len(e_ops), dtype=complex)

            for i, obs_op in enumerate(e_ops):
                observables[i] = obs_dm(rho, obs_op)

            f_obs.write(fmt.format(t, *observables))

        f_obs.close()
        f_dm.close()

        return rho

    else:

        rholist = []  # store density matries

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

        observables = np.zeros((Nt, len(e_ops)), dtype=complex)

        for k in range(Nt):

            t += dt

            Ht = calculateH(t)

            rho = rk4(rho, liouvillian, dt, Ht, c_ops)

            rholist.append(rho.copy())

            observables[k, :] = [obs_dm(rho, op) for op in e_ops]

        result.observables = observables
        result.rholist = rholist

        return result