Spray Barriers

Quick Start

Spraying a barrier coating onto a paper or molded-pulp package involves a set of complex interactions. Here we let you see how your parameters can combine to produce bad or, hopefully, good barriers.


The app was inspired by the work of Dr Alexander Bardenstein of the DTI.

Spray Barriers

Drop D μm
Spray Us m/s
Spray gap mm
Viscosity η cP
Surf Ten σ mN/m
Rq μm
Pore d μm
Porosity φ
Contact angle θ
Q cc/s
Area A cm²
Splash Data
Time Data
//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() 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

    //Send all the inputs as a structured object
    //If you need to convert to, say, SI units, do it here!
    const inputs = {
        U: sliders.SlideU.value,
        gap: sliders.Slidegap.value * 1e-3, //mm to m
        D: sliders.SlideD.value * 1e-6, //μm to m
        eta: sliders.Slideeta.value * 1e-3, //cP to Pa.s
        sigma: sliders.Slidesigma.value * 1e-3, //mN/m to N/m
        Rq: sliders.SlideRq.value * 1e-6, //μm to m
        phi: sliders.Slidephi.value,
        d: sliders.Slided.value * 1e-6, //μm to m
        theta: sliders.Slidetheta.value * Math.PI / 180, //deg to radians
        rho: 1000, //Density fixed to 1kg/m3
        Q: sliders.SlideQ.value * 1e-6, //cm3/s to m3/s
        A: sliders.SlideA.value * 1e-4, //cm2 to m2


    //Send inputs off to CalcIt where the names are instantly available
    //Get all the resonses as an object, result
    const result = CalcIt(inputs);
    document.getElementById('Data').value = result.Data;
    document.getElementById('TimeData').value = result.TimeData;

function CalcIt({ U, gap, D, eta, sigma, Rq, phi, d, theta, rho, Q, A }) {
    //Calculate final U from air drag
    //Uses code from Trajectories app
    const AF = 0.1806, BF = 0.6459, CF = 0.4251, DF = 6880.95 //For drag coeff calc
    const rad = D / 2
    const ReP = 2 * rad / 1.8e-5 //Pre-reynolds number - Diameter/Air Viscosity
    const rhoair = 1.2 //kg/m3 of drop then air
    const Area = Math.PI * rad * rad, Afact = Area / 2 * rhoair //Cross sectional area and drag factor
    const m = 4 / 3 * Math.PI * Math.pow(rad, 3) * rho //Mass of the drop
    const dt = 0.00002 //Timestep seems OK
    let PV=gap,VV=U,t=0,Re=0
    while (t < 1 && PV>0){
    Re = Math.max(0.0001, Math.abs(ReP * VV))
    CDv = 24 / Re * (1 + AF * Math.pow(Re, BF)) + CF / (1 + DF / Re)
    FV = -Afact * CDv * VV * VV// + mgv
    dVdt = FV / m * dt
    VV += dVdt
    PV -= VV * dt
    t += dt
    U=VV //Final velocity
    const We = rho * D * U * U / sigma
    Re = rho * D * U / eta
    const Oh = eta / Math.sqrt(rho * sigma * D)
    const r = Rq / D
    const Ohr = Oh / Math.sqrt(r)
    const pl = 4 / 3 * Math.PI * Math.pow(D / 2, 3) * 1e15
    const beta = Math.max(1, 0.1 * Math.pow(We / Oh, 0.3)) //The formula allows β < 1 which isn't helpful
    const Ucrit = 25.6 * (Math.pow(eta * sigma * sigma / Math.pow(rho, 3) / Math.pow(D, 3)), 0.2)
    let pls = pl < 1000 ? pl.toFixed(0) + "pl" : (pl / 1000).toPrecision(3) + "nl"
    if (pl > 1000000) pls = (pl / 1e6).toFixed(1) + "μl"
    let Splash = ""
    if (Ohr > 0.3) {
        let Kc, Kct
        if (Oh < 0.0007) {
            Kc = Re * Math.pow(Oh, 1.3)
            Kct = 3.8 * (1 + 1.6 * Math.pow(r, 0.33))
        } else {
            Kc = Math.max(0.1, (Re - 5 * Math.pow(Re, 0.67)) * Math.pow(Oh, 1.3))
            Kct = 2.4 * (1 + 1.6 * Math.pow(r, 0.33))
        if (Kc > Kct) {
            Splash = "Kc=" + Kc.toFixed(1) + "> Kct=" + Kct.toFixed(1) + " Corona splash"
        } else {
            Splash = "Kc=" + Kc.toFixed(1) + "< Kct=" + Kct.toFixed(1) + "  No splash"

    } else {
        const Kpt = r < 0.0008 ? 63 : 10.3 / Math.pow(r, 0.25) * (1 + 2 * Math.pow(phi, 0.5))
        const Kp = Re * Math.pow(Oh, 0.33)
        if (Kp > Kpt) {
            Splash = "Kp=" + Kp.toFixed(1) + "> Kpt=" + Kpt.toFixed(1) + " Prompt splash"
        } else {
            Splash = "Kp=" + Kp.toFixed(1) + "< Kpt=" + Kpt.toFixed(1) + "  No splash"
    const Ds = D * 1.26 * beta //Spread drop diameter
    let betat = ", β="
    if (Splash.includes("No")) {
        betat += beta.toFixed(2)
        betat += ", Ds=" + (Ds * 1e6).toFixed(0) + "μm"
    } else {
        betat += "-, Ds= -"

    //Now time calcs
    const ti = D / U
    const tc = Math.sqrt(rho * Math.pow(D, 3) / sigma)
    const tv = rho * D * D / eta
    const k = d * d * Math.pow(phi, 3) / (180 * Math.pow(1 - phi, 2))
    const P = 6 * sigma * (1 - phi) * Math.cos(theta) / (phi * d)
    const ta = 0.4 * eta * Math.pow(D, 6) / (phi * k * P * Math.pow(beta * D, 4))
    TimeData = "ti=" + (ti * 1e6).toFixed(0) + "μs, tc=" + (tc * 1e6).toFixed(0) + "μs, tv=" + (tv * 1e6).toFixed(0) + "μs, ta=" + (ta * 1e3).toPrecision(3) + "ms, k=" + k.toExponential(2) + "m², P=" + (P / 1e5).toFixed(2) + "bar"

    //Now Vol calcs
    const DVol = 4 / 3 * Math.PI * Math.pow(D / 2, 3)
    const NDrops = Q / DVol * ta/2 //Half ta so drops are not yet fully absorbed
    const NDensity = NDrops / A
    const DDist = 1 / Math.sqrt(NDensity)
    let VolData = ", Spray Drop-to-Drop=" + (DDist * 1e6).toFixed(0)+"μm"
    if (Splash.includes("No")) {
        if (Ds > DDist) { VolData += ", Joined" } else { VolData += ", Isolated" }

    //Now we return everything - text boxes, plot and the name of the canvas, which is 'canvas' for a single plot
    return {
        Data: "Vol=" + pls + ", Ui=" + U.toPrecision(3) + "m/s, We=" + We.toPrecision(3) + ", Re=" + Re.toFixed(0) + ", Oh=" + Oh.toExponential(2) + ", r=" + r.toExponential(2) + ", Ohr=" + Ohr.toExponential(2) + ", Ucrit=" + Ucrit.toFixed(1) + "m/s" + ", " + Splash + betat,
        TimeData: TimeData + VolData,


Spray barriers

The increase in the use of paper and molded-pulp packaging requires better barriers. Spray coating a barrier is an attractive method, but experience shows that it is easy to produce a poor barrier, for two reasons. First, if the spray splashes on contact it will tend to give a poor-quality barrier. Second, if the drops are absorbed into the fibres faster than they can join up on the surface, the coating is largely ineffective as a barrier. The obvious fix, to make the surface of the paper/pulp less rough and porous, has its own downsides. Often you have to work with what you've got. The app lets you explore a range of spray options, giving you lots of insightful calculated values and some judgements on whether the drops will splash or not, and whether the coating drops are likely to be "joined" and therefore "good".

The calculations are all related to drops hitting a dry surface. The physics of drops on wet surfaces are, in this context, uninteresting as drops are unlikely to splash and the joining process is effectively instantaneous.

The fact that the app has numerous inputs and outputs means that it's complicated. As discussed below, that's a feature, not a bug.

Splashing and Spreading

We have drops of diameter D of a liquid with viscosity η and surface tension σ arriving at a surface with a contact angle θ, RMS roughness Rq, porosity φ and pore radius r, at an impact velocity Ui which is calculated from the spray velocity Us and the air drag across the spray gap. The density, ρ, is here assumed to be 1 g/cc. If it splashes we have a mess. Assuming, via a spreading coefficient β and a factor of 1.26 for spherical to hemispherical drop, it's spread nicely to a diameter `D_s=1.26βD` what then happens depends on the chances of another drop hitting closer than Ds before the drop is absorbed. That aspect is described below.

Both the spreading coefficient, β, and the chance of exceeding the critical splash value, K, increase with U and decrease with η. We want the maximum β without exceeding K. Unfortunately, K can get smaller with rougher surfaces (roughness creates drop instabilities) so something that works on a smoother paper won't work on a rougher pulp package. However, in other cases, roughness can increase stability (it allows air to escape through the roughness).Porosity can further reduce the tendency to splash. Happily, the timescales for spreading/splashing are generally fast compared to the drop soaking into the medium so, to a good approximation, our sorption calculations can remain independent.

Here we distinguish between two types of splashing (prompt & corona). At higher energies there are other effects such as rebounds, but we only need to see if we exceed a splash limit.

You can't approach this issue without dimensionless numbers. Here we use the Weber number, We, the Reynolds number, Re, the Ohnesorge number, Oh and a dimensionless roughness r that is related to the drop size D. There's an extra variant of Ohnesorge that depends on the roughness, Ohr:

`We=(ρDU^2)/σ, Re=(ρDU)/η, Oh=η/sqrt(ρσD), r=R_q/D, Oh_r=(Oh)/sqrt(r)`

If you find equations based on Capillary Number, Ca, or see equations based on different combinations of Re, We and Oh that's because:

`Ca=(We)/(Re), Oh=sqrt(We)/(Re), Re=sqrt(We)/(Oh), We=(ReOh)^2, Oh=sqrt((Ca)/(Re))`

There are numerous attempts at equations for β and K, some of which depend on the surface roughness measure Rpk/Rsm which most of us can't access. A relatively recent paper1 that looks back at these many attempts gives us results for K based on the more tractable Rq, the root-mean-square roughness. There are two thresholds, one for the onset of "prompt" splashing (on generally rougher surfaces, or lower Oh) calculated from Kp, the other for "corona" splashing, Kc. The splashing changes to corona when Ohr>0.3. In each case we calculate the K value from the given equation and compare it to the threshold value (extra subscript t). Remember that although the general forms make some sense, the systems are complex and chosen equations are from fitting. For prompt splashing, a φ0.5 effect (an increase in critical value) noted in a different paper3 has been added. So other datasets might give somewhat different fitting formulae:

`K_p=ReOh^0.33, K_(pt)=10.3/r^0.25(1+2φ^0.5), 63 if r < 0.0008`

Kc has two forms. When Oh < 0.0007:

`K_c=ReOh^1.3, K_(ct)=3.8(1+1.6r^0.33)`

When Oh > 0.0007 then

`K_c=(Re-5Re^0.67)Oh^1.3, K_(ct)=2.4(1+1.6r^0.33)`

A well-known equation4 for smooth, non-porous substrates gives a velocity Ucrit above which splashing takes place. It is added as an extra heuristic:


The β equation is from2 and uses the coefficients found for water-based systems, averaged over a range of roughnesses:


With no spreading, the diameter is `root(3)(2)`=1.26 larger than the original drop because it forms a hemispherical cap. The final spread diameter, assuming we haven't had a splash is then `D_s=1.26βD`.

Other equations for K and β are available but give similar results over the relevant range.


A helpful review by Tan5 gives us an idea of the timescales involved in each process. Although these are generic times, they help us think through the issues of spray drops. We have ti, inertial impact, tc, capillary spreading, tv, viscous damping and ta, absorption (which depends on permeation coefficient k and capillary pressure P), given by:

`t_i=D/U, t_c=sqrt((ρD^3)/σ), t_v=(ρD^2)/η`

`t_a=(0.4ηD^6)/(φkP(βD)^4), k=(d^2φ^3)/(180(1-φ)^2), P=(6σ(1-φ)cos(θ))/(φd)`

A good barrier coating

We deliver our spray with a flow rate Q over an area A. Because we know the volume of each drop we can calculate the number of drops per second. If we use timescale ta/2 we have an absolute number of drops delivered to area A while previous drops remain not fully absorbed, giving us a number density, N. The average distance between drops is 1/`sqrt(N)` and we can compare this distance to Ds. If it is smaller (and if we also don't have splashing) then we know that on average the drops will join up while still wet, given that the time for drop joining is in the range of tc. And that's the purpose of the app - to see if you are likely to get a reasonably even coating.

It's complicated

If spraying onto porous media was simple, we wouldn't need an app. As you slide the sliders, the many calculated parameters change. Because they are inter-related, the changes can be confusing and anti-intuitive. A good example is the drop-to-drop distance. This changes when you change parameters like porosity which have nothing to do with drops arriving from a spray. But we are calculating drops arriving in ta/2, so a more absorbent material gives a smaller ta and, therefore, fewer drops arriving so a larger drop-to-drop distance.

Another example is drop diameter. As you decrease this (a finer spray) everything is fine ... till suddenly it's not. That's because the dependency of Ui on drop size is large for small drops - so Ui can quickly become small and β reduces to 1 so there is no helpful drop spread.

Because real sprays aren't uniform drop sizes and uniform velocities and because the equations are approximations fitted over a relatively small range of experimental data, the app can never be an accurate guide to perfect coatings. Instead it's a way to help you build your intuitions within a complex process. Although the app can't guarantee a successful coating, it will significantly reduce the chances of a failed one.


Haixiang Zhang et al. How surface roughness promotes or suppresses drop splash, Phys. Fluids 34, 022111 (2022).


Chenglong Tang et al, Dynamics of droplet impact on solid surface with different roughness, Int. J. Multiphase Flow 96 (2017) 56–69.


Ilia V. Roisman et al, Drop splashing induced by target roughness and porosity: The size plays no role, Adv. in Colloid and Interface Sci. 222 (2015) 615–621.


Hilton, JE et al, Modelling spray coating using a combined CFD–DEM and spherical harmonic formulation, Chem. Eng. Sci. 99 (2013) 141-160.


Hua Tan, Absorption of Picoliter Droplets by Thin Porous Substrates, AIChE Journal, 2017, 63, 1690-1703.