The DFT solver, as written
al_it_check.viv
Generated by RUNNING the independent numpy reference at the deck's settings and pinning what it printed; then the published LDA values; then the figure.
# Al: what the calculation must reproduce, and the picture of it. # # dft/run.sh al it # # GENERATED by dft/ref/make_deck.py, which RAN dft/ref/pwdft_ref.py -- an independent numpy implementation that diagonalizes H densely -- # at exactly this deck's settings and pinned what it printed. # A disagreement here is a bug in one of the two implementations. GAMMA_P = NSEG LAST = NPTS - 1.0 test "SCF converged: density, energy, and every occupied band's residual" { assert_lt(DRHO, 1.0e-8) assert_lt(EIGRES, EIG_TOL) assert_lt(ITER, MAXIT) } test "every band-path point converged" { assert_lt(BANDRES, EIG_TOL) } test "free energy agrees with the numpy reference" { assert_near(ETOT, 0.598595595079, 1.0e-7) } test "the Fermi level agrees with the numpy reference" { assert_near(EFERMI, 0.284482863616, 1.0e-7) } test "band energies at L, Gamma and X agree with the numpy reference (eV)" { assert_near(EVB[0.0, 0.0], -4.617181044, 1.0e-5) # L, band 1 assert_near(EVB[0.0, 1.0], -4.436650937, 1.0e-5) # L, band 2 assert_near(EVB[0.0, 2.0], 11.037701390, 1.0e-5) # L, band 3 assert_near(EVB[GAMMA_P, 0.0], -11.149189968, 1.0e-5) # Gamma, band 1 assert_near(EVB[GAMMA_P, 1.0], 12.755642052, 1.0e-5) # Gamma, band 2 assert_near(EVB[GAMMA_P, 2.0], 12.755642052, 1.0e-5) # Gamma, band 3 assert_near(EVB[LAST, 0.0], -2.970240813, 1.0e-5) # X, band 1 assert_near(EVB[LAST, 1.0], -1.642758542, 1.0e-5) # X, band 2 assert_near(EVB[LAST, 2.0], 5.413952043, 1.0e-5) # X, band 3 } #: REFPATH the reference's lowest 3 bands at all 61 path points, eV REFPATH = [[-4.6171810, -4.4366509, 11.0377014], [-4.9626286, -4.0778526, 11.0151567], [-5.3709598, -3.6294740, 10.9603686], [-5.7687850, -3.1649197, 10.8935925], [-6.1537247, -2.6865946, 10.8270654], [-6.5251783, -2.1947575, 10.7676185], [-6.8829740, -1.6904440, 10.7163340], [-7.2269215, -1.1734612, 10.6754854], [-7.5576961, -0.6442180, 10.6430277], [-7.8736339, -0.1024875, 10.6250709], [-8.1754067, 0.4520897, 10.6191859], [-8.4631818, 1.0166687, 10.6255322], [-8.7364591, 1.5947501, 10.6445395], [-8.9953588, 2.1838126, 10.6757166], [-9.2398108, 2.7840464, 10.7193815], [-9.4697537, 3.3951335, 10.7755508], [-9.6859001, 4.0166853, 10.8429381], [-9.8866907, 4.6483203, 10.9240368], [-10.0728089, 5.2895078, 11.0175392], [-10.2442082, 5.9396355, 11.1233618], [-10.4012456, 6.5970020, 11.2413485], [-10.5429905, 7.2634538, 11.3730301], [-10.6701388, 7.9334463, 11.5149269], [-10.7823005, 8.6092907, 11.6681376], [-10.8795647, 9.2872411, 11.8319840], [-10.9619068, 9.9640317, 12.0053142], [-11.0293060, 10.6346494, 12.1860151], [-11.0817453, 11.2907026, 12.3698119], [-11.1192114, 11.9159066, 12.5469762], [-11.1416948, 12.4671918, 12.6931717], [-11.1491900, 12.7556421, 12.7556421], [-11.1391965, 12.5284980, 12.5284980], [-11.1092197, 12.1147978, 12.1147978], [-11.0592694, 11.6738713, 11.6738713], [-10.9893628, 11.2353410, 11.2353410], [-10.8995236, 10.8071141, 10.8071141], [-10.7897825, 10.3921989, 10.3921989], [-10.6601772, 9.9920352, 9.9920352], [-10.5102874, 9.6081096, 9.6081096], [-10.3411438, 9.2394685, 9.2394685], [-10.1524532, 8.8851665, 8.8851665], [-9.9439593, 8.5498335, 8.5498335], [-9.7159019, 8.2312922, 8.2312922], [-9.4678843, 7.9311955, 7.9311955], [-9.2009970, 7.6463929, 7.6463929], [-8.9148366, 7.3786998, 7.3786998], [-8.6095252, 7.1281719, 7.1281719], [-8.2852044, 6.6064674, 6.8948516], [-7.9420419, 5.8303470, 6.6778108], [-7.5802100, 5.0712418, 6.4792057], [-7.1997016, 4.3285752, 6.2984528], [-6.8013868, 3.6002946, 6.1342601], [-6.3853361, 2.8885070, 5.9873582], [-5.9521024, 2.1939748, 5.8577504], [-5.5025229, 1.5176979, 5.7454383], [-5.0379838, 0.8611897, 5.6504218], [-4.5610462, 0.2271105, 5.5727001], [-4.0771648, -0.3795685, 5.5008938], [-3.5994179, -0.9428058, 5.4535902], [-3.1761317, -1.4193801, 5.4238623], [-2.9702408, -1.6427585, 5.4139520]] test "every band at every point of the path agrees with the numpy reference (eV)" { assert_lt(max(abs(EVB[:, 0:shape(REFPATH)[1]] - REFPATH)), 1.0e-5) } # --- the physics: published LDA values, loose on purpose ----------------------- #: EF_FREE the free-electron Fermi energy for three electrons per cell, in eV EF_FREE = 0.5 * pow(3.0 * PI * PI * NELEC / OMEGA, 2.0 / 3.0) * HA_EV BOTTOM = 0.0 - EVB[GAMMA_P, 0.0] show EF_FREE show BOTTOM test "the band bottom is about 11.1 eV below the Fermi level" { assert_near(BOTTOM, 11.1, 0.3) } test "aluminum is nearly free-electron-like: within 10% of (hbar k_F)^2 / 2m" { assert_near(BOTTOM / EF_FREE, 1.0, 0.1) } test "the occupied levels at X" { assert_near(EVB[LAST, 0.0], -2.95, 0.3) assert_near(EVB[LAST, 1.0], -1.55, 0.3) } test "it is a metal: bands cross the Fermi level along the path" { assert_true(any(EVB[:, 1.0] > 0.0)) assert_true(any(EVB[:, 1.0] < 0.0)) } figure("Aluminum: LDA band structure", "wavevector along the path", "energy from the Fermi level (eV)") for b to NBANDS { plot(PATHX, EVB[:, b], "band") } xtick("L", PATHX[0]) xtick("Γ", PATHX[GAMMA_P]) xtick("X", PATHX[LAST])