The impervious drainage area upstream of a facility
Example #1
0
        //Category 4 methods don't care about the discharge point
        /// <summary>
        /// Executes the calculator and returns a PacResults. Supports Category 4 facilities.
        /// </summary>
        /// <param name="catchment">A catchment object defining the hydrologic parameters of the catchment area to be evaluated.</param>
        /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
        /// <param name="facility">A Facility object defining the stormwater management facility to be evaluated.</param>
        /// <param name="category">Identifies the Hierarchy Category the proposed facility will be evaluated against. Must be an integer from 1 to 4.</param>
        /// <returns>A PacResults object containing the results of the calculation.</returns>
        public static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, Facility facility, int category)
        {
            HierarchyCategory categoryEnum;

            switch (category)
            {
            case 1:
                categoryEnum = HierarchyCategory.Category1;
                break;

            case 2:
                categoryEnum = HierarchyCategory.Category2;
                break;

            case 3:
                categoryEnum = HierarchyCategory.Category3;
                break;

            case 4:
                categoryEnum = HierarchyCategory.Category4;
                break;

            default:
                throw new ArgumentException("Invalid hierarchy category specified: Must be integer 1 - 4");
            }
            return(PerformCalculations(catchment, preCatchment, facility, categoryEnum, DischargePoint.A));
        }
Example #2
0
        /// <summary>
        /// Constructs a new Facility object of the specified Type and Configuration, located within
        /// the specified Catchment
        /// </summary>
        /// <param name="type">The type of facility</param>
        /// <param name="configuration">The plumbed facility configuration</param>
        /// <param name="catchment">The Catchment containing the facility</param>
        public Facility(FacilityType type, FacilityConfiguration configuration, Catchment catchment)
        {
            _type          = type;
            _configuration = configuration;
            _catchment     = catchment;

            ConfigureFacility();
        }
Example #3
0
        /// <summary>
        /// Performs the SBUH calculations for the Pollution Reduction storm event
        /// </summary>
        /// <param name="catchment">A Catchment object</param>
        /// <returns>A Hydrograph object containing the results of the SBUH calculations</returns>
        public static Hydrograph CalculateSbuhPr(Catchment catchment)
        {
            //Define design storms
              RainfallEvent pollutionReduction = RainfallEvent.GetScsOneAEvent("Pollution Reduction", 0.83);

              Hydrograph imperviousHydrographPR = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, pollutionReduction);

              return imperviousHydrographPR;
        }
Example #4
0
        /// <summary>
        /// Performs the SBUH calculations for the Pollution Reduction storm event
        /// </summary>
        /// <param name="catchment">A Catchment object</param>
        /// <returns>A Hydrograph object containing the results of the SBUH calculations</returns>
        public static Hydrograph CalculateSbuhPr(Catchment catchment)
        {
            //Define design storms
            RainfallEvent pollutionReduction = RainfallEvent.GetScsOneAEvent("Pollution Reduction", 0.83);

            Hydrograph imperviousHydrographPR = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                    (catchment, pollutionReduction);

            return(imperviousHydrographPR);
        }
Example #5
0
        /// <summary>
        /// Performs the SBUH calculations for the Five-year storm event
        /// </summary>
        /// <param name="catchment">A Catchment object</param>
        /// <returns>A Hydrograph object containing the results of the SBUH calculations</returns>
        public static Hydrograph CalculateSbuh5Year(Catchment catchment)
        {
            //Define design storms
              RainfallEvent rainfallEvent = RainfallEvent.GetScsOneAEvent("Five-Year", 2.9);

              Hydrograph imperviousHydrograph = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, rainfallEvent);

              return imperviousHydrograph;
        }
Example #6
0
        /// <summary>
        /// Performs the SBUH calculations for the Twentyfive-year storm event
        /// </summary>
        /// <param name="catchment">A Catchment object</param>
        /// <returns>A Hydrograph object containing the results of the SBUH calculations</returns>
        public static Hydrograph CalculateSbuh25Year(Catchment catchment)
        {
            //Define design storms
            RainfallEvent rainfallEvent = RainfallEvent.GetScsOneAEvent("Twentyfive-Year", 3.9);

            Hydrograph imperviousHydrograph = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                  (catchment, rainfallEvent);

            return(imperviousHydrograph);
        }
Example #7
0
        /// <summary>
        /// Executes only the SBUH calculations.
        /// </summary>
        /// <param name="catchment">The catchment to calculate the SBUH results.</param>
        /// <returns>A PacResults object which is only minimally populated with results data.
        /// The *PeakInflow and *InflowVolume fields will be populated for each storm event.</returns>
        public static PacResults PerformSbuhCalcs(Catchment catchment)
        {
            Facility dummyFacility = new Facility(FacilityType.Basin, FacilityConfiguration.A, catchment)
            {
                BottomAreaSqFt       = 100,
                BottomWidthFt        = 10,
                SideSlopeRatio       = 3,
                StorageDepth1In      = 9,
                GrowingMediumDepthIn = 18,
                FreeboardIn          = 3,
                Shape = FacilityShape.Rectangle
            };

            return(PerformCalculations(catchment, dummyFacility, 1));
        }
Example #8
0
        //Category 3 methods
        /// <summary>
        /// Executes the calculator and returns a PacResults. Supports Category 3 facilities.
        /// </summary>
        /// <param name="catchment">A catchment object defining the hydrologic parameters of the catchment area to be evaluated.</param>
        /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
        /// <param name="facility">A Facility object defining the stormwater management facility to be evaluated.</param>
        /// <param name="category">Identifies the Hierarchy Category the proposed facility will be evaluated against. Must be an integer from 1 to 4.</param>
        /// <param name="dischargePoint">Identifies the DischargePoint of the proposed facility.</param>
        /// <returns>A PacResults object containing the results of the calculation.</returns>
        public static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, Facility facility, int category, char dischargePoint)
        {
            HierarchyCategory categoryEnum;
            DischargePoint    dischargeEnum;

            switch (category)
            {
            case 1:
                categoryEnum = HierarchyCategory.Category1;
                break;

            case 2:
                categoryEnum = HierarchyCategory.Category2;
                break;

            case 3:
                categoryEnum = HierarchyCategory.Category3;
                break;

            case 4:
                categoryEnum = HierarchyCategory.Category4;
                break;

            default:
                throw new ArgumentException("Invalid hierarchy category specified: Must be integer 1 - 4");
            }

            switch (char.ToUpper(dischargePoint))
            {
            case 'A':
                dischargeEnum = DischargePoint.A;
                break;

            case 'B':
                dischargeEnum = DischargePoint.B;
                break;

            case 'C':
                dischargeEnum = DischargePoint.C;
                break;

            default:
                throw new ArgumentException("Invalid discharge point specified: Must be character A-C");
            }
            return(PerformCalculations(catchment, preCatchment, facility, categoryEnum, dischargeEnum));
        }
        /// <summary>
        /// Performs SBUH calculations for a Catchment
        /// </summary>
        /// <param name="catchment"></param>
        /// <param name="rainfallEvent"></param>
        /// <returns></returns>
        public static Hydrograph CalculateHydrograph(Catchment catchment, RainfallEvent rainfallEvent)
        {
            double A  = catchment.ImperviousAreaSquareFeet / 43560;
            double dt = rainfallEvent.TimeIntervalMinutes;
            double Tc = catchment.TimeOfConcentrationMinutes;
            double CN = catchment.CurveNumber;

            double omega = dt / (2 * Tc + dt);
            double S     = (1000 / CN) - 10;


            IList <double> accumulatedRainfall = rainfallEvent.RainfallInches.Accumulate();
            IList <double> accumulatedRunoff   = new List <double>().Initialize(rainfallEvent.Length);


            for (int i = 0; i < rainfallEvent.Length; i++)
            {
                if (accumulatedRainfall[i] < 0.2 * S)
                {
                    accumulatedRunoff[i] = 0;
                }
                else
                {
                    accumulatedRunoff[i] = Math.Pow(accumulatedRainfall[i] - 0.2 * S, 2)
                                           / (accumulatedRainfall[i] + 0.8 * S);
                }
            }

            IList <double> incrementalRunoff = accumulatedRunoff.Deaccumulate();

            IList <double> instantaneousHydrograph = incrementalRunoff.Select(p => p * 60.5 * A / dt).ToList();

            IList <double> designHydrograph = new List <double>().Initialize(rainfallEvent.Length);

            for (int i = 1; i < rainfallEvent.Length - 1; i++)
            {
                designHydrograph[i] = designHydrograph[i - 1] + omega * (instantaneousHydrograph[i] + instantaneousHydrograph[i - 1] - 2 * designHydrograph[i - 1]);
            }

            string name = string.Format("{0} {1}", catchment.Name, rainfallEvent.EventName);

            return(new Hydrograph(name, "cfs", designHydrograph, dt));
        }
Example #10
0
        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                //Create a new segment
                SlopedFacilitySegment segment = new SlopedFacilitySegment();

                //Assign values to segment. All segments have these fields:
                segment.SegmentLengthFt     = 10;
                segment.CheckDamLengthFt    = 2;
                segment.SlopeRatio          = 0.02;
                segment.SideSlopeRightRatio = 4;
                segment.SideSlopeLeftRatio  = 4;
                segment.DownstreamDepthIn   = 9;
                segment.LandscapeWidthFt    = 2;

                segment.RockStorageWidthFt = 4; //Only facility types with rock galleries use this field; see parameter matrix for details

                //Create a catchment, no change for sloped facilities
                Catchment catchment = new Catchment("Test Catchment");

                //Create a SlopedFacility object, constructed the same way as a standard facility
                SlopedFacility facility = new SlopedFacility(FacilityType.Swale, FacilityConfiguration.A, catchment);

                //Segments can be added or deleted from the sloped facility.
                facility.AddSegment(segment);

                facility.DeleteSegment(segment);



                PerformCalculations();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }
        /// <summary>
        /// Performs SBUH calculations for a Catchment
        /// </summary>
        /// <param name="catchment"></param>
        /// <param name="rainfallEvent"></param>
        /// <returns></returns>
        public static Hydrograph CalculateHydrograph(Catchment catchment, RainfallEvent rainfallEvent)
        {
            double A = catchment.ImperviousAreaSquareFeet / 43560;
              double dt = rainfallEvent.TimeIntervalMinutes;
              double Tc = catchment.TimeOfConcentrationMinutes;
              double CN = catchment.CurveNumber;

              double omega = dt / (2 * Tc + dt);
              double S = (1000 / CN) - 10;

              IList<double> accumulatedRainfall = rainfallEvent.RainfallInches.Accumulate();
              IList<double> accumulatedRunoff = new List<double>().Initialize(rainfallEvent.Length);

              for (int i = 0; i < rainfallEvent.Length; i++)
              {
            if (accumulatedRainfall[i] < 0.2 * S)
              accumulatedRunoff[i] = 0;
            else
              accumulatedRunoff[i] = Math.Pow(accumulatedRainfall[i] - 0.2 * S, 2)
            / (accumulatedRainfall[i] + 0.8 * S);
              }

              IList<double> incrementalRunoff = accumulatedRunoff.Deaccumulate();

              IList<double> instantaneousHydrograph = incrementalRunoff.Select(p => p * 60.5 * A / dt).ToList();

              IList<double> designHydrograph = new List<double>().Initialize(rainfallEvent.Length);

              for (int i = 1; i < rainfallEvent.Length - 1; i++)
              {
            designHydrograph[i] = designHydrograph[i-1] + omega*(instantaneousHydrograph[i] + instantaneousHydrograph[i-1]-2*designHydrograph[i-1]);
              }

              string name = string.Format("{0} {1}", catchment.Name, rainfallEvent.EventName);
              return new Hydrograph(name, "cfs", designHydrograph, dt);
        }
