Source: sketch.js

/*******************************************************************************
 *
 *	@file sketch.js Calculate the energy levels of a cooper pair box Quantum Bit (Qubit)
 *
 *	@author Omar Essilfie-Quaye <omareq08+githubio@gmail.com>
 *	@version 1.0
 *	@date 25-May-2022
 *	@link https://omareq.github.io/Cooper-Pair-Box/
 *	@link https://omareq.github.io/Cooper-Pair-Box/docs/
 *
 *****************************************************************************/

/**
 * Handler for the chart js canvas context.
 *
 * @type       {Chart}
 */
 let energyScatterChart;

/**
 * The charging energy set by the slider in the control panel.
 *
 * @type       {number}
 */
 let setChargingEnergy = 70;

 /**
 * Handler for the charging energy slider.
 *
 * @type       {p5.element}
 */
let chargingEnergySlider = undefined;

/**
 * Handler for the paragraphs that displays the current charging energy.
 *
 * @type       {p5.element}
 */
let chargingEnergyDisplay = undefined;

/**
 * The tunnelling energy set by the slider in the control panel.
 *
 * @type       {number}
 */
let setTunnellingEnergy = 20;

/**
 * Handler for the tunnelling energy slider.
 *
 * @type       {p5.element}
 */
let tunnellingEnergySlider = undefined;

/**
 * Handler for the paragraphs that displays the current tunnelling energy.
 *
 * @type       {p5.element}
 */
let tunnellingEnergyisplay = undefined;

/**
 * Function to setup chart js canvases to plot the energy levels of the cooper
 * pair box.
 */
function chartSetup() {
    let ctx = document.getElementById('EnergyChart');
    energyScatterChart = new Chart(ctx, {
        type: 'line',
        data: {
            datasets: [
                {
                    label: '|0>',
                    data: [],
                    pointRadius: 0,
                    backgroundColor: 'rgba(255, 0, 0, 0.2)',
                    borderColor: 'rgba(255, 0, 0, 0.65)',
                    fill: false
                },
                {
                    label: '|1>',
                    data: [],
                    pointRadius: 0,
                    backgroundColor: 'rgba(0, 255, 0, 0.2)',
                    borderColor: 'rgba(0, 255, 0, 0.65)',
                    fill: false
                },
                {
                    label: '|2>',
                    data: [],
                    pointRadius: 0,
                    backgroundColor: 'rgba(0, 0, 255, 0.2)',
                    borderColor: 'rgba(0, 0, 255, 0.65)',
                    fill: false,
                    hidden: true
                },
                {
                    label: '|3>',
                    data: [],
                    pointRadius: 0,
                    backgroundColor: 'rgba(255, 0, 255, 0.2)',
                    borderColor: 'rgba(255, 0, 255, 0.65)',
                    fill: false,
                    hidden: true
                },
                {
                    label: '|4>',
                    data: [],
                    pointRadius: 0,
                    backgroundColor: 'rgba(0, 255, 255, 0.2)',
                    borderColor: 'rgba(0, 255, 255, 0.65)',
                    fill: false,
                    hidden: true
                }
            ]
        },
        options: {
            aspectRatio:1.5,
            animation: {
                duration: 500 // general animation time
            },
            elements: {
                line: {
                    tension: 0 // disables bezier curves float value 0 to 1
                }
            },
            scales: {
                xAxes: [{
                    type: 'linear',
                    position: 'bottom',
                    scaleLabel: {
                        display: true,
                        labelString: 'Gate Induced Charge'
                      }
                }],
                yAxes: [{
                    // min: -10,
                    // max: 100,
                    scaleLabel: {
                        display: true,
                        labelString: 'Energy'
                    },
                    tooltips: {
                        mode: 'x'
                    }
                }]
            },
            title: {
                display: true,
                text: 'Energy Levels Ec:' + setChargingEnergy
                    + " Ej: " + setTunnellingEnergy
            }
            // showLines: false // disable for all datasets
        }
    });
}

/**
 * Function to plot the energy levels of the cooper pair box.
 */
