Skip to content

Determine GPAW band edges from occupations - #162

Merged
kavanase merged 16 commits into
SMTG-Bham:IO_refactorfrom
sblisesivdin:fix/gpaw-occupation-band-edges
Nov 5, 2026
Merged

kavanase merged 16 commits into
SMTG-Bham:IO_refactorfrom
sblisesivdin:fix/gpaw-occupation-band-edges

Conversation

@sblisesivdin

Copy link
Copy Markdown

This PR replaces Fermi-level-based GPAW band-edge selection with occupation-based determination.

Raw occupations identify filled and empty states across spin channels and k-points. Partially occupied states, changes in occupied-band count across k-points, or overlapping occupied and empty levels give a zero gap, avoiding spurious finite gaps for metals on discrete meshes.

Calculations without both occupied and unoccupied states raise an informative error instead of substituting the Fermi level for an uncomputed edge. Charged supercells continue to omit host band edges.

Validation with GPAW 26.7:

  • Eight new tests passed using real MgO, Cu, and spin-polarised O2 calculations, including zero and finite smearing for Cu, restart round trips, and MgO with only occupied bands.
  • The existing general GPAW output-reader test passed.
  • All applicable pre-commit checks passed.
  • The full test suite was not run.

The documentation describes the occupation threshold and smearing limitations. This addresses the band-edge prerequisite in #156; PAW projection mapping and shallow-defect analysis remain separate work.

Based on the latest IO_refactor, including the merged #161 changes.

@SMTG-Bham SMTG-Bham deleted a comment from coderabbitai Bot Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 68b12e76-d189-44ce-a0f9-70b1f6d68886

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kavanase

kavanase commented Nov 5, 2026

Copy link
Copy Markdown
Member

Thanks @sblisesivdin!

I've pushed a series of changes to the branch, building on this PR. Here's a summary of what has changed and why (with the help of Claude):

Band edges

  • Along with GPAW band edges now coming from the occupations rather than from partitioning eigenvalues at the Fermi level, the per-state occupation thresholds (0.1/0.9) are replaced with band filling (electron counting). For each spin channel, the number of filled bands is the k-point-weighted sum of the raw occupations. The VBM is then the maximum of band n - 1 over k-points, and the CBM the minimum of band n (_get_band_edges in doped/io/gpaw/outputs.py).
    • Why: with smearing, the band-edge states of narrow-gap semiconductors are partially occupied. Per-state thresholds then report a spurious metal (or depend on the threshold and smearing width), whereas the number of filled bands (the occupation sum) is unaffected by smearing when there is a gap.
  • Metals: fractional band filling, or overlapping or near-degenerate band edges (within 10 meV), give a zero gap with the VBM and CBM both at the Fermi level.
  • Charged calculations: band edges are now determined for all calculations, including charged supercells, as for VASP. The host reference still comes only from the bulk calculation.
  • Competing phases: GPAW competing-phase entries now include the band gap in entry.data["summary"].

GPAW defaults

The defaults moved from hard-coded values in _generate_script to doped/io/gpaw/GPAW_sets/GPAW_DefectSet.yaml (default_gpaw_settings, now included in the docs). They were also updated to match doped's VASP recommendations, and any of them can be overridden with gpaw_settings:

  • HSE06 hybrid DFT in plane-wave mode (400 eV cutoff; GPAW only supports HSE06 in PW mode), with Γ-only k-point sampling and spin polarisation.
  • Gaussian smearing of 0.05 eV (as with ISMEAR = 0, SIGMA = 0.05 for VASP) instead of GPAW's default 0.1 eV Fermi-Dirac (which is fine for metals but a poor choice for semiconductors/insulators, as noted in their docs).
  • No point-group symmetry, as symmetry breaking is very likely for defects.
  • PreconLBFGS relaxations (Exp preconditioner, maxstep = 0.2) to fmax = 0.01 eV/Å, using the settings tuned for defect relaxations in Accelerate split vacancy relaxations with optimised PreconLBFGS (rather than GOQN) ddmms/ml-peg#863.

Script generation and input checks

  • The generated scripts now pass all calculator settings directly to GPAW(...), as dicts, so e.g. basis must be a top-level setting, as GPAW expects. Optimizers can be given as a name or as a dict of the name and keyword arguments, including ase.optimize.precon optimizers.
  • Relaxations restart the optimizer once after a RuntimeError, e.g. a line search failing because of SCF noise.
  • Informative errors for:
    • hybrid functionals without plane-wave mode (GPAW silently omits the exact exchange in FD mode, and fails in LCAO mode);
    • trajectory/append_trajectory in the optimizer settings, since doped sets the trajectory;
    • charge in gpaw_settings (set it with charge_state).

GPAW version

GPAW newer than 26.7.0 is now required, because relaxations with hybrid functionals (now the default) fail at the second ionic step with GPAW 26.7.0; this is fixed on the GPAW master branch. Until the next GPAW release, the docs say to install GPAW master from GitLab first, and the test-gpaw CI job does the same, with TODOs to switch back to PyPI. The gpaw install-data step was removed from the docs, as the PAW datasets are installed with GPAW (its gpaw-data dependency).

@kavanase
kavanase merged commit 89f9de4 into SMTG-Bham:IO_refactor Nov 5, 2026
1 of 63 checks passed
@sblisesivdin

Copy link
Copy Markdown
Author

Thanks Sean, these are really very good improvements! The band-filling approach makes a lot of sense, especially for narrow-gap systems with smearing. Next week, I'll pick up the next GPAW task from your updated branch.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants