public InstreamDOC() { InitialLeafDryMatterNonReadilyDegradable = new LinearPerPartFunction(); InitialLeafDryMatterReadilyDegradable = new LinearPerPartFunction(); LeafA = new LinearPerPartFunction(); // set default values DOCDecayConstantAt20DegreeC = 0.03; FirstOrderDOCReleaseRateAt20DegreeC = 0.86; FirstOrderDOCReleaseRateAt20DegreeCNonReadily = 0.125; LeafK1 = 0.03; LeafK2 = 0.003; MaxDOCReleasedAt20DegreeC = 80; MaxDOCReleasedAt20DegreeCNonReadily = 10; ReaerationCoefficient = 0.08; StructureRerationCoefficient = 0.6; WaterQualityFactor = 0.65; WaterTemperature = 20; }
public StorageDOC() { InitialLeafDryMatterNonReadilyDegradable = new LinearPerPartFunction(); InitialLeafDryMatterReadilyDegradable = new LinearPerPartFunction(); LeafA = new LinearPerPartFunction(); // set default values DOCDecayConstantAt20DegreeC = 0.03; FirstOrderDOCReleaseRateAt20DegreeC = 0.86; FirstOrderDOCReleaseRateAt20DegreeCNonReadily = 0.125; LeafK1 = 0.03; LeafK2 = 0.003; MaxDOCReleasedAt20DegreeC = 80; MaxDOCReleasedAt20DegreeCNonReadily = 10; ReaerationCoefficient = 0.08; StructureRerationCoefficient = 0.6; WaterQualityFactor = 0.65; WaterTemperature = 20; _heightForSurfaceAreaLookup = surfaceArea => { var points = StorageModel.StoreGeometry.Cast <DiscreteStoreGeometryEntry>().ToList(); for (var i = 0; i < points.Count; i++) { var point = points[i]; if (i == points.Count - 1) { var lowerPoint = points[i - 1]; return(MathUtils.linearInterpolation(surfaceArea, lowerPoint.surfaceArea, lowerPoint.height, point.surfaceArea, point.height)); } var nextPoint = points[i + 1]; if (surfaceArea >= point.surfaceArea && surfaceArea <= nextPoint.surfaceArea) { return(MathUtils.linearInterpolation(surfaceArea, point.surfaceArea, point.height, nextPoint.surfaceArea, nextPoint.height)); } } throw new Exception($"Could not lookup height for surface area: {surfaceArea}"); }; }
protected DoDocModel() { InitialLeafDryMatterNonReadilyDegradable = new LinearPerPartFunction(); InitialLeafDryMatterReadilyDegradable = new LinearPerPartFunction(); }
private double IntergrateElevationsForAccumulation(double lowerElevation, double upperElevation, LinearPerPartFunction accumulationLookup) { var lowerLoad = accumulationLookup.f(lowerElevation); var upperLoad = accumulationLookup.f(upperElevation); var elevationPoints = accumulationLookup.Select(p => p.Key).Where(p => p > lowerElevation && p < upperElevation).ToArray(); var loads = elevationPoints.Select(p => accumulationLookup.f(p)).ToList(); //change here, get all loads, not sum var areas = elevationPoints.Select(p => Areal.AreaForHeightLookup(p) * 0.0001).ToList(); // get areas as well loads.Insert(0, lowerLoad); loads.Add(upperLoad); areas.Insert(0, Areal.AreaForHeightLookup(lowerElevation) * 0.0001); areas.Add(Areal.AreaForHeightLookup(upperElevation) * 0.0001); var lowerElevationPoints = accumulationLookup.Where(p => p.Key < lowerElevation); var previousElevationPoint = lowerElevationPoints.Any() ? lowerElevationPoints.Last().Key : lowerElevation; var previousLoad = accumulationLookup.f(previousElevationPoint); var previousArea = Areal.AreaForHeightLookup(previousElevationPoint) * 0.0001; var totalLoad = 0d; var totalAreaBetween = 0d; // start at the second element for (var i = 0; i < loads.Count; i++) { double pArea; double pLoad; if (i == 0) { pArea = previousArea; pLoad = previousLoad; } else { pArea = areas[i - 1]; pLoad = loads[i - 1]; } var areaBetween = areas[i] - pArea; totalLoad += areaBetween * (loads[i] + pLoad) / 2; totalAreaBetween += areaBetween; } // if we're accumulating across no area then our rate is 0 if (totalAreaBetween <= 0) { return(0); } return(totalLoad / totalAreaBetween); }