Модель кинетической теории

Изменить: я теперь исправил проблему, о которой я спросил. Сферы оставляли коробку в углах, где операторы if (в цикле while, показанном ниже) запутались. В кусочках кода, которые обращают отдельные компоненты скорости при контакте со стенами, использовались некоторые операторы elif. Когда используется elif (насколько я могу судить), если сфера превышает более чем один предел позиции за раз, программа только переворачивает компонент скорости для одного из них. Это исправляется при замене elif на просто if. Я не уверен, что я полностью понимаю причину этого, так что, надеюсь, кто-то умнее, чем я, прокомментирует такую ​​информацию, но сейчас, если у кого-то есть такая же проблема, я надеюсь, что мой ограниченный вклад поможет!

Сначала немного контекста:

Я пытаюсь построить модель кинетической теории газов в VPython, как упражнение по ревизии для моей степени (физика). Это предполагает, что я построил пустую коробку и поместил в нее кучу сфер, случайно расположенных по всей коробке. Затем мне нужно назначить каждой из сфер свою собственную случайную скорость, а затем использовать цикл, чтобы отрегулировать положение каждой сферы относительно вектора скорости и временного шага.

Сферы также должны подвергаться упругим столкновениям с каждой стенкой и всеми остальными сферами.

Когда сфера встречает стену в направлении х, ее составляющая скорости х переворачивается и аналогично в направлениях у и 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

Еще раз спасибо за любую помощь!

1 ответ

Утверждения elif внутри цикла while в коде, приведенном в исходном вопросе, являются / были причиной проблемы. Условное утверждение elif применимо только в том случае, если исходное условие if не выполнено. Обстоятельство, при котором сфера встречается с углом коробки, удовлетворяет, по крайней мере, двум условиям для изменения компонентов скорости. Это означает, что, хотя можно ожидать, что (как минимум) две компоненты скорости будут обращены вспять, только одна из них есть. То есть направление, указанное в операторе if, является обратным, в то время как компоненты, упомянутые в операциях elif, не являются таковыми, так как первое условие выполнено, и, следовательно, операторы elif игнорируются.

Если каждый elif изменен на отдельный оператор if, код работает как задумано.

Другие вопросы по тегам