Example #12
0
        private void btnTest_Click(object sender, EventArgs e)
        {
            try
              {
            //Create a new segment
            SlopedFacilitySegment segment = new SlopedFacilitySegment();

            //Assign values to segment. All segments have these fields:
            segment.SegmentLengthFt = 10;
            segment.CheckDamLengthFt = 2;
            segment.SlopeRatio = 0.02;
            segment.SideSlopeRightRatio = 4;
            segment.SideSlopeLeftRatio = 4;
            segment.DownstreamDepthIn = 9;
            segment.LandscapeWidthFt = 2;

            segment.RockStorageWidthFt = 4; //Only facility types with rock galleries use this field; see parameter matrix for details

            //Create a catchment, no change for sloped facilities
            Catchment catchment = new Catchment("Test Catchment");

            //Create a SlopedFacility object, constructed the same way as a standard facility
            SlopedFacility facility = new SlopedFacility(FacilityType.Swale, FacilityConfiguration.A, catchment);

            //Segments can be added or deleted from the sloped facility.
            facility.AddSegment(segment);

            facility.DeleteSegment(segment);

            PerformCalculations();
              }
              catch (Exception ex)
              {
            MessageBox.Show("Error: " + ex.Message);
              }
        }
Example #13
0
        private Facility ValidateFacility(string hierarchy, string facilityType, string configuration)
        {
            try
            {
                //Read catchment parameters to local variables
                double imperviousArea         = Convert.ToDouble(txtImperviousArea.Text);
                double curveNumber            = Convert.ToDouble(txtCurveNumber.Text);
                double preCurveNumber         = Convert.ToDouble(txtPreCurveNumber.Text);
                double timeOfConcentration    = Convert.ToDouble(txtTimeOfConcentration.Text);
                double nativeInfiltrationRate = Convert.ToDouble(txtNativeSoilInfiltrationRate.Text);
                InfiltrationTestType infiltrationTestType;

                switch (cmbInfiltrationProcedure.SelectedIndex)
                {
                case (0):
                    infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
                    break;

                case (1):
                    infiltrationTestType = InfiltrationTestType.EncasedFallingHead;
                    break;

                case (2):
                    infiltrationTestType = InfiltrationTestType.DoubleRingInfiltometer;
                    break;

                default:
                    infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
                    break;
                }


                //Create catchment object local variables
                Catchment catchment = new Catchment("Catchment A")
                {
                    ImperviousAreaSquareFeet            = imperviousArea,
                    AcceptableSeparationFromGroundwater = chkMeetsGroundwaterRequirements.Checked,
                    CurveNumber = curveNumber,
                    TimeOfConcentrationMinutes          = timeOfConcentration,
                    TestedInfiltrationRateInchesPerHour = nativeInfiltrationRate,
                    InfiltrationTestType = infiltrationTestType
                };

                //Read facility parameters to local variables
                double        bottomArea                 = Convert.ToDouble(txtBottomArea.Text);
                double        bottomWidth                = Convert.ToDouble(txtBottomWidth.Text);
                double        sideSlope                  = Convert.ToDouble(txtSideSlope.Text);
                double        storageDepth1              = Convert.ToDouble(txtStorageDepth1.Text);
                double        storageDepth2              = Convert.ToDouble(txtStorageDepth2.Text);
                double        storageDepth3              = Convert.ToDouble(txtStorageDepth3.Text);
                double        growingMediumDepth         = Convert.ToDouble(txtGrowingMediumDepth.Text);
                double        freeboardDepth             = Convert.ToDouble(txtFreeboardDepth.Text);
                double        rockStorageDepth           = Convert.ToDouble(txtRockStorageDepth.Text);
                double        rockStorageVoidRatio       = Convert.ToDouble(txtRockVoidRatio.Text);
                double        rockStorageBottomArea      = Convert.ToDouble(txtRockStorageBottomArea.Text);
                double        surfaceAreaAtStorageDepth1 = Convert.ToDouble(txtSurfaceAreaAtDepth1.Text);
                double        bottomPerimiterLength      = Convert.ToDouble(txtBottomPerimeterLength.Text);
                double        surfaceAreaAtStorageDepth2 = Convert.ToDouble(txtSurfaceAreaAtDepth2.Text);
                FacilityShape shape = GetFacilityShape(cmbFacilityShape.Text);

                FacilityConfiguration config;
                config = (FacilityConfiguration)cmbFacilityConfiguration.Text[0];
                FacilityType type = GetFacilityType(cmbFacilityType.Text);


                Facility facility;

                if (type == FacilityType.Basin || type == FacilityType.PlanterFlat)
                {
                    facility = new Facility(type, config, catchment)
                    {
                        BottomAreaSqFt                 = bottomArea,
                        BottomWidthFt                  = bottomWidth,
                        SideSlopeRatio                 = sideSlope,
                        StorageDepth1In                = storageDepth1,
                        StorageDepth2In                = storageDepth2,
                        StorageDepth3In                = storageDepth3,
                        GrowingMediumDepthIn           = growingMediumDepth,
                        FreeboardIn                    = freeboardDepth,
                        RockStorageDepthIn             = rockStorageDepth,
                        RockVoidRatio                  = rockStorageVoidRatio,
                        RockStorageBottomAreaSqFt      = rockStorageBottomArea,
                        SurfaceAreaAtStorageDepth1SqFt = surfaceAreaAtStorageDepth1,
                        BottomPerimeterLengthFt        = bottomPerimiterLength,
                        SurfaceAreaAtStorageDepth2SqFt = surfaceAreaAtStorageDepth2,
                        Shape = shape
                    };
                }
                else //Write sloped facility parameters from UI to facility object and verify results
                {
                    //ShowSlopedFacilityWS();
                    List <SlopedFacilitySegment> segments;
                    if (_sfws != null)
                    {
                        if (_sfws.Segments != null)
                        {
                            segments = _sfws.Segments;
                        }
                        else
                        {
                            segments = new List <SlopedFacilitySegment>();
                        }
                    }
                    else
                    {
                        segments = new List <SlopedFacilitySegment>();
                    }

                    facility = new SlopedFacility(type, config, catchment, segments)
                    {
                        BottomAreaSqFt                 = bottomArea,
                        BottomWidthFt                  = bottomWidth,
                        SideSlopeRatio                 = sideSlope,
                        StorageDepth1In                = storageDepth1,
                        StorageDepth2In                = storageDepth2,
                        StorageDepth3In                = storageDepth3,
                        GrowingMediumDepthIn           = growingMediumDepth,
                        FreeboardIn                    = freeboardDepth,
                        RockStorageDepthIn             = rockStorageDepth,
                        RockVoidRatio                  = rockStorageVoidRatio,
                        RockStorageBottomAreaSqFt      = rockStorageBottomArea,
                        SurfaceAreaAtStorageDepth1SqFt = surfaceAreaAtStorageDepth1,
                        Shape = shape
                    };
                }

                int hierarchyNumber = Convert.ToInt32(hierarchy);
                HierarchyCategory hierarchyCategory = (HierarchyCategory)hierarchyNumber;

                string message;
                _validFacility = Facility.Validate(facility, hierarchyNumber, out message);

                ToggleUIParameters(facility);
                if (!_validFacility)
                {
                    DisableUI(message);
                }

                return(facility);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error with facility parameters: " + ex.Message);
                return(null);
            }
        }
Example #14
0
        private Facility ValidateFacility(string hierarchy, string facilityType, string configuration)
        {
            try
              {
              //Read catchment parameters to local variables
              double imperviousArea = Convert.ToDouble(txtImperviousArea.Text);
              double curveNumber = Convert.ToDouble(txtCurveNumber.Text);
              double preCurveNumber = Convert.ToDouble(txtPreCurveNumber.Text);
              double timeOfConcentration = Convert.ToDouble(txtTimeOfConcentration.Text);
              double nativeInfiltrationRate = Convert.ToDouble(txtNativeSoilInfiltrationRate.Text);
              InfiltrationTestType infiltrationTestType;

              switch (cmbInfiltrationProcedure.SelectedIndex)
              {
              case (0):
                  infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
                  break;
              case (1):
                  infiltrationTestType = InfiltrationTestType.EncasedFallingHead;
                  break;
              case (2):
                  infiltrationTestType = InfiltrationTestType.DoubleRingInfiltometer;
                  break;
              default:
                  infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
                  break;
              }

              //Create catchment object local variables
              Catchment catchment = new Catchment("Catchment A")
              {
              ImperviousAreaSquareFeet = imperviousArea,
              AcceptableSeparationFromGroundwater = chkMeetsGroundwaterRequirements.Checked,
              CurveNumber = curveNumber,
              TimeOfConcentrationMinutes = timeOfConcentration,
              TestedInfiltrationRateInchesPerHour = nativeInfiltrationRate,
              InfiltrationTestType = infiltrationTestType
              };

              //Read facility parameters to local variables
              double bottomArea = Convert.ToDouble(txtBottomArea.Text);
              double bottomWidth = Convert.ToDouble(txtBottomWidth.Text);
              double sideSlope = Convert.ToDouble(txtSideSlope.Text);
              double storageDepth1 = Convert.ToDouble(txtStorageDepth1.Text);
              double storageDepth2 = Convert.ToDouble(txtStorageDepth2.Text);
              double storageDepth3 = Convert.ToDouble(txtStorageDepth3.Text);
              double growingMediumDepth = Convert.ToDouble(txtGrowingMediumDepth.Text);
              double freeboardDepth = Convert.ToDouble(txtFreeboardDepth.Text);
              double rockStorageDepth = Convert.ToDouble(txtRockStorageDepth.Text);
              double rockStorageVoidRatio = Convert.ToDouble(txtRockVoidRatio.Text);
              double rockStorageBottomArea = Convert.ToDouble(txtRockStorageBottomArea.Text);
              double surfaceAreaAtStorageDepth1 = Convert.ToDouble(txtSurfaceAreaAtDepth1.Text);
              double bottomPerimiterLength = Convert.ToDouble(txtBottomPerimeterLength.Text);
              double surfaceAreaAtStorageDepth2 = Convert.ToDouble(txtSurfaceAreaAtDepth2.Text);
              FacilityShape shape = GetFacilityShape(cmbFacilityShape.Text);

              FacilityConfiguration config;
              config = (FacilityConfiguration)cmbFacilityConfiguration.Text[0];
              FacilityType type = GetFacilityType(cmbFacilityType.Text);

              Facility facility;

              if (type == FacilityType.Basin || type == FacilityType.PlanterFlat)
              {
              facility = new Facility(type, config, catchment)
              {
                  BottomAreaSqFt = bottomArea,
                  BottomWidthFt = bottomWidth,
                  SideSlopeRatio = sideSlope,
                  StorageDepth1In = storageDepth1,
                  StorageDepth2In = storageDepth2,
                  StorageDepth3In = storageDepth3,
                  GrowingMediumDepthIn = growingMediumDepth,
                  FreeboardIn = freeboardDepth,
                  RockStorageDepthIn = rockStorageDepth,
                  RockVoidRatio = rockStorageVoidRatio,
                  RockStorageBottomAreaSqFt = rockStorageBottomArea,
                  SurfaceAreaAtStorageDepth1SqFt = surfaceAreaAtStorageDepth1,
                  BottomPerimeterLengthFt = bottomPerimiterLength,
                  SurfaceAreaAtStorageDepth2SqFt = surfaceAreaAtStorageDepth2,
                  Shape = shape
              };
              }
              else //Write sloped facility parameters from UI to facility object and verify results
              {
              //ShowSlopedFacilityWS();
              List<SlopedFacilitySegment> segments;
              if (_sfws != null)
              {
                  if (_sfws.Segments != null)
                      segments = _sfws.Segments;
                  else
                      segments = new List<SlopedFacilitySegment>();
              }
              else
                  segments = new List<SlopedFacilitySegment>();

              facility = new SlopedFacility(type, config, catchment, segments)
              {
                  BottomAreaSqFt = bottomArea,
                  BottomWidthFt = bottomWidth,
                  SideSlopeRatio = sideSlope,
                  StorageDepth1In = storageDepth1,
                  StorageDepth2In = storageDepth2,
                  StorageDepth3In = storageDepth3,
                  GrowingMediumDepthIn = growingMediumDepth,
                  FreeboardIn = freeboardDepth,
                  RockStorageDepthIn = rockStorageDepth,
                  RockVoidRatio = rockStorageVoidRatio,
                  RockStorageBottomAreaSqFt = rockStorageBottomArea,
                  SurfaceAreaAtStorageDepth1SqFt = surfaceAreaAtStorageDepth1,
                  Shape = shape
              };
              }

            int hierarchyNumber = Convert.ToInt32(hierarchy);
            HierarchyCategory hierarchyCategory = (HierarchyCategory)hierarchyNumber;

            string message;
            _validFacility = Facility.Validate(facility, hierarchyNumber, out message);

            ToggleUIParameters(facility);
            if (!_validFacility)
            DisableUI(message);

            return facility;
              }
              catch (Exception ex)
              {
            MessageBox.Show("Error with facility parameters: " + ex.Message);
            return null;
              }
        }
