Young-Laplace

Quick Start

You have a drop of fluid A in fluid B. Thanks to a difference in densities, the drop will deform under gravity, resisted by the intefacial tension. The Young-Laplace equation describes that balance. From an image of the drop and a bit of fitting, you can work out the IFT.

Credits

The Osaka U team led by Masashi Nakamotoa provided the core papers1,2 that inspired the app.

Young-Laplace

Fit h mm
Known Δρ g/cc
Fit: b mm
Fit: σ mN/m
Image Width mm
Threshold
Vol μl
Half-width mm
 Original image
 Magnify for h & b
±X mm
±Y mm
'use strict'
//One universal basic required here to get things going once loaded
let image,edge,edgemin,edgemax,imgWidth, context, imageData,oldImageData

window.onload = function () {
    //restoreDefaultValues(); //Un-comment this if you want to start with defaults
    document.getElementById('Load').addEventListener('click', clearOldName, false);
    document.getElementById('Load').addEventListener('change', handleFileSelect, false);

    loadAndDrawImage("img/Test.png")
    Main();
};
//Any global variables go here


//Main is hard wired as THE place to start calculating when input changes
//It does no calculations itself, it merely sets them up, sends off variables, gets results and, if necessary, plots them.
function Main() {
    saveSettings();

    //Send all the inputs as a structured object
    //If you need to convert to, say, SI units, do it here!
    const inputs = {
        h: sliders.Slideh.value / 1e3,
        b: sliders.Slideb.value / 1e3,
        delta: sliders.Slidedelta.value * 1e3,
        sigma: sliders.Slidesigma.value / 1e3,
        mm: sliders.Slidemm.value,
        Xrange: sliders.SlideXrange.value,
        Yrange: sliders.SlideYrange.value,
    }

    //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('Volume').value = result.Volume
    document.getElementById('Width').value = result.Width

    //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 CalcIt!
}

//Here's the app calculation
//The inputs are just the names provided - their order in the curly brackets is unimportant!
//By convention the input values are provided with the correct units within Main
function CalcIt({ h, b, delta, sigma,mm,Xrange,Yrange }) {
    if (oldImageData!=null) DoStuff()
    let tmp = [], DPlot = [],EPlot=[], z = h, x = 0, phi = 0, Volume = 0,  R = 2 * b, dz = 0
    const phiinc = 0.001,pi = Math.PI, g = 9.81, dgs = delta * g / sigma
    let maxWidth = 0
    for (phi = 0; phi < pi; phi += phiinc) {
        tmp.push({ x: x * 1e3, y: -z * 1e3 })
        x += R * Math.cos(phi) * phiinc
        maxWidth = Math.max(x, maxWidth)
        dz = R * Math.sin(phi) * phiinc
        z -= dz
        R = 1 / (dgs * (h - z) + 2 / b - Math.sin(phi) / x)
        Volume += pi * dz * x * x
        if (z < 0) break
    }
    const tl = tmp.length - 1
    for (let i = 0; i <= tl; i++) {
        DPlot.push({ x: -tmp[tl - i].x, y: tmp[tl - i].y })
    }
    for (let i = 0; i < tmp.length; i++) {
        DPlot.push({ x: tmp[i].x, y: tmp[i].y })
    }
    //Now plot the edge, suitable scales/centered
    if (edge){
        const mmW=mm/imgWidth
        const correction=mm/2+(edgemin*mmW-edgemax*mmW)/2
    for (let i=0; i threshold) {
                data[pos] = 255; data[pos + 1] = 255; data[pos + 2] = 255
            }
            else {
                data[pos] = 0; data[pos + 1] = 0; data[pos + 2] = 0
            }
        }
    }
    edge=[], edgemin=xSize;edgemax=0
    for (y = 1; y < ySize - 1; y++) {
        for (x = 1; x < xSize - 1; x++) {
            pos = (y * xSize + x) * 4;
            if (data[pos - 4] > data[pos] + 127) {
                edge.push({x:x,y:y})
                edgemin=Math.min(edgemin,x)
                break
            }
        }
    }
    for (y = ySize-1; y > 0; y--) {
        for (x = xSize - 1; x >0 ; x--) {
            pos = (y * xSize + x) * 4;
            if (data[pos ] > data[pos-4] + 127) {
                edge.push({x:x,y:y})
                edgemax=Math.max(edgemax,x)
                break
            }
        }
    }
    edgemax=xSize-edgemax
   if (! document.getElementById("Original").checked) context.putImageData(imageData, 0, 0)

}
function clearOldName() { //This is needed because otherwise you can't re-load the same file name!
    document.getElementById('Load').value = ""
}
function handleFileSelect(evt) {
    var f = evt.target.files[0];
    if (f) {
        if (f.type !== '' && !f.type.match('image.*')) {
            return;
        }
        // The URL API is vendor prefixed in Chrome
        window.URL = window.URL || window.webkitURL;
    
        // Create a data URL from the image file
        var imageURL = window.URL.createObjectURL(f);
    
        loadAndDrawImage(imageURL);
       }
}
        

