【Python密度泛函理论】

简介: 【Python密度泛函理论】

13.png1. 密度泛函理论

密度泛函理论(Density Functional Theory)是一种研究多电子体系电子结构的量子力学方法。密度泛函理论在物理和化学上都有广泛的应用,特别是用来研究分子和凝聚态的性质,是凝聚态物理和计算化学领域最常用的方法之一。


电子结构理论的经典方法,特别是Hartree-Fock方法和后Hartree-Fock方法,是基于复杂的多电子波函数的。密度泛函理论的主要目标就是用电子密度取代波函数做为研究的基本量。因为多电子波函数有3N个变量(N 为电子数,每个电子包含三个空间变量),而电子密度仅是三个变量的函数,无论在概念上还是实际上都更方便处理。


Hohenberg-Kohn定理为泛函理论提供了坚实的理论基础:


第一定理指出体系的基态能量仅仅是电子密度的泛函。

第二定理证明了以基态密度为变量,将体系能量通过变分得到最小值之后就得到了基态能量。

密度泛函理论最普遍的应用是通过Kohn-Sham方法实现的。在Kohn-Sham DFT框架中,最难处理的多体问题被简化成了一个没有相互作用的电子在有效势场中的运动问题。


2. Numpy 1D-DFT

http://dcwww.camd.dtu.dk/~askhl/files/python-dft-exercises.pdf


Goal: write our own Kohn-Sham (KS) DFT code


Target: a harmonic oscillator including kinetic energy, electrostatic repulsion between the electrons, and the local density approximation for electronic interactions, ignoring correlation.


Hamiltonian:


1.png


What we have to do?


  1. Represent the Hamiltonian
  2. Calculate the KS wavefunctions, the density
import numpy as np
import matplotlib.pyplot as plt


2.1 Differential operator

In order to represent kinetic operator


2.1.1 First order differentiation


2.png

n_grid=200
x=np.linspace(-5,5,n_grid)
h=x[1]-x[0]
D=-np.eye(n_grid)+np.diagflat(np.ones(n_grid-1),1)
D = D / h


2.1.2 Second oorder differentiation


3.png


D2=D.dot(-D.T)
D2[-1,-1]=D2[0,0]


2.2 Non-interacting electrons

This is the Hamiltonian of non-interacting free particles in a box given by the size of grid:



4.png


eig_non, psi_non=np.linalg.eigh(-D2/2)


plot (energies are shown in the label)


for i in range(3):
    plt.plot(x,psi_non[:,i], label=f"{eig_non[i]:.4f}")
    plt.legend(loc=1)


2.3 Harmonic oscillator


5.png

X=np.diagflat(x*x)


and solve the KS.

eig_harm, psi_harm = np.linalg.eigh(-D2/2+X)


plot

for i in range(5):
    plt.plot(x,psi_harm[:,i], label=f"{eig_harm[i]:.4f}")
    plt.legend(loc=1)

6.png

2.4 Density

We will want to include the Coulomb or Hatree interacion as well as LDA exchange


Both of which are density functinals


So we need to calculate the electron density


7.png

# integral
def integral(x,y,axis=0):
    dx=x[1]-x[0]
    return np.sum(y*dx, axis=axis)


number of electrons

num_electron=17


density