Example #15
0
        //Category 3 methods
        /// <summary>
        /// Executes the calculator and returns a PacResults. Supports Category 3 facilities.
        /// </summary>
        /// <param name="catchment">A catchment object defining the hydrologic parameters of the catchment area to be evaluated.</param>
        /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
        /// <param name="facility">A Facility object defining the stormwater management facility to be evaluated.</param>
        /// <param name="category">Identifies the Hierarchy Category the proposed facility will be evaluated against. Must be an integer from 1 to 4.</param>
        /// <param name="dischargePoint">Identifies the DischargePoint of the proposed facility.</param>
        /// <returns>A PacResults object containing the results of the calculation.</returns>
        public static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, Facility facility, int category, char dischargePoint)
        {
            HierarchyCategory categoryEnum;
            DischargePoint dischargeEnum;

            switch (category)
            {
            case 1:
                categoryEnum = HierarchyCategory.Category1;
                break;
            case 2:
                categoryEnum = HierarchyCategory.Category2;
                break;
            case 3:
                categoryEnum = HierarchyCategory.Category3;
                break;
            case 4:
                categoryEnum = HierarchyCategory.Category4;
                break;
            default:
                throw new ArgumentException("Invalid hierarchy category specified: Must be integer 1 - 4");
            }

            switch (char.ToUpper(dischargePoint))
            {
            case 'A':
                dischargeEnum = DischargePoint.A;
                break;
            case 'B':
                dischargeEnum = DischargePoint.B;
                break;
            case 'C':
                dischargeEnum = DischargePoint.C;
                break;
            default:
                throw new ArgumentException("Invalid discharge point specified: Must be character A-C");
            }
            return PerformCalculations(catchment, preCatchment, facility, categoryEnum, dischargeEnum);
        }
Example #16
0
 /// <summary>
 /// Executes the calculator and returns a PacResults. Supports Category 4 facilities.
 /// </summary>
 /// <param name="catchment">A catchment object defining the hydrologic parameters of the catchment area to be evaluated.</param>
 /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
 /// <param name="slopedFacility">A SlopedFacility object defining the stormwater management facility to be evaluated.</param>
 /// <param name="category">Identifies the Hierarchy Category the proposed facility will be evaluated against. Must be an integer from 1 to 4.</param>
 /// <returns>A PacResults object containing the results of the calculation.</returns>
 public static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, SlopedFacility slopedFacility, int category)
 {
     return(PerformCalculations(catchment, preCatchment, (Facility)slopedFacility, category, 'A'));
 }
Example #17
0
        //Category 4 methods don't care about the discharge point
        /// <summary>
        /// Executes the calculator and returns a PacResults. Supports Category 4 facilities.
        /// </summary>
        /// <param name="catchment">A catchment object defining the hydrologic parameters of the catchment area to be evaluated.</param>
        /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
        /// <param name="facility">A Facility object defining the stormwater management facility to be evaluated.</param>
        /// <param name="category">Identifies the Hierarchy Category the proposed facility will be evaluated against. Must be an integer from 1 to 4.</param>
        /// <returns>A PacResults object containing the results of the calculation.</returns>
        public static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, Facility facility, int category)
        {
            HierarchyCategory categoryEnum;

            switch (category)
            {
            case 1:
                categoryEnum = HierarchyCategory.Category1;
                break;
            case 2:
                categoryEnum = HierarchyCategory.Category2;
                break;
            case 3:
                categoryEnum = HierarchyCategory.Category3;
                break;
            case 4:
                categoryEnum = HierarchyCategory.Category4;
                break;
            default:
                throw new ArgumentException("Invalid hierarchy category specified: Must be integer 1 - 4");
            }
            return PerformCalculations(catchment, preCatchment, facility, categoryEnum, DischargePoint.A);
        }
Example #18
0
        /// <summary>
        /// Executes the calculator and returns a PacResults.
        /// </summary>
        /// <param name="catchment">A catchment object defining the hydrologic parameters of the post-developed catchment area to be evaluated.</param>
        /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
        /// <param name="facility">A Facility object defining the stormwater management facility to be evaluated.</param>
        /// <param name="category">Identifies the HierarchyCategory the proposed facility will be evaluated against.</param>
        /// <param name="dischargePoint">Identifies the DischargePoint of the proposed facility.</param>
        /// <returns>A PacResults object containing the results of the calculation.</returns>
        internal static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, Facility facility, HierarchyCategory category, DischargePoint dischargePoint)
        {
            //Define design storms
            RainfallEvent pollutionReduction = RainfallEvent.GetScsOneAEvent("Pollution Reduction", 0.83);
            RainfallEvent twoYear            = RainfallEvent.GetScsOneAEvent("Two-Year", 2.4);
            RainfallEvent fiveYear           = RainfallEvent.GetScsOneAEvent("Five-Year", 2.9);
            RainfallEvent tenYear            = RainfallEvent.GetScsOneAEvent("Ten-Year", 3.4);
            RainfallEvent twentyFiveYear     = RainfallEvent.GetScsOneAEvent("Twentyfive-Year", 3.9);

            PacResults results = new PacResults();

            //Calculate hydrographs for the most important design storms
            Hydrograph imperviousHydrographPR = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                    (catchment, pollutionReduction);
            Hydrograph imperviousHydrographTwoYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                         (catchment, twoYear);
            Hydrograph imperviousHydrographFiveYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                          (catchment, fiveYear);
            Hydrograph imperviousHydrographTenYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                         (catchment, tenYear);
            Hydrograph imperviousHydrographTwentyfiveYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
                                                                (catchment, twentyFiveYear);

            results.PollutionReductionResults =
                ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographPR);
            results.PollutionReductionPeakOverflow        = results.PollutionReductionResults.PeakOverflow;
            results.PollutionReductionTotalOverflowVolume = results.PollutionReductionResults.OverflowVolume;
            results.PollutionReductionSurfaceCapacity     = results.PollutionReductionResults.PercentSurfaceCapacityUsed;
            results.PollutionReductionPercentRockCapacity = results.PollutionReductionResults.PercentRockCapacityUsed;

            results.PollutionReductionInflowVolume = results.PollutionReductionResults.InflowVolume;
            results.PollutionReductionPeakInflow   = results.PollutionReductionResults.PeakInflowRate;

            results.TwoYearResults =
                ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographTwoYear);
            results.TwoYearPeakOverflow        = results.TwoYearResults.PeakOverflow;
            results.TwoYearTotalOverflowVolume = results.TwoYearResults.OverflowVolume;

            results.TwoYearInflowVolume = results.TwoYearResults.InflowVolume;
            results.TwoYearPeakInflow   = results.TwoYearResults.PeakInflowRate;

            results.FiveYearResults =
                ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographFiveYear);
            results.FiveYearPeakOverflow        = results.FiveYearResults.PeakOverflow;
            results.FiveYearTotalOverflowVolume = results.FiveYearResults.OverflowVolume;

            results.FiveYearInflowVolume = results.FiveYearResults.InflowVolume;
            results.FiveYearPeakInflow   = results.FiveYearResults.PeakInflowRate;

            results.TenYearResults =
                ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographTenYear);
            results.TenYearPeakOverflow        = results.TenYearResults.PeakOverflow;
            results.TenYearTotalOverflowVolume = results.TenYearResults.OverflowVolume;
            results.TenYearSurfaceCapacity     = results.TenYearResults.PercentSurfaceCapacityUsed;
            results.TenYearPercentRockCapacity = results.TenYearResults.PercentRockCapacityUsed;

            results.TenYearInflowVolume = results.TenYearResults.InflowVolume;
            results.TenYearPeakInflow   = results.TenYearResults.PeakInflowRate;

            results.TwentyfiveYearResults =
                ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographTwentyfiveYear);
            results.TwentyfiveYearPeakOverflow        = results.TwentyfiveYearResults.PeakOverflow;
            results.TwentyfiveYearTotalOverflowVolume = results.TwentyfiveYearResults.OverflowVolume;

            results.TwentyfiveYearInflowVolume = results.TwentyfiveYearResults.InflowVolume;
            results.TwentyfiveYearPeakInflow   = results.TwentyfiveYearResults.PeakInflowRate;

            results.TenYearScore                   = PacScore.NotUsed; // Defaults
            results.FlowControlScore               = PacScore.NotUsed;
            results.TwoYearFlowControlScore        = PacScore.NotUsed;
            results.FiveYearFlowControlScore       = PacScore.NotUsed;
            results.TenYearFlowControlScore        = PacScore.NotUsed;
            results.TwentyfiveYearFlowControlScore = PacScore.NotUsed;

            switch (category)
            {
            case HierarchyCategory.Category1:
            case HierarchyCategory.Category2:
                results.TenYearScore = results.TenYearPeakOverflow > 0 ? PacScore.Fail : PacScore.Pass;
                break;

            case HierarchyCategory.Category3:
                //Define preliminary catchment runoff results
                results.PreDevelopedTwoYearPeakInflow        = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twoYear)).PeakInflowRate;
                results.PreDevelopedFiveYearPeakInflow       = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, fiveYear)).PeakInflowRate;
                results.PreDevelopedTenYearPeakInflow        = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, tenYear)).PeakInflowRate;
                results.PreDevelopedTwentyfiveYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twentyFiveYear)).PeakInflowRate;

                switch (dischargePoint)
                {
                case DischargePoint.A:
                    results.FlowControlScore = PacScore.NotUsed;
                    break;

                case DischargePoint.B:
                    if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow / 2)
                    {
                        results.TwoYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.TwoYearFlowControlScore = PacScore.Fail;
                    }
                    if (results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow)
                    {
                        results.FiveYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.FiveYearFlowControlScore = PacScore.Fail;
                    }
                    if (results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                    {
                        results.TenYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.TenYearFlowControlScore = PacScore.Fail;
                    }
                    if (results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTwentyfiveYearPeakInflow)
                    {
                        results.TwentyfiveYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.TwentyfiveYearFlowControlScore = PacScore.Fail;
                    }
                    if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow / 2 &&
                        results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow &&
                        results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow &&
                        results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTwentyfiveYearPeakInflow)
                    {
                        results.FlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.FlowControlScore = PacScore.Fail;
                    }
                    break;

                case DischargePoint.C:
                    if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow)
                    {
                        results.TwoYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.TwoYearFlowControlScore = PacScore.Fail;
                    }
                    if (results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow)
                    {
                        results.FiveYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.FiveYearFlowControlScore = PacScore.Fail;
                    }
                    if (results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                    {
                        results.TenYearFlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.TenYearFlowControlScore = PacScore.Fail;
                    }

                    if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow &&
                        results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow &&
                        results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                    {
                        results.FlowControlScore = PacScore.Pass;
                    }
                    else
                    {
                        results.FlowControlScore = PacScore.Fail;
                    }
                    break;

                default:
                    break;
                }
                break;

            case HierarchyCategory.Category4:
                //Define preliminary catchment runoff results
                results.PreDevelopedTwoYearPeakInflow        = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twoYear)).PeakInflowRate;
                results.PreDevelopedFiveYearPeakInflow       = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, fiveYear)).PeakInflowRate;
                results.PreDevelopedTenYearPeakInflow        = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, tenYear)).PeakInflowRate;
                results.PreDevelopedTwentyfiveYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twentyFiveYear)).PeakInflowRate;
                if (results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                {
                    results.FlowControlScore = PacScore.Pass;
                    results.TwentyfiveYearFlowControlScore = PacScore.Pass;
                }
                else
                {
                    results.FlowControlScore = PacScore.Fail;
                    results.TwentyfiveYearFlowControlScore = PacScore.Fail;
                }
                break;

            default:
                break;
            }

            results.PollutionReductionScore = results.PollutionReductionResults.PeakSurfaceOverflow > 0 ?
                                              PacScore.Fail : PacScore.Pass;

            return(results);
        }
