Skip to content

Fix TDOS/PDOS energy grid misalignment, unify DOS output file naming, and improve plot-tools TDOS - #8144

Open
DanielZhao0432 wants to merge 6 commits into
deepmodeling:developfrom
DanielZhao0432:261013-fix-dos-pdos-issues
Open

DanielZhao0432 wants to merge 6 commits into
deepmodeling:developfrom
DanielZhao0432:261013-fix-dos-pdos-issues

Conversation

@DanielZhao0432

Copy link
Copy Markdown
Collaborator

Reminder

  • I have read AGENTS.md and docs/developers_guide/agent_governance.md.
  • I have linked an issue or explained why this PR does not need one.
  • I have added adequate unit tests and/or case tests, or explained why not.
  • I have listed the exact verification commands run and their results.
  • I have described user-visible behavior changes, including INPUT parameter changes.
  • I have explained core-module impact for ESolver, HSolver, ElecState, Hamilt, Operator, Psi, or other source/ changes.
  • I have requested any needed governance exception below.

Linked Issue

No existing issue: the four problems were found while testing the current tools/02_postprocessing/plot-tools DOS/PDOS workflow against the latest ABACUS output (all of them are stably reproducible, see "What's changed").

Unit Tests and/or Case Tests for my changes

  • Commands run:
    • cmake --build build -j $(nproc) (incremental, after each C++ commit)
    • OMP_NUM_THREADS=1 ctest --test-dir build -V -R MODULE_DOS
    • python3 tools/03_code_analysis/agent_governance_check.py --base origin/develop --head HEAD --format text
    • Runtime regression (OMP_NUM_THREADS=1 mpirun -np 2 ./build/abacus_basic_para): PW-Al (examples/13_dos/01_pw_Al), LCAO-Si2 (examples/13_dos/02_lcao_Si2), LCAO-Fe-AFM nspin=2 (examples/03_spin_polarized/03_Fe_AFM), and the nspin=4 case tests/03_NAO_multik/scf_out_dos_spin4, followed by abacus-plot -d/-p/-o checks on the produced files.
  • Result summary:
    • MODULE_DOS unit tests: 3/3 passed after each C++ commit and after merging upstream/develop.
    • Governance check: no findings.
    • All four cases produce the unified names (doss1g1.txt/doss2g1.txt/pdoss1g1.txt/pdoss2g1.txt); TDOS and PDOS energy grids are now point-by-point identical; totaldosref=38 from the spin4 case still matches its reference (the integrate collector globs dos*.txt, so it is compatible with the new names). plot-tools: default smeared-column plot gives a smooth TDOS and ~0 gap for Al; smearing=false reproduces the raw histogram; all three tdosfile entry styles (list / either spin file / directory) produce identical spin-up/down plots; gaussian_smearing matches the on-disk smeared column to ~1e-5; TDOS figures now show the "Energy(eV)" x-axis label and PDOS multi-subplot layout is unchanged.
  • Checks not run, with reason: the full integration test suite (prohibitive local cost; left to CI). Everything the suite checks through dos*.txt globs is unaffected by the rename.

What's changed?

  1. TDOS/PDOS energy grid alignment (bug fix): cal_dos() labeled each histogram bin [E, E+de) with its right edge, so the TDOS grid started at emin+de while the PDOS text grid starts at emin, and the two files could not be compared point-by-point. Bins are now labeled with their left edge, so both files share the same emin + n*de grid. Only the energy column shifts; all data columns are unchanged.
  2. Unified DOS output file naming (breaking change): PW and LCAO now write the same file names, doss{spin}g{geom}.txt (TDOS) and pdoss{spin}g{geom}.txt (PDOS, LCAO only). Previously PW wrote dos.txt/dos1.txt/dos2.txt while LCAO wrote doss{spin}g{geom}_nao.txt / pdoss{spin}g{geom}_nao.txt. Downstream scripts that parse the old names need to be updated. The basis parameter of ModuleIO::write_pdos_text became unused and was removed (both call sites updated).
  3. plot-tools TDOS plots the smeared column by default (bug fix): TDOS plotted the raw per-bin histogram column (unit: states per bin), which produced spiky curves and false band gaps for metals (e.g. 0.09 eV for Al). It now plots dos_smear (unit 1/eV) by default; a smearing switch (plot(..., smearing=False) or "smearing": false in config.json) restores the raw column, and abacus_plot.utils.gaussian_smearing() lets users apply their own smearing width to it.
  4. plot-tools TDOS supports per-spin files (bug fix): since the DOS output refactoring, ABACUS writes one 5-column file per spin channel, but TDOS only understood the legacy 9-column single-file format, so spin-polarized TDOS could not be plotted. tdosfile now accepts a list of both spin files, a single spin file (its counterpart is found automatically, in both directions so doss2* works too), or a directory; energy grids are validated before merging. nspin=1/2/4 are all supported.
  5. plot-tools x-axis label (bug fix): TDOS figures had no x-axis label. It is now set centrally in DOSPlot._set_figure (bottom-most subplot only when axes share x), and the duplicated set_xlabel calls in the PDOS branches were removed.

