Beispiel #1
0
    def setQuaternion(self, Quaternion):
        """Set the orientation of the body in world coordinates (the display object is oriented to match)."""
        odelib.BaseBody.setQuaternion(self, Quaternion)

        # now set the orientation of the display frame
        # Rotating a point is q * (0,v) * q-1
        # q-1 is w, -x, -y, -z assuming that q is a unit quaternion
        w1, x1, y1, z1 = Quaternion
        v1 = visual.vector(x1, y1, z1)
        w3 = w1
        v3 = -v1

        # First do the axis vector
        w2 = 0.0
        v2 = visual.vector((1.0, 0.0, 0.0))

        # This code is equivalent to a quaternion multiply: qR = q1 * q2 * q3
        w12 = (w1 * w2) - visual.dot(v1, v2)
        v12 = (w1 * v2) + (w2 * v1) + visual.cross(v1, v2)
        wR = (w12 * w3) - visual.dot(v12, v3)
        vR = (w12 * v3) + (w3 * v12) + visual.cross(v12, v3)

        self._myFrame.axis = vR

        # Do it again for the up vector
        w2 = 0.0
        v2 = visual.vector((0.0, 1.0, 0.0))

        # This code is equivalent to a quaternion multiply: qR = q1 * q2 * q3
        w12 = (w1 * w2) - visual.dot(v1, v2)
        v12 = (w1 * v2) + (w2 * v1) + visual.cross(v1, v2)
        wR = (w12 * w3) - visual.dot(v12, v3)
        vR = (w12 * v3) + (w3 * v12) + visual.cross(v12, v3)

        self._myFrame.up = vR
Beispiel #2
0
    def setQuaternion(self, Quaternion):
        """Set the orientation of the body in world coordinates (the display object is oriented to match)."""
        odelib.BaseBody.setQuaternion(self, Quaternion)

        # now set the orientation of the display frame
        # Rotating a point is q * (0,v) * q-1
        # q-1 is w, -x, -y, -z assuming that q is a unit quaternion
        w1, x1, y1, z1 = Quaternion
        v1 = visual.vector(x1, y1, z1)
        w3 = w1
        v3 = -v1

        # First do the axis vector
        w2 = 0.0
        v2 = visual.vector((1.0, 0.0, 0.0))

        # This code is equivalent to a quaternion multiply: qR = q1 * q2 * q3
        w12 = (w1 * w2) - visual.dot(v1, v2)
        v12 = (w1 * v2) + (w2 * v1) + visual.cross(v1, v2)
        wR = (w12 * w3) - visual.dot(v12, v3)
        vR = (w12 * v3) + (w3 * v12) + visual.cross(v12, v3)

        self._myFrame.axis = vR

        # Do it again for the up vector
        w2 = 0.0
        v2 = visual.vector((0.0, 1.0, 0.0))

        # This code is equivalent to a quaternion multiply: qR = q1 * q2 * q3
        w12 = (w1 * w2) - visual.dot(v1, v2)
        v12 = (w1 * v2) + (w2 * v1) + visual.cross(v1, v2)
        wR = (w12 * w3) - visual.dot(v12, v3)
        vR = (w12 * v3) + (w3 * v12) + visual.cross(v12, v3)

        self._myFrame.up = vR
Beispiel #3
0
 def GetElementWorldLocation(self, ElementKey):
     """Returns the location of the specified element in world coordinates."""
     assert ElementKey in self._elementDict
     self._elementDict.get(ElementKey).SetVisible(isVisible)
     localPos = self.GetElement(ElementKey).pos
     xAxis = visual.norm(self._myFrame.axis)
     zAxis = visual.norm(visual.cross(self._myFrame.axis, self._myFrame.up))
     yAxis = visual.norm(visual.cross(z_axis, x_axis))
     worldPos = self._myFrame.pos + (localPos.x * xAxis) + (localPos.y * yAxis) + (localPos.z * zAxis)
     return worldPos
Beispiel #4
0
 def GetElementWorldLocation(self, ElementKey):
     """Returns the location of the specified element in world coordinates."""
     assert ElementKey in self._elementDict
     self._elementDict.get(ElementKey).SetVisible(isVisible)
     localPos = self.GetElement(ElementKey).pos
     xAxis = visual.norm(self._myFrame.axis)
     zAxis = visual.norm(visual.cross(self._myFrame.axis, self._myFrame.up))
     yAxis = visual.norm(visual.cross(z_axis, x_axis))
     worldPos = self._myFrame.pos + (localPos.x * xAxis) + (
         localPos.y * yAxis) + (localPos.z * zAxis)
     return worldPos