Example #19
0
        /// <summary>
        /// Constructs a new Facility object of the specified Type and Configuration, located within
        /// the specified Catchment
        /// </summary>
        /// <param name="type">The type of facility</param>
        /// <param name="configuration">The plumbed facility configuration</param>
        /// <param name="catchment">The Catchment containing the facility</param>
        public Facility(FacilityType type, FacilityConfiguration configuration, Catchment catchment)
        {
            _type = type;
              _configuration = configuration;
              _catchment = catchment;

              ConfigureFacility();
        }
Example #20
0
 /// <summary>
 /// Executes the calculator and returns a PacResults. Supports Category 4 facilities.
 /// </summary>
 /// <param name="catchment">A catchment object defining the hydrologic parameters of the catchment area to be evaluated.</param>
 /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
 /// <param name="slopedFacility">A SlopedFacility object defining the stormwater management facility to be evaluated.</param>
 /// <param name="category">Identifies the Hierarchy Category the proposed facility will be evaluated against. Must be an integer from 1 to 4.</param>
 /// <returns>A PacResults object containing the results of the calculation.</returns>
 public static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, SlopedFacility slopedFacility, int category)
 {
     return PerformCalculations(catchment, preCatchment, (Facility)slopedFacility, category, 'A');
 }
Example #21
0
 /// <summary>
 /// Executes only the SBUH calculations.
 /// </summary>
 /// <param name="catchment">The catchment to calculate the SBUH results.</param>
 /// <returns>A PacResults object which is only minimally populated with results data.
 /// The *PeakInflow and *InflowVolume fields will be populated for each storm event.</returns>
 public static PacResults PerformSbuhCalcs(Catchment catchment)
 {
     Facility dummyFacility = new Facility(FacilityType.Basin, FacilityConfiguration.A, catchment)
       {
       BottomAreaSqFt = 100,
       BottomWidthFt = 10,
       SideSlopeRatio = 3,
       StorageDepth1In = 9,
       GrowingMediumDepthIn = 18,
       FreeboardIn = 3,
       Shape = FacilityShape.Rectangle
       };
       return PerformCalculations(catchment, dummyFacility, 1);
 }
Example #22
0
        /// <summary>
        /// Executes the calculator and returns a PacResults.
        /// </summary>
        /// <param name="catchment">A catchment object defining the hydrologic parameters of the post-developed catchment area to be evaluated.</param>
        /// <param name="preCatchment">A catchment object defining the hydrologic parameters of the pre-developed catchment area to be evaluated.</param>
        /// <param name="facility">A Facility object defining the stormwater management facility to be evaluated.</param>
        /// <param name="category">Identifies the HierarchyCategory the proposed facility will be evaluated against.</param>
        /// <param name="dischargePoint">Identifies the DischargePoint of the proposed facility.</param>
        /// <returns>A PacResults object containing the results of the calculation.</returns>
        internal static PacResults PerformCalculations(Catchment catchment, Catchment preCatchment, Facility facility, HierarchyCategory category, DischargePoint dischargePoint)
        {
            //Define design storms
              RainfallEvent pollutionReduction = RainfallEvent.GetScsOneAEvent("Pollution Reduction", 0.83);
              RainfallEvent twoYear = RainfallEvent.GetScsOneAEvent("Two-Year", 2.4);
              RainfallEvent fiveYear = RainfallEvent.GetScsOneAEvent("Five-Year", 2.9);
              RainfallEvent tenYear = RainfallEvent.GetScsOneAEvent("Ten-Year", 3.4);
              RainfallEvent twentyFiveYear = RainfallEvent.GetScsOneAEvent("Twentyfive-Year", 3.9);

              PacResults results = new PacResults();

              //Calculate hydrographs for the most important design storms
              Hydrograph imperviousHydrographPR = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, pollutionReduction);
              Hydrograph imperviousHydrographTwoYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, twoYear);
              Hydrograph imperviousHydrographFiveYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, fiveYear);
              Hydrograph imperviousHydrographTenYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, tenYear);
              Hydrograph imperviousHydrographTwentyfiveYear = SantaBarbaraUrbanHydrograph.CalculateHydrograph
            (catchment, twentyFiveYear);

              results.PollutionReductionResults =
            ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographPR);
              results.PollutionReductionPeakOverflow = results.PollutionReductionResults.PeakOverflow;
              results.PollutionReductionTotalOverflowVolume = results.PollutionReductionResults.OverflowVolume;
              results.PollutionReductionSurfaceCapacity = results.PollutionReductionResults.PercentSurfaceCapacityUsed;
              results.PollutionReductionPercentRockCapacity = results.PollutionReductionResults.PercentRockCapacityUsed;

              results.PollutionReductionInflowVolume = results.PollutionReductionResults.InflowVolume;
              results.PollutionReductionPeakInflow = results.PollutionReductionResults.PeakInflowRate;

              results.TwoYearResults =
            ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographTwoYear);
              results.TwoYearPeakOverflow = results.TwoYearResults.PeakOverflow;
              results.TwoYearTotalOverflowVolume = results.TwoYearResults.OverflowVolume;

              results.TwoYearInflowVolume = results.TwoYearResults.InflowVolume;
              results.TwoYearPeakInflow = results.TwoYearResults.PeakInflowRate;

              results.FiveYearResults =
            ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographFiveYear);
              results.FiveYearPeakOverflow = results.FiveYearResults.PeakOverflow;
              results.FiveYearTotalOverflowVolume = results.FiveYearResults.OverflowVolume;

              results.FiveYearInflowVolume = results.FiveYearResults.InflowVolume;
              results.FiveYearPeakInflow = results.FiveYearResults.PeakInflowRate;

              results.TenYearResults =
            ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographTenYear);
              results.TenYearPeakOverflow = results.TenYearResults.PeakOverflow;
              results.TenYearTotalOverflowVolume = results.TenYearResults.OverflowVolume;
              results.TenYearSurfaceCapacity = results.TenYearResults.PercentSurfaceCapacityUsed;
              results.TenYearPercentRockCapacity = results.TenYearResults.PercentRockCapacityUsed;

              results.TenYearInflowVolume = results.TenYearResults.InflowVolume;
              results.TenYearPeakInflow = results.TenYearResults.PeakInflowRate;

              results.TwentyfiveYearResults =
            ReservoirRouter.PerformCalculations(facility, category, catchment, imperviousHydrographTwentyfiveYear);
              results.TwentyfiveYearPeakOverflow = results.TwentyfiveYearResults.PeakOverflow;
              results.TwentyfiveYearTotalOverflowVolume = results.TwentyfiveYearResults.OverflowVolume;

              results.TwentyfiveYearInflowVolume = results.TwentyfiveYearResults.InflowVolume;
              results.TwentyfiveYearPeakInflow = results.TwentyfiveYearResults.PeakInflowRate;

              results.TenYearScore = PacScore.NotUsed; // Defaults
              results.FlowControlScore = PacScore.NotUsed;
              results.TwoYearFlowControlScore = PacScore.NotUsed;
              results.FiveYearFlowControlScore = PacScore.NotUsed;
              results.TenYearFlowControlScore = PacScore.NotUsed;
              results.TwentyfiveYearFlowControlScore = PacScore.NotUsed;

              switch (category)
              {
              case HierarchyCategory.Category1:
              case HierarchyCategory.Category2:
              results.TenYearScore = results.TenYearPeakOverflow > 0 ? PacScore.Fail : PacScore.Pass;
              break;
              case HierarchyCategory.Category3:
              //Define preliminary catchment runoff results
              results.PreDevelopedTwoYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twoYear)).PeakInflowRate;
              results.PreDevelopedFiveYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, fiveYear)).PeakInflowRate;
              results.PreDevelopedTenYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, tenYear)).PeakInflowRate;
              results.PreDevelopedTwentyfiveYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twentyFiveYear)).PeakInflowRate;

              switch (dischargePoint)
              {
                  case DischargePoint.A:
                      results.FlowControlScore = PacScore.NotUsed;
                      break;
                  case DischargePoint.B:
                      if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow / 2)
                          results.TwoYearFlowControlScore = PacScore.Pass;
                      else
                          results.TwoYearFlowControlScore = PacScore.Fail;
                      if (results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow)
                          results.FiveYearFlowControlScore = PacScore.Pass;
                      else
                          results.FiveYearFlowControlScore = PacScore.Fail;
                      if (results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                          results.TenYearFlowControlScore = PacScore.Pass;
                      else
                          results.TenYearFlowControlScore = PacScore.Fail;
                      if (results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTwentyfiveYearPeakInflow)
                          results.TwentyfiveYearFlowControlScore = PacScore.Pass;
                      else
                          results.TwentyfiveYearFlowControlScore = PacScore.Fail;
                      if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow / 2 &&
                              results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow &&
                              results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow &&
                              results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTwentyfiveYearPeakInflow)
                          results.FlowControlScore = PacScore.Pass;
                      else
                          results.FlowControlScore = PacScore.Fail;
                      break;
                  case DischargePoint.C:
                      if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow)
                          results.TwoYearFlowControlScore = PacScore.Pass;
                      else
                          results.TwoYearFlowControlScore = PacScore.Fail;
                      if (results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow)
                          results.FiveYearFlowControlScore = PacScore.Pass;
                      else
                          results.FiveYearFlowControlScore = PacScore.Fail;
                      if (results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                          results.TenYearFlowControlScore = PacScore.Pass;
                      else
                          results.TenYearFlowControlScore = PacScore.Fail;

                      if (results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow &&
                              results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow &&
                              results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
                          results.FlowControlScore = PacScore.Pass;
                      else
                          results.FlowControlScore = PacScore.Fail;
                      break;
                  default:
                      break;
              }
              break;
              case HierarchyCategory.Category4:
              //Define preliminary catchment runoff results
              results.PreDevelopedTwoYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twoYear)).PeakInflowRate;
              results.PreDevelopedFiveYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, fiveYear)).PeakInflowRate;
              results.PreDevelopedTenYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, tenYear)).PeakInflowRate;
              results.PreDevelopedTwentyfiveYearPeakInflow = ReservoirRouter.PerformCalculations(facility, category, preCatchment, SantaBarbaraUrbanHydrograph.CalculateHydrograph(preCatchment, twentyFiveYear)).PeakInflowRate;
              if (results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow)
              {
                  results.FlowControlScore = PacScore.Pass;
                  results.TwentyfiveYearFlowControlScore = PacScore.Pass;
              }
              else
              {
                  results.FlowControlScore = PacScore.Fail;
                  results.TwentyfiveYearFlowControlScore = PacScore.Fail;
              }
              break;
              default:
              break;
              }

              results.PollutionReductionScore = results.PollutionReductionResults.PeakSurfaceOverflow > 0 ?
            PacScore.Fail : PacScore.Pass;

              return results;
        }
