WEPSUtils.java [src/soils/utils] Revision: default Date:
/*
* $Id$
*
* This file is part of the Cloud Services Integration Platform (CSIP),
* a Model-as-a-Service framework, API, and application suite.
*
* 2012-2017, OMSLab, Colorado State University.
*
* OMSLab licenses this file to you under the MIT license.
* See the LICENSE file in the project root for more information.
*/
package soils.utils;
/**
*
* @author joelevin
*/
public class WEPSUtils {
// table for settled bulk density as a function of sand (across the top) and clay (down the side)
static final double[][] mbdtv = {
{1.48d, 1.25d, 1.00d, 1.06d, 1.16d, 1.22d, 1.30d, 1.39d, 1.45d, 1.51d, 1.52d},
{1.52d, 1.40d, 1.19d, 1.25d, 1.32d, 1.40d, 1.52d, 1.58d, 1.63d, 1.65d},
{1.52d, 1.40d, 1.25d, 1.35d, 1.45d, 1.53d, 1.60d, 1.64d, 1.72d},
{1.52d, 1.40d, 1.29d, 1.41d, 1.50d, 1.57d, 1.63d, 1.68d},
{1.50d, 1.40d, 1.35d, 1.43d, 1.53d, 1.61d, 1.64d},
{1.46d, 1.40d, 1.40d, 1.43d, 1.53d, 1.62d},
{1.45d, 1.40d, 1.38d, 1.42d, 1.50d},
{1.42d, 1.37d, 1.33d, 1.33d},
{1.33d, 1.32d, 1.20d},
{1.23d, 1.18d},
{1.15d}
};
static final double averageOrganicMatterBulkDensity = 0.224d;
/**
*
* @param clay
* @param sand
* @return
*/
public static double estimateMineralBulkDensity(double clay, double sand) {
//The fractions can't sum to more than 1.0d.
double sum = sand + clay;
if (sum > 1.0d) {
sand /= sum;
clay /= sum;
//System.out.println("essbd: sand plus clay fractions greater than 1.0."+
//" Values adjusted by averaging the difference.");
}
/* li = index into table less than clay content
* lj = index into table less than sand content
* hi = index into table greater than clay content
* hj = index into table greater than sand content
* mi = value between indexes for the interpolation of clay
* mj = value between indexes for the interpolation of sand
* fi = fraction of distance between grid cells for clay
* fj = fraction of distance between grid cells for sand
* mbd = mineral mulk density
* mbd_hi_hj = value for mbdtv[hi][hj] if outside triangular part of table it is reflected
from mbdtv[li][lj] otherwise it is just the real point
*/
double mi = clay * 10.0d;
int li = (int) mi;
double fi = mi - li;
int hi = Math.min(li + 1, 10);
double mj = sand * 10.0d;
int lj = (int) mj;
double fj = mj - lj;
int hj = Math.min(lj + 1, 10);
double mbd, mbd_hi_hj;
if (li + lj == 10) {
//On table edge, no interpolation necessary
mbd = mbdtv[li][lj];
} else {
if (hi + hj > 10) {
//Interpolation on the triangular edge of the table
//mirror li, lj value to make using grid interpolation possible
mbd_hi_hj = mbdtv[li][hj] + mbdtv[hi][lj] - mbdtv[li][lj];
} else {
//interpolation within the table, use grid point
mbd_hi_hj = mbdtv[hi][hj];
}
mbd = (1 - fi) * (1 - fj) * mbdtv[li][lj]
+ (1 - fi) * fj * mbdtv[li][hj]
+ fi * (1 - fj) * mbdtv[hi][lj]
+ fi * fj * mbd_hi_hj;
}
return mbd;
}
/**
* The following method estimates settled soil bulk density from intrinsic
* properties. See Rawls (1983) Soil Science 135, 123-125
*
* If the sum of the sand and clay fractions exceed 1.0 then the fractions are
* averaged.
*
* @param clay fraction of soil clay content
* @param sand fraction of soil sand content
* @param om organic matter
* @return settled bulk density
*/
public static double estimateSettledBulkDensity(double clay, double sand, double om) {
//Average om bds gm/cm^3
double mbd = estimateMineralBulkDensity(clay, sand);
return 1.0d / ((om / averageOrganicMatterBulkDensity) + ((1.0d - om) / mbd));
}
/**
*
* @param settledBulkDensity
* @param wetBulkDensity
* @return
*/
public static double estimateLinearExtensibility(double settledBulkDensity, double wetBulkDensity) {
if (wetBulkDensity > settledBulkDensity) {
throw new IllegalArgumentException("Wet bulk density greater than settled bulk density.");
}
return (Math.pow(settledBulkDensity / wetBulkDensity, 1 / 3) - 1) * 100;
}
}