nach vielen Hilfsthreads hab ich mein Programm jetzt endlich fertig.
Leider hab ich immo nochein Probleme.
Ich benutze immer nur einen Core -> ich verschenke 50% Leistung
Auf dem Rechner auf dem es später laufen soll hab ich einen Quadcore, könnte also 4 Cores verwenden.
Hier erst mal das Programm:
Code: Alles auswählen
import csv
import collections
import pylab
import numpy as n
from threading import Thread
import threading
import matplotlib.pyplot as plt
from optparse import OptionParser
#parser = OptionParser()
#parser.add_option("-m", action="store_true", help="Runs simulation, writting, plotting, write plot", dest="main")
#(options, args) = parser.parse_args()
# Defination Simulations Konstanten und Kraftkopplungen
G=6.674 * 10**(-11) #Gravitationskopplung
#G=1
time = float(0.0001) # Zeit pro Hop in s
hops = int(10000000) # Hops
# Definiere Hilfsfunktionen
def norm(x):
out=n.sqrt(n.dot(x,x))
return out
def csvreader(filename,delim):
print "analyzing ",filename
csv_in = csv.reader(open(filename, "rb"), delimiter=';')
#csv_in = pylab.csv2rec(filename, checkrows=0, skiprows=1, delimiter=delim, names='name,pos_x,pos_y,speed_x,speed_y,mass,bla')
bodies=[]
#Name, Positionx, Positiony, Speedx, Speedy, Masse
for row in list(csv_in)[1:]:
name, pos_x, pos_y, speed_x, speed_y, mass= row
bodies.append([name, n.array([float(pos_x),float(pos_y)]), n.array([float(speed_x),float(speed_y)]), float(mass)])
print "finished reading"
return bodies
def csvwriter(log):
collector = collections.defaultdict(list)
for entry in log:
collector[entry[0]].append(entry[1])
for name, entries in collector.iteritems():
with open("%s.txt" % name, "w") as fobj:
writer = csv.writer(fobj, delimiter='\t', lineterminator='\n')
writer.writerows(entries)
return "finished writing"
def pylplot(log, bodies):
data = collections.defaultdict(lambda: collections.defaultdict(list))
for name, pos, hop in log:
data[name]['x'].append(pos[0])
data[name]['y'].append(pos[1])
t=[]
for y in bodies:
t.append([y[0],y[1][0],y[1][1],y[2][0],y[2][1],y[3]])
fig = plt.figure()
ax = fig.add_subplot(111)
for name in data:
ax.plot(data[name]['x'], data[name]['y'])
plt.legend(t,
'lower right', shadow=True, prop=dict(size=8))
plt.subplots_adjust(left=0, bottom=0, top=1, right=1)
plt.savefig('out.png')
plt.show()
return "plot finished"
def calcgravforce(x,y):
#G * m1 * m2 * er /r^2
out = (x[1]-y[1]) * G * x[3] * y[3] / (norm(x[1]-y[1])**3)
return out
def calcgravforcecomplete(x, bodies):
force = n.array([0,0])
for y in bodies:
if not y == x:
force = force - calcgravforce(x, y)
return force
def calcnewposition(x, force):
# 1/2 * a * t^2 + v * t +x
out = 0.5 * (time**2) * force / x[3] + time * x[2] + x[1]
return out
def calcnewspeed(x, force):
#a * t + v
out = time * force / x[3]+ x[2]
return out
def calcnewmass(x):
#konstante masse, Raketen noch nicht drin
out = x[3]
return out
def calcbody(x, force):
out = [x[0], calcnewposition(x, force), calcnewspeed(x, force), calcnewmass(x)]
return out
def calc(z):
force = calcgravforcecomplete(z[0], z[1])
return calcbody(z[0], force)
#if options.main():
def main():
bodies = csvreader("koerper.txt", ";")
startbodies = bodies[:]
log=[]
for i in range(0, hops):
bodiesnew=[]
for x in bodies:
force = calcgravforcecomplete(x, bodies)
bodiesnew.append(calcbody(x, force))
log.append([x[0], x[1], i])
bodies=bodiesnew
print "finished calc"
print csvwriter(log)
print pylplot(log, startbodies)
return 1
main()
Code: Alles auswählen
for x in bodies:
force = calcgravforcecomplete(x, bodies)
bodiesnew.append(calcbody(x, force))
log.append([x[0], x[1], i])
bodies=bodiesnew
Das gute ist, für jede forschleifen Durchlauf sind alle Werte statisch, man kann es also gut parallelisieren. Nur wie?
Habs jetzt schon mit p = pool() usw. versucht aber da bekomme ich nur ständig irgendwelche Speicheradressen mit Fehlern geplottet. Kann ich das Listenschreiben überhaupt parallelisieren oder nur die eigentliche Berechnung?
Wichtig ist hier vlt auch das ich immo unter Windows das ganze schreibe, es aber später unter Linux laufen soll.