计算化学公社

标题: RASPA批量计算输入文件中的Unitcells值怎么确定 [打印本页]

作者
Author:
thor    时间: 2023-9-15 09:03
标题: RASPA批量计算输入文件中的Unitcells值怎么确定
本帖最后由 thor 于 2023-9-15 09:04 编辑

RASPA计算的时候需要设置盒子大于2倍的cutoff,正交晶系比较好换算,但对于三斜晶系不知道怎么换算。之前有看到别人写计算各个边长对另外两个面的投影,然后取比大的,以此来计算Unitcells值。具体代码如下:
(, 下载次数 Times of downloads: 49)
这对于大部分的三斜晶系确实有用,但是对于某些晶胞参数这样依然出现警告如下,也就说明计算的Unitcells值不够大。我提供两个这个代码处理不了的cif文件供大佬测试
(, 下载次数 Times of downloads: 47)
求问,这种情况到底如何换算才能处理
PS:单个晶胞可以直接扩大,我想做的是高通量,因此需要批量转换

作者
Author:
slxc920113    时间: 2023-9-15 09:22
用atomsk批量对cif最正交化变换。
作者
Author:
thor    时间: 2023-9-15 11:36
slxc920113 发表于 2023-9-15 09:22
用atomsk批量对cif最正交化变换。

不是所有晶胞都可以正交变换的
作者
Author:
qlx    时间: 2023-9-30 16:09
盒子需要大于两倍的cutoff,指的是盒子三个方向的两平行表面间的距离都需要大于两倍的cutoff。原代码计算的一条边向另外一条边的投影,并不能准确地反映非正交晶胞中两平行表面间的距离。以你附件中的CORE2019MOF484.cif为例,按原代码中的算法,会认为前后两个平行面间的距离是OA或AD中较小的那个数值(这里是AD),但实际上,无论是OA还是AD都不是OBC这个平面的法线方向,前后两个表面的距离,既不是OA也不是AD。
(, 下载次数 Times of downloads: 49)


可以根据平行六面体的体积公式,由晶格常数算出体积,除以各个方向的底面积,得到高,即平行表面间的距离。平行六面体体积公式可参见维基百科。
(, 下载次数 Times of downloads: 50)


示例代码如下(python):
  1. import math

  2. def get_unit_cell_number(framework_path, r_cut):

  3.     # 从cif文件中读取晶格常数
  4.     flag = [
  5.         '_cell_length_a', '_cell_length_b', '_cell_length_c',
  6.         '_cell_angle_alpha', '_cell_angle_beta', '_cell_angle_gamma'
  7.     ]
  8.     flag_length = len(flag)
  9.     with open(framework_path, 'r') as f:
  10.         i = 1
  11.         flag_count = 0
  12.         while i <= 5e4:
  13.             flag_content = flag[flag_count]
  14.             line = f.readline()
  15.             if flag_content in line:
  16.                 if flag_content == '_cell_length_a':
  17.                     a = float(line.strip().split()[1])
  18.                 elif flag_content == '_cell_length_b':
  19.                     b = float(line.strip().split()[1])
  20.                 elif flag_content == '_cell_length_c':
  21.                     c = float(line.strip().split()[1])
  22.                 elif flag_content == '_cell_angle_alpha':
  23.                     alpha = float(line.strip().split()[1]) * math.pi / 180 # 计算时用弧度单位   
  24.                 elif flag_content == '_cell_angle_beta':
  25.                     beta = float(line.strip().split()[1]) * math.pi / 180   # 计算时用弧度单位
  26.                 elif flag_content == '_cell_angle_gamma':
  27.                     gamma = float(line.strip().split()[1]) * math.pi / 180 # 计算时用弧度单位
  28.                 else:
  29.                     print(f'No specific operation for flag_content: {flag_content}!')
  30.                
  31.                 flag_count += 1
  32.                 if flag_count == flag_length:
  33.                     break
  34.             i += 1

  35.     # 计算晶胞体积         
  36.     V =  a * b * c * (1 + 2 * math.cos(alpha) * math.cos(beta) * math.cos(gamma) - (math.cos(alpha))**2 - (math.cos(beta))**2 - (math.cos(gamma))**2) ** 0.5
  37.    
  38.     # 计算晶胞各个面的表面积
  39.     base_area_x = b * c * math.sin(alpha)
  40.     base_area_y = a * c * math.sin(beta)
  41.     base_area_z = a * b * math.sin(gamma)

  42.     # 计算各个方向的最小距离,即平行六面体各个方向的高,等于体积除以底面积
  43.     perpendicular_length_x = V / base_area_x
  44.     perpendicular_length_y = V / base_area_y
  45.     perpendicular_length_z = V / base_area_z

  46.     # 根据截断半径r_cut计算所需各方向的unit_cell数目
  47.     unit_cell_x = math.ceil(2 * r_cut / perpendicular_length_x)
  48.     unit_cell_y = math.ceil(2 * r_cut / perpendicular_length_y)
  49.     unit_cell_z = math.ceil(2 * r_cut / perpendicular_length_z)

  50.     return ' '.join([str(unit_cell_x), str(unit_cell_y), str(unit_cell_z)])
复制代码


作者
Author:
thor    时间: 2023-10-6 19:27
qlx 发表于 2023-9-30 16:09
盒子需要大于两倍的cutoff,指的是盒子三个方向的两平行表面间的距离都需要大于两倍的cutoff。原代码计算的 ...

好的,非常感谢,确实可以解决问题。之前没有想到用体积进行换算




欢迎光临 计算化学公社 (http://bbs.keinsci.com/) Powered by Discuz! X3.3