Governance Notes

  • INPUT/docs changes: no INPUT parameter semantics changed. The out_dos description was updated in source/source_io/module_parameter/read_inp_out.cpp (the annotation from which the input reference is generated) and in docs/advanced/elec_properties/dos.md, docs/advanced/output_files/output-specification.md, examples/13_dos/README and the examples/13_dos/*/run.sh file checks; tests/performance/catch_properties.sh was updated to the new file name.
  • Core module impact: limited to source/source_io/module_dos and the DOS output call path in source/source_io/module_ctrl/ctrl_output_pw.cpp (passing the real ionic step so the geometry index is always tagged). No ESolver/HSolver/ElecState/Hamilt logic is touched.
  • Exceptions requested: none.

…h PDOS grid

cal_dos() recorded each energy bin [E, E+de) at its right edge, so the
TDOS energy grid started at emin+de while the PDOS text grid starts at
emin. Both files now share the same emin + n*de grid, allowing
point-by-point comparison of TDOS and PDOS output. Only the energy
column shifts by one step; dos/dos_int/dos_smear values are unchanged.

Verified: ctest --test-dir build -V -R MODULE_DOS (3/3 passed).
…eom}.txt

- write_dos_pw: dos.txt/dos1/dos2.txt -> doss{spin}g{geom}.txt, the same
  scheme as LCAO; the geometry index is now always tagged by passing the
  real istep in ctrl_output_pw
- write_dos_lcao / write_pdos_text: drop the _nao/_pw basis suffix
  (pdoss{spin}g{geom}.txt); the now-unused basis parameter of
  write_pdos_text is removed
- docs (parameters.yaml, input-main.md, dos.md, output-specification.md),
  examples/13_dos and tests/performance/catch_properties.sh updated
  accordingly

Verified: ctest --test-dir build -V -R MODULE_DOS (3/3 passed).
…pairing, x-axis label

- TDOS plots the Gaussian-smeared column (dos_smear, unit 1/eV) by
  default instead of the raw per-bin histogram; a new smearing switch
  (plot(..., smearing=False) or "smearing": false in config.json)
  restores the raw column, and utils.gaussian_smearing() lets users
  apply their own smearing width to it
- TDOS accepts per-spin file pairs of the new text format: tdosfile may
  be a list of both spin files, a single spin file (paired in both
  directions, so doss2* works too), or a directory; energy grids are
  checked before merging. nspin=4 single spinor-summed files work as
  a single channel
- the x-axis label is set centrally in DOSPlot._set_figure (bottom-most
  subplot only), so TDOS figures now show 'Energy(eV)' and the
  duplicated set_xlabel calls in PDOS branches are removed
…dos-issues

# Conflicts:
#	docs/advanced/input_files/input-main.md
#	docs/parameters.yaml
@DanielZhao0432

Copy link
Copy Markdown
Collaborator Author

@ABACUS-PR-BOT please review this PR.

@DanielZhao0432 DanielZhao0432 added Bugs Bugs that only solvable with sufficient knowledge of DFT Input&Output Suitable for coders without knowing too many DFT details Refactor Refactor ABACUS codes labels Oct 14, 2026

@ABACUS-PR-BOT ABACUS-PR-BOT left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review of 5d88d5b with a fresh independent reviewer. Trusted source-governance and whitespace checks passed; builds, runtime/plotting tests and CI verification were not performed. Inline feedback separates the compatibility defect from nonblocking follow-ups.

Comment thread tools/02_postprocessing/plot-tools/abacus_plot/dos.py Outdated
Comment thread tools/02_postprocessing/plot-tools/abacus_plot/dos.py Outdated
Comment on lines +213 to +215
// label the bin [e_old, curr_energy) with its left edge so that the
// TDOS grid (emin + n*de_ev) matches the PDOS grid point-by-point
ene.push_back(e_old);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: an exact endpoint case still has different grid lengths: emin=0, emax=1, de=0.5 produces two TDOS rows (0, 0.5) versus three PDOS points (0, 0.5, 1). The strict while loop predates this PR, so this is a residual limitation of the alignment fix. Please qualify the point-by-point claim and track a common integer-indexed grid plus a row-count/endpoint regression; the code correction can follow separately.

Comment thread examples/13_dos/README Outdated
Comment thread tools/02_postprocessing/plot-tools/README.md Outdated
Comment thread tools/02_postprocessing/plot-tools/abacus_plot/utils.py Outdated
Comment thread tools/02_postprocessing/plot-tools/abacus_plot/dos.py
Comment thread tools/02_postprocessing/plot-tools/README.md Outdated
…pairing robustness

- guard get_subplotspec()/is_last_row() behind getattr/hasattr so
  plotting still works on matplotlib < 3.4 (setup.py declares no
  minimum matplotlib version)
- canonicalize a two-file tdosfile list so the spin-1 channel always
  comes first (a reversed list no longer swaps the up/down labels)
- directory discovery now pairs spin files by identical name suffix
  (doss1g1.txt only pairs doss2g1.txt, never doss2g2.txt) and falls
  back to the legacy PW dos.txt
- docs: the raw dos column is described as states-per-bin (not 1/eV);
  the smearing switch note now covers its effect on the shift=true
  gap estimate; PDOS file patterns corrected to pdoss1*/pdoss2*

Verified with abacus_dos_test cases: reversed list equals forward list,
mixed-geometry directory stays single-spin, legacy dos.txt directory
loads, TDOS/PDOS plots unchanged.
Accumulate the smeared DOS in row chunks (default 1024) instead of
allocating the dense npoints x npoints Gaussian matrix, which would take
~3.2 GB at 20000 energy points. Numerical results are unchanged
(identical to machine precision), verified against the on-disk smeared
column and with 20000-point stress input (~0.7 GB peak RSS).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bugs Bugs that only solvable with sufficient knowledge of DFT Input&Output Suitable for coders without knowing too many DFT details Refactor Refactor ABACUS codes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants