====== Testprogramme ======
Diese Testprogramme helfen uns dabei gewisse Funktionen auf ihre Richtigkeit zu prüfen, wie auch zum Vergleichen welche Funktion bessere Ergebnisse liefert.
===== Vergleich von Planetenbewegungen mit verschiedenen Methoden=====
In diesem Skript wird die Genauigkeit des Euler-Verfahrens mit dem Leapfrog-Verfahren am Bespiel der Erdbewegung
um die Sonne verglichen. Die Bewegung der dunkelblauen Erde wir durch das Leapfrog-Verfahren berechnet, das der hellblauen durch das Euler-Verfahren. Nach einiger Zeit sieht man bereits deutliche Unterschiede in der Bahnbewegung: Die dunkelblaue Erde verlässt die richtige Bahn langsamer, da ihre die Berechnungsfehler kleiner sind.
from functions import *
import pygame
class Sun(object):
def __init__(self):
"""initialize all necessary properties of the sun
"""
self.x = 0
self.y = 0
self.radius = 20
self.mass = 1.989e30
self.colour = (255, 255, 0)
class Earth(object):
def __init__(self, color):
"""initialize all necessary properties of the earth
"""
self.x = 1.49e11
self.y = 0.
self.radius = 10
self.mass = 5.97e24
self.velocity = np.array([0., 2.978e4])
self.force = np.array([0, 0])
self.colour = (color)
def move(self):
"""leapfrog method for differential-equation-solving
"""
self.x += 0.5 * self.velocity[0] * dt
self.y += 0.5 * self.velocity[1] * dt
self.velocity += self.force/self.mass * dt
self.x += 0.5 * self.velocity[0] * dt
self.y += 0.5 * self.velocity[1] * dt
def move2(self):
"""euler-method for differential-equation-solving
"""
self.x += self.velocity[0] * dt
self.y += self.velocity[1] * dt
self.velocity += self.force/self.mass * dt
def draw(a, points):
"""Draws an object on the screen
"""
pygame.draw.circle(screen, a.colour, (int(a.x * 10e-10) + width/2,
int(a.y * 10e-10) + height/2), a.radius, 0)
pygame.draw.aalines(screen, a.colour, False, points, 2)
def draw2(a):
"""Draws an object in the middle of the screen
"""
pygame.draw.circle(screen, a.colour, (width/2, height/2), a.radius, 0)
dt = 36000
(width, height) = (1000, 600)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption(" ")
bgcolour = (10, 10, 10)
earth = Earth((0, 0, 255))
kerbin = Earth((50, 150, 255))
sun = Sun()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# display everything
screen.fill(bgcolour)
draw(erde, linepoints1)
draw(kerbin, linepoints2)
draw2(sonne)
pygame.display.update()
# calculate everything
erde.force = get_force(earth, sun)
kerbin.force = get_force(kerbin, sun)
erde.move()
kerbin.move2()
=====Euler-Verfahren vs Verlet(Leapfrog)-Verfahren=====
import matplotlib.pyplot as plt
import numpy as np
# x .. = f(x)
def f(x):
return -x
def leapfrog(startwertx, startwertv, intervallende, anzahlschritte):
h = (intervallende - startwertx)/anzahlschritte
tpoints = np.linspace(0, intervallende, anzahlschritte)
xpoints = []
vpoints = []
x = startwertx
v = startwertv
for t in tpoints:
xpoints.append(x)
vpoints.append(v)
x += 0.5 * v * h
v += f(x) * h
x += 0.5 * v * h
#x += h * f(x) + f(x) * h**2/2
return tpoints, xpoints
def euler(startwertx, startwertv, intervallende, anzahlschritte):
h = (intervallende - startwertx)/anzahlschritte
tpoints = np.linspace(0, intervallende, anzahlschritte)
xpoints = []
vpoints = []
x = startwertx
v = startwertv
for t in tpoints:
xpoints.append(x)
vpoints.append(v)
v_neu = v + h * f(x)
x += h * v
v = v_neu
#x += h * f(x) + f(x) * h**2/2
return tpoints, xpoints
t1, x1 = leapfrog(0.,1., 100, 500)
t2, x2 = euler(0.,1., 100, 500)
pointsin = np.sin(t1)
abweichung_1 = []
abweichung_2 = []
for i in range(len(t1)):
abweichung_1.append(pointsin[i]-x1[i])
abweichung_2.append(pointsin[i]-x2[i])
fig = plt.figure(figsize = (18, 8.5))
ax = fig.add_subplot(111)
ax.plot(t1, x1, label="Leapfrog")
ax.plot(t2, x2, label="Euler")
ax.plot(t1, np.sin(t1), label="np.Sinus")
ax.plot(t1, abweichung_1, label="Abweichung Leapfrog")
ax.plot(t1, abweichung_2, label="Abweichung Euler")
ax.plot(t1, 0*t1, color="black")
plt.legend(loc=best)
plt.show()
=====Asteoridengürtel nur mit Sonnengravitation=====
import numpy as np
import pygame
from functions import get_force
class Asteorid(object):
def __init__(self,phi,radius):
self.x = np.cos(phi) * radius
self.y = np.sin(phi) * radius
self.radius = np.random.randint(1,3)
self.mass = 6.687e15
self.velocity = np.sqrt(G * 1.989e30/radius)
* np.array([-np.sin(phi), np.cos(phi)])
self.force = np.array([0.,0.])
self.colour = (100,100,100)
def move(self):
self.x += 0.5 * self.velocity[0] * dt
self.y += 0.5 * self.velocity[1] * dt
self.velocity += self.force/self.mass * dt
self.x += 0.5 * self.velocity[0] * dt
self.y += 0.5 * self.velocity[1] * dt
class Sun(object):
"""Our Sun in the point of origin
"""
def __init__(self):
self.x = 0
self.y = 0
self.radius = 20
self.mass = 1.989e30
self.colour = (255,255,0)
def draw(a):
"""Draws an object and its trail on the screen
"""
pygame.draw.circle(screen, a.colour, (int(a.x * 0.5e-9) + width/2,
int(a.y * 0.5e-9) + height/2), a.radius, 0)
def draw2(a):
"""Draws an object in the middle of the screen
"""
pygame.draw.circle(screen, a.colour, (width/2, height/2), a.radius, 0)
G = 6.673e-11
AE = 1.496e11
n = 2000
dt = 36000
liste = []
(width, height) = (1000,600)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption(" ")
background_colour = (10,10,10)
for i in xrange(n):
phi = 2 * np.random.random() * np.pi
radius = np.random.uniform(2.,3.4) * AE
obj = Asteorid(phi, radius)
liste.append(obj)
sonne = Sun()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# display everything
screen.fill(background_colour)
draw2(sonne)
for i in liste:
draw(i)
i.force = get_force(i, sonne)
i.move()
pygame.display.update()
=====Neue Berechnung des Drehimpulses nach einem Zusammenstoß=====
# -*- coding: utf8 -*-
from functions import *
import numpy as np
n = 2
liste_teilchen = init_particle_list(n)
part_1,part_2=liste_teilchen
part_1.velocity = np.array([1.,0.])
part_2.velocity = np.array([0.,1.])
def get_torque(part_1, part_2):
"""
Drehimpulsberechnung für neu entstandenes Teilchen nach Kollision
"""
newpoint_x = (part_1.mass * part_1.x + part_2.mass * part_2.x)
/ (part_1.mass + part_2.mass)
newpoint_y = (part_1.mass * part_1.y + part_2.mass * part_2.y)
/ (part_1.mass + part_2.mass)
newpoint = ([newpoint_x, newpoint_y]) #Schwerpunkt zwischen beiden Teilchen
print part_1.x,part_1.y
print part_2.x,part_2.y
print newpoint
r_1 = ([part_1.x - newpoint_x, part_1.y - newpoint_y]) #Richtungsvektoren
r_2 = ([part_2.x - newpoint_x, part_2.y - newpoint_y])
print r_1
print r_2
torq_1 = part_1.mass * np.cross(r_1, part_1.velocity) #Drehimpulse der einzelnen Teilchen zum Schwerpunkt
torq_2 = part_2.mass * np.cross(r_2, part_2.velocity)
torq = torq_1 + torq_2 #Gesammtdrehimpuls (+ Eigendrehimpulse falls vorhanden)
print torq
return newpoint,torq
for i,part_1 in enumerate(liste_teilchen):
for j,part_2 in enumerate(liste_teilchen):
if i < j:
get_torque(part_1, part_2)