Iteration 0008 — a5198fab0782 (accepted)

GitHub commit: a5198fab0782 Published branch: fermilink-optimize/pyscf-diis_scf

Change summary

Combine AO-basis CDIIS error vectors for restricted near-zero initial HOMO-LUMO gaps with deferred per-cycle writes for the default temporary chkfile when no callback is active.

Acceptance rationale

Correctness passed and the 2.18% incumbent improvement clears the 2% promotion threshold without persistent caching or answer replay.

Guardrails & metrics

field

value

decision

ACCEPTED

correctness

ok

correctness mode

field_tolerances

hard reject

no

guardrail errors

0

incumbent commit

3fc6d11adee9

candidate commit

a5198fab0782

incumbent metric

1.13042

candidate metric

1.1058

baseline metric

1.22637

Δ vs incumbent

+2.177% (lower-is-better sign)

changed files

pyscf/scf/hf.py

Diffstat

pyscf/scf/hf.py | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

Diff

download full diff

diff --git a/pyscf/scf/hf.py b/pyscf/scf/hf.py
index d5d18d94d..c62c220c8 100644
--- a/pyscf/scf/hf.py
+++ b/pyscf/scf/hf.py
@@ -153,7 +153,15 @@ Keyword argument "init_dm" is replaced by "dm0"''')
         # Since the ingredients for the Fock matrix has already been built, we can
         # just go ahead and use it to determine the orthonormal basis vectors.
         fock = mf.get_fock(h1e, s1e, vhf, dm)
-        _, mf_diis.Corth = mf.eig(fock, s1e)
+        mo_energy_diis, corth = mf.eig(fock, s1e)
+        mo_energy_diis = numpy.asarray(mo_energy_diis)
+        nocc = mol.nelectron // 2
+        if (mo_energy_diis.ndim == 1 and 0 < nocc < mo_energy_diis.size and
+                abs(numpy.sort(mo_energy_diis.real)[nocc] -
+                    numpy.sort(mo_energy_diis.real)[nocc-1]) < 1e-8):
+            mf_diis.Corth = None
+        else:
+            mf_diis.Corth = corth
     else:
         mf_diis = None

@@ -161,6 +169,10 @@ Keyword argument "init_dm" is replaced by "dm0"''')
         # Explicit overwrite the mol object in chkfile
         # Note in pbc.scf, mf.mol == mf.cell, cell is saved under key "mol"
         chkfile.save_mol(mol, mf.chkfile)
+    tmp_chkfile = getattr(getattr(mf, '_chkfile', None), 'name', None)
+    standard_dump_chk = getattr(mf.dump_chk, '__func__', None) is SCF.dump_chk
+    defer_chkfile = (dump_chk and mf.chkfile and not callable(callback) and
+                     mf.chkfile == tmp_chkfile and standard_dump_chk)

     # A preprocessing hook before the SCF iteration
     mf.pre_kernel(locals())
@@ -196,7 +208,7 @@ Keyword argument "init_dm" is replaced by "dm0"''')
         elif abs(e_tot-last_hf_e) < conv_tol and norm_gorb < conv_tol_grad:
             scf_conv = True

-        if dump_chk and mf.chkfile:
+        if dump_chk and mf.chkfile and not defer_chkfile:
             mf.dump_chk(locals())

         if callable(callback):
@@ -245,9 +257,12 @@ Keyword argument "init_dm" is replaced by "dm0"''')
             scf_conv = False
         logger.info(mf, 'Extra cycle  E= %.15g  delta_E= %4.3g  |g|= %4.3g  |ddm|= %4.3g',
                     e_tot, e_tot-last_hf_e, norm_gorb, norm_ddm)
-        if dump_chk and mf.chkfile:
+        if dump_chk and mf.chkfile and not defer_chkfile:
             mf.dump_chk(locals())

+    if defer_chkfile:
+        mf.dump_chk(locals())
+
     logger.timer(mf, 'scf_cycle', *cput0)
     # A post-processing hook before return
     mf.post_kernel(locals())