OVITO与matplotlib不兼容的问题
在导入OVITO之前,要先设置环境变量,matplotlib导入顺序没有要求:
import osos.environ['OVITO_GUI_MODE'] = '1'from ovito.io import import_fileimport matplotlib.pyplot as pltplt.plot([1,2])plt.show()
导入并分析dump文件
from ovito.io import import_file
导入单个文件
pipeline = import_file("simulation.dump")
导入LAMMPS中用通配符生成的一系列文件
pipeline = import_file('path/*.dump')
导入列表中的所有文件
file_list = ["dir_a/simulation.dump","dir_b/simulation.dump","dir_c/simulation.dump"]pipeline = import_file(file_list)
查看当前导入的有多少帧
print(pipeline.source.num_frames)
计算某一帧的数据
for frame in range(pipeline.source.num_frames): data = pipeline.compute(frame) ...
从原则上是,compute 接受的 frame 应该是0至 num_frames-1 之间的数,这样刚好是 num_frames 帧。实际操作中,我发现这个 frame 参数可以是0至任意大的数,如果这个 frame 超过了 num_frames,就会以 num_frames-1 的值作为结果。
dump文件中的各变量值都储存在 data.particles 里面,怎么访问呢,这个 data.particles 是个类似于字典的对象,可以用 keys 方法查看有哪些键:
print(list(data.particles.keys()))
['Particle Identifier', 'Particle Type', 'Position', 'Velocity', 'v_r_stretch', 'c_rho_peratom', 'c_ave_eps', 'v_fp', 'v_rdist', 'Velocity Magnitude']
我dump文件本来储存的是以下变量:
id type xs ys zs vx vy vz v_r_stretch c_rho_peratom c_ave_eps v_FP v_rDist
可以发现变量名自动发生了一些变化,比如id变成了Particle Identifier,xs、ys、zs变成了Position,vx、vy、vz变成了Velocity,自定义的变量名中的大写字母变成了小写,比如v_FP变成了v_fp等等。这个OVITO文档里面列举了不少,可以自己去看LAMMPS dump file reader — OVITO User Manual 3.10.6 documentation

然后我们就可以像字典一样访问这些键的值:
ids = data.particles['Particle Identifier']
这样获取到的 ids 对象类型是 ovito.data.Property,有点像 numpy.ndarray,可以取索引的值,有shape、size,可以传给matplotlib画图,但是似乎没有numpy.ndarray的那些方法(max、min 什么的)。我们可以用 np.asarray 把它转换为 numpy.ndarray,还有一种更方便的操作,就是直接用他自己的array属性:
print(ids.array.__class__)print(ids.array.mean())
numpy.ndarray
np.float64(4676.5)
另外,如果对 ovito.data.Property 取索引对应的值的话,也是直接返回一个 numpy.ndarray 的,不需要再用array属性转换了:
print(ids[:250].__class__)print(ids[:250].mean())
numpy.ndarray
125.5
注:矢量的分量(如data.particles['Force.Y'])是numpy.ndarray,但矢量本身(如data.particles['Force'])仍是ovito.data.Property。
我们把ids试着用matplotlib画出来:
plt.plot(ids)plt.show()

可以发现,id是乱序的,这就是默认的导入方式造成的(除非LAMMPS中就指定了 dump_modify sort id)。为了让OVITO按id顺序读取各原子,我们需要在 import_file 中指定 sort_particles=True,这样就可以方便后面分析了。
渲染为图片或视频
切记:要在导入ovito之前,设置好环境变量。
import osos.environ['OVITO_GUI_MODE'] = '1'from ovito.io import import_filefrom ovito.modifiers import SelectTypeModifier, ColorCodingModifierfrom ovito.vis import Viewportpipeline = import_file(...)pipeline.modifiers.extend([...])for frame in range(pipeline.source.num_frames): data = pipeline.compute(frame) data.cell.vis.enabled = False# 去掉simulation cell data.particles.vis.radius = 2e-5# 调整颗粒半径pipeline.add_to_scene()vp = Viewport()vp.type = Viewport.Type.Top # Top视图vp.zoom_all() # 缩放到合适的尺寸vp.render_image(filename='test.png')vp.render_anim(size=(600, 600), filename=f'{output_path}\\animation.mp4', fps=20)
各种Modifiers
ovito.modifiers — OVITO Python Reference 3.11.2 documentation
pipeline.modifiers.extend([ SelectTypeModifier(types={1}), DeleteSelectedModifier(operate_on={'particles'}),])
表达式选择
cond = ['ParticleType==2','abs(Position.Y^2+(Position.Z-0.003)^2-0.002^2)<1e-9','Position.X>0.002','Position.X<0.007']cond = '&&'.join(cond)pipeline.modifiers.extend( [mod.ExpressionSelectionModifier(expression=cond), mod.InvertSelectionModifier(), mod.DeleteSelectedModifier(operate_on={'particles'})])
渲染LAMMPS区域
注意:commands中的旋转角度应当是弧度。
pipeline.modifiers.extend([ RenderLAMMPSRegionsModifier( commands='region anal_del block 0.0034641 0.007 -0.002 0.002 -0.002 0 rotate 'f'1.57 0.0034641 0 -0.002 0 1 0', color_by_region=True )])
各种Overlay
vp.overlays.extend([ ColorLegendOverlay( modifier=pipeline.modifiers[1], # ColorCoding title='v_y (m/s)', alignment=QtCore.Qt.AlignmentFlag.AlignTop | QtCore.Qt.AlignmentFlag.AlignHCenter, offset_x=0, offset_y=-0.1316, font_size=0.098, font='Arial', legend_size=0.36, label_size=0.89, aspect_ratio=4.2 ), TextLabelOverlay( text=f't=[Time] second', font='Arial', font_size=0.053, alignment=QtCore.Qt.AlignmentFlag.AlignTop | QtCore.Qt.AlignmentFlag.AlignHCenter, offset_x=0, offset_y=-0.1992, text_color=(0, 0, 0) )])
alignment必须规定横向位置和纵向位置,用 | 连接。offset是相对于 alignment 规定位置的偏移量。
邻居搜索
ovito.data — OVITO Python Reference 3.11.2 documentation
h = 2 * dLdata = pipeline.compute(frame)finder = CutoffNeighborFinder(h, data)
找空间任意一点的cutoff范围内的颗粒用 find_at(coords)。但是只能逐点查找,也就是说 coords 只能是单个点的坐标,不能是一堆点的坐标(与scipy的cKDTree不同)。
numerator = np.zeros((n_sample, 3))denominator = np.zeros((n_sample, 1))for i in trange(n_sample): neighs = finder.find_at(xyz[i, :])for neigh in neighs: j = neigh.index w = kernel(neigh.distance, h) numerator[i] += v[j] * w * mass[j] / rho[j] denominator[i] += w * mass[j] / rho[j]
找某个颗粒的邻居颗粒用 find(index) 方法找单个颗粒的邻居,或用 find_all(indices=None, sort_by=None) 一次性找所有颗粒的邻居。