wannier-developers / wannier90

Official repository of the Wannier90 code
http://www.wannier.org
GNU General Public License v2.0
237 stars 139 forks source link

wannier center is not accurate in postw90 #378

Open jincao2013 opened 3 years ago

jincao2013 commented 3 years ago

In calculating r matrix rmn(R)=<0m|r|Rn>, the Eq. (31) of Ref. [1] is used for diagonal part, and the Eqs. (C14)-(C16) of Ref. [1] is used for others. The previous equation gives more accurate results in the sense that the calculated wannier center is located at the atom's site (if guiding_centres=T is used in building wannier functions). This strategy is implemented as default in wannier90 code (see subroutine hamiltonian_write_rmn in hamiltonian.F90), and the resulting wannier centers are presented in wannier90.wout.

However, such a strategy is not implemented as default in postw90 (see subroutine get_AA_R in get_oper.F90). I have manually extracted the r matrix (AA_R in postw90) in get_AA_R. In my test case, the diagonal part rn=<0n|r|0n> is not in line with the ones in wannier90.wout, and is not located at atom's site (I only did disentanglement in building wannier functions). One can add transl_inv = T to resolve this issue, but this tag is False by default, and is not introduced in the user guide to date.

Note that the subroutine get_AA_R is called by numbers type of jobs, such as AHC, SHC, optical conductivity, orbital magnetisation, etc.

Reference [1] Phys. Rev. B 56, 12847 (1997).

jincao2013 commented 3 years ago

Note the same problem has been posted in #302 and has not been solved to date.

stepan-tsirkin commented 2 years ago

We also discovered this issue while working on the WanierBerri code .

The workaround by @jaemolihm was to overwrite the diagonal part of AA_R by the values read from the .chk . I suggest that the same can be done in postw90.x : replace lines:

            do i = 1, num_wann
              AA_q_diag(i, idir) = AA_q_diag(i, idir) &
                                   - wb(nn)*bk(idir, nn, ik)*aimag(log(S(i, i)))

by

        if (guiding_centeres) then
            do i = 1, num_wann
              AA_q_diag(i, idir) = wannier_centres(idir,i)
        else
            do i = 1, num_wann
              AA_q_diag(i, idir) = AA_q_diag(i, idir) &
                                   - wb(nn)*bk(idir, nn, ik)*aimag(log(S(i, i)))
        endif

What do you think?

jincao2013 commented 2 years ago

@stepan-tsirkin It seems the wannier_centres is also calculated from Eq.(31) of MV97 in wannier90.x.