private void CalcRunoff_USDA_SoilConservationService(double WaterForRunoff, SoilWaterSoil SoilObject) { //private void soilwat2_scs_runoff(double Rain, double Runon, double TotalInterception, ref double Runoff) // { //cn2_new (output) //Runoff (output) double cn; //! scs curve number double cn1; //! curve no. for dry soil (antecedant) moisture double cn3; //! curve no. for wet soil (antecedant) moisture double cnpd; //! cn proportional in dry range (dul to ll15) double s; //! potential max retention (surface ponding + infiltration) double xpb; //! intermedite variable for deriving runof double[] runoff_wf; //! weighting factor for depth for each layer double dul_fraction; // if between (0-1) not above dul, if (1-infinity) above dul double cover_fract; //! proportion of maximum cover effect on runoff (0-1) double cover_reduction = 0.0; double tillage_fract; double tillage_reduction = 0.0; //! reduction in cn due to tillage runoff_wf = new double[SoilObject.num_layers]; soilwat2_runoff_depth_factor(SoilObject, ref runoff_wf); cnpd = 0.0; foreach (Layer lyr in SoilObject) { dul_fraction = MathUtilities.Divide((lyr.sw_dep - lyr.ll15_dep), (lyr.dul_dep - lyr.ll15_dep), 0.0); cnpd = cnpd + dul_fraction * runoff_wf[lyr.number - 1]; //zero based array. } cnpd = cons.bound(cnpd, 0.0, 1.0); //reduce cn2 for the day due to the cover effect //nb. cover_surface_runoff should really be a parameter to this function cover_fract = MathUtilities.Divide(cover_surface_runoff, coverCnCov, 0.0); cover_fract = cons.bound(cover_fract, 0.0, 1.0); cover_reduction = coverCnRed * cover_fract; cn2_new = _cn2_bare - cover_reduction; //tillage reduction on cn //nb. tillage_cn_red, tillage_cn_rain, and tillage_rain_sum, should really be parameters to this function if (tillageCnCumWater > 0.0) { //We minus 1 because we want the opposite fraction. //Tillage Reduction is biggest (CnRed value) straight after Tillage and gets smaller and becomes 0 when reaches CumWater. //unlike the Cover Reduction, where the reduction starts out smallest (0) and gets bigger and becomes (CnRed value) when you hit CnCover. tillage_fract = MathUtilities.Divide(cumWaterSinceTillage, tillageCnCumWater, 0.0) - 1.0; tillage_reduction = tillageCnRed * tillage_fract; cn2_new = cn2_new + tillage_reduction; } else { //nothing } //! cut off response to cover at high covers if p%cn_red < 100. cn2_new = cons.bound(cn2_new, 0.0, 100.0); cn1 = MathUtilities.Divide(cn2_new, (2.334 - 0.01334 * cn2_new), 0.0); cn3 = MathUtilities.Divide(cn2_new, (0.4036 + 0.005964 * cn2_new), 0.0); cn = cn1 + (cn3 - cn1) * cnpd; // ! curve number will be decided from scs curve number table ??dms s = 254.0 * (MathUtilities.Divide(100.0, cn, 1000000.0) - 1.0); xpb = WaterForRunoff - 0.2 * s; xpb = Math.Max(xpb, 0.0); //assign the output variable Runoff = MathUtilities.Divide(xpb * xpb, (WaterForRunoff + 0.8 * s), 0.0); //sv- I added these output variables cn_red_cov = cover_reduction; cn_red_till = tillage_reduction; //bound check the ouput variable cons.bound_check_real_var(Runoff, 0.0, WaterForRunoff, "runoff"); }
//Initialise the Accumulating Variables public void InitialiseAccumulatingVars(SoilWaterSoil SoilObject, IClock Clock) { //reset the accumulated Evap variables (sumes1, sumes2, t) //nb. sumes1 -> is sum of es during stage1 //used in the SoilWater Init, Reset event // soilwat2_soil_property_param() //assign u and cona to either sumer or winter values // Need to add 12 hours to move from "midnight" to "noon", or this won't work as expected if (DateUtilities.WithinDates(winterDate, Clock.Today, summerDate)) { cona = winterCona; u = winterU; } else { cona = summerCona; u = summerU; } //private void soilwat2_evap_init() // { //################## //Evap Init --> soilwat2_evap_init (), soilwat2_ritchie_init() //################## //soilwat2_ritchie_init(); //*+ Mission Statement //* Initialise ritchie evaporation model double swr_top; //! stage 2 evaporation occurs ratio available sw potentially available sw in top layer Layer top = SoilObject.GetTopLayer(); //! set up evaporation stage swr_top = MathUtilities.Divide((top.sw_dep - top.ll15_dep), (top.dul_dep - top.ll15_dep), 0.0); swr_top = cons.bound(swr_top, 0.0, 1.0); //! are we in stage1 or stage2 evap? if (swr_top < cons.sw_top_crit) { //! stage 2 evap sumes2 = cons.sumes2_max - (cons.sumes2_max * MathUtilities.Divide(swr_top, cons.sw_top_crit, 0.0)); sumes1 = u; t = MathUtilities.Sqr(MathUtilities.Divide(sumes2, cona, 0.0)); } else { //! stage 1 evap sumes2 = 0.0; sumes1 = cons.sumes1_max - (cons.sumes1_max * swr_top); t = 0.0; } }