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, }); }
/// <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; }