Esempio n. 1
0
    def calculate_hamiltonian_matrix(self, useibl=True):
        """Calculate H_kij = H^o_i(k)j(k) + H^u_i(k)j(k)
           i(k): Bloch sum of omega_i
        """

        epso_kn = [eps_n[:M] for eps_n, M in zip(self.eps_kn, self.M_k)]
        self.Ho_kii = np.asarray([np.dot(dagger(Uo_ni) * epso_n, Uo_ni) 
                                  for Uo_ni, epso_n in zip(self.Uo_kni, 
                                                           epso_kn)])

        if self.h_lcao_kii!=None and useibl:
            print "Using h_lcao and infinite band limit"
            Vo_kni = self.Vo_kni
            Huf_kii = [h_lcao_ii - np.dot(dagger(Vo_ni) * epso_n, Vo_ni)
                       for h_lcao_ii, Vo_ni, epso_n in zip(self.h_lcao_kii, 
                                                           self.Vo_kni, 
                                                           epso_kn)]
            self.Huf_kii = np.asarray(Huf_kii)
        else:
            print "Using finite band limit (not using h_lcao)"
            epsu_kn = [eps_n[M:self.N] 
                       for eps_n, M in zip(self.eps_kn, self.M_k)]
            Huf_kii = [np.dot(dagger(Vu_ni) * epsu_n, Vu_ni) 
                       for Vu_ni, epsu_n in zip(self.Vu_kni, epsu_kn)]
            self.Huf_kii = np.asarray(Huf_kii)

        Hu_kii = [dots(dagger(Uu_li), dagger(b_il), Huf_ii, b_il, Uu_li)
                  for Uu_li, b_il, Huf_ii in zip(self.Uu_kli, self.b_kil,
                                                 self.Huf_kii)]
        self.Hu_kii = np.asarray(Hu_kii)
        self.H_kii = self.Ho_kii + self.Hu_kii
Esempio n. 2
0
    def calculate_hamiltonian_matrix(self, useibl=True):
        """Calculate H_kij = H^o_i(k)j(k) + H^u_i(k)j(k)
           i(k): Bloch sum of omega_i
        """

        epso_kn = [eps_n[:M] for eps_n, M in zip(self.eps_kn, self.M_k)]
        self.Ho_kii = np.asarray([np.dot(dagger(Uo_ni) * epso_n, Uo_ni) 
                                  for Uo_ni, epso_n in zip(self.Uo_kni, 
                                                           epso_kn)])

        if self.h_lcao_kii!=None and useibl:
            print "Using h_lcao and infinite band limit"
            Vo_kni = self.Vo_kni
            Huf_kii = [h_lcao_ii - np.dot(dagger(Vo_ni) * epso_n, Vo_ni)
                       for h_lcao_ii, Vo_ni, epso_n in zip(self.h_lcao_kii, 
                                                           self.Vo_kni, 
                                                           epso_kn)]
            self.Huf_kii = np.asarray(Huf_kii)
        else:
            print "Using finite band limit (not using h_lcao)"
            epsu_kn = [eps_n[M:self.N] 
                       for eps_n, M in zip(self.eps_kn, self.M_k)]
            Huf_kii = [np.dot(dagger(Vu_ni) * epsu_n, Vu_ni) 
                       for Vu_ni, epsu_n in zip(self.Vu_kni, epsu_kn)]
            self.Huf_kii = np.asarray(Huf_kii)

        Hu_kii = [dots(dagger(Uu_li), dagger(b_il), Huf_ii, b_il, Uu_li)
                  for Uu_li, b_il, Huf_ii in zip(self.Uu_kli, self.b_kil,
                                                 self.Huf_kii)]
        self.Hu_kii = np.asarray(Hu_kii)
        self.H_kii = self.Ho_kii + self.Hu_kii
    def calculate_edf(self, useibl=True):
        """Calculate the coefficients b_il in the expansion of the EDF.

        ``|phi_l> = sum_i b_il |f^u_i>``, in terms of ``|f^u_i> = P^u|f_i>``.

        To use the infinite band limit set useibl=True.
        N is the total number of bands to use.
        """

        for k, L in enumerate(self.L_k):
            if L == 0:
                assert L != 0, 'L_k=0 for k=%i. Not implemented' % k

        self.Vo_kni = [V_ni[:M] for V_ni, M in zip(self.V_kni, self.M_k)]

        self.Fo_kii = np.asarray(
            [np.dot(dagger(Vo_ni), Vo_ni) for Vo_ni in self.Vo_kni])

        if useibl:
            self.Fu_kii = self.s_lcao_kii - self.Fo_kii
        else:
            self.Vu_kni = [
                V_ni[M:self.N] for V_ni, M in zip(self.V_kni, self.M_k)
            ]
            self.Fu_kii = np.asarray(
                [np.dot(dagger(Vu_ni), Vu_ni) for Vu_ni in self.Vu_kni])
        self.b_kil = []
        for Fu_ii, L in zip(self.Fu_kii, self.L_k):
            b_i, b_ii = la.eigh(Fu_ii)
            ls = b_i.real.argsort()[-L:]
            b_il = b_ii[:, ls]  #pick out the eigenvec with largest eigenvals.
            normalize2(b_il, Fu_ii)  #normalize the EDF: <phi_l|phi_l> = 1
            self.b_kil.append(b_il)
