Exemplo n.º 1
0
Arquivo: hf.py Projeto: sunqm/pyscf
 def get_hcore(self, cell=None, kpt=None):
     if cell is None: cell = self.cell
     if kpt is None: kpt = self.kpt
     if cell.pseudo:
         nuc = self.with_df.get_pp(kpt)
     else:
         nuc = self.with_df.get_nuc(kpt)
     if len(cell._ecpbas) > 0:
         nuc += ecp.ecp_int(cell, kpt)
     return nuc + cell.pbc_intor('int1e_kin', 1, 1, kpt)
Exemplo n.º 2
0
Arquivo: hf.py Projeto: pedersor/pyscf
 def get_hcore(self, cell=None, kpt=None):
     if cell is None: cell = self.cell
     if kpt is None: kpt = self.kpt
     if cell.pseudo:
         nuc = self.with_df.get_pp(kpt)
     else:
         nuc = self.with_df.get_nuc(kpt)
     if len(cell._ecpbas) > 0:
         nuc += ecp.ecp_int(cell, kpt)
     return nuc + cell.pbc_intor('int1e_kin', 1, 1, kpt)
Exemplo n.º 3
0
Arquivo: hf.py Projeto: pedersor/pyscf
def get_hcore(cell, kpt=np.zeros(3)):
    '''Get the core Hamiltonian AO matrix.
    '''
    hcore = get_t(cell, kpt)
    if cell.pseudo:
        hcore += get_pp(cell, kpt)
    else:
        hcore += get_nuc(cell, kpt)
    if len(cell._ecpbas) > 0:
        hcore += ecp.ecp_int(cell, kpt)
    return hcore
Exemplo n.º 4
0
 def get_hcore(self, cell=None, kpts=None):
     if cell is None: cell = self.cell
     if kpts is None: kpts = self.kpts
     if cell.pseudo:
         nuc = lib.asarray(self.with_df.get_pp(kpts))
     else:
         nuc = lib.asarray(self.with_df.get_nuc(kpts))
     if len(cell._ecpbas) > 0:
         nuc += lib.asarray(ecp.ecp_int(cell, kpts))
     t = lib.asarray(cell.pbc_intor('cint1e_kin_sph', 1, 1, kpts))
     return nuc + t
Exemplo n.º 5
0
Arquivo: hf.py Projeto: sunqm/pyscf
def get_hcore(cell, kpt=np.zeros(3)):
    '''Get the core Hamiltonian AO matrix.
    '''
    hcore = get_t(cell, kpt)
    if cell.pseudo:
        hcore += get_pp(cell, kpt)
    else:
        hcore += get_nuc(cell, kpt)
    if len(cell._ecpbas) > 0:
        hcore += ecp.ecp_int(cell, kpt)
    return hcore
Exemplo n.º 6
0
 def get_hcore(self, cell=None, kpts=None):
     if cell is None: cell = self.cell
     if kpts is None: kpts = self.kpts
     if cell.pseudo:
         nuc = self.with_df.get_pp(kpts)
     else:
         nuc = self.with_df.get_nuc(kpts)
     if len(cell._ecpbas) > 0:
         nuc += ecp.ecp_int(cell, kpts)
     t = cell.pbc_intor('cint1e_kin_sph', 1, 1, kpts)
     return lib.asarray(nuc) + lib.asarray(t)
Exemplo n.º 7
0
def get_hcore(mf, cell=None, kpts=None):
    '''Get the core Hamiltonian AO matrices at sampled k-points.

    Args:
        kpts : (nkpts, 3) ndarray

    Returns:
        hcore : (nkpts, nao, nao) ndarray
    '''
    if cell is None: cell = mf.cell
    if kpts is None: kpts = mf.kpts
    if cell.pseudo:
        nuc = lib.asarray(mf.with_df.get_pp(kpts))
    else:
        nuc = lib.asarray(mf.with_df.get_nuc(kpts))
    if len(cell._ecpbas) > 0:
        nuc += lib.asarray(ecp.ecp_int(cell, kpts))
    t = lib.asarray(cell.pbc_intor('int1e_kin', 1, 1, kpts))
    return nuc + t