Example #23
0
        /// <summary>
        /// Contains algorithims implementing the sizing calculations for various facility configurations
        /// </summary>
        /// <param name="facility"></param>
        /// <param name="category"></param>
        /// <param name="catchment"></param>
        /// <param name="inflowHydrograph"></param>
        /// <returns></returns>
        public static StormEventResults PerformCalculations(Facility facility, HierarchyCategory category, Catchment catchment, Hydrograph inflowHydrograph)
        {
            string message;

            Facility.Validate(facility, Convert.ToInt32(category), out message);

            if (!facility.IsValid)
            {
                throw new ArgumentException("Unable to perform calculations: failed validation with message '" + message + "'");
            }

            double dt        = inflowHydrograph.TimeStepMinutes;
            int    timeSteps = inflowHydrograph.AsArray().Count();

            double inflowFromRain;
            double inflowVolume;
            double inflowVolumeCummulative = 0;

            double[] surfaceInfiltrationCapacity = new double[timeSteps]; //Column E, aka Percolation Capacity
            double   initialInfiltrationToAmendedSoil;

            double[] storedToBeInfiltrated = new double[timeSteps];

            double graphLocator = 0;
            double potentialExtraInfiltration;

            double cumulativeInfiltrationVolume = 0;                                //Column J

            double additionalInfiltrationFromStorage;                               //Column K

            double[] totalInfiltrationCapacityToBelowGrade = new double[timeSteps]; //Column L

            double inflowToSurfaceStorageAfterInfiltration;                         //Column M

            double[] inflowMinusInfiltration = new double[timeSteps];               //Column N

            double surfaceStorageCumulativeVolume = 0;                              //Column O,P,Q,R combined.

            double[] flowOvertoppingToUnderdrain = new double[timeSteps];           //Column T (or Column W for type E)

            double[] infiltrationToBelowGrade = new double[timeSteps];              //Column Z
            double[] totalFlowToBelowGrade    = new double[timeSteps];              //Column AA
            double[] inflowToRockStorage      = new double[timeSteps];              //column AB

            double[] totalInfiltrationCapacityToNative = new double[timeSteps];     //Column AE
            double   totalInfiltratedToNative          = 0;

            double rockStorageCumulativeVolume = 0;                                     //Column AJ

            double[] rockPercentCapacity = new double[timeSteps];                       //Column AK/AL for A,B&E facilities; Column AR/AS for C&F;

            double excessRockCumulativeVolume            = 0;                           //Column AM
            double underdrainStorageAreaCumulativeVolume = 0;                           //Column AR

            double[] aboveGradeStoragePercentCapacity          = new double[timeSteps]; //Column AO for A,B facilities; Column S for C,D&F
            double[] aboveGradeSecondaryStoragePercentCapacity = new double[timeSteps]; //Column AO for E facilities

            double[] rockOverflowToEscapeRoute = new double[timeSteps];                 //Column AP
            double[] overflowToEscapeRoute     = new double[timeSteps];                 //Column AQ for A,B,D,E,F facilities; Column AT for C&F

            double nativeInfiltrationRate        = facility.NativeSoilInfiltrationCapacityCfs();
            double growingMediumInfiltrationRate = facility.ImportedMediumInfiltrationCapacityCfs();

            //The Lag Index is a property of the growing medium depth and infiltration rate that
            //corresponds to the number of time steps it will take for water to percolate through the
            //growing medium. The infiltration hydrograph to the rock medium is delayed by the lag index.
            //For facility configurations A, B, and E, no lag is applied when the native infiltration rate is less
            //than the growing medium infilration rate.
            double lagFactor =
                (facility.Configuration == FacilityConfiguration.A ||
                 facility.Configuration == FacilityConfiguration.B ||
                 facility.Configuration == FacilityConfiguration.E) &&
                nativeInfiltrationRate < growingMediumInfiltrationRate ? 0 :
                facility.GrowingMediumPorespace;

            double lagTime = facility.GrowingMediumDepthIn / catchment.ImportedMediumInfiltrationInchesPerHour * 60 * lagFactor;
            int    lag     = (int)Math.Ceiling(lagTime / inflowHydrograph.TimeStepMinutes); // Rounding up is perfored in the current calculator. This may be unnecessary.

            for (int i = 0; i < timeSteps; i++)
            {
                inflowFromRain           = inflowHydrograph.AsArray()[i];
                inflowVolume             = inflowFromRain * 600;
                inflowVolumeCummulative += inflowVolume;

                //Facility configurations A,B, and D have rock-influenced surface storage demand. When
                //the rock storage is full, infiltration rates in the growing medium can be limited by
                //infiltration rates of the native soil.
                if (facility.HasRockInfluencedSurfaceStorage && rockPercentCapacity[Math.Max(1, i - 1)] >= 1)
                {
                    surfaceInfiltrationCapacity[i] = Math.Min(growingMediumInfiltrationRate, nativeInfiltrationRate);
                }
                else
                {
                    surfaceInfiltrationCapacity[i] = growingMediumInfiltrationRate;
                }

                initialInfiltrationToAmendedSoil =
                    Math.Min(inflowFromRain, surfaceInfiltrationCapacity[i]);

                storedToBeInfiltrated[i] = Math.Max(inflowFromRain - initialInfiltrationToAmendedSoil, 0) * 600;

                graphLocator =
                    storedToBeInfiltrated[i] - storedToBeInfiltrated[Math.Max(1, i - 1)] < 0 ?
                    1 : graphLocator;

                potentialExtraInfiltration =
                    (surfaceInfiltrationCapacity[i] - initialInfiltrationToAmendedSoil) * graphLocator;

                cumulativeInfiltrationVolume += (potentialExtraInfiltration * 600);

                // Existing spreadsheet rounds up storageToBeInfiltrated to nearest ten,
                // allowing more potentialExtraInfiltration to fill rock storage. This may be unnecessary...
                double storedToBeInfiltratedRoundedUp      = Math.Ceiling(storedToBeInfiltrated.Sum() / 10) * 10;
                double cumulativeInfiltrationVolumeRounded = Math.Round(cumulativeInfiltrationVolume, 10); // Added 6/24/2015 to deal with binary storage of floating point numbers without changing to decimal data type

                additionalInfiltrationFromStorage =
                    cumulativeInfiltrationVolumeRounded > storedToBeInfiltratedRoundedUp || cumulativeInfiltrationVolumeRounded > facility.SurfaceCapacityAtDepth1CuFt ?
                    0 : potentialExtraInfiltration;

                totalInfiltrationCapacityToBelowGrade[i] = initialInfiltrationToAmendedSoil + additionalInfiltrationFromStorage;

                inflowToSurfaceStorageAfterInfiltration = Math.Max(inflowFromRain - totalInfiltrationCapacityToBelowGrade[i], 0);

                inflowMinusInfiltration[i] = inflowFromRain - surfaceInfiltrationCapacity[i];

                surfaceStorageCumulativeVolume += (inflowMinusInfiltration[i] * 600);

                surfaceStorageCumulativeVolume = Math.Max(surfaceStorageCumulativeVolume, 0);
                surfaceStorageCumulativeVolume = Math.Min(surfaceStorageCumulativeVolume, facility.SurfaceCapacityAtDepth1CuFt);

                flowOvertoppingToUnderdrain[i] =
                    surfaceStorageCumulativeVolume < facility.SurfaceCapacityAtDepth1CuFt ?
                    0 : inflowToSurfaceStorageAfterInfiltration;

                if (i - lag < 0)
                {
                    infiltrationToBelowGrade[i] = totalInfiltrationCapacityToBelowGrade[0];
                }
                else
                {
                    infiltrationToBelowGrade[i] = totalInfiltrationCapacityToBelowGrade[i - lag];
                }

                totalFlowToBelowGrade[i] = infiltrationToBelowGrade[i] + flowOvertoppingToUnderdrain[i];

                if (facility.Configuration == FacilityConfiguration.E || facility.Configuration == FacilityConfiguration.F)
                {
                    inflowToRockStorage[i] = totalFlowToBelowGrade[i];
                }
                else
                {
                    inflowToRockStorage[i] = infiltrationToBelowGrade[i];
                }

                totalInfiltrationCapacityToNative[i] = nativeInfiltrationRate;

                if (rockStorageCumulativeVolume + inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i] < 0)
                {
                    totalInfiltratedToNative += rockStorageCumulativeVolume + inflowToRockStorage[i];
                }
                else
                {
                    totalInfiltratedToNative += totalInfiltrationCapacityToNative[i];
                }

                rockStorageCumulativeVolume += ((inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i]) * 600);

                excessRockCumulativeVolume = rockStorageCumulativeVolume < facility.RockStorageCapacityCuFt ?
                                             0 : rockStorageCumulativeVolume - facility.RockStorageCapacityCuFt;

                rockStorageCumulativeVolume = Math.Max(rockStorageCumulativeVolume, 0);

                if (facility.HasRockInfluencedSurfaceStorage)
                {
                    aboveGradeStoragePercentCapacity[i] =
                        (surfaceStorageCumulativeVolume + excessRockCumulativeVolume) /
                        facility.SurfaceCapacityAtDepth1CuFt;
                    //E facilities have a secondary storage volume
                    if (facility.HasSecondaryOverflow)
                    {
                        aboveGradeSecondaryStoragePercentCapacity[i] =
                            (surfaceStorageCumulativeVolume + excessRockCumulativeVolume) /
                            facility.SurfaceCapacityAtDepth2CuFt;
                        aboveGradeSecondaryStoragePercentCapacity[i] = Math.Min(aboveGradeSecondaryStoragePercentCapacity[i], 1);
                    }
                }
                //C, D, and F facilities have a direct connection from the rock gallery to an overflow,
                //and therefore above grade storage capacity is independent of rock gallery volume
                else
                {
                    aboveGradeStoragePercentCapacity[i] =
                        surfaceStorageCumulativeVolume / facility.SurfaceCapacityAtDepth1CuFt;
                }
                aboveGradeStoragePercentCapacity[i] = Math.Min(aboveGradeStoragePercentCapacity[i], 1);

                if (facility.HasRockInfluencedSurfaceStorage && !facility.HasSecondaryOverflow) // A, B
                {
                    // Added 6/22/2015 to handle case where surface is full, but should overflow more due to limited rock gallery.
                    // This will occur only once during a storm, as the next cycle will limit above grade infiltration to the rock gallery
                    // and overflow the correct amount.
                    double belowGradeInflowMinusInfiltration = inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i];
                    if (aboveGradeStoragePercentCapacity[i] == 1 && belowGradeInflowMinusInfiltration > 0)
                    {
                        rockOverflowToEscapeRoute[i] = belowGradeInflowMinusInfiltration;
                    }
                    else
                    {
                        rockOverflowToEscapeRoute[i] = 0;
                    }

                    rockPercentCapacity[i] = facility.HasRockStorage ?
                                             rockStorageCumulativeVolume / facility.RockStorageCapacityCuFt : 1;
                    rockPercentCapacity[i] = Math.Min(rockPercentCapacity[i], 1);
                }
                else if (facility.HasSecondaryOverflow) // E
                {
                    rockOverflowToEscapeRoute[i] = aboveGradeSecondaryStoragePercentCapacity[i] < 1 ? 0 :
                                                   Math.Max(totalFlowToBelowGrade[i] - facility.NativeSoilInfiltrationCapacityCfs(), 0);

                    rockPercentCapacity[i] = facility.HasRockStorage ?
                                             rockStorageCumulativeVolume / facility.RockStorageCapacityCuFt : 1;
                    rockPercentCapacity[i] = Math.Min(rockPercentCapacity[i], 1);
                }
                else if (!facility.HasRockInfluencedSurfaceStorage) // C, D & F
                {
                    underdrainStorageAreaCumulativeVolume +=
                        ((inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i]) * 600);
                    underdrainStorageAreaCumulativeVolume = Math.Max(underdrainStorageAreaCumulativeVolume, 0);
                    underdrainStorageAreaCumulativeVolume = Math.Min(underdrainStorageAreaCumulativeVolume, facility.RockStorageCapacityCuFt);

                    if ((underdrainStorageAreaCumulativeVolume / facility.RockStorageCapacityCuFt >= 1) || facility.RockStorageCapacityCuFt == 0) // Added facility.RockStorageCapacityCuFt for 0/0 case
                    {
                        rockOverflowToEscapeRoute[i] = inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i];
                    }

                    rockPercentCapacity[i] = facility.HasRockStorage ?
                                             underdrainStorageAreaCumulativeVolume / facility.RockStorageCapacityCuFt : 1;
                    rockPercentCapacity[i] = Math.Min(rockPercentCapacity[i], 1);
                }

                if (facility.Configuration == FacilityConfiguration.F || // Facility F is different, in that overflow from the surface goes to the subsurface
                    facility.Configuration == FacilityConfiguration.E) // Facility E is strange also, in that the flow overtopping to the underdrain doesn't also go to the escape route.
                {
                    overflowToEscapeRoute[i] = excessRockCumulativeVolume > 0 ? rockOverflowToEscapeRoute[i] : 0;
                }
                else
                {
                    overflowToEscapeRoute[i] = excessRockCumulativeVolume > 0 ?
                                               flowOvertoppingToUnderdrain[i] + rockOverflowToEscapeRoute[i] : flowOvertoppingToUnderdrain[i];
                }
            }

            StormEventResults results = new StormEventResults();

            results.PeakSurfaceOverflow = flowOvertoppingToUnderdrain.Max();
            results.PeakOverflow        = overflowToEscapeRoute.Max();
            results.OverflowVolume      = overflowToEscapeRoute.Sum() * 600;

            results.PercentSurfaceCapacityUsed = aboveGradeStoragePercentCapacity.Max();
            results.PercentRockCapacityUsed    = rockPercentCapacity.Max();

            results.InflowVolume   = inflowHydrograph.AsArray().Sum() * 600;
            results.PeakInflowRate = inflowHydrograph.AsArray().Max();

            results.AboveGradePrimaryResults.Add(new Hydrograph("Inflow from rain", "cfs", inflowHydrograph.AsArray(), dt));
            results.AboveGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", surfaceInfiltrationCapacity, dt));

            switch (facility.Configuration)
            {
            case FacilityConfiguration.A:
                results.AboveGradePrimaryResults.Add(new Hydrograph("Infiltration to native soil", "cfs", infiltrationToBelowGrade, dt));
                results.AboveGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", overflowToEscapeRoute, dt));
                results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

                results.PercentRockCapacityUsed = -1; // There is no rock gallery.
                break;

            case FacilityConfiguration.B:
                results.AboveGradePrimaryResults.Add(new Hydrograph("Percolation to below grade storage", "cfs", infiltrationToBelowGrade, dt));
                results.AboveGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", overflowToEscapeRoute, dt));

                results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

                results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", infiltrationToBelowGrade, dt));
                results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));

                results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

                break;

            case FacilityConfiguration.C:
                results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));
                results.AboveGradePrimaryResults.Add(new Hydrograph("Flow bypassing growing medium", "cfs", flowOvertoppingToUnderdrain, dt));

                results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

                results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", inflowToRockStorage, dt));
                results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));
                results.BelowGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", rockOverflowToEscapeRoute, dt));

                results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

                break;

            case FacilityConfiguration.D:
                results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));
                results.AboveGradePrimaryResults.Add(new Hydrograph("Flow bypassing growing medium", "cfs", flowOvertoppingToUnderdrain, dt));

                results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

                break;

            case FacilityConfiguration.E:
                results.AboveGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", rockOverflowToEscapeRoute, dt));
                results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));

                results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeSecondaryStoragePercentCapacity, dt));

                results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", inflowToRockStorage, dt));
                results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));

                results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

                results.PercentSurfaceCapacityUsed = aboveGradeSecondaryStoragePercentCapacity.Max();
                break;

            case FacilityConfiguration.F:
                results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));
                results.AboveGradePrimaryResults.Add(new Hydrograph("Flow bypassing growing medium", "cfs", flowOvertoppingToUnderdrain, dt));

                results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

                results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", inflowToRockStorage, dt));
                results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));
                results.BelowGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", rockOverflowToEscapeRoute, dt));

                results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

                break;
            }
            return(results);
        }
