PAOFLOW.ACBN0#
ACBN0 self-consistent Hubbard U driver.
This module implements the ACBN0 pseudo-hybrid self-consistent determination of on-site Hubbard U corrections from first principles, following
L. A. Agapito, S. Curtarolo and M. Buongiorno Nardelli, Reformulation of DFT+U as a pseudo-hybrid Hubbard density functional for accelerated materials discovery, Phys. Rev. X 5, 011006 (2015).
The driver is exposed through the ACBN0 class. An instance
orchestrates the full self-consistent cycle:
Parse a user-supplied Quantum ESPRESSO
<prefix>.scf.intemplate (and the matching<prefix>.nscf.in/<prefix>.projwfc.in).Fit each pseudopotential’s atomic wavefunctions to a contracted Gaussian basis (
PAOFLOW.projection.upf_gaussfit) so the Coulomb integrals required by the ACBN0 formula can be evaluated analytically.On every outer iteration, inject the current
HUBBARDcard into the SCF/NSCF templates and runpw.x(scf),pw.x(nscf),projwfc.x, PAOFLOW and finallyACBN0_Hartree(under MPI).Recompute U for every Hubbard-active orbital from the ACBN0 numerator (renormalized two-electron integrals) and denominator (occupation-matrix invariants).
Iterate until
max |Δ U| < convergence_threshold.
The class is also the base of eACBN0, which
adds intersite Hubbard V to the same workflow.
Typical usage#
from PAOFLOW.ACBN0 import ACBN0
a = ACBN0('MgO', workdir='./',
mpi_qe='mpirun -np 8',
mpi_python='mpirun -np 1',
mpi_hartree='mpirun -np 8',
qe_path='/path/to/qe/bin',
python_path='/path/to/python/bin',
outputdir='./tmp/')
# Equivalent ways to declare Hubbard-active orbitals:
a.set_hubbard_parameters(['Mg-3s', 'O-2p']) # default U
a.set_hubbard_parameters({'Mg-3s': 1.0, 'O-2p': 8.0}) # custom U
a.set_hubbard_parameters({'O-2p': (8.0, 4.0)}) # +occupation
a.optimize_hubbard_U(convergence_threshold=0.01)
print(a.uVals) # {'Mg-3s': ..., 'O-2p': ...}
Public API#
ACBN0.set_hubbard_parameters()— declare Hubbard-active orbitals. Accepts a list of'species-orbital'labels (default seed U), a dict mapping labels to seed U (eV), or a dict with(U, occupation)tuples to also fixhubbard_occin the&systemnamelist.ACBN0.set_intersite_V_parameters()— seed entries invValsso theHUBBARDcard emitsVlines; used byeACBN0and for fixed-V runs.ACBN0.optimize_hubbard_U()— outer self-consistent loop.ACBN0.run_dft()— one shot of pw.x (scf) + pw.x (nscf) + projwfc.x with the currentHUBBARDcard injected.ACBN0.run_paoflow()— invoke PAOFLOW on the QE save folder to produce the PAO Hamiltonian/overlap and k-point dumps consumed by the ACBN0 numerator/denominator.ACBN0.run_acbn0()— single ACBN0 evaluation pass on the current PAOFLOW dump.ACBN0.hubbard_card()— render the currentself.uVals/self.vValsinto a QEHUBBARDcard.ACBN0.read_cell_atoms(),ACBN0.read_ham_data()— helpers for parsing QEscf.outand the PAOFLOW dumps.
Internal helpers (prefixed with an underscore convention via their
naming) handle Gaussian basis assembly per atom
(ACBN0.getbasis()), construction of the k-resolved density
matrix (ACBN0.Dk()), the back-Fourier transform to real space
(ACBN0.DR()) and the on-site occupation invariants used in the
ACBN0 denominator (ACBN0.Nmm()).
External tools#
The driver shells out to several commands. The launchers are configured at construction time:
pw.xandprojwfc.xfromqe_path, optionally prefixed bympi_qe(e.g.'mpirun -np 8') with extra options inqe_options(e.g.'-npool 4').PAOFLOW is launched as a separate Python process under
mpi_python(typically'mpirun -np 1'because PAOFLOW’s MPI scaling is workflow-dependent and the call here is short).The Hartree integrals (
ACBN0_Hartree) are launched as a separate Python process undermpi_hartree, which defaults tompi_pythonbut can be overridden — typically with a larger-npbecause the pure-Python four-centre Coulomb integrals dominate the wall time for heavy d/f shells.
Conventions#
Energies are in eV; the input
celldm(1)/ lattice quantities are read in their native QE units (Bohr / Å) and converted internally where required.Atom indices follow the QE convention: 1-based, ordered as they appear in the
ATOMIC_POSITIONScard.Orbital labels are written as
'<element>-<n><l>', e.g.'Mn-3d','O-2p'. In magnetic AFM cells with distinct sublattices, the element symbol in the input may be tagged ('MnA','MnB') and the same tag must be used in the U keys.The class respects an existing
HUBBARDcard in the template: any U/V entries already present are loaded intoself.uValsandself.vValsat construction time.
Attributes set at construction#
uVals(dict[str, float]) — current U values, keyed by'species-orbital'.vVals(dict[tuple, float]) — current intersite V values (populated byeACBN0).uspecies(list[str]) — atomic species discovered in theATOMIC_SPECIEScard.basis(dict[str, list]) — per-species fitted Gaussian basis fromPAOFLOW.projection.upf_gaussfit.gaussian_fit().blocks/cards— parsed namelists / cards of the SCF input template, as returned byPAOFLOW.inputs.file_io.struct_from_inputfile_QE().nspin— read from the&systemblock (defaults to 1).hubbard_tag— header line of theHUBBARDcard (e.g.'HUBBARD (atomic)').hubbard_occ— fixedhubbard_occ(i,j)entries to be written back into the&systemnamelist.
Notes
The first thing
__init__()does after parsing the template is to writecompute_hartree.pyinto the current directory; this small launcher is what gets executed undermpi_hartreefor the Coulomb integrals.The PAOFLOW step launched by
run_paoflow()callspao_hamiltonian(write_binary=True, expand_wedge=False):Hksis kept on whichever k-grid QE produced (IBZ when symmetries are on, full BZ whennosym = noinv = .true.) and is written to disk without any FFT to real space. The reshape to(nawf, nawf, nk1, nk2, nk3, nspin)inPAOFLOW.hamiltonian.do_build_pao_hamiltonian.do_build_pao_hamiltonian()is therefore skipped for ACBN0; both IBZ and full-BZ k-grids are accepted.PAOFLOW.hamiltonian.do_build_pao_hamiltonian.build_Hks()now applies a per-k projectability filter (pthr_local, defaulting to0.5 * pthr) in addition to the globalpthr. Bands whose local PAO projection at a given k vanishes (typically one of a degenerate set at high-symmetry points such as Γ, where QE’s gauge choice can leave it with near-zero atomic-orbital content) are dropped from the construction at that k-point only. Without this guard the previous code renormalised the vanishing projection vector to unit norm, corruptingH(k)at high-symmetry points and, in turn, the occupations entering the ACBN0 numerator/denominator.
Attributes#
Classes#
MPI worker for the ACBN0 on-site Hartree / exchange integrals. |
|
MPI-parallel evaluator of the intersite Hubbard V numerator. |
|
Extended ACBN0 (DFT+U+V) driver. |
Module Contents#
- class PAOFLOW.ACBN0.ACBN0_Hartree(datafile)[source]#
Bases:
_HartreeKernelMPI worker for the ACBN0 on-site Hartree / exchange integrals.
Invoked by
ACBN0as a standalone MPI Python program (typically through the auto-generatedcompute_hartree.pylauncher) to evaluate the four-centre Coulomb sums that make up the ACBN0 numerator for a single Hubbard site.Given the renormalized real-space density matrix
D(R=0)per spin channel (built byACBN0.DR()from the PAOFLOW dump) and the contracted-Gaussian basis fitted to the pseudopotential atomic wavefunctions, the kernel accumulates\[ \begin{align}\begin{aligned}U_{\text{num}} = \sum_{abcd} (ab|cd)\, D^{\text{tot}}_{ab}\, D^{\text{tot}}_{cd}, \qquad D^{\text{tot}} = D^{\uparrow} + D^{\downarrow}\\J_{\text{num}} = \sum_{abcd} (ac|bd)\, \bigl[ D^{\uparrow}_{ab}\, D^{\uparrow}_{cd} + D^{\downarrow}_{ab}\, D^{\downarrow}_{cd} \bigr]\end{aligned}\end{align} \]where the four indices run over
basis_2e(the Hubbard-active subshell), the two-electron integrals(ab|cd) = ∫∫ φ_a(r₁) φ_b(r₁) (1/r₁₂) φ_c(r₂) φ_d(r₂) dr₁ dr₂are evaluated analytically byPAOFLOW.utils.pyints.contr_coulomb()over contracted Cartesian Gaussians, and the spin pre-factors follow the ACBN0 decomposition (Agapito et al., Phys. Rev. X 5, 011006 (2015)). The U sum factorises throughD^{tot} = D↑ + D↓(Hartree-like, full σσ’ sum); the J sum carries only the like-spin pieces under the(ac|bd)index permutation.No self-exchange exclusion is applied to the J sum: empirically the no-exclusion form reproduces the published ACBN0 / Lee – Son benchmark U values (e.g. ZnO Zn-3d ≈ 15.47 eV, O-2p ≈ 7.33 eV with ortho-atomic projection), whereas the strict Eq. (11) form with the
(m,n) = (k,l)term removed does not.Parallelization#
Only the unique 4-tuples
(a, b, c, d)under the 8-fold permutation symmetry(ab|cd) = (ba|cd) = (ab|dc) = (cd|ab)of real Cartesian Gaussians are enumerated (canonical form:a ≤ b,c ≤ d,(a, b) ≤ (c, d)). These are split intoself.sizechunks withnumpy.array_split(), scattered withcomm.scatter, evaluated locally andallgather-ed so every rank holds the fulleri_dict. Each rank unfolds the dict into the full(n_2e)^4ERItensor and contracts it with the density-matrix sub-blocks vianumpy.einsum(). The result is replicated on every rank, so no ``MPI.SUM`` reduce is performed — the pickle<outputdir>/tmp_uj.pklis written from rank 0 only.Cost scales as
len(basis_2e) ** 4times the (primitive count) ** 4 insidecontr_coulomb(). For light p-shells (e.g. O-2p,len(basis_2e) = 3) the kernel finishes in milliseconds even at-np 1; for heavy d-shells (e.g. Mn-3d,len(basis_2e) = 5with up to 15 primitives per basis function) the cost runs into tens of millions of Boys-function evaluations and benefits substantially from running undermpirun -np NwithNmatching the number of physical cores — hence the dedicatedmpi_hartreeknob inACBN0.Input format#
The driver writes a pickle file at
datafile(broadcast to all ranks in__init__()) containing:'DR_up','DR_dn'—(nbasis, nbasis)complex arrays, the renormalized real-space density matrices (R=0) per spin channel.'basis'— list ofPAOFLOW.utils.pyints.CGBFcontracted Gaussian basis functions covering the entire site.'basis_2e'— list of integer indices intobasisselecting the Hubbard-active subshell over which the four-index sum is taken (e.g. the 5 d-orbitals of a transition-metal site).
Output#
<outputdir>/tmp_uj.pkl(rank 0 only): a dictionary{'U': float, 'J': float}holding the unnormalized numerator sums as real Python floats. The driver divides these by the denominator (ACBN0.Nmm()) to obtain the final U and J in eV.The real-valued type is load-bearing: QE’s
card_hubbardparser rejects complex-formatted Hubbard values, so the ERI tensor is allocateddtype=float, the density-matrix sub-blocks are.real-coerced, and the einsum results are wrapped infloat(…)before pickling.Notes
The class imports
mpi4pyat module level, so simply importing it in a non-MPI Python process is harmless (it initialises a singleton communicator with size 1). In that mode the kernel runs serially and takes the fullbasis_2e ** 4cost on a single core.
- class PAOFLOW.ACBN0.eACBN0_Hartree(datafile)[source]#
Bases:
_HartreeKernelMPI-parallel evaluator of the intersite Hubbard V numerator.
Companion class to
eACBN0. Implements the spin-summed Coulomb sum that appears in the numerator of Eq. (8) ofS.-H. Lee and Y.-W. Son, First-principles approach with a pseudo-hybrid density functional for extended Hubbard interactions, Phys. Rev. Research 2, 043410 (2020),
\[V^{IJ}(R) = \tfrac{1}{2}\,\frac{\text{num}}{\text{den}}\]with the numerator
\[\text{num} = \sum_{\sigma\sigma'}\sum_{ikjl} \Bigl[ P^{II\sigma}_{ik}\, P^{JJ\sigma'}_{jl} - \delta_{\sigma\sigma'}\, P^{IJ\sigma}_{il}\, P^{JI\sigma}_{jk} \Bigr]\,(ik|jl).\]The renormalized pair density matrices
P^{II},P^{JJ},P^{IJ}(R),P^{JI}(-R)are built byeACBN0._pair_density_matrices()from the PAOFLOW Hamiltonian/overlap dump (Eqs. (4)–(5) of the reference); the two-electron integral(ik|jl) = ∫∫ φ_i^I(r₁) φ_k^I(r₁) (1/r₁₂) φ_j^J(r₂) φ_l^J(r₂) dr₁ dr₂is evaluated analytically over contracted Cartesian Gaussians byPAOFLOW.utils.pyints.contr_coulomb().The denominator of Eq. (8) is built directly on the driver side in
eACBN0.run_eacbn0_V()from the bare occupation matricesn^{II},n^{JJ},n^{IJ},n^{JI}and combined with the numerator returned by this kernel to obtain V in eV.Geometry convention#
The basis functions
gauss_Iare centred at the home-cell position of atom I, whilegauss_Jare centred atr_J + R*, whereR*is the minimum-image lattice translation selected byeACBN0.run_eacbn0_V(). As a result, indicesi, krun over the Gaussians on atom I andj, lover the translated Gaussians on atom J; no further phase factors are required inside the kernel.Parallelization#
Only the unique 4-tuples
(i, k, j, l)under the 4-fold permutation symmetry(ik|jl) = (ki|jl) = (ik|lj)are enumerated (canonical form:i ≤ k,j ≤ l). Because atoms I and J are distinct, the electron-swap symmetry(ik|jl) = (jl|ik)does not apply — only 4-fold (not 8-fold) reduction is available. The unique keys are split intoself.sizechunks withnumpy.array_split(), scattered withcomm.scatter, evaluated locally andallgather-ed so every rank holds the fulleri_dict. Each rank unfolds it into the(n_I, n_I, n_J, n_J)ERItensor and contracts vianumpy.einsum()(direct viaPII_sum/PJJ_sum; same-spin exchange viaP_IJ/P_JI). The result is replicated on every rank, so no ``MPI.SUM`` reduce is performed — the pickle<outputdir>/tmp_v.pklis written from rank 0 only.Cost scales as
n_I² × n_J² × (primitive count)⁴insidecontr_coulomb(). For two p-shells (n_I = n_J = 3) the kernel finishes in a few seconds even at-np 1; for a d–p pair (e.g. Mn-3d to O-2p,n_I = 5,n_J = 3) with the full multi-zeta Gaussian fits the cost runs into tens of millions of Boys-function evaluations and benefits substantially from running undermpirun -np NwithNmatching the number of physical cores — hence the dedicatedmpi_hartreeknob inACBN0, which is reused here.Input format#
The driver writes a pickle file at
datafile(broadcast to all ranks in__init__()) containing one entry per pair:'gauss_I','gauss_J'— lists ofPAOFLOW.utils.pyints.CGBFcontracted Gaussian basis functions covering the Hubbard-active shells on atoms I and J, with origins in Bohr (J already translated byR*).'P_II_up','P_II_dn'—(n_I, n_I)complex on-site renormalized DMs on atom I, per spin channel.'P_JJ_up','P_JJ_dn'—(n_J, n_J)complex on-site renormalized DMs on atom J, per spin channel.'P_IJ_up','P_IJ_dn'—(n_I, n_J)complex intersite renormalized DMs at displacement+R*.'P_JI_up','P_JI_dn'—(n_J, n_I)complex intersite renormalized DMs at displacement-R*.
For spin-restricted runs (
nspin == 1) the driver passes identical up/down halves so that the spin pre-factors below reduce to the spin-restricted form automatically.Output#
<outputdir>/tmp_v.pkl(rank 0 only): a dictionary{'num': complex}holding the unnormalized numerator sum (no 1/2 prefactor — that factor is applied on the driver side together with the denominator).Spin structure#
The bracket
[direct − exchange]inside the four-index sum factorises into two pieces:Direct (Hartree) — full
σ × σ'double sum, equal to(P^{II}_up + P^{II}_dn)_{ik} × (P^{JJ}_up + P^{JJ}_dn)_{jl}. Pre-computed once outside the inner loop asPII_sum/PJJ_sum.Exchange — same-spin only (
δ_{σσ'}), summingP^{IJ}_{σ}_{il} × P^{JI}_{σ}_{jk}overσ ∈ {up, dn}.
Notes
The class imports
mpi4pyat module level, so simply importing it in a non-MPI Python process is harmless (it initialises a singleton communicator with size 1). In that mode the kernel runs serially and takes the fulln_I² × n_J²cost on a single core.
- class PAOFLOW.ACBN0.ACBN0(prefix, pthr=0.95, workdir='./', mpi_qe='', nproc=1, qe_path='', qe_options='', mpi_python='', python_path='', outputdir='./output/', projection='ortho-atomic', mpi_hartree=None, use_local_basis=False, basispath=None, configuration='standard', gaussian_threshold=0.01)[source]#
-
- set_intersite_V_parameters(vpairs)[source]#
Register intersite Hubbard V pairs and their initial values.
- Parameters:
vpairs (list, tuple, or dict) – Either an iterable of
(label1, label2, atom_idx1, atom_idx2, V_init)tuples, or a dict mapping(label1, label2, atom_idx1, atom_idx2)toV_init.label*follow the QEspecies-orbitalconvention (e.g.'Ni-3d');atom_idx*are 1-based atom indices as used in the QEHUBBARDcard.V_initmay beNone, in which case 0.01 eV is used as a seed.
- Dk(basis_dm, basis_2e, Hks, Sks, eigvec_cache=None)[source]#
Build the per-k density matrix
D(k)and the per-k Mulliken projectionn_{lm}(k)onbasis_2efor the occupied manifold.- Parameters:
basis_dm (1D int ndarray) – PAO indices defining the density-matrix block and the two-electron-integral block, respectively.
basis_2e (1D int ndarray) – PAO indices defining the density-matrix block and the two-electron-integral block, respectively.
Hks ((nbasis, nbasis, nkpnts) complex ndarray)
Sks ((nbasis, nbasis, nkpnts) complex ndarray)
eigvec_cache (list of (eig, vec) or None, optional) – If provided, the per-k generalized eigenproblem is not re-solved; values from the cache are used instead. Produced by
_eigh_all_k().
- class PAOFLOW.ACBN0.eACBN0(*args, **kwargs)[source]#
Bases:
ACBN0Extended ACBN0 (DFT+U+V) driver.
This class implements the extended ACBN0 self-consistent scheme that augments the standard on-site Hubbard U calculation with the intersite Hubbard V correction, following the formulation of
S.-H. Lee and Y.-W. Son, First-principles approach with a pseudo-hybrid density functional for extended Hubbard interactions, Phys. Rev. Research 2, 043410 (2020).
Subclass of
ACBN0.eACBN0reuses the entire on-site U machinery (template parsing,pw.x/projwfc.x/ PAOFLOW launches, ACBN0 Hartree integrals, HUBBARD card emission) and adds the bookkeeping and numerics required to evaluate V for an arbitrary set of atomic pairs — including their periodic images.Theoretical background#
Given a pair of Hubbard-active sites
(I, J)separated by a Bravais lattice translationR, the intersite Hubbard parameter is defined as (Eq. 8 of the reference)\[V^{IJ}(R) = \frac{ \frac{1}{2}\sum_{ijkl, \sigma\sigma'} P^{IJ\sigma}_{ij}(R)\, P^{JI\sigma'}_{kl}(-R)\, (ij|kl) }{ \sum_{ij, \sigma\sigma'} n^{II\sigma}_{ii} n^{JJ\sigma'}_{jj} - \sum_{ij, \sigma} n^{IJ\sigma}_{ij}(R) n^{JI\sigma}_{ji}(-R) }\]with the bare on-site / intersite occupation matrices
ndefined by Eq. (2) and their renormalized counterpartsPdefined by Eqs. (4) and (5). The four-centre electron-repulsion integrals(ij|kl)are evaluated in the auxiliary Gaussian basis fitted to the PAO numerical wavefunctions (the same basis used byACBN0_Hartree).Workflow#
The typical usage mirrors
ACBN0but adds a pair-selection step and usesoptimize_hubbard_UV()instead ofoptimize_hubbard_U:from PAOFLOW.ACBN0 import eACBN0 e = eACBN0('MnO', workdir='./', mpi_qe='mpirun -np 8', mpi_python='mpirun -np 1', mpi_hartree='mpirun -np 8', qe_path='/path/to/qe/bin', python_path='/path/to/python/bin', outputdir='./tmp/') e.set_hubbard_parameters({'Mn-3d': 5.0, 'O-2p': 1.0}) e.set_intersite_pairs(cutoff=2.5, V_init=0.5) e.optimize_hubbard_UV(convergence_threshold=0.05, max_iter=25, mixing=0.7)
Each outer iteration of
eACBN0.optimize_hubbard_UV():Writes the current
HUBBARDcard (U on every declared orbital, V on every registered pair) into the SCF/NSCF templates and runspw.x(scf),pw.x(nscf) andprojwfc.x.Runs PAOFLOW to produce the PAO Hamiltonian/overlap and the reduced-zone k-grid dumps.
Calls
eACBN0.run_acbn0()for the on-site U values.Calls
eACBN0.run_eacbn0_V()which, for every registered pair, builds the pair density matrices and dispatches the four-centre integral evaluation tocompute_hartree_v.pyundermpi_hartree.Applies linear mixing to both U and V and checks for convergence (
max |Δ| < convergence_thresholdacross all parameters).
Public API#
Class
eACBN0adds the following methods on top ofACBN0:eACBN0.set_intersite_pairs()— register V pairs either from an explicit list (with optional(n_a, n_b, n_c)image labels) or via a real-space cutoff search restricted to user-selected species pairs.eACBN0.print_intersite_pairs()— print a human-readable summary of every registered pair (atom indices, image, distance, seed V).eACBN0.run_eacbn0_V()— evaluate Eq. (8) for every registered pair using the current PAOFLOW dump andprojwfc.out. Collapses multiple images of the same(label1, label2, i1, i2)key to the minimum-image representative.eACBN0.optimize_hubbard_UV()— joint U+V self-consistent loop with linear mixing.
Internal helpers (prefixed with an underscore) implement geometry parsing from the QE input cards (
eACBN0._geometry_from_cards()), periodic neighbour enumeration with cell-shape-aware image windows (eACBN0._image_window(),eACBN0._enumerate_pairs()), construction of per-site contracted-Gaussian basis functions (eACBN0._atom_shell_gaussians()), pair density-matrix assembly (eACBN0._pair_density_matrices()) and the MPI launcher for the four-centre integrals (eACBN0._launch_compute_hartree_v()).Conventions#
Energies are in eV; lengths are in Ångström in the public API and in Bohr internally where the Gaussian integrals require it.
Atom indices follow the QE convention: 1-based, ordered as listed in the
ATOMIC_POSITIONScard.Periodic images are labelled by integer triples
(n_a, n_b, n_c)applied to atomi2of a pair:R = n_a a_1 + n_b a_2 + n_c a_3.k-points returned by PAOFLOW are in crystal coordinates by default; pass
kpnts_are_cartesian=TruetoeACBN0.run_eacbn0_V()(and hence toeACBN0.optimize_hubbard_UV()) if your PAOFLOW dump uses Cartesian Bohr-1 instead.mpi_hartree(kwarg of the underlyingACBN0) controls the MPI launcher for the pure-Python Coulomb integrals; it can — and usually should — differ frommpi_python, which controls the PAOFLOW step.
Notes
Spin-restricted runs (
nspin = 1) reuse a single density matrix for both spin channels by halving the doubly-occupied DM, so that the on-site limit (I = J, R = 0) reproduces the standardACBN0result exactly.The underlying PAOFLOW call uses
pao_hamiltonian(write_binary=True, expand_wedge=True). The resultingHksis on the full BZ produced by QE The reshape to(nawf, nawf, nk1, nk2, nk3, nspin)inPAOFLOW.hamiltonian.do_build_pao_hamiltonian.do_build_pao_hamiltonian()is now guarded by an array-size check, so the same code path also handles the IBZ k-grid that arises from the bare ACBN0 (U-only) stage when run withoutnosym/noinv.PAOFLOW.hamiltonian.do_build_pao_hamiltonian.build_Hks()now applies a per-k projectability filter (pthr_local, defaulting to0.5 * pthr) in addition to the globalpthr. Bands whose local PAO projection at a given k vanishes (typically one of a degenerate set at high-symmetry points such as Γ, where QE’s gauge choice can leave it with near-zero atomic-orbital content) are dropped from the construction at that k-point only. Without this guard the previous code renormalised the vanishing projection vector to unit norm, corruptingH(k)at high-symmetry points and, in turn, the occupations entering the ACBN0 / eACBN0 numerators and denominators.
- set_intersite_pairs(pairs=None, cutoff=None, include_onsite=False, species_pairs=None, V_init=0.01)[source]#
Register intersite Hubbard V pairs.
Exactly one of
pairsorcutoffmust be given (or both — in which case the explicit list is registered first, then the cutoff search augments it).- Parameters:
pairs (list of tuple, optional) – Explicit pair list. Each entry is either
(label1, label2, atom_idx1, atom_idx2, V_init)(home cell, image = (0,0,0)) or(label1, label2, atom_idx1, atom_idx2, n_a, n_b, n_c, V_init). Atom indices are 1-based.V_initmay beNoneto use theV_initkeyword default.cutoff (float, optional) – Real-space cutoff in Ångström. All ordered
(i, j, R)atom pairs whose separation lies withincutoffare enumerated for every label pair selected byspecies_pairs.include_onsite (bool, default False) – When
Truethe cutoff search also includes the trivial(i, i, R = 0)pairs.species_pairs (list of (str, str), optional) – Restrict the cutoff search to these
(label1, label2)pairs. Defaults to every unordered pair of currently declared Hubbard orbitals (both directions stored).V_init (float, default 0.01) – Seed V value (eV) used when an entry’s
V_initisNoneand for cutoff-enumerated pairs.
- run_eacbn0_V(kpnts_are_cartesian=False)[source]#
Compute intersite Hubbard V for every pair registered in
self.vPairsand return the updated mapping.Assumes that
run_dft+run_paoflowhave already producedprojwfc.outand the PAOFLOW Hamiltonian/overlap dumps inself.outputdir.- Parameters:
kpnts_are_cartesian (bool, default False) – By default PAOFLOW writes
k.txtin crystal coordinates (units of the reciprocal lattice vectors). Set this toTrueif the k-points are already in Cartesian Bohr$^{-1}$ (in which caseR_bohris used directly).- Returns:
new_V –
{(label1, label2, atom_idx1, atom_idx2): V_eV}— one entry per image-collapsed pair. When several images of the same pair are registered the values reported here are those of the closest (minimum-image) image.- Return type:
- optimize_hubbard_UV(convergence_threshold=0.01, max_iter=50, mixing=1.0, kpnts_are_cartesian=False)[source]#
Joint ACBN0 + eACBN0 self-consistent loop.
Each outer iteration runs
pw.x(scf+nscf),projwfc.x, PAOFLOW and then bothrun_acbn0()andrun_eacbn0_V(). Convergence is declared when all U and V parameters change by less thanconvergence_thresholdbetween consecutive iterations.- Parameters:
convergence_threshold (float, default 0.01) – Maximum allowed absolute change (in eV) of any U or V value between iterations.
max_iter (int, default 50) – Hard cap on the number of outer iterations.
mixing (float, default 1.0) – Linear-mixing factor applied to both U and V: 1.0 fully replaces the previous parameters with the freshly-computed ones; smaller values dampen oscillations (e.g.
mixing=0.5usesnew = 0.5*old + 0.5*computed).kpnts_are_cartesian (bool, default False) – Forwarded to
run_eacbn0_V().
- Raises:
RuntimeError – If convergence is not achieved within
max_iteriterations.