Exemplo n.º 8
0
    def test_ecp_pseudo(self):
        from pyscf.pbc.gto import ecp
        cell = pgto.M(a=np.eye(3) * 5,
                      gs=[4] * 3,
                      atom='Cu 0 0 1; Na 0 1 0',
                      ecp='lanl2dz',
                      pseudo={'Cu': 'gthbp'})
        self.assertTrue(all(cell._ecpbas[:, 0] == 1))

        cell = pgto.Cell()
        cell.a = numpy.eye(3) * 8
        cell.gs = [5] * 3
        cell.atom = '''Na 0. 0. 0.
                     H  0.  0.  1.'''
        cell.basis = {'Na': 'lanl2dz', 'H': 'sto3g'}
        cell.ecp = {'Na': 'lanl2dz'}
        cell.build()
        v1 = ecp.ecp_int(cell)
        mol = cell.to_mol()
        v0 = mol.intor('ECPscalar_sph')
        self.assertAlmostEqual(abs(v0 - v1).sum(), 0.0289322453376, 10)
Exemplo n.º 9
0
    def test_ecp_pseudo(self):
        from pyscf.pbc.gto import ecp
        cell = pgto.M(a=np.eye(3) * 5,
                      mesh=[9] * 3,
                      atom='Cu 0 0 1; Na 0 1 0',
                      ecp={'Na': 'lanl2dz'},
                      pseudo={'Cu': 'gthbp'})
        self.assertTrue(all(cell._ecpbas[:, 0] == 1))

        cell = pgto.Cell()
        cell.a = numpy.eye(3) * 8
        cell.mesh = [11] * 3
        cell.atom = '''Na 0. 0. 0.
                     H  0.  0.  1.'''
        cell.basis = {'Na': 'lanl2dz', 'H': 'sto3g'}
        cell.ecp = {'Na': 'lanl2dz'}
        cell.build()
        # FIXME: ECP integrals segfault
        v1 = ecp.ecp_int(cell)
        mol = cell.to_mol()
        v0 = mol.intor('ECPscalar_sph')
        self.assertAlmostEqual(abs(v0 - v1).sum(), 0.029005926114411891, 8)
Exemplo n.º 10
0
    def test_ecp_pseudo(self):
        from pyscf.pbc.gto import ecp
        cell = pgto.M(
            a = np.eye(3)*5,
            gs = [4]*3,
            atom = 'Cu 0 0 1; Na 0 1 0',
            ecp = 'lanl2dz',
            pseudo = {'Cu': 'gthbp'})
        self.assertTrue(all(cell._ecpbas[:,0] == 1))

        cell = pgto.Cell()
        cell.a = numpy.eye(3) * 8
        cell.gs = [5] * 3
        cell.atom='''Na 0. 0. 0.
                     H  0.  0.  1.'''
        cell.basis={'Na':'lanl2dz', 'H':'sto3g'}
        cell.ecp = {'Na':'lanl2dz'}
        cell.build()
        v1 = ecp.ecp_int(cell)
        mol = cell.to_mol()
        v0 = mol.intor('ECPscalar_sph')
        self.assertAlmostEqual(abs(v0 - v1).sum(), 0.0289322453376, 10)
