Функция Ванье — это концепция, соответствующая молекулярным орбиталям в периодических системах. Многие учебники по физике твердого тела подробно описывают функцию Ванье, например, глава 8 учебника Нанкинского университета «Теория твердого тела» [1]. Функция Ванье определяется как преобразование Фурье функции Блоха:
в
– количество элементарных ячеек (также равное
число).
В этой статье кратко представлена функция Ванье с точки зрения квантовой химии LCAO, которую должно быть легче понять тем, кто изучает электронную структуру молекул. Молекулярные орбитали записываются в форме ЛКАО:
ХФ периодической системы аналогичен, но регулярная орбита должна удовлетворять теореме Блоха. Для этого сначала произведем следующее преобразование к АО так, чтобы АО удовлетворяло теореме Блоха:
в
Является элементарной ячейкой
в
. Тогда для каждого
, запишите регулярную орбиту как LCAO:
это каждый
Коэффициент LCAO, полученный методом PBC-HF.
Далее мы также запишем функцию Ванье в форме ЛКАО. Из-за поступательной связи между функциями Ванье каждой элементарной ячейки нам нужно знать только функцию Ванье одной элементарной ячейки. существовать
Лилинг
:
Функция Ванье других элементарных ячеек проходит
Просто панорамируйте. Пучок
Заменять
, LCAO функции Ванье можно получить:
Подобно орбитальной локализации в молекулярных расчетах, функции Ванье также можно локализовать для получения максимально локализованных функций Ванье (MLWF). [2][3][4]
Wannier90 — программа для расчета MLWF. [5] Подробности см. на https://wannier.org/. Интерфейсы с несколькими программами электронной структуры: QE, VASP, Wien2K, PySCF и т. д. Wannier90 может работать независимо или использоваться как библиотека (обратите внимание, что режим lib можно использовать только последовательно).
Кратко представьте принцип расчета MLWF в Wannier90. каждому
, произведем унитарное преобразование функции Блоха:
Затем добавьте вновь полученное
в соответствии с
Становится функцией Ванье. унитарное преобразование
Определяется путем минимизации дисперсии положения функции Ванье (т.е. методом Бойса):
Конкретные детали реализации намного сложнее, чем молекула. Подробности см. в литературе. [2][3][5]
pyWannier90 — это интерфейс между PySCF и Wannier90. Он вызывает Wannier90 (режим lib) для генерации MLWF на основе орбиты, рассчитанной PySCF. Подробности см. на https://github.com/hungpham2017/pyWannier90. Пожалуйста, обратитесь к работе автора Хунга К. Фама о периодическом ДМЕТ [6].
В этой статье используется wannier90-3.1.0 и компилятор Intel. pyWannier90 необходимо сначала установить pybind11 и PySCF.
Разархивируйте wannier90-3.1.0 и pyWannier90 и замените wannier90-3.1.0/src/wannier90_lib.F90 на pyWannier90/src/wannier90_lib.F90.
Скопируйте wannier90-3.1.0/config/make.inc.ifort в wannier90-3.1.0/src/make.inc, удалите строки COMMS и MPIF90 (поскольку режим lib поддерживает только последовательный порт) и добавьте - в FCOPTS fPIC, который является:
F90 = ifort
FCOPTS= -O2 -fPIC
LDOPTS= -O2
Скомпилируйте wannier90 в режиме lib:
make && make lib
Введите pyWannier90/src и измените Makefile. Измените W90DIR на путь wannier90-3.1.0 и измените LIBDIR на путь Intel, например:
W90DIR =[path-to-]/wannier90-3.1.0
LIBDIR =[path-to-]/intel
Скомпилируйте pyWannier90:
make
Получите файл .so, например: libwannier90.cpython-310-x86_64-linux-gnu.so.
Поместите файл .so в [path-to]/pyscf/examples/pbc и запустите пример 47 (моя версия PySCF — 2.2.1):
python 47-pywannier90.py
В случае успеха будут созданы 8 файлов .xsf MLWF-[0-7].xsf. При открытии с помощью VESTA вы можете увидеть, например, 8 орбиталей кристалла Si.
Ниже приведен пример, показывающий использование pyWannier90 для расчета MLWF валентной зоны алмаза (2 орбитали на атом углерода, всего 4):
#импортироватьpywannier90и Расчет Модули, необходимые для PBC-HF
import numpy as np
from pyscf import lib
from pyscf.pbc import gto, scf
from pyscf.pbc.tools import pywannier90
#---------------- Создайте элементарную ячейку алмаза и определите базисный набор и псевдопотенциал --------------
cell = gto.Cell()
cell.atom='''
C 4.462500000000E-01 4.462500000000E-01 4.462500000000E-01
C -4.462500000000E-01 -4.462500000000E-01 -4.462500000000E-01
'''
cell.basis = 'gth-szv'; cell.pseudo = 'gth-pade'
cell.a = '''
0.000000000000E+00 0.178500000000E+01 0.178500000000E+01
0.178500000000E+01 0.000000000000E+00 0.178500000000E+01
0.178500000000E+01 0.178500000000E+01 0.000000000000E+00
'''
cell.build()
#-------------------------- Расчет PBC-HF --------------------------
kmesh = [2,2,2]
kpts = cell.make_kpts(kmesh);nkpts = len(kpts)
mf = scf.KRHF(cell, kpts)
ehf = mf.kernel()
#-------------- ----------Используйте pyWannier90 для расчета MLWF --------------------
nocc = int(sum(mf.mo_occ[0]))//2;ncore = 0
keywords = \
"""
exclude_bands : 5,6,7,8
"""
# Используйте ключевое слово «exclude_bands», чтобы удалить виртуальные орбиты (1–4 — занятые орбиты, 5–8 — виртуальные орбиты).
# Если это полностью электронный расчет, ядерные орбитали также можно удалить.
w90 = pywannier90.W90(mf, cell, kmesh, nocc-ncore, other_keywords=keywords)
# Инициализируйте объект W90, пять параметров: 1) PBC-HF; 2) элементарная ячейка; 3)к-точка; 4) Число Ваньефункций; 5) Другие параметры
w90.use_bloch_phases = True # Определить первое предположение: этот параметр напрямую использует обычную орбиту в качестве первого предположения.
w90.kernel() # Рассчитаем MLWF и получим формулу (7)вU матрица
mo_coeff_kpts = [w90.mo_coeff_kpts[ik][:,w90.band_included_list] for ik in range(nkpts)] #Регулярная занятая орбита каждой k точки
rotated_mo_coeff_kpts = lib.einsum('kui,kji->kuj', mo_coeff_kpts, w90.U_matrix) # Унитарное преобразование, формула (7)
Ts = lib.cartesian_prod((range(kmesh[0]), range(kmesh[1]), range(kmesh[2])))
phase = 1/nkpts*np.exp(1j*2*np.pi*np.dot(Ts, w90.kpt_latt_loc.T))
C_Lui = lib.einsum("kuv,Rk->Ruv", rotated_mo_coeff_kpts, phase) # Коэффициент LCAO, преобразованный к функции Ванье, формула (6)
w90.plot_wf(supercell=kmesh, grid=[20,20,20]) # Нарисовать функцию Ванье
Показ изображений функции Wannier:
Обратите внимание, что это относительно грубое использование, и некоторые проблемы не рассматриваются, например, различные
Количество дорожек может быть неодинаковым, полосы перепутаны и т.п. [3]. Для более подробной информации об использовании обратитесь к исходному коду pyscf/pbc/tools/pywannier90.py и руководству Wannier90.
Матрицу плотности можно рассчитать с помощью коэффициента ЛКАО функции Ванье:
Затем матрицу плотности можно использовать для проверки правильности функции Ванье, например:
Проверить, равна ли она матрице плотности HF (при условии отсутствия замороженного керна при расчете MLWF)
Преобразуйте матрицу плотности HF в реальное пространство:
Сравнивать
и
Равны ли они:
iLs = lib.cartesian_prod([range(kmesh[0]), range(kmesh[1]), range(kmesh[2])])
Ls = np.dot(iLs, cell.lattice_vectors())
expkLd = np.array(np.exp(1j*np.dot(kpts, Ls.T)), order='C')
dm_L_HF = np.einsum("kuv,kL->Luv", dm_k_hf, expkLd)/nkpts
assert np.allclose(dm_L_HF, dm_L)
Проверьте количество электронов
nelec_by_dm = lib.einsum("Luv,Luv->", dm_L, ovlp_L)
assert abs(nelec_by_dm - cell.nelectron) < 1e-6
Также имейте в виду некоторые возможные риски, связанные с Wannier90:
[1]: Ли Чжэнчжун, Теория твердого тела, второе издание, ISBN: 978-704011576-5. [2]:ПРБ, 1997, 56, 12847. [3]: ПРБ, 2001, 65, 035109. [4]: РМП, 2012, 84, 4, 1419. [5]: J. Phys.: Condens Matter 2020, 32, 165902. [6]: JCTC, 2020, 16, 130.
Установите PySCF-2.x в автономном режиме
https://gitlab.com/jxzou/qcinstall/-/blob/main/%E7%A6%BB%E7%BA%BF%E5%AE%89%E8%A3%85PySCF-2.x.md
Установите pybind11
https://gitlab.com/jxzou/qcinstall/-/blob/main/block2%E7%9A%84%E7%BC%96%E8%AF%91%E5%92%8C%E5%AE%89%E8%A3%85.md#21-%E5%AE%89%E8%A3%85pybind11