[wien2k] fix dmftproj port for non-centrosymmetric cells#19
Draft
krystophny wants to merge 16 commits into
Draft
[wien2k] fix dmftproj port for non-centrosymmetric cells#19krystophny wants to merge 16 commits into
krystophny wants to merge 16 commits into
Conversation
…CaOs2) dftkit's Wien2k converter is only covered by the non-SOC SrVO3 case. This adds a SOC + spin-polarized golden test: CaOs2, a cubic fluorite cell with two symmetry-equivalent correlated Os atoms whose magnetic point group has 16 operations, 8 of them time-reversal. It exercises the combined-spin 'ud' block and the time-reversal symmetry path of dmftproj + the converter on a small 8-k-point fixture, validated by h5diff against a reference produced by this converter.
triqs_dftkit.wien2k.symqmc.write_symqmc builds the correlated-shell spinor symmetry matrices (case.symqmc) from case.dmftsym + case.indmftpr + case.struct, reproducing the dmftproj Fortran construction (Wigner D, orbital and spinor time-reversal operators, angular-harmonics basis transform, spin-1/2 phase blocks). It is a full replacement of the symqmc-writing, covering every path: - non-mixing spin-diagonal bases (complex, cubic): the up/up block scaled by the +-(a+g)/2 phase, with the orbital time-reversal operator on the magnetic operations; - mixing fromfile bases that couple spin (the |j,m_j> basis): the full 2(2l+1) spinor representation P spinrot P^dag with the spinor time-reversal -i sigma_y (x) T on the magnetic operations; - l=0 (s) shells: the 2x2 spin phase block. Verified against the dmftproj Fortran output for all three paths on CaOs2 (16 operations, 8 time-reversal): the cubic converter HDF5 is identical (h5diff) and every matrix matches to machine precision. The mixing fromfile path is the one dft_tools #148 singles out; dmftproj reads that basis with a single-precision CMPLX cast and a 250-column line cap (set_ang_trans.f), so its case.symqmc carries a ~1e-7 error there while this generator is full double precision. Tests: the cubic path reuses the SOC golden h5; the mixing and l=0 paths compare to the dmftproj matrix data (single precision, ~26 kB) and assert unitarity.
Port the dmftproj almblm reader and case.oubwin writer to numpy. Given
case.almblm{up,dn} and the energy window in case.indmftpr, select the
contiguous band range per k-point and spin and write case.oubwin{up,dn}
in the dmftproj format. Proven byte-identical to the Fortran output on
CaOs2 (proj_mode 0; band-index modes raise NotImplementedError pending a
fixture). Part of TRIQS#7.
Port the dmftproj projector core to numpy: read the almblm Alm/Clm coefficients, build the raw correlated projector over the in-window bands, apply the local rotation and cubic basis transform, Loewdin-orthonormalize the stacked shells (orthogonal_wannier_SO), and write case.ctqmcout. Matches the dmftproj CaOs2 reference to 4.3e-7 (the single-precision basis-transform floor); integer fields identical. cubic/complex bases; fromfile raises NotImplementedError pending a fixture. almblm fixtures switched to gzip (shared with the oubwin test). Part of TRIQS#7.
Port the dmftproj case.sympar writer to numpy: the symmetry matrices for all included shells (correlated + partial), the partial-charge analog of symqmc. Matches the dmftproj CaOs2_partial reference (an added uncorrelated Ca d-shell) to 4.4e-8. cubic/complex bases; fromfile raises NotImplementedError. Part of TRIQS#7.
Port the dmftproj case.parproj writer to numpy: the partial projectors and density matrices for all included orbitals (radial s12 normalization, the point-integrated density matrix, the Rloc spinor rotations). Matches the dmftproj CaOs2_partial reference to 1.2e-8. cubic/complex bases; fromfile raises NotImplementedError. Part of TRIQS#7.
The five case.* generators each carried their own copy of the almblm reader, Wigner-D, angular-basis transform, indmftpr/dmftsym parsers, band-window selection and formatters. Extract them once into _dmftproj and make every generator a thin consumer: 2260 -> 1699 lines, no shared function defined twice. Add isolated unit tests for the shared primitives. Generators byte/1e-6 identical to before (all golden tests unchanged). Part of TRIQS#7.
…sion fix)
Use the exact analytic cubic harmonics (no float32 cast) and call the same
LAPACK/BLAS routines the Fortran does for the Loewdin step (scipy ZHEEV('V','U')
and ZGEMM with the matching trans flags, not numpy's ZHEEVD / conj-transpose
copies). Regenerate references from the precision-fixed dmftproj (PR TRIQS#14) with
full-precision templates.
The port is now exact to machine precision on every output:
oubwin byte-identical
symqmc 1.5e-14
sympar 1.9e-14
parproj 1.5e-14
ctqmcout 1.5e-14 (full-rank window: 50 bands > 20 correlated spin-orbitals,
so the Loewdin overlap O is non-singular and its
eigenvectors are unique. The physical narrow-window CaOs2
makes O rank-deficient; O^{-1/2} then amplifies the
last-ULP libm difference, a property of that degenerate
case, not the port.)
Tolerances tightened to 1e-11. Part of TRIQS#7.
…window Replace the NotImplementedError guards in ctqmcout/sympar/parproj (fromfile) and oubwin/ctqmcout (proj_mode). fromfile reuses symqmc's spinor machinery (now shared in _dmftproj: mixing_rotrep, rotloc_rotl_so); proj_mode 1/2 add the band-index window selection (set_projections.f). All exercised by full-rank fixtures from the precision-fixed dmftproj and matched to machine precision (fromfile 1.9e-14, proj_mode 1.5e-14, oubwin byte-identical). Part of TRIQS#7.
The band-structure analog of case.ctqmcout, feeding the converter's convert_bands_input. Same correlated-projector machinery on a band k-path; reads nkband from case.klist_band and the Fermi energy from the last line of case.indmftpr (band-mode convention). Fixture generated by a Wien2k band run (lapw1/lapwso/lapw2 -band) + the precision-fixed dmftproj -band on a wide (full-rank) window; the port matches to 2.8e-16. Completes the converter's dmftproj inputs. Part of TRIQS#7.
The Fortran stays on the generator stack; only the capstone removes it.
The generators were validated only for the SO case (2*(2l+1) spinor matrices); the non-SO path (ifSO=0, the common DMFT case e.g. SrVO3) wrongly emitted SO-sized matrices. Handle ifSO=0 in symqmc/ctqmcout/sympar/parproj: (2l+1) matrices, per-spin orthonormalization (orthogonal_wannier), bare (2l+1) representation and Rloc, two independent density-matrix spin blocks, timeinv always false. Add wien2k_noso test against a precision-fixed dmftproj run without -so (CaOs2 spin-polarized non-SO, full-rank window): ctqmcout 1.4e-15, symqmc 2.1e-14, sympar/parproj at machine precision; SO tests unchanged. Part of TRIQS#7.
dmat received np.linalg.det(krotm) as the rotation parity, but krotm in case.dmftsym is the proper part (determinant +1 even for improper ops); the parity lives in iprop. For even l the (-1)^l factor is +1 either way, so the d-shell fixtures never exposed it; for odd l the symmetry matrices came out with the wrong sign. Use iprop in symqmc, sympar and the mixing spinor representation. Add p (l=1) and f (l=3) generator tests against precision-fixed dmftproj. The f-shell projector is rank-deficient on the standard CaOs2 bands (Os carries no f weight near E_F); CaOs2_fshell.almblm is recomputed with a raised lapw1/lapwso band cutoff so a high-energy window has real l=3 character and the Loewdin overlap is full rank. Both match to ~1e-14.
The port was validated only on centrosymmetric, trivial-rotloc, d-shell fixtures (CaOs2, SrVO3). Non-centrosymmetric spin-orbit cells (the dft_tools#148 regime) hit three convention bugs in the p-shell and local-frame paths: - _CUBIC[1]: the cubic l=1 (p) transform was un-normalized and row-ordered pz,py,px instead of the Fortran px,py,pz, so P P^dag != I. _CUBIC[2] (d) was correct, so the d-shell tests never caught it. - The non-mixing magnetic (time-inversion) operations used conj(P.T) where the antiunitary basis change needs P.T (symqmc and sympar shell matrices, and the ctqmcout Rloc rotrep). The mixing path already used P.T; the non-mixing path was inconsistent. It is a no-op for real bases (complex-identity, cubic-d), so only the p-shell with its imaginary p_y row was affected. - The non-mixing ctqmcout path dropped the struct reference local rotation rotloc_ref (beta=pi/2 for Te) that the mixing path composes via rotloc_rotl_so. Both the Rloc rotrep and the projector rotation now compose it; the projector uses dmat(R[isym]) @ dmat(rotloc_ref), the orbital dmat of the full rotloc (rot_projectmat.f), no spin part, no time reversal. Verified against the dmftproj Fortran on the identical lapw2 -almd output (tellurium, P3_1 21, SP+SO): case.symqmc and case.sympar match to 6e-8 and case.ctqmcout (Rloc rotrep + all projectors) to 2e-8, the float32 cubic-template floor; the only larger field is elecn (36 vs 35.999998, a float32 almblm value). Centrosymmetric CaOs2 is byte-identical. Adds a non-centrosymmetric tellurium case.symqmc regression test (small symmetry inputs, no almblm) and a cubic l=1 unitarity check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the non-centrosymmetric failure mode of the dmftproj port. Stacked on #16; the change is the single commit at the tip (4 source files + a regression test), independent of the #148 converter fix (#18).
The port reproduces the Fortran to machine precision on the centrosymmetric fixtures (CaOs2, SrVO3), but those share trivial
rotloc_ref, a real (d-shell) cubic transform, and inversion symmetry. A non-centrosymmetric spin-orbit cell (the dft_tools#148 regime) exposes three convention bugs in the p-shell and local-frame paths:_CUBIC[1]: the cubic l=1 (p) transform was un-normalized and row-orderedpz,py,pxinstead of the Fortranpx,py,pz, soP P^dag != I._CUBIC[2](d) was correct, so the d-shell tests never caught it.conj(P.T)where the antiunitary basis change needsP.T(symqmc/symparshell matrices and thectqmcoutRloc rotrep). The mixing path already usedP.T. A no-op for real bases, so only the p-shell's imaginaryp_yrow was affected.ctqmcoutpath dropped the struct reference local rotationrotloc_ref(beta=pi/2 for Te) that the mixing path composes viarotloc_rotl_so. The Rloc rotrep and the projector rotation now compose it; the projector usesdmat(R[isym]) @ dmat(rotloc_ref), the orbitaldmatof the full rotloc (rot_projectmat.f).Verification
Against the dmftproj Fortran on the identical
lapw2 -almdoutput (tellurium, P3_1 21, point group 32, SP+SO), field-by-field:The floor is the Fortran's single-precision cubic template (~6e-8). Centrosymmetric CaOs2 is byte-identical before/after (
symqmc,sympar,ctqmcoutmax diff 0.000e+00), so the change is a no-op there.Before this fix, the same Te comparison diverges by 3.0 (
symqmc) and 1.5 (ctqmcout).The added
Py_wien2k_symqmc_noncentrosymtest reproduces the symqmc check from small symmetry inputs (no almblm); a cubic l=1 unitarity assertion is added to the common test. The fullctqmcoutmatch needs the 193 MB Te almblm, so it is verified out of tree (above) rather than committed as a fixture.