A Particle In A Box

The infinite square well potential, also known as a particle in a box, is a well understood system whose behavior can be explored in interesting ways with numerical simulations. It also provides a good test of the simulation.

We define our box with a potential that is infinite everywhere except for a small section. A wave function reflects completely from the infinite potential, and so is confined to the area where V = 0 .

V ( x ) = { x < 2.0 0 2.0 x 4.0 x > 4.0

We start with a Gaussian wave packet, representing a localized particle, at the center of the potential well. The wave packet bounces back and forth between the sides of the box. The magnitude of the wave function, | Ψ x t | 2 , in green, shows shifting peaks and valleys as the wave function spreads out and interferes with itself.

Particle in a box.

The Potential

In our scheme we provide a potential function to populate a data array then load the data into a texture. Our new potential function needs to know about the physical distance along the grid. Also, rather than an infinite potential we use a value large enough to produce to total reflections that we need, but not so large as to produce numerical issues for the GPU.


  /**
   * Populate the potential array with a large (effectively infinite) potential
   * for x < vLeft and x > vLeft + vWidth, and a zero potential for
   * vLeft ≤ x ≤ vLeft+vWidth.
   *
   * @param {Number}   length      The physical length of the simulation.
   * @param {Number}   xResolution The number of grid elements in the x direction.
   * @param {Number}   vLeft       The position of the left edge of the potential well.
   * @param {Number}   vWidth      The length of the potential well.
   * @param {Number[]} data        The values for the potential.
   *
   * @returns {Number[]} The data array populated with potential values data[i]=psi(i*length/xResolution).
   */
  function squareWellPotential(length, xResolution, vLeft, vWidth, data) {
    var nelements;
    var x;

    nelements = data.length/4;

    for(var i=0; i<nelements; ++i) {
      x = (length*i)/xResolution;
      if (x >= vLeft && x <= vLeft+vWidth) {
        data[4*i] = 0;
      } else {
        data[4*i] = 30000.0;
      }
    }
    return data;
  }
      

Remember that we store this data in a Float32Array, which is the native data type for loading into a floating point texture with RGB&A components for each pixel. The squareWellPotential that we just created populates the array. Then we create a texture and load the data with a gpgpUtility method we created early on.


  var potentialData, potentialTexture;

  potentialData        = new Float32Array(4*xResolution);
  potentialData        = squareWellPotential(length, xResolution, vLeft, vWidth, potentialData);
  potentialTexture     = gpgpUtility.makeTexture(WebGLRenderingContext.FLOAT, potentialData);
      

This gives some inkling of the flexibility and power of this approach. Next up we will carry this much further and much greater flexibility in specifying the initial wave function how to integrate the simulation with HTML controls.

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.