예제 #1
0
        public override LinkSourceSinkModel CloneForMultipleDivisions()
        {
            return(new InstreamDOC
            {
                IsFloodplain = IsFloodplain,

                MaxAccumulationArea = MaxAccumulationArea,

                LeafAccumulationConstant = LeafAccumulationConstant,

                ReaerationCoefficient = ReaerationCoefficient,

                LeafA = LeafA,

                LeafK1 = LeafK1,

                LeafK2 = LeafK2,

                InitialLeafDryMatterReadilyDegradable = InitialLeafDryMatterReadilyDegradable.Clone(),
                InitialLeafDryMatterNonReadilyDegradable = InitialLeafDryMatterNonReadilyDegradable.Clone(),

                PrimaryProductionReaeration = PrimaryProductionReaeration,

                WaterTemperature = WaterTemperature,

                FirstOrderDOCReleaseRateAt20DegreeC = FirstOrderDOCReleaseRateAt20DegreeC,
                FirstOrderDOCReleaseRateAt20DegreeCNonReadily = FirstOrderDOCReleaseRateAt20DegreeCNonReadily,
                MaxDOCReleasedAt20DegreeC = MaxDOCReleasedAt20DegreeC,
                MaxDOCReleasedAt20DegreeCNonReadily = MaxDOCReleasedAt20DegreeCNonReadily,
                DOCDecayConstantAt20DegreeC = DOCDecayConstantAt20DegreeC,

                ProductionCoefficients = ProductionCoefficients?.ToArray(),
                ProductionBreaks = ProductionBreaks?.ToArray(),

                StructureRerationCoefficient = StructureRerationCoefficient,
                WaterQualityFactor = WaterQualityFactor,
                StaticHeadLoss = StaticHeadLoss,
            });
        }
예제 #2
0
        /// <summary>
        /// Initialises the Zones using the "InitialLeafDryMatter" lookup tables
        ///
        /// The precise logic used here depends on the nature of the <see cref="Zones"/> collection
        /// </summary>
        private void InitialiseMultipleZones()
        {
            // Get the min and max heights of the storage
            var minHeight = FloodplainElevation;
            var maxHeight = Areal.MaxElevation;

            // Build a collection of all the unique points when the leaf matter changes
            // Include the Min and Max elevations as valid points
            var uniqueHeights = new List <double>
            {
                minHeight,
                maxHeight
            };

            foreach (var height in InitialLeafDryMatterReadilyDegradable.ToUnsortedArray().Select(p => p.Key))
            {
                if (height > minHeight)
                {
                    uniqueHeights.Add(height);
                }
            }

            foreach (var height in InitialLeafDryMatterNonReadilyDegradable.ToUnsortedArray().Select(p => p.Key))
            {
                if (height > minHeight)
                {
                    uniqueHeights.Add(height);
                }
            }

            // Add the current elevation
            uniqueHeights.Add(Elevation);

            // Process in increasing order
            var increasingHeights = uniqueHeights.OrderBy(h => h).ToArray();


            // Due to the odd nature of the Zones collection, we shall sort the Zones into Dry and Wet
            var increasingWetZoneArray = new List <FloodplainData>();
            var tempDryZoneArray       = new List <FloodplainData>();

            var previousCumulativeArea = 0.0;

            // Create the first zone from the lowest height to the next lowest height
            var previousHeight = increasingHeights[0];

            for (var i = 1; i < increasingHeights.Length; i++)
            {
                var height = increasingHeights[i];
                // Avoid duplicates
                if (height.EqualWithTolerance(previousHeight))
                {
                    continue;
                }

                // Anything at or below the current storage level is considered Wet
                var isWet = height <= Elevation;

                var area = Fac * Areal.AreaForHeightLookup(height);

                // Get the initial leaf matter settings
                var leafDryMatterNonReadilyDegradable =
                    IntergrateElevationsForAccumulation(
                        previousHeight,
                        height,
                        InitialLeafDryMatterNonReadilyDegradable);

                var leafDryMatterReadilyDegradable =
                    IntergrateElevationsForAccumulation(
                        previousHeight,
                        height,
                        InitialLeafDryMatterReadilyDegradable);

                // Create the zone
                var newZone = new FloodplainData(isWet)
                {
                    CumulativeAreaM2 = area,

                    // Set the area this zone covers
                    ZoneAreaM2 = area - previousCumulativeArea,
                    ElevationM = height,
                    LeafDryMatterNonReadilyDegradable = leafDryMatterNonReadilyDegradable,
                    LeafDryMatterReadilyDegradable    = leafDryMatterReadilyDegradable,
                };

                // Keep track of the last area
                previousCumulativeArea = area;
                previousHeight         = height;

                // Sort the zone into wet and dry
                if (newZone.Dry)
                {
                    tempDryZoneArray.Add(newZone);
                }
                else
                {
                    increasingWetZoneArray.Add(newZone);
                }
            }

            // The Zones collection has a very specific state.
            // This state has been carried over (presumably) from the FORTRAN implemenation.
            // The rules are...
            // 1. Dry zones are grouped together and come first in the collection
            // 2. Dry zones are ordered by DECREASING area
            // 3. Wet zones are grouped together and come last in the collection
            // 4. Wet zones are ordered by INCREASING area

            tempDryZoneArray.Reverse();
            Zones.AddRange(tempDryZoneArray);
            Zones.AddRange(increasingWetZoneArray);

            // Also set the PreviousArea to the current Area so the Zones arenconsidered "stable" on the first timestep
            PreviousArea = Areal.Area;
        }