From a0708c5869ab2c69629311b49a986ee95d16ca3b Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Tue, 6 Aug 2019 09:39:48 +0200 Subject: [PATCH] adding whr data to engine data, fixing reading whr data from xml --- .../XMLDeclarationEngineDataProvider.cs | 31 +++++++-- .../ComponentData/FuelConsumptionMapReader.cs | 64 ------------------- .../DeclarationDataAdapter.cs | 25 ++++++++ .../Data/CombustionEngineData.cs | 17 +++++ .../Data/Engine/WHRPowerMap.cs | 4 +- VectoCore/VectoCore/VectoCore.csproj | 10 +-- 6 files changed, 76 insertions(+), 75 deletions(-) diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs index 78f24a51b5..150e47abe2 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs @@ -271,15 +271,23 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider protected virtual IWHRData ReadWHRData() { var correctionFactorNodes = GetNodes(new[] { XMLNames.Engine_FuelModes_Fuel, XMLNames.Engine_WHRCorrectionFactors }); + var whrPwrNodes = GetNodes(new[] { XMLNames.Engine_FuelModes_Fuel, XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry + }) + .Cast<XmlNode>().All(x => x.Attributes?[XMLNames.Engine_FuelConsumptionMap_WHRElPower_Attr] == null); if (correctionFactorNodes.Count == 0) { + if (whrPwrNodes) { + Warn("WHR correction factors provided but no electric power defined - ignoring WHR."); + } return new XMLWHRData(); } if (correctionFactorNodes.Count > 1) { - throw new VectoException("WHRData can only be defined for one fuel!"); + throw new VectoException("WHRData (correction factors) can only be defined for one fuel!"); } - if (GetNodes(new[] { XMLNames.Engine_FuelModes_Fuel, XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry }) - .Cast<XmlNode>().All(x => x.Attributes?[XMLNames.Engine_FuelConsumptionMap_WHRElPower_Attr] == null)) { + if (whrPwrNodes) { + if (correctionFactorNodes.Count == 1) { + Warn("WHR electric power provided but no correction factors found - ignoring WHR."); + } return new XMLWHRData(); } @@ -290,7 +298,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider var fuel = fuelNodes[i]; if (GetNodes("Entry", fuel).Cast<XmlNode>().Any(x => x.Attributes?[XMLNames.Engine_FuelConsumptionMap_WHRElPower_Attr] != null)) { if (whrFuelNode != null) { - throw new VectoException("WHRData can only be defined for one fuel!"); + throw new VectoException("WHRData (electric power) can only be defined for one fuel!"); } whrFuelNode = fuel; @@ -300,6 +308,19 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider whrFuelNode = fuelNodes[0]; } + if (GetNodes(new [] { XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry}, whrFuelNode) + .Cast<XmlNode>().Any(x => x.Attributes?[XMLNames.Engine_FuelConsumptionMap_WHRElPower_Attr] == null)) { + var missing = GetNodes(new[] { XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry }, whrFuelNode) + .Cast<XmlNode>().Where(x => x.Attributes?[XMLNames.Engine_FuelConsumptionMap_WHRElPower_Attr] == null); + throw new VectoException( + "WHRData has to be provided for every entry in the FC-Map! {0}", + string.Join("; ", + missing.Select( + x => string.Format( + "n: {0}, T: {1}", x.Attributes?[XMLNames.Engine_FuelConsumptionMap_EngineSpeed_Attr]?.Value, + x.Attributes?[XMLNames.Engine_FuelConsumptionMap_Torque_Attr]?.Value)))); + } + if (correctionFactorNodes[0].ParentNode != whrFuelNode) { throw new VectoException("Correction Factors and WHR-Map have to be defined for the same fuel!"); } @@ -345,7 +366,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider public TableData GeneratedElectricPower { - get { return WHRPower ?? (WHRPower = ReadTableData(XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry, AttributeMappings.WHRPowerMapMapping)); } + get { return WHRPower ?? (WHRPower = BaseNode == null ? null : ReadTableData(XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry, AttributeMappings.WHRPowerMapMapping)); } } #endregion diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/FuelConsumptionMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/FuelConsumptionMapReader.cs index 8d1e4e3de7..4e88d36432 100644 --- a/VectoCore/VectoCore/InputData/Reader/ComponentData/FuelConsumptionMapReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/FuelConsumptionMapReader.cs @@ -40,70 +40,6 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.InputData.Reader.ComponentData { - public static class WHRPowerReader - { - public static WHRPowerMap 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 WHRPowerMap 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.ElectricPower, - string.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); - delaunayMap.AddPoint(entry.Torque.Value(), - (headerValid ? row.ParseDouble(Fields.EngineSpeed) : row.ParseDouble(0)).RPMtoRad().Value(), - entry.FuelConsumption.Value()); - } catch (Exception e) { - throw new VectoException(string.Format("FuelConsumptionMap - Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e); - } - } - - delaunayMap.Triangulate(); - return new WHRPowerMap(delaunayMap); - } - - private static bool HeaderIsValid(DataColumnCollection columns) - { - return columns.Contains(Fields.EngineSpeed) && columns.Contains(Fields.Torque) && - columns.Contains(Fields.ElectricPower); - } - - 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 ElectricPower = "whr power"; - } - } - public static class FuelConsumptionMapReader { public static FuelConsumptionMap ReadFromFile(string fileName) diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index f11f2dc9f3..f9080d329b 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -232,9 +232,34 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } retVal.FullLoadCurves = fullLoadCurves; + + var whr = CreateWHRData(mode.WasteHeatRecoveryData); + if (whr != null) { + whr.WHRCorrectionFactor = DeclarationData.WHTCCorrection.Lookup( + mission.MissionType.GetNonEMSMissionType(), whr.CFRural, whr.CFUrban, + whr.CFMotorway) * whr.CFColdHot * whr.CFRegPer; + } + retVal.WHRData = whr; + return retVal; } + private static WHRData CreateWHRData(IWHRData whrInputData) + { + if (whrInputData == null || whrInputData.GeneratedElectricPower == null) { + return null; + } + + return new WHRData() { + CFUrban = whrInputData.UrbanCorrectionFactor, + CFRural = whrInputData.RuralCorrectionFactor, + CFMotorway = whrInputData.MotorwayCorrectionFactor, + CFColdHot = whrInputData.BFColdHot, + CFRegPer = whrInputData.CFRegPer, + WHRMap = WHRPowerReader.Create(whrInputData.GeneratedElectricPower) + }; + } + private static NewtonMeter VehMaxTorque( ITransmissionInputData gear, int numGears, Dictionary<int, ITorqueLimitInputData> limits, diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs index 9e461a32cc..511a9140aa 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs @@ -34,6 +34,7 @@ using System.ComponentModel.DataAnnotations; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.ComponentData; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; @@ -44,6 +45,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data { [Required, SIRange(1, 5)] public Second EngineStartTime; + [Required, SIRange(1000 * 1E-6, 20000 * 1E-6)] public CubicMeter Displacement { get; internal set; } @@ -69,6 +71,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [Required, ValidateObject] public List<CombustionEngineFuelData> Fuels { get; internal set; } + public WHRData WHRData; + // ReSharper disable once UnusedMember.Global -- used in CustomValidation public static ValidationResult ValidateData(CombustionEngineData data, ValidationContext context) @@ -80,6 +84,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data } } + public class WHRData + { + public double CFUrban { get; internal set; } + public double CFRural { get; internal set; } + public double CFMotorway { get;internal set; } + + public double CFColdHot { get; internal set; } + public double CFRegPer { get; internal set; } + public double WHRCorrectionFactor { get; internal set; } + + public WHRPowerMap WHRMap { get; internal set; } + } + public class CombustionEngineFuelData { public CombustionEngineFuelData() diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/WHRPowerMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/WHRPowerMap.cs index 9d998b5d8a..5838b89c18 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/WHRPowerMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/WHRPowerMap.cs @@ -36,13 +36,13 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData // delaunay map needs is initialised with rpm, therefore the angularVelocity has to be converted. var value = WHRMap.Interpolate(torque, engineSpeed); if (value.HasValue) { - result.ElectricPower = value.Value.SI(Unit.SI.Kilo.Gramm.Per.Second).Cast<Watt>(); + result.ElectricPower = value.Value.SI<Watt>(); return result; } if (allowExtrapolation) { result.ElectricPower = - WHRMap.Extrapolate(torque, engineSpeed).SI(Unit.SI.Kilo.Gramm.Per.Second).Cast<Watt>(); + WHRMap.Extrapolate(torque, engineSpeed).SI<Watt>(); result.Extrapolated = true; return result; } diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 3e785a8d17..e2ff058383 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -254,6 +254,8 @@ <Compile Include="InputData\FileIO\XML\Declaration\IXMLDeclarationInputDataReader.cs" /> <Compile Include="InputData\FileIO\XML\IXMLInputDataReader.cs" /> <Compile Include="InputData\FileIO\XML\XMLInputDataNinjectModule.cs" /> + <Compile Include="Models\SimulationComponent\Data\Engine\WHRPowerMap.cs" /> + <Compile Include="InputData\Reader\ComponentData\WHRPowerReader.cs" /> <Compile Include="Models\SimulationComponent\Impl\StopStartCombustionEngine.cs" /> <Compile Include="Models\Simulation\DataBus\IEngineControl.cs" /> <Compile Include="Models\Simulation\ISimulatorFactory.cs" /> @@ -315,14 +317,14 @@ <Compile Include="InputData\Reader\DataObjectAdapter\AbstractSimulationDataAdapter.cs" /> <Compile Include="InputData\Reader\DataObjectAdapter\DeclarationDataAdapter.cs" /> <Compile Include="InputData\Reader\DataObjectAdapter\EngineeringDataAdapter.cs" /> - <Compile Include="InputData\Reader\DrivingCycleDataReader.cs" /> - <Compile Include="InputData\Reader\FullLoadCurveReader.cs" /> + <Compile Include="InputData\Reader\ComponentData\DrivingCycleDataReader.cs" /> + <Compile Include="InputData\Reader\ComponentData\FullLoadCurveReader.cs" /> <Compile Include="InputData\Reader\Impl\DeclarationModeVectoRunDataFactory.cs" /> <Compile Include="InputData\Reader\Impl\DeclarationVTPModeVectoRunDataFactory.cs" /> <Compile Include="InputData\Reader\Impl\DrivingCycleProxy.cs" /> <Compile Include="InputData\Reader\Impl\EngineeringModeVectoRunDataFactory.cs" /> <Compile Include="InputData\Reader\Impl\EngineOnlyVectoRunDataFactory.cs" /> - <Compile Include="InputData\Reader\ShiftPolygonReader.cs" /> + <Compile Include="InputData\Reader\ComponentData\ShiftPolygonReader.cs" /> <Compile Include="Models\Declaration\AuxDemandEntry.cs" /> <Compile Include="Models\Declaration\AuxiliaryTypeHelper.cs" /> <Compile Include="Models\Connector\Ports\IDriverDemandPort.cs" /> @@ -337,7 +339,7 @@ <Compile Include="Models\Declaration\WeightingFactors.cs" /> <Compile Include="Models\Declaration\WeightingGroups.cs" /> <Compile Include="Models\SimulationComponent\Data\AngledriveData.cs" /> - <Compile Include="Models\SimulationComponent\Data\Engine\FuelConsumptionMapReader.cs" /> + <Compile Include="InputData\Reader\ComponentData\FuelConsumptionMapReader.cs" /> <Compile Include="Models\SimulationComponent\Data\PTOData.cs" /> <Compile Include="Models\SimulationComponent\ILossMap.cs" /> <Compile Include="Models\SimulationComponent\Data\PTOLossMap.cs" /> -- GitLab