Example #24
0
        private void PerformCalculations()
        {
            Facility facility =  ValidateFacility(cmbHierachy.Text, cmbFacilityType.Text, cmbFacilityConfiguration.Text);
              double preCurveNumber = Convert.ToDouble(txtPreCurveNumber.Text);

              int hierarchyNumber = Convert.ToInt32(cmbHierachy.Text);

              PacResults results = PacExecutor.PerformCalculations(facility.Catchment, facility, hierarchyNumber);

              txtPrPassFail.Text = results.PollutionReductionScore.ToString();
              txt10YrPassFail.Text = results.TenYearScore.ToString();
              txtPrPercentCapacity.Text = string.Format("{0:0.0}%", results.PollutionReductionSurfaceCapacity * 100);
              txt10YrPercentCapacity.Text = string.Format("{0:0.0}%", results.TenYearSurfaceCapacity * 100);
              txt2YrPeakInFlow.Text = string.Format("{0:0.000}", results.TwoYearPeakInflow);
              txt5YrPeakInFlow.Text = string.Format("{0:0.000}", results.FiveYearPeakInflow);
              txt10YrPeakInFlow.Text = string.Format("{0:0.000}", results.TenYearPeakInflow);
              txt25YrPeakInFlow.Text = string.Format("{0:0.000}", results.TwentyfiveYearPeakInflow);
              txt2YrPeakFlow.Text = string.Format("{0:0.000}", results.TwoYearPeakOverflow);
              txt5YrPeakFlow.Text = string.Format("{0:0.000}", results.FiveYearPeakOverflow);
              txt10YrPeakFlow.Text = string.Format("{0:0.000}", results.TenYearPeakOverflow);
              txt25YrPeakFlow.Text = string.Format("{0:0.000}", results.TwentyfiveYearPeakOverflow);

              txtPrRockCap.Text = string.Format("{0:0.0}%", results.PollutionReductionPercentRockCapacity * 100);
              txt10YrRockCap.Text = string.Format("{0:0.0}%", results.TenYearPercentRockCapacity * 100);
              txtTotalFacilityArea.Text = string.Format("{0:0}", facility.TotalFacilityAreaSqFt);
              txtSizingFactor.Text = string.Format("{0:0.0}%", facility.FacilitySizingRatio * 100);

              txt10YrOverflowCuFt.Text = string.Format("{0:0.000}", results.TenYearTotalOverflowVolume);
              txtPROverflowCuFt.Text = string.Format("{0:0.000}", results.PollutionReductionTotalOverflowVolume);

              PlotResults(chartPollutionReductionAboveGrade, results.PollutionReductionResults.AboveGradePrimaryResults, results.PollutionReductionResults.AboveGradeSecondaryResults);
              PlotResults(chartPollutionReductionBelowGrade, results.PollutionReductionResults.BelowGradePrimaryResults, results.PollutionReductionResults.BelowGradeSecondaryResults);
              PlotResults(chartTenYearAboveGrade, results.TenYearResults.AboveGradePrimaryResults, results.TenYearResults.AboveGradeSecondaryResults);
              PlotResults(chartTenYearBelowGrade, results.TenYearResults.BelowGradePrimaryResults, results.TenYearResults.BelowGradeSecondaryResults);

              String selected = this.cmbHierachy.SelectedItem as String;
              InfiltrationTestType infiltrationTestType;

              switch (cmbInfiltrationProcedure.SelectedIndex)
              {
              case(0):
              infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
              break;
              case(1):
              infiltrationTestType = InfiltrationTestType.EncasedFallingHead;
              break;
              case(2):
              infiltrationTestType = InfiltrationTestType.DoubleRingInfiltometer;
              break;
              default:
              infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
              break;
              }

              if (selected.Equals("3") || selected.Equals("4"))
              {
              Catchment preCatchment = new Catchment("Pre-Developed Catchment A")
              {
              ImperviousAreaSquareFeet = facility.Catchment.ImperviousAreaSquareFeet,
              AcceptableSeparationFromGroundwater = chkMeetsGroundwaterRequirements.Checked,
              CurveNumber = preCurveNumber,
              TimeOfConcentrationMinutes = facility.Catchment.TimeOfConcentrationMinutes,
              TestedInfiltrationRateInchesPerHour = facility.Catchment.DesignInfiltrationNativeInchesPerHour,
              InfiltrationTestType = infiltrationTestType
              };

              char dischargePoint = 'A';
              switch(this.cmbDischargePoint.SelectedIndex)
              {
              case 0:
                  dischargePoint = 'A';
                  break;
              case 1:
                  dischargePoint = 'B';
                  break;
              case 2:
                  dischargePoint = 'C';
                  break;
              default:
                  dischargePoint = 'A';
                  break;
              }

              results = PacExecutor.PerformCalculations(facility.Catchment, preCatchment, facility, hierarchyNumber, dischargePoint);

              txtPre2YrPeakFlow.Text = string.Format("{0:0.000}", results.PreDevelopedTwoYearPeakInflow);
              txtPre5YrPeakFlow.Text = string.Format("{0:0.000}", results.PreDevelopedFiveYearPeakInflow);
              txtPre10YrPeakFlow.Text = string.Format("{0:0.000}", results.PreDevelopedTenYearPeakInflow);
              txtPre25YrPeakFlow.Text = string.Format("{0:0.000}", results.PreDevelopedTwentyfiveYearPeakInflow);
              tblPeakTable.RowStyles[1].SizeType = SizeType.AutoSize;
              if(selected.Equals("3"))
              {
              switch (this.cmbDischargePoint.SelectedIndex)
              {
                  case 0:
                      lbl2YrPassFail.Text = "N/A";
                      lbl5YrPassFail.Text = "N/A";
                      lbl10YrPassFail.Text = "N/A";
                      lbl25YrPassFail.Text = "N/A";
                      break;
                  case 1:
                      lbl2YrPassFail.Text = results.TwoYearPeakOverflow <= (results.PreDevelopedTwoYearPeakInflow/2) ? "Pass" : "Fail";
                      lbl5YrPassFail.Text = results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow ? "Pass" : "Fail";
                      lbl10YrPassFail.Text = results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow ? "Pass" : "Fail";
                      lbl25YrPassFail.Text = results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTwentyfiveYearPeakInflow ? "Pass" : "Fail";
                      break;
                  case 2:
                      lbl2YrPassFail.Text = results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow ? "Pass" : "Fail";
                      lbl5YrPassFail.Text = results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow ? "Pass" : "Fail";
                      lbl10YrPassFail.Text = results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow ? "Pass" : "Fail";
                      lbl25YrPassFail.Text = "N/A";
                      break;
                  default:
                      lbl2YrPassFail.Text = "N/A";
                      lbl5YrPassFail.Text = "N/A";
                      lbl10YrPassFail.Text = "N/A";
                      lbl25YrPassFail.Text = "N/A";
                      break;
              }
              }
              else
              {
              lbl2YrPassFail.Text = "N/A";
              lbl5YrPassFail.Text = "N/A";
              lbl10YrPassFail.Text = "N/A";
              lbl25YrPassFail.Text = results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow ? "Pass" : "Fail";
              }
              }
              else
              {
              tblPeakTable.RowStyles[1].SizeType = SizeType.Absolute;
              tblPeakTable.RowStyles[1].Height = 0;
              lbl2YrPassFail.Text = "N/A";
              lbl5YrPassFail.Text = "N/A";
              lbl10YrPassFail.Text = "N/A";
              lbl25YrPassFail.Text = "N/A";
              }
              lblFlowControlScore.Text = results.FlowControlScore.ToString();
              lbl2YrPassFail.Text = results.TwoYearFlowControlScore.ToString();
              lbl5YrPassFail.Text = results.FiveYearFlowControlScore.ToString();
              lbl10YrPassFail.Text = results.TenYearFlowControlScore.ToString();
              lbl25YrPassFail.Text = results.TwentyfiveYearFlowControlScore.ToString();
        }