Beispiel #5
0
    def build(self, Verticies, Faces, Colors=None, Normals=None, IsSoft=False):
        """Build a displayable tri-mesh object.  This is an overload of ode.TriMeshData.build()."""
        # Fill out our TriMeshData object properties by calling the parent
        ode.TriMeshData.build(self, Verticies, Faces)

        self._verticies = []
        self._colors = []
        self._normals = []

        # Expand the mesh to make it suitable for use with Visual
        for face in Faces:
            for index, vertex in enumerate(face):
                self._verticies.append(Verticies[vertex])
                if Colors is not None:
                    self._colors.append(Colors[vertex])
                else:
                    # Assign a default
                    self._colors.append(visual.color.white)
                if Normals is not None:
                    self._normals.append(Normals[vertex])
                else:
                    # Compute the normals using cross products
                    normal = visual.norm(visual.cross(Verticies[face[index]], Verticies[face[(index + 1) % 3]]))
                    self._normals.append(normal)

        if IsSoft:
            # Need to go back and average normals -- implement later
            pass
Beispiel #6
0
    def build(self, Verticies, Faces, Colors=None, Normals=None, IsSoft=False):
        """Build a displayable tri-mesh object.  This is an overload of ode.TriMeshData.build()."""
        # Fill out our TriMeshData object properties by calling the parent
        ode.TriMeshData.build(self, Verticies, Faces)

        self._verticies = []
        self._colors = []
        self._normals = []

        # Expand the mesh to make it suitable for use with Visual
        for face in Faces:
            for index, vertex in enumerate(face):
                self._verticies.append(Verticies[vertex])
                if Colors is not None:
                    self._colors.append(Colors[vertex])
                else:
                    # Assign a default
                    self._colors.append(visual.color.white)
                if Normals is not None:
                    self._normals.append(Normals[vertex])
                else:
                    # Compute the normals using cross products
                    normal = visual.norm(
                        visual.cross(Verticies[face[index]],
                                     Verticies[face[(index + 1) % 3]]))
                    self._normals.append(normal)

        if IsSoft:
            # Need to go back and average normals -- implement later
            pass
def golfball_step(t,x,y,z,vx,vy,vz,m,g,B2,S0,w,dt,w_vector,v_vector):
    t = t+dt
    x = x + vx*dt
    y = y + vy*dt
    z = z + vz*dt
    FM = (S0*visual.cross(w_vector,v_vector))/m
    #vz = vz + (Fmz/m)*dt
    vz = vz + FM.z*dt#((S0*w*vx)*dt)
    v = math.sqrt((vx**2)+(vy**2)+(vz**2))
    vx = vx - (((B2*v*vx)/m)*dt) + FM.x*dt#((S0*w*vy)*dt)
    vy = vy - g*dt - (((B2*v*vy)/m)*dt) + FM.y*dt#((S0*w*vz)*dt)
    return t,x,y,z,vx,vy,vz
def go(animate=True):  # default: True
    r, v = np.array([0.4667, 0.0]), np.array([0.0, 8.198])  # init r, v
    t, h, ta, angle = 0.0, 0.002, [], []
    w = 1.0 / vp.mag(r)  # $W_0=\Omega(r)$

    if (animate): planet, info, RLvec = set_scene(r)
    while t < 100:  # run for 100 years
        L = vp.cross(r, v)  # $\vec{L}/m=\vec{r}\times \vec{v}$
        A = vp.cross(v, L) - GM * r / vp.mag(r)  # scaled RL vec,
        ta.append(t)
        angle.append(np.arctan(A.y / A.x) * 180 * 3600 / np.pi)  # arcseconds
        if (animate):
            vp.rate(100)
            planet.pos = r  # move planet
            RLvec.axis, RLvec.length = A, .25  # update RL vec
            info.text = 'Angle": %8.2f' % (angle[-1])  # angle info
        r, v, t, w = ode.leapfrog_tt(mercury, r, v, t, w, h)

    plt.figure()  # make plot
    plt.plot(ta, angle)
    plt.xlabel('Time (year)'), plt.ylabel('Precession (arcsec)')
    plt.show()
Beispiel #9
0
def go(animate = True):                     # default: True
    r, v = np.array([0.4667, 0.0]), np.array([0.0, 8.198]) # init r, v
    t, h, ta, angle = 0.0, 0.002, [], []
    w = 1.0/vp.mag(r)                       # $W_0=\Omega(r)$
    
    if (animate): planet, info, RLvec = set_scene(r)
    while t<100:                            # run for 100 years
        L = vp.cross(r, v)                  # $\vec{L}/m=\vec{r}\times \vec{v}$
        A = vp.cross(v, L) - GM*r/vp.mag(r) # scaled RL vec, 
        ta.append(t)
        angle.append(np.arctan(A.y/A.x)*180*3600/np.pi) # arcseconds
        if (animate):    
            vp.rate(100)   
            planet.pos = r                              # move planet
            RLvec.axis, RLvec.length = A, .25           # update RL vec
            info.text='Angle": %8.2f' %(angle[-1])      # angle info 
        r, v, t, w = ode.leapfrog_tt(mercury, r, v, t, w, h)
        
    plt.figure()        # make plot
    plt.plot(ta, angle)
    plt.xlabel('Time (year)'), plt.ylabel('Precession (arcsec)')
    plt.show()