Exemplo n.º 11
0
def pyscf2QP(cell, mf, kpts, kmesh=None, cas_idx=None, int_threshold=1E-8):
    '''
    kpts = List of kpoints coordinates. Cannot be null, for gamma is other script
    kmesh = Mesh of kpoints (optional)
    cas_idx = List of active MOs. If not specified all MOs are actives
    int_threshold = The integral will be not printed in they are bellow that
    '''

    from pyscf.pbc import ao2mo
    from pyscf.pbc import tools
    from pyscf import lib
    from pyscf.pbc.gto import ecp

    mo_coef_threshold = int_threshold
    ovlp_threshold = int_threshold
    kin_threshold = int_threshold
    ne_threshold = int_threshold
    bielec_int_threshold = int_threshold

    natom = len(cell.atom_coords())
    print('n_atom', natom)
    print('num_elec', cell.nelectron)

    mo_coeff = mf.mo_coeff
    # Mo_coeff actif
    mo_k = np.array([c[:, cas_idx]
                     for c in mo_coeff] if cas_idx is not None else mo_coeff)
    e_k = np.array(
        [e[cas_idx]
         for e in mf.mo_energy] if cas_idx is not None else mf.mo_energy)

    Nk, nao, nmo = mo_k.shape
    print("n Kpts", Nk)
    print("n active Mos", nmo)

    # Write all the parameter need to creat a dummy EZFIO folder who will containt the integral after.
    # More an implentation detail than a real thing
    with open('param', 'w') as f:
        # Note the use of nmo_tot
        f.write(' '.join(map(str,
                             (cell.nelectron * Nk, Nk * nmo, natom * Nk))))

    with open('num_ao', 'w') as f:
        f.write(str(nao * Nk))
    #                             _
    # |\ |      _ |  _   _. ._   |_)  _  ._      |  _ o  _  ._
    # | \| |_| (_ | (/_ (_| |    | \ (/_ |_) |_| | _> | (_) | |
    #                                    |

    #Total energy shift due to Ewald probe charge = -1/2 * Nelec*madelung/cell.vol =
    shift = tools.pbc.madelung(cell, kpts) * cell.nelectron * -.5
    e_nuc = (cell.energy_nuc() + shift) * Nk

    print('nucl_repul', e_nuc)
    with open('e_nuc', 'w') as f:
        f.write(str(e_nuc))

    def get_phase(cell, kpts, kmesh=None):
        '''
        The unitary transformation that transforms the supercell basis k-mesh
        adapted basis.
        '''

        latt_vec = cell.lattice_vectors()
        if kmesh is None:
            # Guess kmesh
            scaled_k = cell.get_scaled_kpts(kpts).round(8)
            kmesh = (len(np.unique(scaled_k[:, 0])),
                     len(np.unique(scaled_k[:,
                                            1])), len(np.unique(scaled_k[:,
                                                                         2])))

        R_rel_a = np.arange(kmesh[0])
        R_rel_b = np.arange(kmesh[1])
        R_rel_c = np.arange(kmesh[2])
        R_vec_rel = lib.cartesian_prod((R_rel_a, R_rel_b, R_rel_c))
        R_vec_abs = np.einsum('nu, uv -> nv', R_vec_rel, latt_vec)

        NR = len(R_vec_abs)
        phase = np.exp(1j * np.einsum('Ru, ku -> Rk', R_vec_abs, kpts))
        phase /= np.sqrt(NR)  # normalization in supercell

        # R_rel_mesh has to be construct exactly same to the Ts in super_cell function
        scell = tools.super_cell(cell, kmesh)
        return scell, phase

    def mo_k2gamma(cell, mo_energy, mo_coeff, kpts, kmesh=None):
        '''
        Transform MOs in Kpoints to the equivalents supercell
        '''
        scell, phase = get_phase(cell, kpts, kmesh)

        E_g = np.hstack(mo_energy)
        C_k = np.asarray(mo_coeff)
        Nk, Nao, Nmo = C_k.shape
        NR = phase.shape[0]

        # Transform AO indices
        C_gamma = np.einsum('Rk, kum -> Rukm', phase, C_k)
        C_gamma = C_gamma.reshape(Nao * NR, Nk * Nmo)

        E_sort_idx = np.argsort(E_g)
        E_g = E_g[E_sort_idx]
        C_gamma = C_gamma[:, E_sort_idx]
        s = scell.pbc_intor('int1e_ovlp')
        assert (abs(
            reduce(np.dot, (C_gamma.conj().T, s, C_gamma)) -
            np.eye(Nmo * Nk)).max() < 1e-7)

        # Transform MO indices
        E_k_degen = abs(E_g[1:] - E_g[:-1]).max() < 1e-5
        if np.any(E_k_degen):
            degen_mask = np.append(False, E_k_degen) | np.append(
                E_k_degen, False)
            shift = min(E_g[degen_mask]) - .1
            f = np.dot(C_gamma[:, degen_mask] * (E_g[degen_mask] - shift),
                       C_gamma[:, degen_mask].conj().T)
            assert (abs(f.imag).max() < 1e-5)

            e, na_orb = la.eigh(f.real, s, type=2)
            C_gamma[:, degen_mask] = na_orb[:, e > 0]

        if abs(C_gamma.imag).max() < 1e-7:
            print('!Warning  Some complexe pollutions in MOs are present')

        C_gamma = C_gamma.real
        if abs(
                reduce(np.dot, (C_gamma.conj().T, s, C_gamma)) -
                np.eye(Nmo * Nk)).max() < 1e-7:
            print('!Warning  Some complexe pollutions in MOs are present')

        s_k = cell.pbc_intor('int1e_ovlp', kpts=kpts)
        # overlap between k-point unitcell and gamma-point supercell
        s_k_g = np.einsum('kuv,Rk->kuRv', s_k,
                          phase.conj()).reshape(Nk, Nao, NR * Nao)
        # The unitary transformation from k-adapted orbitals to gamma-point orbitals
        mo_phase = lib.einsum('kum,kuv,vi->kmi', C_k.conj(), s_k_g, C_gamma)

        return mo_phase

    #       __    __          _
    # |\/| |  |  |    _   _  |_  _
    # |  | |__|  |__ (_) (/_ |  _>
    #
    with open('mo_coef_complex', 'w') as outfile:
        c_kpts = np.reshape(mf.mo_coeff_kpts, (Nk, nao, nmo))

        for ik in range(Nk):
            shift1 = ik * nao + 1
            shift2 = ik * nmo + 1
            for i in range(nao):
                for j in range(nmo):
                    cij = c_kpts[ik, i, j]
                    if abs(cij) > mo_coef_threshold:
                        outfile.write(
                            '%s %s %s %s\n' %
                            (i + shift1, j + shift2, cij.real, cij.imag))

    # ___
    #  |  ._ _|_  _   _  ._ _. |  _   |\/|  _  ._   _
    # _|_ | | |_ (/_ (_| | (_| | _>   |  | (_) | | (_)
    #                 _|

    with open('overlap_ao_complex', 'w') as outfile:
        #s_kpts_ao = np.reshape(mf.cell.pbc_intor('int1e_ovlp_sph',kpts=kpts),(Nk,nao,nao))
        s_kpts_ao = np.reshape(mf.get_ovlp(cell=cell, kpts=kpts),
                               (Nk, nao, nao))

        for ik in range(Nk):
            shift = ik * nao + 1
            for i in range(nao):
                for j in range(i, nao):
                    sij = s_kpts_ao[ik, i, j]
                    if abs(sij) > ovlp_threshold:
                        outfile.write(
                            '%s %s %s %s\n' %
                            (i + shift, j + shift, sij.real, sij.imag))

    with open('kinetic_ao_complex', 'w') as outfile:
        #t_kpts_ao = np.reshape(mf.cell.pbc_intor('int1e_kin_sph',kpts=kpts),(Nk,nao,nao))
        t_kpts_ao = np.reshape(cell.pbc_intor('int1e_kin', 1, 1, kpts=kpts),
                               (Nk, nao, nao))

        for ik in range(Nk):
            shift = ik * nao + 1
            for i in range(nao):
                for j in range(i, nao):
                    tij = t_kpts_ao[ik, i, j]
                    if abs(tij) > kin_threshold:
                        outfile.write(
                            '%s %s %s %s\n' %
                            (i + shift, j + shift, tij.real, tij.imag))

    with open('ne_ao_complex', 'w') as outfile:
        if mf.cell.pseudo:
            v_kpts_ao = np.reshape(mf.with_df.get_pp(kpts=kpts),
                                   (Nk, nao, nao))
        else:
            v_kpts_ao = np.reshape(mf.with_df.get_nuc(kpts=kpts),
                                   (Nk, nao, nao))
        if len(cell._ecpbas) > 0:
            v_kpts_ao += np.reshape(ecp.ecp_int(cell, kpts), (Nk, nao, nao))

        for ik in range(Nk):
            shift = ik * nao + 1
            for i in range(nao):
                for j in range(i, nao):
                    vij = v_kpts_ao[ik, i, j]
                    if abs(vij) > ne_threshold:
                        outfile.write(
                            '%s %s %s %s\n' %
                            (i + shift, j + shift, vij.real, vij.imag))

    # ___                              _
    #  |  ._ _|_  _   _  ._ _. |  _   |_) o
    # _|_ | | |_ (/_ (_| | (_| | _>   |_) |
    #                 _|
    #
    kconserv = tools.get_kconserv(cell, kpts)

    def idx2_tri(i, j):
        ij1 = min(i, j)
        ij2 = max(i, j)
        return ij1 + (ij2 * (ij2 - 1)) // 2
