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.)
If using Wannier90 or QE converter with the develop branch of Wannier90, reading of
u_dis.matfails 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
In this code, one reads Wannier90
u_dis.matassuming that the firstn_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
A fix is to change the parsing code as follows
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.matwhereV = U_dis * U. Then ifv.matis present, we can read it with the new format, and otherwise use the old format. I think writingseedname_v.matis a reasonable thing that Wannier90 can have. (But, this will not solve the problem for commits between v3.1 and v4.0 releases.)