Moisture Sorption
Quick Start
We need to know how much moisture a food powder such as starch, a dried beverage or a sugar absorbs at a given water activity aw. This dependency is described via a water sorption isotherm, conveniently fitted to the GAB (Guggenheim-Anderson-de Boer) model. The amount absorbed affects the glass transition temperature Tg, which in turn affects whether the powder will stick together as calculated via the Powders-Moisture app.
Credits
These food science apps are produced in conjunction with expert Prof Emmanuel Purlis, CONICET, Argentina. This app is the first part of a chain of logic1 from a Nestlé & U Sheffield team.
Sorption Isotherms
//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();
};
//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 = {
M: sliders.SlideM.value,
C: sliders.SlideC.value,
K: sliders.SlideK.value,
RH: sliders.SlideRH.value,
}
//Get all the resonses as a structure
const result = CalcIt(inputs)
//Set all the text box outputs
document.getElementById('PercW').value = result.PercW
if (result.plots) {
for (let i = 0; i < result.plots.length; i++) {
plotIt(result.plots[i], result.canvas[i]);
}
}
}
//Here's the real app calculation
function CalcIt({ M,C,K,RH }) {
//The structure automatically has the names provided from input
//By convention the values are provided with the correct units within CalcIt
let GotRH=false,PercW=0,WPts=[]
for (let i = 0; i <= 95; i++) {
aw=i/100
M1=100*M*C*K*aw/((1-K)*(1-K*aw+C*K*aw))
WPts.push({x:aw*100,y:M1})
if (i>=RH && ! GotRH){
GotRH=true
PercW=M1
}
}
//Now we return everything - text boxes, plot and the name of the canvas, which is 'canvas' for a single plot
const prmap = {
plotData: [WPts], //An array of 1 or more datasets
lineLabels: ["%Water"], //An array of labels for each dataset
hideLegend: true,
xLabel: 'a_w& ', //Label for the x axis, with an & to separate the units
yLabel: '%Water& ', //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: 'P3', //These are the sig figs for the Tooltip readout. A wide choice!
ySigFigs: 'P3', //F for Fixed, P for Precision, E for exponential
}
return {
PercW: PercW.toFixed(1),
plots: [prmap],
canvas: ['canvas'],
};
}
A water sorption isotherm shows the volume fraction of water absorbed versus the water activity, aw or, if you prefer, %RH/100. To get these isotherms you need to be able to measure the weight increase as the %RH of the air is changed, allowing enough time for equilibrium to be reached before stepping to the next level. There is often hysteresis (not shown) between the values measured going from 0 to 100% and 100% going down to 0, with the descending isotherm showing more sorption that the ascending one.
The GAB model has three parameters: M which is supposed to what would be expected from a monolayer coverage, typically in the 0.05 to 0.2 range, but with foods we have absorption as well as adsorption, then there's C which is in the 1-50 range, and K which is an adjustment parameter, typically in the 0.5 to 1 range. When K=1 the equation is formally equivalent to the well-known BET isotherm. The GAB model calculates the Sorption, S for a given water activity, aw. Because experimental data and GAB both have problems above 0.95 activity, the graph stops at that point.
`S=(MCKa_w)/((1-Ka_w)(1-Ka_w+CKa_w))`
When you set your actual RH the fraction at that RH is calculated and you can use the value in the Tg-Moisture app.
1Christine I. Haider, Gerhard Niederreiter, Stefan Palzer, Michael J. Hounslow, Agba D. Salman, Unwanted agglomeration of industrial amorphous food powder from a particle perspective, Chem. Eng. Res. & Design, 132, 2018, 1160–1169