From 0d735af1017a3c5c0478ba8fb59f33a558c31384 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Tue, 26 Jul 2016 09:57:39 +0200 Subject: [PATCH] split fuelconsumption map into lookup-part and input data reading part --- .../ComponentData/RetarderLossMapReader.cs | 2 +- .../TorqueConverterDataReader.cs | 3 +- .../TransmissionLossMapReader.cs | 10 +- .../AbstractSimulationDataAdapter.cs | 10 +- .../Data/Engine/FuelConsumptionMap.cs | 90 +---------------- .../Data/Engine/FuelConsumptionMapReader.cs | 98 +++++++++++++++++++ .../BusAuxiliaries/AuxDemandTest.cs | 2 +- .../FuelConsumptionMapTest.cs | 4 +- .../TorqueConverterDataTest.cs | 5 +- .../SimulationComponentData/ValidationTest.cs | 2 +- 10 files changed, 121 insertions(+), 105 deletions(-) create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs index 9cd7522be1..d47c2d21e5 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs @@ -78,7 +78,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data }).ToList(); } - private static class Fields + public static class Fields { /// <summary> /// [rpm] diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/TorqueConverterDataReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/TorqueConverterDataReader.cs index 8031ec1ffe..ae2cf4d192 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/TorqueConverterDataReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/TorqueConverterDataReader.cs @@ -4,9 +4,10 @@ using System.IO; using System.Linq; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Utils; -namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox +namespace TUGraz.VectoCore.InputData.Reader.ComponentData { public class TorqueConverterDataReader { diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/TransmissionLossMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/TransmissionLossMapReader.cs index ca761e29df..e6304bf963 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/TransmissionLossMapReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/TransmissionLossMapReader.cs @@ -31,7 +31,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox public static TransmissionLossMap Create(DataTable data, double gearRatio, string gearName) { if (data.Columns.Count < 3) { - throw new VectoException("TransmissionLossMap Data File for {0} must consist of at least 3 columns.", gearName); + throw new VectoException("TransmissionLossMap Data File for {0} must consist of 3 columns.", gearName); } if (data.Rows.Count < 4) { @@ -44,9 +44,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox entries = CreateFromColumnNames(data); } else { LoggingObject.Logger<TransmissionLossMap>().Warn( - "TransmissionLossMap {5}: Header line is not valid. Expected: '{0}, {1}, {2}, <{3}>'. Got: '{4}'. Falling back to column index.", - TransmissionLossMapReader.Fields.InputSpeed, TransmissionLossMapReader.Fields.InputTorque, - TransmissionLossMapReader.Fields.TorqeLoss, TransmissionLossMapReader.Fields.Efficiency, + "TransmissionLossMap {5}: Header line is not valid. Expected: '{0}, {1}, {2}'. Got: '{4}'. Falling back to column index.", + Fields.InputSpeed, Fields.InputTorque, Fields.TorqeLoss, ", ".Join(data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Reverse()), gearName); entries = CreateFromColumIndizes(data); @@ -116,9 +115,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox /// <summary>[Nm]</summary> public const string TorqeLoss = "Torque Loss"; - - /// <summary>[-]</summary> - public const string Efficiency = "Eff"; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs index 86b6494cff..bf9bab60dc 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs @@ -30,7 +30,9 @@ */ using System; +using System.Collections.Generic; using System.Linq; +using iTextSharp.text.pdf; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; @@ -89,8 +91,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter Type = data.Type, }; switch (retarder.Type) { - //case RetarderType.EngineRetarder: - case RetarderType.TransmissionInputRetarder: + //case RetarderType.EngineRetarder: + case RetarderType.TransmissionInputRetarder: retarder.LossMap = RetarderLossMapReader.Create(data.LossMap); retarder.Ratio = data.Ratio; break; @@ -123,7 +125,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter IntegrityStatus = data.IntegrityStatus, Displacement = data.Displacement, IdleSpeed = data.IdleSpeed, - ConsumptionMap = FuelConsumptionMap.Create(data.FuelConsumptionMap), + ConsumptionMap = FuelConsumptionMapReader.Create(data.FuelConsumptionMap), }; return retVal; } @@ -216,7 +218,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter case AngularGearType.None: return null; default: - throw new ArgumentOutOfRangeException("data", "Unknown AngularGear Type."); + throw new ArgumentOutOfRangeException("data", "Unknown Angulargear Type."); } } catch (Exception e) { throw new VectoException("Error while reading AngularGear data: {0}", e.Message); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs index 4a88139444..bbc64f3d86 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs @@ -43,75 +43,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine { public class FuelConsumptionMap : SimulationComponentData { - [Required, ValidateObject] private readonly DelaunayMap _fuelMap = new DelaunayMap("FuelConsumptionMap"); + [Required, ValidateObject] private readonly DelaunayMap _fuelMap; - private FuelConsumptionMap() {} - - public static FuelConsumptionMap ReadFromFile(string fileName) + protected internal FuelConsumptionMap(DelaunayMap fuelMap) { - try { - var data = VectoCSVFile.Read(fileName); - return Create(data); - } catch (Exception e) { - throw new VectoException(string.Format("File {0}: {1}", fileName, e.Message), e); - } - } - - public static FuelConsumptionMap Create(DataTable data) - { - var headerValid = HeaderIsValid(data.Columns); - if (!headerValid) { - Logger<FuelConsumptionMap>().Warn( - "FuelConsumptionMap: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: {3}", - Fields.EngineSpeed, Fields.Torque, Fields.FuelConsumption, - ", ".Join(data.Columns.Cast<DataColumn>().Select(c => c.ColumnName))); - } - var fuelConsumptionMap = new FuelConsumptionMap(); - - foreach (DataRow row in data.Rows) { - try { - var entry = headerValid ? CreateFromColumNames(row) : CreateFromColumnIndizes(row); - - // Delaunay map works only as expected, when the angularVelocity is in rpm. - fuelConsumptionMap._fuelMap.AddPoint(entry.Torque.Value(), - headerValid ? row.ParseDouble(Fields.EngineSpeed) : row.ParseDouble(0), - entry.FuelConsumption.Value()); - } catch (Exception e) { - throw new VectoException(string.Format("Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e); - } - } - - fuelConsumptionMap._fuelMap.Triangulate(); - return fuelConsumptionMap; - } - - private static bool HeaderIsValid(DataColumnCollection columns) - { - return columns.Contains(Fields.EngineSpeed) && columns.Contains(Fields.Torque) && - columns.Contains(Fields.FuelConsumption); - } - - private static FuelConsumptionEntry CreateFromColumnIndizes(DataRow row) - { - return new FuelConsumptionEntry( - engineSpeed: row.ParseDouble(0).RPMtoRad(), - torque: row.ParseDouble(1).SI<NewtonMeter>(), - fuelConsumption: - row.ParseDouble(2).SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>() - ); - } - - private static FuelConsumptionEntry CreateFromColumNames(DataRow row) - { - return new FuelConsumptionEntry( - engineSpeed: row.ParseDouble(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(), - torque: row.ParseDouble(Fields.Torque).SI<NewtonMeter>(), - fuelConsumption: - row.ParseDouble(Fields.FuelConsumption) - .SI() - .Gramm.Per.Hour.ConvertTo() - .Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>() - ); + _fuelMap = fuelMap; } /// <summary> @@ -135,26 +71,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine angularVelocity.AsRPM); } - public static class Fields - { - /// <summary> - /// [rpm] - /// </summary> - public const string EngineSpeed = "engine speed"; - - /// <summary> - /// [Nm] - /// </summary> - public const string Torque = "torque"; - - /// <summary> - /// [g/h] - /// </summary> - public const string FuelConsumption = "fuel consumption"; - } - [SuppressMessage("ReSharper", "MemberCanBePrivate.Local")] - private class FuelConsumptionEntry + public class FuelConsumptionEntry { [Required, SIRange(0, 5000 * Constants.RPMToRad)] public PerSecond EngineSpeed { get; set; } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs new file mode 100644 index 0000000000..34357faf66 --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs @@ -0,0 +1,98 @@ +using System; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine +{ + public class FuelConsumptionMapReader + { + public static FuelConsumptionMap ReadFromFile(string fileName) + { + try { + var data = VectoCSVFile.Read(fileName); + return Create(data); + } catch (Exception e) { + throw new VectoException(string.Format("File {0}: {1}", fileName, e.Message), e); + } + } + + public static FuelConsumptionMap Create(DataTable data) + { + var headerValid = HeaderIsValid(data.Columns); + if (!headerValid) { + LoggingObject.Logger<FuelConsumptionMap>().Warn( + "FuelConsumptionMap: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: {3}", + Fields.EngineSpeed, Fields.Torque, Fields.FuelConsumption, + ", ".Join(data.Columns.Cast<DataColumn>().Select(c => c.ColumnName))); + } + var delaunayMap = new DelaunayMap("FuelConsumptionMap"); + + foreach (DataRow row in data.Rows) { + try { + var entry = headerValid ? CreateFromColumNames(row) : CreateFromColumnIndizes(row); + + // Delaunay map works only as expected, when the angularVelocity is in rpm. + delaunayMap.AddPoint(entry.Torque.Value(), + headerValid ? DataTableExtensionMethods.ParseDouble(row, (string)Fields.EngineSpeed) : row.ParseDouble(0), + entry.FuelConsumption.Value()); + } catch (Exception e) { + throw new VectoException(string.Format("Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e); + } + } + + delaunayMap.Triangulate(); + return new FuelConsumptionMap(delaunayMap); + } + + private static bool HeaderIsValid(DataColumnCollection columns) + { + return columns.Contains(Fields.EngineSpeed) && columns.Contains(Fields.Torque) && + columns.Contains(Fields.FuelConsumption); + } + + private static FuelConsumptionMap.FuelConsumptionEntry CreateFromColumnIndizes(DataRow row) + { + return new FuelConsumptionMap.FuelConsumptionEntry( + engineSpeed: row.ParseDouble(0).RPMtoRad(), + torque: row.ParseDouble(1).SI<NewtonMeter>(), + fuelConsumption: + row.ParseDouble(2).SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>() + ); + } + + private static FuelConsumptionMap.FuelConsumptionEntry CreateFromColumNames(DataRow row) + { + return new FuelConsumptionMap.FuelConsumptionEntry( + engineSpeed: row.ParseDouble((string)Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(), + torque: row.ParseDouble((string)Fields.Torque).SI<NewtonMeter>(), + fuelConsumption: + row.ParseDouble((string)Fields.FuelConsumption) + .SI() + .Gramm.Per.Hour.ConvertTo() + .Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>() + ); + } + + public static class Fields + { + /// <summary> + /// [rpm] + /// </summary> + public const string EngineSpeed = "engine speed"; + + /// <summary> + /// [Nm] + /// </summary> + public const string Torque = "torque"; + + /// <summary> + /// [g/h] + /// </summary> + public const string FuelConsumption = "fuel consumption"; + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs b/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs index c9f2acef12..5b06ce329f 100644 --- a/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs +++ b/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs @@ -123,7 +123,7 @@ namespace TUGraz.VectoCore.Tests.Integration.BusAuxiliaries var engineFCMapFilePath = @"TestData\Integration\BusAuxiliaries\24t Coach.vmap"; var vehicle = new VehicleContainer(ExecutionMode.Engineering); - var fcMap = FuelConsumptionMap.ReadFromFile(engineFCMapFilePath); + var fcMap = FuelConsumptionMapReader.ReadFromFile(engineFCMapFilePath); var fld = EngineFullLoadCurve.ReadFromFile(engineFLDFilePath); var modelData = new CombustionEngineData() { ConsumptionMap = fcMap, diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs index 440bbc14f6..517e1508d5 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs @@ -47,7 +47,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestMethod] public void TestFuelConsumption_FixedPoints() { - var map = FuelConsumptionMap.ReadFromFile(@"TestData\Components\24t Coach.vmap"); + var map = FuelConsumptionMapReader.ReadFromFile(@"TestData\Components\24t Coach.vmap"); var lines = File.ReadAllLines(@"TestData\Components\24t Coach.vmap").Skip(1).ToArray(); AssertMapValuesEqual(lines, map); } @@ -55,7 +55,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData [TestMethod] public void TestFuelConsumption_InterpolatedPoints() { - var map = FuelConsumptionMap.ReadFromFile(@"TestData\Components\24t Coach.vmap"); + var map = FuelConsumptionMapReader.ReadFromFile(@"TestData\Components\24t Coach.vmap"); var lines = File.ReadAllLines(@"TestData\Components\24t CoachInterpolated.vmap").Skip(1).ToArray(); AssertMapValuesEqual(lines, map); } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs index 1c63a09ef9..25debf9c59 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/TorqueConverterDataTest.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using NUnit.Framework; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Tests.Utils; @@ -75,7 +76,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData ] public void TestTorqueConverterInvalidOperatingPoint(double nOut, double Pout) { - var tqLimit = 1600; + var tqLimit = 1600.RPMtoRad(); var tqInput = new[] { "0,3.935741,563.6598 ", @@ -100,7 +101,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var outTorque = (Pout * 1000).SI<Watt>() / outAngularSpeed; tqData.GetInputTorqueAndAngularSpeed(outTorque, outAngularSpeed, out inTorque, out inAngularSpeed); - Assert.IsTrue(inAngularSpeed.Value() > 1600.RPMtoRad().Value()); + Assert.IsTrue(inAngularSpeed.Value() > tqLimit.Value()); } } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs index 4bc51dcc34..889858f55b 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs @@ -86,7 +86,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData WHTCRural = 1, WHTCMotorway = 1, FullLoadCurve = EngineFullLoadCurve.Create(fullLoad), - ConsumptionMap = FuelConsumptionMap.Create(fuelConsumption) + ConsumptionMap = FuelConsumptionMapReader.Create(fuelConsumption) }; data.FullLoadCurve.EngineData = data; -- GitLab