This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

The DFT solver, as written

cu_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.

View on GitHub
# Cu: what the calculation must reproduce, and the picture of it.
#
# dft/run.sh cu it
#
# GENERATED by dft/ref/make_deck.py, which RAN dft/ref/pwdft_iter.py -- an independent numpy implementation of the same iterative method --
# 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 - 0.5)
}
test "every band-path point converged" {
assert_lt(BANDRES, EIG_TOL)
}
test "free energy agrees with the numpy reference" {
assert_near(ETOT, -6.840756354444, 1.0e-7)
}
test "the Fermi level agrees with the numpy reference" {
assert_near(EFERMI, 0.471147207119, 1.0e-7)
}
test "band energies at L, Gamma and X agree with the numpy reference (eV)" {
assert_near(EVB[0.0, 0.0], -5.296650288, 1.0e-5) # L, band 1
assert_near(EVB[0.0, 1.0], -3.222805723, 1.0e-5) # L, band 2
assert_near(EVB[0.0, 2.0], -3.222805722, 1.0e-5) # L, band 3
assert_near(EVB[0.0, 3.0], -1.589489056, 1.0e-5) # L, band 4
assert_near(EVB[0.0, 4.0], -1.589489051, 1.0e-5) # L, band 5
assert_near(EVB[0.0, 5.0], -1.159059264, 1.0e-5) # L, band 6
assert_near(EVB[0.0, 6.0], 3.711105058, 1.0e-5) # L, band 7
assert_near(EVB[GAMMA_P, 0.0], -9.627422876, 1.0e-5) # Gamma, band 1
assert_near(EVB[GAMMA_P, 1.0], -3.280592543, 1.0e-5) # Gamma, band 2
assert_near(EVB[GAMMA_P, 2.0], -3.280592541, 1.0e-5) # Gamma, band 3
assert_near(EVB[GAMMA_P, 3.0], -3.280592538, 1.0e-5) # Gamma, band 4
assert_near(EVB[GAMMA_P, 4.0], -2.253370433, 1.0e-5) # Gamma, band 5
assert_near(EVB[GAMMA_P, 5.0], -2.253370431, 1.0e-5) # Gamma, band 6
assert_near(EVB[GAMMA_P, 6.0], 23.106843100, 1.0e-5) # Gamma, band 7
assert_near(EVB[LAST, 0.0], -4.992229494, 1.0e-5) # X, band 1
assert_near(EVB[LAST, 1.0], -4.615690603, 1.0e-5) # X, band 2
assert_near(EVB[LAST, 2.0], -1.630434012, 1.0e-5) # X, band 3
assert_near(EVB[LAST, 3.0], -1.398723220, 1.0e-5) # X, band 4
assert_near(EVB[LAST, 4.0], -1.398723218, 1.0e-5) # X, band 5
assert_near(EVB[LAST, 5.0], 1.311674647, 1.0e-5) # X, band 6
assert_near(EVB[LAST, 6.0], 7.215638275, 1.0e-5) # X, band 7
}
 