function chartUpdate() {
    let numEigenVals = 5;
    let x = [];
    let xMin = 0;
    let xMax = 1.2 * numEigenVals;
    let num_elements = 30 * numEigenVals;
    let itt = (xMax - xMin) / num_elements;
    let eigValues = [];
    let i = 0;

    energyScatterChart.options.title.text = 'Energy Levels Ec:' +
        setChargingEnergy +
        " Ej: " + setTunnellingEnergy;

    energyScatterChart.data.datasets[0].data = [];
    energyScatterChart.data.datasets[1].data = [];
    energyScatterChart.data.datasets[2].data = [];
    energyScatterChart.data.datasets[3].data = [];
    energyScatterChart.data.datasets[4].data = [];

    for(let n = xMin; n < xMax; n += itt) {
        let h = hamiltonian(setChargingEnergy,
            setTunnellingEnergy,
            n,
            numEigenVals);

        let ans = math.eigs(h);
        let eig = ans.values;
        let vec = ans.vectors;
        eigValues.push(eig);
        energyScatterChart.data.datasets[0].data.push({
            x:n,
            y:eigValues[i].get([0])
        });
        energyScatterChart.data.datasets[1].data.push({
            x:n,
            y:eigValues[i].get([1])
        });
        energyScatterChart.data.datasets[2].data.push({
            x:n,
            y:eigValues[i].get([2])
        });
        energyScatterChart.data.datasets[3].data.push({
            x:n,
            y:eigValues[i].get([3])
        });
        energyScatterChart.data.datasets[4].data.push({
            x:n,
            y:eigValues[i].get([4])
        });
        i++;
    }
    energyScatterChart.update(0);
    return eigValues;
}

/**
 * Function to calculate the Hamiltonian matrix for a cooper pair box qubit with
 * a given charging energy and tunnelling energy
 *
 * @param      {number}  charging_energy   The charging energy - The energy
 * reuired to either add or subtract a cooper pair from the system
 * @param      {number}  tunnelling_energy  The tunnelling energy - The energy
 * required for a cooper pair to transition form one energy level to another.
 * @param      {number}  [n=0]             The gate induced charge for the
 * cooper pair box.
 * @param      {number}  [states=5]        The number of states the cooper pair
 * box can take.
 * @return     {Array | Matrix}  The Hamiltonian matrix
 */
function hamiltonian(charging_energy, tunnelling_energy, n=0, states=5) {
    ec = charging_energy;
    ej = tunnelling_energy;
    matrix = [];

    for(let y = 0; y < states; y++) {
        row = [];
        for(let x = 0; x < states; x++) {
            if(x ==y) {
                row.push(ec * pow(states - x - n, 2));
            } else if (x == (y + 1) || y == (x + 1)) {
                row.push(-0.5 * ej);
            } else {
                row.push(0);
            }
        }
        matrix.push(row);
    }
    return math.matrix(matrix);
}

/**
 * p5.js setup function, creates canvas.
 */
function setup() {
	let cnvSize;
	if(windowWidth > windowHeight) {
		cnvSize = windowHeight;
	} else {
		cnvSize = windowWidth;
	}
	let cnv = createCanvas(0,0);//cnvSize, 0.7 * cnvSize);
	cnv.parent('sketch');

    chargingEnergyDisplay = createP("Charging Energy (Ec): " +
        str(setChargingEnergy));
    chargingEnergyDisplay.parent("charging-energy-val");

    chargingEnergySlider = createSlider(5, 1000, setChargingEnergy, 5);
    chargingEnergySlider.parent("charging-energy");

    tunnellingEnergyDisplay = createP("Tunnelling Energy (Ej): " +
        str(setTunnellingEnergy));
    tunnellingEnergyDisplay.parent("tunnelling-energy-val");

    tunnellingEnergySlider = createSlider(0, 1000, setTunnellingEnergy, 5);
    tunnellingEnergySlider.parent("tunnelling-energy");

    chartSetup();
    chartUpdate();
}

/**
 * p5.js draw function, is run every frame to create the desired animation
 */
function draw() {
	background(0);

    let sliderVal = chargingEnergySlider.value();
    if(sliderVal != setChargingEnergy && sliderVal > setTunnellingEnergy) {
        setChargingEnergy = sliderVal;
        chargingEnergyDisplay.elt.innerText = "Charging Energy (Ec): " +
            str(setChargingEnergy);
        chartUpdate();
    }

    sliderVal = tunnellingEnergySlider.value();
    if(sliderVal != setTunnellingEnergy && sliderVal < setChargingEnergy) {
        setTunnellingEnergy = sliderVal;
        tunnellingEnergyDisplay.elt.innerText = "Tunnelling (Ej): " +
            str(setTunnellingEnergy);
        chartUpdate();
    }

}


Documentation generated by JSDoc 3.6.3 on Sat Jun 11 2022 21:25:48 GMT+0100 (BST)