#    eri_4d_ao = np.zeros((Nk,nao,Nk,nao,Nk,nao,Nk,nao), dtype=np.complex)
#    for d, kd in enumerate(kpts):
#        for c, kc in enumerate(kpts):
#            if c > d: break
#            idx2_cd = idx2_tri(c,d)
#            for b, kb in enumerate(kpts):
#                if b > d: break
#                a = kconserv[b,c,d]
#                if idx2_tri(a,b) > idx2_cd: continue
#                if ((c==d) and (a>b)): continue
#                ka = kpts[a]
#                v = mf.with_df.get_ao_eri(kpts=[ka,kb,kc,kd],compact=False).reshape((nao,)*4)
#                v *= 1./Nk
#                eri_4d_ao[a,:,b,:,c,:,d] = v
#
#    eri_4d_ao = eri_4d_ao.reshape([Nk*nao]*4)
#
#    with open('bielec_ao_complex','w') as outfile:
#        for d in range(Nk):
#            for c in range(Nk):
#                if c > d: break
#                idx2_cd = idx2_tri(c,d)
#                for b in range(Nk):
#                    if b > d: break
#                    a = kconserv[b,c,d]
#                    if idx2_tri(a,b) > idx2_cd: continue
#                    if ((c==d) and (a>b)): continue
#                    for l in range(nao):
#                        ll=l+d*nao
#                        for j in range(nao):
#                            jj=j+c*nao
#                            if jj>ll: break
#                            idx2_jjll = idx2_tri(jj,ll)
#                            for k in range(nao):
#                                kk=k+b*nao
#                                if kk>ll: break
#                                for i in range(nao):
#                                    ii=k+a*nao
#                                    if idx2_tri(ii,kk) > idx2_jjll: break
#                                    if ((jj==ll) and (ii>kk)): break
#                                        v=eri_4d_ao[ii,kk,jj,ll]
#                                        if (abs(v) > bielec_int_threshold):
#                                            outfile.write('%s %s %s %s %s %s\n' % (ii+1,jj+1,kk+1,ll+1,v.real,v.imag))

    with open('bielec_ao_complex', 'w') as outfile:
        for d, kd in enumerate(kpts):
            for c, kc in enumerate(kpts):
                if c > d: break
                idx2_cd = idx2_tri(c, d)
                for b, kb in enumerate(kpts):
                    if b > d: break
                    a = kconserv[b, c, d]
                    if idx2_tri(a, b) > idx2_cd: continue
                    if ((c == d) and (a > b)): continue
                    ka = kpts[a]
                    eri_4d_ao_kpt = mf.with_df.get_ao_eri(
                        kpts=[ka, kb, kc, kd], compact=False).reshape(
                            (nao, ) * 4)
                    eri_4d_ao_kpt *= 1. / Nk
                    for l in range(nao):
                        ll = l + d * nao
                        for j in range(nao):
                            jj = j + c * nao
                            if jj > ll: break
                            idx2_jjll = idx2_tri(jj, ll)
                            for k in range(nao):
                                kk = k + b * nao
                                if kk > ll: break
                                for i in range(nao):
                                    ii = k + a * nao
                                    if idx2_tri(ii, kk) > idx2_jjll: break
                                    if ((jj == ll) and (ii > kk)): break
                                    v = eri_4d_ao_kpt[i, k, j, l]
                                    if (abs(v) > bielec_int_threshold):
                                        outfile.write('%s %s %s %s %s %s\n' %
                                                      (ii + 1, jj + 1, kk + 1,
                                                       ll + 1, v.real, v.imag))
