python wannier90 基于wannier90的*_hr.dat文件选取截断hopping绘制能带图

news2024/12/26 0:45:19

        我们知道wannier90可以根据选取TMDs的轨道信息生成详细的hopping energy *_hr.dat文件,选取所有的hopping绘制起来的时候比较简单,但是我们发现取几圈的近似hopping也可以将band表示出来,类似的思想有Pybinding的三带近似(DOI: 10.1103/PhysRevB.88.085433)和Fang的TMDs的紧束缚模型半经验参数近似(DOI: 10.1103/PhysRevB.92.205108)等等。

        我们首先要知道wannier90.dat文件里的数据格式,我们需要的是 类似于

-12   -6    0    1    1    0.000020   -0.000000
-12   -6    0    2    1    0.000000   -0.000000
-12   -6    0    3    1    0.000000    0.000000
-12   -6    0    4    1    0.000004    0.000000
-12   -6    0    5    1    0.000000    0.000000

这样的数据,这里前面三个代表directions[x,y,z] 中间两个代表[fromAtom, toAtom]也就是Rij,后面两个值代表了hopping,代表复数 a+bi 的[a, b]。

        这里的画圈有点类似,也就是根据选择当前原子和目标原子的距离来简要进行阶段,例如下图展示了四层原子(包括[0,0]),可能第三圈的hopping贡献远大于第四圈,所以截取到第三圈即可绘制band。

 这里给出MX_2部分示例,选取M的d_(z^2) d_(xy) d_(x^2-y^2)和总的S轨道计算的一个wannier90 *_hr.dat文件,任意选择截取1-10([0,0]就算了几乎是onsite energy)圈的一个代码,其实取到第5圈就已经比较近似于全部圈层的结果了:

#!/usr/bin python
# -*- encoding: utf-8 -*-
'''
@Author  :   Celeste Young
@File    :   基于fang2015提取MoS2轨道.py    
@Time    :   2023/4/3 14:47  
@E-mail  :   iamwxyoung@qq.com
@Tips    :   
'''

import time
import matplotlib.pyplot as plt
import pandas as pd
# import pybinding as pb
import numpy as np
import functools
import threading


