SolWriter.java [src/java/d/util] 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 d.util;

import d.dataNodes.WEPPData;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import soils.Component;
import soils.Horizon;

/**
 *
 * @author Brad
 */
public class SolWriter {

    // Sol file description
    // Line 1:  version control number (95.7) - real (datver)
    // Line 2:  a) User comment line - character*80, (solcom)
    // Line 3:  a) number of overland flow elements(OFE's) or channels integer (ntemp)
    //          b) flag to to use internal hydraulic conductivity adjustments - integer (ksflag)
    //              0 - do not use adjustments (conductivity will be held constant)
    //              1 - use internal adjustments
    //      Lines 4 & 5 are repeated for the number of OFE's or channels on Line 3a.
    // Line 4:  a) soil name for current OFE or channel - character (slid)
    //          b) soil texture for current OFE or channel - character (texid)
    //          c) number of soil layers for current OFE or channel - integer (nsl)
    //          d) albedo of the bare dry surface soil on the current OFE or channel - real (salb)
    //          e) initial saturation level of the soil profile porosity (m/m) - real (sat)
    //          f) baseline interrill erodibility parameter (kg*s/m4) - real (ki)
    //          g) baseline rill erodibility parameter (s/m) - real (kr)
    //          h) baseline critical shear parameter (N/m2) - real (shcrit)
    //          i) effective hydraulic conductivity of surface soil (mm/h) - real (avke)
    // Line 5: (repeated for the number of soil layers indicated on Line 4c.)
    //          a) depth from soil surface to bottom of soil layer (mm) - real (solthk)
    //          b) percentage of sand in the layer (%) - real (sand)
    //          c) percentage of clay in the layer (%) - real (clay)
    //          d) percentage of organic matter (volume) in the layer (%) - real (orgmat)
    //          e) cation exchange capacity in the layer (meq/100 g of soil) - real (cec)
    //          f) percentage of rock fragments by volume in the layer (%) - real (rfg)
    // Line 6: Bedrock restricting layer info (Most of the soils are not going to have any bedrock layer defined so this line ends up being all 0's)
    //          a) flag to indicate if present
    //          b) type
    //          c) anisotropy ratio
    //          d) ksat
    // May want to break this into methods if it grows
    public String writeSolEx(Component comp, File solFile, int ksflag, WEPPData data, boolean writeFile) throws IOException {
        String ret_val = "";
        ArrayList<String> lines = new ArrayList<>();
        String soil_line;
        String horizon_line;
        String bedrock_line;
        Horizon horizon;
        NumberFormat formatter = new DecimalFormat("0.000000");

        // Line 1:
        lines.add(Double.toString(2006.2));
        //Line 2:
        lines.add("Comments: sol file generated by csip-soils.");

        //Line 3:
        // only one soil is used
        // always use hydraulic conductivity adjustments
        lines.add(1 + " " + 1);

        //Line 4:
        // append some soil info here
        soil_line = "\'" + comp.compname() + "\' ";
        soil_line += "\'" + SoilCalc.getSurfaceTexture(comp) + "\' ";
        soil_line += comp.horizons.size() + " ";
        soil_line += formatter.format(SoilCalc.getSurfaceAlbedo(comp.albedodry_r(), Utils.getSurfaceHorizon(comp).om_r())) + " ";
        soil_line += formatter.format(0.75) + " ";
        soil_line += formatter.format(data.getInterrill()) + " ";
        soil_line += formatter.format(data.getRill()) + " ";
        soil_line += formatter.format(data.getShear()) + " ";
        soil_line += formatter.format(data.getConductivity()) + "";

        lines.add(soil_line);

        //Line 5:
        for (Map.Entry<String, Horizon> horizon_data : comp.horizons.entrySet()) {
            horizon = horizon_data.getValue();

            if (horizon.hzname().length() > 0 && horizon.hzname().charAt(0) == 'R') // It is bedrock and no layer past this is good
            {
                break;
            }
            if (horizon.hzname().length() > 1 && horizon.hzname().charAt(0) == 'C' && horizon.hzname().charAt(1) == 'r') // It is soft bedrock and no layer past this is good
            {
                break;
            }
            horizon_line = "  " + formatter.format(horizon.hzdepb_r() * 10) + " "; // convert from cm to mm
            horizon_line += formatter.format(horizon.sandtotal_r()) + " ";
            horizon_line += formatter.format(horizon.claytotal_r()) + " ";
            horizon_line += formatter.format(horizon.om_r()) + " ";
            horizon_line += formatter.format(horizon.cec7_r()) + " ";
            horizon_line += formatter.format(SoilCalc.getRockFrags(horizon) * 100); // put rock frag here. should be in percent
            lines.add(horizon_line);
        }

        //Line 6:
        // add some bedrock data
        bedrock_line = (int) data.getRestrict() + " ";
        bedrock_line += data.getRestrictType() + " ";
        bedrock_line += formatter.format(data.getAniso()) + " ";
        bedrock_line += formatter.format(data.getUksat());
        lines.add(bedrock_line);

        if (writeFile) {
            FileUtils.writeLines(solFile, lines);
        } else {
            for (int i = 0; i < lines.size(); i++) {
                ret_val += lines.get(i) + ((i < lines.size())? System.lineSeparator():"");
            }
        }

        return ret_val;
    }

    public void writeSol(Component comp, File solFile, int ksflag, WEPPData data) throws IOException {
        writeSolEx(comp, solFile, ksflag, data, true);
    }
}