Exemplo n.º 12
0
def pyscf2QP(cell,mf, kpts, kmesh=None, cas_idx=None, int_threshold = 1E-8, 
        print_ao_ints_bi=False, 
        print_mo_ints_bi=False, 
        print_ao_ints_df=True, 
        print_mo_ints_df=False, 
        print_ao_ints_mono=True, 
        print_mo_ints_mono=False):
    '''
    kpts = List of kpoints coordinates. Cannot be null, for gamma is other script
    kmesh = Mesh of kpoints (optional)
    cas_idx = List of active MOs. If not specified all MOs are actives
    int_threshold = The integral will be not printed in they are bellow that
    '''
  
    from pyscf.pbc import ao2mo
    from pyscf.pbc import tools
    from pyscf.pbc.gto import ecp
    import h5py
    
    mo_coef_threshold = int_threshold
    ovlp_threshold = int_threshold
    kin_threshold = int_threshold
    ne_threshold = int_threshold
    bielec_int_threshold = int_threshold

    natom = len(cell.atom_coords())
    print('n_atom per kpt',   natom)
    print('num_elec per kpt', cell.nelectron)
  
    mo_coeff = mf.mo_coeff
    # Mo_coeff actif
    mo_k = np.array([c[:,cas_idx] for c in mo_coeff] if cas_idx is not None else mo_coeff)
    e_k =  np.array([e[cas_idx] for e in mf.mo_energy] if cas_idx is not None else mf.mo_energy)
  
    Nk, nao, nmo = mo_k.shape
    print("n Kpts", Nk)
    print("n active Mos per kpt", nmo)
    print("n AOs per kpt", nao)

    naux = mf.with_df.auxcell.nao
    print("n df fitting functions", naux)
    with open('num_df','w') as f:
        f.write(str(naux))
  
    # Write all the parameter need to creat a dummy EZFIO folder who will containt the integral after.
    # More an implentation detail than a real thing
    with open('param','w') as f:
    # Note the use of nmo_tot
        f.write(' '.join(map(str,(cell.nelectron*Nk, Nk*nmo, natom*Nk))))
  
    with open('num_ao','w') as f:
        f.write(str(nao*Nk))
    with open('num_kpts','w') as f:
        f.write(str(Nk))
    #                             _                             
    # |\ |      _ |  _   _. ._   |_)  _  ._      |  _ o  _  ._  
    # | \| |_| (_ | (/_ (_| |    | \ (/_ |_) |_| | _> | (_) | | 
    #                                    |                      
    
    #Total energy shift due to Ewald probe charge = -1/2 * Nelec*madelung/cell.vol =
    shift = tools.pbc.madelung(cell, kpts)*cell.nelectron * -.5 
    e_nuc = (cell.energy_nuc() + shift)*Nk
  
    print('nucl_repul', e_nuc)
    with open('e_nuc','w') as f:
        f.write(str(e_nuc))
  
  
  
    #       __    __          _                                 
    # |\/| |  |  |    _   _  |_  _ 
    # |  | |__|  |__ (_) (/_ |  _> 
    #                                               
    with open('mo_coef_complex','w') as outfile:
        c_kpts = np.reshape(mo_k,(Nk,nao,nmo))

        for ik in range(Nk):
            shift1=ik*nao+1
            shift2=ik*nmo+1
            for i in range(nao):
                for j in range(nmo):
                    cij = c_kpts[ik,i,j]
                    if abs(cij) > mo_coef_threshold:
                        outfile.write('%s %s %s %s\n' % (i+shift1, j+shift2, cij.real, cij.imag))
    
    # ___                                              
    #  |  ._ _|_  _   _  ._ _. |  _   |\/|  _  ._   _  
    # _|_ | | |_ (/_ (_| | (_| | _>   |  | (_) | | (_) 
    #                 _|                              
   
    if mf.cell.pseudo:
        v_kpts_ao = np.reshape(mf.with_df.get_pp(kpts=kpts),(Nk,nao,nao))
    else:
        v_kpts_ao = np.reshape(mf.with_df.get_nuc(kpts=kpts),(Nk,nao,nao))
    if len(cell._ecpbas) > 0:
        v_kpts_ao += np.reshape(ecp.ecp_int(cell, kpts),(Nk,nao,nao))

    ne_ao = ('ne',v_kpts_ao,ne_threshold)
    ovlp_ao = ('overlap',np.reshape(mf.get_ovlp(cell=cell,kpts=kpts),(Nk,nao,nao)),ovlp_threshold)
    kin_ao = ('kinetic',np.reshape(cell.pbc_intor('int1e_kin',1,1,kpts=kpts),(Nk,nao,nao)),kin_threshold)

    for name, intval_kpts_ao, thresh in (ne_ao, ovlp_ao, kin_ao):
        if print_ao_ints_mono:
            with open('%s_ao_complex' % name,'w') as outfile:
                for ik in range(Nk):
                    shift=ik*nao+1
                    for i in range(nao):
                        for j in range(i,nao):
                            int_ij = intval_kpts_ao[ik,i,j]
                            if abs(int_ij) > thresh:
                                outfile.write('%s %s %s %s\n' % (i+shift, j+shift, int_ij.real, int_ij.imag))
        if print_mo_ints_mono:
            intval_kpts_mo = np.einsum('kim,kij,kjn->kmn',mo_k.conj(),intval_kpts_ao,mo_k)
            with open('%s_mo_complex' % name,'w') as outfile:
                for ik in range(Nk):
                    shift=ik*nmo+1
                    for i in range(nmo):
                        for j in range(i,nmo):
                            int_ij = intval_kpts_mo[ik,i,j]
                            if abs(int_ij) > thresh:
                                outfile.write('%s %s %s %s\n' % (i+shift, j+shift, int_ij.real, int_ij.imag))

  
    # ___                              _    
    #  |  ._ _|_  _   _  ._ _. |  _   |_) o 
    # _|_ | | |_ (/_ (_| | (_| | _>   |_) | 
    #                 _|                    
    #
    kconserv = tools.get_kconserv(cell, kpts)

    with open('kconserv_complex','w') as outfile:
        for a in range(Nk):
            for b in range(Nk):
                for c in range(Nk):
                    d = kconserv[a,b,c]
                    outfile.write('%s %s %s %s\n' % (a+1,c+1,b+1,d+1))
    

    intfile=h5py.File(mf.with_df._cderi,'r')

    j3c = intfile.get('j3c')
    naosq = nao*nao
    naotri = (nao*(nao+1))//2
    j3ckeys = list(j3c.keys())
    j3ckeys.sort(key=lambda strkey:int(strkey))

    # in new(?) version of PySCF, there is an extra layer of groups before the datasets
    # datasets used to be [/j3c/0,   /j3c/1,   /j3c/2,   ...]
    # datasets now are    [/j3c/0/0, /j3c/1/0, /j3c/2/0, ...]
    j3clist = [j3c.get(i+'/0') for i in j3ckeys]
    if j3clist==[None]*len(j3clist):
    # if using older version, stop before last level
        j3clist = [j3c.get(i) for i in j3ckeys]

    nkinvsq = 1./np.sqrt(Nk)

    # dimensions are (kikj,iaux,jao,kao), where kikj is compound index of kpts i and j
    # output dimensions should be reversed (nao, nao, naux, nkptpairs)
    j3arr=np.array([(i.value.reshape([-1,nao,nao]) if (i.shape[1] == naosq) else makesq3(i.value,nao)) * nkinvsq for i in j3clist])

    nkpt_pairs = j3arr.shape[0]

    if print_ao_ints_df:
        with open('df_ao_integral_array','w') as outfile:
            pass
        with open('df_ao_integral_array','a') as outfile:
            for k,kpt_pair in enumerate(j3arr):
                for iaux,dfbasfunc in enumerate(kpt_pair):
                    for i,i0 in enumerate(dfbasfunc):
                        for j,v in enumerate(i0):
                            if (abs(v) > bielec_int_threshold):
                                outfile.write('%s %s %s %s %s %s\n' % (i+1,j+1,iaux+1,k+1,v.real,v.imag))

    if print_mo_ints_df:
        kpair_list=[]
        for i in range(Nk):
            for j in range(Nk):
                if(i>=j):
                    kpair_list.append((i,j,idx2_tri((i,j))))
        j3mo = np.array([np.einsum('mij,ik,jl->mkl',j3arr[kij],mo_k[ki].conj(),mo_k[kj]) for ki,kj,kij in kpair_list])
        with open('df_mo_integral_array','w') as outfile:
            pass
        with open('df_mo_integral_array','a') as outfile:
            for k,kpt_pair in enumerate(j3mo):
                for iaux,dfbasfunc in enumerate(kpt_pair):
                    for i,i0 in enumerate(dfbasfunc):
                        for j,v in enumerate(i0):
                            if (abs(v) > bielec_int_threshold):
                                outfile.write('%s %s %s %s %s %s\n' % (i+1,j+1,iaux+1,k+1,v.real,v.imag))




