Python-分子动力学模拟-Lammps-离子液体-统计受限体系粒子的个数

   日期:2020-07-12     浏览:354    评论:0    
核心提示:Python-分子动力学模拟-Lammps-离子液体-统计受限体系粒子的个数小弟我第一次写博客,课题组沿用十几年的fortran源代码,一个人一个声明,根本看不懂,网上跟着黑马学习了python,写了几个程序,天下的语言都好,我一直都觉得能解决问题的语言就是好语言,管它是白猫还是黑猫,python的优点在于读取你想要的数据这点比较方便,缺点就是效率低下,反正我是工作站,有的是时间等他处理数据。言归正传,一般获取体系的粒子数是建模的第一步,不管你是NVT,NPT获取的也罢,都要统计受限区域的粒子个数,此博

Python-分子动力学模拟-Lammps-离子液体-统计受限体系粒子的个数

小弟我第一次写博客,课题组沿用十几年的fortran源代码,一个人一个声明,根本看不懂,网上跟着黑马学习了python,写了几个程序,天下的语言都好,我一直都觉得能解决问题的语言就是好语言,管它是白猫还是黑猫,python的优点在于读取你想要的数据这点比较方便,缺点就是效率低下,反正我是工作站,有的是时间等他处理数据。
言归正传,一般获取体系的粒子数是建模的第一步,不管你是NVT,NPT获取的也罢,都要统计受限区域的粒子个数,此博客的离子液体是[BMIM][BF4]和[BMIM][PF6],阳离子的中心原子采用的是N,阴离子的中心原子分别采用的是B和P。
可以交流学习一下,目前研二在读,一篇EA期刊IF=6.215,3月份接收的,
DOI: 10.1016/j.electacta.2020.135981
现在闲下来了,整理一下源代码。

图片

获取受限体系的平均粒子数

源码如下

注释的比较详细:
此源代码针对lammps输出的轨迹文件

# -*- coding: utf-8 -*-
# @Time : 2020/7/8 10:35 
# @Author :Jiabao_Zhu
# @File : read_confinedMolNumber.py 
# @Software: PyCharm
import pandas as pd
from numba import jit

LINES = 30000  # 看看是不是包含石墨烯的碳原子(不包含有30000) 33840
H_LINE = 9  # 表头,轨迹文件有几行空行
frames = 2002  # frame个数+1 因为range()函数左闭右开
rangeXfrom = -21.472  # XYZ的起始范围
rangeXto = 21.472
rangeYfrom = -19.905
rangeYto = 19.905
rangeZfrom = -18.375
rangeZto = 18.375

skiprows = [j * (LINES + H_LINE) + i for j in range(frames) for i in range(H_LINE)]
path = "./dumpNVT.lammpstrj"
# 取出数据,第2,3,4,5,6列,分别对应轨迹文件里的mol,type,x,y,z列
data = pd.read_csv(path, sep=' ', skiprows=skiprows, usecols=[1, 2, 3, 4, 5], header=None).values
f = open('confinedMolNumber.txt', 'w+', encoding='utf-8')  # 写入文件


@jit  # numba加速
def isInConfined_Anion(data):
    B_Number_List = []  # 创建符合条件的B原子个数的空列表,用来储存统计之后每一帧的个数
    for i in range(int(data.shape[0]/LINES)):  # data.shape[0]/LINES 指所有的数据行/一帧的行数,求出来就是多少帧的循环
        # 取出N1-bmim type 2 B-BF4 type 9 质心
        data_slice = data[i*LINES:(i+1)*LINES]  # 把所有帧的数据data进行切片,取出每一帧的数据进行处理
        atom_B = data_slice[data_slice[:, 1] == 9, 2:]  # data_slice[:,0]==9取出type为9的坐标
        B = atom_B
        B_index = []
        for j in range(B.shape[0]):  # shape[0]代表行数,shape[1]代表列数 B.shape[0]指取出来的B原子的行数=B的分子数
            # B-BF4边界判定
            if rangeXfrom < B[j][0] < rangeXto and rangeYfrom < B[j][1] < rangeYto and rangeZfrom < B[j][2] < rangeZto:
                B_index.append(j)
        B_Number = 0  # 符合条件的B原子个数的初始化
        for k in B_index:  # 遍历B_index列表,查看有多少个,
            B_Number += 1  # 一帧下的符合条件的个数
        # print(B_Number)
        B_Number_List.append(B_Number)  # 所有帧下的符合条件的个数添加到B_Number_List,如果有2帧,就应该有两个数据,2000帧,就应该有2000个数据
    # print(B_Number_List)
    B_Number_ = 0
    for l in B_Number_List:
        B_Number_ += l
    avg_B = str(B_Number_/(frames-1))  # 转化为str f.writelines(list_anion)只能识别str
    # print("阴离子平均个数为:", avg_B)
    list_anion = ["阴离子平均个数为:", avg_B]
    f.writelines(list_anion)


@jit
def isInConfined_Cation(data):
    N_Number_List = []
    for i in range(int(data.shape[0]/LINES)):
        # 取出N1-bmim type 2 B-BF4 type 9 质心
        data_slice = data[i*LINES:(i+1)*LINES]
        atom_N = data_slice[data_slice[:, 1] == 2, 2:]
        N = atom_N
        N_index = []
        for j in range(N.shape[0]):
            if rangeXfrom < N[j][0] < rangeXto and rangeYfrom < N[j][1] < rangeYto and rangeZfrom < N[j][2] < rangeZto:
                N_index.append(j)
        N_Number = 0
        for k in N_index:
            N_Number += 1
        N_Number_List.append(N_Number)
    N_Number_ = 0
    for l in N_Number_List:
        N_Number_ += l
    avg_N = str(N_Number_/((frames-1)*2))  # 转化为str
    # print("阳离子平均个数为:", avg_N)
    list_cation = ["阳离子平均个数为:", avg_N]
    f.writelines(list_cation)


if __name__ == "__main__":

    isInConfined_Cation(data)
    isInConfined_Anion(data)

    f.close()

效果如下:

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服