DaycentStrata.java [src/java/d/soils] Revision: default Date:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package d.soils;
import csip.api.server.ServiceException;
import data.interpretors.IFCFile;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import soils.Component;
import soils.Horizon;
import soils.MapUnit;
import soils.exceptions.SDMException;
import soils.exceptions.WEPPException;
import soils.exceptions.WEPSException;
/**
*
* @author sidereus
*/
public class DaycentStrata {
private final Map<Double, List<Profile>> strata = new LinkedHashMap<>();
private final List<Double> requiredDepths = new LinkedList();
private Component comp = null;
private double top = 0.0;
private IFCFile ifcFile;
public DaycentStrata(Component comp) {
this.comp = comp;
requiredDepths.add(2.0);
requiredDepths.add(5.0);
requiredDepths.add(10.0);
requiredDepths.add(20.0);
requiredDepths.add(30.0);
requiredDepths.add(45.0);
requiredDepths.add(60.0);
requiredDepths.add(75.0);
requiredDepths.add(90.0);
requiredDepths.add(105.0);
requiredDepths.add(120.0);
requiredDepths.add(150.0);
requiredDepths.add(180.0);
requiredDepths.add(210.0);
// requiredDepths.add(240.0);
}
public DaycentStrata(MapUnit mapunit, Component _comp) throws WEPSException, IOException, WEPPException, ServiceException, SDMException {
if (mapunit.components().size() > 1) {
if (!mapunit.components().containsKey(_comp.cokey())) {
throw new ServiceException("This mapunit does not contain this component cokey.");
}
}
comp = _comp;
requiredDepths.add(2.0);
requiredDepths.add(5.0);
requiredDepths.add(10.0);
requiredDepths.add(20.0);
requiredDepths.add(30.0);
requiredDepths.add(45.0);
requiredDepths.add(60.0);
requiredDepths.add(75.0);
requiredDepths.add(90.0);
requiredDepths.add(105.0);
requiredDepths.add(120.0);
requiredDepths.add(150.0);
requiredDepths.add(180.0);
requiredDepths.add(210.0);
// requiredDepths.add(240.0);
if (comp.usesGenericIFCorSOLValues()) {
//Don't throw these away anymore...set them to use their original layer data.
comp.usesGenericIFCorSOLValues(false);
}
String ifcString = mapunit.toIfc(comp.cokey());
ifcFile = new IFCFile(ifcString);
//Create new horizons array from the IFC information for the comp object and insert them.
LinkedHashMap<String, Horizon> newHorizons = new LinkedHashMap<>();
int beginLayer = 0;
for (int i = 0; i < ifcFile.numberOfSoilLayers; i++) {
Horizon tHorizon = new Horizon();
tHorizon.chkey(String.valueOf(i + 1));
tHorizon.dbthirdbar_r(ifcFile.wetBulkDensity[i]);
tHorizon.hzthk_r(ifcFile.layerThickness[i] / 10);
tHorizon.hzdepb_r(beginLayer + tHorizon.hzthk_r());
tHorizon.hzdept_r(beginLayer);
tHorizon.fieldCapacitySWC(ifcFile.fieldCapacitySWC[i]);
tHorizon.wiltingPointSWC(ifcFile.wiltingPointSWC[i]);
tHorizon.sandtotal_r(ifcFile.fractionSand[i] * 100);
tHorizon.claytotal_r(ifcFile.fractionClay[i] * 100);
tHorizon.om_r(ifcFile.organicMaterial[i] * 100);
tHorizon.ksat_r(ifcFile.saturatedHydraulicConductivity[i] * 1000000); //um/s to cm/s
tHorizon.soilPh(ifcFile.soilpH[i]);
if (checkBulkField(tHorizon)) {
break;
}
newHorizons.put(tHorizon.chkey(), tHorizon);
beginLayer += tHorizon.hzthk_r();
}
comp.setHorizons(newHorizons);
}
public Map<Double, List<Profile>> computeDaycentStrata() {
comp.horizons().values().forEach((horizon) -> {
//if (top == 0.0 & horizon.hzdepb_r() < 2) continue; // skip if initial horizon hzdepb < 2 cm
if (horizon.dbthirdbar_r() >= 0) { //ifcFile.wetBulkDensity value
createDaycentHorizon(requiredDepths, horizon);
}
});
return strata;
}
private boolean checkBulkField(Horizon h) {
double partdens = 2.65;
double porosity = 1.0 - (h.dbthirdbar_r() / partdens);
return porosity - h.fieldCapacitySWC() < 0.0;
}
private void createDaycentHorizon(List<Double> requiredDepths, Horizon horizon) {
if (!requiredDepths.isEmpty()) {
if (horizon.hzdepb_r() <= requiredDepths.get(0)) { // add horizon
addDaycentHorizon(horizon, requiredDepths.get(0), top, horizon.hzdepb_r());
top = horizon.hzdepb_r();
} else if (horizon.hzdepb_r() > requiredDepths.get(0)) {
addDaycentHorizon(horizon, requiredDepths.get(0), top, requiredDepths.get(0));
top = requiredDepths.get(0);
requiredDepths.remove(0);
createDaycentHorizon(requiredDepths, horizon);
}
}
// } else {
// if (horizon.hzdepb_r() > 90.0 & top < 90.0) { // for root algorithm
// double bottom = 90;
// addDaycentHorizon(horizon, bottom, top, bottom);
// top = bottom;
// createDaycentHorizon(requiredDepths, horizon);
// } else {
// addDaycentHorizon(horizon, horizon.hzdepb_r(), top, horizon.hzdepb_r());
// top = horizon.hzdepb_r();
// }
// }
}
private List getLinkedList(double bottomLayer) {
if (strata.containsKey(bottomLayer)) {
return strata.get(bottomLayer);
} else {
return new LinkedList<>();
}
}
private void addDaycentHorizon(Horizon horizon, double depth, double top, double bottom) {
List<Profile> listProf = getLinkedList(depth);
Profile prof = new Profile(top, bottom, horizon);
listProf.add(prof);
strata.put(depth, listProf);
}
}