physics - Trying to simulate a 1-dimensional wave -
i'm trying make simplified simulation of 1-dimensional wave chain of harmonic oscillators. differential equation position x[i]
of i-th oscillator (assuming equilibrium @ x[i]=0
) turns out - according textbooks - one:
m*x[i]''=-k(2*x[i]-x[i-1]-x[i+1])
(the derivative wrt time) tried numerically compute dynamics following algorithm. here osc[i]
i-th oscillator object attributes loc
(absolute location), vel
(velocity), acc
(acceleration) , bloc
(equilibrium location), dt
time increment:
for every i: osc[i].vel+=dt*osc[i].acc; osc[i].loc+=dt*osc[i].vel; osc[i].vel*=0.99; osc[i].acc=-k*2*(osc[i].loc-osc[i].bloc); if(i!=0){ osc[i].acc+=+k*(osc[i-1].loc-osc[i-1].bloc); } if(i!=n-1){ osc[i].acc+=+k*(osc[i+1].loc-osc[i+1].bloc); }
you can see algorithm in action here, click give impulse 6-th oscillator. can see not doesn't generate wave @ generate motion growing total energy (even if added dampening!). doing wrong?
all given answers provide (great) deal of useful information. must is:
- use ja72´s observation performing updates - need coherent , compute acceleration @ node based on positions same iteration batch (i.e. not mix $x⁽k⁾$ , $x⁽k+1⁾$ in same expression of acceleration these amounts belonging different iteration steps)
- forget original positions tom10 said - need consider relative positions - behaviour of wave equation laplacian smoothing filter applied polygonal line - point relaxed using 2 directly connected neighbours, being pulled towards middle of segment determined neighbours
- finally, if want energy conserved (i.e. not have water surface stop vibrating), it's worth using symplectic integrator. symplectic/semi-implicit euler do. don't need higher order integrators kind of simulation, if have time, consider using verlet or ruth-forest they're both symplectic , of order 2 or 3 in terms of accuracy. runge-kutta will, implicit euler, draw energy (much slower) system, you'll inherent damping. explicit euler spell doom - that's bad choice - (esp stiff or undamped systems). there tons of other integrators out there, go ahead , experiment.
p.s. did not implement true implicit euler since 1 requires simultaneously affecting particles. that, must use projected conjugate gradient method, derive jacobians , solve sparse linear systems string of particles. explicit or semi-implicit methods "follow leader" behaviour expect animation.
now, if want more, implemented , tested answer in scilab (too lazy program in c++):
n=50; i=1:n x(i) = 1; end dt = 0.02; k = 0.05; x(20) = 1.1; xold = x; v = 0 * x; plot(x, 'r'); plot(x*0,'r'); iteration=1:10000 = 1:n if (i>1 & < n) acc = k*(0.5*(xold(i-1) + xold(i+1)) - xold(i)); v(i) = v(i) + dt * acc; x(i) = xold(i) + v(i) *dt; end end if (iteration/500 == round(iteration / 500) ) plot(x - iteration/10000,'g'); end xold = x; end plot(x,'b');
the wave evolution seen in stacked graphs below:
Comments
Post a Comment