def make_path(k0, k1, *ks, step=0.1):  # kpath 
    k_points = [np.atleast_1d(k) for k in (k0, k1) + ks]
    if not all(k.shape == k_points[0].shape for k in k_points[:1]):
        raise RuntimeError("All k-points must have the same shape")

    k_paths = []
    point_indices = [0]
    for k_start, k_end in zip(k_points[:-1], k_points[1:]):
        num_steps = int(np.linalg.norm(k_end - k_start) // step)
        # k_path.shape == num_steps, k_space_dimensions
        k_path = np.array([np.linspace(s, e, num_steps, endpoint=False)
                           for s, e in zip(k_start, k_end)]).T
        k_paths.append(k_path)
        point_indices.append(point_indices[-1] + num_steps)
    k_paths.append(k_points[-1])

    return np.vstack(k_paths)  # , point_indices)


def isinDirect(v_, hvts):  # 判断是否在所选的directions里,上图的n层
    for vs in hvts:
        if ''.join(v_) == ''.join(list(map(str, vs))):
            return True
    return False


def read_dat(*args, **kwargs):
    with open("data/wannier90_hr_MoS2.dat", "r") as f:
        lines = f.readlines()
    rij = [[[] for col in range(nb)] for row in range(nb)]
    tij = [[[] for col in range(nb)] for row in range(nb)]
    for line in lines:
        ll = line.split()
        if isinDirect(ll[:3], kwargs['hvts']):
            x, y, z, frAt, toAt = list(map(int, ll[:5]))
            t_real, t_image = list(map(float, ll[5:]))
            rij[frAt - 1][toAt - 1].append([x, y, z])
            tij[frAt - 1][toAt - 1].append([t_real + 1j * t_image])
 
    return rij, tij


def plot_rec(*args, **kwargs):  # 绘制布里渊区的积分路径
    fig = plt.figure(figsize=(5, 5))
    ax = plt.axes()
    ax.arrow(0, 0, a1[0], a1[1], length_includes_head=False, head_width=0.05, fc='b', ec='k')
    ax.arrow(0, 0, a2[0], a2[1], length_includes_head=False, head_width=0.05, fc='b', ec='k')
    ax.arrow(0, 0, b1[0], b1[1], length_includes_head=False, head_width=0.05, fc='r', ec='red')
    ax.arrow(0, 0, b2[0], b2[1], length_includes_head=False, head_width=0.05, fc='r', ec='red')
    ax.plot([0, Middle[0], K1[0], 0], [0, Middle[1], K1[1], 0])
    ax.scatter([0, Middle[0], K1[0], 0], [0, Middle[1], K1[1], 0])
    ax.set_xlim(-1, 4)
    ax.set_ylim(-2, 4)
    ax.grid()
    plt.show()


def phase(*args, **kwargs):
    rij = kwargs['hr']
    wk = kwargs['wk']
    R_vec = 0
    for ii in range(3):
        R_vec += rij[ii] * basis_vector[ii]
    inner_product = np.dot(R_vec, wk)
    return np.exp(1j * inner_product)


def Hamham(wak, tij, rij):
    h = np.zeros((nb, nb), dtype=complex)
    for ii in range(nb):
        for jj in range(nb):
            for vij in range(len(rij[ii][jj])):
                hr = rij[ii][jj][vij]
                h[ii, jj] = h[ii, jj] + tij[ii][jj][vij][0] * phase(hr=hr, wk=wak)
    return h


def get_sphere(*args, **kwargs):  #获取需要的层的directions,传入参数n=[1,11)
    sp_ = args[0]
    spDict = {}
    # sp = 0
    sp0 = [[0, 0, 0]]
    spDict['sp0'] = sp0
    # sp = 1 >> 3*2
    sp1 = [[1, 0, 0], [1, 1, 0], [0, 1, 0]]
    sp1 = sp1 + [list(-np.array(sp1[i])) for i in range(len(sp1))]
    spDict['sp1'] = sp1
    # sp = 2 >> 3*2
    sp2 = [[2, 1, 0], [1, 2, 0], [-1, 1, 0]]
    sp2 = sp2 + [list(-np.array(sp2[i])) for i in range(len(sp2))]
    spDict['sp2'] = sp2
    # sp = 3 >> 3*2
    sp3 = [[2, 0, 0], [2, 2, 0], [0, 2, 0]]
    sp3 = sp3 + [list(-np.array(sp3[i])) for i in range(len(sp3))]
    spDict['sp3'] = sp3
    # sp = 4 >> 6*2
    sp4 = [[3, 1, 0], [3, 2, 0], [2, 3, 0], [1, 3, 0], [-1, 2, 0], [-2, 1, 0]]
    sp4 = sp4 + [list(-np.array(sp4[i])) for i in range(len(sp4))]
    spDict['sp4'] = sp4
    # sp = 5 >> 3*2
    sp5 = [[3, 0, 0], [3, 3, 0], [0, 3, 0]]
    sp5 = sp5 + [list(-np.array(sp5[i])) for i in range(len(sp5))]
    spDict['sp5'] = sp5
    # sp = 6 >> 3*2
    sp6 = [[4, 2, 0], [2, 4, 0], [-2, 2, 0]]
    sp6 = sp6 + [list(-np.array(sp6[i])) for i in range(len(sp6))]
    spDict['sp6'] = sp6
    # sp = 7 >> 3*2
    sp7 = [[4, 1, 0], [4, 3, 0], [3, 4, 0], [1, 4, 0], [-1, 3, 0], [-3, 1, 0]]
    sp7 = sp7 + [list(-np.array(sp7[i])) for i in range(len(sp7))]
    spDict['sp7'] = sp7
    # sp = 8 >> 3*2
    sp8 = [[4, 0, 0], [4, 4, 0], [0, 4, 0]]
    sp8 = sp8 + [list(-np.array(sp8[i])) for i in range(len(sp8))]
    spDict['sp8'] = sp8
    sp9 = [[5, 2, 0], [5, 3, 0], [2, 5, 0], [3, 5, 0], [-2, 3, 0], [-3, 2, 0]]
    sp9 = sp9 + [list(-np.array(sp9[i])) for i in range(len(sp9))]
    spDict['sp9'] = sp9
    sp10 = [[5, 1, 0], [5, 4, 0], [1, 5, 0], [4, 5, 0], [-1, 4, 0], [-4, 1, 0]]
    sp10 = sp10 + [list(-np.array(sp10[i])) for i in range(len(sp10))]
    spDict['sp10'] = sp10
    if sp_ == 0:
        return sp0

    tmpl = []
    for i in range(sp_):
        tmpl += [j for j in spDict['sp%d' % i]]
    return tmpl


def selectAllOrbital():
    with open("data/wannier90_hr_MoS2.dat", "r") as f:
        lines = f.readlines()
    rij = [[[] for col in range(nb)] for row in range(nb)]
    tij = [[[] for col in range(nb)] for row in range(nb)]
    for line in lines:
        ll = line.split()
        if len(ll) == 7:
            x, y, z, frAt, toAt = list(map(int, ll[:5]))
            t_real, t_image = list(map(float, ll[5:]))
            rij[frAt - 1][toAt - 1].append([x, y, z])
            tij[frAt - 1][toAt - 1].append([t_real + 1j * t_image])
    hamilton = functools.partial(Hamham, tij=tij, rij=rij)
    idx = 0
    result = np.zeros([len(path), 11])
    for kxy in range(len(path)):
        k = np.r_[path[kxy], [0]]
        w, t = np.linalg.eig(hamilton(k))
        w = list(w)
        w.sort()
        result[idx, :] = np.real(w)  # 将本征值进行保存
        idx += 1
    xk = [0, rt3, rt3 + 1, rt3 + 3]
    kk = np.linspace(0, 4.7, num=len(path))  # 作为x轴,使其和本征值矩阵每一列的y的值个数相同
    plt.figure(figsize=(4, 5))
    plt.plot(kk, result, c="r")
    plt.xticks(xk, ["Γ", "M", "K", "Γ"])
    plt.ylabel("Energy(eV)", fontsize=14)
    plt.axvline(rt3, color='gray', linestyle='--')
    plt.axvline(rt3 + 1, color='gray', linestyle='--')
    plt.title('all orbital')
    plt.savefig('all orbital.png')
    print('Saved all orbital figure!')


def selectOrbital(orbi):
    print('started %d/%d' % (orbi, 10))
    hvts = get_sphere(orbi)
    result = np.zeros([len(path), 11])  # 解的矩阵
    Rij, Tij = read_dat(hvts=hvts)
    hamilton = functools.partial(Hamham, tij=Tij, rij=Rij)
    idx = 0
    for kxy in range(len(path)):
        k = np.r_[path[kxy], [0]]
        w, t = np.linalg.eig(hamilton(k))
        w = list(w)
        w.sort()
        result[idx, :] = np.real(w)  # 将本征值进行保存
        idx += 1
    xk = [0, rt3, rt3 + 1, rt3 + 3]
    kk = np.linspace(0, 4.7, num=len(path))  # 作为x轴,使其和本征值矩阵每一列的y的值个数相同
    plt.figure(figsize=(4, 5))
    plt.plot(kk, result, c="r")
    plt.xticks(xk, ["Γ", "M", "K", "Γ"])
    plt.ylabel("Energy(eV)", fontsize=14)
    plt.axvline(rt3, color='gray', linestyle='--')
    plt.axvline(rt3 + 1, color='gray', linestyle='--')
    plt.title('%d orbital' % orbi)
    plt.savefig('%d orbital.png' % orbi)
    print('finish %d/%d' % (orbi, 10))


if __name__ == '__main__':
    # start here
    time1 = time.time()
    nb = 11  # number of bands
    a = 3.160  # 3.18
    c = 12.29  # distance of layers
    dxx = 3.13  # distance of orbital X-X
    dxm = 2.41  # distance of orbital X-M
    # constant checked
    rt3 = 3 ** 0.5
    pi = np.pi
    a1 = a * np.array([rt3 / 2, -1 / 2, 0])
    a2 = a * np.array([0, 1, 0])
    a3 = a * np.array([0, 0, 5])
    basis_vector = np.array([a1, a2, a3])

    b1 = 2 * pi / a * np.array([1 / rt3, 1])
    b2 = 4 * pi / a / rt3 * np.array([1, 0])

    Gamma = np.array([0, 0])
    Middle = 1 / 2 * b1
    K1 = 1 / 3 * (2 * b1 - b2)
    K2 = -1 / 3 * (2 * b1 - b2)
    # plot_rec()
    path = make_path(Gamma, Middle, K1, Gamma, step=0.01)

    # selectAllOrbital()  # 这里取消注释会绘制总的圈层的band

    for orb in range(1, 11):
        selectOrbital(orbi=orb)


    time2 = time.time()
    print('>> Finished, use time %d s' % (time2 - time1))

附上我的hr.dat的结果图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/431383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

区块链技术在软件开发中的应用

如果你是一名软件开发者或者IT从业者,你一定已经听说过区块链技术。区块链是一种基于密码学的分布式账本技术,被广泛应用于数字货币、金融、物联网等领域。但是,除了这些领域之外,区块链技术还可以在软件开发中发挥重要作用。本文…

CLIP 论文解读

文章目录模型训练推理实验与Visual N-Grams 相比较分布Shift的鲁棒性不足参考现有的计算机视觉系统用来预测一组固定的预订对象类别,比如ImageNet数据集有1000类,CoCo数据集有80类。这种受限的监督形式限制了模型的通用性和可用性。使用这种方法训练好的…

《花雕学AI》02:人工智能挺麻利,十分钟就为我写了一篇长长的故事

ChatGPT最近火爆全网,上线短短两个多月,活跃用户就过亿了,刷新了历史最火应用记录,网上几乎每天也都是ChatGPT各种消息。国内用户由于无法直接访问ChatGPT,所以大部分用户都无缘体验。不过呢,前段时间微软正…

Nginx实现会话保持,集群模式下session域共享

前言 生产环境下,多数系统为了应对线上多种复杂情况而进行了集群架构的部署,保证系统的高性能、价格有效性、可伸缩性、高可用性等。通常将生产环境下的域名指向Nginx服务,通过它做HTTP协议的Web负载均衡。 session是什么 在计算机中&…

13.广度优先搜索

一、算法内容 1.简介 广度优先搜索BFS(Breadth First Search)按照广度优先的方式进行搜索,可以理解为“尝试所有下一步可能”地穷举所有可行的方案,并不断尝试,直到找到一种情况满足问题问题的要求。 BFS从起点开始…

C语言——学生信息管理系统(数组)

文章目录一、前言二、目的三、框架1.菜单1.1主菜单1.2子菜单2.流程图2.1总流程图2.2开始流程图2.3增加学生信息流程图2.4.删除学生信息流程图2.5修改学生信息流程图2.6查询学生信息流程图2.7对学生信息排序流程图3.思路四、代码五、演示视频一、前言 因为最近是在赶进度总结&a…

无人驾驶--工控机安装autoware

时隔好久,又来写文章了,这次有高人指点,要系统的学习一下无人驾驶了。 使用的是易咖的底盘车,工控机是米文动力Apex Xavier II,基于autoware框架 首先是在工控机上安装autoware,工控是ubuntu18环境。 参…

Python入门教程+项目实战-9.2节: 字符串的操作符

目录 9.2.1 字符串常用操作符 9.2.2 操作符:拼接字符串 9.2.3 *操作符:字符串的乘法 9.2.4 []操作符:索引访问 9.2.5 [:]操作符:分片字符串 9.2.6 in操作符:查找子串 9.2.7 %操作符:格式化字符串 9…

为什么要做软件测试

随着信息技术的发展和普及,人们对软件的使用越来越普及。但是在软件的使用过程中,软件的效果却不尽如人意。为了确保软件的质量,整个软件业界已经逐渐意识到测试的重要性,软件测试已经成为IT 领域的黄金行业。本篇文章将会带领大家…

使用Tensorboard多超参数随机搜索训练

文章目录1超参数训练代码2远端电脑启动tensorboard完整代码位置https://gitee.com/chuge325/base_machinelearning.git 这里还参考了tensorflow的官方文档 但是由于是pytorch训练的差别还是比较大的,经过多次尝试完成了训练 硬件是两张v100 1超参数训练代码 这个…

Android Studio升级Gradle Plugin升级导致项目运行失败问题

背景&错误 升级Android Studio 旧项目无法运行,奇奇怪怪什么错误都有 例如: java.lang.IllegalAccessError: class org.gradle.api.internal.tasks.compile.processing.AggregatingProcessingStrategy (in unnamed module 0x390ea9fb) cannot acce…

传智健康-day2

一.需求分析(预约管理功能开发) 预约管理功能,包括检查项管理、检查组管理、体检套餐管理、预约设置等、预约管理属于系统的基础功能,主要就是管理一些体检的基础数据。 检查组是检查项的集合 二.基础环境搭建 1导入预约管理模块数据表 需要用到的…

Ubuntu安装MySQL及常用操作

一、安装MySQL 使用以下命令即可进行mysql安装,注意安装前先更新一下软件源以获得最新版本: sudo apt-get update #更新软件源 sudo apt-get install mysql-server #安装mysql 上述命令会安装以下包: apparmor mysql-client-5.7 mysql-c…

不定期更新:我对 ChatGPT 进行多方位了解后的报告,超级全面,建议想了解的朋友看看

优质介绍视频: GPT4前端【AI编程新纪元】 【渐构】万字科普GPT4为何会颠覆现有工作流;为何你要关注微软Copilot、文心一言等大模型 此文章不定期更新(一周应该会更新一次) 最近一次更新:2023.4.16 12:00 ChatGPT 是什…

零基础搭建私人影音媒体平台【远程访问Jellyfin播放器】

文章目录1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置4.公网访问测试5. 结语1. 前言 随着移动智能设备的普及,各种各样的使用需求也被开发出来&#xf…

关于加强供水企业营销管理的几点思考

供水营销部门是供水企业最重要的职能部门之一,其工作职能直接与供水企业的经济利益和社会效益息息相关,具体来说,主要涉及到五个方面的指标内容:水费回收率、 水量漏损率(产销差率)、水表完好率、水价调整及…

《年会抽奖》:无人获奖的概率

目录 一、题目 二、思路 1、错排问题 2、n 的阶乘 3、输出格式要求 三、代码 一、题目 题目:年会抽奖 题目链接:年会抽奖 今年公司年会的奖品特别给力,但获奖的规矩却很奇葩: 1. 首先,所有人员都将…

SpringBoot起步依赖和自动配置

文章目录 1、起步依赖2、自动配置 1、起步依赖 概念 起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起支持某一功能。 简单的说,起步依赖就…

这才是后端API该有的样子

一般系统大致架构如下: 有些小伙伴会说,这个架构太简单太low了吧,什么网关、缓存、消息中间件都没有。 需要说明的是,因为我们主题是API接口(tbAPI,pinduoduo API接口调用)所以聚焦这一点上就行…

Java FileChannel文件的读写实例

一、概述: 文件通道FileChannel是用于读取,写入,文件的通道。FileChannel只能被InputStream、OutputStream、RandomAccessFile创建。使用fileChannel.transferTo()可以极大的提高文件的复制效率,他们读和写直接建立了通道&#x…