/* * JGrass - Free Open Source Java GIS http://www.jgrass.org * (C) HydroloGIS - www.hydrologis.com * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Library General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) any * later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more * details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jgrasstools.hortonmachine.modules.hydrogeomorphology.adige.duffy; import java.util.HashMap; /** * Class taking care of the distribution of discharge to gain delayed release. * * @author Andrea Antonello (www.hydrologis.com) * @author Silvia Franceschi (www.hydrologis.com) */ public abstract class ADischargeDistributor { /** * Identifier for usage of Nash distribution. */ public static final int DISTRIBUTOR_TYPE_NASH = 0; /* * Parameters of mean and variance considering saturation. */ public static final int PARAMS_AVG_SUP_10 = 0; public static final int PARAMS_AVG_SUP_30 = 1; public static final int PARAMS_AVG_SUP_60 = 2; public static final int PARAMS_VAR_SUP_10 = 3; public static final int PARAMS_VAR_SUP_30 = 4; public static final int PARAMS_VAR_SUP_60 = 5; public static final int PARAMS_AVG_SUB = 6; public static final int PARAMS_VAR_SUB = 7; public static final int PARAMS_V_SUP = 8; public static final int PARAMS_V_SUB = 9; protected double[] subSuperficialDischargeArray; protected double[] superficialDischargeArray; protected final long startDateMillis; protected final long timeStepMillis; protected final HashMap<Integer, Double> parameters; /** * Creates a discharge distributor called from the extending class. * * @param startDateMillis see {@link ADischargeDistributor#createDischargeDistributor(int, long, long, long)} doc. * @param endDateMillis see {@link ADischargeDistributor#createDischargeDistributor(int, long, long, long)} doc. * @param timeStepMillis see {@link ADischargeDistributor#createDischargeDistributor(int, long, long, long)} doc. * @param parameters see {@link ADischargeDistributor#createDischargeDistributor(int, long, long, long)} doc. */ protected ADischargeDistributor( long startDateMillis, long endDateMillis, long timeStepMillis, HashMap<Integer, Double> parameters ) { this.startDateMillis = startDateMillis; this.timeStepMillis = timeStepMillis; this.parameters = parameters; long intervals = (endDateMillis - startDateMillis) / timeStepMillis + 1; subSuperficialDischargeArray = new double[(int) intervals]; superficialDischargeArray = new double[(int) intervals]; } /** * Creates a {@link ADischargeDistributor discharge distributor}. * * @param distributorType defines the type to be used. Possible values are: * <ul> * <li>{@link ADischargeDistributor#DISTRIBUTOR_TYPE_NASH NASH: 0}</li> * </ul> * @param startDateMillis the start time used to define the complete time horizont. * @param endDateMillis the end time used to define the complete time horizont. * @param timeStepMillis the time step used to define the complete time horizont. * @param parameters a {@link HashMap map of parameters} to be used for the * distribution model. Supported values are: * <ul> * <li>{@link ADischargeDistributor#PARAMS_AVG_SUP_10}: the mean * of the width function for 10% of saturated areas * for the superficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_AVG_SUP_30}: the mean * of the width function for 30% of saturated areas * for the superficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_AVG_SUP_60}: the mean * of the width function for 60% of saturated areas * for the superficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_VAR_SUP_10}: the variance * of the width function for 10% of saturated areas * for the superficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_VAR_SUP_30}: the variance * of the width function for 30% of saturated areas * for the superficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_VAR_SUP_60}: the variance * of the width function for 60% of saturated areas * for the superficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_AVG_SUB}: the mean * of the width function for the subsuperficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_VAR_SUB}: the variance * of the width function for the subsuperficial flow case.</li> * <li>{@link ADischargeDistributor#PARAMS_V_SUP}: the * speed of the superficial flow.</li> * <li>{@link ADischargeDistributor#PARAMS_V_SUB}: the * speed of the subsuperficial flow.</li> * </ul> * * @return the created discharge distributor. */ public static ADischargeDistributor createDischargeDistributor( int distributorType, long startDateMillis, long endDateMillis, long timeStepMillis, HashMap<Integer, Double> parameters ) { if (distributorType == DISTRIBUTOR_TYPE_NASH) { return new NashDischargeDistributor(startDateMillis, endDateMillis, timeStepMillis, parameters); } else { throw new IllegalArgumentException("No such distribution model available."); } } /** * Calculates the current superficial discharge. * * <p> * The discharge takes into account the distribution * of all the distributed discharge contributions * in the prior timesteps. * </p> * * @param superficialDischarge the non distributed discharge value. * @param saturatedAreaPercentage the percentage of saturated area. * @param timeInMillis the current timestep. * @return the calculated discharge. */ public double calculateSuperficialDischarge( double superficialDischarge, double saturatedAreaPercentage, long timeInMillis ) { distributeIncomingSuperficialDischarge(superficialDischarge, saturatedAreaPercentage, timeInMillis); return superficialDischargeArray[indexFromTimeInMillis(timeInMillis)]; } /** * Calculates the current subsuperficial discharge. * * <p> * The discharge takes into account the distribution * of all the distributed discharge contributions * in the prior timesteps. * </p> * * @param subSuperficialDischarge the non distributed discharge value. * @param saturatedAreaPercentage the percentage of saturated area. * @param timeInMillis the current timestep. * @return the calculated discharge. */ public double calculateSubsuperficialDischarge( double subSuperficialDischarge, double saturatedAreaPercentage, long timeInMillis ) { distributeIncomingSubSuperficialDischarge(subSuperficialDischarge, saturatedAreaPercentage, timeInMillis); return subSuperficialDischargeArray[indexFromTimeInMillis(timeInMillis)]; } /** * Get the discharge array index for the current time. * * @param currentTimeInMillis the current time in milliseconds. * @return the index that can be used in the discharge arrays. */ protected int indexFromTimeInMillis( long currentTimeInMillis ) { int index = (int) ((currentTimeInMillis - startDateMillis) / timeStepMillis); return index; } /** * The method that applies the distribution method to the incoming discharge. * * <p><b>NOTE</b>: this is for the superficial case.</p> * * @param ssuperficialDischarge the non distributed discharge value. * @param saturatedAreaPercentage the percentage of saturated area. * @param currentTimeInMillis the current timestep. */ protected abstract void distributeIncomingSuperficialDischarge( double superficialDischarge, double saturatedAreaPercentage, long currentTimeInMillis ); /** * The method that applies the distribution method to the incoming discharge. * * <p><b>NOTE</b>: this is for the subsuperficial case.</p> * * @param subSuperficialDischarge the non distributed discharge value. * @param saturatedAreaPercentage the percentage of saturated area. * @param currentTimeInMillis the current timestep. */ protected abstract void distributeIncomingSubSuperficialDischarge( double subSuperficialDischarge, double saturatedAreaPercentage, long currentTimeInMillis ); }