import hfscf
import numpy as np
def SCF (r = 1.4632, Z=[1,1], b1 = hfscf.GTO["H"], b2 = hfscf.GTO["H"], b = 3):
# Происходит задание центров атомов
R = [0, r]
# Генерируем матрицу перекрывания S
s_scf = hfscf.S(R, b1, b2, b)
# Генерируем гамильтониан H для оператора Фока
h_scf = hfscf.H(R, Z, b1, b2, b)
# Диагонализируем матрицу S
# Так, находим диагональную матрицу Х (X = S^(-1/2)
# Xa - сопряженно-транспонированная матрица
X = hfscf.diagon(m=s_scf)
Xa = X.getH()
# Создаем матрицу плотности
p_scf = np.matrix([[0,0],[0,0]], dtype=np.float64)
# Проверяем сходимость SCF (итеративно заполняем матрицу F, диагонализируем, проверяем разницу)
for iteracion in range(50):
# Расчет двухэлектронной части матрицы Фока (G)
# Генерация матрицы Фока F, F = H + G
g_scf = hfscf.G(r, p_scf, b1, b2, b)
f_scf = h_scf + g_scf
# Теперь делаем матрицу F', F' = X_adj * F * X
f_tra = Xa * f_scf * X
# Диагонализируем матрицу F' с последующей генерацией C'
c_tra = hfscf.diagon2(m=f_tra)
# Построение матрицы коэффициентов C, C = X * C'
c_scf = X * c_tra
# Из матрицы C строим матрицу Р
# Пересчитываем матрицу плотности P
p_temp = hfscf.P(C=c_scf)
print("Завершил " + str(iteracion + 1) + " итерацию.\n")
# Происходит проверка сходимости
if np.linalg.norm(p_temp - p_scf) < 1E-4:
print("SCF сошлось!")
return {"S":s_scf,"H":h_scf,"X": X,"F":f_scf,"C":c_scf,"P":p_temp}
else:
p_scf = p_temp
print("SCF НЕ сошлось.")
return {"S":s_scf,"H":h_scf,"X": X,"F":f_scf,"C":c_scf,"P":p_temp}
S - матрица перекрывания,
F - матрица Фока,
X - диагональная матрица,
H - гамильтониан для оператора Фока,
C - матрица коэффициентов
orbitals = SCF()
Завершил 1 итерацию. Завершил 2 итерацию. Завершил 3 итерацию. Завершил 4 итерацию. Завершил 5 итерацию. Завершил 6 итерацию. Завершил 7 итерацию. SCF сошлось!
orbitals
{'S': matrix([[0.99999999, 0.63749012], [0.63749012, 0.99999999]]), 'H': matrix([[-1.09920375, -0.91954841], [-0.91954841, -1.09920375]]), 'X': matrix([[ 0.55258063, 1.17442445], [ 0.55258063, -1.17442445]]), 'F': matrix([[-0.34684107, -0.57771139], [-0.57771139, -0.34684028]]), 'C': matrix([[ 0.55258114, -1.17442421], [ 0.55258013, 1.17442468]]), 'P': matrix([[0.61069182, 0.61069071], [0.61069071, 0.6106896 ]])}
hfscf.orbital(orbitals['C'])
hfscf.orbital2D(orbitals['C'], orbitals['X'], orbitals['F'])
На картинке выше мы видим 2 орбитали (связывающая слева и разрыхляющая справа, по-видимому)
orben = hfscf.ener_orbs(orbitals['X'], orbitals['F'])
el_en = hfscf.ener_elec(orbitals['P'], orbitals['H'], orbitals['F'])
tot_en = hfscf.ener_tot(elec=el_en)
print('Энергии орбиталей:\t\t\t' + str(orben[0]) + ' и ' + str(orben[1]))
print('Электронная энергия молекулы:\t\t' + str(el_en))
print('Полная энергия молекулы:\t\t ' + str(tot_en))
Энергии орбиталей: -0.5646153594583118 и 0.6368673980935621 Электронная энергия молекулы: -1.7974485548087507 Полная энергия молекулы: -1.1140149845517797