Esempio n. 4
0
    def calculate_edf(self, useibl=True):
        """Calculate the coefficients b_il in the expansion of the EDF.

        ``|phi_l> = sum_i b_il |f^u_i>``, in terms of ``|f^u_i> = P^u|f_i>``.

        To use the infinite band limit set useibl=True.
        N is the total number of bands to use.
        """
        
        for k, L in enumerate(self.L_k):
            if L==0:
                assert L!=0, 'L_k=0 for k=%i. Not implemented' % k
        
        self.Vo_kni = [V_ni[:M] for V_ni, M in zip(self.V_kni, self.M_k)]
        
        self.Fo_kii = np.asarray([np.dot(dagger(Vo_ni), Vo_ni) 
                                  for Vo_ni in self.Vo_kni])
        
        if useibl:
            self.Fu_kii = self.s_lcao_kii - self.Fo_kii
        else:
            self.Vu_kni = [V_ni[M:self.N] 
                           for V_ni, M in zip(self.V_kni, self.M_k)]
            self.Fu_kii = np.asarray([np.dot(dagger(Vu_ni), Vu_ni) 
                                     for Vu_ni in self.Vu_kni])
        self.b_kil = [] 
        for Fu_ii, L in zip(self.Fu_kii, self.L_k):
            b_i, b_ii = la.eigh(Fu_ii)
            ls = b_i.real.argsort()[-L:] 
            b_il = b_ii[:, ls] #pick out the eigenvec with largest eigenvals.
            normalize2(b_il, Fu_ii) #normalize the EDF: <phi_l|phi_l> = 1
            self.b_kil.append(b_il)
Esempio n. 5
0
def single_zeta(paw, spin, verbose=False):
    angular = [
        ['1'],
        ['y', 'z', 'x'],
        ['xy', 'yz', '3z^2-r^2', 'xz', 'x^2-y^2'],
        [
            '3x^2y-y^3', 'xyz', '5yz^2-yr^2', '5z^3-3zr^2', '5xz^2-xr^2',
            'x^2z-y^2z', 'x^3-3xy^2'
        ],
    ]
    if verbose:
        print('index atom orbital')
    p_jn = []
    for a, P_ni in paw.wfs.kpt_u[spin].P_ani.items():
        setup = paw.wfs.setups[a]
        i = 0
        for l, n in zip(setup.l_j, setup.n_j):
            if n < 0:
                break
            for j in range(i, i + 2 * l + 1):
                p_jn.append(P_ni[:, j])
                if verbose:
                    print('%5i %4i %s_%s' %
                          (len(p_jn), a, 'spdf'[l], angular[l][j - i]))
            i += 2 * l + 1
    projections_nj = dagger(np.array(p_jn))
    assert projections_nj.shape[0] >= projections_nj.shape[1]
    return projections_nj
    def localize(self, calc, M=None, T=0, projections=None, ortho=True,
                 verbose=False):
        # M is size of Hilbert space to fix. Default is ~ number of occ. bands.
        if M is None:
            M = 0
            f_n = calc.get_occupation_numbers(0, self.spin)
            while f_n[M] > .01:
                M += 1

        if projections is None:
            projections = single_zeta(calc, self.spin, verbose=verbose)
        
        self.U_nn, self.S_jj = get_locfun_rotation(projections, M, T, ortho)
        if self.Z_nnc is None:
            self.value = 1
            return self.value
        
        self.Z_jjc = np.empty(self.S_jj.shape + (3,))
        for c in range(3):
            self.Z_jjc[:, :, c] = np.dot(dagger(self.U_nn),
                                     np.dot(self.Z_nnc[:, :, c], self.U_nn))
        
        self.value = np.sum(np.abs(self.Z_jjc.diagonal())**2)
        
        return self.value # / Bohr**6
