double[] visc20 = {1.000, 1.013, 1.026, 1.039, 1.053, 1.067, 1.082, 1.097, 1.112, 1.128, 1.144, 1.160, 1.177, 1.195, 1.213, 1.232, 1.251, 1.271, 1.291, 1.312, 1.333, 1.378, 1.426, 1.477, 1.531, 1.589, 1.650, 1.716, 1.786, 1.861, 1.941, 2.120, 2.326, 2.568, 2.849, 3.181, 3.754, 4.044, 4.612, 5.304, 6.150, 7.220, 8.579, 10.28, 12.49, 15.40, 19.30, 24.63, 32.06, 42.69, 58.37, 82.26, 119.9, 181.7, 287.9, 480.6, 853.2, 1628};
int viscLength = visc20.length;
for(int i=0; i<viscLength; i++)visc20[i] *= 1.005;
double[] concnWA = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84};
double[] concnGA = {0, 5, 10, 15.1, 20.1, 25.2, 30.3, 35.4, 40.6, 45.7, 50.9, 56.1, 61.3, 66.5, 71.8, 77.1, 82.4, 87.7, 93.1, 98.4, 103.8, 114.7, 125.6, 136.6, 147.7, 158.9, 170.2, 181.5, 193, 204.5, 216.2, 239.8, 263.8, 288.1, 312.9, 338.1, 363.7, 389.8, 416.2, 443.2, 470.6, 498.4, 526.8, 555.6, 584.9, 614.8, 645.1, 676, 707.4, 739.3, 771.9, 804.9, 838.6, 872.8, 907.6, 943.1, 979.1, 1015.7, 1053, 1090.9, 1129.4, 1168.5, 1208.2};
ArrayMaths amC = new ArrayMaths(concnGA);
double[] zero = {1.7921, 1.5188, 1.3077, 1.1404, 1.0050, 0.8937, 0.8007, 0.7225, 0.6560, 0.5988, 0.5454, 0.5064, 0.4688, 0.4355, 0.4061, 0.3799, 0.3565, 0.3355, 0.3165, 0.2994, 0.2838};
int length0 = zero.length;
double[] twenty = {3.804, 3.154, 2.652, 2.267, 1.960, 1.704, 1.504, 1.331, 1.193, 1.070, 0.970, 0.884, 0.808, 0.742, 0.685, 0.635, 0.590, 0.550};
int length20 = twenty.length;
double[] forty = {14.77, 11.56, 9.794, 7.468, 6.200, 5.187, 4.382, 3.762, 3.249, 2.847, 2.497, 2.219, 1.982, 1.778, 1.608, 1.462, 1.334, 1.221, 1.123, 1.037, 0.960};
int length40 = forty.length;
double[] sixty = {238, 156, 109.8, 74.6, 56.5, 43.86, 33.78, 26.52, 21.28, 17.18, 14.01, 11.67, 9.83, 8.34, 7.15, 6.20, 5.40, 4.73, 4.15, 3.72, 3.34};
int length60 = sixty.length;
double[] temp = new double[length0];
temp[0] = 0;
for(int i=1; i<length60; i++)temp[i] = temp[i-1] + 5.0;
ArrayMaths am0 = new ArrayMaths(zero);
ArrayMaths am20 = new ArrayMaths(twenty);
ArrayMaths am40 = new ArrayMaths(forty);
ArrayMaths am60 = new ArrayMaths(sixty);
ArrayMaths amT = new ArrayMaths(temp);
double[] concn85 = {0.0, 216.2, 470.6, 771.9};
double[] concn100 = {0.0, 470.6, 771.9};
double ret = Double.NaN;
if(gPerL<=771.9){
if(temperature<=85){
int lengthT85 = length20;
int lengthC85 = amC.indexOf(771.9);
double[] temp85 = amT.subarray_as_double(0, length20-1);
double[] conc85 = amC.subarray_as_double(0, lengthC85);
lengthC85++;
double[][] array = new double[lengthT85][lengthC85];
for(int i=0; i<lengthT85; i++){
double[] lvisc = {Math.log(zero[i]), Math.log(twenty[i]), Math.log(forty[i]), Math.log(sixty[i])};
CubicSpline cs = new CubicSpline(concn85, lvisc);
for(int j=0; j<lengthC85; j++){
array[i][j] = cs.interpolate(conc85[j]);
}
}
BiCubicSpline bcs = new BiCubicSpline(temp85, conc85, array);
ret = Math.exp(bcs.interpolate(temperature, gPerL));
}
else{
if(temperature>100.0){
throw new IllegalArgumentException("Temperature, " + temperature + ", out of range");
}
else{
int lengthT100 = length60;
int lengthC100 = amC.indexOf(771.9);
double[] temp100 = amT.subarray_as_double(0, lengthT100-1);
double[] conc100 = amC.subarray_as_double(0, lengthC100);
lengthC100++;
double[][] array = new double[lengthT100][lengthC100];
for(int i=0; i<lengthT100; i++){