当前位置: 首页 > news >正文

晶界能计算

直接上公式,我计算了两种晶界有关的能量。

晶界形成能是展示稳定性的,我觉得和偏聚功差别并不大。

一、TiAl-TiB2界面

晶界能TiAl-TiB2
type堆叠方式EGB+BAbulk-TiAlbulk-TiB2γGB稳定性
B端1ABC-216.91034.2717-58.51969191-108.543-0.72723稳定
2ACB-214.415-59.8739562-108.543-0.67108
3BAC-217.876-58.17774813-108.543-0.74631
5CAB-216.853-59.87370293-108.543-0.70665
4BCA-216.679-58.17779715-108.543-0.72885
6CBA-214.112-58.52002092-108.543-0.68641
Ti端ABC-191.996-58.52040265-99.1439-0.50088稳定
ACB-191.987-58.17828086-99.1443-0.50573
BAC-201.359-59.87465277-99.1439-0.61771
CAB-200.617-59.87458076-99.1438-0.60689
BCA-201.635-58.17821694-99.144-0.6465
CBA-198.692-58.52062103-99.1437-0.59856

根据论文,这种界面分为Ti端和B端终止,这里还对他们的堆叠方式做出了区分。(B端的123456代表文件夹里的文件序号qwq)。EGB+B是拼接后界面的能量,A用下面代码即可计算:

import numpy as np
import osdef calculate_gb_area(poscar_file, gb_plane='001'):with open(poscar_file, 'r') as f:lines = f.readlines()a = np.array([float(x) for x in lines[2].split()])b = np.array([float(x) for x in lines[3].split()])c = np.array([float(x) for x in lines[4].split()])if gb_plane == '001':a1, a2 = a, belif gb_plane == '110':a1, a2 = a, (b + c)/2else:raise ValueError("Unsupported gb_plane: use '001' or '110'")area = np.linalg.norm(np.cross(a1, a2))return area# 获取当前目录下所有.vasp文件
vasp_files = [f for f in os.listdir('.') if f.endswith('.vasp')]# 打开输出文件
with open('gb_areas.txt', 'w') as out_file:out_file.write("Filename\t\tInterface Area (Ų)\n")out_file.write("--------------------------------------\n")for vasp_file in vasp_files:try:area = calculate_gb_area(vasp_file, gb_plane='001')out_file.write(f"{vasp_file}\t{area:.4f}\n")except Exception as e:out_file.write(f"{vasp_file}\tError: {str(e)}\n")

事实证明,不同的堆叠方式并不会影响晶面面积。

接着,因为我当初用materials studio直接扩胞建模,所以我并没有晶界两端bulk的模型,所以这里直接将生成的晶界模型劈成两端,只要具有周期性那就没有问题(我也不知道为啥)。分成两部分的代码在这里:

import numpy as np
import osdef read_poscar(poscar_file):with open(poscar_file, 'r') as f:lines = f.readlines()# 读取标题和缩放因子title = lines[0].strip()scale = float(lines[1].strip())# 读取晶格向量lattice = []for i in range(2, 5):lattice.append([float(x) for x in lines[i].split()])lattice = np.array(lattice)# 读取元素种类和数量elements = lines[5].split()counts = [int(x) for x in lines[6].split()]# 确定坐标类型coord_type = lines[7].strip().lower()# 读取所有原子坐标coords = []for line in lines[8:8+sum(counts)]:coords.append([float(x) for x in line.split()[:3]])coords = np.array(coords)return title, scale, lattice, elements, counts, coord_type, coordsdef write_poscar(filename, title, scale, lattice, elements, counts, coord_type, coords):with open(filename, 'w') as f:f.write(title + '\n')f.write(f"{scale:20.16f}\n")for vec in lattice:f.write(f"{vec[0]:20.16f} {vec[1]:20.16f} {vec[2]:20.16f}\n")f.write(' '.join(elements) + '\n')f.write(' '.join(map(str, counts)) + '\n')f.write(coord_type + '\n')for coord in coords:f.write(f"{coord[0]:20.16f} {coord[1]:20.16f} {coord[2]:20.16f}\n")def get_composition_name(elements):"""根据元素组成返回适当的文件名部分"""elem_set = set(elements)if elem_set == {'Ti', 'B'}:return 'TiB2'elif elem_set == {'Ti', 'Al'}:return 'TiAl'elif elem_set == {'Ti', 'Al', 'B'}:return 'TiAlB'elif 'Ti' in elem_set and 'Al' in elem_set:return 'TiAl'elif 'Ti' in elem_set and 'B' in elem_set:return 'TiB2'else:return '_'.join(sorted(elements))def split_poscar(poscar_file, output_prefix):try:title, scale, lattice, elements, counts, coord_type, coords = read_poscar(poscar_file)# 创建原子类型列表atom_types = []for elem, count in zip(elements, counts):atom_types += [elem] * count# 分离z坐标>0.5的原子mask = coords[:, 2] > 0.5coords_z_gt_05 = coords[mask]types_z_gt_05 = [atom_types[i] for i in range(len(atom_types)) if mask[i]]coords_z_le_05 = coords[~mask]types_z_le_05 = [atom_types[i] for i in range(len(atom_types)) if not mask[i]]# 统计元素数量并保持原始顺序def count_elements(types, elements_order):counts = []for elem in elements_order:counts.append(types.count(elem))return counts# 保持原始元素顺序elements_order = elements# 统计上部分(z>0.5)counts_z_gt_05 = count_elements(types_z_gt_05, elements_order)filtered_elements_z_gt_05 = [elem for elem, cnt in zip(elements_order, counts_z_gt_05) if cnt > 0]filtered_counts_z_gt_05 = [cnt for cnt in counts_z_gt_05 if cnt > 0]# 统计下部分(z<=0.5)counts_z_le_05 = count_elements(types_z_le_05, elements_order)filtered_elements_z_le_05 = [elem for elem, cnt in zip(elements_order, counts_z_le_05) if cnt > 0]filtered_counts_z_le_05 = [cnt for cnt in counts_z_le_05 if cnt > 0]# 重新排序坐标以匹配元素顺序def reorder_coords(types, coords, elements_order):reordered_coords = []for elem in elements_order:for i, atom_type in enumerate(types):if atom_type == elem:reordered_coords.append(coords[i])return np.array(reordered_coords)coords_z_gt_05 = reorder_coords(types_z_gt_05, coords_z_gt_05, filtered_elements_z_gt_05)coords_z_le_05 = reorder_coords(types_z_le_05, coords_z_le_05, filtered_elements_z_le_05)# 生成智能文件名base_name = os.path.splitext(os.path.basename(poscar_file))[0]comp_name_upper = get_composition_name(filtered_elements_z_gt_05)comp_name_lower = get_composition_name(filtered_elements_z_le_05)output_upper = f"{output_prefix}/{base_name}_{comp_name_upper}.vasp"output_lower = f"{output_prefix}/{base_name}_{comp_name_lower}.vasp"# 创建输出目录(如果不存在)os.makedirs(output_prefix, exist_ok=True)# 写入文件write_poscar(output_upper, title, scale, lattice, filtered_elements_z_gt_05, filtered_counts_z_gt_05, coord_type, coords_z_gt_05)write_poscar(output_lower, title, scale, lattice, filtered_elements_z_le_05, filtered_counts_z_le_05, coord_type, coords_z_le_05)return True, base_name, comp_name_upper, comp_name_lowerexcept Exception as e:print(f"处理文件 {poscar_file} 时出错: {str(e)}")return False, os.path.basename(poscar_file), "", ""def process_all_vasp_files(input_dir=".", output_dir="split_results"):# 获取当前目录下所有.vasp文件和POSCAR文件vasp_files = [f for f in os.listdir(input_dir) if f.endswith('.vasp') or f == 'POSCAR']if not vasp_files:print("当前目录下未找到.vasp文件")returnprint(f"找到 {len(vasp_files)} 个VASP文件需要处理")success_count = 0for vasp_file in vasp_files:file_path = os.path.join(input_dir, vasp_file)success, filename, comp_upper, comp_lower = split_poscar(file_path, output_dir)if success:print(f"已处理: {filename} -> {comp_upper}.vasp 和 {comp_lower}.vasp")success_count += 1else:print(f"处理失败: {filename}")print(f"\n处理完成! 成功处理 {success_count}/{len(vasp_files)} 个文件")print(f"结果保存在 {output_dir} 目录中")if __name__ == "__main__":process_all_vasp_files()

然后,将分成的vasp文件分别跑一下单点,得到表中两列bulk的能能量,根据公式计算即可。表中的结果看来,TiB2-TiAl的界面比单胞更稳定,而且B端终止稳定性优于Ti端终止。

二、TiAl-Ti3Al界面

这个界面模型是师兄建立的,我在界面的基础上掺杂了B。

掺杂位置主要选择了S2、S4、S6三种,计算掺杂后的总能量为E-TiAlB。break成上图的三段后,分别计算top、middle、low的能量,面积A计算方法也同上。即可得到晶界能。

  topmiddlelowAE-TiAlE-TiAlBγGB晶界能γseg偏析能