Beispiel #10
0
def vs_loop():

    #pan_inc = 0.25
    #zoom_inc = array((0.25,0.25,0.25))
    pan_inc = 0.25
    zoom_inc = array((0.05, 0.05, 0.05))

    # for scene rotation with invariant light direction
    light_frame = vs.frame()
    for obj in vs.scene.lights:
        if isinstance(obj, vs.distant_light):
            obj.frame = light_frame  # put distant lights in a frame
    prev_scene_forward = vs.vector(
        vs.scene.forward)  # keep a copy of the old forward

    while True:

        if vs.scene.kb.keys:
            key = vs.scene.kb.getkey()

            if key == 'up':
                vs.scene.center = array(vs.scene.center) + array(
                    (0, pan_inc, 0))
            elif key == 'down':
                vs.scene.center = array(vs.scene.center) + array(
                    (0, -pan_inc, 0))
            elif key == 'left':
                vs.scene.center = array(vs.scene.center) + array(
                    (-pan_inc, 0, 0))
            elif key == 'right':
                vs.scene.center = array(vs.scene.center) + array(
                    (pan_inc, 0, 0))

            elif key == 'shift+up':
                vs.scene.range -= zoom_inc
            elif key == 'shift+down':
                vs.scene.range += zoom_inc

        if vs.scene.forward != prev_scene_forward:
            new = vs.scene.forward
            axis = vs.cross(prev_scene_forward, new)
            angle = new.diff_angle(prev_scene_forward)
            light_frame.rotate(axis=axis, angle=angle)
            prev_scene_forward = vs.vector(new)
def ball_step(x,y,z,vx,vy,vz,g,ball,S0,w_vector,dt):
    v_vector = visual.vector(vx,vy,vz) #Defines velocity vector based on components

    FM = S0 * visual.cross(w_vector,v_vector) / ball.mass #Finds acceleration from Magnus Force
    
    x = x + vx*dt
    y = y + vy*dt #Alters the position
    z = z + vz*dt

    vz = vz + FM.z*dt #Changes vz based on the Magnus acceleration in the Z direction
    
    v = v_vector.mag #defines v as the magnitude of the velocity vector for use below

    vx = vx - (((ball.drag*v*vx)/ball.mass)*dt) + FM.x*dt #updates x component of velocity
    
    vy = vy - 9.8*dt - (((ball.drag*v*vy)/ball.mass)*dt)# + FM.y*dt #updates y component of velocity
    '''This is where I believe my problem exists. I cannot figure out why the other two velocities are altered by the
    effect of the magnus force, but in this equation, y is not being altered at least noticeably.'''

    return x,y,z,vx,vy,vz
Beispiel #12
0
def vs_loop():

    #pan_inc = 0.25
    #zoom_inc = array((0.25,0.25,0.25))
    pan_inc = 0.25
    zoom_inc = array((0.05,0.05,0.05))

    # for scene rotation with invariant light direction
    light_frame = vs.frame()
    for obj in vs.scene.lights:
        if isinstance(obj, vs.distant_light):
            obj.frame = light_frame # put distant lights in a frame
    prev_scene_forward = vs.vector(vs.scene.forward) # keep a copy of the old forward

    while True:

        if vs.scene.kb.keys:
            key = vs.scene.kb.getkey()

            if key == 'up':
                vs.scene.center = array(vs.scene.center) + array((0,pan_inc,0))
            elif key == 'down':
                vs.scene.center = array(vs.scene.center) + array((0,-pan_inc,0))
            elif key == 'left':
                vs.scene.center = array(vs.scene.center) + array((-pan_inc,0,0))
            elif key == 'right':
                vs.scene.center = array(vs.scene.center) + array((pan_inc,0,0))

            elif key == 'shift+up':
                vs.scene.range -= zoom_inc
            elif key == 'shift+down':
                vs.scene.range += zoom_inc

        if vs.scene.forward != prev_scene_forward:
            new = vs.scene.forward
            axis = vs.cross(prev_scene_forward, new)
            angle = new.diff_angle(prev_scene_forward)
            light_frame.rotate(axis=axis, angle=angle)
            prev_scene_forward = vs.vector(new)
