diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs index a1d0615730832207433ce005eba0cb148e7ee819..2915ab4095e162c509848a3d88a66c6b025bedf6 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs @@ -177,7 +177,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdaper Technology = a.Technology, TechList = a.TechList.DefaultIfNull(Enumerable.Empty<string>()).ToArray(), DemandType = AuxiliaryDemandType.Mapping, - Data = new AuxiliaryData(a) //AuxiliaryData.Create(a.DemandMap) + Data = new AuxiliaryData(a, a.ID) //AuxiliaryData.Create(a.DemandMap) }).Concat(new VectoRunData.AuxData { ID = "", DemandType = AuxiliaryDemandType.Direct }.ToEnumerable()).ToList(); } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs index 417e39428fd1566068b191e007f399c5cfdf0dbb..5b552934298c414872a90ed2fdab9c1448cb479e 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/AuxiliaryData.cs @@ -43,8 +43,6 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data { - - [CustomValidation(typeof(AuxiliaryData), "ValidateAuxMap")] public class AuxiliaryData { @@ -57,16 +55,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [Required, Range(double.Epsilon, 1)] public double EfficiencyToEngine { get; set; } - [Required] private readonly DelauneyMap _map = new DelauneyMap(); + [Required] private readonly DelauneyMap _map; public Watt GetPowerDemand(PerSecond nAuxiliary, Watt powerAuxOut) { return _map.Interpolate(nAuxiliary.Value(), powerAuxOut.Value()).SI<Watt>(); } - public static AuxiliaryData ReadFromFile(string fileName) + public static AuxiliaryData ReadFromFile(string fileName, string id) { - var auxData = new AuxiliaryData(); + var auxData = new AuxiliaryData(id); try { var stream = new StreamReader(fileName); @@ -118,8 +116,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data } } - internal AuxiliaryData(IAuxiliaryEngineeringInputData data) + internal AuxiliaryData(string id) + { + _map = new DelauneyMap(id); + } + + internal AuxiliaryData(IAuxiliaryEngineeringInputData data, string id) { + _map = new DelauneyMap("AuxiliaryData " + id); TransmissionRatio = data.TransmissionRatio; EfficiencyToEngine = data.EfficiencyToEngine; EfficiencyToSupply = data.EfficiencyToSupply; @@ -132,7 +136,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data _map.Triangulate(); } - private AuxiliaryData() {} private static bool HeaderIsValid(DataColumnCollection columns) { diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs index 2a3b78a1b8251cfbaea0f09a9a1e0f56534f000e..7a615e66f21c7673243222d2e9d8494517525fe8 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs @@ -42,7 +42,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine { public class FuelConsumptionMap : SimulationComponentData { - [Required, ValidateObject] private readonly DelauneyMap _fuelMap = new DelauneyMap(); + [Required, ValidateObject] private readonly DelauneyMap _fuelMap = new DelauneyMap("FuelConsumptionMap"); private FuelConsumptionMap() {} diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs index 5b7b3e471b0c883961a6345183549fa5787de5ed..e8cd1700befa538a13c63a7d65c0464bd3f31b76 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/TransmissionLossMap.cs @@ -144,11 +144,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox GearName = gearName; _ratio = gearRatio; _entries = entries; - _lossMap = new DelauneyMap(); - _invertedLossMap = new DelauneyMap(); + _lossMap = new DelauneyMap("TransmissionLossMap " + GearName); + _invertedLossMap = new DelauneyMap("TransmissionLossMapInv. " + GearName); foreach (var entry in _entries) { - _lossMap.AddPoint(entry.InputSpeed.ConvertTo().Rounds.Per.Minute.Value(), (entry.InputTorque - entry.TorqueLoss).Value(), entry.TorqueLoss.Value()); - _invertedLossMap.AddPoint(entry.InputSpeed.ConvertTo().Rounds.Per.Minute.Value(), entry.InputTorque.Value(), entry.TorqueLoss.Value()); + _lossMap.AddPoint(entry.InputSpeed.ConvertTo().Rounds.Per.Minute.Value(), + (entry.InputTorque - entry.TorqueLoss).Value(), entry.TorqueLoss.Value()); + _invertedLossMap.AddPoint(entry.InputSpeed.ConvertTo().Rounds.Per.Minute.Value(), entry.InputTorque.Value(), + entry.TorqueLoss.Value()); } _lossMap.Triangulate(); @@ -164,7 +166,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox /// <returns>Torque loss as seen on input side (towards the engine).</returns> public NewtonMeter GetTorqueLoss(PerSecond outAngularVelocity, NewtonMeter outTorque) { - var torqueLoss = _lossMap.Interpolate(outAngularVelocity.ConvertTo().Rounds.Per.Minute.Value() * _ratio, outTorque.Value() / _ratio, true).SI<NewtonMeter>(); + var torqueLoss = + _lossMap.Interpolate(outAngularVelocity.ConvertTo().Rounds.Per.Minute.Value() * _ratio, outTorque.Value() / _ratio, + true).SI<NewtonMeter>(); Log.Debug("GearboxLoss {0}: {1}, outAngularVelocity: {2}, outTorque: {3}", GearName, torqueLoss, outAngularVelocity, outTorque); @@ -181,7 +185,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox public NewtonMeter GetOutTorque(PerSecond inAngularVelocity, NewtonMeter inTorque, bool allowExtrapolation = false) { var torqueLoss = - _invertedLossMap.Interpolate(inAngularVelocity.ConvertTo().Rounds.Per.Minute.Value(), inTorque.Value(), allowExtrapolation).SI<NewtonMeter>(); + _invertedLossMap.Interpolate(inAngularVelocity.ConvertTo().Rounds.Per.Minute.Value(), inTorque.Value(), + allowExtrapolation).SI<NewtonMeter>(); return (inTorque - torqueLoss) / _ratio; } diff --git a/VectoCore/VectoCore/Utils/DelauneyMap.cs b/VectoCore/VectoCore/Utils/DelauneyMap.cs index 98a3b84612b7b06f078ccce9e5cf536354767ae6..da342b71914ce704f119698ccfd007c39d48f586 100644 --- a/VectoCore/VectoCore/Utils/DelauneyMap.cs +++ b/VectoCore/VectoCore/Utils/DelauneyMap.cs @@ -53,6 +53,13 @@ namespace TUGraz.VectoCore.Utils private readonly ThreadLocal<bool> _extrapolated = new ThreadLocal<bool>(); + private readonly string _mapName; + + public DelauneyMap(string name) + { + _mapName = name; + } + public bool Extrapolated { get { return _extrapolated.Value; } @@ -74,7 +81,8 @@ namespace TUGraz.VectoCore.Utils public void Triangulate() { if (Points.Count < 3) { - throw new ArgumentException(string.Format("Triangulation needs at least 3 Points. Got {0} Points.", Points.Count)); + throw new ArgumentException(string.Format("{0}: Triangulation needs at least 3 Points. Got {1} Points.", _mapName, + Points.Count)); } SanitycheckInputPoints(); @@ -85,7 +93,7 @@ namespace TUGraz.VectoCore.Utils var max = Points.Max(point => Math.Max(Math.Abs(point.X), Math.Abs(point.Y))) * superTriangleScalingFactor; var superTriangle = new Triangle(new Point(max, 0), new Point(0, max), new Point(-max, -max)); var triangles = new List<Triangle> { superTriangle }; - + var pointCount = 0; var points = Points.ToArray(); @@ -102,7 +110,7 @@ namespace TUGraz.VectoCore.Utils var point1 = point; var containerTriangles = triangles.FindAll(t => t.ContainsInCircumcircle(point1)); triangles = triangles.Except(containerTriangles).ToList(); - + // Remove duplicate edges. This leaves the convex hull of the edges. // The edges in this convex hull are oriented counterclockwise! var allEdges = containerTriangles.SelectMany(t => t.GetEdges()).ToList(); @@ -179,10 +187,11 @@ namespace TUGraz.VectoCore.Utils var frame = new StackFrame(2); var method = frame.GetMethod(); - var type = method.DeclaringType.Name; - var methodName = method.Name; + var type = string.Join("", method.DeclaringType.Name.Split(Path.GetInvalidFileNameChars())); + var methodName = string.Join("", method.Name.Split(Path.GetInvalidFileNameChars())); Directory.CreateDirectory("delauney"); - chart.SaveImage(string.Format("delauney\\{0}_{1}_{2}_{3}.png", type, methodName, superTriangle.GetHashCode(), i), ChartImageFormat.Png); + chart.SaveImage(string.Format("delauney\\{0}_{1}_{2}_{3}.png", type, methodName, superTriangle.GetHashCode(), i), + ChartImageFormat.Png); } } @@ -198,7 +207,7 @@ namespace TUGraz.VectoCore.Utils } if (!allowExtrapolation) { - throw new VectoException("Interpolation failed. x: {0}, y: {1}", x, y); + throw new VectoException("{2}: Interpolation failed. x: {0}, y: {1}", x, y, _mapName); } Extrapolated = true; diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs index 754e865c9aecb68ea7bf60e96e09a52eb407e279..6aa4ff93fbc29f347cd9e06557d57db0ef84ee62 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -187,7 +187,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var aux = new EngineAuxiliary(container); - var auxData = AuxiliaryData.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux"); + var auxData = AuxiliaryData.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux", "ALT"); // ratio = 4.078 // efficiency_engine = 0.96 // efficiency_supply = 0.98 @@ -246,7 +246,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation var aux = new EngineAuxiliary(container); - var auxData = AuxiliaryData.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux"); + var auxData = AuxiliaryData.ReadFromFile(@"TestData\Components\24t_Coach_ALT.vaux", "ALT"); // ratio = 4.078 // efficiency_engine = 0.96 // efficiency_supply = 0.98 @@ -297,7 +297,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation [TestMethod] public void AuxFileMissing() { - AssertHelper.Exception<VectoException>(() => AuxiliaryData.ReadFromFile(@"NOT_EXISTING_AUX_FILE.vaux"), + AssertHelper.Exception<VectoException>(() => AuxiliaryData.ReadFromFile(@"NOT_EXISTING_AUX_FILE.vaux", "N.A."), "Auxiliary file not found: NOT_EXISTING_AUX_FILE.vaux"); } diff --git a/VectoCore/VectoCoreTest/Utils/DelauneyMapTest.cs b/VectoCore/VectoCoreTest/Utils/DelauneyMapTest.cs index 413ca1740111d4f8cab927aa471911e6ad0ef5a2..f2db3a65d2bb88d1df299451eb13e0de1cb17331 100644 --- a/VectoCore/VectoCoreTest/Utils/DelauneyMapTest.cs +++ b/VectoCore/VectoCoreTest/Utils/DelauneyMapTest.cs @@ -42,7 +42,7 @@ namespace TUGraz.VectoCore.Tests.Utils [TestMethod] public void Test_Simple_DelauneyMap() { - var map = new DelauneyMap(); + var map = new DelauneyMap("TEST"); map.AddPoint(0, 0, 0); map.AddPoint(1, 0, 0); map.AddPoint(0, 1, 0); @@ -57,7 +57,7 @@ namespace TUGraz.VectoCore.Tests.Utils [TestMethod] public void Test_DelauneyMapTriangle() { - var map = new DelauneyMap(); + var map = new DelauneyMap("TEST"); map.AddPoint(0, 0, 0); map.AddPoint(1, 0, 1); map.AddPoint(0, 1, 2); @@ -82,15 +82,15 @@ namespace TUGraz.VectoCore.Tests.Utils AssertHelper.AreRelativeEqual(1.5, map.Interpolate(0, 0.75)); // extrapolation (should fail) - AssertHelper.Exception<VectoException>(() => map.Interpolate(1, 1), "Interpolation failed. x: 1, y: 1"); - AssertHelper.Exception<VectoException>(() => map.Interpolate(-1, -1), "Interpolation failed. x: -1, y: -1"); - AssertHelper.Exception<VectoException>(() => map.Interpolate(1, -1), "Interpolation failed. x: 1, y: -1"); - AssertHelper.Exception<VectoException>(() => map.Interpolate(-1, 1), "Interpolation failed. x: -1, y: 1"); + AssertHelper.Exception<VectoException>(() => map.Interpolate(1, 1), "TEST: Interpolation failed. x: 1, y: 1"); + AssertHelper.Exception<VectoException>(() => map.Interpolate(-1, -1), "TEST: Interpolation failed. x: -1, y: -1"); + AssertHelper.Exception<VectoException>(() => map.Interpolate(1, -1), "TEST: Interpolation failed. x: 1, y: -1"); + AssertHelper.Exception<VectoException>(() => map.Interpolate(-1, 1), "TEST: Interpolation failed. x: -1, y: 1"); } public void Test_DelauneyMapPlane() { - var map = new DelauneyMap(); + var map = new DelauneyMap("TEST"); map.AddPoint(0, 0, 0); map.AddPoint(1, 0, 1); map.AddPoint(0, 1, 2); @@ -132,27 +132,42 @@ namespace TUGraz.VectoCore.Tests.Utils [TestMethod] public void Test_Delauney_LessThan3Points() { - AssertHelper.Exception<ArgumentException>(() => new DelauneyMap().Triangulate(), - "Triangulation needs at least 3 Points. Got 0 Points."); + AssertHelper.Exception<ArgumentException>(() => new DelauneyMap("TEST").Triangulate(), + "TEST: Triangulation needs at least 3 Points. Got 0 Points."); AssertHelper.Exception<ArgumentException>(() => { - var map1 = new DelauneyMap(); + var map1 = new DelauneyMap("TEST"); map1.AddPoint(1, 0, 0); map1.Triangulate(); - }, "Triangulation needs at least 3 Points. Got 1 Points."); + }, "TEST: Triangulation needs at least 3 Points. Got 1 Points."); AssertHelper.Exception<ArgumentException>(() => { - var map2 = new DelauneyMap(); + var map2 = new DelauneyMap("TEST"); map2.AddPoint(1, 0, 0); map2.AddPoint(0, 1, 0); map2.Triangulate(); - }, "Triangulation needs at least 3 Points. Got 2 Points."); + }, "TEST: Triangulation needs at least 3 Points. Got 2 Points."); - var map = new DelauneyMap(); + var map = new DelauneyMap("TEST"); map.AddPoint(1, 0, 0); map.AddPoint(0, 1, 0); map.AddPoint(0, 0, 1); map.Triangulate(); } + + [TestMethod] + public void Test_Delauney_DuplicatePoints() + { + var map = new DelauneyMap("TEST"); + map.AddPoint(0, 0, 0); + map.AddPoint(1, 0, 1); + map.AddPoint(1, 1, 3); + map.AddPoint(0, 1, 2); + map.AddPoint(1, 1, 5); + + + AssertHelper.Exception<VectoException>(() => { map.Triangulate(); }, + "TEST: Input Data for Delauney map contains duplicates!\n1 / 1"); + } } } \ No newline at end of file