/** * This operation returns the value of the squared modulus of the specular reflectivity for a * single wave vector Q. * * @param waveVectorQ the value of the wave vector * @param wavelength the wavelength of the incident neutrons * @param tiles the list of Tiles that contains the physical parameters needed for the * calculation, including the scattering densities, absorption parameters and thicknesses. * @return the squared modulus of the specular reflectivity */ public double getModSqrdSpecRef(double waveVectorQ, double wavelength, Tile[] tiles) { double modSqrdSpecRef = 0.0; if (wavelength > 0.0) { // Variables only needed if we are going to do the work, i.e. - // wavelength > 0.0. Tile tile; Complex aNm1Sq, fNm1N, rNm1N = new Complex(0.0, 0.0), one = new Complex(1.0, 0.0), qN = new Complex(0.0, 0.0), rNNp1 = new Complex(0.0, 0.0); // Get the bottom tile int nLayers = tiles.length; tile = tiles[nLayers - 1]; // Starting point--no reflected beam in bottom-most (bulk) layer double qCSq = 16.0 * Math.PI * tile.scatteringLength; double muLAbs = tile.trueAbsLength; double mulInc = tile.incAbsLength; double thickness = tile.thickness; // Setup other values for the problem double betaNm1 = 4.0 * Math.PI * (muLAbs + mulInc / wavelength); Complex qNm1 = new Complex(waveVectorQ * waveVectorQ - qCSq, -2.0 * betaNm1); qNm1 = qNm1.sqrt(); // Loop through to calculate recursion formula described in Parratt. // Start at the bottom and work up. for (int i = nLayers - 1; i > 0; i--) { // Get the tile above tile[i] (started at the bottom tile = tiles[i - 1]; // Calculate the normal component of Q for layer and layer-1 qN = qNm1; qCSq = 16.0 * Math.PI * tile.scatteringLength; muLAbs = tile.trueAbsLength; mulInc = tile.incAbsLength; thickness = tile.thickness; betaNm1 = 4.0 * Math.PI * (muLAbs + mulInc / wavelength); qNm1 = new Complex(waveVectorQ * waveVectorQ - qCSq, -2.0 * betaNm1); qNm1 = qNm1.sqrt(); // Calculate phase factor, e^(-0.5*d*qNm1) aNm1Sq = (new Complex(qNm1.getImaginary(), qNm1.getReal()).multiply(-0.5 * thickness)).exp(); // CDiv(qNm1-qN,qNm1+qN) fNm1N = qNm1.subtract(qN).divide(qNm1.add(qN)); // Calculate the reflectivity amplitude. // CMult(aNm1Sq, CMult(aNm1Sq, CDiv(CAdd(rNNp1, fNm1N), // CAdd(CMult(rNNp1, fNm1N), CReal(1))))) Complex y = rNNp1.multiply(fNm1N).add(one); Complex z = rNNp1.add(fNm1N); rNm1N = aNm1Sq.multiply(aNm1Sq).multiply(z.divide((y))); // Carry over to the next iteration rNNp1 = rNm1N; } modSqrdSpecRef = rNm1N.getReal() * rNm1N.getReal() + rNm1N.getImaginary() * rNm1N.getImaginary(); } return modSqrdSpecRef; }