Skip to content

Wannier90 converter with disentanglement fails when used with develop branch of Wannier90 due to u_dis.mat format change #1

Description

@jaemolihm

If using Wannier90 or QE converter with the develop branch of Wannier90, reading of u_dis.mat fails because its format has changed in Wannier90. There is no problem when using (i) Wannier90 v3.1.0 (this is the latest release as of Feb 2026), or (ii) disentanglement is not used, or (iii) only high-energy bands are truncated by the disentanglement window.

Detail

https://github.com/TRIQS/dftkit/blob/unstable/python/triqs_dftkit/wannier90/converter.py#L668-L674

        #initiate U disentanglement matrices and fill from file 'seedname_u_dis.mat'
        udis_mat_spin = np.zeros([n_k, num_ks_bands, n_wannier_spin], dtype=complex)
        for ik in range(n_k):
            # this assumes that u_dis_mat first index is the first state in the dis window
            # which is different from the eig file which starts with the first KS ev given to w90
            udis_mat_spin[ik, inside_window[ik]] = udis_data[ik, :, :n_inside_per_k[ik]].T
            if not np.allclose(udis_data[ik, :, n_inside_per_k[ik]:], 0):
                raise ValueError('This error could come from rounding of the band window in the seedname.wout. '
                                 + 'Never use default outer window but something wider and '
                                 + 'check that your outer window is not close to any band energy.')

In this code, one reads Wannier90 u_dis.mat assuming that the first n_inside_per_k[ik] band indices are data, and the rest is zero. For example, if there are 5 bands and only band 2, 3, 4 are inside the outer window, the data should be [A, B, C, 0, 0].

However, this changed in the develop branch of Wannier90 in commit wannier-developers/wannier90@e292d99 (Jan 10, 2024) Now, the format is to keep the original band order, so [0, A, B, C, 0]. (Arguably, this is a more sensible format.)

https://github.com/wannier-developers/wannier90/blob/0137a03c00acfe099cd45c50ff7f92157f52ff5f/src/plot.F90#L2445-L2460

      open (newunit=matunit, file=trim(seedname)//'_u_dis.mat', form='formatted')
      write (matunit, *) header
      write (matunit, *) num_kpts, num_wann, num_bands
      do nkp = 1, num_kpts
        utmp = 0.d0
        ioff = dis_manifold%nfirstwin(nkp)
        nbw = dis_manifold%ndimwin(nkp)
        utmp(ioff:ioff + nbw - 1, :) = u_matrix_opt(1:nbw, :, nkp)
        write (matunit, *)
        write (matunit, '(f15.10,sp,f15.10,sp,f15.10)') kpt_latt(:, nkp)
        !write (matunit, '(f15.10,sp,f15.10)') ((u_matrix_opt(i, j, nkp), i=1, num_bands), j=1, num_wann)
        write (matunit, '(f15.10,sp,f15.10)') ((utmp(i, j), i=1, num_bands), j=1, num_wann)
      end do
      close (matunit)
      deallocate (utmp)
    endif

A fix is to change the parsing code as follows

            # IMPORTANT: Wannier90 behavior changed in commit e292d991 (Jul 2023, included since v4.0)
            # Now u_dis.mat uses the original band indices, instead of filling the first n_inside_per_k
            # states and then zeros.
            udis_mat_spin[ik, :, :] = udis_data[ik, :, :].T
            if not np.allclose(udis_mat_spin[ik, ~inside_window[ik], :], 0):
                raise ValueError('Bands outside the disentanglement window have non-zero entries in u_dis.mat at k-point {}. '
                                 .format(ik)
                                 + 'This could come from rounding of the band window in seedname.wout. '
                                 + 'Never use the default outer window; use something wider and '
                                 + 'check that your outer window is not close to any band energy.')

However, this breaks backward compatibility. One may try both and choose what works. But I am not sure this is safe.

I believe one solution is to update Wannier90 further to also write seedname_v.mat where V = U_dis * U. Then if v.mat is present, we can read it with the new format, and otherwise use the old format. I think writing seedname_v.mat is a reasonable thing that Wannier90 can have. (But, this will not solve the problem for commits between v3.1 and v4.0 releases.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions