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