#    eri_4d_ao = np.zeros((Nk,nao,Nk,nao,Nk,nao,Nk,nao), dtype=np.complex)
#    for d, kd in enumerate(kpts):
#        for c, kc in enumerate(kpts):
#            if c > d: break
#            idx2_cd = idx2_tri(c,d)
#            for b, kb in enumerate(kpts):
#                if b > d: break
#                a = kconserv[b,c,d]
#                if idx2_tri(a,b) > idx2_cd: continue
#                if ((c==d) and (a>b)): continue
#                ka = kpts[a]
#                v = mf.with_df.get_ao_eri(kpts=[ka,kb,kc,kd],compact=False).reshape((nao,)*4)
#                v *= 1./Nk
#                eri_4d_ao[a,:,b,:,c,:,d] = v
#    
#    eri_4d_ao = eri_4d_ao.reshape([Nk*nao]*4)


    if (print_ao_ints_bi or print_mo_ints_bi):
        if print_ao_ints_bi:
            with open('bielec_ao_complex','w') as outfile: 
                pass
        if print_mo_ints_bi:
            with open('bielec_mo_complex','w') as outfile: 
                pass
        for d, kd in enumerate(kpts):
            for c, kc in enumerate(kpts):
                if c > d: break
                idx2_cd = idx2_tri((c,d))
                for b, kb in enumerate(kpts):
                    if b > d: break
                    a = kconserv[b,c,d]
                    if idx2_tri((a,b)) > idx2_cd: continue
                    if ((c==d) and (a>b)): continue
                    ka = kpts[a]

                    if print_ao_ints_bi:
                        with open('bielec_ao_complex','a') as outfile:
                            eri_4d_ao_kpt = mf.with_df.get_ao_eri(kpts=[ka,kb,kc,kd],compact=False).reshape((nao,)*4)
                            eri_4d_ao_kpt *= 1./Nk
                            for l in range(nao):
                                ll=l+d*nao
                                for j in range(nao):
                                    jj=j+c*nao
                                    if jj>ll: break
                                    idx2_jjll = idx2_tri((jj,ll))
                                    for k in range(nao):
                                        kk=k+b*nao
                                        if kk>ll: break
                                        for i in range(nao):
                                            ii=i+a*nao
                                            if idx2_tri((ii,kk)) > idx2_jjll: break
                                            if ((jj==ll) and (ii>kk)): break
                                            v=eri_4d_ao_kpt[i,k,j,l]
                                            if (abs(v) > bielec_int_threshold):
                                                outfile.write('%s %s %s %s %s %s\n' % (ii+1,jj+1,kk+1,ll+1,v.real,v.imag))
            
                    if print_mo_ints_bi:
                        with open('bielec_mo_complex','a') as outfile:
                            eri_4d_mo_kpt = mf.with_df.ao2mo([mo_k[a], mo_k[b], mo_k[c], mo_k[d]],
                                                              [ka,kb,kc,kd],compact=False).reshape((nmo,)*4)
                            eri_4d_mo_kpt *= 1./Nk
                            for l in range(nmo):
                                ll=l+d*nmo
                                for j in range(nmo):
                                    jj=j+c*nmo
                                    if jj>ll: break
                                    idx2_jjll = idx2_tri((jj,ll))
                                    for k in range(nmo):
                                        kk=k+b*nmo
                                        if kk>ll: break
                                        for i in range(nmo):
                                            ii=i+a*nmo
                                            if idx2_tri((ii,kk)) > idx2_jjll: break
                                            if ((jj==ll) and (ii>kk)): break
                                            v=eri_4d_mo_kpt[i,k,j,l]
                                            if (abs(v) > bielec_int_threshold):
                                                outfile.write('%s %s %s %s %s %s\n' % (ii+1,jj+1,kk+1,ll+1,v.real,v.imag))