Example #25
0
        private void PerformCalculations()
        {
            Facility facility       = ValidateFacility(cmbHierachy.Text, cmbFacilityType.Text, cmbFacilityConfiguration.Text);
            double   preCurveNumber = Convert.ToDouble(txtPreCurveNumber.Text);

            int hierarchyNumber = Convert.ToInt32(cmbHierachy.Text);

            PacResults results = PacExecutor.PerformCalculations(facility.Catchment, facility, hierarchyNumber);

            txtPrPassFail.Text          = results.PollutionReductionScore.ToString();
            txt10YrPassFail.Text        = results.TenYearScore.ToString();
            txtPrPercentCapacity.Text   = string.Format("{0:0.0}%", results.PollutionReductionSurfaceCapacity * 100);
            txt10YrPercentCapacity.Text = string.Format("{0:0.0}%", results.TenYearSurfaceCapacity * 100);
            txt2YrPeakInFlow.Text       = string.Format("{0:0.000}", results.TwoYearPeakInflow);
            txt5YrPeakInFlow.Text       = string.Format("{0:0.000}", results.FiveYearPeakInflow);
            txt10YrPeakInFlow.Text      = string.Format("{0:0.000}", results.TenYearPeakInflow);
            txt25YrPeakInFlow.Text      = string.Format("{0:0.000}", results.TwentyfiveYearPeakInflow);
            txt2YrPeakFlow.Text         = string.Format("{0:0.000}", results.TwoYearPeakOverflow);
            txt5YrPeakFlow.Text         = string.Format("{0:0.000}", results.FiveYearPeakOverflow);
            txt10YrPeakFlow.Text        = string.Format("{0:0.000}", results.TenYearPeakOverflow);
            txt25YrPeakFlow.Text        = string.Format("{0:0.000}", results.TwentyfiveYearPeakOverflow);

            txtPrRockCap.Text         = string.Format("{0:0.0}%", results.PollutionReductionPercentRockCapacity * 100);
            txt10YrRockCap.Text       = string.Format("{0:0.0}%", results.TenYearPercentRockCapacity * 100);
            txtTotalFacilityArea.Text = string.Format("{0:0}", facility.TotalFacilityAreaSqFt);
            txtSizingFactor.Text      = string.Format("{0:0.0}%", facility.FacilitySizingRatio * 100);

            txt10YrOverflowCuFt.Text = string.Format("{0:0.000}", results.TenYearTotalOverflowVolume);
            txtPROverflowCuFt.Text   = string.Format("{0:0.000}", results.PollutionReductionTotalOverflowVolume);

            PlotResults(chartPollutionReductionAboveGrade, results.PollutionReductionResults.AboveGradePrimaryResults, results.PollutionReductionResults.AboveGradeSecondaryResults);
            PlotResults(chartPollutionReductionBelowGrade, results.PollutionReductionResults.BelowGradePrimaryResults, results.PollutionReductionResults.BelowGradeSecondaryResults);
            PlotResults(chartTenYearAboveGrade, results.TenYearResults.AboveGradePrimaryResults, results.TenYearResults.AboveGradeSecondaryResults);
            PlotResults(chartTenYearBelowGrade, results.TenYearResults.BelowGradePrimaryResults, results.TenYearResults.BelowGradeSecondaryResults);

            String selected = this.cmbHierachy.SelectedItem as String;
            InfiltrationTestType infiltrationTestType;

            switch (cmbInfiltrationProcedure.SelectedIndex)
            {
            case (0):
                infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
                break;

            case (1):
                infiltrationTestType = InfiltrationTestType.EncasedFallingHead;
                break;

            case (2):
                infiltrationTestType = InfiltrationTestType.DoubleRingInfiltometer;
                break;

            default:
                infiltrationTestType = InfiltrationTestType.OpenPitFallingHead;
                break;
            }

            if (selected.Equals("3") || selected.Equals("4"))
            {
                Catchment preCatchment = new Catchment("Pre-Developed Catchment A")
                {
                    ImperviousAreaSquareFeet            = facility.Catchment.ImperviousAreaSquareFeet,
                    AcceptableSeparationFromGroundwater = chkMeetsGroundwaterRequirements.Checked,
                    CurveNumber = preCurveNumber,
                    TimeOfConcentrationMinutes          = facility.Catchment.TimeOfConcentrationMinutes,
                    TestedInfiltrationRateInchesPerHour = facility.Catchment.DesignInfiltrationNativeInchesPerHour,
                    InfiltrationTestType = infiltrationTestType
                };

                char dischargePoint = 'A';
                switch (this.cmbDischargePoint.SelectedIndex)
                {
                case 0:
                    dischargePoint = 'A';
                    break;

                case 1:
                    dischargePoint = 'B';
                    break;

                case 2:
                    dischargePoint = 'C';
                    break;

                default:
                    dischargePoint = 'A';
                    break;
                }

                results = PacExecutor.PerformCalculations(facility.Catchment, preCatchment, facility, hierarchyNumber, dischargePoint);

                txtPre2YrPeakFlow.Text             = string.Format("{0:0.000}", results.PreDevelopedTwoYearPeakInflow);
                txtPre5YrPeakFlow.Text             = string.Format("{0:0.000}", results.PreDevelopedFiveYearPeakInflow);
                txtPre10YrPeakFlow.Text            = string.Format("{0:0.000}", results.PreDevelopedTenYearPeakInflow);
                txtPre25YrPeakFlow.Text            = string.Format("{0:0.000}", results.PreDevelopedTwentyfiveYearPeakInflow);
                tblPeakTable.RowStyles[1].SizeType = SizeType.AutoSize;
                if (selected.Equals("3"))
                {
                    switch (this.cmbDischargePoint.SelectedIndex)
                    {
                    case 0:
                        lbl2YrPassFail.Text  = "N/A";
                        lbl5YrPassFail.Text  = "N/A";
                        lbl10YrPassFail.Text = "N/A";
                        lbl25YrPassFail.Text = "N/A";
                        break;

                    case 1:
                        lbl2YrPassFail.Text  = results.TwoYearPeakOverflow <= (results.PreDevelopedTwoYearPeakInflow / 2) ? "Pass" : "Fail";
                        lbl5YrPassFail.Text  = results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow ? "Pass" : "Fail";
                        lbl10YrPassFail.Text = results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow ? "Pass" : "Fail";
                        lbl25YrPassFail.Text = results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTwentyfiveYearPeakInflow ? "Pass" : "Fail";
                        break;

                    case 2:
                        lbl2YrPassFail.Text  = results.TwoYearPeakOverflow <= results.PreDevelopedTwoYearPeakInflow ? "Pass" : "Fail";
                        lbl5YrPassFail.Text  = results.FiveYearPeakOverflow <= results.PreDevelopedFiveYearPeakInflow ? "Pass" : "Fail";
                        lbl10YrPassFail.Text = results.TenYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow ? "Pass" : "Fail";
                        lbl25YrPassFail.Text = "N/A";
                        break;

                    default:
                        lbl2YrPassFail.Text  = "N/A";
                        lbl5YrPassFail.Text  = "N/A";
                        lbl10YrPassFail.Text = "N/A";
                        lbl25YrPassFail.Text = "N/A";
                        break;
                    }
                }
                else
                {
                    lbl2YrPassFail.Text  = "N/A";
                    lbl5YrPassFail.Text  = "N/A";
                    lbl10YrPassFail.Text = "N/A";
                    lbl25YrPassFail.Text = results.TwentyfiveYearPeakOverflow <= results.PreDevelopedTenYearPeakInflow ? "Pass" : "Fail";
                }
            }
            else
            {
                tblPeakTable.RowStyles[1].SizeType = SizeType.Absolute;
                tblPeakTable.RowStyles[1].Height   = 0;
                lbl2YrPassFail.Text  = "N/A";
                lbl5YrPassFail.Text  = "N/A";
                lbl10YrPassFail.Text = "N/A";
                lbl25YrPassFail.Text = "N/A";
            }
            lblFlowControlScore.Text = results.FlowControlScore.ToString();
            lbl2YrPassFail.Text      = results.TwoYearFlowControlScore.ToString();
            lbl5YrPassFail.Text      = results.FiveYearFlowControlScore.ToString();
            lbl10YrPassFail.Text     = results.TenYearFlowControlScore.ToString();
            lbl25YrPassFail.Text     = results.TwentyfiveYearFlowControlScore.ToString();
        }
