Mie Scattering

Quick Start

The science of scattering by particles is very hard. This app, plus the Rayleigh one, provide two idealised cases that at least provide some guidance about the effects of particle sizes and refractive indices.

Here we have a higher (less unrealistic) concentration of particles and see how much scattering there is for any given particle size at our chosen wavelength, λ, and refractive indices of the medium and the particle.

Scattering from surfaces is discussed in the Gloss app.

The app was updated in Nov 2022 with dual plots, provision of the formulae and with the wavelength range increased to the near-IR as that is of increasing interest for solar control.

Mie Scattering

nmedium
nparticle
λ nm
d nm
//One universal basic required here to get things going once loaded
window.onload = function () {
    //restoreDefaultValues(); //Un-comment this if you want to start with defaults
    Main();
};

//Main() is hard wired as THE place to start calculating when inputs change
//It does no calculations itself, it merely sets them up, sends off variables, gets results and, if necessary, plots them.
function Main() {
    //Save settings every time you calculate, so they're always ready on a reload
    saveSettings();

    //Send all the inputs as a structured object
    //If you need to convert to, say, SI units, do it here!
    const inputs = {
        nm: sliders.Slidenm.value,
        np: sliders.Slidenp.value,
        lambda: sliders.Slidelambda.value, //No need to convert to nm
        phi: sliders.Slidephi.value/2, //Because we use their ratio. But we divide by 2 as the input is a diameter
    };

    //Send inputs off to CalcIt where the names are instantly available
    //Get all the resonses as an object, result


    const result = CalcIt(inputs);

    //Set all the text box outputs
    // document.getElementById('phiphi').value = result.phiphi; 
    //Do all relevant plots by calling plotIt - if there's no plot, nothing happens
    //plotIt is part of the app infrastructure in app.new.js
    if (result.plots) {
        for (let i = 0; i < result.plots.length; i++) {
            plotIt(result.plots[i], result.canvas[i]);
        }
    }

    //You might have some other stuff to do here, but for most apps that's it for Main!
}

//Here's the app calculation
function CalcIt({ nm, np,lambda, phi }) {
    let Rad=[], L=[]

    let tmp = 4 * Math.PI * (np / nm - 1) / lambda
    let p = 0, Q = 0
    const LRange= 2000
    const PRange= 2000
    for (i = 1; i <= PRange; i++) {
        p = i * tmp/2
        Q = 2 - 4 / p * Math.sin(p) + 4 / (p * p) * (1 - Math.cos(p))
        Rad.push({x:i, y:Q})
    }
    tmp = 4 * Math.PI * (np / nm - 1) 
    for (i = 400; i <= LRange; i++) {
        p =tmp*phi/i
        Q = 2 - 4 / p * Math.sin(p) + 4 / (p * p) * (1 - Math.cos(p))
        L.push({x:i, y:Q})
    }

    const plotData = [Rad]
    const plotData1 = [L]
    const lineLabels = ["d dependence at chosen wavelength λ"]
    const lineLabels1 = ["λ dependence at chosen particle size d"]
    const myColors = ["blue"]
    const myColors1 = ["orange"]
    const borderWidth = [2]

    //Now set up all the graphing data detail by detail.
    const prmap = {
        plotData: plotData, //An array of 1 or more datasets
        fontSize:20,
        lineLabels: lineLabels, //An array of labels for each dataset
        colors: myColors, //An array of colors for each dataset
        hideLegend: false,
        borderWidth: borderWidth,
        xLabel: 'd&nm', //Label for the x axis, with an & to separate the units
        yLabel: 'Scattering& ', //Label for the y axis, with an & to separate the units
        y2Label: null, //Label for the y2 axis, null if not needed
        yAxisL1R2: [], //Array to say which axis each dataset goes on. Blank=Left=1
        logX: false, //Is the x-axis in log form?
        xTicks: undefined, //We can define a tick function if we're being fancy
        logY: false, //Is the y-axis in log form?
        yTicks: undefined, //We can define a tick function if we're being fancy
        legendPosition: 'top', //Where we want the legend - top, bottom, left, right
        xMinMax: [,], //Set min and max, e.g. [-10,100], leave one or both blank for auto
        yMinMax: [,], //Set min and max, e.g. [-10,100], leave one or both blank for auto
        y2MinMax: [,], //Set min and max, e.g. [-10,100], leave one or both blank for auto
        xSigFigs: 'F0', //These are the sig figs for the Tooltip readout. A wide choice!
        ySigFigs: 'F2', //F for Fixed, P for Precision, E for exponential
    };
    const prmap1 = {
        plotData: plotData1, //An array of 1 or more datasets
        lineLabels: lineLabels1, //An array of labels for each dataset
        colors: myColors1, //An array of colors for each dataset
        hideLegend: false,
        borderWidth: borderWidth,
        xLabel: 'λ&nm', //Label for the x axis, with an & to separate the units
        yLabel: 'Scattering& ', //Label for the y axis, with an & to separate the units
        y2Label: null, //Label for the y2 axis, null if not needed
        yAxisL1R2: [], //Array to say which axis each dataset goes on. Blank=Left=1
        logX: false, //Is the x-axis in log form?
        xTicks: undefined, //We can define a tick function if we're being fancy
        logY: false, //Is the y-axis in log form?
        yTicks: undefined, //We can define a tick function if we're being fancy
        legendPosition: 'top', //Where we want the legend - top, bottom, left, right
        xMinMax: [,], //Set min and max, e.g. [-10,100], leave one or both blank for auto
        yMinMax: [0,], //Set min and max, e.g. [-10,100], leave one or both blank for auto
        y2MinMax: [,], //Set min and max, e.g. [-10,100], leave one or both blank for auto
        xSigFigs: 'F0', //These are the sig figs for the Tooltip readout. A wide choice!
        ySigFigs: 'F2', //F for Fixed, P for Precision, E for exponential
    };

    //Now we return everything - text boxes, plot and the name of the canvas, which is 'canvas' for a single plot
    return {
        plots: [prmap, prmap1],
        canvas: ['canvas', 'canvas1'],
    };
}
    

The scattering from features of typical dimension d at wavelength λ can be approximated by Mie theory. The scattering depends on the refractive index, nparticle compared to that of the medium nmedium.

Although Mie theory is complex, the van den Hulst approximation does an adequate job. We first calculate a value, p, depending on the refractive indice ratio between the particles and the medium and on the ratio of particle size, d, to wavelength λ:

`p=4π(n_"particle"/n_"medium"-1)d/(2λ)`

Then the scattering, Q, is given by:

`Q=2-(4/p)sin(p)+(4/p^2)(1-cos(p))`

Now we can plot the data at a fixed λ with varying particle size d, or at a fixed d with varying λ.

What does Q mean and what are its units? Because of the approximations involved, just take the results as some sort of relative values, varying from small to large amounts of scattering.