def main(): if len(argv) < 3: raise Exception('>>> ERROR! Please supply values for black hole mass [>= 1.0] and spin [0.0 - 1.0] <<<') m = float(argv[1]) a = float(argv[2]) horizon = m * (1.0 + sqrt(1.0 - a * a)) cauchy = m * (1.0 - sqrt(1.0 - a * a)) # set up the scene scene.center = (0.0, 0.0, 0.0) scene.width = scene.height = 1024 scene.range = (20.0, 20.0, 20.0) inner = 2.0 * sqrt(cauchy**2 + a**2) ellipsoid(pos = scene.center, length = inner, height = inner, width = 2.0 * cauchy, color = color.blue, opacity = 0.4) # Inner Horizon outer = 2.0 * sqrt(horizon**2 + a**2) ellipsoid(pos = scene.center, length = outer, height = outer, width = 2.0 * horizon, color = color.blue, opacity = 0.3) # Outer Horizon ergo = 2.0 * sqrt(4.0 + a**2) ellipsoid(pos = scene.center, length = ergo, height = ergo, width = 2.0 * horizon, color = color.gray(0.7), opacity = 0.2) # Ergosphere if fabs(a) > 0.0: ring(pos=scene.center, axis=(0, 0, 1), radius = a, color = color.white, thickness=0.01) # Singularity else: sphere(pos=scene.center, radius = 0.05, color = color.white) # Singularity ring(pos=scene.center, axis=(0, 0, 1), radius = sqrt(isco(a)**2 + a**2), color = color.magenta, thickness=0.01) # ISCO curve(pos=[(0.0, 0.0, -15.0), (0.0, 0.0, 15.0)], color = color.gray(0.7)) #cone(pos=(0,0,12), axis=(0,0,-12), radius=12.0 * tan(0.15 * pi), opacity=0.2) #cone(pos=(0,0,-12), axis=(0,0,12), radius=12.0 * tan(0.15 * pi), opacity=0.2) #sphere(pos=(0,0,0), radius=3.0, opacity=0.2) #sphere(pos=(0,0,0), radius=12.0, opacity=0.1) # animate! ball = sphere() # Particle counter = 0 dataLine = stdin.readline() while dataLine: # build raw data arrays rate(60) if counter % 1000 == 0: ball.visible = False ball = sphere(radius = 0.2) # Particle ball.trail = curve(size = 1) # trail data = loads(dataLine) e = float(data['v4e']) if e < -120.0: ball.color = color.green elif e < -90.0: ball.color = color.cyan elif e < -60.0: ball.color = color.yellow elif e < -30.0: ball.color = color.orange else: ball.color = color.red r = float(data['r']) th = float(data['th']) ph = float(data['ph']) ra = sqrt(r**2 + a**2) sth = sin(th) ball.pos = (ra * sth * cos(ph), ra * sth * sin(ph), r * cos(th)) ball.trail.append(pos = ball.pos, color = ball.color) counter += 1 dataLine = stdin.readline()
def __init__(self, center, radius, normal, I, scene, loops = 1, pitch = 1): Shape.__init__(self, scene) self.center = center self.radius = radius self.normal = normal self.loops = loops self.pitch = pitch self.length = loops*pitch self.I = I # some consonants self.C = mu_0*I/pi self.oner = [[1,0,0], [0,1,0], [0,0,1]] # rotation matrices for this coil, rotating so norm becomes z axis self.rotate = self.find_rotmatrix(normal.norm(), vector(0, 0, 1)) self.antiRotate = inverse(self.rotate) if loops == 1: self.obj = ring(pos = center, axis = normal*self.length, radius = radius, thickness = 0.1, display = scene, material = materials.chrome) else: self.obj = helix(pos = center, axis = normal*self.length, radius = radius, coils = loops, thickness = 0.1, display = scene, material = materials.chrome)
def set_scene(r): # r = position of test body vp.display(title='Restricted 3body', background=(1,1,1)) body = vp.sphere(pos=r, color=(0,0,1), radius=0.03, make_trail=1) sun = vp.sphere(pos=(-a,0), color=(1,0,0), radius=0.1) jupiter = vp.sphere(pos=(b, 0), color=(0,1,0), radius=0.05) circle = vp.ring(pos=(0,0), color=(0,0,0), thickness=0.005, axis=(0,0,1), radius=1) # unit circle return body
def set_scene(r): # r = position of test body vp.display(title='Restricted 3body', background=(1, 1, 1)) body = vp.sphere(pos=r, color=(0, 0, 1), radius=0.03, make_trail=1) sun = vp.sphere(pos=(-a, 0), color=(1, 0, 0), radius=0.1) jupiter = vp.sphere(pos=(b, 0), color=(0, 1, 0), radius=0.05) circle = vp.ring(pos=(0, 0), color=(0, 0, 0), thickness=0.005, axis=(0, 0, 1), radius=1) # unit circle return body
def init_gui(self): # Is the orientation matrix missing here???? self.length = 100 wallR = box(pos=vector(self.length / 2., 0, 0), size=(0.2, self.length, self.length), color=color.green) wallB = box(pos=vector(0, 0, -self.length / 2.), size=(self.length, self.length, 0.2), color=color.white) wallDown = box(pos=vector(0, -self.length / 2., 0), size=(self.length, 0.2, self.length), color=color.red) wallUp = box(pos=vector(0, self.length / 2., 0), size=(self.length, 0.2, self.length), color=color.white) wallL = box(pos=vector(-self.length / 2., 0, 0), size=(0.2, self.length, self.length), color=color.blue) self.unit_target = self.target_vector / np.linalg.norm( self.target_vector) self.target_position = np.array( self.unit_target) * self.max_factor * self.force_scale self.ball = sphere(pos=[0, 0, 0], radius=self.ball_rad, color=self.ball_color) self.target = sphere(pos=self.target_position, radius=self.target_rad, color=self.target_color) self.shadow_cursor = ring(pos=[0, -self.length / 2, 0], axis=(0, 10, 0), radius=self.ball_rad, thickness=1, color=[0.25, 0.25, 0.25]) self.shadow_target = ring(pos=[ self.target_position[0], -self.length / 2, self.target_position[2] ], axis=(0, 10, 0), radius=self.ball_rad, thickness=1, color=[0.25, 0.25, 0.25])
def __init__(self, center, radius, normal, I, scene, loops=1, pitch=1): Shape.__init__(self, scene) self.center = center self.radius = radius self.normal = normal self.loops = loops self.pitch = pitch self.length = loops * pitch self.I = I # some consonants self.C = mu_0 * I / pi self.oner = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] # rotation matrices for this coil, rotating so norm becomes z axis self.rotate = self.find_rotmatrix(normal.norm(), vector(0, 0, 1)) self.antiRotate = inverse(self.rotate) if loops == 1: self.obj = ring(pos=center, axis=normal * self.length, radius=radius, thickness=0.1, display=scene, material=materials.chrome) else: self.obj = helix(pos=center, axis=normal * self.length, radius=radius, coils=loops, thickness=0.1, display=scene, material=materials.chrome)
yoffset=a / 6, zoffset=-a / 6, text='z', box=False, background=color.white, opacity=0.06, line=False) #Draw the solenoid ra = 0.5 # 5 cm radius (we decide the units for nicer visualization) l = 1 # 10 cm length N = 30 for i in xrange(N + 1): ring(pos = (0,0,l *i / float(N)), axis = (0,0,1), radius = ra\ ,thickness = 0.02, color = color.yellow, opacity = 0.3) # function to calculate B of a solenoid composed by the two rings taken from group_11.py I = 10 # current in the solenoid dtheta = 5 * 1e-3 # integral precision def solenoid(P, N, l): # B of solenoid length l from origin loops N at P interval = int(2 * pi / dtheta) # interval = 5 # for debug i = np.outer(np.ones((N, )), np.arange(interval)) # i.shape = (N, interval) theta = dtheta * i # theta.shape = (N, interval) z = np.outer( l * np.arange(N) / float(N - 1), # location of the loops
scene = display(title='Rolling torus @ %0.2f realtime' % k, width=800, height=800, up=(0, 0, -1), uniform=1, background=black, forward=(1, 0, 0)) # Inertial reference frame arrows N = [ arrow(pos=NO, axis=N1, color=red), arrow(pos=NO, axis=N2, color=green), arrow(pos=NO, axis=N3, color=blue) ] torus = ring(pos=CO[0], axis=B2[0], radius=r1, thickness=r2, color=blue) # Arrows for body fixed coordinates in plane of torus c1 = arrow(pos=CO[0], axis=C1[0], up=C3[0], color=red) c3 = arrow(pos=CO[0], axis=C3[0], up=C1[0], color=green) # Ground contact path trail = curve() trail.append(pos=(x[0, 3], x[0, 4], 0.0), color=white) i = 1 while i < n: torus.pos = CO[i] torus.axis = B2[i] c1.pos = CO[i] c3.pos = CO[i] c1.axis = C1[i] c3.axis = C3[i]
# # Program 7.7: Electric dipole fields (edipole.py) # J Wang, Computational modeling and visualization with Python # import visual as vp, numpy as np r, scale, m, n = 0.5, 0.05, 11, 19 # parameters 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))
xoffset=-a / 6, yoffset=a / 6, zoffset=-a / 6, text='z', box=False, background=color.white, opacity=0.06, line=False) #Draw the two electromagnets ra = 0.5 # 5 cm radius loop1 = ring(pos=(0, 0, 0), axis=(0, 0, 1), radius=ra, thickness=0.02, color=color.yellow) loop2 = ring(pos=(0, 0, 1), axis=(0, 0, 1), radius=ra, thickness=0.02, color=color.cyan) # function to calculate B of a solenoid composed by the two rings taken from group_11.py I = 10 # current in the solenoid dtheta = 1e-3 # integral precision def solenoid(P, N, l): # B of solenoid length l from origin loops N at P
line=False) label(pos=vector(0, 0, a / 2), xoffset=-a / 6, yoffset=a / 6, zoffset=-a / 6, text='z', box=False, background=color.white, opacity=0.06, line=False) #Draw the ring loop = ring(pos=(0, 0, 0), axis=(0, 1, 0), radius=0.5, thickness=0.02, color=color.yellow) # Ask the user the location where we want to show the contributions to B xp = input("Choose a point (enter x)") yp = input("Choose a point (enter y)") zp = input("Choose a point (enter z)") P = (xp, yp, zp) # Location where we want to show the contributions to B # Choose two infinitesimal points on the ring sourceR = (0.5, 0, 0) sourceL = (-0.5, 0, 0)
blue = (0, 0, 1) white = (1, 1, 1) NO = (0,0,0) N1 = (1, 0, 0) N2 = (0, 1, 0) N3 = (0, 0, 1) scene = display(title='Rolling torus @ %0.2f realtime'%k, width=800, height=800, up=(0,0,-1), uniform=1, background=black, forward=(1,0,0)) # Inertial reference frame arrows N = [arrow(pos=NO,axis=N1,color=red), arrow(pos=NO,axis=N2,color=green), arrow(pos=NO,axis=N3,color=blue)] torus = ring(pos=CO[0], axis=B2[0], radius=r1, thickness=r2, color=blue) # Arrows for body fixed coordinates in plane of torus c1 = arrow(pos=CO[0], axis=C1[0], up=C3[0], color=red) c3 = arrow(pos=CO[0], axis=C3[0], up=C1[0], color=green) # Ground contact path trail = curve() trail.append(pos=(x[0,3], x[0,4], 0.0), color=white) i = 1 while i<n: torus.pos = CO[i] torus.axis = B2[i] c1.pos = CO[i] c3.pos = CO[i] c1.axis = C1[i] c3.axis = C3[i]
sVis = vs.sphere(pos = tuple(s.center - centScene), radius = s.radius, opacity=0.3) # central line if (i < len(tunnel.t)-1): s2 = tunnel.t[i+1] # vVis = vs.arrow(pos=s.center - centScene, # axis=(s2.center[0]-s.center[0], # s2.center[1]-s.center[1], # s2.center[2]-s.center[2]), # color=(1,0,0), shaftwidth=1) for i, disk in enumerate(disks[:]): # if (i != 0): # print "Disk distance: {}".format(disk_dist(disks[i-1], disk)) vs.ring(pos=disk.center - centScene, axis=disk.normal, radius=disk.radius, thickness=0.01, color=(1,0,0)) # if i % 2 == 1: # vVis = vs.arrow(pos=tuple(disk.center - centScene), # axis=tuple(disk.normal * 0.25) , # color=(0,1,0), shaftwidth=0.5) output_path = arguments.get("--output-file") if output_path: with open(output_path, "w") as output_file: for disk in disks: line = "{} {} {} {} {} {} {}\n".format(disk.center[0], disk.center[1], disk.center[2], disk.normal[0], disk.normal[1], disk.normal[2], disk.radius) output_file.write(line)
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()
opacity=0.3) # central line if (i < len(tunnel.t) - 1): s2 = tunnel.t[i + 1] vVis = vs.arrow(pos=s.center - centScene, axis=(s2.center[0] - s.center[0], s2.center[1] - s.center[1], s2.center[2] - s.center[2]), color=(1, 0, 0), shaftwidth=0.3) for i, disk in enumerate(disks[:]): # if (i != 0): # print "Disk distance: {}".format(disk_dist(disks[i-1], disk)) vs.ring(pos=disk.center - centScene, axis=disk.normal, radius=disk.radius, thickness=0.01, color=(1, 0, 0)) # if i % 2 == 1: # vVis = vs.arrow(pos=tuple(disk.center - centScene), # axis=tuple(disk.normal * 0.25) , # color=(0,1,0), shaftwidth=0.5) output_path = arguments.get("--output-file") if output_path: with open(output_path, "w") as output_file: for disk in disks: line = "{} {} {} {} {} {} {}\n".format( disk.center[0], disk.center[1], disk.center[2], disk.normal[0], disk.normal[1], disk.normal[2], disk.radius)