Example #26
0
        /// <summary>
        /// Contains algorithims implementing the sizing calculations for various facility configurations
        /// </summary>
        /// <param name="facility"></param>
        /// <param name="category"></param>
        /// <param name="catchment"></param>
        /// <param name="inflowHydrograph"></param>
        /// <returns></returns>
        public static StormEventResults PerformCalculations(Facility facility, HierarchyCategory category, Catchment catchment, Hydrograph inflowHydrograph)
        {
            string message;
              Facility.Validate(facility, Convert.ToInt32(category), out message);

              if (!facility.IsValid)
            throw new ArgumentException("Unable to perform calculations: failed validation with message '" + message + "'");

              double dt = inflowHydrograph.TimeStepMinutes;
              int timeSteps = inflowHydrograph.AsArray().Count();

              double inflowFromRain;
              double inflowVolume;
              double inflowVolumeCummulative = 0;

              double[] surfaceInfiltrationCapacity = new double[timeSteps]; //Column E, aka Percolation Capacity
              double initialInfiltrationToAmendedSoil;
              double[] storedToBeInfiltrated = new double[timeSteps];

              double graphLocator = 0;
              double potentialExtraInfiltration;

              double cumulativeInfiltrationVolume = 0; //Column J

              double additionalInfiltrationFromStorage; //Column K

              double[] totalInfiltrationCapacityToBelowGrade = new double[timeSteps]; //Column L

              double inflowToSurfaceStorageAfterInfiltration; //Column M

              double[] inflowMinusInfiltration = new double[timeSteps]; //Column N

              double surfaceStorageCumulativeVolume = 0; //Column O,P,Q,R combined.

              double[] flowOvertoppingToUnderdrain = new double[timeSteps]; //Column T (or Column W for type E)

              double[] infiltrationToBelowGrade = new double[timeSteps]; //Column Z
              double[] totalFlowToBelowGrade = new double[timeSteps]; //Column AA
              double[] inflowToRockStorage = new double[timeSteps]; //column AB

              double[] totalInfiltrationCapacityToNative = new double[timeSteps]; //Column AE
              double totalInfiltratedToNative = 0;

              double rockStorageCumulativeVolume = 0; //Column AJ

              double[] rockPercentCapacity = new double[timeSteps]; //Column AK/AL for A,B&E facilities; Column AR/AS for C&F;

              double excessRockCumulativeVolume = 0; //Column AM
              double underdrainStorageAreaCumulativeVolume = 0; //Column AR

              double[] aboveGradeStoragePercentCapacity = new double[timeSteps]; //Column AO for A,B facilities; Column S for C,D&F
              double[] aboveGradeSecondaryStoragePercentCapacity = new double[timeSteps]; //Column AO for E facilities

              double[] rockOverflowToEscapeRoute = new double[timeSteps]; //Column AP
              double[] overflowToEscapeRoute = new double[timeSteps]; //Column AQ for A,B,D,E,F facilities; Column AT for C&F

              double nativeInfiltrationRate = facility.NativeSoilInfiltrationCapacityCfs();
              double growingMediumInfiltrationRate = facility.ImportedMediumInfiltrationCapacityCfs();

              //The Lag Index is a property of the growing medium depth and infiltration rate that
              //corresponds to the number of time steps it will take for water to percolate through the
              //growing medium. The infiltration hydrograph to the rock medium is delayed by the lag index.
              //For facility configurations A, B, and E, no lag is applied when the native infiltration rate is less
              //than the growing medium infilration rate.
              double lagFactor =
            (facility.Configuration == FacilityConfiguration.A ||
            facility.Configuration == FacilityConfiguration.B ||
            facility.Configuration == FacilityConfiguration.E) &&
            nativeInfiltrationRate < growingMediumInfiltrationRate ? 0 :
            facility.GrowingMediumPorespace;

              double lagTime = facility.GrowingMediumDepthIn / catchment.ImportedMediumInfiltrationInchesPerHour * 60 * lagFactor;
              int lag = (int)Math.Ceiling(lagTime / inflowHydrograph.TimeStepMinutes); // Rounding up is perfored in the current calculator. This may be unnecessary.

              for (int i = 0; i < timeSteps; i++)
              {
            inflowFromRain = inflowHydrograph.AsArray()[i];
            inflowVolume = inflowFromRain * 600;
            inflowVolumeCummulative += inflowVolume;

            //Facility configurations A,B, and D have rock-influenced surface storage demand. When
            //the rock storage is full, infiltration rates in the growing medium can be limited by
            //infiltration rates of the native soil.
            if (facility.HasRockInfluencedSurfaceStorage && rockPercentCapacity[Math.Max(1, i - 1)] >= 1)
              surfaceInfiltrationCapacity[i] = Math.Min(growingMediumInfiltrationRate, nativeInfiltrationRate);
            else
              surfaceInfiltrationCapacity[i] = growingMediumInfiltrationRate;

            initialInfiltrationToAmendedSoil =
              Math.Min(inflowFromRain, surfaceInfiltrationCapacity[i]);

            storedToBeInfiltrated[i] = Math.Max(inflowFromRain - initialInfiltrationToAmendedSoil, 0) * 600;

            graphLocator =
            storedToBeInfiltrated[i] - storedToBeInfiltrated[Math.Max(1, i - 1)] < 0 ?
            1 : graphLocator;

            potentialExtraInfiltration =
              (surfaceInfiltrationCapacity[i] - initialInfiltrationToAmendedSoil) * graphLocator;

            cumulativeInfiltrationVolume += (potentialExtraInfiltration * 600);

              // Existing spreadsheet rounds up storageToBeInfiltrated to nearest ten,
              // allowing more potentialExtraInfiltration to fill rock storage. This may be unnecessary...
            double storedToBeInfiltratedRoundedUp = Math.Ceiling(storedToBeInfiltrated.Sum()/10)*10;
            double cumulativeInfiltrationVolumeRounded = Math.Round(cumulativeInfiltrationVolume, 10); // Added 6/24/2015 to deal with binary storage of floating point numbers without changing to decimal data type

            additionalInfiltrationFromStorage =
              cumulativeInfiltrationVolumeRounded > storedToBeInfiltratedRoundedUp || cumulativeInfiltrationVolumeRounded > facility.SurfaceCapacityAtDepth1CuFt ?
              0 : potentialExtraInfiltration;

            totalInfiltrationCapacityToBelowGrade[i] = initialInfiltrationToAmendedSoil + additionalInfiltrationFromStorage;

            inflowToSurfaceStorageAfterInfiltration = Math.Max(inflowFromRain - totalInfiltrationCapacityToBelowGrade[i], 0);

            inflowMinusInfiltration[i] = inflowFromRain - surfaceInfiltrationCapacity[i];

            surfaceStorageCumulativeVolume += (inflowMinusInfiltration[i] * 600);

            surfaceStorageCumulativeVolume = Math.Max(surfaceStorageCumulativeVolume, 0);
            surfaceStorageCumulativeVolume = Math.Min(surfaceStorageCumulativeVolume, facility.SurfaceCapacityAtDepth1CuFt);

            flowOvertoppingToUnderdrain[i] =
              surfaceStorageCumulativeVolume < facility.SurfaceCapacityAtDepth1CuFt ?
              0 : inflowToSurfaceStorageAfterInfiltration;

            if (i - lag < 0)
            infiltrationToBelowGrade[i] = totalInfiltrationCapacityToBelowGrade[0];
            else
            infiltrationToBelowGrade[i] = totalInfiltrationCapacityToBelowGrade[i - lag];

            totalFlowToBelowGrade[i] = infiltrationToBelowGrade[i] + flowOvertoppingToUnderdrain[i];

            if (facility.Configuration == FacilityConfiguration.E || facility.Configuration == FacilityConfiguration.F)
              inflowToRockStorage[i] = totalFlowToBelowGrade[i];
            else
              inflowToRockStorage[i] = infiltrationToBelowGrade[i];

            totalInfiltrationCapacityToNative[i] = nativeInfiltrationRate;

            if (rockStorageCumulativeVolume + inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i] < 0)
            totalInfiltratedToNative += rockStorageCumulativeVolume + inflowToRockStorage[i];
            else
            totalInfiltratedToNative += totalInfiltrationCapacityToNative[i];

            rockStorageCumulativeVolume += ((inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i]) * 600);

            excessRockCumulativeVolume = rockStorageCumulativeVolume < facility.RockStorageCapacityCuFt ?
              0 : rockStorageCumulativeVolume - facility.RockStorageCapacityCuFt;

            rockStorageCumulativeVolume = Math.Max(rockStorageCumulativeVolume, 0);

            if (facility.HasRockInfluencedSurfaceStorage)
            {
              aboveGradeStoragePercentCapacity[i] =
              (surfaceStorageCumulativeVolume + excessRockCumulativeVolume) /
              facility.SurfaceCapacityAtDepth1CuFt;
              //E facilities have a secondary storage volume
              if (facility.HasSecondaryOverflow)
              {
            aboveGradeSecondaryStoragePercentCapacity[i] =
            (surfaceStorageCumulativeVolume + excessRockCumulativeVolume) /
            facility.SurfaceCapacityAtDepth2CuFt;
            aboveGradeSecondaryStoragePercentCapacity[i] = Math.Min(aboveGradeSecondaryStoragePercentCapacity[i], 1);
              }
            }
            //C, D, and F facilities have a direct connection from the rock gallery to an overflow,
            //and therefore above grade storage capacity is independent of rock gallery volume
            else
            {
              aboveGradeStoragePercentCapacity[i] =
            surfaceStorageCumulativeVolume / facility.SurfaceCapacityAtDepth1CuFt;
            }
            aboveGradeStoragePercentCapacity[i] = Math.Min(aboveGradeStoragePercentCapacity[i], 1);

            if (facility.HasRockInfluencedSurfaceStorage && !facility.HasSecondaryOverflow) // A, B
            {
            // Added 6/22/2015 to handle case where surface is full, but should overflow more due to limited rock gallery.
            // This will occur only once during a storm, as the next cycle will limit above grade infiltration to the rock gallery
            // and overflow the correct amount.
            double belowGradeInflowMinusInfiltration = inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i];
            if (aboveGradeStoragePercentCapacity[i] == 1 && belowGradeInflowMinusInfiltration > 0 )
                rockOverflowToEscapeRoute[i] = belowGradeInflowMinusInfiltration;
            else
                rockOverflowToEscapeRoute[i] = 0;

            rockPercentCapacity[i] = facility.HasRockStorage ?
              rockStorageCumulativeVolume / facility.RockStorageCapacityCuFt : 1;
            rockPercentCapacity[i] = Math.Min(rockPercentCapacity[i], 1);
            }
            else if (facility.HasSecondaryOverflow) // E
            {
              rockOverflowToEscapeRoute[i] = aboveGradeSecondaryStoragePercentCapacity[i] < 1 ? 0 :
              Math.Max(totalFlowToBelowGrade[i] - facility.NativeSoilInfiltrationCapacityCfs(), 0);

              rockPercentCapacity[i] = facility.HasRockStorage ?
            rockStorageCumulativeVolume / facility.RockStorageCapacityCuFt : 1;
              rockPercentCapacity[i] = Math.Min(rockPercentCapacity[i], 1);
            }
            else if (!facility.HasRockInfluencedSurfaceStorage) // C, D & F
            {
              underdrainStorageAreaCumulativeVolume +=
            ((inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i]) * 600);
              underdrainStorageAreaCumulativeVolume = Math.Max(underdrainStorageAreaCumulativeVolume, 0);
              underdrainStorageAreaCumulativeVolume = Math.Min(underdrainStorageAreaCumulativeVolume, facility.RockStorageCapacityCuFt);

              if ((underdrainStorageAreaCumulativeVolume / facility.RockStorageCapacityCuFt >= 1) || facility.RockStorageCapacityCuFt == 0) // Added facility.RockStorageCapacityCuFt for 0/0 case
            rockOverflowToEscapeRoute[i] = inflowToRockStorage[i] - totalInfiltrationCapacityToNative[i];

              rockPercentCapacity[i] = facility.HasRockStorage ?
            underdrainStorageAreaCumulativeVolume / facility.RockStorageCapacityCuFt : 1;
              rockPercentCapacity[i] = Math.Min(rockPercentCapacity[i], 1);
            }

            if (facility.Configuration == FacilityConfiguration.F // Facility F is different, in that overflow from the surface goes to the subsurface
              || facility.Configuration == FacilityConfiguration.E) // Facility E is strange also, in that the flow overtopping to the underdrain doesn't also go to the escape route.
            overflowToEscapeRoute[i] = excessRockCumulativeVolume > 0 ? rockOverflowToEscapeRoute[i] : 0;
            else
            overflowToEscapeRoute[i] = excessRockCumulativeVolume > 0 ?
                flowOvertoppingToUnderdrain[i] + rockOverflowToEscapeRoute[i] : flowOvertoppingToUnderdrain[i];
              }

              StormEventResults results = new StormEventResults();

              results.PeakSurfaceOverflow = flowOvertoppingToUnderdrain.Max();
              results.PeakOverflow = overflowToEscapeRoute.Max();
              results.OverflowVolume = overflowToEscapeRoute.Sum() * 600;

              results.PercentSurfaceCapacityUsed = aboveGradeStoragePercentCapacity.Max();
              results.PercentRockCapacityUsed = rockPercentCapacity.Max();

              results.InflowVolume = inflowHydrograph.AsArray().Sum() * 600;
              results.PeakInflowRate = inflowHydrograph.AsArray().Max();

              results.AboveGradePrimaryResults.Add(new Hydrograph("Inflow from rain", "cfs", inflowHydrograph.AsArray(), dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", surfaceInfiltrationCapacity, dt));

              switch (facility.Configuration)
              {
              case FacilityConfiguration.A:
              results.AboveGradePrimaryResults.Add(new Hydrograph("Infiltration to native soil", "cfs", infiltrationToBelowGrade, dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", overflowToEscapeRoute, dt));
              results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

              results.PercentRockCapacityUsed = -1; // There is no rock gallery.
              break;
              case FacilityConfiguration.B:
              results.AboveGradePrimaryResults.Add(new Hydrograph("Percolation to below grade storage", "cfs", infiltrationToBelowGrade, dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", overflowToEscapeRoute, dt));

              results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

              results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", infiltrationToBelowGrade, dt));
              results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));

              results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

              break;
              case FacilityConfiguration.C:
              results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Flow bypassing growing medium", "cfs", flowOvertoppingToUnderdrain, dt));

              results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

              results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", inflowToRockStorage, dt));
              results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));
              results.BelowGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", rockOverflowToEscapeRoute, dt));

              results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

              break;
              case FacilityConfiguration.D:
              results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Flow bypassing growing medium", "cfs", flowOvertoppingToUnderdrain, dt));

              results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

              break;
              case FacilityConfiguration.E:
              results.AboveGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", rockOverflowToEscapeRoute, dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));

              results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeSecondaryStoragePercentCapacity, dt));

              results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", inflowToRockStorage, dt));
              results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));

              results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

              results.PercentSurfaceCapacityUsed = aboveGradeSecondaryStoragePercentCapacity.Max();
              break;
              case FacilityConfiguration.F:
              results.AboveGradePrimaryResults.Add(new Hydrograph("Total flow to below grade storage", "cfs", inflowToRockStorage, dt));
              results.AboveGradePrimaryResults.Add(new Hydrograph("Flow bypassing growing medium", "cfs", flowOvertoppingToUnderdrain, dt));

              results.AboveGradeSecondaryResults.Add(new Hydrograph("Percent surface capacity", "%", aboveGradeStoragePercentCapacity, dt));

              results.BelowGradePrimaryResults.Add(new Hydrograph("Inflow to rock storage", "cfs", inflowToRockStorage, dt));
              results.BelowGradePrimaryResults.Add(new Hydrograph("Infiltration capacity", "cfs", totalInfiltrationCapacityToNative, dt));
              results.BelowGradePrimaryResults.Add(new Hydrograph("Overflow to approved discharge", "cfs", rockOverflowToEscapeRoute, dt));

              results.BelowGradeSecondaryResults.Add(new Hydrograph("Percent rock capacity", "%", rockPercentCapacity, dt));

              break;
              }
              return results;
        }
Example #27
0
 /// <summary>
 /// Constructor for a sloped facility
 /// </summary>
 /// <param name="type">The FacilityType; should be Swale or SlopedPlanter</param>
 /// <param name="configuration">The Configuration of the facility</param>
 /// <param name="catchment">The catchment for the facility</param>
 /// <param name="segments">A list of Segments to load the facility with</param>
 public SlopedFacility(FacilityType type, FacilityConfiguration configuration, Catchment catchment, List<SlopedFacilitySegment> segments)
     : base(type, configuration, catchment)
 {
     _segments = segments;
       SlopedFacility._this = this;
 }
Example #28
0
 /// <summary>
 /// Constructor for a sloped facility
 /// </summary>
 /// <param name="type">The FacilityType; should be Swale or SlopedPlanter</param>
 /// <param name="configuration">The Configuration of the facility</param>
 /// <param name="catchment">The catchment for the facility</param>
 /// <param name="segments">A list of Segments to load the facility with</param>
 public SlopedFacility(FacilityType type, FacilityConfiguration configuration, Catchment catchment, List <SlopedFacilitySegment> segments)
     : base(type, configuration, catchment)
 {
     _segments            = segments;
     SlopedFacility._this = this;
 }