Esempio n. 7
0
    def localize(self,
                 calc,
                 M=None,
                 T=0,
                 projections=None,
                 ortho=True,
                 verbose=False):
        # M is size of Hilbert space to fix. Default is ~ number of occ. bands.
        if M is None:
            M = 0
            f_n = calc.get_occupation_numbers(0, self.spin)
            while f_n[M] > .01:
                M += 1

        if projections is None:
            projections = single_zeta(calc, self.spin, verbose=verbose)

        self.U_nn, self.S_jj = get_locfun_rotation(projections, M, T, ortho)
        if self.Z_nnc is None:
            self.value = 1
            return self.value

        self.Z_jjc = np.empty(self.S_jj.shape + (3, ))
        for c in range(3):
            self.Z_jjc[:, :,
                       c] = np.dot(dagger(self.U_nn),
                                   np.dot(self.Z_nnc[:, :, c], self.U_nn))

        self.value = np.sum(np.abs(self.Z_jjc.diagonal())**2)

        return self.value  # / Bohr**6
def single_zeta(paw, spin, verbose=False):
    angular = [['1'],
               ['y', 'z', 'x'],
               ['xy', 'yz', '3z^2-r^2', 'xz', 'x^2-y^2'],
               ['3x^2y-y^3', 'xyz', '5yz^2-yr^2', '5z^3-3zr^2',
                '5xz^2-xr^2', 'x^2z-y^2z', 'x^3-3xy^2'],
               ]
    if verbose:
        print('index atom orbital')
    p_jn = []
    for a, P_ni in paw.wfs.kpt_u[spin].P_ani.items():
        setup = paw.wfs.setups[a]
        i = 0
        for l, n in zip(setup.l_j, setup.n_j):
            if n < 0:
                break
            for j in range(i, i + 2 * l + 1):
                p_jn.append(P_ni[:, j])
                if verbose:
                    print('%5i %4i %s_%s' % (len(p_jn), a,
                                             'spdf'[l], angular[l][j - i]))
            i += 2 * l + 1
    projections_nj = dagger(np.array(p_jn))
    assert projections_nj.shape[0] >= projections_nj.shape[1]
    return projections_nj
    def get_centers(self):
        z_jjc = np.empty(self.S_jj.shape+(3,))
        for c in range(3):
            z_jjc = np.dot(dagger(self.U_nn),
                            np.dot(self.Z_nnc[:,:,c], self.U_nn))

        scaled_c = -np.angle(z_jjc.diagonal()).T / (2 * pi)
        return (scaled_c % 1.0) * self.cell_c
Esempio n. 10
0
def get_locfun_rotation(projections_nj, M=None, T=0, ortho=False):
    """Mikkel Strange's localized functions.
    
    projections_nj = <psi_n|p_j>
    psi_n: eigenstates
    p_j: localized function
    Nw =  number of localized functions
    M = Number of fixed states
    T = Number of virtual states to exclude (from above) 
    """

    Nbands, Nw = projections_nj.shape
    if M is None:
        M = Nw
    L = Nw - M # Extra degrees of freedom
    V = Nbands - M - T# Virtual states
    a0_nj = projections_nj[:M, :]
    a0_vj = projections_nj[M:M + V, :]

    if V == 0:
        D_jj = np.dot(dagger(projections_nj), projections_nj)
        U_nj = 1.0 / np.sqrt(D_jj.diagonal()) * projections_nj
        S_jj = np.dot(dagger(U_nj), U_nj)
        assert np.diagonal(np.linalg.cholesky(S_jj)).min() > .01, \
               'Close to linear dependence.'
        if ortho:
            lowdin(U_nj, S_jj)
            S_jj = np.identity(len(S_jj))
        return U_nj, S_jj

    #b_v, b_vv = np.linalg.eigh(np.dot(a0_vj, dagger(a0_vj)))
    #T_vp = b_vv[:, np.argsort(-b_v)[:L]]
    b_j, b_jj = np.linalg.eigh(np.dot(dagger(a0_vj), a0_vj))
    T_vp = np.dot(a0_vj, b_jj[:, np.argsort(-b_j.real)[:L]])

    R_vv = np.dot(T_vp, dagger(T_vp))
    D_jj = np.dot(dagger(a0_nj), a0_nj) + np.dot(dagger(a0_vj),
                                                   np.dot(R_vv, a0_vj))
    D2_j = 1.0 / np.sqrt(D_jj.diagonal())
    ap_nj = D2_j * a0_nj
    ap_vj = D2_j * np.dot(R_vv, a0_vj)
    S_jj = np.dot(dagger(ap_nj), ap_nj) + np.dot(dagger(ap_vj), ap_vj)

    # Check for linear dependencies
    Scd = np.diagonal(np.linalg.cholesky(S_jj)).min()
    if Scd < 0.01:
        print(('Warning: possibly near linear dependence.\n'
               'Minimum eigenvalue of cholesky decomposition is %s' % Scd))

    if ortho:
        lowdin(ap_nj, S_jj)
        lowdin(ap_vj, S_jj)
        S_jj = np.identity(len(S_jj))

    U_nj = np.concatenate([ap_nj.flat, ap_vj.flat]).reshape(M+V, Nw)
    return U_nj, S_jj
