diff --git a/User Manual/fileformat/VSUM.md b/User Manual/fileformat/VSUM.md index 6e12ca6645fb2ca31cf3743df1780f5532f9e8f8..092b6206ff98d267ff02d5f8d5b75159019b69f5 100644 --- a/User Manual/fileformat/VSUM.md +++ b/User Manual/fileformat/VSUM.md @@ -7,20 +7,22 @@ The .vsum file includes total / average results for each calculation run in one | Name | Unit | Description | ----- | ---- | ----------------------------------------- -| Job | [-] | Job number. Format is "x-y" with x = file number and y = cycle number +| Job | [-] | Job number in the format "x-y" (where x = file number and y = cycle number) | Input File | [-] | Name of the input file | Cycle | [-] | Name of the cycle file +| Status | [-] | The result status of the run (Success, Aborted) | time | [s] | Total simulation time -| distance | [km] | Total travelled distance +| distance | [km] | Total traveled distance | speed | [km/h] | Average vehicle speed | ∆altitude | [m] | Altitude difference between start and end of cycle | Ppos | [kW] | Average positive engine power | Pneg | [kW] | Average negative engine power -| FC-Final | [g/km] \& [l/100km] \& [l/100tkm] | Average fuel consumption. Final value after all corrections. -| FC-Map | [g/h] & [g/km] | Fuel consumption interpolated form [Fuel Map](#fuel-consumption-calculation). -| FC-AUXc | [g/km] | Fuel consumption after [Auxiliary-Start/Stop Correction](#fuel-consumption-calculation). (Based on FC.) +| FC-Final | [g/km], [l/100km], [l/100tkm] | Average fuel consumption. Final value after all corrections. +| FC-Map | [g/h], [g/km] | Fuel consumption interpolated fromm [Fuel Map](#fuel-consumption-calculation). +| FC-AUXc | [g/h], [g/km] | Fuel consumption after [Auxiliary-Start/Stop Correction](#fuel-consumption-calculation). (Based on FC.) | FC-WHTCc | [g/km] | Fuel consumption after [WHTC Correction](#fuel-consumption-calculation). (Based on FC-AUXc.) -| Co~2~ | [g/km] & [g/tkm] | Average CO~2~ emissions. +| Co~2~ | [g/km], [g/tkm] | Average CO~2~ emissions. +| PwheelPos | [kW] | Average positive wheel power | Pbrake | [kW] | Average brake power (not including engine drag) | EposICE | [kWh] | Total positive engine work | EnegICE | [kWh] | Total negative engine work (engine brake) @@ -33,10 +35,10 @@ The .vsum file includes total / average results for each calculation run in one | Ebrake | [kWh] | Total work dissipated in mechanical braking (sum of service brakes, retader and additional engine exhaust brakes) | Etransm | [kWh] | Total work of transmission losses | Eretarder | [kWh] | Total retarder losses -| Etorqueconv | [kWh] | Total torque converter losses +| Etorqueconv | [kWh] | Total torque converter losses | Mass | [kg] | Vehicle mass (equals **Curb Weight Vehicle** plus **Curb Weight Extra Trailer/Body**, see [Vehicle Editor](#vehicle-editor)) | Loading | [kg] | Vehicle loading (see [Vehicle Editor](#vehicle-editor)) -| a | [m/s2] | Average acceleration +| a | [m/s²] | Average acceleration | a_pos | [m/s²] | Average acceleration in acceleration phases \* | a_neg | [m/s²] | Average deceleration in deceleration phases \* | Acc.Noise | [m/s²] | Acceleration noise diff --git a/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs b/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs index 1a6ea2570ac334428f444fff073021c85c5010ac..b0c5f8834d519013a775b42625703673d5deeb21 100644 --- a/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs +++ b/VectoCore/FileIO/Reader/Impl/DeclarationModeSimulationDataReader.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Security.Principal; using Newtonsoft.Json; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.FileIO.DeclarationFile; @@ -47,9 +48,10 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl var gearboxData = dao.CreateGearboxData(Gearbox, engineData); var gearboxTypeString = string.Format("{0}-Speed {1}", gearboxData.Gears.Count, gearboxData.Type); - // todo: set correct <USERNAME> in Report - var report = new DeclarationReport(engineData.FullLoadCurve, segment, "<USERNAME>", engineData.ModelName, - engineTypeString, gearboxData.ModelName, gearboxTypeString, Job.BasePath, Job.JobFile, resultCount); + var report = new DeclarationReport(engineData.FullLoadCurve, segment, WindowsIdentity.GetCurrent().Name, + engineData.ModelName, + engineTypeString, gearboxData.ModelName, gearboxTypeString, Job.BasePath, + Path.GetFileNameWithoutExtension(Job.JobFile), resultCount); foreach (var mission in segment.Missions) { DrivingCycleData cycle; @@ -75,6 +77,8 @@ namespace TUGraz.VectoCore.FileIO.Reader.Impl Report = report, Mission = mission, }; + simulationRunData.EngineData.WHTCCorrectionFactor = DeclarationData.WHTCCorrection.Lookup(mission.MissionType, + engineData.WHTCRural.Value(), engineData.WHTCUrban.Value(), engineData.WHTCMotorway.Value()); simulationRunData.Cycle.Name = mission.MissionType.ToString(); simulationRunData.VehicleData.VehicleClass = segment.VehicleClass; yield return simulationRunData; diff --git a/VectoCore/Models/Declaration/DeclarationReport.cs b/VectoCore/Models/Declaration/DeclarationReport.cs index 139b444725fad3873267e7b2252044b527873a41..79fbd2bb229fe7a9b95c8168084e069bf2a2527e 100644 --- a/VectoCore/Models/Declaration/DeclarationReport.cs +++ b/VectoCore/Models/Declaration/DeclarationReport.cs @@ -9,6 +9,7 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Windows.Forms.DataVisualization.Charting; +using NLog; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Utils; @@ -162,14 +163,12 @@ namespace TUGraz.VectoCore.Models.Declaration private Stream CreateTitlePage(Dictionary<MissionType, ResultContainer> missions) { var stream = new MemoryStream(); - var resourceName = string.Format("{0}Report.title{1}CyclesTemplate.pdf", RessourceHelper.Namespace, missions.Count); var inputStream = RessourceHelper.ReadStream(resourceName); - var reader = new PdfReader(inputStream); - var stamper = new PdfStamper(reader, stream); + var pdfFields = stamper.AcroFields; pdfFields.SetField("version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); pdfFields.SetField("Job", _jobFile); @@ -191,33 +190,21 @@ namespace TUGraz.VectoCore.Models.Declaration foreach (var results in missions.Values.OrderBy(m => m.Mission.MissionType)) { pdfFields.SetField("Mission" + i, results.Mission.MissionType.ToString()); - var m = results.ModData[LoadingType.ReferenceLoad]; - var dt = m.GetValues<Second>(ModalResultField.simulationInterval); - var maxDistance = m.GetValues<Meter>(ModalResultField.dist).Max(); - var maxTime = m.GetValues<Second>(ModalResultField.time).Max(); - - var avgSpeed = maxDistance / maxTime; + var data = results.ModData[LoadingType.ReferenceLoad]; pdfFields.SetField("Loading" + i, results.Mission.RefLoad.ConvertTo().Ton.ToOutputFormat(1) + " t"); - pdfFields.SetField("Speed" + i, avgSpeed.ConvertTo().Kilo.Meter.Per.Hour.ToOutputFormat(1) + " km/h"); - - var fc = m.GetValues<KilogramPerSecond>(ModalResultField.FCMap); - var fcWeight = fc.Zip(dt, (fcVal, dtVal) => fcVal * dtVal).Sum(); - var fcVolume = (fcWeight / Physics.FuelDensity).Cast<CubicMeter>(); - var co2Weight = fcWeight * Physics.CO2PerFuelWeight; + pdfFields.SetField("Speed" + i, data.Speed().ConvertTo().Kilo.Meter.Per.Hour.ToOutputFormat(1) + " km/h"); - var fcAvgVolume = fcVolume / maxDistance; - var co2AvgWeight = co2Weight / maxDistance; + var fcLiterPer100Km = data.FuelConsumptionLiterPer100Kilometer(); + pdfFields.SetField("FC" + i, fcLiterPer100Km.ToOutputFormat(1)); var loadingTon = results.Mission.RefLoad.ConvertTo().Ton; - - var fcLiterPer100Km = fcAvgVolume.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter; var fcLiterPer100Tonkm = fcLiterPer100Km / loadingTon; - var co2GrammPerKm = co2AvgWeight.ConvertTo().Gramm.Per.Kilo.Meter; + pdfFields.SetField("FCt" + i, fcLiterPer100Tonkm.ToOutputFormat(1)); + + var co2GrammPerKm = data.CO2PerMeter().ConvertTo().Gramm.Per.Kilo.Meter; var co2GrammPerTonKm = co2GrammPerKm / loadingTon; - pdfFields.SetField("FC" + i, fcLiterPer100Km.ToOutputFormat(1)); - pdfFields.SetField("FCt" + i, fcLiterPer100Tonkm.ToOutputFormat(1)); pdfFields.SetField("CO2" + i, co2GrammPerKm.ToOutputFormat(1)); pdfFields.SetField("CO2t" + i, co2GrammPerTonKm.ToOutputFormat(1)); i++; @@ -277,34 +264,23 @@ namespace TUGraz.VectoCore.Models.Declaration foreach (var pair in results.ModData) { var loadingType = pair.Key; - var m = pair.Value; - - var dt = m.GetValues<Second>(ModalResultField.simulationInterval); - var maxDistance = m.GetValues<Meter>(ModalResultField.dist).Max(); - var maxTime = m.GetValues<Second>(ModalResultField.time).Max(); - var avgSpeed = maxDistance / maxTime; - - var fc = m.GetValues<KilogramPerSecond>(ModalResultField.FCMap); - var fcWeight = fc.Zip(dt, (fcVal, dtVal) => fcVal * dtVal).Sum(); - var fcVolume = (fcWeight / Physics.FuelDensity).Cast<CubicMeter>(); - var co2Weight = fcWeight * Physics.CO2PerFuelWeight; - var fcAvgVolume = fcVolume / maxDistance; - var co2AvgWeight = co2Weight / maxDistance; - var loadingTon = results.Mission.Loadings[loadingType].ConvertTo().Ton; + var data = pair.Value; - var fcLiterPer100Km = fcAvgVolume.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter; - var co2GrammPerKm = co2AvgWeight.ConvertTo().Gramm.Per.Kilo.Meter; + var loadingTon = results.Mission.Loadings[loadingType].ConvertTo().Ton; + var loadAppendix = loadingType.GetShortName(); - var loadString = loadingType.GetShortName(); + pdfFields.SetField("Load" + loadAppendix, loadingTon.ToOutputFormat(1) + " t"); + pdfFields.SetField("Speed" + loadAppendix, data.Speed().ConvertTo().Kilo.Meter.Per.Hour.ToOutputFormat(1)); - pdfFields.SetField("Load" + loadString, - results.Mission.Loadings[loadingType].ConvertTo().Ton.ToOutputFormat(1) + " t"); - pdfFields.SetField("Speed" + loadString, avgSpeed.ConvertTo().Kilo.Meter.Per.Hour.ToOutputFormat(1)); - pdfFields.SetField("FCkm" + loadString, fcLiterPer100Km.ToOutputFormat(1)); - pdfFields.SetField("FCtkm" + loadString, + var fcLiterPer100Km = data.FuelConsumptionLiterPer100Kilometer(); + pdfFields.SetField("FCkm" + loadAppendix, fcLiterPer100Km.ToOutputFormat(1)); + pdfFields.SetField("FCtkm" + loadAppendix, loadingTon.IsEqual(0) ? "-" : (fcLiterPer100Km / loadingTon).ToOutputFormat(1)); - pdfFields.SetField("CO2km" + loadString, co2GrammPerKm.ToOutputFormat(1)); - pdfFields.SetField("CO2tkm" + loadString, + + + var co2GrammPerKm = data.CO2PerMeter().ConvertTo().Gramm.Per.Kilo.Meter; + pdfFields.SetField("CO2km" + loadAppendix, co2GrammPerKm.ToOutputFormat(1)); + pdfFields.SetField("CO2tkm" + loadAppendix, loadingTon.IsEqual(0) ? "-" : (co2GrammPerKm / loadingTon).ToOutputFormat(1)); } @@ -387,24 +363,16 @@ namespace TUGraz.VectoCore.Models.Declaration }); foreach (var missionResult in missions.OrderBy(m => m.Key)) { - var m = missionResult.Value.ModData[LoadingType.ReferenceLoad]; - var fc = m.GetValues<KilogramPerSecond>(ModalResultField.FCMap); - var dt = m.GetValues<Second>(ModalResultField.simulationInterval); - - var fcWeight = fc.Zip(dt, (fcValue, dtValue) => fcValue * dtValue).Sum(); - - var maxDistance = m.GetValues<Meter>(ModalResultField.dist).Max(); - var loading = missionResult.Value.Mission.Loadings[LoadingType.ReferenceLoad]; + var data = missionResult.Value.ModData[LoadingType.ReferenceLoad]; - var co2Weight = fcWeight * Physics.CO2PerFuelWeight; - - var co2GPerTonKm = co2Weight.ConvertTo().Gramm / (maxDistance.ConvertTo().Kilo.Meter * loading.ConvertTo().Ton); + var loadingTon = missionResult.Value.Mission.Loadings[LoadingType.ReferenceLoad].ConvertTo().Ton; + var co2GrammPerTonKm = data.CO2PerMeter().ConvertTo().Gramm.Per.Kilo.Meter / loadingTon; var series = new Series(missionResult.Key + " (Ref. load.)"); var dataPoint = new DataPoint { Name = missionResult.Key.ToString(), - YValues = new[] { co2GPerTonKm.Value() }, - Label = co2GPerTonKm.ToOutputFormat(1, showUnit: true), + YValues = new[] { co2GrammPerTonKm.Value() }, + Label = co2GrammPerTonKm.ToOutputFormat(1, showUnit: true), Font = new Font("Helvetica", 20), LabelBackColor = Color.White }; @@ -458,23 +426,13 @@ namespace TUGraz.VectoCore.Models.Declaration ChartType = SeriesChartType.Point }; foreach (var pair in missionResult.Value.ModData) { - var modData = missionResult.Value.ModData[pair.Key]; - var fc = modData.GetValues<KilogramPerSecond>(ModalResultField.FCMap); - var dt = modData.GetValues<Second>(ModalResultField.simulationInterval).ToList(); - - var fcSum = fc.Zip(dt, (fcValue, dtValue) => fcValue * dtValue).Sum(); - - - var maxDistance = modData.GetValues<Meter>(ModalResultField.dist).Max(); - var maxTime = modData.GetValues<Second>(ModalResultField.time).Max(); - - var avgKmh = maxDistance.ConvertTo().Kilo.Meter / maxTime.ConvertTo().Hour; - var co2GPerKm = fcSum.ConvertTo().Gramm * Physics.CO2PerFuelWeight / maxDistance.ConvertTo().Kilo.Meter; + var data = missionResult.Value.ModData[pair.Key]; - var loading = missionResult.Value.Mission.Loadings[pair.Key].ConvertTo().Ton; + var co2GramPerKilometer = data.CO2PerMeter().ConvertTo().Gramm.Per.Kilo.Meter; + var loadingTon = missionResult.Value.Mission.Loadings[pair.Key].ConvertTo().Ton; - var point = new DataPoint(avgKmh.Value(), co2GPerKm.Value()) { - Label = string.Format(CultureInfo.InvariantCulture, "{0:0.0} t", loading.Value()), + var point = new DataPoint(data.Speed().ConvertTo().Kilo.Meter.Per.Hour.Value(), co2GramPerKilometer.Value()) { + Label = string.Format(CultureInfo.InvariantCulture, "{0:0.0} t", loadingTon.Value()), Font = new Font("Helvetica", 16), LabelBackColor = Color.White }; @@ -627,8 +585,8 @@ namespace TUGraz.VectoCore.Models.Declaration var dataPoints = new Series("load points (Ref. load.)") { ChartType = SeriesChartType.Point, Color = Color.Red }; dataPoints.Points.DataBindXY( - modData.GetValues<SI>(ModalResultField.n).Select(x => x.ConvertTo().Rounds.Per.Minute).ToDouble(), - modData.GetValues<SI>(ModalResultField.Tq_eng).ToDouble()); + modData.GetValues<PerSecond>(ModalResultField.n).Select(x => x.ConvertTo().Rounds.Per.Minute).ToDouble(), + modData.GetValues<NewtonMeter>(ModalResultField.Tq_eng).ToDouble()); operatingPointsChart.Series.Add(dataPoints); operatingPointsChart.Update(); diff --git a/VectoCore/Models/Declaration/WHTCCorrection.cs b/VectoCore/Models/Declaration/WHTCCorrection.cs index adb0eb173cfb7f5ad6c51dc7ad7f62cf01b1e75c..18967378f26330f42cd440b9b16731337fc421a7 100644 --- a/VectoCore/Models/Declaration/WHTCCorrection.cs +++ b/VectoCore/Models/Declaration/WHTCCorrection.cs @@ -8,7 +8,8 @@ namespace TUGraz.VectoCore.Models.Declaration { public class WHTCCorrection : LookupData<MissionType, double, double, double, double> { - private Dictionary<MissionType, WHTCCorrectionEntry> _data = new Dictionary<MissionType, WHTCCorrectionEntry>(); + private readonly Dictionary<MissionType, WHTCCorrectionEntry> _data = + new Dictionary<MissionType, WHTCCorrectionEntry>(); protected const string ResourceId = "TUGraz.VectoCore.Resources.Declaration.WHTC-Weighting-Factors.csv"; diff --git a/VectoCore/Models/Simulation/Data/IModalDataWriter.cs b/VectoCore/Models/Simulation/Data/IModalDataWriter.cs index 0d5ee7fc98e72dde72f5325b8e116459c888f67d..3f225287bff78a0549f6c320410c8fa15a8fad61 100644 --- a/VectoCore/Models/Simulation/Data/IModalDataWriter.cs +++ b/VectoCore/Models/Simulation/Data/IModalDataWriter.cs @@ -77,7 +77,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data return data.GetValues<SI>(col).Where(filter ?? (x => x != null)).Sum(); } - public static SI Average(this IEnumerable<SI> self, Func<SI, bool> filter = null) + public static SI Average(this IEnumerable<SI> self, Func<SI, bool> filter) { var values = self.Where(filter ?? (x => x != null && !double.IsNaN(x.Value()))).ToList(); return values.Any() ? values.Sum() / values.Count : null; @@ -92,5 +92,296 @@ namespace TUGraz.VectoCore.Models.Simulation.Data { return self ?? defaultValue; } + + public static MeterPerSquareSecond AccelerationsPositive3SecondAverage(this IModalDataWriter data) + { + var acceleration3SecondAverage = AccelerationPer3Seconds(data); + return acceleration3SecondAverage.Where(x => x > 0.125).Average(); + } + + public static MeterPerSquareSecond AccelerationNoise(this IModalDataWriter data) + { + var avg = data.AccelerationAverage(); + var accelerationAverages = AccelerationPerSecond(data).ToList(); + var sqareAvg = accelerationAverages.Select(x => (x - avg) * (x - avg)).Sum() / accelerationAverages.Count; + return sqareAvg.Sqrt().Cast<MeterPerSquareSecond>(); + } + + public static MeterPerSquareSecond AverageAccelerations3SecondNegative(this IModalDataWriter data) + { + var acceleration3SecondAverage = AccelerationPer3Seconds(data); + return acceleration3SecondAverage.Where(x => x < -0.125).Average(); + } + + public static Scalar PercentAccelerationTime(this IModalDataWriter data) + { + var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); + return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x > 0.125) / acceleration3SecondAverage.Count; + } + + public static Scalar PercentDecelerationTime(this IModalDataWriter data) + { + var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); + return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x < -0.125) / acceleration3SecondAverage.Count; + } + + public static Scalar PercentCruiseTime(this IModalDataWriter data) + { + var acceleration3SecondAverage = AccelerationPer3Seconds(data).ToList(); + return 100.SI<Scalar>() * acceleration3SecondAverage.Count(x => x.IsBetween(-0.125, -0.125)) / + acceleration3SecondAverage.Count; + } + + public static Scalar PercentStopTime(this IModalDataWriter data) + { + var stopTime = data.GetValues<MeterPerSecond>(ModalResultField.v_act) + .Zip(data.SimulationIntervals(), (v, dt) => new { v, dt }) + .Where(x => x.v < 0.1).Select(x => x.dt).Sum(); + + return 100 * (stopTime / data.Duration()).Cast<Scalar>(); + } + + public static MeterPerSquareSecond AccelerationAverage(this IModalDataWriter data) + { + return data.TimeIntegral<MeterPerSecond>(ModalResultField.acc) / data.Duration(); + } + + public static Second[] SimulationIntervals(this IModalDataWriter data) + { + return data.GetValues<Second>(ModalResultField.simulationInterval).ToArray(); + } + + public static Meter AltitudeDelta(this IModalDataWriter data) + { + return data.GetValues<Meter>(ModalResultField.altitude).Last() - + data.GetValues<Meter>(ModalResultField.altitude).First(); + } + + public static WattSecond PowerAccelerations(this IModalDataWriter data) + { + var paEngine = data.TimeIntegral<WattSecond>(ModalResultField.PaEng); + var paGearbox = data.TimeIntegral<WattSecond>(ModalResultField.PaGB); + return paEngine + paGearbox; + } + + public static WattSecond WorkTransmission(this IModalDataWriter data) + { + var plossdiff = data.TimeIntegral<WattSecond>(ModalResultField.PlossGB); + var plossgb = data.TimeIntegral<WattSecond>(ModalResultField.PlossDiff); + return plossdiff + plossgb; + } + + public static WattSecond WorkRetarder(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.PlossRetarder); + } + + public static WattSecond WorkTorqueConverter(this IModalDataWriter data) + { + //TODO (MK, 2015-11-10): return torque converter work - this was currently not possible because torque converter is not implemented. + return 0.SI<WattSecond>(); + } + + public static Second Duration(this IModalDataWriter data) + { + return (data.Max(ModalResultField.time) - data.Min(ModalResultField.time)).Cast<Second>(); + } + + public static Meter Distance(this IModalDataWriter data) + { + return (data.Max(ModalResultField.dist) - data.Min(ModalResultField.dist)).Cast<Meter>(); + } + + public static WattSecond WorkTotalMechanicalBrake(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pbrake); + } + + public static WattSecond WorkAuxiliaries(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Paux); + } + + public static WattSecond WorkRoadGradientResistance(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pgrad); + } + + public static WattSecond WorkRollingResistance(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Proll); + } + + public static WattSecond WorkAirResistance(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pair); + } + + public static WattSecond EngineWorkPositive(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pe_eng, x => x > 0); + } + + public static WattSecond EngineWorkNegative(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pe_eng, x => x < 0); + } + + public static Watt PowerBrake(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pbrake) / data.Duration(); + } + + public static Watt PowerWheelPositive(this IModalDataWriter data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.Pwheel, x => x > 0) / data.Duration(); + } + + public static KilogramPerMeter FuelConsumptionWHTCCorrected(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / data.Distance(); + } + + public static KilogramPerSecond FuelConsumptionWHTCCorrectedPerSecond(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / data.Duration(); + } + + public static KilogramPerMeter FuelConsumptionAuxStartStopCorrected(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCAUXc) / data.Distance(); + } + + public static KilogramPerSecond FuelConsumptionAuxStartStopCorrectedPerSecond(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCAUXc) / data.Duration(); + } + + public static KilogramPerMeter FuelConsumptionFinal(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / data.Distance(); + } + + public static SI FuelConsumptionFinalLiterPer100Kilometer(this IModalDataWriter data) + { + var fcVolumePerMeter = data.FuelConsumptionFinal() / Physics.FuelDensity; + return fcVolumePerMeter.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter; + } + + public static KilogramPerMeter CO2PerMeter(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) * Physics.CO2PerFuelWeight / data.Distance(); + } + + public static SI FuelConsumptionLiterPer100Kilometer(this IModalDataWriter data) + { + var fcVolumePerMeter = data.FuelConsumptionPerMeter() / Physics.FuelDensity; + return fcVolumePerMeter.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter; + } + + public static KilogramPerSecond FuelConsumptionPerSecond(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) / data.Duration(); + } + + public static KilogramPerMeter FuelConsumptionPerMeter(this IModalDataWriter data) + { + return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) / data.Distance(); + } + + public static Watt EnginePowerNegativeAverage(this IModalDataWriter data) + { + var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval); + var values = data.GetValues<Watt>(ModalResultField.Pe_eng) + .Zip(simulationIntervals, (value, dt) => new { Dt = dt, Value = value * dt }) + .Where(v => v.Value < 0).ToList(); + if (values.Any()) { + return values.Select(v => v.Value).Sum() / values.Select(v => v.Dt).Sum(); + } + return 0.SI<Watt>(); + } + + public static Watt EnginePowerPositiveAverage(this IModalDataWriter data) + { + var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval); + var values = data.GetValues<Watt>(ModalResultField.Pe_eng) + .Zip(simulationIntervals, (value, dt) => new { Dt = dt, Value = value * dt }) + .Where(v => v.Value > 0).ToList(); + if (values.Any()) { + return values.Select(v => v.Value).Sum() / values.Select(v => v.Dt).Sum(); + } + return 0.SI<Watt>(); + } + + public static MeterPerSecond Speed(this IModalDataWriter data) + { + return Distance(data) / Duration(data); + } + + public static WattSecond AuxiliaryWork(this IModalDataWriter data, DataColumn auxCol) + { + var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval); + return data.GetValues<Watt>(auxCol).Zip(simulationIntervals, (value, dt) => value * dt).Sum().Cast<WattSecond>(); + } + + + private static T TimeIntegral<T>(this IModalDataWriter 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(IModalDataWriter data) + { + var accelerationAverages = AccelerationPerSecond(data).ToList(); + var runningAverage = (accelerationAverages[0] + accelerationAverages[1] + accelerationAverages[2]) / 3.0; + yield return 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; + } + } + + /// <summary> + /// Calculates the average acceleration for whole seconds. + /// </summary> + private static IEnumerable<MeterPerSquareSecond> AccelerationPerSecond(IModalDataWriter data) + { + var dtSum = 0.SI<Second>(); + var accAvg = 0.SI<MeterPerSecond>(); + + var accValues = data.GetValues<MeterPerSquareSecond>(ModalResultField.acc); + + foreach (var value in accValues.Zip(SimulationIntervals(data), (acc, dt) => new { acc, dt })) { + var dt = value.dt; + var acc = value.acc; + + while (dtSum + dt >= 1) { + var diffDt = 1.SI<Second>() - dtSum; + yield return (accAvg + acc * diffDt) / 1.SI<Second>(); + dt -= diffDt; + dtSum = 0.SI<Second>(); + accAvg = 0.SI<MeterPerSecond>(); + } + if (dt > 0) { + accAvg += acc * dt; + dtSum += dt; + } + } + + // return remaining data. acts like extrapolation to next whole second. + if (dtSum > 0) { + yield return accAvg / 1.SI<Second>(); + } + } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Data/ISummaryDataWriter.cs b/VectoCore/Models/Simulation/Data/ISummaryDataWriter.cs deleted file mode 100644 index 3da42f812217ad2536c3a680e3766f2df57fd244..0000000000000000000000000000000000000000 --- a/VectoCore/Models/Simulation/Data/ISummaryDataWriter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Models.Simulation.Data -{ - /// <summary> - /// Provides methods to write and finish the Summary. - /// </summary> - public interface ISummaryDataWriter - { - /// <summary> - /// Writes a single sum entry for the given modaldata of the job. - /// </summary> - /// <param name="data">The modal data.</param> - /// <param name="vehicleMass">The vehicle mass.</param> - /// <param name="vehicleLoading">The vehicle loading.</param> - void Write(IModalDataWriter data, Kilogram vehicleMass = null, Kilogram vehicleLoading = null); - - /// <summary> - /// Writes the data to the sum file. - /// </summary> - void Finish(); - } -} \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs b/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs index d777f6648539365f8f49d4e1fe45de309710a581..63ee0db2724161e67b20bc3363ccf13fa533b519 100644 --- a/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs +++ b/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs @@ -1,16 +1,13 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; -using System.Globalization; using System.Linq; -using System.Linq.Expressions; using System.Runtime.CompilerServices; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation.Data { + public delegate void WriteSumData(IModalDataWriter data, Kilogram vehicleMass, Kilogram loading); + /// <summary> /// Class for the sum file in vecto. /// </summary> @@ -47,7 +44,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data private const string ERETARDER = "Eretarder [kWh]"; private const string MASS = "Mass [kg]"; private const string LOADING = "Loading [kg]"; - private const string A = "a [m/s^2]"; + private const string ACCELERATIONS = "a [m/s^2]"; private const string APOS = "a_pos [m/s^2]"; private const string ANEG = "a_neg [m/s^2]"; private const string PACC = "pAcc [%]"; @@ -55,10 +52,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Data private const string PCRUISE = "pCruise [%]"; private const string PSTOP = "pStop [%]"; private const string ETORQUECONV = "Etorqueconv [kWh]"; - private const string CO2 = "CO2 [g/km]"; - private const string CO2T = "CO2 [g/tkm]"; + private const string CO2KM = "CO2 [g/km]"; + private const string CO2TKM = "CO2 [g/tkm]"; private const string FCFINAL = "FC-Final [g/km]"; - private const string FCFINAL_LITER = "FC-Final [l/100km]"; + private const string FCFINAL_LITERPER100KM = "FC-Final [l/100km]"; private const string FCFINAL_LITERPER100TKM = "FC-Final [l/100tkm]"; private const string ACCNOISE = "Acc.Noise [m/s^2]"; // ReSharper restore InconsistentNaming @@ -69,7 +66,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data protected SummaryFileWriter() {} - private IList<string> _auxColumns = new List<string>(); + private readonly IList<string> _auxColumns = new List<string>(); /// <summary> /// Initializes a new instance of the <see cref="SummaryFileWriter"/> class. @@ -87,11 +84,24 @@ namespace TUGraz.VectoCore.Models.Simulation.Data _table.Columns.AddRange(new[] { TIME, DISTANCE, SPEED, ALTITUDE, PPOS, PNEG, FCMAP, FCMAPKM, FCAUXC, FCAUXCKM, FCWHTCC, FCWHTCCKM, PWHEELPOS, PBRAKE, - EPOSICE, ENEGICE, EAIR, EROLL, EGRAD, EACC, EAUX, EBRAKE, ETRANSM, ERETARDER, MASS, LOADING, A, APOS, ANEG, PACC, - PDEC, PCRUISE, PSTOP, ETORQUECONV, CO2, CO2T, FCFINAL, FCFINAL_LITER, FCFINAL_LITERPER100TKM, ACCNOISE + EPOSICE, ENEGICE, EAIR, EROLL, EGRAD, EACC, EAUX, EBRAKE, ETRANSM, ERETARDER, MASS, LOADING, ACCELERATIONS, APOS, + ANEG, PACC, PDEC, PCRUISE, PSTOP, ETORQUECONV, CO2KM, CO2TKM, FCFINAL, FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, + ACCNOISE }.Select(x => new DataColumn(x, typeof(SI))).ToArray()); } + public virtual void Write(bool isEngineOnly, IModalDataWriter data, string jobFileName, string jobName, + string cycleFileName, + Kilogram vehicleMass, Kilogram vehicleLoading) + { + if (isEngineOnly) { + WriteEngineOnly(data, jobFileName, jobName, cycleFileName); + } else { + WriteFullPowertrain(data, jobFileName, jobName, cycleFileName, vehicleMass, vehicleLoading); + } + } + + protected internal void WriteEngineOnly(IModalDataWriter data, string jobFileName, string jobName, string cycleFileName) { @@ -100,185 +110,87 @@ namespace TUGraz.VectoCore.Models.Simulation.Data row[INPUTFILE] = jobFileName; row[CYCLE] = cycleFileName; row[STATUS] = data.RunStatus; - row[TIME] = data.GetValues<SI>(ModalResultField.time).Max(); - row[PPOS] = data.GetValues<SI>(ModalResultField.Pe_eng).Where(x => x > 0).Average(); - row[PNEG] = data.GetValues<SI>(ModalResultField.Pe_eng).Where(x => x < 0).Average(); - row[FCMAP] = data.GetValues<SI>(ModalResultField.FCMap).Average(); - row[FCAUXC] = data.GetValues<SI>(ModalResultField.FCAUXc).Average(); - row[FCWHTCC] = data.GetValues<SI>(ModalResultField.FCWHTCc).Average(); - + row[TIME] = data.Duration(); + row[PPOS] = data.EnginePowerPositiveAverage().ConvertTo().Kilo.Watt; + row[PNEG] = data.EnginePowerNegativeAverage().ConvertTo().Kilo.Watt; + row[FCMAP] = data.FuelConsumptionPerSecond().ConvertTo().Gramm.Per.Hour; + row[FCAUXC] = data.FuelConsumptionAuxStartStopCorrectedPerSecond().ConvertTo().Gramm.Per.Hour; + row[FCWHTCC] = data.FuelConsumptionWHTCCorrectedPerSecond().ConvertTo().Gramm.Per.Hour; WriteAuxiliaries(data, row); _table.Rows.Add(row); } - [MethodImpl(MethodImplOptions.Synchronized)] - private void WriteAuxiliaries(IModalDataWriter data, DataRow row) - { - var simulationInterval = data.GetValues<Second>(ModalResultField.simulationInterval).ToArray(); - - _auxColumns = _auxColumns.Union(data.Auxiliaries.Select(kv => "Eaux_" + kv.Key + " [kWh]")).ToList(); - - var sum = 0.SI().Kilo.Watt.Hour.ConvertTo().Kilo.Watt.Hour; - foreach (var aux in data.Auxiliaries) { - var colName = "Eaux_" + aux.Key + " [kWh]"; - if (!_table.Columns.Contains(colName)) { - _table.Columns.Add(colName, typeof(SI)); - } - - var currentSum = data.GetValues<Watt>(aux.Value) - .Zip(simulationInterval, (P, dt) => P.ConvertTo().Kilo.Watt * dt.ConvertTo().Hour) - .Sum(); - row[colName] = currentSum; - sum += currentSum; - } - row[EAUX] = sum; - } - protected internal void WriteFullPowertrain(IModalDataWriter data, string jobFileName, string jobName, string cycleFileName, Kilogram vehicleMass, Kilogram vehicleLoading) { _engineOnly = false; - var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval).ToArray(); - - var time = data.Max(ModalResultField.time) - data.Min(ModalResultField.time); - var distance = data.Max(ModalResultField.dist) - data.Min(ModalResultField.dist); - - var totalFuelConsumption = TimeIntegralFuelConsumption(ModalResultField.FCMap, data, simulationIntervals); - var row = _table.NewRow(); + _table.Rows.Add(row); row[JOB] = jobName; row[INPUTFILE] = jobFileName; row[CYCLE] = cycleFileName; row[STATUS] = data.RunStatus; - row[TIME] = time; //data.Max(ModalResultField.time).DefaultIfNull(); - row[DISTANCE] = distance.ConvertTo().Kilo.Meter; //data.Max(ModalResultField.dist).DefaultIfNull(); - row[SPEED] = (distance / time).ConvertTo().Kilo.Meter.Per.Hour; - row[PPOS] = data.Average(ModalResultField.Pe_eng, x => x > 0).DefaultIfNull(); - row[PNEG] = data.Average(ModalResultField.Pe_eng, x => x < 0).DefaultIfNull(); - row[FCMAP] = (totalFuelConsumption / time).ConvertTo().Gramm.Per.Hour; - row[FCMAPKM] = (totalFuelConsumption / distance).ConvertTo().Gramm.Per.Kilo.Meter; - // data.Average(ModalResultField.FCMap).DefaultIfNull(); - row[FCAUXC] = data.Average(ModalResultField.FCAUXc).DefaultIfNull(); - row[FCWHTCC] = data.Average(ModalResultField.FCWHTCc).DefaultIfNull(); - row[PBRAKE] = data.Average(ModalResultField.Pbrake).DefaultIfNull(); - row[EPOSICE] = data.Average(ModalResultField.Pe_eng, x => x > 0).DefaultIfNull(); - row[ENEGICE] = data.Average(ModalResultField.Pe_eng, x => x < 0).DefaultIfNull(); - row[EAIR] = TimeIntegralPower(ModalResultField.Pair, data, simulationIntervals).DefaultIfNull(); - row[EROLL] = TimeIntegralPower(ModalResultField.Proll, data, simulationIntervals).DefaultIfNull(); - row[EGRAD] = TimeIntegralPower(ModalResultField.Pgrad, data, simulationIntervals).DefaultIfNull(); - row[EAUX] = TimeIntegralPower(ModalResultField.Paux, data, simulationIntervals).DefaultIfNull(); - row[EBRAKE] = TimeIntegralPower(ModalResultField.Pbrake, data, simulationIntervals).DefaultIfNull(); - - var plossdiff = TimeIntegralPower(ModalResultField.PlossDiff, data, simulationIntervals).DefaultIfNull(); - var plossgb = TimeIntegralPower(ModalResultField.PlossGB, data, simulationIntervals).DefaultIfNull(); - if ((plossdiff ?? plossgb) != null) { -// row[ETRANSM] = (plossdiff ?? 0.SI().Watt.Second.ConvertTo().Watt.Hour) + -// (plossgb ?? 0.SI().Watt.Second.ConvertTo().Watt.Hour); + row[TIME] = data.Duration(); + row[DISTANCE] = data.Distance().ConvertTo().Kilo.Meter; + row[SPEED] = data.Speed().ConvertTo().Kilo.Meter.Per.Hour; + row[ALTITUDE] = data.AltitudeDelta(); + row[PPOS] = data.EnginePowerPositiveAverage().ConvertTo().Kilo.Watt; + row[PNEG] = data.EnginePowerNegativeAverage().ConvertTo().Kilo.Watt; + row[FCFINAL] = data.FuelConsumptionFinal().ConvertTo().Gramm.Per.Kilo.Meter; + row[FCFINAL_LITERPER100KM] = data.FuelConsumptionFinalLiterPer100Kilometer(); + if (!vehicleLoading.IsEqual(0)) { + row[FCFINAL_LITERPER100TKM] = data.FuelConsumptionFinalLiterPer100Kilometer() / vehicleLoading.ConvertTo().Ton; } - row[ERETARDER] = TimeIntegralPower(ModalResultField.PlossRetarder, data, simulationIntervals).DefaultIfNull(); - - var paeng = data.Sum(ModalResultField.PaEng); - var pagb = data.Sum(ModalResultField.PaGB); - if ((paeng ?? pagb) != null) { - row[EACC] = paeng ?? 0.SI() + pagb ?? 0.SI(); + row[FCMAP] = data.FuelConsumptionPerSecond().ConvertTo().Gramm.Per.Hour; + row[FCMAPKM] = data.FuelConsumptionPerMeter().ConvertTo().Gramm.Per.Kilo.Meter; + row[FCAUXC] = data.FuelConsumptionAuxStartStopCorrectedPerSecond().ConvertTo().Gramm.Per.Hour; + row[FCAUXCKM] = data.FuelConsumptionAuxStartStopCorrected().ConvertTo().Gramm.Per.Kilo.Meter; + row[FCWHTCC] = data.FuelConsumptionWHTCCorrectedPerSecond().ConvertTo().Gramm.Per.Hour; + row[FCWHTCCKM] = data.FuelConsumptionWHTCCorrected().ConvertTo().Gramm.Per.Kilo.Meter; + row[CO2KM] = data.CO2PerMeter().ConvertTo().Gramm.Per.Kilo.Meter; + if (!vehicleLoading.IsEqual(0)) { + row[CO2TKM] = data.CO2PerMeter().ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton; } - - row[ALTITUDE] = data.GetValues<SI>(ModalResultField.altitude).Last() - - data.GetValues<SI>(ModalResultField.altitude).First(); - + row[PWHEELPOS] = data.PowerWheelPositive().ConvertTo().Kilo.Watt; + row[PBRAKE] = data.PowerBrake().ConvertTo().Kilo.Watt; + row[EPOSICE] = data.EngineWorkPositive().ConvertTo().Kilo.Watt.Hour; + row[ENEGICE] = data.EngineWorkNegative().ConvertTo().Kilo.Watt.Hour; + row[EAIR] = data.WorkAirResistance().ConvertTo().Kilo.Watt.Hour; + row[EROLL] = data.WorkRollingResistance().ConvertTo().Kilo.Watt.Hour; + row[EGRAD] = data.WorkRoadGradientResistance().ConvertTo().Kilo.Watt.Hour; + row[EACC] = data.PowerAccelerations().ConvertTo().Kilo.Watt.Hour; + row[EAUX] = data.WorkAuxiliaries().ConvertTo().Kilo.Watt.Hour; WriteAuxiliaries(data, row); - - if (vehicleMass != null) { - row[MASS] = vehicleMass; - } - - if (vehicleLoading != null) { - row[LOADING] = vehicleLoading; - } - - var dtValues = data.GetValues<SI>(ModalResultField.simulationInterval).Cast<Second>().ToList(); - var accValues = data.GetValues<SI>(ModalResultField.acc).Cast<MeterPerSquareSecond>(); - var accelerations = CalculateAverageOverSeconds(dtValues, accValues).ToList(); - if (accelerations.Any()) { - row[A] = accelerations.Average(); - } - - var acceleration3SecondAverage = Calculate3SecondAverage(accelerations).ToList(); - if (acceleration3SecondAverage.Any()) { - row[APOS] = acceleration3SecondAverage.Average(x => x > 0.125).DefaultIfNull(); - row[ANEG] = acceleration3SecondAverage.Average(x => x < -0.125).DefaultIfNull(); - row[PACC] = 100.SI() * acceleration3SecondAverage.Count(x => x > 0.125) / acceleration3SecondAverage.Count; - row[PDEC] = 100.SI() * acceleration3SecondAverage.Count(x => x < -0.125) / acceleration3SecondAverage.Count; - row[PCRUISE] = 100.SI() * acceleration3SecondAverage.Count(x => x < 0.125 && x > -0.125) / - acceleration3SecondAverage.Count; - } - var pStopTime = data.GetValues<SI>(ModalResultField.v_act) - .Zip(dtValues, (velocity, dt) => new { velocity, dt }) - .Where(x => x.velocity < 0.1) - .Sum(x => x.dt.Value()); - row[PSTOP] = 100 * pStopTime / dtValues.Sum(); - - _table.Rows.Add(row); + row[EBRAKE] = data.WorkTotalMechanicalBrake().ConvertTo().Kilo.Watt.Hour; + row[ETRANSM] = data.WorkTransmission().ConvertTo().Kilo.Watt.Hour; + row[ERETARDER] = data.WorkRetarder().ConvertTo().Kilo.Watt.Hour; + row[ETORQUECONV] = data.WorkTorqueConverter().ConvertTo().Kilo.Watt.Hour; + row[MASS] = vehicleMass; + row[LOADING] = vehicleLoading; + row[ACCELERATIONS] = data.AccelerationAverage(); + row[APOS] = data.AccelerationsPositive3SecondAverage(); + row[ANEG] = data.AverageAccelerations3SecondNegative(); + row[ACCNOISE] = data.AccelerationNoise(); + row[PACC] = data.PercentAccelerationTime(); + row[PDEC] = data.PercentDecelerationTime(); + row[PCRUISE] = data.PercentCruiseTime(); + row[PSTOP] = data.PercentStopTime(); } - protected static SI TimeIntegralPower(ModalResultField field, IModalDataWriter data, - IEnumerable<Second> simulationIntervals) - { - return data.GetValues<Watt>(field) - .Zip(simulationIntervals, (P, dt) => dt.ConvertTo().Hour * (P ?? 0.SI<Watt>()).ConvertTo().Kilo.Watt) - .Sum(); - } - - protected static Kilogram TimeIntegralFuelConsumption(ModalResultField field, IModalDataWriter data, - IEnumerable<Second> simulationIntervals) - { - return data.GetValues<KilogramPerSecond>(field) - .Zip(simulationIntervals, (FC, dt) => dt * (FC ?? 0.SI<KilogramPerSecond>())) - .Sum().Cast<Kilogram>(); - } - - private static IEnumerable<SI> Calculate3SecondAverage(IReadOnlyList<SI> accelerations) - { - if (accelerations.Count >= 3) { - var runningAverage = (accelerations[0] + accelerations[1] + accelerations[2]) / 3.0; - for (var i = 2; i < accelerations.Count() - 1; i++) { - runningAverage -= accelerations[i - 2] / 3.0; - runningAverage += accelerations[i + 1] / 3.0; - yield return runningAverage; - } - } - } - - - private static IEnumerable<SI> CalculateAverageOverSeconds(IEnumerable<Second> dtValues, - IEnumerable<MeterPerSquareSecond> accValues) + [MethodImpl(MethodImplOptions.Synchronized)] + private void WriteAuxiliaries(IModalDataWriter data, DataRow row) { - var dtSum = 0.SI().Second; - var accSum = 0.SI().Meter.Per.Second; - var acceleration = dtValues.Zip(accValues, (dt, acc) => new { dt, acc }).ToList(); - foreach (var x in acceleration.ToList()) { - var currentX = x; - - while (dtSum + currentX.dt >= 1) { - var splitX = new { dt = 1.SI<Second>() - dtSum, currentX.acc }; - yield return accSum; - dtSum = 0.SI<Second>(); - accSum = 0.SI<MeterPerSecond>(); - - currentX = new { dt = currentX.dt - splitX.dt, currentX.acc }; - } - if (currentX.dt > 0) { - accSum += currentX.dt * currentX.acc ?? 0.SI(); - dtSum += currentX.dt; + foreach (var aux in data.Auxiliaries) { + var colName = "Eaux_" + aux.Key + " [kWh]"; + if (!_table.Columns.Contains(colName)) { + _table.Columns.Add(colName, typeof(SI)); + _auxColumns.Add(colName); } - } - // return remaining data. acts like extrapolation to next whole second. - if (dtSum > 0) { - yield return accSum; + row[colName] = data.AuxiliaryWork(aux.Value).ConvertTo().Kilo.Watt.Hour; } } @@ -294,64 +206,16 @@ namespace TUGraz.VectoCore.Models.Simulation.Data dataColumns.AddRange(_auxColumns); dataColumns.AddRange(new[] { - PPOS, PNEG, FCMAP, FCMAPKM, FCAUXC, FCAUXCKM, FCWHTCC, FCWHTCCKM, CO2, CO2T, FCFINAL, FCFINAL_LITERPER100TKM, - FCFINAL_LITER, PWHEELPOS, PBRAKE, EPOSICE, ENEGICE, EAIR, EROLL, EGRAD, EACC, EAUX, EBRAKE, ETRANSM, - ERETARDER, ETORQUECONV, MASS, LOADING, A, APOS, ANEG, ACCNOISE, PACC, PDEC, PCRUISE, PSTOP + PPOS, PNEG, FCMAP, FCMAPKM, FCAUXC, FCAUXCKM, FCWHTCC, FCWHTCCKM, CO2KM, CO2TKM, FCFINAL, FCFINAL_LITERPER100KM, + FCFINAL_LITERPER100TKM, PWHEELPOS, PBRAKE, EPOSICE, ENEGICE, EAIR, EROLL, EGRAD, EACC, EAUX, EBRAKE, ETRANSM, + ERETARDER, ETORQUECONV, MASS, LOADING, ACCELERATIONS, APOS, ANEG, ACCNOISE, PACC, PDEC, PCRUISE, PSTOP }); } - VectoCSVFile.Write(_sumFileName, new DataView(_table).ToTable(false, dataColumns.ToArray())); - } - } -} - -/// <summary> -/// Decorator for FullPowertrain which adds some data for later use in the SummaryFileWriter. -/// </summary> -public class SumWriterDecoratorFullPowertrain : SummaryFileWriter, ISummaryDataWriter -{ - private readonly SummaryFileWriter _writer; - private readonly string _jobFileName; - private readonly string _jobName; - private readonly string _cycleFileName; - - public SumWriterDecoratorFullPowertrain(SummaryFileWriter writer, string jobFileName, string jobName, - string cycleFileName) - { - _writer = writer; - _jobFileName = jobFileName; - _jobName = jobName; - _cycleFileName = cycleFileName; - } - - public void Write(IModalDataWriter data, Kilogram vehicleMass = null, Kilogram vehicleLoading = null) - { - Log.Info("Writing Summary File"); - _writer.WriteFullPowertrain(data, _jobFileName, _jobName, _cycleFileName, vehicleMass, vehicleLoading); - } -} - - -/// <summary> -/// Decorator for EngineOnly Mode which adds some data for later use in the SummaryFileWriter. -/// </summary> -public class SumWriterDecoratorEngineOnly : SummaryFileWriter, ISummaryDataWriter -{ - private readonly SummaryFileWriter _writer; - private readonly string _jobFileName; - private readonly string _jobName; - private readonly string _cycleFileName; + var sortedAndFilteredTable = new DataView(_table, "", JOB, DataViewRowState.CurrentRows).ToTable(false, + dataColumns.ToArray()); - public SumWriterDecoratorEngineOnly(SummaryFileWriter writer, string jobFileName, string jobName, string cycleFileName) - { - _writer = writer; - _jobFileName = jobFileName; - _jobName = jobName; - _cycleFileName = cycleFileName; - } - - public void Write(IModalDataWriter data, Kilogram vehicleMass = null, Kilogram vehicleLoading = null) - { - _writer.WriteEngineOnly(data, _jobFileName, _jobName, _cycleFileName); + VectoCSVFile.Write(_sumFileName, sortedAndFilteredTable); + } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/Models/Simulation/Data/VectoRunData.cs index 6ecf013f7f2f958d38ae135b5c7b89fc31afeb02..2237d4ec074816cf68a48bab2e33567290e7373c 100644 --- a/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -2,7 +2,6 @@ using System.Runtime.Serialization; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Impl; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.Simulation.Data diff --git a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 3ce4cc26db60640e81c506b569fb389f0225113a..2075d3242abc3a051b8cdf5602889b0070624c81 100644 --- a/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Simulation.Data; @@ -19,7 +17,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl private readonly IModalDataWriter _dataWriter; - public PowertrainBuilder(IModalDataWriter dataWriter, ISummaryDataWriter sumWriter, bool engineOnly) + public PowertrainBuilder(IModalDataWriter dataWriter, bool engineOnly, WriteSumData sumWriter = null) { _engineOnly = engineOnly; _dataWriter = dataWriter; diff --git a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index 427e53951b9e874c1f4319e8a21c949b8fe6ba0d..4093dcfea6f4ac5b61d3f21595bca8f46cd3842b 100644 --- a/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; -using NLog; +using System.Threading; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.FileIO.Reader; @@ -12,6 +12,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl { public class SimulatorFactory : LoggingObject { + private static int _jobNumberCounter; + public enum FactoryMode { EngineeringMode, @@ -24,7 +26,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl public SimulatorFactory(FactoryMode mode, string jobFile) { Log.Fatal("########## VectoCore Version {0} ##########", Assembly.GetExecutingAssembly().GetName().Version); - JobNumber = 0; + JobNumber = Interlocked.Increment(ref _jobNumberCounter); _mode = mode; switch (mode) { case FactoryMode.DeclarationMode: @@ -66,9 +68,11 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl new ModalDataWriter(string.Format(modFileName, data.Cycle.Name, data.ModFileSuffix ?? ""), writer => d.Report.AddResult(d.Loading, d.Mission, writer), _mode); modWriter.WriteModalResults = WriteModalResults; - var jobName = string.Format("{0}-{1}", JobNumber, i++); - var sumWriterDecorator = DecorateSumWriter(data.IsEngineOnly, SumWriter, data.JobFileName, jobName, data.Cycle.Name); - var builder = new PowertrainBuilder(modWriter, sumWriterDecorator, DataReader.IsEngineOnly); + var builder = new PowertrainBuilder(modWriter, + DataReader.IsEngineOnly, (writer, mass, loading) => + SumWriter.Write(d.IsEngineOnly, modWriter, d.JobFileName, string.Format("{0}-{1}", JobNumber, i++), + d.Cycle.Name + ".vdri", + mass, loading)); VectoRun run; if (data.IsEngineOnly) { @@ -82,24 +86,5 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl yield return run; } } - - /// <summary> - /// Decorates the sum writer with a correct decorator (either EngineOnly or FullPowertrain). - /// </summary> - /// <param name="engineOnly">if set to <c>true</c> [engine only].</param> - /// <param name="sumWriter">The sum writer.</param> - /// <param name="jobFileName">Name of the job file.</param> - /// <param name="jobName">Name of the job.</param> - /// <param name="cycleName">The cycle file.</param> - /// <returns></returns> - private static ISummaryDataWriter DecorateSumWriter(bool engineOnly, SummaryFileWriter sumWriter, - string jobFileName, string jobName, string cycleName) - { - if (engineOnly) { - return new SumWriterDecoratorEngineOnly(sumWriter, jobFileName, jobName, cycleName); - } - - return new SumWriterDecoratorFullPowertrain(sumWriter, jobFileName, jobName, cycleName); - } } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index 9d6e2400875fd9bcfc2617bd20409c4ae0f30ef6..9a5751d8fd2aed7fe40a2d2ec160331133928032 100644 --- a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; -using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.SimulationComponent; @@ -29,8 +29,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl internal ISimulationOutPort Cycle; - internal ISummaryDataWriter SumWriter; internal IModalDataWriter DataWriter; + internal WriteSumData WriteSumData; #region IGearCockpit @@ -130,10 +130,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl #endregion - public VehicleContainer(IModalDataWriter dataWriter = null, ISummaryDataWriter sumWriter = null) + public VehicleContainer(IModalDataWriter dataWriter = null, WriteSumData writeSumData = null) { DataWriter = dataWriter; - SumWriter = sumWriter; + WriteSumData = writeSumData ?? delegate {}; } #region IVehicleContainer @@ -213,7 +213,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Log.Info("VehicleContainer finishing simulation."); DataWriter.Finish(RunStatus); - SumWriter.Write(DataWriter, VehicleMass, VehicleLoading); + WriteSumData(DataWriter, VehicleMass, VehicleLoading); } public VectoRun.Status RunStatus { get; set; } diff --git a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs index 32a8a3d1d524a9ce294039f49179a53bd0bb5c2e..226e25fb27efbb63fb88aea5b9ec8437d3f0f701 100644 --- a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs +++ b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs @@ -23,6 +23,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public EngineFullLoadCurve FullLoadCurve { get; internal set; } + private double _whtcCorrectionFactor = 1; + + public double WHTCCorrectionFactor + { + get { return _whtcCorrectionFactor; } + internal set { _whtcCorrectionFactor = value; } + } + #region Equality Member protected bool Equals(CombustionEngineData other) @@ -62,6 +70,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data return hashCode; } } + #endregion } } \ No newline at end of file diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 2f03a9ebc611fc6e70f8d2cb42aebe84745a0a7a..0ae4c257d05e5b1a7843e7aa4753a42bb0c770b3 100644 --- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -6,6 +6,7 @@ using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; @@ -214,8 +215,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl writer[ModalResultField.n] = CurrentState.EngineSpeed; try { - writer[ModalResultField.FCMap] = - Data.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, CurrentState.EngineSpeed); + var fc = Data.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, CurrentState.EngineSpeed); + writer[ModalResultField.FCMap] = fc; + + //todo (MK, 2015-11-11): calculate aux start stop correction when start stop functionality is implemented in v3 + var fcaux = fc; + writer[ModalResultField.FCAUXc] = fcaux; + writer[ModalResultField.FCWHTCc] = fcaux * Data.WHTCCorrectionFactor; } catch (VectoException ex) { Log.Warn("t: {0} - {1} n: {2} Tq: {3}", CurrentState.AbsTime, ex.Message, CurrentState.EngineSpeed, CurrentState.EngineTorque); diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs index 26b901877e430b28844b5ecc4dd37180de092f53..d2ee769e33823c14bc37fba04ca7ad8b7e191dda 100644 --- a/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -1,15 +1,12 @@ using System; -using System.CodeDom; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Security.Cryptography.X509Certificates; using NLog; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Connector.Ports.Impl; -using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.Simulation.Impl; diff --git a/VectoCore/Utils/IEnumberableExtensionMethods.cs b/VectoCore/Utils/IEnumberableExtensionMethods.cs index 1ffc5b57fe5933d844a1524260ea7a7fb41eb727..48cc64ca4bc85515389666dcfd381d7734be3145 100644 --- a/VectoCore/Utils/IEnumberableExtensionMethods.cs +++ b/VectoCore/Utils/IEnumberableExtensionMethods.cs @@ -49,6 +49,12 @@ namespace TUGraz.VectoCore.Utils return valueList.Any() ? valueList.Aggregate((sum, current) => sum + current) : null; } + public static T Average<T>(this IEnumerable<T> values) where T : SIBase<T> + { + var valueList = values.ToList(); + return valueList.Any() ? valueList.Aggregate((sum, current) => sum + current) / valueList.Count : null; + } + public static SI Sum(this IEnumerable<SI> values) { var valueList = values.ToList(); diff --git a/VectoCore/Utils/Physics.cs b/VectoCore/Utils/Physics.cs index c814e3c0e53e058a8901faf55f7e27045914bcf1..2b18f0625e35034482339a7be26aec20a67335b5 100644 --- a/VectoCore/Utils/Physics.cs +++ b/VectoCore/Utils/Physics.cs @@ -20,7 +20,7 @@ /// <summary> - /// Factor to convert from fuel weight to co2 weight. + /// fuel[kg] => co2[kg]. Factor to convert from fuel weight to co2 weight. /// </summary> public static readonly double CO2PerFuelWeight = 3.16; } diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs index e17a8fb4c99f5df99f876e6c3da8be09a898f1b1..77e17394349ec46ddbe8b8c9151dcd1d3e644c32 100644 --- a/VectoCore/Utils/SI.cs +++ b/VectoCore/Utils/SI.cs @@ -30,11 +30,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator +. /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Scalar operator +(Scalar si1, Scalar si2) { @@ -44,11 +39,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator +. /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Scalar operator +(Scalar si1, double si2) { @@ -58,11 +48,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator +. /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Scalar operator +(double si1, Scalar si2) { @@ -72,11 +57,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator -. /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Scalar operator -(Scalar si1, Scalar si2) { @@ -86,11 +66,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator -. /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Scalar operator -(Scalar si1, double si2) { @@ -100,11 +75,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator -. /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Scalar operator -(double si1, Scalar si2) { @@ -178,18 +148,14 @@ namespace TUGraz.VectoCore.Utils Denominator = new[] { Unit.s, Unit.s }; } + /// <summary> - /// Implements the operator /. + /// Implements the operator *. /// </summary> - /// <param name="meterPerSecond">The meter per second.</param> - /// <param name="meterPerSquareSecond">The meter per square second.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] - public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond) + public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second) { - return SIBase<Second>.Create(meterPerSecond.Value() / meterPerSquareSecond.Val); + return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value()); } } @@ -215,6 +181,32 @@ namespace TUGraz.VectoCore.Utils { Numerator = new[] { Unit.m }; } + + [DebuggerHidden] + public static MeterPerSecond operator /(Meter meter, Second second) + { + return ((meter as SI) / second).Cast<MeterPerSecond>(); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static Second operator /(Meter second, MeterPerSecond meterPerSecond) + { + return SIBase<Second>.Create(second.Val / meterPerSecond.Value()); + } + } + + public class KilogramPerMeter : SIBase<KilogramPerMeter> + { + [JsonConstructor, DebuggerHidden] + protected KilogramPerMeter(double val) + : base(val) + { + Numerator = new[] { Unit.k, Unit.g }; + Denominator = new[] { Unit.m }; + } } /// <summary> @@ -227,6 +219,18 @@ namespace TUGraz.VectoCore.Utils { Numerator = new[] { Unit.k, Unit.g }; } + + [DebuggerHidden] + public static KilogramPerSecond operator /(Kilogram kg, Second second) + { + return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value()); + } + + [DebuggerHidden] + public static KilogramPerMeter operator /(Kilogram kg, Meter m) + { + return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value()); + } } /// <summary> @@ -312,6 +316,22 @@ namespace TUGraz.VectoCore.Utils } } + public class WattSecond : SIBase<WattSecond> + { + [JsonConstructor, DebuggerHidden] + protected WattSecond(double val) : base(val) + { + Numerator = new[] { Unit.W, Unit.s }; + } + + [DebuggerHidden] + public static Watt operator /(WattSecond wattSecond, Second second) + { + return SIBase<Watt>.Create(wattSecond.Val / second.Value()); + } + } + + /// <summary> /// SI Class for Watt [W]. /// </summary> @@ -350,6 +370,12 @@ namespace TUGraz.VectoCore.Utils { return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value()); } + + [DebuggerHidden] + public static WattSecond operator *(Watt watt, Second second) + { + return SIBase<WattSecond>.Create(watt.Val * second.Value()); + } } /// <summary> @@ -381,11 +407,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator /. /// </summary> - /// <param name="meterPerSecond">The meter per second.</param> - /// <param name="meter">The meter.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter) { @@ -395,25 +416,24 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator /. /// </summary> - /// <param name="second">The second.</param> - /// <param name="meterPerSecond">The meter per second.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] - public static Second operator /(Meter second, MeterPerSecond meterPerSecond) + public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond) + { + return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second) { - return SIBase<Second>.Create(second.Value() / meterPerSecond.Val); + return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value()); } /// <summary> /// Implements the operator *. /// </summary> - /// <param name="meterPerSecond">The meter per second.</param> - /// <param name="second">The second.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Meter operator *(MeterPerSecond meterPerSecond, Second second) { @@ -423,11 +443,6 @@ namespace TUGraz.VectoCore.Utils /// <summary> /// Implements the operator *. /// </summary> - /// <param name="meterPerSecond">The meter per second.</param> - /// <param name="second">The second.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] public static Meter operator *(Second second, MeterPerSecond meterPerSecond) { @@ -1592,6 +1607,17 @@ namespace TUGraz.VectoCore.Utils return lower <= Val && Val <= upper; } + /// <summary> + /// Determines whether the SI is between lower and uppper bound. + /// </summary> + /// <param name="lower">The lower bound.</param> + /// <param name="upper">The upper bound.</param> + /// <returns></returns> + public bool IsBetween(double lower, double upper) + { + return lower <= Val && Val <= upper; + } + #endregion #region ToString diff --git a/VectoCore/VectoCore.csproj b/VectoCore/VectoCore.csproj index 0d592ade9fcfe85538fd4f2432510bf38a341aa9..afa07c2c560682996bd396f2613b03028f6e972e 100644 --- a/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore.csproj @@ -179,6 +179,7 @@ <Compile Include="Models\SimulationComponent\Data\FullLoadCurve.cs" /> <Compile Include="Models\Simulation\DataBus\IMileageCounter.cs" /> <Compile Include="Models\Simulation\DataBus\IRoadLookAhead.cs" /> + <Compile Include="Models\Simulation\Data\VectoJobData.cs" /> <Compile Include="Models\Simulation\Impl\DistanceRun.cs" /> <Compile Include="Models\Simulation\Impl\PowertrainBuilder.cs" /> <Compile Include="Models\Simulation\Impl\TimeRun.cs" /> @@ -217,7 +218,6 @@ <Compile Include="Models\SimulationComponent\Impl\AxleGear.cs" /> <Compile Include="Models\SimulationComponent\Impl\Retarder.cs" /> <Compile Include="Models\SimulationComponent\IPowerTrainComponent.cs" /> - <Compile Include="Models\Simulation\Data\ISummaryDataWriter.cs" /> <Compile Include="Models\Simulation\Data\SummaryFileWriter.cs" /> <Compile Include="Models\Simulation\Data\VectoRunData.cs" /> <Compile Include="Models\SimulationComponent\Impl\Driver.cs" /> diff --git a/VectoCoreTest/Integration/CoachPowerTrain.cs b/VectoCoreTest/Integration/CoachPowerTrain.cs index abfdba3c780f5ee9e4412b289a6c8ec391bfa67b..2ed08020c52b409d2b51088a17e5c74f4f355d5d 100644 --- a/VectoCoreTest/Integration/CoachPowerTrain.cs +++ b/VectoCoreTest/Integration/CoachPowerTrain.cs @@ -39,8 +39,7 @@ namespace TUGraz.VectoCore.Tests.Integration public static VehicleContainer CreatePowerTrain(DrivingCycleData cycleData, string modFileName, bool overspeed = false) { var modalWriter = new ModalDataWriter(modFileName); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(modalWriter, sumWriter); + var container = new VehicleContainer(modalWriter); var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile); var axleGearData = CreateAxleGearData(); diff --git a/VectoCoreTest/Integration/DeclarationReportTest.cs b/VectoCoreTest/Integration/DeclarationReportTest.cs index a2b6d3d6b0e917d3d402ac3bddf65e4dd4255040..f463bc88ab7189b98038ecb27d17a52bd85ccbd3 100644 --- a/VectoCoreTest/Integration/DeclarationReportTest.cs +++ b/VectoCoreTest/Integration/DeclarationReportTest.cs @@ -1,4 +1,6 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.IO; +using System.Threading; +using Microsoft.VisualStudio.TestTools.UnitTesting; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; @@ -10,18 +12,25 @@ namespace TUGraz.VectoCore.Tests.Integration [TestMethod] public void DeclarationReport_Test() { + if (File.Exists("job-report.vsum")) { + File.Delete("job-report.vsum"); + } + + if (File.Exists("job-report.pdf")) { + File.Delete("job-report.pdf"); + } + var sumWriter = new SummaryFileWriter(@"job-report.vsum"); var jobContainer = new JobContainer(sumWriter); - var factory = new SimulatorFactory(SimulatorFactory.FactoryMode.DeclarationMode, @"TestData\Jobs\job-report.vecto"); jobContainer.AddRuns(factory); jobContainer.Execute(); - //ResultFileHelper.TestSumFile(@"TestData\Results\Integration\job.vsum", @"job.vsum"); + jobContainer.WaitFinished(); - //ResultFileHelper.TestModFile(@"TestData\Results\Integration\job_1-Gear-Test-dist.vmod", - // @"TestData\job_1-Gear-Test-dist.vmod", testRowCount: false); + Assert.IsTrue(File.Exists(@"job-report.vsum")); + Assert.IsTrue(File.Exists(@"TestData\Jobs\job-report.pdf")); } } } \ No newline at end of file diff --git a/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs index 5d08f2c7f0d43d9d51a38520a9c4defd2283f479..65764e6bff8c4a58ca394f07873d88fdf502b1c2 100644 --- a/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs +++ b/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs @@ -39,8 +39,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns public void Test_FullPowertrain_SimpleGearbox() { var modalWriter = new ModalDataWriter("Coach_FullPowertrain_SimpleGearbox.vmod"); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(modalWriter, sumWriter); + var container = new VehicleContainer(modalWriter); var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile); var cycleData = DrivingCycleDataReader.ReadFromFileDistanceBased(CycleFile); @@ -98,8 +97,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns public void Test_FullPowertrain() { var modalWriter = new ModalDataWriter("Coach_FullPowertrain.vmod"); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(modalWriter, sumWriter); + var container = new VehicleContainer(modalWriter); var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile); var cycleData = DrivingCycleDataReader.ReadFromFileDistanceBased(CoachCycleFile); @@ -174,8 +172,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns public void Test_FullPowertrain_LowSpeed() { var modalWriter = new ModalDataWriter("Coach_FullPowertrain_LowSpeed.vmod"); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(modalWriter, sumWriter); + var container = new VehicleContainer(modalWriter); var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile); var cycleData = DrivingCycleDataReader.ReadFromFileDistanceBased(CycleFile); diff --git a/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs b/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs index 9aa836400062b4dfcdd82ebf95228ccd49d79288..39a3e1c293aa54b952473bde11e50bb9e26105e5 100644 --- a/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs +++ b/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs @@ -45,8 +45,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var driverData = CreateDriverData(AccelerationFile); var modalWriter = new ModalDataWriter("Coach_MinimalPowertrainOverload.vmod"); //new TestModalDataWriter(); - var sumWriter = new TestSumWriter(); - var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var vehicleContainer = new VehicleContainer(modalWriter); var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); dynamic tmp = Port.AddComponent(driver, new Vehicle(vehicleContainer, vehicleData)); @@ -96,8 +95,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var driverData = CreateDriverData(AccelerationFile); var modalWriter = new ModalDataWriter("Coach_MinimalPowertrain.vmod"); //new TestModalDataWriter(); - var sumWriter = new TestSumWriter(); - var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var vehicleContainer = new VehicleContainer(modalWriter); var cycle = new DistanceBasedDrivingCycle(vehicleContainer, cycleData); @@ -168,8 +166,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var modalWriter = new ModalDataWriter("Coach_MinimalPowertrainOverload.vmod", SimulatorFactory.FactoryMode.EngineeringMode); - var sumWriter = new TestSumWriter(); - var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var vehicleContainer = new VehicleContainer(modalWriter); var cycle = new DistanceBasedDrivingCycle(vehicleContainer, cycleData); diff --git a/VectoCoreTest/Integration/Truck40tPowerTrain.cs b/VectoCoreTest/Integration/Truck40tPowerTrain.cs index 6bde76e2496fdef4a376b7c01d5745d57ca21cfc..b3fba6eb62e7bab75fcdeeabd15071b6fb5ed34d 100644 --- a/VectoCoreTest/Integration/Truck40tPowerTrain.cs +++ b/VectoCoreTest/Integration/Truck40tPowerTrain.cs @@ -46,8 +46,7 @@ namespace TUGraz.VectoCore.Tests.Integration Kilogram loading, bool overspeed = false) { var modalWriter = new ModalDataWriter(modFileName); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(modalWriter, sumWriter); + var container = new VehicleContainer(modalWriter); var engineData = EngineeringModeSimulationDataReader.CreateEngineDataFromFile(EngineFile); var axleGearData = CreateAxleGearData(); diff --git a/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCoreTest/Models/Simulation/AuxTests.cs index 30f2cdd8a020eec123623bbff4e6663878abd4af..0e75df621772e5662210459a6e23eae95a7ecafe 100644 --- a/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -1,5 +1,4 @@ -using System.Linq; -using TUGraz.VectoCore.Utils; +using TUGraz.VectoCore.Utils; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Tests.Utils; using TUGraz.VectoCore.FileIO.Reader; @@ -7,7 +6,6 @@ using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; using Microsoft.VisualStudio.TestTools.UnitTesting; -using TUGraz.VectoCore.FileIO; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Impl; @@ -27,9 +25,8 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation dataWriter.AddAuxiliary("AC"); var sumWriter = new SummaryFileWriter(@"AuxWriteModFileSumFile.vsum"); - var deco = new SumWriterDecoratorFullPowertrain(sumWriter, "", "", ""); - - var container = new VehicleContainer(dataWriter, deco); + var container = new VehicleContainer(dataWriter, + (writer, mass, loading) => sumWriter.WriteFullPowertrain(dataWriter, "", "", "", null, null)); var data = DrivingCycleDataReader.ReadFromFileDistanceBased(@"TestData\Cycles\LongHaul_short.vdri"); var mockcycle = new MockDrivingCycle(container, data); var port = new MockTnOutPort(); @@ -77,8 +74,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation public void AuxConstant() { var dataWriter = new MockModalDataWriter(); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(dataWriter, sumWriter); + var container = new VehicleContainer(dataWriter); var port = new MockTnOutPort(); var aux = new Auxiliary(container); aux.InPort().Connect(port); @@ -113,8 +109,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation public void AuxDirect() { var dataWriter = new MockModalDataWriter(); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(dataWriter, sumWriter); + var container = new VehicleContainer(dataWriter); var data = DrivingCycleDataReader.ReadFromFileTimeBased(@"TestData\Cycles\Coach time based short.vdri"); var cycle = new MockDrivingCycle(container, data); var port = new MockTnOutPort(); @@ -146,8 +141,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation dataWriter.AddAuxiliary("ALT1"); dataWriter.AddAuxiliary("CONSTANT"); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(dataWriter, sumWriter); + var container = new VehicleContainer(dataWriter); var data = DrivingCycleDataReader.ReadFromFileTimeBased(@"TestData\Cycles\Coach time based short.vdri"); // cycle ALT1 is set to values to equal the first few fixed points in the auxiliary file. // ALT1.aux file: nAuxiliary speed 2358: 0, 0.38, 0.49, 0.64, ... @@ -203,8 +197,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var dataWriter = new MockModalDataWriter(); dataWriter.AddAuxiliary(auxId); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(dataWriter, sumWriter); + var container = new VehicleContainer(dataWriter); var data = DrivingCycleDataReader.ReadFromFileTimeBased(@"TestData\Cycles\Coach time based short.vdri"); // cycle ALT1 is set to values to equal the first few fixed points in the auxiliary file. // ALT1.aux file: nAuxiliary speed 2358: 0, 0.38, 0.49, 0.64, ... diff --git a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs index 24092823959b61078fb8bc8fbb229736a2c89463..cce5995c6b65d1b516ab0c0f42fe22fa37675a77 100644 --- a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs +++ b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs @@ -17,8 +17,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation public void TestEngineOnly() { var dataWriter = new MockModalDataWriter(); - var sumWriter = new TestSumWriter(); - var container = new VehicleContainer(dataWriter, sumWriter); + var container = new VehicleContainer(dataWriter); var cycleData = DrivingCycleDataReader.ReadFromFileEngineOnly(@"TestData\Cycles\Coach Engine Only.vdri"); var cycle = new EngineOnlyDrivingCycle(container, cycleData); @@ -133,7 +132,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation [TestMethod] public void Test_TimeBased_TimeFieldMissing() { - var container = new VehicleContainer(new MockModalDataWriter(), new TestSumWriter()); + var container = new VehicleContainer(new MockModalDataWriter()); var cycleData = DrivingCycleDataReader.ReadFromFileTimeBased(@"TestData\Cycles\Cycle time field missing.vdri"); var cycle = new TimeBasedDrivingCycle(container, cycleData); diff --git a/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs b/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs index b6800417bc9e9d00d0e34d006afc9a1012c40f61..00fd71389b764a3387876da4f7849aae91d13828 100644 --- a/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs +++ b/VectoCoreTest/Models/Simulation/PowerTrainBuilderTest.cs @@ -22,8 +22,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var runData = reader.NextRun().First(); var writer = new MockModalDataWriter(); - var sumWriter = new TestSumWriter(); - var builder = new PowertrainBuilder(writer, sumWriter, false); + var builder = new PowertrainBuilder(writer, false); var powerTrain = builder.Build(runData); diff --git a/VectoCoreTest/Models/Simulation/SimulationTests.cs b/VectoCoreTest/Models/Simulation/SimulationTests.cs index f13aa51927e7b6b112848ecb35d6bc199cd25dd8..8201a30ab6d09c60aba786e627e0011b0d1c41bd 100644 --- a/VectoCoreTest/Models/Simulation/SimulationTests.cs +++ b/VectoCoreTest/Models/Simulation/SimulationTests.cs @@ -41,6 +41,16 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation ResultFileHelper.TestModFile(expected, actual); } + private class MockSumWriter : SummaryFileWriter + { + public override void Write(bool isEngineOnly, IModalDataWriter data, string jobFileName, string jobName, + string cycleFileName, + Kilogram vehicleMass, Kilogram vehicleLoading) {} + + public override void Finish() {} + } + + [TestMethod] public void TestEngineOnly_SimulatorRun() { @@ -49,7 +59,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var run = CreateRun(actual); - var sim = new JobContainer(new TestSumWriter()); + var sim = new JobContainer(new MockSumWriter()); sim.AddRun(run); sim.Execute(); diff --git a/VectoCoreTest/Models/SimulationComponent/DriverTest.cs b/VectoCoreTest/Models/SimulationComponent/DriverTest.cs index 003a61f76de5a56125c2cb0c0f6cd8024361a666..df4a0d5b45ea0b7b399d8e8e517c485d87b1d2b0 100644 --- a/VectoCoreTest/Models/SimulationComponent/DriverTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/DriverTest.cs @@ -42,8 +42,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var modalWriter = new ModalDataWriter("Coach_MinimalPowertrain_Coasting.vmod", SimulatorFactory.FactoryMode.EngineeringMode); //new TestModalDataWriter(); - var sumWriter = new TestSumWriter(); - var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var vehicleContainer = new VehicleContainer(modalWriter); var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); var engine = new CombustionEngine(vehicleContainer, engineData); @@ -96,10 +95,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var driverData = CreateDriverData(); - var modalWriter = new ModalDataWriter("Coach_MinimalPowertrain_Coasting.vmod", - SimulatorFactory.FactoryMode.EngineeringMode); //new TestModalDataWriter(); - var sumWriter = new TestSumWriter(); - var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var modalWriter = new ModalDataWriter("Coach_MinimalPowertrain_Coasting.vmod"); + var vehicleContainer = new VehicleContainer(modalWriter); var driver = new Driver(vehicleContainer, driverData, new DefaultDriverStrategy()); var engine = new CombustionEngine(vehicleContainer, engineData); @@ -157,8 +154,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var driverData = CreateDriverData(); var modalWriter = new ModalDataWriter("Coach_MinimalPowertrain.vmod", SimulatorFactory.FactoryMode.EngineeringMode); - var sumWriter = new TestSumWriter(); - var vehicleContainer = new VehicleContainer(modalWriter, sumWriter); + var vehicleContainer = new VehicleContainer(modalWriter); var cycle = new MockDrivingCycle(vehicleContainer, null); diff --git a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs index bf03b90d46a275b6dfcd3972f429055e77523ff4..1f7a41629cda700936a89a9703b8add83aa52eb0 100644 --- a/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/GearboxTest.cs @@ -48,7 +48,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent Tuple.Create((uint)i, new GearData { FullLoadCurve = FullLoadCurve.ReadFromFile(GearboxFullLoadCurveFile), - LossMap = TransmissionLossMap.ReadFromFile((i != 6) ? IndirectLossMap : DirectLossMap, ratio), + LossMap = TransmissionLossMap.ReadFromFile((i != 6) ? IndirectLossMap : DirectLossMap, ratio, i.ToString()), Ratio = ratio, ShiftPolygon = ShiftPolygon.ReadFromFile(GearboxShiftPolygonFile) })) diff --git a/VectoCoreTest/Utils/TestSumWriter.cs b/VectoCoreTest/Utils/TestSumWriter.cs deleted file mode 100644 index 95c41f931db85ae7a65c7cd5b65d148cf0ab7043..0000000000000000000000000000000000000000 --- a/VectoCoreTest/Utils/TestSumWriter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Utils; - -namespace TUGraz.VectoCore.Tests.Utils -{ - public class TestSumWriter : SummaryFileWriter, ISummaryDataWriter - { - public void Write(IModalDataWriter data, Kilogram vehicleMass = null, Kilogram vehicleLoading = null) {} - - public override void Finish() {} - } -} \ No newline at end of file diff --git a/VectoCoreTest/VectoCoreTest.csproj b/VectoCoreTest/VectoCoreTest.csproj index 973e2c1dddaadc9c69a4e4d0b66c9649be7b6a67..ace6d23cf28490106842ebd484a47686ac1f7aa9 100644 --- a/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCoreTest/VectoCoreTest.csproj @@ -107,7 +107,6 @@ <Compile Include="Utils\ResultFileHelper.cs" /> <Compile Include="Utils\MockPorts.cs" /> <Compile Include="Models\Simulation\SimulationTests.cs" /> - <Compile Include="Utils\TestSumWriter.cs" /> <Compile Include="Models\Simulation\VechicleContainerTests.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\Settings.Designer.cs">