The Korteweg-de Vries equation is the non-linear PDE
u_{t} + u_{xxx} + 6uu_{x} = 0. It allows soliton solutions – solitary waves that do not lose their shape, the
non-linearity of the equation somehow perfectly offsetting the dispersion – which are appropriately-scaled sech^{2} functions.

The JavaScript on this page numerically solves the KdV equation with the split-step FFT method, following the very handy page on Wikiwaves, written by Michael Meylan. For the Fourier transforms I have used Nick Jones' jsfft.

The calculation is a pretty heavy one, and on my phone the controls become quite unresponsive (it takes a few seconds to register when I tap 'Pause',
but it does eventually halt the calculation). Choices below the plot for the initial values of u are a single soliton (default); two solitons, which
collide and show a phase shift; and a couple of non-soliton waves – one a sech^{2} function of the wrong height-to-width ratio, and
a sine wave that roughly approximates the single soliton choice, but which immediately breaks apart. I find the top-down view the most rewarding.

The calculation will start when you click the appropriate phrase below the plot.

Mouse controls: Left-click and drag to rotate; alt (Mac)- or ctrl (Windows)-click-drag or middle-click-drag to pan; scroll or shift-click-drag to zoom. Touch screen controls: one finger to rotate; two-finger scroll to pan; pinch to zoom. Click/tap on the cube icons to snap to a side-on view.

Initial state: Start calculation.

Reset.

You can see how the plot is constructed in the HTML source:

- The basic idea is to initialise
`params.data.z`

to have values of zero in the row/column corresponding to t=0, and null values elsewhere. This is done in`init_plot()`

, which also sets the axes (time goes to the x-axis, x goes to the y-axis, fun). - The position axis for the PDE (y-axis in the plot) has its axis reversed compared to what I want from t-x-u axes, so I use
`params.y_scale_bounds = [10.5, -10.5];`

to have it the right way round. - Immediately after initialising,
`init_wave()`

reads what sort of initial wave form is chosen, fills in a`complex_array.ComplexArray`

called`kdv_u`

(global variable) and then calls`three_d.set_surface_point_z()`

to fill in the correct initial values at t=0. - The calculation starts by calling
`integrate_system()`

, which then gets repeatedly called in`requestAnimationFrame()`

. First it calls`step_forward()`

, asking for 3000 time steps, to update`kdv_u`

. Then the values of`kdv_u`

are copied into the next row of the plot, via`three_d.set_surface_point_z()`

. - The grid is too fine for the mesh to look nice at the standard zoom, so it is hidden as soon as the calculation starts with
`three_d.hide_mesh()`

. The mesh needs to be shown before the calculation starts, though, so that the initial wave can be seen. (Surfaces of zero width are never drawn.)

*Posted 2016-12-22.*

Home > three_d.js > Examples