Esempio n. 11
0
    def get_norm_of_projection(self):
        norm_kn = np.zeros((self.nk, self.N))
        Sinv_kii = np.asarray([la.inv(S_ii) for S_ii in self.S_kii])

        normo_kn = np.asarray([dots(Uo_ni, Sinv_ii, dagger(Uo_ni)).diagonal()
                    for Uo_ni, Sinv_ii in zip(self.Uo_kni, Sinv_kii)])
        
        Vu_kni = np.asarray([V_ni[M:self.N] 
                             for V_ni, M in zip(self.V_kni, self.M_k)])

        Pu_kni = [dots(Vu_ni, b_il, Uu_li) 
                for Vu_ni, b_il, Uu_li in zip(Vu_kni, self.b_kil, self.Uu_kli)]

        normu_kn = np.asarray([dots(Pu_ni, Sinv_ii, dagger(Pu_ni)).diagonal()
                    for Pu_ni, Sinv_ii in zip(Pu_kni, Sinv_kii)])

        return np.hstack((normo_kn, normu_kn))
Esempio n. 12
0
    def get_centers(self):
        z_jjc = np.empty(self.S_jj.shape + (3, ))
        for c in range(3):
            z_jjc = np.dot(dagger(self.U_nn),
                           np.dot(self.Z_nnc[:, :, c], self.U_nn))

        scaled_c = -np.angle(z_jjc.diagonal()).T / (2 * pi)
        return (scaled_c % 1.0) * self.cell_c
Esempio n. 13
0
def get_locfun_rotation(projections_nj, M=None, T=0, ortho=False):
    """Mikkel Strange's localized functions.
    
    projections_nj = <psi_n|p_j>
    psi_n: eigenstates
    p_j: localized function
    Nw =  number of localized functions
    M = Number of fixed states
    T = Number of virtual states to exclude (from above) 
    """

    Nbands, Nw = projections_nj.shape
    if M is None:
        M = Nw
    L = Nw - M  # Extra degrees of freedom
    V = Nbands - M - T  # Virtual states
    a0_nj = projections_nj[:M, :]
    a0_vj = projections_nj[M:M + V, :]

    if V == 0:
        D_jj = np.dot(dagger(projections_nj), projections_nj)
        U_nj = 1.0 / np.sqrt(D_jj.diagonal()) * projections_nj
        S_jj = np.dot(dagger(U_nj), U_nj)
        assert np.diagonal(np.linalg.cholesky(S_jj)).min() > .01, \
               'Close to linear dependence.'
        if ortho:
            lowdin(U_nj, S_jj)
            S_jj = np.identity(len(S_jj))
        return U_nj, S_jj

    #b_v, b_vv = np.linalg.eigh(np.dot(a0_vj, dagger(a0_vj)))
    #T_vp = b_vv[:, np.argsort(-b_v)[:L]]
    b_j, b_jj = np.linalg.eigh(np.dot(dagger(a0_vj), a0_vj))
    T_vp = np.dot(a0_vj, b_jj[:, np.argsort(-b_j.real)[:L]])

    R_vv = np.dot(T_vp, dagger(T_vp))
    D_jj = np.dot(dagger(a0_nj), a0_nj) + np.dot(dagger(a0_vj),
                                                 np.dot(R_vv, a0_vj))
    D2_j = 1.0 / np.sqrt(D_jj.diagonal())
    ap_nj = D2_j * a0_nj
    ap_vj = D2_j * np.dot(R_vv, a0_vj)
    S_jj = np.dot(dagger(ap_nj), ap_nj) + np.dot(dagger(ap_vj), ap_vj)

    # Check for linear dependencies
    Scd = np.diagonal(np.linalg.cholesky(S_jj)).min()
    if Scd < 0.01:
        print(('Warning: possibly near linear dependence.\n'
               'Minimum eigenvalue of cholesky decomposition is %s' % Scd))

    if ortho:
        lowdin(ap_nj, S_jj)
        lowdin(ap_vj, S_jj)
        S_jj = np.identity(len(S_jj))

    U_nj = np.concatenate([ap_nj.flat, ap_vj.flat]).reshape(M + V, Nw)
    return U_nj, S_jj
