【问题标题】:Kinetic Theory Model动力学理论模型
【发布时间】:2016-03-16 14:32:33
【问题描述】:

编辑:我现在已经解决了我询问的问题。球体将盒子留在角落里,if 语句(在下面显示的 while 循环中)被混淆了。在反转与墙壁接触时速度的各个分量的代码中,使用了一些 elif 语句。当使用 elif 时(据我所知),如果球体一次超过一个以上的位置限制,程序只会反转其中一个的速度分量。这在用简单的 if 替换 elif 时得到纠正。我不确定我是否完全理解这背后的原因,所以希望比我更聪明的人会评论这些信息,但现在,如果有人遇到同样的问题,我希望我有限的输入有所帮助!

先了解一下上下文:

我正在尝试在 VPython 中建立气体动力学理论模型,作为我(物理)学位的复习练习。这涉及到我构建一个空心盒子并将一堆球体放入其中,随机放置在整个盒子中。然后我需要为每个球体分配自己的随机速度,然后使用循环参考其速度矢量和时间步长调整每个球体的位置。

球体还应该与每面墙和所有其他球体发生弹性碰撞。

当球体在 x 方向遇到墙壁时,它的 x 速度分量会反转,并且在 y 和 z 方向上也是如此。 当一个球体遇到另一个球体时,它们会交换速度。

目前,我的代码可以创建正确数量的球体并随机分布它们,并为每个球体提供自己的随机速度。除了碰撞之外,球体也会按应有的方式移动。球体应该全部留在盒子内,因为它们应该从所有墙壁上反弹。它们似乎相互反弹,但偶尔会有一两个球体直接穿过盒子。

我对编程非常陌生,我不太了解这里发生了什么或为什么会发生,但如果有人能帮助我,我将不胜感激。

以下是我到目前为止的代码(我试图评论我在每个步骤中所做的事情):

##########################################################
# This code is meant to create an empty box and then create
# a certain number of spheres (num_spheres) that will sit inside
# the box. Each sphere will then be assigned a random velocity vector.
# A loop will then adjust the position of each sphere to make them
# move. The spheres will undergo elastic collisions with the box walls
# and also with the other spheres in the box.

##########################################################

from visual import *
import random as random
import numpy as np

num_spheres = 15 

fps = 24 #fps of while loop (later)

dt = 1.0/fps #time step

l = 40 #length of box

w = 2 #width of box

radius = 0.5 #radius of spheres

##########################################################
# Creating an empty box with sides length/height l, width w

wallR = box(pos = (l/2.0,0,0), size=(w,l,l), color=color.white, opacity=0.25)
wallL = box(pos = (-l/2.0,0,0), size=(w,l,l), color=color.white, opacity=0.25)
wallU = box(pos = (0,l/2.0,0), size=(l,w,l), color=color.white, opacity=0.25)
wallD = box(pos = (0,-l/2.0,0), size=(l,w,l), color=color.white, opacity=0.25)
wallF = box(pos = (0,0,l/2.0), size=(l,l,w), color=color.white, opacity=0.25)
wallB = box(pos = (0,0,-l/2.0), size=(l,l,w), color=color.white, opacity=0.25)

#defining a function that creates a list of 'num_spheres' randomly positioned spheres
def create_spheres(num):
    global l, radius
    particles = []  # Create an empty list
    for i in range(0,num): # Loop i from 0 to num-1
        v = np.random.rand(3)
        particles.append(sphere(pos= (3.0/4.0*l) * (v - 0.5), #pos such that spheres are inside box
                            radius = radius, color=color.red, index=i))
        # each sphere is given an index for ease of referral later
    return particles

#defining a global variable = the array of velocities for the spheres
velarray = []

#defining a function that gives each sphere a random velocity
def velocity_spheres(sphere_list):
     global velarray
     for sphere in spheres:
        #making the sign of each velocity component random
        rand = random.randint(0,1) 
        if rand == 1:
            sign = 1
        else:
            sign = -1

        mu = 10 #defining an average for normal distribution
        sigma = 0.1 #defining standard deviation of normal distribution

        # 3 random numbers form the velocity vector
        vel = vector(sign*random.normalvariate(mu, sigma),sign*random.normalvariate(mu, sigma),
                 sign*random.normalvariate(mu, sigma))

        velarray.append(vel)


spheres = create_spheres(num_spheres) #creating some spheres
velocity_spheres(spheres) # invoking the velocity function

while True:
    rate(fps)

    for sphere in spheres:
        sphere.pos += velarray[sphere.index]*dt
        #incrementing sphere position by reference to its own velocity vector

        if abs(sphere.pos.x) > (l/2.0)-w-radius:
            (velarray[sphere.index])[0] = -(velarray[sphere.index])[0]
            #reversing x-velocity on contact with a side wall

        elif abs(sphere.pos.y) > (l/2.0)-w-radius:
            (velarray[sphere.index])[1] = -(velarray[sphere.index])[1]
            #reversing y-velocity on contact with a side wall

        elif abs(sphere.pos.z) > (l/2.0)-w-radius:
            (velarray[sphere.index])[2] = -(velarray[sphere.index])[2]
            #reversing z-velocity on contact with a side wall

        for sphere2 in spheres: #checking other spheres
            if sphere2 != sphere:
                #making sure we aren't checking the sphere against itself

                if abs(sphere2.pos-sphere.pos) < (sphere.radius+sphere2.radius):
                    #if the other spheres are touching the sphere we are looking at

                    v1 = velarray[sphere.index]
                    #noting the velocity of the first sphere before the collision

                    velarray[sphere.index] = velarray[sphere2.index]
                    #giving the first sphere the velocity of the second before the collision
                    velarray[sphere2.index] = v1
                    #giving the second sphere the velocity of the first before the collision

再次感谢您的帮助!

【问题讨论】:

  • 不要简单地反转粒子的速度分量,也要把它们放在盒子里——例如简单地夹住盒子里粒子的位置(减少两倍的球体半径) .如果你想要完全弹性反弹,你需要计算每个粒子和每一步墙的所有碰撞点,进行第一次碰撞,将粒子移动到那里,固定它的速度,重新计算剩余步骤的碰撞,等等...
  • 我实际上意识到出了什么问题,现在已经纠正了,不过还是谢谢
  • 当然,我很抱歉没有遵守协议!

标签: physics bounce vpython


【解决方案1】:

原始问题中给出的代码中 while 循环中的 elif 语句是/是问题的原因。条件语句 elif 仅适用于不满足原始 if 条件的情况。球体与长方体的角相交的情况至少满足两个速度分量反转的条件。这意味着,虽然人们会期望(至少)两个速度分量被反转,但只有一个是反转的。也就是说,if 语句指定的方向是相反的,而 elif 语句中提到的组件则不是,因为第一个条件已经满足,因此 elif 语句被忽略。

如果将每个 elif 更改为单独的 if 语句,则代码将按预期工作。

【讨论】:

    猜你喜欢
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多