2016-06-22 13 views
0

Hier habe ich einen Code für meine neueste Computational Physics Final geschrieben (bereits benotet). In diesem Code gibt es eine Variable namens u_xt, die zu jedem Zeitpunkt t die Verteilung u (x) sammelt. Nach der Berechnung der Form der neuen Kurve mit Finite-Differenzen-Methoden benutze ich die Append-Funktion (und probiere auch den Weg, ein Array zu erstellen und n-tes Element bei jedem Schritt zuzuweisen) und erhalte die endgültige Kurve (bei t = t_upper) für alle Werte von u_xt [n] für n> = 1 und u_xt [0] ist die Anfangskurve.Anfügen an Liste speichert nur das letzte Element in Python 3

Ich kann nicht herausfinden, warum.

# animation adapted from http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/ 

from numpy import linspace, zeros 
import matplotlib.pyplot as plt 
from matplotlib import animation 

# setting up parameters 
dt = 0.1 
dx = 0.1 
dtdx = dt/dx 

# some tentative limits 
x_upper = 10 
x_lower = -10 
t_upper = 10 

# arrange variables 
x = linspace(x_lower, x_upper, (x_upper-x_lower)/dx + 1) 
t = linspace(0, t_upper, t_upper/dt) 

# initial condition 
u = zeros(len(x)) 
u[135:140] = 1 

# variable for full solution 
u_xt = [] # <-- BELONGS TO THE DEVIL, SEE BELOW 
u_xt.append(u) 
u_old = u 
u_new = zeros(len(u)) 

# value of u at next time step... 
for n in range(1, int(t_upper/dt)): 
    # we need i-th element for n+1 
    for i in range(int((x_upper-x_lower)/dx)): 
     # use old u to get new u at i-th grid 
     u_new[i] = u_old[i] + 0.5*dtdx*(u_old[i+1] - u_old[i]) - 0.4*dt*u_old[i] 

    # save new u 
    u_xt.append(u_new) 
    # for the next step, newfound u is old u (so poetic) 
    u_old = u_new 
    # For some reason u_xt is saving only the last calculation (for t=t_upper) 
    # It clearly is in the correct indentation! 
    # Even u_xt[1] is the last curve. If I comment out the u_old = u_new line, then it saves only the first time-step calculation (as it should). But add that line and then u_xt becomes a dedicated servant of SATAN. 

    # <RANT> 
    # The solution (when looked at final snapshots with different t_upper values) is that of a diminishing translation to the left of the initial curve. But because u_xt is the variable of SATAN, it is not working. This refusal to carry out logic is at such magnitudes, it could replace the loss of free energy of our universe since the big friggin bang! Except, of course, u_xt is the variable of OATHBREAKER and will not do anything useful without eating your soul first. 
    # </RANT> 

# let's animate! 

# set up figure, axis and plot element 
fig = plt.figure() 
ax = plt.axes(xlim=(-10,10), ylim=(0,1.1)) 
line, = ax.plot([], [], lw=2) 

# initializing function 
def init(): 
    line.set_data([], []) 
    return line, 

# animation function 
def animate(k): 
    line.set_data(x, u_xt[k]) 
    return line, 

# call animator 
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=int(t_upper/dt), interval=20, blit=True) 

# save the animation (requires ffmpeg to be installed and callable from system path, can be commented out if not desired without ill effect) 
anim.save('_q5.mp4', fps=30, extra_args=['-vcodec', 'libx264']) 

plt.figure() 
plt.plot(x, u_xt[-1], label="Final moment of the curve") 
plt.show() 
+1

Ihre äußere 'for' Schleife füllt' u_xt' mit mehreren Kopien der 'u_new' Liste. Dies hängt mit dem Problem hier zusammen: http://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across-sublists-unexpectedly –

+0

Eine ähnliche Frage, aber mit einer Liste von Diktaten: http : //stackoverflow.com/questions/32057828/appending-to-a-list-in-python-adds-last-element-every-time –

Antwort

1

Kopieren Sie einfach es, sonst sind Sie nur Referenzierung mehrfach:

u_xt.append(list(u_new)) 
+0

Danke, das hat funktioniert. Ich habe das resultierende Video hochgeladen, also schön, es endlich zu sehen. [Hier ist es.] (Https://youtu.be/koUvNswH2YM) –