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.

Setting The Potential

In our scheme we provide a potential function to populate a data array then provide that data to the FDTD code. 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.
   *
   * @returns {Array<Number>} The data array populated with potential values data[i]=V(i*length/xResolution).
   */
  function setPotential(length, xResolution, vLeft, vWidth) {
    const potentialData = [];
    let x;

    for (let i = 0; i <; xResolution; ++i) {
      x = (length * i) / xResolution;
      if (x >= vLeft && x <= vLeft + vWidth) {
        potentialData[i] = 0;
      }
      else {
        // We can't do much larger than this w/o trouble on GPUs
        potentialData[i] = 1.0E+5;
      }
    }
    return potentialData;
  }
      

setPotential populates an array with our potential values. We will need to pack this into a Float32Array, which is the native data type for a 32 bit floating point number, before providing it to the FDTD shader.


  const potentialData = setPotential(length, xResolution, vLeft, vWidth);
            

The parameters buffer always has room for the potential.


  parametersBuffer = device.createBuffer({
    label: "Parameters buffer",
    mappedAtCreation: true,
    size: Float32Array.BYTES_PER_ELEMENT                // dt
          + Uint32Array.BYTES_PER_ELEMENT               // xResolution
          + Float32Array.BYTES_PER_ELEMENT              // length
          + xResolution*Float32Array.BYTES_PER_ELEMENT, // potential
      usage:  debug ? GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC : GPUBufferUsage.STORAGE
            // How we use this buffer, in the debug case we copy it to another buffer for reading
    });
            

We only set the potential if it is provided.


    // Get the raw array buffer for the mapped GPU buffer
    const parametersArrayBuffer = parametersBuffer.getMappedRange();

    let bytesSoFar = 0;
    new Float32Array(parametersArrayBuffer, bytesSoFar, 1).set([dt]);
    bytesSoFar += Float32Array.BYTES_PER_ELEMENT;
    new Uint32Array(parametersArrayBuffer, bytesSoFar, 1).set([xResolution]);
    bytesSoFar += Uint32Array.BYTES_PER_ELEMENT;
    new Float32Array(parametersArrayBuffer, bytesSoFar, 1).set([length]);
    bytesSoFar += Float32Array.BYTES_PER_ELEMENT;
    if (potential) {
      new Float32Array(parametersArrayBuffer, bytesSoFar, xResolution).set(potential);
    }
            

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.