diff --git a/VectoConsole/Program.cs b/VectoConsole/Program.cs index 046cd421aa5007dc5696dcfccaa131d29b24c41b..d6bd3f87c8ab7b189d6a28a0898cf4ca7334bc47 100644 --- a/VectoConsole/Program.cs +++ b/VectoConsole/Program.cs @@ -73,6 +73,7 @@ Description: -t: output information about execution times -mod: write mod-data in addition to sum-data + -1Hz: convert mod-data to 1Hz resolution -eng: switch to engineering mode (implies -mod) -v: Shows verbose information (errors and warnings will be displayed) -vv: Shows more verbose information (infos will be displayed) @@ -80,7 +81,7 @@ Description: -vvvv: Shows all verbose information (everything, slow!) -V: show version information -h: Displays this help. - + Examples: vecto.exe ""12t Delivery Truck.vecto"" 40t_Long_Haul_Truck.vecto vecto.exe 24tCoach.vecto 40t_Long_Haul_Truck.vecto @@ -144,7 +145,7 @@ Examples: ShowVersionInformation(); } - var fileList = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray(); + var fileList = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t", "-1Hz" }).ToArray(); var jobFiles = fileList.Where( f => @@ -157,7 +158,6 @@ Examples: return 1; } - var stopWatch = new Stopwatch(); var timings = new Dictionary<string, double>(); @@ -176,7 +176,6 @@ Examples: stopWatch.Start(); - if (!jobFiles.Any()) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(@"No Job files found. Please restart the application with a valid '.vecto' file."); @@ -189,11 +188,11 @@ Examples: if (Path.GetExtension(file) == Constants.FileExtensions.VectoJobFile) { var dataProvider = JSONInputDataFactory.ReadJsonJob(file); fileWriter = new FileOutputWriter(file); - var runsFactory = new SimulatorFactory(mode, dataProvider, fileWriter); + var runsFactory = new SimulatorFactory(mode, dataProvider, fileWriter) { + ModalResults1Hz = args.Contains("-1Hz"), + WriteModalResults = args.Contains("-mod") + }; - if (args.Contains("-mod")) { - runsFactory.WriteModalResults = true; - } _jobContainer.AddRuns(runsFactory); } if (Path.GetExtension(file) == Constants.FileExtensions.VectoXMLDeclarationFile) { @@ -248,7 +247,6 @@ Examples: stopWatch.Stop(); timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); - PrintProgress(_jobContainer.GetProgress(), args.Contains("-t")); if (args.Contains("-t")) { diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 5bc8ddb4cc98e3b9f22bdcaa9a39dd35de51f857..06516a70c8eb0fd766ececf2d420afd0b0477372 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -39,6 +39,7 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.OutputData { @@ -265,8 +266,88 @@ namespace TUGraz.VectoCore.OutputData { public ModalResults Filter(ModalResults data) { - //todo mk-2016-05-24: implement 1Hz filter - return data; + var absTime = 0.SI<Second>(); + var results = new ModalResults(); + var remainingDt = 0.SI<Second>(); + + object[] remainingRow = null; + + foreach (DataRow row in data.Rows) { + var currentDt = row.Field<Second>((int)ModalResultField.simulationInterval); + + // if remaining + current >= 1: split current row and add remaining row. + // 1) take full remaining row + // 2) split current row on difference to next full second + // 3) continue with remaining time on current row + if (remainingDt > 0 && remainingDt + currentDt >= 1) { + var diffDt = 1.SI<Second>() - remainingDt; + var r = results.NewRow(); + r.ItemArray = AddRow(remainingRow, MultiplyRow(row.ItemArray, diffDt)); + absTime += diffDt; + r[(int)ModalResultField.simulationInterval] = absTime; + results.Rows.Add(r); + currentDt = VectoMath.Min(currentDt - remainingDt - 1.SI<Second>(), 0.SI<Second>()); + } + + // split current Row until dt < 1 + while (currentDt >= 1) { + currentDt = currentDt - 1.SI<Second>(); + var r = results.NewRow(); + r.ItemArray = row.ItemArray; + absTime += 1.SI<Second>(); + r[(int)ModalResultField.simulationInterval] = absTime; + results.Rows.Add(r); + } + + // normalize rest of the remaining row if dt > 0 for summation of next row + if (currentDt > 0) { + if (remainingDt > 0) + remainingRow = AddRow(remainingRow, MultiplyRow(row.ItemArray, currentDt)); + else + remainingRow = MultiplyRow(row.ItemArray, currentDt); + remainingDt += currentDt; + absTime += remainingDt; + } else { + remainingRow = null; + remainingDt = 0.SI<Second>(); + } + } + + // if last row was not enough to full second: take last row as whole second + if (remainingDt >= 0) { + var r = results.NewRow(); + r.ItemArray = remainingRow; + r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); + results.Rows.Add(r); + } + + return results; + } + + private static object[] MultiplyRow(IEnumerable<object> row, Second dt) + { + return row.Select(val => { + val.Switch() + .Case<SI>(si => val = si * dt.Value()) + .Case<int>(i => val = i * dt.Value()) + .Case<double>(d => val = d * dt.Value()) + .Case<float>(f => val = f * dt.Value()) + .Case<uint>(ui => val = ui * dt.Value()); + return val; + }).ToArray(); + } + + private static object[] AddRow(IEnumerable<object> row, IEnumerable<object> addRow) + { + return row.ZipAll(addRow, (val, addVal) => { + val.Switch() + .Case<SI>(si => val = si + (SI)addVal) + .Case<int>(i => val = i + (int)addVal) + .Case<double>(d => val = d + (double)addVal) + .Case<float>(f => val = f + (float)addVal) + .Case<uint>(ui => val = ui + (uint)addVal); + return val; + }).ToArray(); } public string ID