对于分子动力学的一门课,我要模拟一个有周期边界的盒子里的100个粒子。我必须考虑粒子与粒子的碰撞,因为墙壁是“透明的”,这些相互作用可以跨越边界发生。由于模拟应该包含50000个步骤,而且我希望将来会有越来越多的额外任务,所以我希望我的代码尽可能高效(尽管运行时间很长,但我必须使用python)。
该系统包括
class particlesInPeriodicBox:
# define the particle properties
def __init__(self,
initialState = [[0,0,0,0]], # state with form [x, y, vx, vy] for each particle
boundaries = [0, 10, 0, 5], # box boundaries with form [xmin, xmax, ymin, ymax] in nm
radius = 0.2, # particle radius in nm
mass = 2): # mass in g/mol. Here a parameter instead of a global variable
self.initialState = np.asarray(initialState, dtype=float)
self.state = self.initialState.copy()
self.radius = radius
self.time = 0 # keep count of time, if time, i want to implement a 'clock'
self.mass = mass # mass
self.boundaries = boundaries
def collision(self):
"""
now, one has to check for collisions. I do this by distance check and will solve this problems below.
To minimize the simulation time I then will only consider the particles that colided.
"""
dist = squareform(pdist(self.state[:, :2])) # direct distance
colPart1, colPart2 = np.where(dist < 2 * self.radius) # define collision partners 1 and 2 as those where the distance between the centeres are smaller than two times the radius
# resolve self-self collissions
unique = (colPart1 < colPart2)
colPart1 = colPart1[unique]
colPart2 = colPart2[unique]
"""
The following loop resolves the collisions. I zip the lists of collisionpartners to one aray,
where one entry contains both colisionpartners.
"""
for cp1, cp2 in zip(colPart1, colPart2): # cp1/cp2 are the two particles colliding in one collision.
# masses could be different in future...
m1 = self.mass[cp1]
m2 = self.mass[cp2]
# take the position (x,y) tuples for the two particles
r1 = self.state[cp1, :2]
r2 = self.state[cp2, :2]
# same with velocities
v1 = self.state[cp1, 2:]
v2 = self.state[cp2, 2:]
# get relative parameters
r = r1-r2
v = r2-r1
# center of mass velocity:
vcm = (m1 * v1 + m2 * v2) / (m1 + m2)
"""
This is the part with the elastic collision
"""
dotrr = np.dot(r, r) # the dot product of the relative position with itself
dotvr = np.dot(v, r) # the dot product of the relative velocity with the relative position
v = 2 * r * dotvr / dotrr - v # new relative velocity
"""
In this center of mass frame, the velocities 'reflect' on the center of mass in oposite directions
"""
self.state[cp1, 2:] = vcm + v * m2/(m1 + m2) # new velocity of particle 1 still considering possible different masses
self.state[cp2, 2:] = vcm - v * m1/(m1 + m2) # new velocity of particle 2
按照我的理解,这种处理对整个数组的操作的技术比每次手动遍历它更有效。移动的粒子‘槽’的墙壁是容易的,我只是减去或增加的盒子的尺寸,分别。但是:
目前,该算法只看到方框内部的冲突,而不是跨越边界。这个问题我想了一会,想出了以下几个想法:
对于第一个问题,也许可以使用一些技术,如在周期性边界条件下计算接触数/配位数,但我不确定这是否是最有效的方法。
谢谢你!
模数很可能是一个快速的运算,就像你要得到的一样。在任何自重的运行时系统中,这将直接连接到片内浮除操作,这可能比一组繁琐的“if-subtract”对更快。
我觉得你的9细胞解决方案有点过火了。在2x2矩阵中使用4个单元格,检查两个区域:原始单元格和以“四角”点(2x2中间)为中心的相同尺寸。对于任何一对点,适当的距离是这两个中较小的一个。注意,这个方法也给出了一个框架,在这个框架中你可以很容易地计算动量变化。
第三种可能的方法是将尺寸增加一倍(如上面的2x2),但给每个粒子四组坐标,每个方框中一组。在计算距离时,修改你的算法以考虑所有四个因素。如果您有良好的矢量化包和并行性,这可能是首选的解决方案。
本节暂未进行完全的重写,错误可能会很多。如果可能的话,请对照原文进行阅读。如果有报告本节的错误,将会延迟至重写之后进行处理。 一个微粒,从OpenGL的角度看就是一个总是面向摄像机方向且(通常)包含一个大部分区域是透明的纹理的小四边形.一个微粒本身主要就是一个精灵(sprite),前面我们已经早就使用过了,但是当你把成千上万个这些微粒放在一起的时候,就可以创造出令人疯狂的效果. 当处理这些微粒的时
粒子系统是游戏引擎特效表现的基础,它可以用于模拟的火、烟、水、云、雪、落叶等自然现象,也可用于模拟发光轨迹、速度线等抽象视觉效果。 基本结构 粒子系统的基本单元是粒子,一个粒子一般具有位置、大小、颜色、速度、加速度、生命周期等属性。在每一帧中,粒子系统一般会执行如下步骤: 产生新的粒子,并初始化 删除超过生命周期的粒子 更新粒子的动态属性 渲染所有有效的粒子 一般粒子系统会有如下几个部分组成: 发
粒子系统入门 本节介绍如何实现常见类型的粒子系统。你可以自由使用文档中所有代码,不受 Unity 的任何限制。
使用粒子系统 Unity 使用一个组件实现粒子系统。在场景中放置粒子系统的常用方式是,添加一个预制的游戏对象(菜单:GameObject > Create General > Particle Syste),或者为一个现有的游戏对象添加粒子系统组件(菜单:Component > Effects > Particle System)。因为该组件相当复杂,所以检视视图被分割成数个可折叠的部分或 模块,
什么是粒子系统? 粒子 是小而简单的图像或网格,由粒子系统负责显示和剧烈移动。每个粒子代表了流体或无形实体的一小部分,所有粒子一起创建实体的完整外观。以烟雾为例,每个粒子是一张微小的烟雾纹理,像小块浮云一样。当许多这种微小浮云被一起布置在场景的某个区域时,整体效果是巨大的、体积填充的云朵。 系统动力学 每个粒子的生命周期是预定好的,通常是几秒钟,在此期间它可以经历各种变化。当粒子系统生成或射出一个
我试图在MyAdapter文件中使用以下函数:- 这会给我一个构建错误,如下所示:- 错误:(1824,41)错误:没有为ParticleSystem(Context,int,int,int)构造函数ParticleSystem(ViewGroup,int,Drawable,long)不适用(参数不匹配;上下文不能转换为ViewGroup)构造函数ParticleSystem(活动,int,int