The Floating Drop method

The cited papers suggested a "Quick IFT" method where you just placed a drop of oil on water or water on oil, took an image, and fitted the shape to Young-Laplace.

The default image on loading shows a drop of oil onto a surfactant solution, yielding an IFT around 5 mN/m. If you deselect "Original image" you see the image thresholded (using your chosen Threshold value), from which the drop shape is derived and plotted.

You need to input two pieces of real data:

  • Δρ: The density difference between drop and main liquid. The sign shows the direction of the density difference, a negative value means downwards (drop is more dense than the liquid)
  • Image Width: The width of the full image, which defines the scale used to compare calculated to real drop shape

Now there are three fitting parameters:

  • σ: This is the IFT you want to measure
  • h: The height of the drop from interface to lowest point.
  • b: This is the radius of curvature of the drop at its lowest point.

In principle both h and b can be measured from the image, but it's more practical to make them a tunable parameter. This is because images can have many artefacts that can confuse algorithms but not humans (see "What happens at the surface?" later in this text). In any case, Young-Laplace fitting algorithms are notoriously tricky. Via the Magnify option, and tuning the X and Y range for best viewing, you can adjust the h and b values to get a good match for both parameters, meaning that σ is the only truly adjustable parameter for the fit, as this controls the general curvature of the drop.

Young-LaplaceYoung-Laplace

There are 3 interconnected equations governing the shape. They depend on b, h, σ, Δρ and on g, gravity. They relate to the angle φ which is 0 at the bottom of the drop and increases as you go upwards. The x-axis is horizontal and z is vertical. The radius of curvature at each point is R, with R=b at the lowest point. We then have:

  • `(δx)/(δφ)=Rcosφ`
  • `(δz)/(δφ)=Rsinφ`
  • `1/R=(Δρg)/σ (h-z)+2/b-(sinφ)/x`

There is no analytical solution to this, so you just start at the bottom and step through small increments in φ. The numerics can explode when your settings don't match potential realities, so don't be alarmed by strange results.

Getting a good image

The technique for going from image to outline for you to fit is rudimentary - it depends on your threshold value. There are many more sophisticated image analysis techniques which might make shape extraction more accurate in the case of poorer-quality images. But experience shows that there's no substitute for a good original image. So pour your energies into a setup that is at the same time simple and reliable - and where the mm width of the image is a known constant. That's a lot of work, but it will pay off in terms of ease of measurement across multiple samples.

What happens at the surface?

Getting a good image of the basic shape is hard. At the interface between air and liquid, optical and physical effects combine to make it hard to have a meaningful combination of image and fit, so focus on the main shape (fit h and b as a priority) without worrying too much about a perfect fit at the top of the drop. Delightful concepts such as Neumann's Triangle might give you some small theoretical improvements at the expense of much extra work. So keep it simple.

Beyond the floating drop method

Young-Laplace applies to pendant drops from syringes and to bubbles in liquids. As long as you can define where the interesting stuff starts, so you can define h, the analysis should work just fine. However, sliders that cover the likely range of the floating drop method are ill-suited to gas bubbles. Maybe a separate Bubble-Young-Laplace will be needed.

1Masashi Nakamoto, Toshihiro Tanaka, Takaiku Yamamoto, Measurement of interfacial tension between oil and an aqueous solution via a floating drop method, Colloids and Surfaces A 529 (2017) 985–989

2Masashi Nakamoto, Yuko Kasai, Toshihiro Tanaka, Takaiku Yamamoto, Measurement of liquid/liquid interfacial tension with water on liquid paraffin by the floating drop method, Colloids and Surfaces A 603 (2020) 125250