Beispiel #13
0
def drawThumbPattern(pattern, i, gc, l, m, length):
    faces = pattern.faces
    center = vector(m * (i + 1) + l * (i + 1 / 2.0), l / 2 + m, 0)
    for face in faces:
        edge1 = face.vertices[1].coords - face.vertices[0].coords
        edge2 = face.vertices[-1].coords - face.vertices[0].coords
        if cross(edge1, edge2).z > 0:  # the angle from edge1 to 2 is negative
            gc.SetBrush(wx.Brush('white'))
        else:
            gc.SetBrush(wx.Brush('yellow'))
        path = gc.CreatePath()
        for i in range(len(face.vertices)):
            vertex = face.vertices[i]
            coords = vector(vertex.coords.x, -vertex.coords.y)
            length = 100  # from center of the origami to a vertex
            vPosition = center + coords / length * l / 2
            if i == 0:
                path.MoveToPoint(vPosition.x, vPosition.y)
            else:
                path.AddLineToPoint(vPosition.x, vPosition.y)
        path.CloseSubpath()
        gc.DrawPath(path)
Beispiel #14
0
 def cross(self, other):
     temp = cross(self.v, other.v)
     return Vector((temp.x, temp.y, temp.z))
Beispiel #15
0
S_LENGTH_LABEL = vp.label(pos=S_LENGTH.pos, text="Fix Length", yoffset=-5,
                          opacity=0, box=0, line=0)

S_TEXT = vp.label(pos=(0, 12, 0), text="Yellow = Red x Green",
                  opacity=0, box=0, line=0)

FIXLENGTH = 0
FIXTHETA = 0

AVECTOR = vp.array([0, 0, -3.5])
BVECTOR = vp.vector(0, 3, 2)

A = vp.arrow(pos=(0, 0, 0), shaftwidth=R, color=vp.color.red)
B = vp.arrow(pos=(0, 0, 0), axis=BVECTOR, shaftwidth=R, color=vp.color.green)
A.axis = AVECTOR
CVECTOR = vp.cross(AVECTOR, BVECTOR)
C = vp.arrow(pos=(0, 0, 0), axis=CVECTOR, shaftwidth=R, color=vp.color.yellow)

vp.scene.autoscale = 0
vp.scene.forward = (-1, -.5, -1)

DRAG = 0

while True:
    vp.rate(100)
    if vp.scene.mouse.events:
        M = vp.scene.mouse.getevent()
        if M.drag:
            DRAG = True
            OBS = None
        elif M.drop:
Beispiel #16
0
def bdipole(r):  # calc magnetic fields at $\vec{r}$
    b, rel = vp.vector(0, 0, 0), r - rs
    for i in range(len(ds)):  # sum over segments
        b += vp.cross(ds[i], rel[i]) / vp.mag(
            rel[i])**3  # $\sum Id\vec{s}\times \vec{r}/r^3$
    return b
def baseball(Y, t):  # Y = [r, v] assumed
    v = Y[1]
    fm = alpha * vp.cross(omega, v)  # Magnus force
    a = (fm - b2 * vp.mag(v) * v) / mass - [0, g, 0]  # minus g-vec
    return np.array([v, a])  # np array
Beispiel #18
0
      up=ex*np.cos(j)*rr+ey*np.sin(j)*rr+ez*(0)+center
      up=up.rotate(angle=r1data[k][0],axis=r1data[k][1])
      up=up.rotate(angle=r2data[k][0],axis=r2data[k][1])
      L.append((up.x,up.y,up.z))
      down=ex*np.cos(j)*rru+ey*np.sin(j)*rru+ez*(h)+center
      down=down.rotate(angle=r1data[k][0],axis=r1data[k][1])
      down=down.rotate(angle=r2data[k][0],axis=r2data[k][1])
      L.append((down.x,down.y,down.z))
#    if up.x>0:
#      continue
    hexagon.pos = L
#ball=vs.sphere(pos=(0,0,0),radius=17.5)
#fig = plt.figure()
#ax = fig.add_subplot(111, projection='3d')
##ax.plot(xx,yy,zz,".")
#ax.scatter(x,y,z,color="g",s=100)
#ax.set_xlabel('x')
#ax.set_ylabel('y')
#ax.set_zlabel('z')
#plt.show()
#for i in range(len(x)):
#  print x[i],y[i],z[i]
while 1:
    vs.rate(50)
    if vs.scene.forward != old:
        new = vs.scene.forward
        axis = vs.cross(old,new)
        angle = new.diff_angle(old)
        lframe.rotate(axis=axis, angle=angle)
        old = vs.vector(new)
 def cross(self, other):
     temp = cross(self.v, other.v)
     return Vector((temp.x, temp.y, temp.z))
def angular_momentum(self, pos = vector()):
	return cross(self.pos - pos, self.momentum)
scene = vp.display(title='Electric dipole', background=(.2,.5,1), 
                   forward=(0,-1,-.5), up=(0,0,1))