def get_nx(num_electron, psi, x):
    # normalization
    I=integral(x,psi**2,axis=0)
    normed_psi=psi/np.sqrt(I)[None, :]
    # occupation num
    fn=[2 for _ in range(num_electron//2)]
    if num_electron % 2:
        fn.append(1)
    # density
    res=np.zeros_like(normed_psi[:,0])
    for ne, psi  in zip(fn,normed_psi.T):
        res += ne*(psi**2)
    return res


plot

plt.plot(get_nx(num_electron,psi_non, x), label="non")
plt.plot(get_nx(num_electron,psi_harm, x), label="harm")
plt.legend(loc=1)

8.png

2.5 Exchange energy


9.png

def get_exchange(nx,x):
    energy=-3./4.*(3./np.pi)**(1./3.)*integral(x,nx**(4./3.))
    potential=-(3./np.pi)**(1./3.)*nx**(1./3.)
    return energy, potential


2.6 coulomb potential


10.png

def get_hatree(nx,x, eps=1e-1):
    h=x[1]-x[0]
    energy=np.sum(nx[None,:]*nx[:,None]*h**2/np.sqrt((x[None,:]-x[:,None])**2+eps)/2)
    potential=np.sum(nx[None,:]*h/np.sqrt((x[None,:]-x[:,None])**2+eps),axis=-1)
    return energy, potential


2.7 Solve the KS equation:Self-consistency loop

initialize the density (you can take an arbitrary constant)

Calculate the Exchange and Hatree potentials

Calculate the Hamiltonian

Calculate the wavefunctions and eigen values

If not converged, calculate the density and back to 1.

def print_log(i,log):
    print(f"step: {i:<5} energy: {log['energy'][-1]:<10.4f} energy_diff: {log['energy_diff'][-1]:.10f}")
max_iter=1000
energy_tolerance=1e-5
log={"energy":[float("inf")], "energy_diff":[float("inf")]}
nx=np.zeros(n_grid)
for i in range(max_iter):
    ex_energy, ex_potential=get_exchange(nx,x)
    ha_energy, ha_potential=get_hatree(nx,x)
    # Hamiltonian
    H=-D2/2+np.diagflat(ex_potential+ha_potential+x*x)
    energy, psi= np.linalg.eigh(H)
    # log
    log["energy"].append(energy[0])
    energy_diff=energy[0]-log["energy"][-2]
    log["energy_diff"].append(energy_diff)
    print_log(i,log)
    # convergence
    if abs(energy_diff) < energy_tolerance:
        print("converged!")
        break
    # update density
    nx=get_nx(num_electron,psi,x)
else:
    print("not converged")

11.png

plot

for i in range(5):
    plt.plot(x,psi[:,i], label=f"{energy[i]:.4f}")
    plt.legend(loc=1)

12.png

compare the density to free particles

plt.plot(nx)
plt.plot(get_nx(num_electron,psi_harm,x), label="no-interaction")
plt.legend()


目录
相关文章
|
9月前
|
Python
核密度曲线(python
核密度曲线(python
81 0
|
9月前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习】密度聚类DBSCAN、OPTICS的讲解及实战演示(附源码 超详细)
【Python机器学习】密度聚类DBSCAN、OPTICS的讲解及实战演示(附源码 超详细)
590 0
|
4月前
|
数据采集 机器学习/深度学习 搜索推荐
Python自动化:关键词密度分析与搜索引擎优化
Python自动化:关键词密度分析与搜索引擎优化
|
9月前
|
数据可视化 数据挖掘 TensorFlow
Python贝叶斯高斯混合模型GMM聚类分析数据和混合密度可视化
Python贝叶斯高斯混合模型GMM聚类分析数据和混合密度可视化
python绘制正态分布及三大抽样分布的概率密度图像(一)
python绘制正态分布及三大抽样分布的概率密度图像(一)
python绘制正态分布及三大抽样分布的概率密度图像(一)
python绘制正态分布及三大抽样分布的概率密度图像(二)
python绘制正态分布及三大抽样分布的概率密度图像(二)
python绘制正态分布及三大抽样分布的概率密度图像(二)
|
数据可视化 Python
python可视化进阶---seaborn1.3 分布数据可视化 - 直方图与密度图 displot() / kdeplot()/ rugplot()
一、分布数据可视化 - 直方图与密度图 displot() / kdeplot()/ rugplot() 加载模块,设置风格,尺度
353 0
python可视化进阶---seaborn1.3 分布数据可视化 - 直方图与密度图 displot() / kdeplot()/ rugplot()
|
2月前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
2月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
2月前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
128 80

热门文章

最新文章