diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index 49e825daa165913cbd2e5c337cbb25e3272d10ab..0ff2b1891a239133175e7e09e2e4fc8c00bc6a7b 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -98,6 +98,7 @@ namespace TUGraz.VectoCore.OutputData IEnumerable<T> GetValues<T>(DataColumn col); Dictionary<string, DataColumn> Auxiliaries { get; set; } + T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T>; void SetDataValue(string fieldName, object value); @@ -147,49 +148,44 @@ namespace TUGraz.VectoCore.OutputData return self ?? defaultValue; } - public static MeterPerSquareSecond AccelerationsPositive(this IModalDataContainer data) + public static MeterPerSquareSecond AccelerationsPositive(this MeterPerSquareSecond[] acceleration3SecondAverage) { try { - var acceleration3SecondAverage = AccelerationPer3Seconds(data); return acceleration3SecondAverage.Where(x => x > 0.125).Average(); } catch (NullReferenceException) { return null; } } - public static MeterPerSquareSecond AccelerationsNegative(this IModalDataContainer data) + public static MeterPerSquareSecond AccelerationsNegative(this MeterPerSquareSecond[] acceleration3SecondAverage) { - var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); - if (acceleration3SecondAverage.Any()) { + if (acceleration3SecondAverage.Length > 0) { return acceleration3SecondAverage.Where(x => x < -0.125).Average(); } return null; } - public static Scalar AccelerationTimeShare(this IModalDataContainer data) + public static Scalar AccelerationTimeShare(this MeterPerSquareSecond[] acceleration3SecondAverage) { - var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); - if (acceleration3SecondAverage.Any()) { - return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x > 0.125) / acceleration3SecondAverage.Count; + if (acceleration3SecondAverage.Length > 0) { + return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x > 0.125) / acceleration3SecondAverage.Length; } return null; } - public static Scalar DecelerationTimeShare(this IModalDataContainer data) + public static Scalar DecelerationTimeShare(this MeterPerSquareSecond[] acceleration3SecondAverage) { - var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); - if (acceleration3SecondAverage.Any()) { - return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x < -0.125) / acceleration3SecondAverage.Count; + if (acceleration3SecondAverage.Length > 0) { + return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x < -0.125) / acceleration3SecondAverage.Length; } return null; } - public static Scalar CruiseTimeShare(this IModalDataContainer data) + public static Scalar CruiseTimeShare(this MeterPerSquareSecond[] acceleration3SecondAverage) { - var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); - if (acceleration3SecondAverage.Any()) { + if (acceleration3SecondAverage.Length > 0) { return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x.IsBetween(-0.125, -0.125)) / - acceleration3SecondAverage.Count; + acceleration3SecondAverage.Length; } return null; } @@ -197,8 +193,8 @@ namespace TUGraz.VectoCore.OutputData public static Scalar StopTimeShare(this IModalDataContainer data) { var stopTime = data.GetValues<MeterPerSecond>(ModalResultField.v_act) - .Zip(data.SimulationIntervals(), (v, dt) => new { v, dt }) - .Where(x => x.v < 0.1).Sum(x => x.dt) ?? 0.SI<Second>(); + .Zip(data.SimulationIntervals(), (v, dt) => new { v, dt }) + .Where(x => x.v < 0.1).Sum(x => x.dt) ?? 0.SI<Second>(); return 100 * (stopTime / data.Duration()).Cast<Scalar>(); } @@ -467,33 +463,23 @@ namespace TUGraz.VectoCore.OutputData return data.GetValues<Watt>(auxCol).Zip(simulationIntervals, (value, dt) => value * dt).Sum().Cast<WattSecond>(); } - private static T TimeIntegral<T>(this IModalDataContainer data, ModalResultField field, Func<SI, bool> filter = null) - where T : SIBase<T> - { - var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval); - var filteredList = data.GetValues<SI>(field) - .Zip(simulationIntervals, (value, dt) => new { value, dt }) - .Where(x => filter == null || filter(x.value)).ToList(); - - return filteredList.Any() - ? filteredList.Select(x => (x.value == null ? SIBase<T>.Create(0) : x.value * x.dt)).Sum().Cast<T>() - : SIBase<T>.Create(0); - } - - private static IEnumerable<MeterPerSquareSecond> AccelerationPer3Seconds(IModalDataContainer data) + public static MeterPerSquareSecond[] AccelerationPer3Seconds(this IModalDataContainer data) { + var accs = new List<MeterPerSquareSecond>(1000); var accelerationAverages = AccelerationPerSecond(data).ToList(); if (accelerationAverages.Count >= 3) { var runningAverage = (accelerationAverages[0] + accelerationAverages[1] + accelerationAverages[2]) / 3.0; - yield return runningAverage; + accs.Add(runningAverage); for (var i = 2; i < accelerationAverages.Count - 1; i++) { runningAverage -= accelerationAverages[i - 2] / 3.0; runningAverage += accelerationAverages[i + 1] / 3.0; - yield return runningAverage; + accs.Add(runningAverage); } } + + return accs.ToArray(); } /// <summary> diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index b7fc496636c002614ae8481fab4c151ad2b26b2b..39cf24c121e3aabd53a57eccc8c522c73f36c7fc 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -204,7 +204,6 @@ namespace TUGraz.VectoCore.OutputData }); } - var strCols = dataColumns.Select(x => x.GetName()) .Concat(Auxiliaries.Values.Select(c => c.ColumnName)) .Concat( @@ -232,6 +231,23 @@ namespace TUGraz.VectoCore.OutputData return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); } + public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) + where T : SIBase<T> + { + var result = 0.0; + for (var i = 0; i < Data.Rows.Count; i++) { + var value = Data.Rows[i][(int)field]; + if (value != null && value != DBNull.Value) { + var siValue = (SI)value; + if (filter == null || filter(siValue)) { + result += siValue.Value() * ((Second)Data.Rows[i][(int)ModalResultField.simulationInterval]).Value(); + } + } + } + + return result.SI<T>(); + } + public IEnumerable<T> GetValues<T>(ModalResultField key) { return GetValues<T>(Data.Columns[(int)key]); diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index 5f9fc989dd6c9851f46f50eac26eb822a2f166bb..a86a4665b998b690488bc057d0e2c86235c4acbb 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -257,12 +257,14 @@ namespace TUGraz.VectoCore.OutputData row[E_CLUTCH_NEG] = modData.EngineWorkNegative().ConvertTo().Kilo.Watt.Hour; row[E_FCMAP_POS] = modData.TotalEngineWorkPositive().ConvertTo().Kilo.Watt.Hour; + var acc = modData.AccelerationPer3Seconds(); + row[ACC] = modData.AccelerationAverage(); - row[ACC_POS] = modData.AccelerationsPositive(); - row[ACC_NEG] = modData.AccelerationsNegative(); - row[ACC_TIMESHARE] = modData.AccelerationTimeShare(); - row[DEC_TIMESHARE] = modData.DecelerationTimeShare(); - row[CRUISE_TIMESHARE] = modData.CruiseTimeShare(); + row[ACC_POS] = acc.AccelerationsPositive(); + row[ACC_NEG] = acc.AccelerationsNegative(); + row[ACC_TIMESHARE] = acc.AccelerationTimeShare(); + row[DEC_TIMESHARE] = acc.DecelerationTimeShare(); + row[CRUISE_TIMESHARE] = acc.CruiseTimeShare(); row[STOP_TIMESHARE] = modData.StopTimeShare(); } diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 1ff028aaed45e694a81395c9438da5677c6c84b3..c8d04b557624fd3a695f562168a57242ac2ad00c 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -92,6 +93,11 @@ namespace TUGraz.VectoCore.Tests.Utils return Data.Rows.Cast<DataRow>().Select(x => x.Field<T>(col)); } + public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> + { + throw new NotImplementedException(); + } + public Dictionary<string, DataColumn> Auxiliaries { get; set; } public void SetDataValue(string fieldName, object value)