#: REFPATH the reference's lowest 7 bands at all 61 path points, eV
REFPATH = [[-5.2966503, -3.2228057, -3.2228057, -1.5894891, -1.5894891, -1.1590593, 3.7111051],
[-5.3023605, -3.2212051, -3.2212051, -1.5925527, -1.5925527, -1.2142349, 3.7924267],
[-5.2817266, -3.2161461, -3.2161461, -1.5993602, -1.5993602, -1.3645257, 4.0566953],
[-5.3038555, -3.2140161, -3.2140161, -1.5849400, -1.5849400, -1.5834155, 4.4212966],
[-5.3554123, -3.2049588, -3.2049588, -1.8425102, -1.6098263, -1.6098263, 4.8723457],
[-5.4277444, -3.1930864, -3.1930864, -2.1139773, -1.6398625, -1.6398625, 5.3970377],
[-5.5136767, -3.1740799, -3.1740799, -2.3677614, -1.6200152, -1.6200152, 5.9881633],
[-5.6496660, -3.1664652, -3.1664652, -2.6143998, -1.7230776, -1.7230776, 6.6062766],
[-5.8089065, -3.1481946, -3.1481946, -2.8214789, -1.7704653, -1.7704653, 7.2675693],
[-5.9935963, -3.1704327, -3.1704327, -2.9769762, -1.8262931, -1.8262931, 7.9663249],
[-6.2228336, -3.1635970, -3.1635970, -3.1517483, -1.9463375, -1.9463375, 8.6670131],
[-6.4571202, -3.2407169, -3.1420360, -3.1420360, -1.9718914, -1.9718914, 9.4135563],
[-6.7100794, -3.3224627, -3.0315007, -3.0315007, -1.9992540, -1.9992540, 10.1732346],
[-6.9693512, -3.3676604, -3.0126763, -3.0126763, -2.0527404, -2.0527404, 10.9562832],
[-7.2319150, -3.4130136, -2.9954765, -2.9954765, -2.1034885, -2.1034885, 11.7519320],
[-7.4904483, -3.4231371, -2.9808032, -2.9808032, -2.1502427, -2.1502427, 12.5692144],
[-7.7424755, -3.4204550, -2.9471387, -2.9471387, -2.1404287, -2.1404287, 13.4016022],
[-7.9849137, -3.4086047, -2.9439332, -2.9439332, -2.1730110, -2.1730110, 14.2476674],
[-8.2153102, -3.3880995, -2.9421311, -2.9421311, -2.1654473, -2.1654473, 15.1064367],
[-8.4318722, -3.3729127, -2.9908825, -2.9908825, -2.2103996, -2.2103996, 15.9740537],
[-8.6329388, -3.3456453, -3.0031298, -3.0031298, -2.2213051, -2.2213051, 16.8523183],
[-8.8174347, -3.3162600, -3.0181471, -3.0181471, -2.2265038, -2.2265038, 17.7370584],
[-8.9843782, -3.2425275, -3.0820959, -3.0820959, -2.2404115, -2.2404115, 18.6314139],
[-9.1331630, -3.2154857, -3.1418357, -3.1418357, -2.2704368, -2.2704368, 19.5155226],
[-9.2631071, -3.1890543, -3.1611980, -3.1611980, -2.2652301, -2.2652301, 20.3876179],
[-9.3737496, -3.2096397, -3.2096397, -3.1637151, -2.2273535, -2.2273535, 21.2294059],
[-9.4647279, -3.2263891, -3.2263891, -3.1807280, -2.2013032, -2.2013032, 21.9964857],
[-9.5357591, -3.2970908, -3.2606316, -3.2606316, -2.2581264, -2.2581263, 22.5973177],
[-9.5866360, -3.2880169, -3.2716156, -3.2716156, -2.2555853, -2.2555853, 22.9418095],
[-9.6172191, -3.2824624, -3.2783326, -3.2783326, -2.2539392, -2.2539392, 23.0742598],
[-9.6274229, -3.2805925, -3.2805925, -3.2805925, -2.2533704, -2.2533704, 23.1068431],
[-9.6138182, -3.2845279, -3.2768529, -3.2768529, -2.2566586, -2.2516083, 23.0671929],
[-9.5730465, -3.2962809, -3.2656443, -3.2656443, -2.2664580, -2.2463373, 22.9534875],
[-9.5052355, -3.3156938, -3.2304175, -3.2304175, -2.2362083, -2.2189760, 22.7791300],
[-9.4106120, -3.3222212, -3.1771446, -3.1771446, -2.3352840, -2.2214605, 22.5622159],
[-9.2894829, -3.3072200, -3.0287124, -3.0287124, -2.3044912, -2.1783853, 22.3209725],
[-9.1423013, -3.3504838, -2.9952163, -2.9952163, -2.3443871, -2.1609313, 22.0602316],
[-8.9696135, -3.3081071, -2.8995928, -2.8995928, -2.3662245, -2.0771054, 21.5763183],
[-8.7723963, -3.3651808, -2.8544532, -2.8544532, -2.5108728, -2.0549706, 20.9673472],
[-8.5514475, -3.4149001, -2.7788814, -2.7788814, -2.5800924, -2.0772745, 20.3662392],
[-8.3080752, -3.4817360, -2.7185961, -2.7185961, -2.6327536, -2.0533857, 19.7720635],
[-8.0440114, -3.5517757, -2.6830530, -2.6521156, -2.6521156, -2.0273928, 19.1900495],
[-7.7615090, -3.6722817, -2.7289116, -2.6487287, -2.6487287, -2.0061511, 18.6151246],
[-7.4635567, -3.7473671, -2.7656222, -2.5728557, -2.5728557, -1.9770334, 18.0643142],
[-7.1533341, -3.7480126, -2.7678265, -2.4657252, -2.4657252, -1.9122749, 17.5345082],
[-6.8335382, -3.8252933, -2.7043966, -2.3715114, -2.3715114, -1.8815472, 17.0229893],
[-6.5170862, -3.9019502, -2.6900294, -2.2832943, -2.2832943, -1.8502675, 16.5322670],
[-6.2110978, -4.0218419, -2.6458710, -2.2135083, -2.2135083, -1.8187701, 16.0631940],
[-5.9111634, -4.0939514, -2.4863288, -2.0699737, -2.0699737, -1.7809919, 15.6244142],
[-5.6886967, -4.1641259, -2.4438625, -2.0023108, -2.0023108, -1.7510639, 14.8345906],
[-5.5006679, -4.2883942, -2.2521355, -1.9539196, -1.9539196, -1.8246407, 13.8540231],
[-5.3133434, -4.3497837, -1.9196293, -1.8612429, -1.8612429, -1.7972371, 12.9264409],
[-5.1993721, -4.4060721, -1.7762965, -1.7762965, -1.7712976, -1.5724857, 12.0100328],
[-5.1552170, -4.4591852, -1.7650147, -1.7650147, -1.7553990, -1.1901430, 11.1138925],
[-5.1096854, -4.4827130, -1.7346669, -1.6597465, -1.6597465, -0.7478089, 10.2736429],
[-5.0542340, -4.5177998, -1.7045123, -1.5284168, -1.5284168, -0.2775791, 9.4983981],
[-5.0237827, -4.5511441, -1.6887208, -1.4771083, -1.4771082, 0.1833763, 8.7858902],
[-5.0164065, -4.5772794, -1.6754240, -1.4348124, -1.4348124, 0.6113402, 8.1576861],
[-5.0129888, -4.5959815, -1.6647539, -1.4024450, -1.4024450, 0.9732953, 7.6549334],
[-5.0332674, -4.6161649, -1.7064992, -1.4948265, -1.4948265, 1.2216768, 7.3107947],
[-4.9922295, -4.6156906, -1.6304340, -1.3987232, -1.3987232, 1.3116746, 7.2156383]]
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 -----------------------
G1 = EVB[GAMMA_P, 0.0]
G25 = EVB[GAMMA_P, 1.0]
G12 = EVB[GAMMA_P, 4.0]
X1 = EVB[LAST, 0.0]
X5 = EVB[LAST, 4.0]
L1 = EVB[0.0, 0.0]
L3 = EVB[0.0, 4.0]
L2P = EVB[0.0, 5.0]
#: LGAP L1 - L2', the gap above the neck. SHOWN, NOT ASSERTED: it comes out near 4.9 eV
#: here, against 5.40 in the paper's LDA column (whose pseudopotential keeps the 3s
#: and 3p shells in the valence; this one does not) and 4.95 measured. Every
#: OCCUPIED level below agrees with that column to 0.2 eV or better; why this
#: empty one differs by 0.5 has not been run down, so no tolerance is claimed.
LGAP = EVB[0.0, 6.0] - L2P
show G1
show G12
show X5
show L3
show L2P
show LGAP
test "the s band bottoms out at Gamma1, about 9.8 eV below the Fermi level" {
assert_near(G1, -9.79, 0.3)
}
test "the d bands sit where LDA puts them: Gamma12, X5 and L3" {
assert_near(G12, -2.27, 0.25)
assert_near(X5, -1.40, 0.25)
assert_near(L3, -1.63, 0.25)
}
test "d-band degeneracies: Gamma25' is a triplet; Gamma12, X5 and both L3 levels are doublets" {
assert_near(EVB[GAMMA_P, 3.0] - EVB[GAMMA_P, 1.0], 0.0, 1.0e-4)
assert_near(EVB[GAMMA_P, 5.0] - EVB[GAMMA_P, 4.0], 0.0, 1.0e-4)
assert_near(EVB[LAST, 4.0] - EVB[LAST, 3.0], 0.0, 1.0e-4)
assert_near(EVB[0.0, 2.0] - EVB[0.0, 1.0], 0.0, 1.0e-4)
assert_near(EVB[0.0, 4.0] - EVB[0.0, 3.0], 0.0, 1.0e-4)
}
test "d-band widths: Gamma12 - Gamma25', X5 - X3, X5 - X1, L3 - L3 and L3 - L1" {
assert_near(G12 - G25, 0.91, 0.15)
assert_near(X5 - EVB[LAST, 1.0], 3.23, 0.15)
assert_near(X5 - X1, 3.70, 0.25)
assert_near(L3 - EVB[0.0, 1.0], 1.58, 0.15)
assert_near(L3 - L1, 3.72, 0.25)
}
test "LDA's known failure: the d bands are too shallow (X5 is measured at -2.01 eV) and too wide (X5 - X1 is measured at 3.17 eV)" {
assert_gt(X5, -2.01 + 0.3)
assert_gt(X5 - X1, 3.17 + 0.3)
}
test "the neck of the Fermi surface: L2' is OCCUPIED, about 1.1 eV below the Fermi level" {
assert_near(L2P, -1.12, 0.3)
}
test "it is a metal: the sixth band is empty at X and occupied at L" {
assert_gt(EVB[LAST, 5.0], 0.5)
assert_lt(L2P, -0.5)
}
 
figure("Copper: 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])