PST-300_gama-Ti3Al-relaxedS2-106.304-105.44297-92.98328.3977-317.774-324.3302-0.3451-6.55643
S4-105.05091-324.0399-0.34689-6.26608
S6-104.16193-324.2835-0.36683-6.50971
PST-240_gama-Ti3Al-relaxedS2-94.98266728.3313-318.527-325.3086-0.54778-6.78167
S4-105.46357-324.8508-0.35473-6.32382
S6-105.40963-325.0233-0.35873-6.49635
PST-180_gama-Ti3Al-relaxedS2-104.5420728.3174-318.457-323.9392-0.35508-5.48205
S4-105.35087-324.7065-0.35435-6.2493
S6-104.31086-324.4751-0.36863-6.01792
PST-120_gama-Ti3Al-relaxedS2-98.86630828.323-318.523-325.2518-0.47838-6.72918
S4-105.33213-324.7574-0.35551-6.23483
S6-104.44461-324.54450.032671-6.02188
PST-60_gama-Ti3Al-relaxedS2-102.5388628.3228-318.456-325.0617-0.4102-6.60592
S4-102.82955-324.6415-0.39765-6.18573
S6-102.17671-324.8985-0.41371-6.44274
PST-0_gama-Ti3Al-relaxedS2-104.9467728.3995-317.681-323.9896-0.34782-6.3082
S4-104.1744-324.3511-0.36778-6.6697
S6-94.60448-323.656-0.52403-5.97457
gammaTiAl-111-120-relaxedS2-98.89486228.0138-296.501-303.183-0.08926-6.68245
S4-87.290235-302.0732-0.27658-5.5727
S6-86.968389-302.8875-0.29685-6.38696
gamma-gama-111-0-relaxedS2-99.32918827.9281-297.36-303.9991-0.09637-6.63927
S4-87.756831-303.9992-0.30355-6.63932
S6-86.846781-303.6142-0.31295-6.25432
gamma-gama-60-relaxedS2-98.88615328.0247-296.48-303.1616-0.089-6.68125
S4-88.365886-303.2357-0.27802-6.75533
S6-86.345828-302.9114-0.30827-6.43109

偏析能就更加简单了,用E-TiAlB-E-TiAl即可。由结果可见,B的掺杂使界面更加稳定。

http://www.dtcms.com/a/304523.html

相关文章:

  • flexiblejs + pxtorem 实现浏览器缩放适配:兼顾系统缩放与文本放大体验
  • 图形界面应用程序技术栈大全
  • getgff.py脚本-python006
  • 【学习路线】游戏开发大师之路:从编程基础到独立游戏制作
  • 2025年科研算力革命:8卡RTX 5090服务器如何重塑AI研究边界?
  • react 项目怎么打断点
  • vite + chalk打印输出彩色命令行
  • 基于Dify构建本地化知识库智能体:从0到1的实践指南
  • 橡胶制品加工:塑造生活的柔韧力量
  • python基础:request请求Cookie保持登录状态、重定向与历史请求、SSL证书校验、超时和重试失败、自动生成request请求代码和案例实践
  • Python批量生成N天前的多word个文件,并根据excel统计数据,修改word模板,合并多个word文件
  • 中科米堆CASAIM金属件自动3d测量外观尺寸三维检测解决方案
  • 火山方舟使用豆包基模 —— 基础流程
  • 深港同心·科创启航——“智创探索+实习计划”启航礼在前海举行
  • 三十、【Linux邮件服务器】搭建Postfix邮件服务器
  • Ubuntu卡在启动画面:显卡驱动与密码重置
  • ubuntu18.04制作raid0
  • Ubuntu 部署 PaddleOCR 完整指南
  • Ubuntu 抽取系统制作便于chroot的镜像文件
  • C#开发基础之深入理解“集合遍历时不可修改”的异常背后的设计
  • 三十一、【Linux网站服务器】搭建httpd服务器演示个人主页、用户认证、https加密网站配置
  • Solar月赛(应急响应)——攻击者使用什么漏洞获取了服务器的配置文件?
  • GESP2025年6月认证C++七级( 第三部分编程题(2)调味平衡)
  • cuda中的线程块和线程束的区别以及什么是串行化 (来自deepseek)
  • 1 + X 传感网 中级 | 任务五 Wifi通信实践
  • 向量数据库深度解析:FAISS、Qdrant、Milvus、Pinecone使用教程与实战案例
  • Excel文件批量加密工具
  • 哈希函数详解:从MD5到SHA-3的密码学基石
  • JSON-RPC 2.0 规范
  • 寻找重复元素-类链表/快慢指针