I call a method EvaluateWaves() at regular intervals to update the Z values. It takes into account preset constants, such as desired wave speed, fluid viscosity, and so on.

Since a disturbance in the middle should result in the same thing happening outward radially in all directions, I was surprised to see the result after an EvaluateWaves() call resulting in some non-symmetrical results:

I am sending the grid to my fragment shader which performs the calculations and writes it out to a texture bound to the framebuffer object. The texture is ping-ponged back and forth at each evaluation.

// We assume the outer edge of fluid surface is fixed. This also makes
// querying neighbours easier since we can assume there always will be
// exactly eight all around it after this, though we don't affect the
// diagonal neighbours...