zaxis = vp.curve(pos=[(0,0,-r),(0,0,r)])                    
qpos = vp.sphere(pos=(0,0,.02), radius=0.01, color=(1,0,0))
qneg = vp.sphere(pos=(0,0,-.02), radius=0.01, color=(0,0,1))
c1 = vp.ring(pos=(0,0,0), radius=r, axis=(0,0,1), thickness=0.002)
c2 = vp.ring(pos=(0,0,0), radius=r, axis=(0,1,0), thickness=0.002)

theta, phi = np.linspace(0, np.pi, m), np.linspace(0, 2*np.pi, n) # grid 
phi, theta = vp.meshgrid(phi, theta)
rs = r*np.sin(theta)
x, y, z = rs*np.cos(phi), rs*np.sin(phi), r*np.cos(theta)   # coord. 
for i in range(m):
    for j in range(n):
        rvec = vp.vector(x[i,j], y[i,j], z[i,j])
        B = scale*vp.cross(rvec, vp.vector(0,0,1))/(r*r)    # $\vec{r}\times \hat z/r^2$
        E = vp.cross(B, rvec)/r                             # $\vec{B}\times \vec{r}/r$
        vp.arrow(pos=rvec, axis=E, length=vp.mag(E), color=(1,1,0))
        vp.arrow(pos=rvec, axis=B, length=vp.mag(B), color=(0,1,1))
    
    
    
    
    
    
    
    
    
    
   
Beispiel #22
0
def moment(point, end1, end2=vector(0, 0, 0)):
    '''Returns the moment defined as the distance between a point 
    and a line formed by two endpoints, end1 and end2.
    All points must be given as 3d vectors'''
    return mag(cross(point - end2, point - end1)) /     \
           mag(end1 - end2)
rhatR = arrow(pos = P, axis = (P[0]-sourceR[0],P[1]-sourceR[1],P[2]-sourceR[2]),\
              length=0.2, shaftwidth = 0.02, color = color.red)
rhatL = arrow(pos= P, axis = (P[0]-sourceL[0],P[1]-sourceL[1],P[2]-sourceL[2]), \
              length = 0.2 , shaftwidth = 0.02, color=color.blue)

# Decide the direction of the current dl (CCW from the top)-  at the location of the right infinitestimal
# it is dlR

dlR = vector(0, 0, -1)
RVec = vector(P[0] - sourceR[0], P[1] - sourceR[1], P[2] - sourceR[2])

# Use Biot-Savart to calculate the infinitesimal contribution to the magnetic field
# by one of the two infinitesimals

dbR = arrow(pos=P,
            axis=cross(dlR, RVec),
            length=0.2,
            shaftwidth=0.02,
            color=(1, 0.7, 0))

# Same calculation for the symmetric infinitesimal

dlL = vector(0, 0, 1)
LVec = vector(P[0] - sourceL[0], P[1] - sourceL[1], P[2] - sourceL[2])

dbL = arrow(pos=P,
            axis=cross(dlL, LVec),
            length=0.2,
            shaftwidth=0.02,
            color=(0, 0.7, 1))