Esempio n. 14
0
    def get_norm_of_projection(self):
        norm_kn = np.zeros((self.nk, self.N))
        Sinv_kii = np.asarray([la.inv(S_ii) for S_ii in self.S_kii])

        normo_kn = np.asarray([dots(Uo_ni, Sinv_ii, dagger(Uo_ni)).diagonal()
                    for Uo_ni, Sinv_ii in zip(self.Uo_kni, Sinv_kii)])
        
        Vu_kni = np.asarray([V_ni[M:self.N] 
                             for V_ni, M in zip(self.V_kni, self.M_k)])

        Pu_kni = [dots(Vu_ni, b_il, Uu_li) 
                for Vu_ni, b_il, Uu_li in zip(Vu_kni, self.b_kil, self.Uu_kli)]

        normu_kn = np.asarray([dots(Pu_ni, Sinv_ii, dagger(Pu_ni)).diagonal()
                    for Pu_ni, Sinv_ii in zip(Pu_kni, Sinv_kii)])

        return np.hstack((normo_kn, normu_kn))
Esempio n. 15
0
 def calculate_rotations(self):
     Uo_kni = [Vo_ni.copy() for Vo_ni in self.Vo_kni]
     Uu_kli = [np.dot(dagger(b_il), Fu_ii) 
               for b_il, Fu_ii in zip(self.b_kil, self.Fu_kii)]
     #Normalize such that <omega_i|omega_i> = <f_i|f_i>
     for Uo_ni, Uu_li, s_ii in zip(Uo_kni, Uu_kli, self.s_lcao_kii):
         normalize(Uo_ni, Uu_li, s_ii.diagonal())
     self.Uo_kni = Uo_kni
     self.Uu_kli = Uu_kli
Esempio n. 16
0
 def calculate_rotations(self):
     Uo_kni = [Vo_ni.copy() for Vo_ni in self.Vo_kni]
     Uu_kli = [np.dot(dagger(b_il), Fu_ii) 
               for b_il, Fu_ii in zip(self.b_kil, self.Fu_kii)]
     #Normalize such that <omega_i|omega_i> = <f_i|f_i>
     for Uo_ni, Uu_li, s_ii in zip(Uo_kni, Uu_kli, self.s_lcao_kii):
         normalize(Uo_ni, Uu_li, s_ii.diagonal())
     self.Uo_kni = Uo_kni
     self.Uu_kli = Uu_kli
Esempio n. 17
0
 def get_hamiltonian(self, calc):
     # U^T diag(eps_n) U
     eps_n = calc.get_eigenvalues(kpt=0, spin=self.spin)
     return np.dot(dagger(self.U_nn) * eps_n, self.U_nn)
Esempio n. 18
0
 def get_hamiltonian(self, calc):
     # U^T diag(eps_n) U
     eps_n = calc.get_eigenvalues(kpt=0, spin=self.spin)
     return np.dot(dagger(self.U_nn) * eps_n, self.U_nn)
 def calculate_overlaps(self):
     Wo_kii = [np.dot(dagger(Uo_ni), Uo_ni) for Uo_ni in self.Uo_kni]
     Wu_kii = [np.dot(dagger(Uu_li), Uu_li) for Uu_li in self.Uu_kli]
     #Wu_kii = [dots(dagger(Uu_li), dagger(b_il), Fu_ii, b_il, Uu_li)
     #for Uu_li, b_il, Fu_ii in zip(self.Uu_kli, self.b_kil, self.Fu_kii)]
     self.S_kii = np.asarray(Wo_kii) + np.asarray(Wu_kii)
Esempio n. 20
0
def normalize2(C, S):
    C /= np.sqrt(dots(dagger(C), S, C).diagonal())
def normalize2(C, S):
    C /= np.sqrt(dots(dagger(C), S, C).diagonal())
Esempio n. 22
0
 def calculate_overlaps(self):
     Wo_kii = [np.dot(dagger(Uo_ni), Uo_ni) for Uo_ni in self.Uo_kni]
     Wu_kii = [np.dot(dagger(Uu_li), Uu_li) for Uu_li in self.Uu_kli]
     #Wu_kii = [dots(dagger(Uu_li), dagger(b_il), Fu_ii, b_il, Uu_li) 
     #for Uu_li, b_il, Fu_ii in zip(self.Uu_kli, self.b_kil, self.Fu_kii)]
     self.S_kii = np.asarray(Wo_kii) + np.asarray(Wu_kii)