Beispiel #24
0
def Simulation():

    config.Atoms = []  # spheres
    p = []  # momentums (vectors)
    apos = []  # positions (vectors)
    ampl = 0  #амплитуда движения
    period = 5
    k = 1.4E-23  # Boltzmann constant
    R = 8.3
    dt = 1E-5
    time = 0

    def checkCollisions(Natoms, Ratom):
        hitlist = []
        r2 = 2 * Ratom
        for i in range(Natoms):
            for j in range(i):
                dr = apos[i] - apos[j]
                if dr.mag < r2:
                    hitlist.append([i, j])
        return hitlist

    def speed(time, piston_mode, period, ampl, temp):
        if (piston_mode == 0):
            return 0
        if (piston_mode == 1):
            return ampl / 10 * 3 * sin(time / period * 2 * pi) * sqrt(
                3 * config.mass * k * temp) / (5 * config.mass) / period * 100
        if (piston_mode == 2):
            if (time % period < period // 2):
                return 1.5 * ampl / 10 * sqrt(3 * config.mass * k * temp) / (
                    5 * config.mass) / period * 100
            else:
                return -1.5 * ampl / 10 * sqrt(3 * config.mass * k * temp) / (
                    5 * config.mass) / period * 100
        if (piston_mode == 3):
            if (time % period < period // 5):
                return 5 * ampl / 10 * sqrt(3 * config.mass * k * temp) / (
                    5 * config.mass) / period * 100
            else:
                return -5 / 4 * ampl / 10 * sqrt(
                    3 * config.mass * k * temp) / (5 *
                                                   config.mass) / period * 100
        if (piston_mode == 4):
            if (time % period < 4 * period // 5):
                return 5 / 4 * ampl / 10 * sqrt(3 * config.mass * k * temp) / (
                    5 * config.mass) / period * 100
            else:
                return -5 * ampl / 10 * sqrt(3 * config.mass * k * temp) / (
                    5 * config.mass) / period * 100

    width, height = config.w.win.GetSize()

    offset = config.w.dheight
    deltav = 100  # histogram bar width

    disp = display(
        window=config.w,
        x=offset,
        y=offset,
        forward=vector(0, -0.05, -1),
        range=1,  # userspin = False,
        width=width / 3,
        height=height)

    g1 = gdisplay(window=config.w,
                  x=width / 3 + 2 * offset,
                  y=2 * offset,
                  background=color.white,
                  xtitle='t',
                  ytitle='v',
                  foreground=color.black,
                  width=width / 3,
                  height=height / 2 - 2 * offset)

    g2 = gdisplay(window=config.w,
                  x=width / 3 + 2 * offset,
                  y=height / 2 + offset,
                  background=color.white,
                  foreground=color.black,
                  width=width / 3,
                  height=height / 2 - 2 * offset)

    # adding empty dots to draw axis
    graph_average_speed = gcurve(gdisplay=g1, color=color.white)
    graph_average_speed.plot(pos=(3000, 1500))
    graph_temp = gcurve(gdisplay=g2, color=color.white)
    graph_temp.plot(pos=(3000, config.Natoms * deltav / 1000))

    speed_text = wx.StaticText(config.w.panel,
                               pos=(width / 3 + 2 * offset, offset),
                               label="Средняя скорость")
    graph_text = wx.StaticText(config.w.panel,
                               pos=(width / 3 + 2 * offset, height / 2),
                               label="")

    L = 1  # container is a cube L on a side
    d = L / 2 + config.Ratom  # half of cylinder's height
    topborder = d
    gray = color.gray(0.7)  # color of edges of container

    # cylinder drawing
    cylindertop = cylinder(pos=(0, d - 0.001, 0), axis=(0, 0.005, 0), radius=d)
    ringtop = ring(pos=(0, d, 0), axis=(0, -d, 0), radius=d, thickness=0.005)
    ringbottom = ring(pos=(0, -d, 0),
                      axis=(0, -d, 0),
                      radius=d,
                      thickness=0.005)
    body = cylinder(pos=(0, -d, 0), axis=(0, 2 * d, 0), radius=d, opacity=0.2)

    # body_tmp = cylinder(pos = (0, d, 0), axis = (0, 2 * d, 0), radius = d + 0.1, color = (0, 0, 0))
    # ceil = box(pos = (0, d, 0), length = 5, height = 0.005, width = 5, color = (0, 0, 0))
    # floor = box(pos = (0, -d, 0), length = 100, height = 0.005, width = 100, color = (0, 0, 0))
    # left = box(pos = (d + 0.005, 0, 0), axis = (0, 1, 0), length = 100, height = 0.005, width = 100, color = (0, 0, 0))
    # right = box(pos = (-d - 0.005, 0, 0), axis = (0, 1, 0), length = 100, height = 0.005, width = 100, color = (0, 0, 0))

    # uniform particle distribution
    for i in range(config.Natoms):
        qq = 2 * pi * random.random()

        x = sqrt(random.random()) * L * cos(qq) / 2
        y = L * random.random() - L / 2
        z = sqrt(random.random()) * L * sin(qq) / 2

        if i == 0:
            # particle with a trace
            config.Atoms.append(
                sphere(pos=vector(x, y, z),
                       radius=config.Ratom,
                       color=color.cyan,
                       make_trail=False,
                       retain=100,
                       trail_radius=0.3 * config.Ratom))
        else:
            config.Atoms.append(
                sphere(pos=vector(x, y, z), radius=config.Ratom, color=gray))

        apos.append(vector(x, y, z))

    # waiting to start, adjusting everything according to changing variables
    """WAITING TO START"""
    last_Natoms = config.Natoms
    last_Ratom = config.Ratom
    while config.start == 0:
        if config.menu_switch == 0:
            disp.delete()
            g1.display.delete()
            g2.display.delete()

            graph_text.Destroy()
            speed_text.Destroy()
            return

        if config.Natoms > last_Natoms:
            for i in range(config.Natoms - last_Natoms):
                qq = 2 * pi * random.random()
                x = sqrt(random.random()) * L * cos(qq) / 2
                y = L * random.random() - L / 2
                z = sqrt(random.random()) * L * sin(qq) / 2

                if last_Natoms == 0:
                    # particle with a trace
                    config.Atoms.append(
                        sphere(pos=vector(x, y, z),
                               radius=config.Ratom,
                               color=color.cyan,
                               make_trail=False,
                               retain=100,
                               trail_radius=0.3 * config.Ratom))
                else:
                    config.Atoms.append(
                        sphere(pos=vector(x, y, z),
                               radius=config.Ratom,
                               color=gray))
                apos.append(vector(x, y, z))
            last_Natoms = config.Natoms

        elif config.Natoms < last_Natoms:
            for i in range(last_Natoms - config.Natoms):
                config.Atoms.pop().visible = False
                apos.pop()
            last_Natoms = config.Natoms

        if last_Ratom != config.Ratom:
            for i in range(last_Natoms):
                config.Atoms[i].radius = config.Ratom
            last_Ratom = config.Ratom

        if config.model == 0:
            if config.piston_mode >= 1:
                graph_text.SetLabel("Температура")
            else:
                graph_text.SetLabel("Распределение скоростей частиц")
        sleep(0.1)

    # freezed all variables, ready to start
    last_T = config.T
    last_ampl = config.ampl
    last_period = config.period
    last_piston_mode = config.piston_mode
    last_model = config.model

    pavg = sqrt(3 * config.mass * k *
                last_T)  # average kinetic energy p**2/(2config.mass) = (3/2)kT

    for i in range(last_Natoms):
        theta = pi * random.random()
        phi = 2 * pi * random.random()

        px = pavg * sin(theta) * cos(phi)
        py = pavg * sin(theta) * sin(phi)
        pz = pavg * cos(theta)

        p.append(vector(px, py, pz))

    if last_model == 1:
        disp.delete()
        unavail = wx.StaticText(
            config.w.panel,
            style=wx.ALIGN_CENTRE_HORIZONTAL,
            label="Отображение модели недоступно в режиме статистики",
            pos=(offset, height / 2 - offset))
        unavail.Wrap(width / 3)
        last_period = last_period / 10
        last_piston_mode += 1
        graph_text.SetLabel("Температура")
    """ DRAW GRAPHS """

    g1.display.delete()
    g2.display.delete()

    if last_piston_mode == 0:
        g1 = gdisplay(window=config.w,
                      x=width / 3 + 2 * offset,
                      y=2 * offset,
                      background=color.white,
                      xtitle='t',
                      ytitle='v',
                      foreground=color.black,
                      width=width / 3,
                      height=height / 2 - 2 * offset,
                      ymin=0.7 * pavg / config.mass,
                      ymax=1.3 * pavg / config.mass)

        g2 = gdisplay(window=config.w,
                      x=width / 3 + 2 * offset,
                      y=height / 2 + offset,
                      background=color.white,
                      foreground=color.black,
                      xtitle='v',
                      ytitle='Frequency',
                      width=width / 3,
                      height=height / 2 - 2 * offset,
                      xmax=3000 / 300 * last_T,
                      ymax=last_Natoms * deltav / 1000)

    else:
        g1 = gdisplay(window=config.w,
                      x=width / 3 + 2 * offset,
                      y=2 * offset,
                      background=color.white,
                      xtitle='t',
                      ytitle='v',
                      foreground=color.black,
                      width=width / 3,
                      height=height / 2 - 2 * offset)

        g2 = gdisplay(window=config.w,
                      x=width / 3 + 2 * offset,
                      y=height / 2 + offset,
                      background=color.white,
                      xtitle='t',
                      ytitle='T',
                      foreground=color.black,
                      width=width / 3,
                      height=height / 2 - 2 * offset)

    graph_average_speed = gcurve(gdisplay=g1, color=color.black)

    if last_piston_mode:
        graph_temp = gcurve(gdisplay=g2, color=color.black)
    else:
        theory_speed = gcurve(gdisplay=g2, color=color.black)
        dv = 10
        for v in range(0, int(3000 / 300 * last_T), dv):
            theory_speed.plot(pos=(v, (deltav / dv) * last_Natoms * 4 * pi *
                                   ((config.mass /
                                     (2 * pi * k * last_T))**1.5) *
                                   exp(-0.5 * config.mass * (v**2) /
                                       (k * last_T)) * (v**2) * dv))

        hist_speed = ghistogram(gdisplay=g2,
                                bins=arange(0, int(3000 / 300 * last_T), 100),
                                color=color.red,
                                accumulate=True,
                                average=True)

        speed_data = []  # histogram data
        for i in range(last_Natoms):
            speed_data.append(pavg / config.mass)
            # speed_data.append(0)
    """ MAIN CYCLE """
    while config.start:

        while config.pause:
            sleep(0.1)

        rate(100)

        sp = speed(time, last_piston_mode, last_period, last_ampl, 300)
        cylindertop.pos.y -= sp * dt
        time += 1

        for i in range(last_Natoms):
            config.Atoms[i].pos = apos[i] = apos[i] + (p[i] / config.mass) * dt

            if last_piston_mode == 0:
                speed_data[i] = mag(p[i]) / config.mass

        total_momentum = 0
        v_sum = 0
        for i in range(last_Natoms):
            total_momentum += mag2(p[i])
            v_sum += sqrt(mag2(p[i])) / config.mass

        graph_average_speed.plot(pos=(time, v_sum / last_Natoms))

        if last_piston_mode:
            graph_temp.plot(pos=(time, total_momentum / (3 * k * config.mass) /
                                 last_Natoms))
        else:
            hist_speed.plot(data=speed_data)

        hitlist = checkCollisions(last_Natoms, last_Ratom)

        for ij in hitlist:

            i = ij[0]
            j = ij[1]
            ptot = p[i] + p[j]
            posi = apos[i]
            posj = apos[j]
            vi = p[i] / config.mass
            vj = p[j] / config.mass
            vrel = vj - vi
            a = vrel.mag2
            if a == 0:  # exactly same velocities
                continue
            rrel = posi - posj
            if rrel.mag > config.Ratom:  # one atom went all the way through another
                continue

            # theta is the angle between vrel and rrel:
            dx = dot(rrel, norm(vrel))  # rrel.mag*cos(theta)
            dy = cross(rrel, norm(vrel)).mag  # rrel.mag*sin(theta)
            # alpha is the angle of the triangle composed of rrel, path of atom j, and a line
            #   from the center of atom i to the center of atom j where atome j hits atom i:
            alpha = asin(dy / (2 * config.Ratom))
            d = (2 * config.Ratom) * cos(
                alpha
            ) - dx  # distance traveled into the atom from first contact
            deltat = d / vrel.mag  # time spent moving from first contact to position inside atom

            posi = posi - vi * deltat  # back up to contact configuration
            posj = posj - vj * deltat
            mtot = 2 * config.mass
            pcmi = p[
                i] - ptot * config.mass / mtot  # transform momenta to cm frame
            pcmj = p[j] - ptot * config.mass / mtot
            rrel = norm(rrel)
            pcmi = pcmi - 2 * pcmi.dot(rrel) * rrel  # bounce in cm frame
            pcmj = pcmj - 2 * pcmj.dot(rrel) * rrel
            p[i] = pcmi + ptot * config.mass / mtot  # transform momenta back to lab frame
            p[j] = pcmj + ptot * config.mass / mtot
            apos[i] = posi + (
                p[i] / config.mass) * deltat  # move forward deltat in time
            apos[j] = posj + (p[j] / config.mass) * deltat

        # collisions with walls
        for i in range(last_Natoms):

            # проекция радиус-вектора на плоскость
            loc = vector(apos[i])
            loc.y = 0

            # вылет за боковую стенку (цилиндр радиуса L / 2 + config.Ratom)
            if (mag(loc) > L / 2 + 0.01 - last_Ratom +
                    sqrt(p[i].x**2 + p[i].z**2) / config.mass * dt):

                # проекция импульса на плоскость
                proj_p = vector(p[i])
                proj_p.y = 0

                loc = norm(loc)
                # скалярное произведение нормированного радиус-вектора на импульс (все в проекции на плоскость)
                dotlp = dot(loc, proj_p)

                if dotlp > 0:
                    p[i] -= 2 * dotlp * loc
                # dotlp < 0 - атом улетает от стенки
                # dotlp = 0 - атом летит вдоль стенки

            loc = apos[i]

            # вылет за торцы
            if loc.y + p[i].y / config.mass * dt < -L / 2 - 0.01 + last_Ratom:
                p[i].y = abs(p[i].y)

            if loc.y + p[
                    i].y / config.mass * dt > cylindertop.pos.y - last_Ratom:
                v_otn = p[i].y / config.mass + sp
                if v_otn > 0:
                    p[i].y = (-v_otn - sp) * config.mass

        # type here

    if last_model == 0:
        disp.delete()
    else:
        unavail.Destroy()

    g1.display.delete()
    g2.display.delete()

    graph_text.Destroy()
    speed_text.Destroy()
def runge_lenz(self, o):
	# print(cross(self.momentum, cross(self.pos, self.momentum)) - pow(self.mass, 2.0) * o.mass * g * norm(self.pos - o.pos))
	return cross(self.momentum, self.l()) - pow(self.mass, 2.0) * o.mass * g * norm(self.pos - o.pos)
Beispiel #26
0
def baseball(Y, t):                 # Y = [r, v] assumed
    v = Y[1]
    fm = alpha*vp.cross(omega, v)               # Magnus force
    a = (fm - b2*vp.mag(v)*v)/mass - [0,g,0]    # minus g-vec
    return np.array([v, a])                     # np array
Beispiel #27
0
def bdipole(r):                     # calc magnetic fields at $\vec{r}$
    b, rel = vp.vector(0,0,0), r-rs
    for i in range(len(ds)):        # sum over segments
        b += vp.cross(ds[i], rel[i])/vp.mag(rel[i])**3   # $\sum Id\vec{s}\times \vec{r}/r^3$
    return b