diff --git a/VECTO.sln.DotSettings b/VECTO.sln.DotSettings index 147e42b1e5859ecd5ecf48f31543c2ebf6b31b8f..1f889a17ccd10ca88071a8b3f024ffc25316a7a0 100644 --- a/VECTO.sln.DotSettings +++ b/VECTO.sln.DotSettings @@ -114,4 +114,7 @@ <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean> - <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EFormat_002ESettingsUpgrade_002EAlignmentTabFillStyleMigration/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EFormat_002ESettingsUpgrade_002EAlignmentTabFillStyleMigration/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EJavaScript_002ECodeStyle_002ESettingsUpgrade_002EJsParsFormattingSettingsUpgrader/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EJavaScript_002ECodeStyle_002ESettingsUpgrade_002EJsWrapperSettingsUpgrader/@EntryIndexedValue">True</s:Boolean> + <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> diff --git a/VECTO/GUI/EngineForm.vb b/VECTO/GUI/EngineForm.vb index 4c43013ccd157c9ee8ac2872359533e5e456ca22..0067aec7f6c062c24a8bd8101521ff3144f7a0ad 100644 --- a/VECTO/GUI/EngineForm.vb +++ b/VECTO/GUI/EngineForm.vb @@ -197,21 +197,21 @@ Public Class EngineForm TbName.Text = engine.Model TbDispl.Text = (engine.Displacement*1000*1000).ToGUIFormat() TbInertia.Text = engine.Inertia.ToGUIFormat() - TbNleerl.Text = engine.IdleSpeed.AsRPM.ToGUIFormat() + TbNleerl.Text = engine.EngineModes.First().IdleSpeed.AsRPM.ToGUIFormat() - TbMAP.Text = GetRelativePath(engine.FuelConsumptionMap.Source, basePath) - TbFLD.Text = GetRelativePath(engine.FullLoadCurve.Source, basePath) - TbWHTCurban.Text = engine.WHTCUrban.ToGUIFormat() - TbWHTCrural.Text = engine.WHTCRural.ToGUIFormat() - TbWHTCmw.Text = engine.WHTCMotorway.ToGUIFormat() + TbMAP.Text = GetRelativePath(engine.EngineModes.First().Fuels.First().FuelConsumptionMap.Source, basePath) + TbFLD.Text = GetRelativePath(engine.EngineModes.First().FullLoadCurve.Source, basePath) + TbWHTCurban.Text = engine.EngineModes.First().Fuels.First().WHTCUrban.ToGUIFormat() + TbWHTCrural.Text = engine.EngineModes.First().Fuels.First().WHTCRural.ToGUIFormat() + TbWHTCmw.Text = engine.EngineModes.First().Fuels.First().WHTCMotorway.ToGUIFormat() TbWHTCEngineering.Text = engine.WHTCEngineering.ToGUIFormat() - TbColdHotFactor.Text = engine.ColdHotBalancingFactor.ToGUIFormat() - tbRegPerCorrFactor.Text = engine.CorrectionFactorRegPer.ToGUIFormat() + TbColdHotFactor.Text = engine.EngineModes.First().Fuels.First().ColdHotBalancingFactor.ToGUIFormat() + tbRegPerCorrFactor.Text = engine.EngineModes.First().Fuels.First().CorrectionFactorRegPer.ToGUIFormat() tbMaxTorque.Text = engine.MaxTorqueDeclared.ToGUIFormat() tbRatedPower.Text = (engine.RatedPowerDeclared.Value()/1000).ToGUIFormat() tbRatedSpeed.Text = engine.RatedSpeedDeclared.AsRPM.ToGUIFormat() - cbFuelType.SelectedValue = engine.FuelType + cbFuelType.SelectedValue = engine.EngineModes.First().Fuels.First().FuelType DeclInit() diff --git a/VECTO/GUI/GearboxForm.vb b/VECTO/GUI/GearboxForm.vb index dc586e93ced8aaf02a3325ff0c162a9139e4afbf..9d38b57f0c5f82ae251a06a1adb71f6d4e178386 100644 --- a/VECTO/GUI/GearboxForm.vb +++ b/VECTO/GUI/GearboxForm.vb @@ -816,7 +816,7 @@ Public Class GearboxForm Dim vehicle As IVehicleEngineeringInputData = inputData.JobInputData.Vehicle 'inputData = TryCast(JSONInputDataFactory.ReadComponentData(vectoJob.PathEng(False)), IEngineeringInputDataProvider) Dim engine As IEngineEngineeringInputData = inputData.JobInputData.Vehicle.Components.EngineInputData - Dim engineFld As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.FullLoadCurve) + Dim engineFld As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.EngineModes.First().FullLoadCurve) s = New Series @@ -828,12 +828,12 @@ Public Class GearboxForm s.Name = "Full load" chart.Series.Add(s) - If VectoJobForm.Visible AndAlso engine.IdleSpeed > 0 Then + If VectoJobForm.Visible AndAlso engine.EngineModes.First().IdleSpeed > 0 Then 'If FLD0.Init(VectoJobForm.n_idle) Then 'Dim fullLoadCurve As FullLoadCurve = ConvertToFullLoadCurve(FLD0.LnU, FLD0.LTq) Dim gears As IList(Of ITransmissionInputData) = ConvertToGears(LvGears.Items) - Dim shiftLines As ShiftPolygon = GetShiftLines(engine.IdleSpeed, engineFld, vehicle, gears, gear) + Dim shiftLines As ShiftPolygon = GetShiftLines(engine.EngineModes.First().IdleSpeed, engineFld, vehicle, gears, gear) If (Not IsNothing(shiftLines)) Then @@ -1068,11 +1068,11 @@ Public Class GearboxForm Dim vehicle As IVehicleEngineeringInputData = inputData.JobInputData.Vehicle Dim engine As IEngineEngineeringInputData = vehicle.Components.EngineInputData - Dim engineFld As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.FullLoadCurve) + Dim engineFld As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.EngineModes.First().FullLoadCurve) - If VectoJobForm.Visible AndAlso engine.IdleSpeed > 0 Then + If VectoJobForm.Visible AndAlso engine.EngineModes.First().IdleSpeed > 0 Then Dim gears As IList(Of ITransmissionInputData) = ConvertToGears(LvGears.Items) - Dim shiftLines As ShiftPolygon = GetShiftLines(engine.IdleSpeed, engineFld, vehicle, gears, gear) + Dim shiftLines As ShiftPolygon = GetShiftLines(engine.EngineModes.First().IdleSpeed, engineFld, vehicle, gears, gear) If (Not IsNothing(shiftLines)) Then ShiftPolygonExport.WriteShiftPolygon(shiftLines, jobFile & "_Gear " & gear & ".vgbs") End If diff --git a/VECTO/GUI/VectoJobForm.vb b/VECTO/GUI/VectoJobForm.vb index 1cd34fee5b1f9d956867263a295acb7506851dc5..d333594150a36d2871c92bb90daf2468db5c19af 100644 --- a/VECTO/GUI/VectoJobForm.vb +++ b/VECTO/GUI/VectoJobForm.vb @@ -1247,9 +1247,9 @@ lbDlog: If engine Is Nothing Then Return - engine.IdleSpeed.Value() + 'engine.IdleSpeed.Value() - Dim fullLoadCurve As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.FullLoadCurve) + Dim fullLoadCurve As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.EngineModes.First().FullLoadCurve) s = New Series s.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(), @@ -1275,7 +1275,7 @@ lbDlog: TbEngTxt.Text = String.Format("{0} l {1} kw {2}", (engine.Displacement.Value() * 1000).ToString("0.0"), pmax.ToString("#"), engine.Model) - Dim fuelConsumptionMap As FuelConsumptionMap = FuelConsumptionMapReader.Create(engine.FuelConsumptionMap) + Dim fuelConsumptionMap As FuelConsumptionMap = FuelConsumptionMapReader.Create(engine.EngineModes.First().Fuels.First().FuelConsumptionMap) s = New Series s.Points.DataBindXY(fuelConsumptionMap.Entries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(), diff --git a/VECTO/GUI/VectoVTPJobForm.vb b/VECTO/GUI/VectoVTPJobForm.vb index bf86a95cfd2b385355b8de17b8631335b97c5379..f335f24a5c7c817f10ee7b1cfae3ffe4589dbfb1 100644 --- a/VECTO/GUI/VectoVTPJobForm.vb +++ b/VECTO/GUI/VectoVTPJobForm.vb @@ -603,9 +603,9 @@ Public Class VectoVTPJobForm If engine Is Nothing Then Return - engine.IdleSpeed.Value() + 'engine.IdleSpeed.Value() - Dim fullLoadCurve As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.FullLoadCurve) + Dim fullLoadCurve As EngineFullLoadCurve = FullLoadCurveReader.Create(engine.EngineModes.First().FullLoadCurve) s = New Series s.Points.DataBindXY(fullLoadCurve.FullLoadEntries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(), @@ -631,7 +631,7 @@ Public Class VectoVTPJobForm TbEngTxt.Text = String.Format("{0} l {1} kw {2}", (engine.Displacement.Value()*1000).ToString("0.0"), pmax.ToString("#"), engine.Model) - Dim fuelConsumptionMap As FuelConsumptionMap = FuelConsumptionMapReader.Create(engine.FuelConsumptionMap) + Dim fuelConsumptionMap As FuelConsumptionMap = FuelConsumptionMapReader.Create(engine.EngineModes.First().Fuels.First().FuelConsumptionMap) s = New Series s.Points.DataBindXY(fuelConsumptionMap.Entries.Select(Function(x) x.EngineSpeed.AsRPM).ToArray(), diff --git a/VECTO/Input Files/Engine.vb b/VECTO/Input Files/Engine.vb index c091b259bc2400670b5f34c3a122d3d5907bd1b7..f097cddc5b183a76458364eb798f0e74ff1d951c 100644 --- a/VECTO/Input Files/Engine.vb +++ b/VECTO/Input Files/Engine.vb @@ -19,6 +19,7 @@ Imports TUGraz.VectoCommon.InputData Imports TUGraz.VectoCommon.Models Imports TUGraz.VectoCommon.Utils Imports TUGraz.VectoCore.InputData.Reader.DataObjectAdapter +Imports TUGraz.VectoCore.Models.Declaration Imports TUGraz.VectoCore.Models.SimulationComponent.Data Imports TUGraz.VectoCore.Utils @@ -28,7 +29,7 @@ Imports TUGraz.VectoCore.Utils ''' <remarks></remarks> <CustomValidation(GetType(Engine), "ValidateEngine")> Public Class Engine - Implements IEngineEngineeringInputData, IEngineDeclarationInputData + Implements IEngineEngineeringInputData, IEngineDeclarationInputData, IEngineModeDeclarationInputData, IEngineFuelDelcarationInputData ''' <summary> ''' Current format version @@ -249,7 +250,11 @@ Public Class Engine .MaxTorque = New List(Of String), .GearRatios = New List(Of Double)() } - engineData = doa.CreateEngineData(engine, Nothing, dummyGearboxData, New List(Of ITorqueLimitInputData), TankSystem.Compressed) + dim dummyVehicle as IVehicleDeclarationInputData = New DummyVehicle() With { + .GearboxInputData = dummyGearboxData, + .EngineInputData = engine + } + engineData = doa.CreateEngineData(dummyVehicle, engine.EngineModes.First(), New Mission() With {.MissionType = MissionType.LongHaul}) Else Dim doa As EngineeringDataAdapter = New EngineeringDataAdapter() engineData = doa.CreateEngineData(engine, Nothing, New List(Of ITorqueLimitInputData), Nothing, TankSystem.Compressed) @@ -271,10 +276,10 @@ Public Class Engine Public ReadOnly Property DataSource As DataSource Implements IComponentInputData.DataSource Get - Dim retVal As DataSource = New DataSource() - retVal.SourceType = DataSourceType.JSONFile - retVal.SourceFile = FilePath - Return retVal + Dim retVal As DataSource = New DataSource() + retVal.SourceType = DataSourceType.JSONFile + retVal.SourceFile = FilePath + Return retVal End Get End Property @@ -330,50 +335,50 @@ Public Class Engine End Get End Property - Public ReadOnly Property IEngineDeclarationInputData_IdleSpeed As PerSecond _ - Implements IEngineDeclarationInputData.IdleSpeed + Public ReadOnly Property IEngineModeDeclarationInputData_IdleSpeed As PerSecond _ + Implements IEngineModeDeclarationInputData.IdleSpeed Get Return IdleSpeed.RPMtoRad() End Get End Property - Public ReadOnly Property WHTCMotorway As Double Implements IEngineDeclarationInputData.WHTCMotorway + Public ReadOnly Property WHTCMotorway As Double Implements IEngineFuelDelcarationInputData.WHTCMotorway Get Return WHTCMotorwayInput End Get End Property - Public ReadOnly Property WHTCRural As Double Implements IEngineDeclarationInputData.WHTCRural + Public ReadOnly Property WHTCRural As Double Implements IEngineFuelDelcarationInputData.WHTCRural Get Return WHTCRuralInput End Get End Property - Public ReadOnly Property WHTCUrban As Double Implements IEngineDeclarationInputData.WHTCUrban + Public ReadOnly Property WHTCUrban As Double Implements IEngineFuelDelcarationInputData.WHTCUrban Get Return WHTCUrbanInput End Get End Property - Public ReadOnly Property ColdHotBalancingFactor As Double Implements IEngineDeclarationInputData.ColdHotBalancingFactor + Public ReadOnly Property ColdHotBalancingFactor As Double Implements IEngineFuelDelcarationInputData.ColdHotBalancingFactor Get Return ColdHotBalancingFactorInput End Get End Property - Public ReadOnly Property CorrectionFactorRegPer As Double Implements IEngineDeclarationInputData.CorrectionFactorRegPer + Public ReadOnly Property CorrectionFactorRegPer As Double Implements IEngineFuelDelcarationInputData.CorrectionFactorRegPer Get Return correctionFactorRegPerInput End Get End Property - Public ReadOnly Property FuelType As FuelType Implements IEngineDeclarationInputData.FuelType + Public ReadOnly Property FuelType As FuelType Implements IEngineFuelDelcarationInputData.FuelType Get Return FuelTypeInput End Get End Property - Public ReadOnly Property FuelConsumptionMap As TableData Implements IEngineDeclarationInputData.FuelConsumptionMap + Public ReadOnly Property FuelConsumptionMap As TableData Implements IEngineFuelDelcarationInputData.FuelConsumptionMap Get If Not File.Exists(_fuelConsumptionMapPath.FullPath) Then _ Throw New VectoException("FuelConsumptionMap is missing or invalid") @@ -381,7 +386,7 @@ Public Class Engine End Get End Property - Public ReadOnly Property FullLoadCurve As TableData Implements IEngineDeclarationInputData.FullLoadCurve + Public ReadOnly Property FullLoadCurve As TableData Implements IEngineModeDeclarationInputData.FullLoadCurve Get If Not File.Exists(_fullLoadCurvePath.FullPath) Then _ Throw New VectoException("Full-Load Curve is missing or invalid") @@ -389,6 +394,12 @@ Public Class Engine End Get End Property + Public ReadOnly Property Fuels As IList(Of IEngineFuelDelcarationInputData) Implements IEngineModeDeclarationInputData.Fuels + Get + Return new List(Of IEngineFuelDelcarationInputData)({me}) + End Get + End Property + Public ReadOnly Property RatedPowerDeclared As Watt Implements IEngineDeclarationInputData.RatedPowerDeclared Get Return ratedPowerInput @@ -407,6 +418,12 @@ Public Class Engine End Get End Property + Public ReadOnly Property EngineModes As IList(Of IEngineModeDeclarationInputData) Implements IEngineDeclarationInputData.EngineModes + get + Return New List(Of IEngineModeDeclarationInputData)({me}) + End Get + End Property + Public ReadOnly Property Inertia As KilogramSquareMeter Implements IEngineEngineeringInputData.Inertia Get Return EngineInertia.SI(Of KilogramSquareMeter)() @@ -422,4 +439,56 @@ Public Class Engine #End Region End Class +Public Class DummyVehicle + Implements IVehicleDeclarationInputData, IVehicleComponentsDeclaration + Public ReadOnly Property DataSource As DataSource Implements IComponentInputData.DataSource + Public ReadOnly Property SavedInDeclarationMode As Boolean Implements IComponentInputData.SavedInDeclarationMode + Public ReadOnly Property Manufacturer As String Implements IComponentInputData.Manufacturer + Public ReadOnly Property Model As String Implements IComponentInputData.Model + Public ReadOnly Property [Date] As String Implements IComponentInputData.[Date] + Public ReadOnly Property CertificationMethod As CertificationMethod Implements IComponentInputData.CertificationMethod + Public ReadOnly Property CertificationNumber As String Implements IComponentInputData.CertificationNumber + Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue + Public ReadOnly Property Identifier As String Implements IVehicleDeclarationInputData.Identifier + Public ReadOnly Property ExemptedVehicle As Boolean Implements IVehicleDeclarationInputData.ExemptedVehicle + Public ReadOnly Property VIN As String Implements IVehicleDeclarationInputData.VIN + Public ReadOnly Property LegislativeClass As LegislativeClass Implements IVehicleDeclarationInputData.LegislativeClass + Public ReadOnly Property VehicleCategory As VehicleCategory Implements IVehicleDeclarationInputData.VehicleCategory + Public ReadOnly Property AxleConfiguration As AxleConfiguration Implements IVehicleDeclarationInputData.AxleConfiguration + Public ReadOnly Property CurbMassChassis As Kilogram Implements IVehicleDeclarationInputData.CurbMassChassis + Public ReadOnly Property GrossVehicleMassRating As Kilogram Implements IVehicleDeclarationInputData.GrossVehicleMassRating + Public ReadOnly Property TorqueLimits As IList(Of ITorqueLimitInputData) Implements IVehicleDeclarationInputData.TorqueLimits + get + Return new List(Of ITorqueLimitInputData)() + End Get + End Property + Public ReadOnly Property ManufacturerAddress As String Implements IVehicleDeclarationInputData.ManufacturerAddress + Public ReadOnly Property EngineIdleSpeed As PerSecond Implements IVehicleDeclarationInputData.EngineIdleSpeed + Public ReadOnly Property VocationalVehicle As Boolean Implements IVehicleDeclarationInputData.VocationalVehicle + Public ReadOnly Property SleeperCab As Boolean Implements IVehicleDeclarationInputData.SleeperCab + Public ReadOnly Property TankSystem As TankSystem? Implements IVehicleDeclarationInputData.TankSystem + Public ReadOnly Property ADAS As IAdvancedDriverAssistantSystemDeclarationInputData Implements IVehicleDeclarationInputData.ADAS + Public ReadOnly Property ZeroEmissionVehicle As Boolean Implements IVehicleDeclarationInputData.ZeroEmissionVehicle + Public ReadOnly Property HybridElectricHDV As Boolean Implements IVehicleDeclarationInputData.HybridElectricHDV + Public ReadOnly Property DualFuelVehicle As Boolean Implements IVehicleDeclarationInputData.DualFuelVehicle + Public ReadOnly Property MaxNetPower1 As Watt Implements IVehicleDeclarationInputData.MaxNetPower1 + Public ReadOnly Property MaxNetPower2 As Watt Implements IVehicleDeclarationInputData.MaxNetPower2 + Public ReadOnly Property Components As IVehicleComponentsDeclaration Implements IVehicleDeclarationInputData.Components + get + Return me + End Get + End Property + + Public ReadOnly Property AirdragInputData As IAirdragDeclarationInputData Implements IVehicleComponentsDeclaration.AirdragInputData + Public Property GearboxInputData As IGearboxDeclarationInputData Implements IVehicleComponentsDeclaration.GearboxInputData + Public ReadOnly Property TorqueConverterInputData As ITorqueConverterDeclarationInputData Implements IVehicleComponentsDeclaration.TorqueConverterInputData + Public ReadOnly Property AxleGearInputData As IAxleGearInputData Implements IVehicleComponentsDeclaration.AxleGearInputData + Public ReadOnly Property AngledriveInputData As IAngledriveInputData Implements IVehicleComponentsDeclaration.AngledriveInputData + Public Property EngineInputData As IEngineDeclarationInputData Implements IVehicleComponentsDeclaration.EngineInputData + Public ReadOnly Property AuxiliaryInputData As IAuxiliariesDeclarationInputData Implements IVehicleComponentsDeclaration.AuxiliaryInputData + Public ReadOnly Property RetarderInputData As IRetarderInputData Implements IVehicleComponentsDeclaration.RetarderInputData + Public ReadOnly Property PTOTransmissionInputData As IPTOTransmissionInputData Implements IVehicleComponentsDeclaration.PTOTransmissionInputData + Public ReadOnly Property AxleWheels As IAxlesDeclarationInputData Implements IVehicleComponentsDeclaration.AxleWheels +End Class + diff --git a/VECTO/Input Files/Gearbox.vb b/VECTO/Input Files/Gearbox.vb index 2863acb3e629eacf92e2b4980bc714af337dfebf..51eb8b48ad1ecbde99a46acf4b709a43bf4c3197 100644 --- a/VECTO/Input Files/Gearbox.vb +++ b/VECTO/Input Files/Gearbox.vb @@ -216,8 +216,7 @@ Public Class Gearbox Dim doa As DeclarationDataAdapter = New DeclarationDataAdapter() Try - - engine = doa.CreateEngineData(inputData.JobInputData.Vehicle.Components.EngineInputData, Nothing, gearbox, New List(Of ITorqueLimitInputData), TankSystem.Compressed) + engine = doa.CreateEngineData(inputData.JobInputData.Vehicle, inputData.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First(), New Mission() With {.MissionType = MissionType.LongHaul}) Catch engine = GetDefaultEngine(gearbox.Gears) End Try diff --git a/VECTO/Input Files/Vehicle.vb b/VECTO/Input Files/Vehicle.vb index 90a9f182aaec69ef17dfad73bc48f7dfe439c486..03c243f59c7029be46e65ce0469fc55ac8cc6e20 100644 --- a/VECTO/Input Files/Vehicle.vb +++ b/VECTO/Input Files/Vehicle.vb @@ -68,11 +68,11 @@ Public Class Vehicle Public legClass As LegislativeClass Public VehicleHeight As Double - public EcoRolltype as EcoRollType - public PCC as PredictiveCruiseControlType - public EngineStop as Boolean + public EcoRolltype as EcoRollType + public PCC as PredictiveCruiseControlType + public EngineStop as Boolean - public VehicleTankSystem as TankSystem? + public VehicleTankSystem as TankSystem? Public Sub New() _path = "" @@ -323,13 +323,13 @@ Public Class Vehicle End Get End Property - Public ReadOnly Property Identifier As String Implements IVehicleDeclarationInputData.Identifier - get - Return "" - End Get - End Property + Public ReadOnly Property Identifier As String Implements IVehicleDeclarationInputData.Identifier + get + Return "" + End Get + End Property - Public ReadOnly Property ExemptedVehicle As Boolean Implements IVehicleDeclarationInputData.ExemptedVehicle + Public ReadOnly Property ExemptedVehicle As Boolean Implements IVehicleDeclarationInputData.ExemptedVehicle get Return false End Get @@ -413,9 +413,9 @@ Public Class Vehicle End Property Public ReadOnly Property IVehicleEngineeringInputData_Components As IVehicleComponentsEngineering Implements IVehicleEngineeringInputData.Components - get - Return me - End Get + get + Return me + End Get End Property Public ReadOnly Property CrosswindCorrectionMap As TableData _ @@ -619,13 +619,13 @@ Public Class Vehicle End Get End Property - Public ReadOnly Property IVehicleComponentsDeclaration_AuxiliaryInputData As IAuxiliariesDeclarationInputData Implements IVehicleComponentsDeclaration.AuxiliaryInputData - get - return nothing - End Get - End Property + Public ReadOnly Property IVehicleComponentsDeclaration_AuxiliaryInputData As IAuxiliariesDeclarationInputData Implements IVehicleComponentsDeclaration.AuxiliaryInputData + get + return nothing + End Get + End Property - Public ReadOnly Property AuxiliaryInputData As IAuxiliariesEngineeringInputData Implements IVehicleComponentsEngineering.AuxiliaryInputData + Public ReadOnly Property AuxiliaryInputData As IAuxiliariesEngineeringInputData Implements IVehicleComponentsEngineering.AuxiliaryInputData get Return Nothing End Get diff --git a/VECTO/OutputData/JSONFileWriter.vb b/VECTO/OutputData/JSONFileWriter.vb index c1a67d45ac517ab35876d60a1f8ab431524a38bc..5917092db6ac0ef58467e1c77b7676c4c79cd08e 100644 --- a/VECTO/OutputData/JSONFileWriter.vb +++ b/VECTO/OutputData/JSONFileWriter.vb @@ -43,23 +43,23 @@ Public Class JSONFileWriter body.Add("ModelName", eng.Model) body.Add("Displacement", eng.Displacement.ConvertToCubicCentiMeter().ToString()) - body.Add("IdlingSpeed", eng.IdleSpeed.AsRPM) + body.Add("IdlingSpeed", eng.EngineModes.First().IdleSpeed.AsRPM) body.Add("Inertia", eng.Inertia.Value()) - body.Add("WHTC-Urban", eng.WHTCUrban) - body.Add("WHTC-Rural", eng.WHTCRural) - body.Add("WHTC-Motorway", eng.WHTCMotorway) + body.Add("WHTC-Urban", eng.EngineModes.First().Fuels.First().WHTCUrban) + body.Add("WHTC-Rural", eng.EngineModes.First().Fuels.First().WHTCRural) + body.Add("WHTC-Motorway", eng.EngineModes.First().Fuels.First().WHTCMotorway) body.Add("WHTC-Engineering", eng.WHTCEngineering) - body.Add("ColdHotBalancingFactor", eng.ColdHotBalancingFactor) - body.Add("CFRegPer", eng.CorrectionFactorRegPer) + body.Add("ColdHotBalancingFactor", eng.EngineModes.First().Fuels.First().ColdHotBalancingFactor) + body.Add("CFRegPer", eng.EngineModes.First().Fuels.First().CorrectionFactorRegPer) body.Add("RatedPower", eng.RatedPowerDeclared.Value()) body.Add("RatedSpeed", eng.RatedSpeedDeclared.AsRPM) body.Add("MaxTorque", eng.MaxTorqueDeclared.Value()) - body.Add("FuelType", eng.FuelType.ToString()) + body.Add("FuelType", eng.EngineModes.First().Fuels.First().FuelType.ToString()) - body.Add("FullLoadCurve", GetRelativePath(eng.FullLoadCurve.Source, Path.GetDirectoryName(filename))) + body.Add("FullLoadCurve", GetRelativePath(eng.EngineModes.First().FullLoadCurve.Source, Path.GetDirectoryName(filename))) - body.Add("FuelMap", GetRelativePath(eng.FuelConsumptionMap.Source, Path.GetDirectoryName(filename))) + body.Add("FuelMap", GetRelativePath(eng.EngineModes.First().Fuels.First().FuelConsumptionMap.Source, Path.GetDirectoryName(filename))) WriteFile(header, body, filename) End Sub diff --git a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs index c32b74e64f87ebf3f0dda956950ecda317d2f756..905396fd4e149221f555006a2d80ee9120708a79 100644 --- a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs +++ b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs @@ -485,13 +485,40 @@ namespace TUGraz.VectoCommon.InputData /// cf. VECTO Input Parameters.xlsx /// </summary> CubicMeter Displacement { get; } + + Watt RatedPowerDeclared { get; } + + PerSecond RatedSpeedDeclared { get; } + + NewtonMeter MaxTorqueDeclared { get; } + + IList<IEngineModeDeclarationInputData> EngineModes { get; } + } + public interface IEngineModeDeclarationInputData + { /// <summary> /// P063 /// cf. VECTO Input Parameters.xlsx /// </summary> PerSecond IdleSpeed { get; } + /// <summary> + /// P144 + /// P068, P069, P70, P71 + /// cf. VECTO Input Parameters.xlsx + /// </summary> + TableData FullLoadCurve { get; } + + IList<IEngineFuelDelcarationInputData> Fuels { get; } + + } + + public interface IEngineFuelDelcarationInputData + { + + FuelType FuelType { get; } + /// <summary> /// P111 /// cf. VECTO Input Parameters.xlsx @@ -517,8 +544,6 @@ namespace TUGraz.VectoCommon.InputData double CorrectionFactorRegPer { get; } - FuelType FuelType { get; } - /// <summary> /// P067 /// P072, P073, P074 @@ -527,20 +552,9 @@ namespace TUGraz.VectoCommon.InputData /// </summary> TableData FuelConsumptionMap { get; } - /// <summary> - /// P144 - /// P068, P069, P70, P71 - /// cf. VECTO Input Parameters.xlsx - /// </summary> - TableData FullLoadCurve { get; } - - Watt RatedPowerDeclared { get; } - - PerSecond RatedSpeedDeclared { get; } - - NewtonMeter MaxTorqueDeclared { get; } } + public interface IAuxiliariesDeclarationInputData { bool SavedInDeclarationMode { get; } diff --git a/VectoCommon/VectoCommon/Resources/XMLNames.Designer.cs b/VectoCommon/VectoCommon/Resources/XMLNames.Designer.cs index 0e6081e2eb2373d8492dad467e11236b14ac9b9b..ae747f4ad1349e959f5fc8e559df10493db38e0a 100644 --- a/VectoCommon/VectoCommon/Resources/XMLNames.Designer.cs +++ b/VectoCommon/VectoCommon/Resources/XMLNames.Designer.cs @@ -1473,6 +1473,15 @@ namespace TUGraz.VectoCommon.Resources { } } + /// <summary> + /// Looks up a localized string similar to Mode. + /// </summary> + public static string Report_Engine_FuelMode { + get { + return ResourceManager.GetString("Report_Engine_FuelMode", resourceCulture); + } + } + /// <summary> /// Looks up a localized string similar to ExemptedVehicle. /// </summary> @@ -1518,6 +1527,33 @@ namespace TUGraz.VectoCommon.Resources { } } + /// <summary> + /// Looks up a localized string similar to FuelMode. + /// </summary> + public static string Report_Result_FuelMode { + get { + return ResourceManager.GetString("Report_Result_FuelMode", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to dual fuel mode. + /// </summary> + public static string Report_Result_FuelMode_Val_Dual { + get { + return ResourceManager.GetString("Report_Result_FuelMode_Val_Dual", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to single fuel mode. + /// </summary> + public static string Report_Result_FuelMode_Val_Single { + get { + return ResourceManager.GetString("Report_Result_FuelMode_Val_Single", resourceCulture); + } + } + /// <summary> /// Looks up a localized string similar to Mission. /// </summary> @@ -1797,6 +1833,24 @@ namespace TUGraz.VectoCommon.Resources { } } + /// <summary> + /// Looks up a localized string similar to Fuel. + /// </summary> + public static string Report_Results_Fuel { + get { + return ResourceManager.GetString("Report_Results_Fuel", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to type. + /// </summary> + public static string Report_Results_Fuel_Type_Attr { + get { + return ResourceManager.GetString("Report_Results_Fuel_Type_Attr", resourceCulture); + } + } + /// <summary> /// Looks up a localized string similar to FuelConsumption. /// </summary> @@ -1914,6 +1968,15 @@ namespace TUGraz.VectoCommon.Resources { } } + /// <summary> + /// Looks up a localized string similar to FuelTypes. + /// </summary> + public static string Report_Vehicle_FuelTypes { + get { + return ResourceManager.GetString("Report_Vehicle_FuelTypes", resourceCulture); + } + } + /// <summary> /// Looks up a localized string similar to Retarder. /// </summary> diff --git a/VectoCommon/VectoCommon/Resources/XMLNames.resx b/VectoCommon/VectoCommon/Resources/XMLNames.resx index 4e3ede03d84abf02fcaa1af1bf09777557fc483e..47d5519e91bb6134ec4cac332bfa7e97a8fe262d 100644 --- a/VectoCommon/VectoCommon/Resources/XMLNames.resx +++ b/VectoCommon/VectoCommon/Resources/XMLNames.resx @@ -1053,4 +1053,25 @@ <data name="TorqueConverter_MaxInputSpeed" xml:space="preserve"> <value>MaxInputSpeed</value> </data> + <data name="Report_Vehicle_FuelTypes" xml:space="preserve"> + <value>FuelTypes</value> + </data> + <data name="Report_Result_FuelMode" xml:space="preserve"> + <value>FuelMode</value> + </data> + <data name="Report_Result_FuelMode_Val_Dual" xml:space="preserve"> + <value>dual fuel mode</value> + </data> + <data name="Report_Result_FuelMode_Val_Single" xml:space="preserve"> + <value>single fuel mode</value> + </data> + <data name="Report_Results_Fuel" xml:space="preserve"> + <value>Fuel</value> + </data> + <data name="Report_Results_Fuel_Type_Attr" xml:space="preserve"> + <value>type</value> + </data> + <data name="Report_Engine_FuelMode" xml:space="preserve"> + <value>Mode</value> + </data> </root> \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs index d537d272bfaddaf726150eaf3914f0326c853aea..fb80a8452856b179b74fdbbe21f5e08a70505b5a 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs @@ -30,7 +30,9 @@ */ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using Newtonsoft.Json.Linq; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; @@ -102,7 +104,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON } - public class JSONEngineDataV3 : JSONFile, IEngineEngineeringInputData + public class JSONEngineDataV3 : JSONFile, IEngineEngineeringInputData, IEngineModeDeclarationInputData, IEngineFuelDelcarationInputData { public JSONEngineDataV3(JObject data, string fileName, bool tolerateMissing = false) : base(data, fileName, tolerateMissing) {} @@ -156,6 +158,8 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON } } + public IList<IEngineFuelDelcarationInputData> Fuels { get { return new IEngineFuelDelcarationInputData[] { this }; } } + public virtual Watt RatedPowerDeclared { get { return 0.SI<Watt>(); } @@ -171,6 +175,8 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON get { return 0.SI<NewtonMeter>(); } } + public IList<IEngineModeDeclarationInputData> EngineModes { get { return new IEngineModeDeclarationInputData[] { this }; } } + public virtual KilogramSquareMeter Inertia { get { return Body.GetEx<double>(JsonKeys.Engine_Inertia).SI<KilogramSquareMeter>(); } diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractCommonComponentType.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractCommonComponentType.cs index eb627b521035c23d79edf55c1b34a37c34744fe0..266faffd7d4addfbf787b89a1bd685d36155743b 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractCommonComponentType.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractCommonComponentType.cs @@ -39,17 +39,6 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider { } } - protected virtual TableData ReadTableData(string baseElement, string entryElement, Dictionary<string, string> mapping) - { - var entries = BaseNode.SelectNodes( - XMLHelper.QueryLocalName(baseElement, entryElement)); - if (entries != null && entries.Count > 0) { - return XMLHelper.ReadTableData(mapping, entries); - } - - return null; - } - public virtual string CertificationNumber { get { return GetString(XMLNames.Component_CertificationNumber); } diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractXMLType.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractXMLType.cs index 1fa555e394a1ae5d08aa94d5e54b645a874a2e55..aa6ce22e040d45ce63b5e6ae4d66b8b2d797d638 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractXMLType.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/AbstractXMLType.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Xml; using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Utils; @@ -84,5 +86,16 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider { { return node?.Attributes?.GetNamedItem(attribute)?.InnerText; } + + protected virtual TableData ReadTableData(string baseElement, string entryElement, Dictionary<string, string> mapping) + { + var entries = BaseNode.SelectNodes( + XMLHelper.QueryLocalName(baseElement, entryElement)); + if (entries != null && entries.Count > 0) { + return XMLHelper.ReadTableData(mapping, entries); + } + + return null; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs index 6167654c32e1daec266dca10143f04f5a205a7cf..df2da08ad231f224770651ac50f5badff151aa61 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Xml; using System.Xml.Linq; using TUGraz.IVT.VectoXML; @@ -19,6 +21,8 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider public static readonly string QUALIFIED_XSD_TYPE = XMLHelper.CombineNamespace(NAMESPACE_URI.NamespaceName, XSD_TYPE); + protected List<IEngineModeDeclarationInputData> _engineModes; + public XMLDeclarationEngineDataProviderV10( IXMLDeclarationVehicleData vehicle, XmlNode componentNode, string sourceFile) : base(componentNode, sourceFile) @@ -33,44 +37,6 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider get { return GetDouble(XMLNames.Engine_Displacement).SI(Unit.SI.Cubic.Centi.Meter).Cast<CubicMeter>(); } } - public virtual PerSecond IdleSpeed - { - get { return GetDouble(XMLNames.Engine_IdlingSpeed).RPMtoRad(); } - } - - public virtual FuelType FuelType - { - get { - var value = GetString(XMLNames.Engine_FuelType); - if ("LPG".Equals(value, StringComparison.InvariantCultureIgnoreCase)) { - return FuelType.LPGPI; - } - if ("NG".Equals(value, StringComparison.InvariantCultureIgnoreCase)) { - return FuelType.NGPI; - } - - return value.ParseEnum<FuelType>(); - } - } - - public virtual TableData FuelConsumptionMap - { - get { - return ReadTableData( - XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry, - AttributeMappings.FuelConsumptionMapMapping); - } - } - - public virtual TableData FullLoadCurve - { - get { - return ReadTableData( - XMLNames.Engine_FullLoadAndDragCurve, XMLNames.Engine_FullLoadCurve_Entry, - AttributeMappings.EngineFullLoadCurveMapping); - } - } - public virtual Watt RatedPowerDeclared { get { return GetDouble(XMLNames.Engine_RatedPower).SI<Watt>(); } @@ -86,31 +52,101 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider get { return GetDouble(XMLNames.Engine_MaxTorque).SI<NewtonMeter>(); } } - public virtual double WHTCMotorway + public virtual IList<IEngineModeDeclarationInputData> EngineModes { - get { return GetDouble(XMLNames.Engine_WHTCMotorway); } + get { + return _engineModes ?? + (_engineModes = new List<IEngineModeDeclarationInputData>() { new XMLSingleFuelEngine(BaseNode) }); + } } + - public virtual double WHTCRural + public class XMLSingleFuelEngine : AbstractXMLType, IEngineModeDeclarationInputData { - get { return GetDouble(XMLNames.Engine_WHTCRural); } - } + protected IList<IEngineFuelDelcarationInputData> _fuels; - public virtual double WHTCUrban - { - get { return GetDouble(XMLNames.Engine_WHTCUrban); } - } + public XMLSingleFuelEngine(XmlNode baseNode) : base(baseNode) + { + } + + public virtual PerSecond IdleSpeed + { + get { return GetDouble(XMLNames.Engine_IdlingSpeed).RPMtoRad(); } + } + + public virtual TableData FullLoadCurve + { + get { + return ReadTableData( + XMLNames.Engine_FullLoadAndDragCurve, XMLNames.Engine_FullLoadCurve_Entry, + AttributeMappings.EngineFullLoadCurveMapping); + } + } + + public virtual IList<IEngineFuelDelcarationInputData> Fuels { + get { + return _fuels ?? (_fuels = new List<IEngineFuelDelcarationInputData>() { new XMLSingleFuelEngineFuel(BaseNode) }); + } + + } - public virtual double ColdHotBalancingFactor - { - get { return GetDouble(XMLNames.Engine_ColdHotBalancingFactor); } } - public virtual double CorrectionFactorRegPer + public class XMLSingleFuelEngineFuel : AbstractXMLType, IEngineFuelDelcarationInputData { - get { return GetDouble(XMLNames.Engine_CorrectionFactor_RegPer); } + public XMLSingleFuelEngineFuel(XmlNode baseNode) : base(baseNode) { } + + public virtual FuelType FuelType + { + get { + var value = GetString(XMLNames.Engine_FuelType); + if ("LPG".Equals(value, StringComparison.InvariantCultureIgnoreCase)) { + return FuelType.LPGPI; + } + if ("NG".Equals(value, StringComparison.InvariantCultureIgnoreCase)) { + return FuelType.NGPI; + } + + return value.ParseEnum<FuelType>(); + } + } + + public virtual TableData FuelConsumptionMap + { + get { + return ReadTableData( + XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry, + AttributeMappings.FuelConsumptionMapMapping); + } + } + + public virtual double WHTCMotorway + { + get { return GetDouble(XMLNames.Engine_WHTCMotorway); } + } + + public virtual double WHTCRural + { + get { return GetDouble(XMLNames.Engine_WHTCRural); } + } + + public virtual double WHTCUrban + { + get { return GetDouble(XMLNames.Engine_WHTCUrban); } + } + + public virtual double ColdHotBalancingFactor + { + get { return GetDouble(XMLNames.Engine_ColdHotBalancingFactor); } + } + + public virtual double CorrectionFactorRegPer + { + get { return GetDouble(XMLNames.Engine_CorrectionFactor_RegPer); } + } } + #endregion #region Overrides of AbstractXMLResource @@ -125,6 +161,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider #endregion } + // --------------------------------------------------------------------------------------- public class XMLDeclarationEngineDataProviderV20 : XMLDeclarationEngineDataProviderV10 @@ -166,14 +203,75 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider IXMLDeclarationVehicleData vehicle, XmlNode componentNode, string sourceFile) : base( vehicle, componentNode, sourceFile) { } - public override FuelType FuelType + protected override XNamespace SchemaNamespace { - get { return GetString(XMLNames.Engine_FuelType).ParseEnum<FuelType>(); } + get { return NAMESPACE_URI; } } + } + + // --------------------------------------------------------------------------------------- + + public class XMLDeclarationEngineDataProviderV23 : XMLDeclarationEngineDataProviderV20 + { + /* + * Support for dual-fuel engines (in different operating modes - either single fuel or dual fuel) + */ + + public new static readonly XNamespace NAMESPACE_URI = XMLDefinitions.DECLARATION_DEFINITIONS_NAMESPACE_URI_V23; + + public new static readonly string QUALIFIED_XSD_TYPE = + XMLHelper.CombineNamespace(NAMESPACE_URI.NamespaceName, XSD_TYPE); + + public XMLDeclarationEngineDataProviderV23( + IXMLDeclarationVehicleData vehicle, XmlNode componentNode, string sourceFile) : base( + vehicle, componentNode, sourceFile) { } protected override XNamespace SchemaNamespace { get { return NAMESPACE_URI; } } + + #region Overrides of XMLDeclarationEngineDataProviderV10 + + public override IList<IEngineModeDeclarationInputData> EngineModes + { + get { + return _engineModes ?? (_engineModes = GetNodes("Mode") + .Cast<XmlNode>().Select(x => new XMLDualFuelEngineMode(x)).Cast<IEngineModeDeclarationInputData>().ToList()); + } + } + + #endregion + + public class XMLDualFuelEngineMode : XMLSingleFuelEngine + { + public XMLDualFuelEngineMode(XmlNode baseNode) : base(baseNode) { } + + #region Overrides of XMLSingleFuelEngine + + public override IList<IEngineFuelDelcarationInputData> Fuels + { + get { + return _fuels ?? (_fuels = GetNodes("Fuel").Cast<XmlNode>().Select(x => new XMLDualFuelEngineFuel(x)) + .Cast<IEngineFuelDelcarationInputData>().ToList()); + } + } + + #endregion + } + + public class XMLDualFuelEngineFuel : XMLSingleFuelEngineFuel + { + public XMLDualFuelEngineFuel(XmlNode baseNode) : base(baseNode) { } + + #region Overrides of XMLSingleFuelEngineFuel + + public override FuelType FuelType + { + get { return GetAttribute(BaseNode, "type").ParseEnum<FuelType>(); } + } + + #endregion + } } } diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV22InjectModule.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV22InjectModule.cs index d7ad0232f4d198626e8bb6cea1575d7b97e0f28e..69e4ab3ce8479f70dd7708b0e8ec957fdbfb2e57 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV22InjectModule.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV22InjectModule.cs @@ -3,7 +3,8 @@ using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider; using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.Interfaces; using TUGraz.VectoCore.Utils; -namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.NinjectModules { +namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.NinjectModules +{ public class XMLDeclarationInputDataV22InjectModule : NinjectModule { #region Overrides of NinjectModule diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV23InjectModule.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV23InjectModule.cs new file mode 100644 index 0000000000000000000000000000000000000000..d2aff2bbb38eaf8f1eb452ba1cda38e0e4be490b --- /dev/null +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationInputDataV23InjectModule.cs @@ -0,0 +1,19 @@ +using Ninject.Modules; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration.Interfaces; + +namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.NinjectModules +{ + public class XMLDeclarationInputDataV23InjectModule : NinjectModule + { + #region Overrides of NinjectModule + + public override void Load() + { + Bind<IXMLEngineDeclarationInputData>().To<XMLDeclarationEngineDataProviderV23>() + .Named(XMLDeclarationEngineDataProviderV23.QUALIFIED_XSD_TYPE); + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationReaderInjectModule.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationReaderInjectModule.cs index 823952c254f8f819580ecfd9dc98ce329ab4fd1f..150912bf0b813a34036ca712b7b75d6767472f8b 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationReaderInjectModule.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/NinjectModules/XMLDeclarationReaderInjectModule.cs @@ -21,6 +21,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration new XMLDeclarationInputDataV20InjectModule(), new XMLDeclarationInputDataV21InjectModule(), new XMLDeclarationInputDataV22InjectModule(), + new XMLDeclarationInputDataV23InjectModule(), }); #endregion diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/DataProvider/XMLEngineeringEngineDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/DataProvider/XMLEngineeringEngineDataProvider.cs index 2c1fb8e5a6bcd1f296f796d1306ecf522cffa38b..6252c3372d74d27075edffa3066d331b8fd427ce 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/DataProvider/XMLEngineeringEngineDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/DataProvider/XMLEngineeringEngineDataProvider.cs @@ -29,6 +29,8 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.Collections.Generic; +using System.Linq; using System.Xml; using System.Xml.Linq; using TUGraz.IVT.VectoXML; @@ -43,7 +45,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering.DataProvider { internal class XMLEngineeringEngineDataProviderV07 : AbstractEngineeringXMLComponentDataProvider, - IXMLEngineData + IXMLEngineData, IEngineModeDeclarationInputData, IEngineFuelDelcarationInputData { public static readonly XNamespace NAMESPACE_URI = XMLDefinitions.ENGINEERING_DEFINITONS_NAMESPACE_V07; @@ -139,6 +141,10 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering.DataProvider } } + public virtual IList<IEngineFuelDelcarationInputData> Fuels { + get { return new[] { this }.Cast<IEngineFuelDelcarationInputData>().ToList(); } + } + public virtual Watt RatedPowerDeclared { get { @@ -160,6 +166,8 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering.DataProvider } } + public virtual IList<IEngineModeDeclarationInputData> EngineModes { get { return new[] { this }.Cast<IEngineModeDeclarationInputData>().ToList(); } } + public virtual KilogramSquareMeter Inertia { get { return GetString(XMLNames.Engine_Inertia, required: false)?.ToDouble().SI<KilogramSquareMeter>(); } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs index 502dfae3a8170391f98fe93aa24b2bbb4e47fc29..40fb02f9b2942a54551ba47eed3ef30f6e45334b 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs @@ -132,12 +132,12 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter CertificationMethod = CertificationMethod.Measured, DigestValueInput = data.DigestValue != null ? data.DigestValue.DigestValue : "", Displacement = data.Displacement, - IdleSpeed = data.IdleSpeed, - ConsumptionMap = FuelConsumptionMapReader.Create(data.FuelConsumptionMap), + //IdleSpeed = data.IdleSpeed, + //ConsumptionMap = FuelConsumptionMapReader.Create(data.FuelConsumptionMap), RatedPowerDeclared = data.RatedPowerDeclared, RatedSpeedDeclared = data.RatedSpeedDeclared, MaxTorqueDeclared = data.MaxTorqueDeclared, - FuelData = DeclarationData.FuelData.Lookup(data.FuelType, tankSystem) + //FuelData = DeclarationData.FuelData.Lookup(data.FuelType, tankSystem) }; return retVal; } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index 098b5d1e511a1c205ee0f9f451b71860c4147928..164315aeee86fa26c604f47ac9e1ab173c7db8e3 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -180,25 +180,39 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } - internal CombustionEngineData CreateEngineData(IEngineDeclarationInputData engine, PerSecond vehicleEngineIdleSpeed, - IGearboxDeclarationInputData gearbox, IEnumerable<ITorqueLimitInputData> torqueLimits, TankSystem? tankSystem = null) + internal CombustionEngineData CreateEngineData(IVehicleDeclarationInputData vehicle, IEngineModeDeclarationInputData mode, Mission mission) { + var engine = vehicle.Components.EngineInputData; + var gearbox = vehicle.Components.GearboxInputData; + if (!engine.SavedInDeclarationMode) { WarnDeclarationMode("EngineData"); } - var retVal = SetCommonCombustionEngineData(engine, tankSystem); - retVal.IdleSpeed = VectoMath.Max(engine.IdleSpeed, vehicleEngineIdleSpeed); - retVal.WHTCUrban = engine.WHTCUrban; - retVal.WHTCMotorway = engine.WHTCMotorway; - retVal.WHTCRural = engine.WHTCRural; - retVal.ColdHotCorrectionFactor = engine.ColdHotBalancingFactor; - retVal.CorrectionFactorRegPer = engine.CorrectionFactorRegPer; + var retVal = SetCommonCombustionEngineData(engine, vehicle.TankSystem); + retVal.IdleSpeed = VectoMath.Max(mode.IdleSpeed, vehicle.EngineIdleSpeed); + + retVal.Fuels = new List<CombustionEngineFuelData>(); + foreach (var fuel in mode.Fuels) { + retVal.Fuels.Add(new CombustionEngineFuelData() { + WHTCUrban = fuel.WHTCUrban, + WHTCRural = fuel.WHTCRural, + WHTCMotorway = fuel.WHTCMotorway, + ColdHotCorrectionFactor = fuel.ColdHotBalancingFactor, + CorrectionFactorRegPer = fuel.CorrectionFactorRegPer, + FuelData = DeclarationData.FuelData.Lookup(fuel.FuelType, vehicle.TankSystem), + ConsumptionMap = FuelConsumptionMapReader.Create(fuel.FuelConsumptionMap), + FuelConsumptionCorrectionFactor = DeclarationData.WHTCCorrection.Lookup( + mission.MissionType.GetNonEMSMissionType(), fuel.WHTCRural, fuel.WHTCUrban, + fuel.WHTCMotorway) * fuel.ColdHotBalancingFactor * fuel.CorrectionFactorRegPer, + }); + } + retVal.Inertia = DeclarationData.Engine.EngineInertia(retVal.Displacement, gearbox.Type); - var limits = torqueLimits.ToDictionary(e => e.Gear); + var limits = vehicle.TorqueLimits.ToDictionary(e => e.Gear); var numGears = gearbox.Gears.Count; var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1); - fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve, true); + fullLoadCurves[0] = FullLoadCurveReader.Create(mode.FullLoadCurve, true); fullLoadCurves[0].EngineData = retVal; foreach (var gear in gearbox.Gears) { var maxTorque = VectoMath.Min( diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs index 46d86f91347697f8f38ed4ff19be7f7e58e4f44e..d48a799aa05990632b92c073d18969a3c377ffde 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs @@ -137,14 +137,23 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter if (engine.SavedInDeclarationMode) { WarnEngineeringMode("EngineData"); } - + var mode = engine.EngineModes.First(); var retVal = SetCommonCombustionEngineData(engine, tankSystem); + retVal.IdleSpeed = mode.IdleSpeed; + retVal.Fuels = new List<CombustionEngineFuelData>(); + foreach (var fuel in mode.Fuels) { + retVal.Fuels.Add(new CombustionEngineFuelData() { + FuelData = DeclarationData.FuelData.Lookup(fuel.FuelType, tankSystem), + ConsumptionMap = FuelConsumptionMapReader.Create(fuel.FuelConsumptionMap), + FuelConsumptionCorrectionFactor = engine.WHTCEngineering, + }); + } retVal.Inertia = engine.Inertia + (gbx != null && gbx.Type.AutomaticTransmission() ? torqueConverter.Inertia : 0.SI<KilogramSquareMeter>()); var limits = torqueLimits.ToDictionary(e => e.Gear); var numGears = gbx == null ? 0 : gbx.Gears.Count; var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1); - fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve); + fullLoadCurves[0] = FullLoadCurveReader.Create(engine.EngineModes.First().FullLoadCurve); fullLoadCurves[0].EngineData = retVal; if (gbx != null) { foreach (var gear in gbx.Gears) { @@ -153,7 +162,10 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter } } retVal.FullLoadCurves = fullLoadCurves; - retVal.FuelConsumptionCorrectionFactor = engine.WHTCEngineering; + //foreach (var fuelEntry in retVal.Fuels) { + + + //retVal.Fuels[0].FuelConsumptionCorrectionFactor = engine.WHTCEngineering; return retVal; } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs index 4c680443814b8c0afda04b06a366e3cdae7b7569..cc3f1444bab8d0efc81a5c27f6e92a9bdc3d8287 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs @@ -61,7 +61,6 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl private Segment _segment; private DriverData _driverdata; private AirdragData _airdragData; - private CombustionEngineData _engineData; private AxleGearData _axlegearData; private AngledriveData _angledriveData; private GearboxData _gearboxData; @@ -109,12 +108,11 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl _segment.Missions.First().Loadings.First().Value); _airdragData = _dao.CreateAirdragData(vehicle.Components.AirdragInputData, _segment.Missions.First(), _segment); - _engineData = _dao.CreateEngineData(vehicle.Components.EngineInputData, - vehicle.EngineIdleSpeed, - vehicle.Components.GearboxInputData, vehicle.TorqueLimits, vehicle.TankSystem); _axlegearData = _dao.CreateAxleGearData(InputDataProvider.JobInputData.Vehicle.Components.AxleGearInputData); _angledriveData = _dao.CreateAngledriveData(InputDataProvider.JobInputData.Vehicle.Components.AngledriveInputData); - _gearboxData = _dao.CreateGearboxData(vehicle.Components.GearboxInputData, _engineData, + var tmpEngine = _dao.CreateEngineData( + vehicle, vehicle.Components.EngineInputData.EngineModes[0], _segment.Missions.First()); + _gearboxData = _dao.CreateGearboxData(vehicle.Components.GearboxInputData, tmpEngine, _axlegearData.AxleGear.Ratio, tempVehicle.DynamicTyreRadius, tempVehicle.VehicleCategory, vehicle.Components.TorqueConverterInputData); _retarderData = _dao.CreateRetarderData(vehicle.Components.RetarderInputData); @@ -127,20 +125,23 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl private void InitializeReport() { VectoRunData powertrainConfig; + List<List<FuelData.Entry>> fuels; if (InputDataProvider.JobInputData.Vehicle.ExemptedVehicle) { powertrainConfig = new VectoRunData() { Exempted = true, VehicleData = _dao.CreateVehicleData(InputDataProvider.JobInputData.Vehicle, null, null), InputDataHash = InputDataProvider.XMLHash }; + fuels = new List<List<FuelData.Entry>>(); } else { + var vehicle = InputDataProvider.JobInputData.Vehicle; powertrainConfig = new VectoRunData() { VehicleData = _dao.CreateVehicleData( InputDataProvider.JobInputData.Vehicle, _segment.Missions.First(), _segment.Missions.First().Loadings.First().Value), AirdragData = _airdragData, - EngineData = _engineData, + EngineData = _dao.CreateEngineData(vehicle, vehicle.Components.EngineInputData.EngineModes[0], _segment.Missions.First()), GearboxData = _gearboxData, AxleGearData = _axlegearData, Retarder = _retarderData, @@ -153,8 +154,10 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl InputDataHash = InputDataProvider.XMLHash }; powertrainConfig.VehicleData.VehicleClass = _segment.VehicleClass; + fuels = vehicle.Components.EngineInputData.EngineModes.Select(x => x.Fuels.Select(f => DeclarationData.FuelData.Lookup(f.FuelType, vehicle.TankSystem)).ToList()) + .ToList(); } - Report.InitializeReport(powertrainConfig); + Report.InitializeReport(powertrainConfig, fuels); } public IEnumerable<VectoRunData> NextRun() @@ -182,54 +185,58 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl var vehicle = InputDataProvider.JobInputData.Vehicle; var adasCombination = DeclarationData.ADASCombinations.Lookup(vehicle.ADAS); - foreach (var mission in _segment.Missions) { - if (mission.MissionType.IsEMS() && - _engineData.RatedPowerDeclared.IsSmaller(DeclarationData.MinEnginePowerForEMS)) { - continue; - } - DrivingCycleData cycle; - lock (CyclesCacheLock) { - if (CyclesCache.ContainsKey(mission.MissionType)) { - cycle = CyclesCache[mission.MissionType]; - } else { - cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, CycleType.DistanceBased, "", false); - CyclesCache.Add(mission.MissionType, cycle); + var engine = InputDataProvider.JobInputData.Vehicle.Components.EngineInputData; + var engineModes = engine.EngineModes; + + foreach (var engineMode in engineModes) { + + foreach (var mission in _segment.Missions) { + if (mission.MissionType.IsEMS() && + engine.RatedPowerDeclared.IsSmaller(DeclarationData.MinEnginePowerForEMS)) { + continue; + } + + DrivingCycleData cycle; + lock (CyclesCacheLock) { + if (CyclesCache.ContainsKey(mission.MissionType)) { + cycle = CyclesCache[mission.MissionType]; + } else { + cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, CycleType.DistanceBased, "", false); + CyclesCache.Add(mission.MissionType, cycle); + } + } + foreach (var loading in mission.Loadings) { + var simulationRunData = new VectoRunData { + Loading = loading.Key, + VehicleData = _dao.CreateVehicleData(vehicle, mission, loading.Value), + AirdragData = _dao.CreateAirdragData(vehicle.Components.AirdragInputData, mission, _segment), + EngineData = _dao.CreateEngineData(InputDataProvider.JobInputData.Vehicle, engineMode, mission), // _engineData.Copy(), // a copy is necessary because every run has a different correction factor! + GearboxData = _gearboxData, + AxleGearData = _axlegearData, + AngledriveData = _angledriveData, + Aux = _dao.CreateAuxiliaryData( + vehicle.Components.AuxiliaryInputData, mission.MissionType, + _segment.VehicleClass), + Cycle = new DrivingCycleProxy(cycle, mission.MissionType.ToString()), + Retarder = _retarderData, + DriverData = _driverdata, + ExecutionMode = ExecutionMode.Declaration, + JobName = InputDataProvider.JobInputData.JobName, + ModFileSuffix = loading.Key.ToString(), + Report = Report, + Mission = mission, + PTO = mission.MissionType == MissionType.MunicipalUtility + ? _municipalPtoTransmissionData + : _ptoTransmissionData, + InputDataHash = InputDataProvider.XMLHash, + SimulationType = SimulationType.DistanceCycle + }; + simulationRunData.EngineData.ADASCorrectionFactor = DeclarationData.ADASBenefits.Lookup( + _segment.VehicleClass, adasCombination, mission.MissionType, loading.Key); + simulationRunData.VehicleData.VehicleClass = _segment.VehicleClass; + yield return simulationRunData; } - } - foreach (var loading in mission.Loadings) { - var simulationRunData = new VectoRunData { - Loading = loading.Key, - VehicleData = _dao.CreateVehicleData(vehicle, mission, loading.Value), - AirdragData = _dao.CreateAirdragData(vehicle.Components.AirdragInputData, mission, _segment), - EngineData = _engineData.Copy(), // a copy is necessary because every run has a different correction factor! - GearboxData = _gearboxData, - AxleGearData = _axlegearData, - AngledriveData = _angledriveData, - Aux = _dao.CreateAuxiliaryData(vehicle.Components.AuxiliaryInputData, mission.MissionType, - _segment.VehicleClass), - Cycle = new DrivingCycleProxy(cycle, mission.MissionType.ToString()), - Retarder = _retarderData, - DriverData = _driverdata, - ExecutionMode = ExecutionMode.Declaration, - JobName = InputDataProvider.JobInputData.JobName, - ModFileSuffix = loading.Key.ToString(), - Report = Report, - Mission = mission, - PTO = mission.MissionType == MissionType.MunicipalUtility - ? _municipalPtoTransmissionData - : _ptoTransmissionData, - InputDataHash = InputDataProvider.XMLHash, - SimulationType = SimulationType.DistanceCycle - }; - simulationRunData.EngineData.FuelConsumptionCorrectionFactor = DeclarationData.WHTCCorrection.Lookup( - mission.MissionType.GetNonEMSMissionType(), _engineData.WHTCRural, _engineData.WHTCUrban, - _engineData.WHTCMotorway) * - _engineData.ColdHotCorrectionFactor * _engineData.CorrectionFactorRegPer; - simulationRunData.EngineData.ADASCorrectionFactor = DeclarationData.ADASBenefits.Lookup( - _segment.VehicleClass, adasCombination, mission.MissionType, loading.Key); - simulationRunData.VehicleData.VehicleClass = _segment.VehicleClass; - yield return simulationRunData; } } } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs index b89cbc6dc7c188fdd546e048f542d9b9505972b6..89be51f0dac1d41d5537933c45a50c7c5f498500 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs @@ -103,7 +103,9 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl Report.InputDataHash = JobInputData.VectoJobHash; Report.ManufacturerRecord = JobInputData.ManufacturerReportInputData; Report.ManufacturerRecordHash = JobInputData.VectoManufacturerReportHash; - Report.InitializeReport(powertrainConfig); + var fuels = JobInputData.Vehicle.Components.EngineInputData.EngineModes.Select(x => x.Fuels.Select(f => DeclarationData.FuelData.Lookup(f.FuelType, JobInputData.Vehicle.TankSystem)).ToList()) + .ToList(); + Report.InitializeReport(powertrainConfig, fuels); } @@ -126,9 +128,8 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl vehicle.Components.AirdragInputData, Segment.Missions.First(), Segment); EngineData = Dao.CreateEngineData( - vehicle.Components.EngineInputData, - vehicle.EngineIdleSpeed, - vehicle.Components.GearboxInputData, vehicle.TorqueLimits, vehicle.TankSystem); + vehicle, vehicle.Components.EngineInputData.EngineModes.First(), + new Mission() { MissionType = MissionType.LongHaul }); AxlegearData = Dao.CreateAxleGearData(vehicle.Components.AxleGearInputData); AngledriveData = Dao.CreateAngledriveData(vehicle.Components.AngledriveInputData); GearboxData = Dao.CreateGearboxData( @@ -188,7 +189,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl vtpRunData.Mission = new Mission() { MissionType = MissionType.VerificationTest }; - var ncvStd = DeclarationData.FuelData.Lookup(JobInputData.Vehicle.Components.EngineInputData.FuelType).LowerHeatingValueVecto; + //var ncvStd = DeclarationData.FuelData.Lookup(JobInputData.Vehicle.Components.EngineInputData.FuelType).LowerHeatingValueVecto; //var ncvCorrection = ncvStd / JobInputData.NetCalorificValueTestFuel; var mileageCorrection = GetMileagecorrectionFactor(JobInputData.Mileage); vtpRunData.VTPData = new VTPData() { diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs index 96d13b1cc6a8a4116951ec72090cd46fa1dd642e..a52b50ebebe4beef58170ef8c788809ac8239f3c 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs @@ -34,6 +34,7 @@ using System.ComponentModel; using System.Data; using System.Runtime.Serialization; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.OutputData; // ReSharper disable InconsistentNaming @@ -53,8 +54,15 @@ namespace TUGraz.VectoCore.Models.Simulation.Data protected ModalResults(SerializationInfo info, StreamingContext context) : base(info, context) {} public ModalResults() + { + } + + public ModalResults(bool createFcColumns = true) { foreach (var value in EnumHelper.GetValues<ModalResultField>()) { + if (!createFcColumns && ModalDataContainer.FuelConsumptionSignals.Contains(value)) { + continue; + } var col = new DataColumn(value.GetName(), value.GetAttribute().DataType) { Caption = value.GetCaption() }; col.ExtendedProperties[ExtendedPropertyNames.Decimals] = value.GetAttribute().Decimals; col.ExtendedProperties[ExtendedPropertyNames.OutputFactor] = value.GetAttribute().OutputFactor; diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs index 7a8d100553529c297e412aa343be96be7820cdea..0ced0f17b01cc0d8f9e82175a197571fb3137acc 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs @@ -106,32 +106,32 @@ namespace TUGraz.VectoCore.Models.Simulation.Data /// <summary> /// [g/h] Fuel consumption from FC map.. /// </summary> - [ModalResultField(typeof(SI), name: "FC-Map", caption: "FC-Map [g/h]", outputFactor: 3600 * 1000)] FCMap, + [ModalResultField(typeof(SI), name: "FC-Map", caption: "FC-Map{0} [g/h]", outputFactor: 3600 * 1000)] FCMap, /// <summary> /// [g/h] Fuel consumption after correction for different NCV in VECTO Engine and VECTO sim. (Based on FC.) /// </summary> - [ModalResultField(typeof(SI), name: "FC-NCVc", caption: "FC-NCVc [g/h]", outputFactor: 3600 * 1000)] FCNCVc, + [ModalResultField(typeof(SI), name: "FC-NCVc", caption: "FC-NCVc{0} [g/h]", outputFactor: 3600 * 1000)] FCNCVc, /// <summary> /// [g/h] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) /// </summary> - [ModalResultField(typeof(SI), name: "FC-WHTCc", caption: "FC-WHTCc [g/h]", outputFactor: 3600 * 1000)] FCWHTCc, + [ModalResultField(typeof(SI), name: "FC-WHTCc", caption: "FC-WHTCc{0} [g/h]", outputFactor: 3600 * 1000)] FCWHTCc, /// <summary> /// [g/h] Fuel consumption after smart auxiliary correction. /// </summary> - [ModalResultField(typeof(SI), name: "FC-AAUX", caption: "FC-AAUX [g/h]", outputFactor: 3600 * 1000)] FCAAUX, + [ModalResultField(typeof(SI), name: "FC-AAUX", caption: "FC-AAUX{0} [g/h]", outputFactor: 3600 * 1000)] FCAAUX, /// <summary> /// [g/h] Fuel consumption after correction for ADAS technologies. (Based on FC-AAUXc.) /// </summary> - [ModalResultField(typeof(SI), name: "FC-ADAS", caption: "FC-ADAS [g/h]", outputFactor: 3600 * 1000)] FCADAS, + [ModalResultField(typeof(SI), name: "FC-ADAS", caption: "FC-ADAS{0} [g/h]", outputFactor: 3600 * 1000)] FCADAS, /// <summary> /// [g/h] Fuel consumption after WHTC Correction. (Based on FC-ADAS.) /// </summary> - [ModalResultField(typeof(SI), name: "FC-Final", caption: "FC-Final [g/h]", outputFactor: 3600 * 1000)] FCFinal, + [ModalResultField(typeof(SI), name: "FC-Final", caption: "FC-Final{0} [g/h]", outputFactor: 3600 * 1000)] FCFinal, /// <summary> /// [km] Travelled distance. diff --git a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs index 45a5ce4b025b3bd187ef01e9ed3e7338e6db56d8..c7bd12a9e5d52cef62b8806f8aa714dbff031e6f 100644 --- a/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs +++ b/VectoCore/VectoCore/Models/Simulation/DataBus/IDataBus.cs @@ -43,8 +43,6 @@ namespace TUGraz.VectoCore.Models.Simulation.DataBus { ExecutionMode ExecutionMode { get; } - FuelType FuelType { get; } - Second AbsTime { get; set; } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs index 5f10765174638a54386571d7b809e53f0136534b..9783a72ce44e412dd34bef9e139ca4ef74b431bf 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs @@ -274,8 +274,9 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl internal static IAuxInProvider CreateAdvancedAuxiliaries(VectoRunData data, IVehicleContainer container) { var conventionalAux = CreateAuxiliaries(data, container); + // TODO: MQ 2019-07-30 -- which fuel map for advanced auxiliaries?! var busAux = new BusAuxiliariesAdapter(container, data.AdvancedAux.AdvancedAuxiliaryFilePath, data.Cycle.Name, - data.VehicleData.TotalVehicleWeight, data.EngineData.ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux); + data.VehicleData.TotalVehicleWeight, data.EngineData.Fuels[0].ConsumptionMap, data.EngineData.IdleSpeed, conventionalAux); return busAux; } diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs index be10e8d69c6ac66aa46165db59bc9b6b828c898a..f8275ce622d897069b02b80d4c829f230635d168 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs @@ -172,10 +172,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl Log.Error("Output filter for 1Hz results is only available for distance-based cycles!"); warning1Hz = true; } - + var fuels = data.EngineData.Fuels.Select(x => x.FuelData).ToList(); IModalDataContainer modContainer = new ModalDataContainer( - data, ModWriter, + data, ModWriter, fuels, addReportResult: _mode == ExecutionMode.Declaration ? addReportResult : null, writeEngineOnly: _engineOnlyMode, filter: GetModDataFilter(data)) { diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs index b3ab10a4d3e9d3ee35f0d622f544e99c727a8145..e29b96608bb99ae9ceb6ad0ccc905600ce20bd8e 100644 --- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs +++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs @@ -279,10 +279,6 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl return Cycle; } - public FuelType FuelType - { - get { return ModData.FuelData.FuelType; } - } public Second AbsTime { get; set; } diff --git a/VectoCore/VectoCore/Models/Simulation/SimulationFactoryNinjectModule.cs b/VectoCore/VectoCore/Models/Simulation/SimulationFactoryNinjectModule.cs index 1048415c7333d40d807973f366504e62bdbe5e83..73f1f6bdf70f11b0cc534681f5d19162327a0acf 100644 --- a/VectoCore/VectoCore/Models/Simulation/SimulationFactoryNinjectModule.cs +++ b/VectoCore/VectoCore/Models/Simulation/SimulationFactoryNinjectModule.cs @@ -1,4 +1,5 @@ -using Ninject.Extensions.Factory; +using System.Collections.Generic; +using Ninject.Extensions.Factory; using Ninject.Modules; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCore.Models.Declaration; @@ -34,7 +35,7 @@ namespace TUGraz.VectoCore.Models.Simulation { #region Implementation of IDeclarationReport - public void InitializeReport(VectoRunData modelData) + public void InitializeReport(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { } @@ -56,7 +57,7 @@ namespace TUGraz.VectoCore.Models.Simulation { #region Implementation of IDeclarationReport - public void InitializeReport(VectoRunData modelData) + public void InitializeReport(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs index f740f75e8c1174ebec885bf0529f99b37a61f671..cbe3069e27e7ce4bdad52f0fa414b2e3acf995a1 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs @@ -51,29 +51,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [Required, SIRange(0, 10)] public KilogramSquareMeter Inertia { get; internal set; } - [Required, Range(0.9, 2)] - public double WHTCUrban { get; internal set; } - - [Required, Range(0.9, 2)] - public double WHTCRural { get; internal set; } - - [Required, Range(0.9, 2)] - public double WHTCMotorway { get; internal set; } - - [Required, ValidateObject] - public FuelConsumptionMap ConsumptionMap { get; internal set; } - [Required, ValidateObject] public Dictionary<uint, EngineFullLoadCurve> FullLoadCurves { get; internal set; } - - [Required, Range(double.MinValue, double.MaxValue)] - public double ColdHotCorrectionFactor { get; internal set; } - - [Required, Range(double.MinValue, double.MaxValue)] - public double CorrectionFactorRegPer { get; internal set; } - - public double FuelConsumptionCorrectionFactor { get; internal set; } - + public double ADASCorrectionFactor { get; internal set; } public PerSecond RatedSpeedDeclared { get; internal set; } @@ -82,44 +62,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public NewtonMeter MaxTorqueDeclared { get; internal set; } - public FuelData.Entry FuelData { get; internal set; } - + [Required, ValidateObject] + public List<CombustionEngineFuelData> Fuels { get; internal set; } + public CombustionEngineData() { - WHTCUrban = 1; - WHTCMotorway = 1; - WHTCRural = 1; - CorrectionFactorRegPer = 1; - FuelConsumptionCorrectionFactor = 1; ADASCorrectionFactor = 1; } - public CombustionEngineData Copy() - { - return new CombustionEngineData { - Manufacturer = Manufacturer, - ModelName = ModelName, - Displacement = Displacement, - IdleSpeed = IdleSpeed, - Inertia = Inertia, - WHTCUrban = WHTCUrban, - WHTCRural = WHTCRural, - WHTCMotorway = WHTCMotorway, - ConsumptionMap = ConsumptionMap, - FullLoadCurves = FullLoadCurves, - CorrectionFactorRegPer = CorrectionFactorRegPer, - ColdHotCorrectionFactor = ColdHotCorrectionFactor, - FuelConsumptionCorrectionFactor = FuelConsumptionCorrectionFactor, - RatedPowerDeclared = RatedPowerDeclared, - RatedSpeedDeclared = RatedSpeedDeclared, - MaxTorqueDeclared = MaxTorqueDeclared, - FuelData = FuelData, - ADASCorrectionFactor = ADASCorrectionFactor, - CertificationNumber = CertificationNumber, - CertificationMethod = CertificationMethod, - }; - } - // ReSharper disable once UnusedMember.Global -- used in CustomValidation public static ValidationResult ValidateData(CombustionEngineData data, ValidationContext context) { @@ -129,4 +79,38 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data return ValidationResult.Success; } } + + public class CombustionEngineFuelData + { + public CombustionEngineFuelData() + { + WHTCUrban = 1; + WHTCMotorway = 1; + WHTCRural = 1; + CorrectionFactorRegPer = 1; + FuelConsumptionCorrectionFactor = 1; + } + + [Required, Range(0.9, 2)] + public double WHTCUrban { get; internal set; } + + [Required, Range(0.9, 2)] + public double WHTCRural { get; internal set; } + + [Required, Range(0.9, 2)] + public double WHTCMotorway { get; internal set; } + + [Required, Range(double.MinValue, double.MaxValue)] + public double ColdHotCorrectionFactor { get; internal set; } + + [Required, Range(double.MinValue, double.MaxValue)] + public double CorrectionFactorRegPer { get; internal set; } + + public double FuelConsumptionCorrectionFactor { get; internal set; } + + [Required, ValidateObject] + public FuelConsumptionMap ConsumptionMap { get; internal set; } + + public FuelData.Entry FuelData { get; internal set; } + } } diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs index b99687f861dc4f74165cde5166f33e0b870a1a8a..2d516e1c5dca8bd86b665b52d776a7315c603497 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BusAuxiliariesAdapter.cs @@ -31,9 +31,11 @@ using System; using System.IO; +using System.Linq; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; @@ -74,7 +76,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl _fcMapAdapter = new FuelConsumptionAdapter() { FcMap = fcMap }; tmpAux.VectoInputs.FuelMap = _fcMapAdapter; - tmpAux.VectoInputs.FuelDensity = FuelData.Instance().Lookup(container.FuelType).FuelDensity; + // TODO: MQ 2019-07-30: how to handle fuel in aaux? + tmpAux.VectoInputs.FuelDensity = FuelData.Instance().Lookup((container as IVehicleContainer).RunData.EngineData.Fuels.First().FuelData.FuelType).FuelDensity; //'Set Signals tmpAux.Signals.EngineIdleSpeed = engineIdleSpeed; diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index 610bdc57baa2c2479f122c0fa95fedccee3cc4ce..376ac543142ea2c7f9429ee5ef829307cee516d2 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -37,6 +37,7 @@ using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; 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; @@ -383,44 +384,50 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl container[ModalResultField.Tq_full] = CurrentState.DynamicFullLoadTorque; container[ModalResultField.Tq_drag] = CurrentState.FullDragTorque; - var result = ModelData.ConsumptionMap.GetFuelConsumption(CurrentState.EngineTorque, avgEngineSpeed, - DataBus.ExecutionMode != ExecutionMode.Declaration); - if (DataBus.ExecutionMode != ExecutionMode.Declaration && result.Extrapolated) { - Log.Warn("FuelConsumptionMap was extrapolated: range for FC-Map is not sufficient: n: {0}, torque: {1}", - avgEngineSpeed.Value(), CurrentState.EngineTorque.Value()); - } - var pt1 = ModelData.FullLoadCurves[DataBus.Gear].PT1(avgEngineSpeed); - if (DataBus.ExecutionMode == ExecutionMode.Declaration && pt1.Extrapolated) { - Log.Error("requested rpm below minimum rpm in pt1 - extrapolating. n_eng_avg: {0}", - avgEngineSpeed); - } + foreach (var fuel in ModelData.Fuels) { + var result = fuel.ConsumptionMap.GetFuelConsumption( + CurrentState.EngineTorque, avgEngineSpeed, + DataBus.ExecutionMode != ExecutionMode.Declaration); + if (DataBus.ExecutionMode != ExecutionMode.Declaration && result.Extrapolated) { + Log.Warn( + "FuelConsumptionMap for fuel {2} was extrapolated: range for FC-Map is not sufficient: n: {0}, torque: {1}", + avgEngineSpeed.Value(), CurrentState.EngineTorque.Value(), fuel.FuelData.FuelType.GetLabel()); + } + var pt1 = ModelData.FullLoadCurves[DataBus.Gear].PT1(avgEngineSpeed); + if (DataBus.ExecutionMode == ExecutionMode.Declaration && pt1.Extrapolated) { + Log.Error( + "requested rpm below minimum rpm in pt1 - extrapolating. n_eng_avg: {0}", + avgEngineSpeed); + } - var fc = result.Value; - var fcNCVcorr = fc * ModelData.FuelData.HeatingValueCorrection; // TODO: wird fcNCVcorr + var fc = result.Value; + var fcNCVcorr = fc * fuel.FuelData.HeatingValueCorrection; // TODO: wird fcNCVcorr - var fcWHTC = fcNCVcorr * WHTCCorrectionFactor; - var fcAAUX = fcWHTC; - var advancedAux = EngineAux as BusAuxiliariesAdapter; - if (advancedAux != null) { - advancedAux.DoWriteModalResults(container); - fcAAUX = advancedAux.AAuxFuelConsumption; + var fcWHTC = fcNCVcorr * WHTCCorrectionFactor(fuel.FuelData); + var fcAAUX = fcWHTC; + var advancedAux = EngineAux as BusAuxiliariesAdapter; + if (advancedAux != null) { + advancedAux.DoWriteModalResults(container); + fcAAUX = advancedAux.AAuxFuelConsumption; + } + var fcADAS = fcAAUX * ModelData.ADASCorrectionFactor; + var fcFinal = fcADAS; + + container[ModalResultField.FCMap, fuel.FuelData] = fc; + container[ModalResultField.FCNCVc, fuel.FuelData] = fcNCVcorr; + container[ModalResultField.FCWHTCc, fuel.FuelData] = fcWHTC; + container[ModalResultField.FCAAUX, fuel.FuelData] = fcAAUX; + container[ModalResultField.FCADAS, fuel.FuelData] = fcADAS; + container[ModalResultField.FCFinal, fuel.FuelData] = fcFinal; } - var fcADAS = fcAAUX * ModelData.ADASCorrectionFactor; - var fcFinal = fcADAS; - - container[ModalResultField.FCMap] = fc; - container[ModalResultField.FCNCVc] = fcNCVcorr; - container[ModalResultField.FCWHTCc] = fcWHTC; - container[ModalResultField.FCAAUX] = fcAAUX; - container[ModalResultField.FCADAS] = fcADAS; - container[ModalResultField.FCFinal] = fcFinal; } - protected virtual double WHTCCorrectionFactor + protected virtual double WHTCCorrectionFactor(FuelData.Entry fuel) { - get { return ModelData.FuelConsumptionCorrectionFactor; } + return ModelData.Fuels.First(x=> x.FuelData.FuelType == fuel.FuelType).FuelConsumptionCorrectionFactor; } + protected override void DoCommitSimulationStep() { AdvanceState(); diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs index 170ac934b6fcc74ebb0c1f7c456899d9d1481800..5c5267c138ebf4341ad2a1531166ea4d9b388b77 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VTPCombustionEngine.cs @@ -35,6 +35,7 @@ using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; 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.SimulationComponent.Data; @@ -196,17 +197,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return DataBus.CycleData.LeftSample.EngineSpeed; } - protected override double WHTCCorrectionFactor + + // TODO: MQ 2019-07-30 + protected override double WHTCCorrectionFactor (FuelData.Entry fuel) { - get { - if (DataBus.CycleData.LeftSample.VehicleTargetSpeed >= Constants.SimulationSettings.HighwaySpeedThreshold) { - return ModelData.WHTCMotorway; - } - if (DataBus.CycleData.LeftSample.VehicleTargetSpeed >= Constants.SimulationSettings.RuralSpeedThreshold) { - return ModelData.WHTCRural; - } - return ModelData.WHTCUrban; + var selected = ModelData.Fuels.First(x => x.FuelData.FuelType == fuel.FuelType); + + if (DataBus.CycleData.LeftSample.VehicleTargetSpeed >= Constants.SimulationSettings.HighwaySpeedThreshold) { + return selected.WHTCMotorway; + } + if (DataBus.CycleData.LeftSample.VehicleTargetSpeed >= Constants.SimulationSettings.RuralSpeedThreshold) { + return selected.WHTCRural; } + return selected.WHTCUrban; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index 4772a64a63e5c571361b5d76d526ff65c676af14..e017d19563c28f2a00b932f44295201780c566cc 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -46,7 +46,7 @@ namespace TUGraz.VectoCore.OutputData * This methodd is called once befor creating the simulation runs with a temporary * VectoRunData instance */ - void InitializeReport(VectoRunData modelData); + void InitializeReport(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes); /** * called when creating the simulation run (before starting the simulations) @@ -157,6 +157,6 @@ namespace TUGraz.VectoCore.OutputData protected internal abstract void DoWriteReport(); - public abstract void InitializeReport(VectoRunData modelData); + public abstract void InitializeReport(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes); } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index 81b51be39e067eac0a77824ce84af95a0ff4abcb..2a8621f4796849934e8d830d7423878a86eb8e11 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; @@ -56,6 +57,8 @@ namespace TUGraz.VectoCore.OutputData /// <returns></returns> object this[ModalResultField key] { get; set; } + object this[ModalResultField key, FuelData.Entry fuel] { get; set; } + /// <summary> /// Indexer for auxiliary fields of the DataWriter. /// </summary> @@ -70,7 +73,7 @@ namespace TUGraz.VectoCore.OutputData /// </summary> void CommitSimulationStep(); - FuelData.Entry FuelData { get; } + IList<FuelData.Entry> FuelData { get; } VectoRun.Status RunStatus { get; } @@ -88,6 +91,8 @@ namespace TUGraz.VectoCore.OutputData T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T>; + T TimeIntegral<T>(string field, Func<SI, bool> filter = null) where T : SIBase<T>; + void SetDataValue(string fieldName, object value); void AddAuxiliary(string id, string columnName = null); @@ -102,6 +107,8 @@ namespace TUGraz.VectoCore.OutputData /// called after the simulation is finished and the sum-entries have been written /// </summary> void FinishSimulation(); + + string GetColumnName(FuelData.Entry fuelData, ModalResultField mrf); } public static class ModalDataContainerExtensions @@ -151,8 +158,8 @@ namespace TUGraz.VectoCore.OutputData public static Scalar AccelerationTimeShare(this IModalDataContainer data) { var accelerationTimeShare = data.GetValues(x => new { - a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + a = x.Field<MeterPerSquareSecond>(ModalResultField.acc.GetName()).DefaultIfNull(0), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }) .Sum(x => x.a > 0.125 ? x.dt : 0.SI<Second>()).DefaultIfNull(0); return 100 * (accelerationTimeShare / data.Duration()).Cast<Scalar>(); @@ -161,8 +168,8 @@ namespace TUGraz.VectoCore.OutputData public static Scalar DecelerationTimeShare(this IModalDataContainer data) { var decelerationTimeShare = data.GetValues(x => new { - a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + a = x.Field<MeterPerSquareSecond>(ModalResultField.acc.GetName()).DefaultIfNull(0), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }) .Sum(x => x.a < -0.125 ? x.dt : 0.SI<Second>()).DefaultIfNull(0); return 100 * (decelerationTimeShare / data.Duration()).Cast<Scalar>(); @@ -171,9 +178,9 @@ namespace TUGraz.VectoCore.OutputData public static Scalar CruiseTimeShare(this IModalDataContainer data) { var cruiseTime = data.GetValues(x => new { - v = x.Field<MeterPerSecond>((int)ModalResultField.v_act).DefaultIfNull(0), - a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + v = x.Field<MeterPerSecond>(ModalResultField.v_act.GetName()).DefaultIfNull(0), + a = x.Field<MeterPerSquareSecond>(ModalResultField.acc.GetName()).DefaultIfNull(0), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }) .Sum(x => x.v >= 0.1.KMPHtoMeterPerSecond() && x.a.IsBetween(-0.125, 0.125) ? x.dt : 0.SI<Second>()) .DefaultIfNull(0); @@ -183,8 +190,8 @@ namespace TUGraz.VectoCore.OutputData public static Scalar StopTimeShare(this IModalDataContainer data) { var stopTime = data.GetValues(x => new { - v = x.Field<MeterPerSecond>((int)ModalResultField.v_act).DefaultIfNull(0), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + v = x.Field<MeterPerSecond>(ModalResultField.v_act.GetName()).DefaultIfNull(0), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }) .Sum(x => x.v < 0.1.KMPHtoMeterPerSecond() ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>(); return 100 * (stopTime / data.Duration()).Cast<Scalar>(); @@ -270,10 +277,10 @@ namespace TUGraz.VectoCore.OutputData var max = data.GetValues<Meter>(ModalResultField.dist).LastOrDefault() ?? 0.SI<Meter>(); var first = data.GetValues( r => new { - dist = r.Field<Meter>((int)ModalResultField.dist), - vact = r.Field<MeterPerSecond>((int)ModalResultField.v_act), - acc = r.Field<MeterPerSquareSecond>((int)ModalResultField.acc), - dt = r.Field<Second>((int)ModalResultField.simulationInterval) + dist = r.Field<Meter>(ModalResultField.dist.GetName()), + vact = r.Field<MeterPerSecond>(ModalResultField.v_act.GetName()), + acc = r.Field<MeterPerSquareSecond>(ModalResultField.acc.GetName()), + dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()) }).First(); var min = 0.SI<Meter>(); if (first != null && first.vact != null && first.acc != null && first.dt != null) { @@ -330,86 +337,97 @@ namespace TUGraz.VectoCore.OutputData return data.WorkWheelsPos() / data.Duration(); } - public static KilogramPerMeter FuelConsumptionWHTC(this IModalDataContainer data) + public static KilogramPerMeter FuelConsumptionWHTC(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / distance; + var column = data.GetColumnName(fuelData, ModalResultField.FCWHTCc); + return data.TimeIntegral<Kilogram>(column) / distance; } - public static KilogramPerSecond FuelConsumptionWHTCPerSecond(this IModalDataContainer data) + public static KilogramPerSecond FuelConsumptionWHTCPerSecond(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / data.Duration(); + var column = data.GetColumnName(fuelData, ModalResultField.FCWHTCc); + return data.TimeIntegral<Kilogram>(column) / data.Duration(); } - public static KilogramPerMeter FuelConsumptionNCVCorrected(this IModalDataContainer data) + public static KilogramPerMeter FuelConsumptionNCVCorrected(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCNCVc) / distance; + var column = data.GetColumnName(fuelData, ModalResultField.FCNCVc); + return data.TimeIntegral<Kilogram>(column) / distance; } - public static KilogramPerSecond FuelConsumptionNCVCorrectedPerSecond(this IModalDataContainer data) + public static KilogramPerSecond FuelConsumptionNCVCorrectedPerSecond(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TimeIntegral<Kilogram>(ModalResultField.FCNCVc) / data.Duration(); + var column = data.GetColumnName(fuelData, ModalResultField.FCNCVc); + return data.TimeIntegral<Kilogram>(column) / data.Duration(); } - public static KilogramPerSecond FuelConsumptionAAUXPerSecond(this IModalDataContainer data) + public static KilogramPerSecond FuelConsumptionAAUXPerSecond(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TimeIntegral<Kilogram>(ModalResultField.FCAAUX) / data.Duration(); + var column = data.GetColumnName(fuelData, ModalResultField.FCAAUX); + return data.TimeIntegral<Kilogram>(column) / data.Duration(); } - public static KilogramPerMeter FuelConsumptionAAUX(this IModalDataContainer data) + public static KilogramPerMeter FuelConsumptionAAUX(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCAAUX) / distance; + var column = data.GetColumnName(fuelData, ModalResultField.FCAAUX); + return data.TimeIntegral<Kilogram>(column) / distance; } - public static KilogramPerSecond FuelConsumptionADASPerSecond(this IModalDataContainer data) + public static KilogramPerSecond FuelConsumptionADASPerSecond(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TimeIntegral<Kilogram>(ModalResultField.FCADAS) / data.Duration(); + var column = data.GetColumnName(fuelData, ModalResultField.FCADAS); + return data.TimeIntegral<Kilogram>(column) / data.Duration(); } - public static KilogramPerMeter FuelConsumptionADAS(this IModalDataContainer data) + public static KilogramPerMeter FuelConsumptionADAS(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCADAS) / distance; + var column = data.GetColumnName(fuelData, ModalResultField.FCADAS); + return data.TimeIntegral<Kilogram>(column) / distance; } - public static KilogramPerSecond FuelConsumptionFinalPerSecond(this IModalDataContainer data) + public static KilogramPerSecond FuelConsumptionFinalPerSecond(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) / data.Duration(); + var column = data.GetColumnName(fuelData, ModalResultField.FCFinal); + return data.TimeIntegral<Kilogram>(column) / data.Duration(); } - public static KilogramPerMeter FuelConsumptionFinal(this IModalDataContainer data) + public static KilogramPerMeter FuelConsumptionFinal(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) / distance; + + var column = data.GetColumnName(fuelData, ModalResultField.FCFinal); + return data.TimeIntegral<Kilogram>(column) / distance; } - public static VolumePerMeter FuelConsumptionFinalVolumePerMeter(this IModalDataContainer data) + public static VolumePerMeter FuelConsumptionFinalVolumePerMeter(this IModalDataContainer data, FuelData.Entry fuelData) { - var fuelConsumptionFinal = data.FuelConsumptionFinal(); - if (fuelConsumptionFinal == null || data.FuelData.FuelDensity == null) { + var fuelConsumptionFinal = data.FuelConsumptionFinal(fuelData); + if (fuelConsumptionFinal == null || fuelData.FuelDensity == null) { return null; } - var fcVolumePerMeter = fuelConsumptionFinal / data.FuelData.FuelDensity; + var fcVolumePerMeter = fuelConsumptionFinal / fuelData.FuelDensity; return fcVolumePerMeter.Cast<VolumePerMeter>(); } @@ -419,35 +437,44 @@ namespace TUGraz.VectoCore.OutputData if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * data.FuelData.CO2PerFuelWeight / distance; + + var sum = 0.SI<Kilogram>(); + foreach (var fuelData in data.FuelData) { + sum += data.GetValues( + row => row.Field<Second>(ModalResultField.simulationInterval.GetName()) * + row.Field<KilogramPerSecond>(data.GetColumnName(fuelData, ModalResultField.FCFinal))).Sum() * fuelData.CO2PerFuelWeight; + } + + return sum / distance; + //return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * fuelData.CO2PerFuelWeight / distance; } - public static JoulePerMeter EnergyPerMeter(this IModalDataContainer data) + public static JoulePerMeter EnergyPerMeter(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * data.FuelData.LowerHeatingValueVecto / distance; + return data.TimeIntegral<Kilogram>(data.GetColumnName(fuelData, ModalResultField.FCFinal)) * fuelData.LowerHeatingValueVecto / distance; } - public static Kilogram TotalFuelConsumption(this IModalDataContainer data) + public static Kilogram TotalFuelConsumptionFcMap(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TimeIntegral<Kilogram>(ModalResultField.FCMap); + return data.TimeIntegral<Kilogram>(data.GetColumnName(fuelData, ModalResultField.FCMap)); } - public static KilogramPerSecond FCMapPerSecond(this IModalDataContainer data) + public static KilogramPerSecond FCMapPerSecond(this IModalDataContainer data, FuelData.Entry fuelData) { - return data.TotalFuelConsumption() / data.Duration(); + return data.TotalFuelConsumptionFcMap(fuelData) / data.Duration(); } - public static KilogramPerMeter FCMapPerMeter(this IModalDataContainer data) + public static KilogramPerMeter FCMapPerMeter(this IModalDataContainer data, FuelData.Entry fuelData) { var distance = data.Distance(); if (distance == null || distance.IsEqual(0)) { return null; } - return data.TotalFuelConsumption() / distance; + return data.TotalFuelConsumptionFcMap(fuelData) / distance; } @@ -509,8 +536,8 @@ namespace TUGraz.VectoCore.OutputData public static PerSecond AvgEngineSpeed(this IModalDataContainer data) { - var integral = data.GetValues(x => x.Field<PerSecond>((int)ModalResultField.n_eng_avg).Value() * - x.Field<Second>((int)ModalResultField.simulationInterval).Value()).Sum(); + var integral = data.GetValues(x => x.Field<PerSecond>(ModalResultField.n_eng_avg.GetName()).Value() * + x.Field<Second>(ModalResultField.simulationInterval.GetName()).Value()).Sum(); return (integral / Duration(data).Value()).SI<PerSecond>(); } @@ -522,9 +549,9 @@ namespace TUGraz.VectoCore.OutputData public static Scalar EngineMaxLoadTimeShare(this IModalDataContainer data) { var sum = data.GetValues(x => new { - tMax = x.Field<NewtonMeter>((int)ModalResultField.Tq_full).DefaultIfNull(-1), - tEng = x.Field<NewtonMeter>((int)ModalResultField.T_eng_fcmap).DefaultIfNull(0), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + tMax = x.Field<NewtonMeter>(ModalResultField.Tq_full.GetName()).DefaultIfNull(-1), + tEng = x.Field<NewtonMeter>(ModalResultField.T_eng_fcmap.GetName()).DefaultIfNull(0), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }).Sum(x => x.tMax.IsEqual(x.tEng, 5.SI<NewtonMeter>()) ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>(); return 100 * sum / Duration(data); } @@ -543,8 +570,8 @@ namespace TUGraz.VectoCore.OutputData var gearCount = 0; var shifts = data.GetValues(x => new { - Gear = x.Field<uint>((int)ModalResultField.Gear), - Speed = x.Field<MeterPerSecond>((int)ModalResultField.v_act) + Gear = x.Field<uint>(ModalResultField.Gear.GetName()), + Speed = x.Field<MeterPerSecond>(ModalResultField.v_act.GetName()) }); foreach (var entry in shifts) { if (entry.Speed != null && entry.Speed.IsSmallerOrEqual(0.1)) { @@ -567,8 +594,8 @@ namespace TUGraz.VectoCore.OutputData public static Scalar CoastingTimeShare(this IModalDataContainer data) { var sum = data.GetValues(x => new { - DrivingBehavior = x.Field<DrivingBehavior>((int)ModalResultField.drivingBehavior), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + DrivingBehavior = x.Field<DrivingBehavior>(ModalResultField.drivingBehavior.GetName()), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }) .Sum(x => x.DrivingBehavior == DrivingBehavior.Coasting ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>(); return 100 * sum / Duration(data); @@ -577,8 +604,8 @@ namespace TUGraz.VectoCore.OutputData public static Scalar BrakingTimeShare(this IModalDataContainer data) { var sum = data.GetValues(x => new { - DrivingBehavior = x.Field<DrivingBehavior>((int)ModalResultField.drivingBehavior), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + DrivingBehavior = x.Field<DrivingBehavior>(ModalResultField.drivingBehavior.GetName()), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }) .Sum(x => x.DrivingBehavior == DrivingBehavior.Braking ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>(); return 100 * sum / Duration(data); @@ -592,8 +619,8 @@ namespace TUGraz.VectoCore.OutputData } var gearData = data.GetValues(x => new { - Gear = x.Field<uint>((int)ModalResultField.Gear), - dt = x.Field<Second>((int)ModalResultField.simulationInterval) + Gear = x.Field<uint>(ModalResultField.Gear.GetName()), + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()) }); foreach (var entry in gearData) { diff --git a/VectoCore/VectoCore/OutputData/ModFilter/ActualModalDataFilter.cs b/VectoCore/VectoCore/OutputData/ModFilter/ActualModalDataFilter.cs index ee1bcf858a32394cda828c8bf1028d98a56f8782..767ba03564d02a9433de1a34d51a36ed2ee54e00 100644 --- a/VectoCore/VectoCore/OutputData/ModFilter/ActualModalDataFilter.cs +++ b/VectoCore/VectoCore/OutputData/ModFilter/ActualModalDataFilter.cs @@ -46,10 +46,10 @@ namespace TUGraz.VectoCore.OutputData.ModFilter //var ds = 1e-12.SI<Meter>(); var init = data.Rows[0]; - var v_act = init.Field<MeterPerSecond>((int)ModalResultField.v_act); - var n_engine = init.Field<PerSecond>((int)ModalResultField.n_eng_avg); - var dist = init.Field<Meter>((int)ModalResultField.dist); - var n_gbx_out = init.Field<PerSecond>((int)ModalResultField.n_gbx_out_avg); + var v_act = init.Field<MeterPerSecond>(ModalResultField.v_act.GetName()); + var n_engine = init.Field<PerSecond>(ModalResultField.n_eng_avg.GetName()); + var dist = init.Field<Meter>(ModalResultField.dist.GetName()); + var n_gbx_out = init.Field<PerSecond>(ModalResultField.n_gbx_out_avg.GetName()); for (var i = 1; i < data.Rows.Count; i++) { //var prev = data.Rows[i - 1]; @@ -57,10 +57,10 @@ namespace TUGraz.VectoCore.OutputData.ModFilter var start = results.NewRow(); var end = results.NewRow(); - start[(int)ModalResultField.time] = current.Field<Second>((int)ModalResultField.time) - - current.Field<Second>((int)ModalResultField.simulationInterval) / 2.0; - end[(int)ModalResultField.time] = current.Field<Second>((int)ModalResultField.time) + - current.Field<Second>((int)ModalResultField.simulationInterval) / 2.0; + start[ModalResultField.time.GetName()] = current.Field<Second>(ModalResultField.time.GetName()) - + current.Field<Second>(ModalResultField.simulationInterval.GetName()) / 2.0; + end[ModalResultField.time.GetName()] = current.Field<Second>(ModalResultField.time.GetName()) + + current.Field<Second>(ModalResultField.simulationInterval.GetName()) / 2.0; SetConstantValues(current, start, end, ModalResultField.simulationInterval, @@ -70,23 +70,23 @@ namespace TUGraz.VectoCore.OutputData.ModFilter ModalResultField.Gear, ModalResultField.TC_Locked); - start[(int)ModalResultField.v_act] = v_act; - v_act = 2 * current.Field<MeterPerSecond>((int)ModalResultField.v_act) - v_act; - end[(int)ModalResultField.v_act] = v_act; + start[ModalResultField.v_act.GetName()] = v_act; + v_act = 2 * current.Field<MeterPerSecond>(ModalResultField.v_act.GetName()) - v_act; + end[ModalResultField.v_act.GetName()] = v_act; SetConstantValues(current, start, end, ModalResultField.v_targ); - start[(int)ModalResultField.dist] = dist; - dist = current.Field<Meter>((int)ModalResultField.dist); - end[(int)ModalResultField.dist] = dist; + start[ModalResultField.dist.GetName()] = dist; + dist = current.Field<Meter>(ModalResultField.dist.GetName()); + end[ModalResultField.dist.GetName()] = dist; - start[(int)ModalResultField.n_eng_avg] = n_engine; - n_engine = 2 * current.Field<PerSecond>((int)ModalResultField.n_eng_avg) - n_engine; - end[(int)ModalResultField.n_eng_avg] = n_engine; + start[ModalResultField.n_eng_avg.GetName()] = n_engine; + n_engine = 2 * current.Field<PerSecond>(ModalResultField.n_eng_avg.GetName()) - n_engine; + end[ModalResultField.n_eng_avg.GetName()] = n_engine; - start[(int)ModalResultField.n_gbx_out_avg] = n_gbx_out; - n_gbx_out = 2 * current.Field<PerSecond>((int)ModalResultField.n_gbx_out_avg) - n_gbx_out; - end[(int)ModalResultField.n_gbx_out_avg] = n_gbx_out; + start[ModalResultField.n_gbx_out_avg.GetName()] = n_gbx_out; + n_gbx_out = 2 * current.Field<PerSecond>(ModalResultField.n_gbx_out_avg.GetName()) - n_gbx_out; + end[ModalResultField.n_gbx_out_avg.GetName()] = n_gbx_out; SetConstantValues(current, start, end, ModalResultField.T_eng_fcmap, @@ -143,21 +143,22 @@ namespace TUGraz.VectoCore.OutputData.ModFilter private void SetConstantValues(DataRow current, DataRow start, DataRow end, params ModalResultField[] fields) { foreach (var field in fields) { - if (current[(int)field] == DBNull.Value) { + var fieldName = field.GetName(); + if (current[fieldName] == DBNull.Value) { continue; } if (field.GetDataType() == typeof(SI)) { - start[(int)field] = current.Field<SI>((int)field); - end[(int)field] = current.Field<SI>((int)field); + start[fieldName] = current.Field<SI>(fieldName); + end[fieldName] = current.Field<SI>(fieldName); } else if (field.GetDataType() == typeof(double)) { - start[(int)field] = current.Field<double>((int)field); - end[(int)field] = current.Field<double>((int)field); + start[fieldName] = current.Field<double>(fieldName); + end[fieldName] = current.Field<double>(fieldName); } else if (field.GetDataType() == typeof(int)) { - start[(int)field] = current.Field<int>((int)field); - end[(int)field] = current.Field<int>((int)field); + start[fieldName] = current.Field<int>(fieldName); + end[fieldName] = current.Field<int>(fieldName); } else if (field.GetDataType() == typeof(uint)) { - start[(int)field] = current.Field<uint>((int)field); - end[(int)field] = current.Field<uint>((int)field); + start[fieldName] = current.Field<uint>(fieldName); + end[fieldName] = current.Field<uint>(fieldName); } } } diff --git a/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs b/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs index 97183958b3dc8931fd878d66f1bb5fcd2f75bec7..7575b637e20910f624a490ceb6b18effa2f92f9e 100644 --- a/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs +++ b/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs @@ -52,16 +52,16 @@ namespace TUGraz.VectoCore.OutputData.ModFilter var absTime = 0.SI<Second>(); var distance = 0.SI<Meter>(); - var v = data.Rows[0].Field<MeterPerSecond>((int)ModalResultField.v_act); + var v = data.Rows[0].Field<MeterPerSecond>(ModalResultField.v_act.GetName()); var remainingDt = 0.SI<Second>(); var vPrevious = v; for (var i = 0; i < data.Rows.Count; i++) { var row = data.Rows[i]; - var currentDt = row.Field<Second>((int)ModalResultField.simulationInterval); + var currentDt = row.Field<Second>(ModalResultField.simulationInterval.GetName()); - if (row.Field<Meter>((int)ModalResultField.dist).IsSmaller(distance, 1e-3)) { + if (row.Field<Meter>(ModalResultField.dist.GetName()).IsSmaller(distance, 1e-3)) { LogManager.GetLogger(typeof(ModalData1HzFilter).FullName).Error("1Hz-Filter: distance must always be increasing."); } @@ -69,9 +69,9 @@ namespace TUGraz.VectoCore.OutputData.ModFilter if (remainingDt > 0 && remainingDt + currentDt >= 1) { // calculate values var dt = 1.SI<Second>() - remainingDt; - var gear = row[(int)ModalResultField.Gear]; + var gear = row[ModalResultField.Gear.GetName()]; gearsList[gear] = gearsList.GetValueOrZero(gear) + dt; - var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; + var a = (MeterPerSquareSecond)row[ModalResultField.acc.GetName()]; var ds = dt * v + a / 2 * dt * dt; if (ds.IsSmaller(0)) { throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative. ds: {0} {1}", ds, "1"); @@ -83,11 +83,11 @@ namespace TUGraz.VectoCore.OutputData.ModFilter // write a new row for the combined 1 second var r = results.NewRow(); r.ItemArray = AddRow(remainingRow, MultiplyRow(row.ItemArray, dt)); - r[(int)ModalResultField.time] = absTime; - r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); - r[(int)ModalResultField.Gear] = gearsList.MaxBy(kv => kv.Value).Key; - r[(int)ModalResultField.dist] = distance; - r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; + r[ModalResultField.time.GetName()] = absTime; + r[ModalResultField.simulationInterval.GetName()] = 1.SI<Second>(); + r[ModalResultField.Gear.GetName()] = gearsList.MaxBy(kv => kv.Value).Key; + r[ModalResultField.dist.GetName()] = distance; + r[ModalResultField.v_act.GetName()] = (v + vPrevious) / 2; vPrevious = v; results.Rows.Add(r); @@ -104,7 +104,7 @@ namespace TUGraz.VectoCore.OutputData.ModFilter // calculate values var dt = 1.SI<Second>(); currentDt = currentDt - 1.SI<Second>(); - var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; + var a = (MeterPerSquareSecond)row[ModalResultField.acc.GetName()]; var ds = v * dt + a / 2 * dt * dt; if (ds.IsSmaller(0)) { throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative. ds: {0} {1}", ds, "2"); @@ -116,10 +116,10 @@ namespace TUGraz.VectoCore.OutputData.ModFilter // write a new row for the sliced 1 second var r = results.NewRow(); r.ItemArray = row.ItemArray; - r[(int)ModalResultField.time] = absTime; - r[(int)ModalResultField.simulationInterval] = dt; - r[(int)ModalResultField.dist] = distance; - r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; + r[ModalResultField.time.GetName()] = absTime; + r[ModalResultField.simulationInterval.GetName()] = dt; + r[ModalResultField.dist.GetName()] = distance; + r[ModalResultField.v_act.GetName()] = (v + vPrevious) / 2; vPrevious = v; results.Rows.Add(r); } @@ -128,9 +128,9 @@ namespace TUGraz.VectoCore.OutputData.ModFilter if (currentDt > 0) { // calculate values var dt = currentDt; - var gear = row[(int)ModalResultField.Gear]; + var gear = row[ModalResultField.Gear.GetName()]; gearsList[gear] = gearsList.GetValueOrZero(gear) + dt; - var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; + var a = (MeterPerSquareSecond)row[ModalResultField.acc.GetName()]; var ds = v * dt + a / 2 * dt * dt; if (ds.IsSmaller(0)) { throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative. ds: {0} {1}", ds, "3"); @@ -155,7 +155,7 @@ namespace TUGraz.VectoCore.OutputData.ModFilter // calculate values var last = data.Rows.Cast<DataRow>().Last(); var dt = remainingDt; - var a = (MeterPerSquareSecond)last[(int)ModalResultField.acc]; + var a = (MeterPerSquareSecond)last[ModalResultField.acc.GetName()]; var ds = v * dt + a / 2 * dt * dt; if (v.IsEqual(0)) { ds = 0.SI<Meter>(); @@ -170,11 +170,11 @@ namespace TUGraz.VectoCore.OutputData.ModFilter // write a new row for the last second var r = results.NewRow(); r.ItemArray = MultiplyRow(remainingRow, 1 / dt).ToArray(); - r[(int)ModalResultField.time] = VectoMath.Ceiling(absTime); - r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); - r[(int)ModalResultField.Gear] = gearsList.MaxBy(kv => kv.Value).Key; - r[(int)ModalResultField.dist] = distance; - r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; + r[ModalResultField.time.GetName()] = VectoMath.Ceiling(absTime); + r[ModalResultField.simulationInterval.GetName()] = 1.SI<Second>(); + r[ModalResultField.Gear.GetName()] = gearsList.MaxBy(kv => kv.Value).Key; + r[ModalResultField.dist.GetName()] = distance; + r[ModalResultField.v_act.GetName()] = (v + vPrevious) / 2; results.Rows.Add(r); } diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index cc4e5718ff1dd99c9588cdf42e091f1d3d3e232a..609c3b62d66be84783981b3db896f43fd5821bb5 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -35,6 +35,7 @@ using System.Data; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; +using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Declaration; @@ -54,6 +55,14 @@ namespace TUGraz.VectoCore.OutputData private readonly IModalDataWriter _writer; private readonly List<string> _additionalColumns = new List<string>(); private Exception SimException; + + protected internal readonly Dictionary<FuelData.Entry, Dictionary<ModalResultField, DataColumn>> FuelColumns = new Dictionary<FuelData.Entry, Dictionary<ModalResultField, DataColumn>>(); + + public static readonly IList<ModalResultField> FuelConsumptionSignals = new[] { + ModalResultField.FCMap, ModalResultField.FCNCVc, ModalResultField.FCWHTCc, ModalResultField.FCAAUX, + ModalResultField.FCADAS, ModalResultField.FCFinal + }; + public int JobRunId { get; private set; } public string RunName { get; private set; } public string CycleName { get; private set; } @@ -79,17 +88,17 @@ namespace TUGraz.VectoCore.OutputData public bool WriteAdvancedAux { get; set; } - public ModalDataContainer(string runName, FuelData.Entry fuel, IModalDataWriter writer, bool writeEngineOnly = false, params IModalDataFilter[] filters) + public ModalDataContainer(string runName, IList<FuelData.Entry> fuel, IModalDataWriter writer, bool writeEngineOnly = false, params IModalDataFilter[] filters) : this(0, runName, "", fuel, "", writer, _ => { }, writeEngineOnly, filters) {} - public ModalDataContainer(VectoRunData runData, IModalDataWriter writer, Action<ModalDataContainer> addReportResult, + public ModalDataContainer(VectoRunData runData, IModalDataWriter writer, IList<FuelData.Entry> fuels, Action<ModalDataContainer> addReportResult, bool writeEngineOnly, params IModalDataFilter[] filter) : this( - runData.JobRunId, runData.JobName, runData.Cycle.Name, runData.EngineData.FuelData, runData.ModFileSuffix, writer, + runData.JobRunId, runData.JobName, runData.Cycle.Name, fuels, runData.ModFileSuffix, writer, addReportResult, writeEngineOnly, filter) {} - protected ModalDataContainer(int jobRunId, string runName, string cycleName, FuelData.Entry fuelData, string runSuffix, + protected ModalDataContainer(int jobRunId, string runName, string cycleName, IList<FuelData.Entry> fuels, string runSuffix, IModalDataWriter writer, Action<ModalDataContainer> addReportResult, bool writeEngineOnly, params IModalDataFilter[] filters) { @@ -100,13 +109,33 @@ namespace TUGraz.VectoCore.OutputData JobRunId = jobRunId; _writer = writer; - FuelData = fuelData; - + Data = new ModalResults(false); + foreach (var entry in fuels) { + if (FuelColumns.ContainsKey(entry)) { + throw new VectoException("Fuel {0} already added!", entry.FuelType.GetLabel()); + } + FuelColumns[entry] = new Dictionary<ModalResultField, DataColumn>(); + foreach (var fcCol in FuelConsumptionSignals) { + + var col = new DataColumn(fuels.Count == 1 ? fcCol.GetName() : string.Format("{0}_{1}", fcCol.GetName(), entry.FuelType.GetLabel()), typeof(SI)) + { + Caption = string.Format(fcCol.GetCaption(), fuels.Count == 1 ? "" : "_" + entry.FuelType.GetLabel()) + }; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.Decimals] = + fcCol.GetAttribute().Decimals; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.OutputFactor] = + fcCol.GetAttribute().OutputFactor; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.ShowUnit] = + fcCol.GetAttribute().ShowUnit; + FuelColumns[entry][fcCol] = col; + Data.Columns.Add(col); + } + } + _writeEngineOnly = writeEngineOnly; _filters = filters ?? new IModalDataFilter[0]; _addReportResult = addReportResult ?? (x => { }); - Data = new ModalResults(); Auxiliaries = new Dictionary<string, DataColumn>(); CurrentRow = Data.NewRow(); WriteAdvancedAux = false; @@ -121,7 +150,10 @@ namespace TUGraz.VectoCore.OutputData CurrentRow = Data.NewRow(); } - public FuelData.Entry FuelData { get; internal set; } + public IList<FuelData.Entry> FuelData + { + get { return FuelColumns.Keys.ToList(); } + } public void Finish(VectoRun.Status runStatus, Exception exception = null) { @@ -132,11 +164,8 @@ namespace TUGraz.VectoCore.OutputData var strCols = dataColumns.Select(x => x.GetName()) .Concat(Auxiliaries.Values.Select(c => c.ColumnName)) - .Concat( - new[] { - ModalResultField.FCMap, ModalResultField.FCNCVc, ModalResultField.FCWHTCc, - ModalResultField.FCAAUX, ModalResultField.FCADAS, ModalResultField.FCFinal - }.Select(x => x.GetName())); + .Concat(FuelColumns.SelectMany(kv => kv.Value.Select(kv2 => kv2.Value.ColumnName))); + #if TRACE strCols = strCols.Concat(_additionalColumns); #endif @@ -290,14 +319,20 @@ namespace TUGraz.VectoCore.OutputData } public T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T> + { + return TimeIntegral<T>(field.GetName(), filter); + } + + public T TimeIntegral<T>(string field, Func<SI, bool> filter = null) where T : SIBase<T> { var result = 0.0; + var idx = Data.Columns.IndexOf(field); for (var i = 0; i < Data.Rows.Count; i++) { - var value = Data.Rows[i][(int)field]; + var value = Data.Rows[i][idx]; if (value != null && value != DBNull.Value) { var siValue = (SI)value; if (filter == null || filter(siValue)) { - result += siValue.Value() * ((Second)Data.Rows[i][(int)ModalResultField.simulationInterval]).Value(); + result += siValue.Value() * ((Second)Data.Rows[i][ModalResultField.simulationInterval.GetName()]).Value(); } } } @@ -307,13 +342,40 @@ namespace TUGraz.VectoCore.OutputData public IEnumerable<T> GetValues<T>(ModalResultField key) { - return GetValues<T>(Data.Columns[(int)key]); + return GetValues<T>(Data.Columns[key.GetName()]); } public object this[ModalResultField key] { - get { return CurrentRow[(int)key]; } - set { CurrentRow[(int)key] = value; } + get { return CurrentRow[key.GetName()]; } + set { CurrentRow[key.GetName()] = value; } + } + + public string GetColumnName(FuelData.Entry fuelData, ModalResultField mrf) + { + if (!FuelColumns.ContainsKey(fuelData) || !FuelColumns[fuelData].ContainsKey(mrf)) { + throw new VectoException("unknown fuel {0} for key {1}", fuelData.GetLabel(), mrf.GetName()); + } + + return FuelColumns[fuelData][mrf].ColumnName; + } + + public object this[ModalResultField key, FuelData.Entry fuel] + { + get { + if (!FuelColumns.ContainsKey(fuel) || !FuelColumns[fuel].ContainsKey(key)) { + throw new VectoException("unknown fuel {0} for key {1}", fuel.GetLabel(), key.GetName()); + } + + return CurrentRow[FuelColumns[fuel][key]]; + } + set { + if (!FuelColumns.ContainsKey(fuel) || !FuelColumns[fuel].ContainsKey(key)) { + throw new VectoException("unknown fuel {0} for key {1}", fuel.GetLabel(), key.GetName()); + } + + CurrentRow[FuelColumns[fuel][key]] = value; + } } public object this[string auxId] diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index b774f06cdc0851f172bdb0329d0c219c0511ecb0..f40fbde84bd2e1d1c6b913c31a7eba1c3ae238d5 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -123,22 +123,22 @@ namespace TUGraz.VectoCore.OutputData public const string SPEED = "speed [km/h]"; public const string ALTITUDE_DELTA = "altitudeDelta [m]"; - public const string FCMAP_H = "FC-Map [g/h]"; - public const string FCMAP_KM = "FC-Map [g/km]"; - public const string FCNCVC_H = "FC-NCVc [g/h]"; - public const string FCNCVC_KM = "FC-NCVc [g/km]"; - public const string FCWHTCC_H = "FC-WHTCc [g/h]"; - public const string FCWHTCC_KM = "FC-WHTCc [g/km]"; - public const string FCAAUX_H = "FC-AAUX [g/h]"; - public const string FCAAUX_KM = "FC-AAUX [g/km]"; - public const string FCADAS_H = "FC-ADAS [g/h]"; - public const string FCADAS_KM = "FC-ADAS [g/km]"; - - public const string FCFINAL_H = "FC-Final [g/h]"; - public const string FCFINAL_KM = "FC-Final [g/km]"; - public const string FCFINAL_LITERPER100KM = "FC-Final [l/100km]"; - public const string FCFINAL_LITERPER100TKM = "FC-Final [l/100tkm]"; - public const string FCFINAL_LiterPer100M3KM = "FC-Final [l/100m³km]"; + public const string FCMAP_H = "FC-Map{0} [g/h]"; + public const string FCMAP_KM = "FC-Map{0} [g/km]"; + public const string FCNCVC_H = "FC-NCVc{0} [g/h]"; + public const string FCNCVC_KM = "FC-NCVc{0} [g/km]"; + public const string FCWHTCC_H = "FC-WHTCc{0} [g/h]"; + public const string FCWHTCC_KM = "FC-WHTCc{0} [g/km]"; + public const string FCAAUX_H = "FC-AAUX{0} [g/h]"; + public const string FCAAUX_KM = "FC-AAUX{0} [g/km]"; + public const string FCADAS_H = "FC-ADAS{0} [g/h]"; + public const string FCADAS_KM = "FC-ADAS{0} [g/km]"; + + public const string FCFINAL_H = "FC-Final{0} [g/h]"; + public const string FCFINAL_KM = "FC-Final{0} [g/km]"; + public const string FCFINAL_LITERPER100KM = "FC-Final{0} [l/100km]"; + public const string FCFINAL_LITERPER100TKM = "FC-Final{0} [l/100tkm]"; + public const string FCFINAL_LiterPer100M3KM = "FC-Final{0} [l/100m³km]"; public const string CO2_KM = "CO2 [g/km]"; public const string CO2_TKM = "CO2 [g/tkm]"; @@ -237,6 +237,16 @@ namespace TUGraz.VectoCore.OutputData public const string AIRDRAG_CERTIFICATION_NUMBER = "AirDrag certification number"; public const string AIRDRAG_CERTIFICATION_METHOD = "AirDrag certification option"; + protected readonly string[] fcColumns = { + FCMAP_H, FCMAP_KM, + FCNCVC_H, FCNCVC_KM, + FCWHTCC_H, FCWHTCC_KM, + FCAAUX_H, FCAAUX_KM, + FCADAS_H, FCADAS_KM, + FCFINAL_H, FCFINAL_KM, + FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, FCFINAL_LiterPer100M3KM, + }; + // ReSharper restore InconsistentNaming internal readonly DataTable Table; @@ -251,9 +261,12 @@ namespace TUGraz.VectoCore.OutputData public SummaryDataContainer(ISummaryWriter writer) { _sumWriter = writer; - Table = new DataTable(); + InitTableColumns(); + } + private void InitTableColumns() + { Table.Columns.AddRange( new[] { Tuple.Create(SORT, typeof(int)), @@ -275,12 +288,12 @@ namespace TUGraz.VectoCore.OutputData Tuple.Create(ENGINE_IDLING_SPEED, typeof(ConvertedSI)), Tuple.Create(ENGINE_RATED_SPEED, typeof(ConvertedSI)), Tuple.Create(ENGINE_DISPLACEMENT, typeof(ConvertedSI)), - Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)), - Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)), - Tuple.Create(ENGINE_WHTC_MOTORWAY, typeof(double)), - Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)), - Tuple.Create(ENGINE_CF_REG_PER, typeof(double)), - Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)), + Tuple.Create(ENGINE_WHTC_URBAN, typeof(string)), + Tuple.Create(ENGINE_WHTC_RURAL, typeof(string)), + Tuple.Create(ENGINE_WHTC_MOTORWAY, typeof(string)), + Tuple.Create(ENGINE_BF_COLD_HOT, typeof(string)), + Tuple.Create(ENGINE_CF_REG_PER, typeof(string)), + Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(string)), Tuple.Create(VEHICLE_FUEL_TYPE, typeof(string)), Tuple.Create(AIRDRAG_MODEL, typeof(string)), Tuple.Create(CD_x_A_DECLARED, typeof(ConvertedSI)), @@ -334,13 +347,12 @@ namespace TUGraz.VectoCore.OutputData CARGO_VOLUME, TIME, DISTANCE, SPEED, ALTITUDE_DELTA, - FCMAP_H, FCMAP_KM, - FCNCVC_H, FCNCVC_KM, - FCWHTCC_H, FCWHTCC_KM, - FCAAUX_H, FCAAUX_KM, - FCADAS_H, FCADAS_KM, - FCFINAL_H, FCFINAL_KM, - FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, FCFINAL_LiterPer100M3KM, SPECIFIC_FC, + }.Select(x => new DataColumn(x, typeof(ConvertedSI))).ToArray()); + + Table.Columns.AddRange(fcColumns.Select(x => new DataColumn(string.Format(x, ""), typeof(ConvertedSI))).ToArray()); + Table.Columns.AddRange( + new[] { + SPECIFIC_FC, CO2_KM, CO2_TKM, CO2_M3KM, P_WHEEL_POS, P_FCMAP_POS, E_FCMAP_POS, E_FCMAP_NEG, E_POWERTRAIN_INERTIA, @@ -403,12 +415,31 @@ namespace TUGraz.VectoCore.OutputData } } + private void UpdateTableColumns(IList<FuelData.Entry> modDataFuelData) + { + if (modDataFuelData.Count <= 1) { + return; + } + + foreach (var entry in modDataFuelData) { + foreach (var column in fcColumns) { + var colName = string.Format(column, "_"+entry.FuelType.GetLabel()); + if (!Table.Columns.Contains(colName)) { + var col = new DataColumn(colName, typeof(ConvertedSI)); + Table.Columns.Add(col); + col.SetOrdinal(Table.Columns.IndexOf(ALTITUDE_DELTA) + 1); + } + } + } + } + /// <summary> /// Writes the result of one run into the summary data container. /// </summary> [MethodImpl(MethodImplOptions.Synchronized)] public virtual void Write(IModalDataContainer modData, int jobNr, int runNr, VectoRunData runData) { + UpdateTableColumns(modData.FuelData); var row = Table.NewRow(); Table.Rows.Add(row); @@ -430,7 +461,7 @@ namespace TUGraz.VectoCore.OutputData gearCount = (uint)runData.GearboxData.Gears.Count; } - row[VEHICLE_FUEL_TYPE] = modData.FuelData.GetLabel(); + row[VEHICLE_FUEL_TYPE] = string.Join(", ", modData.FuelData.Select(x => x.GetLabel())); var totalTime = modData.Duration(); row[TIME] = (ConvertedSI)totalTime; @@ -481,44 +512,50 @@ namespace TUGraz.VectoCore.OutputData WriteGearshiftStats(modData, row, gearCount); } + + private static void WriteFuelconsumptionEntries( IModalDataContainer modData, DataRow row, Kilogram vehicleLoading, CubicMeter cargoVolume, bool vtpCycle) { - var tmp = modData.FCMapPerSecond(); - row[FCMAP_H] = tmp.ConvertToGrammPerHour(); - var fcMapPerMeter = modData.FCMapPerMeter(); - if (fcMapPerMeter != null) { - row[FCMAP_KM] = fcMapPerMeter.ConvertToGrammPerKiloMeter(); - } + foreach (var entry in modData.FuelData) { + var suffix = modData.FuelData.Count <= 1 ? "" : "_" + entry.FuelType.GetLabel(); + + var tmp = modData.FCMapPerSecond(entry); + row[FcCol(FCMAP_H, suffix)] = tmp.ConvertToGrammPerHour(); + var fcMapPerMeter = modData.FCMapPerMeter(entry); + if (fcMapPerMeter != null) { + row[FcCol(FCMAP_KM, suffix)] = fcMapPerMeter.ConvertToGrammPerKiloMeter(); + } - row[FCNCVC_H] = modData.FuelConsumptionNCVCorrectedPerSecond().ConvertToGrammPerHour(); - var fuelConsumptionAuxStartStopCorrected = modData.FuelConsumptionNCVCorrected(); - row[FCNCVC_KM] = fuelConsumptionAuxStartStopCorrected.ConvertToGrammPerKiloMeter(); + row[FcCol(FCNCVC_H, suffix)] = modData.FuelConsumptionNCVCorrectedPerSecond(entry).ConvertToGrammPerHour(); + var fuelConsumptionAuxStartStopCorrected = modData.FuelConsumptionNCVCorrected(entry); + row[FcCol(FCNCVC_KM, suffix)] = fuelConsumptionAuxStartStopCorrected.ConvertToGrammPerKiloMeter(); - row[FCWHTCC_H] = modData.FuelConsumptionWHTCPerSecond().ConvertToGrammPerHour(); - var fuelConsumptionWHTCCorrected = modData.FuelConsumptionWHTC(); - row[FCWHTCC_KM] = fuelConsumptionWHTCCorrected.ConvertToGrammPerKiloMeter(); + row[FcCol(FCWHTCC_H, suffix)] = modData.FuelConsumptionWHTCPerSecond(entry).ConvertToGrammPerHour(); + var fuelConsumptionWHTCCorrected = modData.FuelConsumptionWHTC(entry); + row[FcCol(FCWHTCC_KM, suffix)] = fuelConsumptionWHTCCorrected.ConvertToGrammPerKiloMeter(); - row[FCAAUX_H] = modData.FuelConsumptionAAUXPerSecond().ConvertToGrammPerHour(); - var fuelConsumptionAaux = modData.FuelConsumptionAAUX(); - row[FCAAUX_KM] = fuelConsumptionAaux.ConvertToGrammPerKiloMeter(); + row[FcCol(FCAAUX_H, suffix)] = modData.FuelConsumptionAAUXPerSecond(entry).ConvertToGrammPerHour(); + var fuelConsumptionAaux = modData.FuelConsumptionAAUX(entry); + row[FcCol(FCAAUX_KM, suffix)] = fuelConsumptionAaux.ConvertToGrammPerKiloMeter(); - row[FCADAS_H] = modData.FuelConsumptionADASPerSecond().ConvertToGrammPerHour(); - var fuelConsumptionAdas = modData.FuelConsumptionADAS(); - row[FCADAS_KM] = fuelConsumptionAdas.ConvertToGrammPerKiloMeter(); + row[FcCol(FCADAS_H, suffix)] = modData.FuelConsumptionADASPerSecond(entry).ConvertToGrammPerHour(); + var fuelConsumptionAdas = modData.FuelConsumptionADAS(entry); + row[FcCol(FCADAS_KM, suffix)] = fuelConsumptionAdas.ConvertToGrammPerKiloMeter(); - row[FCFINAL_H] = modData.FuelConsumptionFinalPerSecond().ConvertToGrammPerHour(); - var fcfinal = modData.FuelConsumptionFinal(); - row[FCFINAL_KM] = fcfinal.ConvertToGrammPerKiloMeter(); + row[FcCol(FCFINAL_H, suffix)] = modData.FuelConsumptionFinalPerSecond(entry).ConvertToGrammPerHour(); + var fcfinal = modData.FuelConsumptionFinal(entry); + row[FcCol(FCFINAL_KM, suffix)] = fcfinal.ConvertToGrammPerKiloMeter(); - var fcFinal = modData.FuelConsumptionFinalVolumePerMeter(); - row[FCFINAL_LITERPER100KM] = fcFinal.ConvertToLiterPer100Kilometer(); - if (vehicleLoading != null && !vehicleLoading.IsEqual(0) && fcFinal != null) { - row[FCFINAL_LITERPER100TKM] = (fcFinal / vehicleLoading).ConvertToLiterPer100TonKiloMeter(); - } - if (cargoVolume > 0 && fcFinal != null) { - row[FCFINAL_LiterPer100M3KM] = (fcFinal / cargoVolume).ConvertToLiterPerCubicMeter100KiloMeter(); + var fcFinal = modData.FuelConsumptionFinalVolumePerMeter(entry); + row[FcCol(FCFINAL_LITERPER100KM, suffix)] = fcFinal.ConvertToLiterPer100Kilometer(); + if (vehicleLoading != null && !vehicleLoading.IsEqual(0) && fcFinal != null) { + row[FcCol(FCFINAL_LITERPER100TKM, suffix)] = (fcFinal / vehicleLoading).ConvertToLiterPer100TonKiloMeter(); + } + if (cargoVolume > 0 && fcFinal != null) { + row[FcCol(FCFINAL_LiterPer100M3KM, suffix)] = (fcFinal / cargoVolume).ConvertToLiterPerCubicMeter100KiloMeter(); + } } if (vtpCycle) { @@ -527,6 +564,10 @@ namespace TUGraz.VectoCore.OutputData } } + private static string FcCol(string col, string suffix) + { + return string.Format(col, suffix); + } private void WriteAuxiliaries(IModalDataContainer modData, DataRow row) { @@ -593,7 +634,10 @@ namespace TUGraz.VectoCore.OutputData } } - var eFC = modData.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * modData.FuelData.LowerHeatingValueVecto; + var eFC = 0.SI<Joule>(); + foreach (var fuel in modData.FuelData) { + eFC += modData.TimeIntegral<Kilogram>(modData.GetColumnName(fuel, ModalResultField.FCFinal)) * fuel.LowerHeatingValueVecto; + } var eIcePos = modData.TimeIntegral<WattSecond>(ModalResultField.P_eng_fcmap, x => x > 0); row[AVERAGE_ENGINE_EFFICIENCY] = eFC.IsEqual(0, 1e-9) ? 0 : (eIcePos / eFC).Value(); @@ -615,10 +659,10 @@ namespace TUGraz.VectoCore.OutputData var tcData = modData.GetValues( x => new { - dt = x.Field<Second>((int)ModalResultField.simulationInterval), - locked = x.Field<int>((int)ModalResultField.TC_Locked), - P_TCin = x.Field<Watt>((int)ModalResultField.P_TC_in), - P_TCout = x.Field<Watt>((int)ModalResultField.P_TC_out) + dt = x.Field<Second>(ModalResultField.simulationInterval.GetName()), + locked = x.Field<int>(ModalResultField.TC_Locked.GetName()), + P_TCin = x.Field<Watt>(ModalResultField.P_TC_in.GetName()), + P_TCout = x.Field<Watt>(ModalResultField.P_TC_out.GetName()) }); eTcIn = 0.SI<WattSecond>(); eTcOut = 0.SI<WattSecond>(); @@ -730,7 +774,7 @@ namespace TUGraz.VectoCore.OutputData row[ENGINE_MANUFACTURER] = data.Manufacturer; row[ENGINE_MODEL] = data.ModelName; row[ENGINE_CERTIFICATION_NUMBER] = data.CertificationNumber; - row[ENGINE_FUEL_TYPE] = data.FuelData.GetLabel(); + row[ENGINE_FUEL_TYPE] = string.Join(" / ", data.Fuels.Select(x => x.FuelData.GetLabel())); row[ENGINE_RATED_POWER] = data.RatedPowerDeclared != null && data.RatedPowerDeclared > 0 ? data.RatedPowerDeclared.ConvertToKiloWatt() : data.FullLoadCurves[0].MaxPower.ConvertToKiloWatt(); @@ -740,12 +784,12 @@ namespace TUGraz.VectoCore.OutputData : (ConvertedSI)data.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>(); row[ENGINE_DISPLACEMENT] = data.Displacement.ConvertToCubicCentiMeter(); - row[ENGINE_WHTC_URBAN] = data.WHTCUrban; - row[ENGINE_WHTC_RURAL] = data.WHTCRural; - row[ENGINE_WHTC_MOTORWAY] = data.WHTCMotorway; - row[ENGINE_BF_COLD_HOT] = data.ColdHotCorrectionFactor; - row[ENGINE_CF_REG_PER] = data.CorrectionFactorRegPer; - row[ENGINE_ACTUAL_CORRECTION_FACTOR] = data.FuelConsumptionCorrectionFactor; + row[ENGINE_WHTC_URBAN] = string.Join(" / ", data.Fuels.Select(x => x.WHTCUrban)); + row[ENGINE_WHTC_RURAL] = string.Join(" / ", data.Fuels.Select(x => x.WHTCRural)); + row[ENGINE_WHTC_MOTORWAY] = string.Join(" / ", data.Fuels.Select(x => x.WHTCMotorway)); + row[ENGINE_BF_COLD_HOT] = string.Join(" / ", data.Fuels.Select(x => x.ColdHotCorrectionFactor)); + row[ENGINE_CF_REG_PER] = string.Join(" / ", data.Fuels.Select(x => x.CorrectionFactorRegPer)); + row[ENGINE_ACTUAL_CORRECTION_FACTOR] = string.Join(" / ", data.Fuels.Select(x => x.FuelConsumptionCorrectionFactor)); } private static void WriteAxleWheelsData(List<Axle> data, DataRow row) diff --git a/VectoCore/VectoCore/OutputData/XML/Engineering/Writer/XMLEngineeringEngineWriter.cs b/VectoCore/VectoCore/OutputData/XML/Engineering/Writer/XMLEngineeringEngineWriter.cs index 29b1036355a69525039d24208a31d1e91049e488..14c2a807d012b96c3ebb64f4a93ff595823b132f 100644 --- a/VectoCore/VectoCore/OutputData/XML/Engineering/Writer/XMLEngineeringEngineWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/Engineering/Writer/XMLEngineeringEngineWriter.cs @@ -1,4 +1,5 @@ using System.IO; +using System.Linq; using System.Xml.Linq; using TUGraz.IVT.VectoXML; using TUGraz.VectoCommon.InputData; @@ -28,10 +29,10 @@ namespace TUGraz.VectoCore.OutputData.XML.Engineering.Writer GetXMLTypeAttribute(), GetDefaultComponentElements(data), new XElement(ns + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), - new XElement(ns + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(ns + XMLNames.Engine_IdlingSpeed, data.EngineModes.First().IdleSpeed.AsRPM.ToXMLFormat(0)), data.Inertia != null ? new XElement(ns + XMLNames.Engine_Inertia, data.Inertia.Value()) : null, new XElement(ns + XMLNames.Engine_FCCorrection, data.WHTCEngineering.ToXMLFormat(4)), - new XElement(ns + XMLNames.Engine_FuelType, data.FuelType.ToXMLFormat()), + new XElement(ns + XMLNames.Engine_FuelType, data.EngineModes.First().Fuels.First().FuelType.ToXMLFormat()), new XElement(ns + XMLNames.Engine_FuelConsumptionMap, GetFuelConsumptionMap(ns, data)), new XElement(ns + XMLNames.Engine_FullLoadAndDragCurve, GetFullLoadDragCurve(ns, data)) }; @@ -42,23 +43,23 @@ namespace TUGraz.VectoCore.OutputData.XML.Engineering.Writer protected virtual object[] GetFullLoadDragCurve(XNamespace ns, IEngineEngineeringInputData data) { if (Writer.Configuration.SingleFile) { - return EmbedDataTable(data.FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping); + return EmbedDataTable(data.EngineModes.First().FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping); } var filename = Path.Combine( Writer.Configuration.BasePath, Writer.RemoveInvalidFileCharacters(string.Format("ENG_{0}.vfld", data.Model))); - return ExtCSVResource(data.FullLoadCurve, filename); + return ExtCSVResource(data.EngineModes.First().FullLoadCurve, filename); } protected virtual object[] GetFuelConsumptionMap(XNamespace ns, IEngineEngineeringInputData data) { if (Writer.Configuration.SingleFile) { - return EmbedDataTable(data.FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping); + return EmbedDataTable(data.EngineModes.First().Fuels.First().FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping); } var filename = Path.Combine( Writer.Configuration.BasePath, Writer.RemoveInvalidFileCharacters(string.Format("ENG_{0}.vmap", data.Model))); - return ExtCSVResource(data.FuelConsumptionMap, filename); + return ExtCSVResource(data.EngineModes.First().Fuels.First().FuelConsumptionMap, filename); } #region Overrides of AbstractXMLWriter @@ -83,10 +84,10 @@ namespace TUGraz.VectoCore.OutputData.XML.Engineering.Writer GetXMLTypeAttribute(), GetDefaultComponentElements(data), new XElement(v10 + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), - new XElement(v10 + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(v10 + XMLNames.Engine_IdlingSpeed, data.EngineModes.First().IdleSpeed.AsRPM.ToXMLFormat(0)), data.Inertia != null ? new XElement(v10 + XMLNames.Engine_Inertia, data.Inertia.Value()) : null, new XElement(v10 + XMLNames.Engine_FCCorrection, data.WHTCEngineering.ToXMLFormat(4)), - new XElement(v10 + XMLNames.Engine_FuelType, data.FuelType.ToXMLFormat()), + new XElement(v10 + XMLNames.Engine_FuelType, data.EngineModes.First().Fuels.First().FuelType.ToXMLFormat()), new XElement(v10 + XMLNames.Engine_FuelConsumptionMap, GetFuelConsumptionMap(v10, data)), new XElement(v10 + XMLNames.Engine_FullLoadAndDragCurve, GetFullLoadDragCurve(v10, data)), new XElement(v11 + XMLNames.Engine_RatedPower, data.RatedPowerDeclared?.Value().ToXMLFormat(0) ?? "xxx kW"), diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs index b2b00935e63b03369da9ac2139a051fc2b2cf3b3..fc46098dd4095cb51a08679510415704da6614fd 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs @@ -52,7 +52,7 @@ namespace TUGraz.VectoCore.OutputData.XML { public class XMLCustomerReport { - public const string CURRENT_SCHEMA_VERSION = "0.7"; + public const string CURRENT_SCHEMA_VERSION = "0.8"; protected readonly XElement VehiclePart; @@ -78,7 +78,7 @@ namespace TUGraz.VectoCore.OutputData.XML Results = new XElement(tns + XMLNames.Report_Results); } - public void Initialize(VectoRunData modelData) + public void Initialize(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { var exempted = modelData.Exempted; VehiclePart.Add( @@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Vehicle_VocationalVehicle, modelData.VehicleData.VocationalVehicle), new XElement(tns + XMLNames.Vehicle_SleeperCab, modelData.VehicleData.SleeperCab), GetADAS(modelData.VehicleData.ADAS) - }.Concat(ComponentData(modelData)) + }.Concat(ComponentData(modelData, fuelModes)) ); if (exempted) { Results.Add(new XElement(tns + XMLNames.Report_ExemptedVehicle)); @@ -126,7 +126,7 @@ namespace TUGraz.VectoCore.OutputData.XML ); } - private XElement[] ComponentData(VectoRunData modelData) + private XElement[] ComponentData(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { return new[] { new XElement( @@ -135,7 +135,9 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement( tns + XMLNames.Report_Vehicle_EngineDisplacement, XMLHelper.ValueAsUnit(modelData.EngineData.Displacement, XMLNames.Unit_ltr, 1)), - new XElement(tns + XMLNames.Engine_FuelType, modelData.EngineData.FuelData.FuelType.ToXMLFormat()), + new XElement(tns + XMLNames.Report_Vehicle_FuelTypes, + fuelModes.SelectMany(x => x.Select(f => f.FuelType.ToXMLFormat())).Distinct().Select(x => new XElement(tns + XMLNames.Engine_FuelType, x)) + ), new XElement( tns + XMLNames.Report_Vehicle_TransmissionCertificationMethod, modelData.GearboxData.CertificationMethod.ToXMLFormat()), @@ -198,7 +200,7 @@ namespace TUGraz.VectoCore.OutputData.XML { return new object[] { new XElement(tns + XMLNames.Report_Result_Payload, XMLHelper.ValueAsUnit(result.Payload, XMLNames.Unit_kg, 0)), - new XElement(tns + XMLNames.Report_Results_FuelType, XMLHelper.ToXmlStr(result.FuelData)), + new XElement(tns + XMLNames.Report_Result_FuelMode, result.FuelData.Count > 1 ? XMLNames.Report_Result_FuelMode_Val_Dual : XMLNames.Report_Result_FuelMode_Val_Single), new XElement(tns + XMLNames.Report_Results_AverageSpeed, XMLHelper.ValueAsUnit(result.AverageSpeed, XMLNames.Unit_kmph, 1)), XMLDeclarationReport.GetResults(result, tns, false).Cast<object>().ToArray() }; diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index 09376d879bc36075ecfd60fc6db358169b77806c..a2e8ad3e2854c15772c42573d60567f356e6f180 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -74,7 +74,7 @@ namespace TUGraz.VectoCore.OutputData.XML public Kilogram CO2Total { get; private set; } - public Kilogram FuelConsumptionTotal { get; private set; } + public Dictionary<FuelType, Kilogram> FuelConsumptionTotal { get; private set; } public Meter Distance { get; private set; } @@ -96,7 +96,7 @@ namespace TUGraz.VectoCore.OutputData.XML public string StackTrace { get; private set; } - public FuelData.Entry FuelData { get; private set; } + public IList<FuelData.Entry> FuelData { get; private set; } public Kilogram Payload { get; private set; } @@ -136,9 +136,9 @@ namespace TUGraz.VectoCore.OutputData.XML var entriesDriving = data.GetValues( r => new { - dt = r.Field<Second>((int)ModalResultField.simulationInterval), - v = r.Field<MeterPerSecond>((int)ModalResultField.v_act), - nEng = r.Field<PerSecond>((int)ModalResultField.n_eng_avg) + dt = r.Field<Second>(ModalResultField.simulationInterval.GetName()), + v = r.Field<MeterPerSecond>(ModalResultField.v_act.GetName()), + nEng = r.Field<PerSecond>(ModalResultField.n_eng_avg.GetName()) }).Where(x => x.v.IsGreater(0)).ToArray(); var drivingTime = entriesDriving.Sum(x => x.dt); @@ -148,9 +148,16 @@ namespace TUGraz.VectoCore.OutputData.XML EngineSpeedDrivingMax = entriesDriving.Max(x => x.nEng); Distance = data.Distance(); - FuelConsumptionTotal = data.TimeIntegral<Kilogram>(ModalResultField.FCFinal); - CO2Total = FuelConsumptionTotal * data.FuelData.CO2PerFuelWeight; - EnergyConsumptionTotal = FuelConsumptionTotal * data.FuelData.LowerHeatingValueVecto; + FuelConsumptionTotal = new Dictionary<FuelType, Kilogram>(); + CO2Total = 0.SI<Kilogram>(); + EnergyConsumptionTotal = 0.SI<Joule>(); + foreach (var entry in FuelData) { + var col = data.GetColumnName(entry, ModalResultField.FCFinal); + var fcFinal = data.TimeIntegral<Kilogram>(col); + FuelConsumptionTotal[entry.FuelType] = fcFinal; + CO2Total += fcFinal * entry.CO2PerFuelWeight; + EnergyConsumptionTotal += fcFinal * entry.LowerHeatingValueVecto; + } var gbxOutSignal = runData.Retarder.Type == RetarderType.TransmissionOutputRetarder ? ModalResultField.P_retarder_in @@ -220,7 +227,7 @@ namespace TUGraz.VectoCore.OutputData.XML } - public override void InitializeReport(VectoRunData modelData) + public override void InitializeReport(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { var weightingGroup = modelData.Exempted ? WeightingGroup.Unknown @@ -230,8 +237,8 @@ namespace TUGraz.VectoCore.OutputData.XML _weightingFactors = weightingGroup == WeightingGroup.Unknown ? ZeroWeighting : DeclarationData.WeightingFactors.Lookup(weightingGroup); - _manufacturerReport.Initialize(modelData); - _customerReport.Initialize(modelData); + _manufacturerReport.Initialize(modelData, fuelModes); + _customerReport.Initialize(modelData, fuelModes); _monitoringReport.Initialize(modelData); } @@ -261,69 +268,83 @@ namespace TUGraz.VectoCore.OutputData.XML public static IEnumerable<XElement> GetResults(ResultEntry result, XNamespace tns, bool fullOutput) { - var fuel = result.FuelData; - var retVal = new List<XElement> { - new XElement( - tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/km"), - (result.FuelConsumptionTotal / result.Distance).ConvertToGrammPerKiloMeter().ToMinSignificantDigits(3, 1)), - new XElement( - tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/t-km"), - (result.FuelConsumptionTotal / result.Distance / result.Payload) - .ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 1)), - result.CargoVolume > 0 - ? new XElement( - tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/m³-km"), - (result.FuelConsumptionTotal.ConvertToGramm() / result.Distance.ConvertToKiloMeter() / result.CargoVolume) - .Value - ().ToMinSignificantDigits(3, 1)) - : null - }; - - //FC - if (fullOutput) { - retVal.Add( + //var fuel = result.FuelData; + var retVal = new List<XElement>(); + + foreach (var fuel in result.FuelData) { + var fcResult = new XElement(tns + XMLNames.Report_Results_Fuel, new XAttribute(XMLNames.Report_Results_Fuel_Type_Attr, fuel.FuelType.ToXMLFormat())); + fcResult.Add( new XElement( tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/km"), - (result.EnergyConsumptionTotal / result.Distance.ConvertToKiloMeter() / 1e6) - .Value().ToMinSignificantDigits(3, 1))); - retVal.Add( + new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/km"), + (result.FuelConsumptionTotal[fuel.FuelType] / result.Distance) + .ConvertToGrammPerKiloMeter().ToMinSignificantDigits(3, 1)), new XElement( tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/t-km"), - (result.EnergyConsumptionTotal / result.Distance.ConvertToKiloMeter() / result.Payload.ConvertToTon() / 1e6) - .Value().ToMinSignificantDigits(3, 1))); - if (result.CargoVolume > 0) - retVal.Add( + new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/t-km"), + (result.FuelConsumptionTotal[fuel.FuelType] / result.Distance / result.Payload) + .ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 1)), + result.CargoVolume > 0 + ? new XElement( + tns + XMLNames.Report_Results_FuelConsumption, + new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/m³-km"), + (result.FuelConsumptionTotal[fuel.FuelType].ConvertToGramm() / result.Distance.ConvertToKiloMeter() / + result.CargoVolume) + .Value + ().ToMinSignificantDigits(3, 1)) + : null + ); + + //FC + // TODO: MQ 2019-07-31 - per fuel or overall? + if (fullOutput) { + fcResult.Add( new XElement( tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/m³-km"), - (result.EnergyConsumptionTotal / result.Distance.ConvertToKiloMeter() / result.CargoVolume / 1e6).Value() - .ToMinSignificantDigits(3, 1))); - } - if (fuel.FuelDensity != null) { - retVal.Add( - new XElement( - tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "l/100km"), - (result.FuelConsumptionTotal.ConvertToGramm() / fuel.FuelDensity / result.Distance.ConvertToKiloMeter() * 100) - .Value().ToMinSignificantDigits(3, 1))); - retVal.Add( - new XElement( - tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "l/t-km"), - (result.FuelConsumptionTotal.ConvertToGramm() / fuel.FuelDensity / result.Distance.ConvertToKiloMeter() / - result.Payload.ConvertToTon()).Value().ToMinSignificantDigits(3, 1))); - if (result.CargoVolume > 0) - retVal.Add( + new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/km"), + (result.FuelConsumptionTotal[fuel.FuelType] * fuel.LowerHeatingValueVecto / + result.Distance.ConvertToKiloMeter() / 1e6) + .Value().ToMinSignificantDigits(3, 1)), + new XElement( + tns + XMLNames.Report_Results_FuelConsumption, + new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/t-km"), + (result.FuelConsumptionTotal[fuel.FuelType] * fuel.LowerHeatingValueVecto / + result.Distance.ConvertToKiloMeter() / result.Payload.ConvertToTon() / 1e6) + .Value().ToMinSignificantDigits(3, 1))); + if (result.CargoVolume > 0) { + fcResult.Add( + new XElement( + tns + XMLNames.Report_Results_FuelConsumption, + new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/m³-km"), + (result.FuelConsumptionTotal[fuel.FuelType] * fuel.LowerHeatingValueVecto / + result.Distance.ConvertToKiloMeter() / result.CargoVolume / 1e6).Value().ToMinSignificantDigits(3, 1))); + } + } + if (fuel.FuelDensity != null) { + fcResult.Add( + new XElement( + tns + XMLNames.Report_Results_FuelConsumption, + new XAttribute(XMLNames.Report_Results_Unit_Attr, "l/100km"), + (result.FuelConsumptionTotal[fuel.FuelType].ConvertToGramm() / fuel.FuelDensity / + result.Distance.ConvertToKiloMeter() * 100) + .Value().ToMinSignificantDigits(3, 1)), new XElement( tns + XMLNames.Report_Results_FuelConsumption, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "l/m³-km"), - (result.FuelConsumptionTotal.ConvertToGramm() / fuel.FuelDensity / result.Distance.ConvertToKiloMeter() / - result.CargoVolume).Value().ToMinSignificantDigits(3, 1))); + new XAttribute(XMLNames.Report_Results_Unit_Attr, "l/t-km"), + (result.FuelConsumptionTotal[fuel.FuelType].ConvertToGramm() / fuel.FuelDensity / + result.Distance.ConvertToKiloMeter() / + result.Payload.ConvertToTon()).Value().ToMinSignificantDigits(3, 1))); + if (result.CargoVolume > 0) { + fcResult.Add( + new XElement( + tns + XMLNames.Report_Results_FuelConsumption, + new XAttribute(XMLNames.Report_Results_Unit_Attr, "l/m³-km"), + (result.FuelConsumptionTotal[fuel.FuelType].ConvertToGramm() / fuel.FuelDensity / + result.Distance.ConvertToKiloMeter() / + result.CargoVolume).Value().ToMinSignificantDigits(3, 1))); + } + } + retVal.Add(fcResult); } //CO2 diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs index 58f638a3bce93174894a51592542d189ef5685de..a56c939da744bfcd6b175abb2e3253582d14d810 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationWriter.cs @@ -138,7 +138,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Vehicle_IdlingSpeed, vehicle.EngineIdleSpeed != null ? vehicle.EngineIdleSpeed.AsRPM.ToXMLFormat(0) - : engine.IdleSpeed.AsRPM.ToXMLFormat(0)), + : engine.EngineModes.First().IdleSpeed.AsRPM.ToXMLFormat(0)), new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), retarder.Type.IsDedicatedComponent() ? new XElement(tns + XMLNames.Vehicle_RetarderRatio, retarder.Ratio.ToXMLFormat(3)) @@ -174,27 +174,27 @@ namespace TUGraz.VectoCore.OutputData.XML { var id = CreateIdString(string.Format("ENG-{0}", data.Model.RemoveWhitespace())); - var fld = FullLoadCurveReader.Create(data.FullLoadCurve, true); + var fld = FullLoadCurveReader.Create(data.EngineModes.First().FullLoadCurve, true); return new XElement((ns ?? tns) + XMLNames.Component_Engine, new XElement(tns + XMLNames.ComponentDataWrapper, new XAttribute(XMLNames.Component_ID_Attr, id), GetDefaultComponentElements(string.Format("ENG-{0}", data.Model), data.Model), new XElement(tns + XMLNames.Engine_Displacement, (data.Displacement.Value() * 1000 * 1000).ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_IdlingSpeed, data.IdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_IdlingSpeed, data.EngineModes.First().IdleSpeed.AsRPM.ToXMLFormat(0)), new XElement(tns + XMLNames.Engine_RatedSpeed, fld.RatedSpeed.AsRPM.ToXMLFormat(0)), new XElement(tns + XMLNames.Engine_RatedPower, fld.FullLoadStationaryPower(fld.RatedSpeed).ToXMLFormat(0)), new XElement(tns + XMLNames.Engine_MaxTorque, fld.MaxTorque.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_WHTCUrban, data.WHTCUrban.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_WHTCRural, data.WHTCRural.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_WHTCMotorway, data.WHTCMotorway.ToXMLFormat(4)), - new XElement(tns + XMLNames.Engine_ColdHotBalancingFactor, data.ColdHotBalancingFactor.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_WHTCUrban, data.EngineModes.First().Fuels.First().WHTCUrban.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_WHTCRural, data.EngineModes.First().Fuels.First().WHTCRural.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_WHTCMotorway, data.EngineModes.First().Fuels.First().WHTCMotorway.ToXMLFormat(4)), + new XElement(tns + XMLNames.Engine_ColdHotBalancingFactor, data.EngineModes.First().Fuels.First().ColdHotBalancingFactor.ToXMLFormat(4)), new XElement(tns + XMLNames.Engine_CorrectionFactor_RegPer, "1.0000"), new XElement(tns + XMLNames.Engine_CorrecionFactor_NCV, "1.0000"), new XElement(tns + XMLNames.Engine_FuelType, "Diesel CI"), new XElement(tns + XMLNames.Engine_FuelConsumptionMap, - EmbedDataTable(data.FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping)), + EmbedDataTable(data.EngineModes.First().Fuels.First().FuelConsumptionMap, AttributeMappings.FuelConsumptionMapMapping)), new XElement(tns + XMLNames.Engine_FullLoadAndDragCurve, - EmbedDataTable(data.FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping) + EmbedDataTable(data.EngineModes.First().FullLoadCurve, AttributeMappings.EngineFullLoadCurveMapping) ) ), AddSignatureDummy(id) diff --git a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs index 59cad7f46a28d1e64b1270abceef73cd20a52e35..edfa7e66f1e2ca3ae5cc3a0b0da65f23d429db58 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs @@ -53,7 +53,7 @@ namespace TUGraz.VectoCore.OutputData.XML { public class XMLManufacturerReport { - public const string CURRENT_SCHEMA_VERSION = "0.7"; + public const string CURRENT_SCHEMA_VERSION = "0.8"; protected XElement VehiclePart; @@ -74,7 +74,7 @@ namespace TUGraz.VectoCore.OutputData.XML Results = new XElement(tns + XMLNames.Report_Results); } - public void Initialize(VectoRunData modelData) + public void Initialize(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { var exempted = modelData.Exempted; VehiclePart.Add( @@ -98,7 +98,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Vehicle_PTO, modelData.PTO != null), GetADAS(modelData.VehicleData.ADAS), GetTorqueLimits(modelData.EngineData), - VehicleComponents(modelData) + VehicleComponents(modelData, fuelModes) } ); if (exempted) { @@ -118,10 +118,10 @@ namespace TUGraz.VectoCore.OutputData.XML ); } - private XElement VehicleComponents(VectoRunData modelData) + private XElement VehicleComponents(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { return new XElement(tns + XMLNames.Vehicle_Components, - GetEngineDescription(modelData.EngineData), + GetEngineDescription(modelData.EngineData, fuelModes), GetGearboxDescription(modelData.GearboxData), GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData), GetRetarderDescription(modelData.Retarder), @@ -175,15 +175,15 @@ namespace TUGraz.VectoCore.OutputData.XML : new XElement(tns + XMLNames.Vehicle_TorqueLimits, limits.Cast<object>().ToArray()); } - private XElement GetEngineDescription(CombustionEngineData engineData) + private XElement GetEngineDescription(CombustionEngineData engineData, List<List<FuelData.Entry>> fuelModes) { return new XElement(tns + XMLNames.Component_Engine, GetCommonDescription(engineData), new XElement(tns + XMLNames.Engine_RatedPower, XMLHelper.ValueAsUnit(engineData.RatedPowerDeclared, XMLNames.Unit_kW)), new XElement(tns + XMLNames.Engine_IdlingSpeed, XMLHelper.ValueAsUnit(engineData.IdleSpeed, XMLNames.Unit_RPM)), new XElement(tns + XMLNames.Engine_RatedSpeed, XMLHelper.ValueAsUnit(engineData.RatedSpeedDeclared, XMLNames.Unit_RPM)), - new XElement(tns + XMLNames.Engine_Displacement, XMLHelper.ValueAsUnit(engineData.Displacement, XMLNames.Unit_ltr, 1)), - new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelData.FuelType.ToXMLFormat()) + new XElement(tns + XMLNames.Engine_Displacement, XMLHelper.ValueAsUnit(engineData.Displacement, XMLNames.Unit_ltr, 1)), + fuelModes.Select(x => new XElement(tns + XMLNames.Report_Engine_FuelMode, x.Select(f => new XElement(tns + XMLNames.Engine_FuelType, f.FuelType.ToXMLFormat())))) ); } @@ -356,7 +356,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Report_ResultEntry_SimulationParameters, new XElement(tns + XMLNames.Report_ResultEntry_TotalVehicleMass, XMLHelper.ValueAsUnit(result.TotalVehicleWeight, XMLNames.Unit_kg)), new XElement(tns + XMLNames.Report_ResultEntry_Payload, XMLHelper.ValueAsUnit(result.Payload, XMLNames.Unit_kg)), - new XElement(tns + XMLNames.Report_ResultEntry_FuelType, XMLHelper.ToXmlStr(result.FuelData)) + new XElement(tns + XMLNames.Report_Result_FuelMode, result.FuelData.Count > 1 ? XMLNames.Report_Result_FuelMode_Val_Dual : XMLNames.Report_Result_FuelMode_Val_Single) ), new XElement(tns + XMLNames.Report_ResultEntry_VehiclePerformance, new XElement(tns + XMLNames.Report_ResultEntry_AverageSpeed, XMLHelper.ValueAsUnit(result.AverageSpeed, XMLNames.Unit_kmph, 1)), diff --git a/VectoCore/VectoCore/OutputData/XML/XMLMonitoringReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLMonitoringReport.cs index 4cc3fa9119c268386837041e876192244dda6fbe..edd37c2539bdc8436a82f8252165edebe8e350b3 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLMonitoringReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLMonitoringReport.cs @@ -31,7 +31,9 @@ using System; using System.Linq; +using System.Xml; using System.Xml.Linq; +using System.Xml.Schema; using System.Xml.XPath; using TUGraz.IVT.VectoXML.Writer; using TUGraz.VectoCommon.Models; @@ -39,14 +41,17 @@ using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Utils; +using XmlDocumentType = TUGraz.VectoCore.Utils.XmlDocumentType; namespace TUGraz.VectoCore.OutputData.XML { public class XMLMonitoringReport { - public const string CURRENT_SCHEMA_VERSION = "0.7"; + public const string CURRENT_SCHEMA_VERSION = "0.8"; - private XMLManufacturerReport _manufacturerReport; + public const string NAMESPACE_BASE_URI = "urn:tugraz:ivt:VectoAPI:MonitoringOutput"; + + private readonly XMLManufacturerReport _manufacturerReport; protected XNamespace tns; protected XNamespace di; @@ -56,7 +61,7 @@ namespace TUGraz.VectoCore.OutputData.XML public XMLMonitoringReport(XMLManufacturerReport manufacturerReport) { di = "http://www.w3.org/2000/09/xmldsig#"; - tns = "urn:tugraz:ivt:VectoAPI:MonitoringOutput:v" + CURRENT_SCHEMA_VERSION; + tns = NAMESPACE_BASE_URI + ":v" + CURRENT_SCHEMA_VERSION; _manufacturerReport = manufacturerReport; } @@ -68,11 +73,30 @@ namespace TUGraz.VectoCore.OutputData.XML return null; } + + bool mrfErrors = false; + mrf.Validate(XMLValidator.GetXMLSchema(XmlDocumentType.ManufacturerReport), (o, e) => mrfErrors = true, true); + if (mrfErrors) { + return null; + } + + var mrfType = GetXMLType(mrf.Root); + if (mrfType == null) { + return null; + } + var retVal = GenerateReport(); + var prefix = "mrf" + mrfType.Namespace.Split(':').Last(); + + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); retVal.Root?.Add( + new XAttribute(XNamespace.Xmlns + prefix, mrfType.Namespace), new XElement( tns + "ManufacturerRecord", + new XAttribute(xsi + "type", string.Format("{0}:{1}", prefix, mrfType.Name)), + new XAttribute("xmlns", mrfType.Namespace), + new XAttribute(XNamespace.Xmlns + "m", tns), GetManufacturerData(mrf)), _additionalFields ); @@ -80,7 +104,14 @@ namespace TUGraz.VectoCore.OutputData.XML } } - + private XmlQualifiedName GetXMLType(XElement mrfRoot) + { + var si = mrfRoot.GetSchemaInfo(); + + return si?.SchemaType?.BaseXmlSchemaType.QualifiedName; + } + + private object[] GetManufacturerData(XDocument mrf) { return mrf.Root?.XPathSelectElements("./*").ToArray<object>(); @@ -104,7 +135,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XAttribute( xsi + "schemaLocation", string.Format( - "{0} {1}VectoMonitoring.{2}.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl, CURRENT_SCHEMA_VERSION)) + "{0} {1}VectoMonitoring.xsd", NAMESPACE_BASE_URI, AbstractXMLWriter.SchemaLocationBaseUrl)) ) ); return retVal; diff --git a/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs index febcbe21c2329b6445bc5be30e9170f1663cb932..c357bb0c180869e9ff205c858bcbd8dc5dea4d45 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs @@ -189,7 +189,8 @@ namespace TUGraz.VectoCore.OutputData.XML var vtpFcMeasuredCorr = vtpResult.VTPFcMeasured / vtpResult.VTPWorkPWheelPos * vtpResult.VTPFcCorrectionFactor; var vtpFcSimulated = vtpResult.VTPFcFinalSimulated / vtpResult.VTPWorPWheelSimPos; var cVtp = vtpFcMeasuredCorr / vtpFcSimulated; - var declaredCO2 = result.FuelConsumptionTotal / result.Distance / result.Payload; + // TODO: MQ 20119-07-31 - how to handle vtp with dual-fuel vehicles? + var declaredCO2 = result.FuelConsumptionTotal.Sum(x => x.Value) / result.Distance / result.Payload; var verifiedCO2 = declaredCO2 * cVtp; Results.Add( @@ -273,7 +274,7 @@ namespace TUGraz.VectoCore.OutputData.XML return retVal; } - public override void InitializeReport(VectoRunData modelData) + public override void InitializeReport(VectoRunData modelData, List<List<FuelData.Entry>> fuelModes) { GeneralPart.Add( new XElement(tns + XMLNames.Component_Manufacturer, modelData.VehicleData.Manufacturer), @@ -292,7 +293,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement(tns + XMLNames.Vehicle_PTO, modelData.PTO != null), new XElement( tns + XMLNames.Vehicle_Components, - GetEngineDescription(modelData.EngineData), + GetEngineDescription(modelData.EngineData, fuelModes), GetGearboxDescription(modelData.GearboxData), GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData), GetRetarderDescription(modelData.Retarder), @@ -458,7 +459,7 @@ namespace TUGraz.VectoCore.OutputData.XML XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc))); } - private XElement GetEngineDescription(CombustionEngineData engineData) + private XElement GetEngineDescription(CombustionEngineData engineData, List<List<FuelData.Entry>> fuelModes) { return new XElement( tns + XMLNames.Component_Engine, @@ -467,7 +468,7 @@ namespace TUGraz.VectoCore.OutputData.XML new XElement( tns + XMLNames.Engine_Displacement, engineData.Displacement.ConvertToCubicCentiMeter().ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelData.FuelType.ToXMLFormat()) + new XElement(tns + XMLNames.Engine_FuelType, string.Join( ", ", fuelModes.SelectMany(x => x.Select(f => f.FuelType.ToXMLFormat())).Distinct())) ); } diff --git a/VectoCore/VectoCore/Utils/XMLDefinitions.cs b/VectoCore/VectoCore/Utils/XMLDefinitions.cs index 1bc68b40b3104a7be31dc8b60f67da788952600c..548fd4f5cdc66aa9d234b560a638f199d9ad9ddb 100644 --- a/VectoCore/VectoCore/Utils/XMLDefinitions.cs +++ b/VectoCore/VectoCore/Utils/XMLDefinitions.cs @@ -47,6 +47,8 @@ namespace TUGraz.VectoCore.Utils public const string DECLARATION_DEFINITIONS_NAMESPACE_URI_V22 = DECLARATION_NAMESPACE + ":v2.2"; + public const string DECLARATION_DEFINITIONS_NAMESPACE_URI_V23 = DECLARATION_NAMESPACE + ":v2.3_DF"; + public const string DECLARATION_INPUT_NAMESPACE = "urn:tugraz:ivt:VectoAPI:DeclarationInput"; diff --git a/VectoCore/VectoCore/Utils/XMLValidator.cs b/VectoCore/VectoCore/Utils/XMLValidator.cs index 76dcdfde63168ce6864f98df6e985eaea00e9359..01c3532c12a2349763bb2cff31b795cc87197511 100644 --- a/VectoCore/VectoCore/Utils/XMLValidator.cs +++ b/VectoCore/VectoCore/Utils/XMLValidator.cs @@ -95,9 +95,12 @@ namespace TUGraz.VectoCore.Utils { _resultAction(false); _valid = false; + ValidationError = args?.Message ?? "no schema found"; _validationErrorAction(args?.Severity ?? XmlSeverityType.Error, new ValidationEvent { ValidationEventArgs = args }); } + public string ValidationError { get; private set; } + public static void CallBackExceptionOnError(XmlSeverityType severity, ValidationEvent evt) { if (severity == XmlSeverityType.Error) { @@ -105,7 +108,7 @@ namespace TUGraz.VectoCore.Utils } } - private static XmlSchemaSet GetXMLSchema(XmlDocumentType docType) + public static XmlSchemaSet GetXMLSchema(XmlDocumentType docType) { var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() }; foreach (var entry in EnumHelper.GetValues<XmlDocumentType>()) { diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index a601a1bbf233c40ebcf7d5408515a98c7058db17..51ca8cfdad63afff04366bad258ec3bd582210d5 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -173,6 +173,7 @@ <Compile Include="InputData\FileIO\XML\Declaration\NinjectModules\XMLDeclarationInputDataV20InjectModule.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\NinjectModules\XMLDeclarationInputDataV21InjectModule.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\NinjectModules\XMLDeclarationInputDataV22InjectModule.cs" /> + <Compile Include="InputData\FileIO\XML\Declaration\NinjectModules\XMLDeclarationInputDataV23InjectModule.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\Reader\Impl\AbstractComponentReader.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\Reader\Impl\XMLADASReader.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\Reader\Impl\XMLComponentReader.cs" /> diff --git a/VectoCore/VectoCoreTest/FileIO/JsonWriteTest.cs b/VectoCore/VectoCoreTest/FileIO/JsonWriteTest.cs index f23bdd9ebd54235c969451c68aa44aba53bf4420..8d14899f47fdc91c1d04cb4c2341c99511e8a692 100644 --- a/VectoCore/VectoCoreTest/FileIO/JsonWriteTest.cs +++ b/VectoCore/VectoCoreTest/FileIO/JsonWriteTest.cs @@ -94,7 +94,7 @@ namespace TUGraz.VectoCore.Tests.FileIO Assert.NotNull(savedInprovider); AssertHelper.PublicPropertiesEqual(typeof(IEngineDeclarationInputData),engineInputData, savedInprovider.JobInputData.Vehicle.Components.EngineInputData, - new[] { "Source" }); + new[] { "Source", "EngineModes" }); } [TestCase(@"TestData\Generic Vehicles\Declaration Mode\Class9_RigidTruck_6x2\AMT_12.vgbx")] diff --git a/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs index d109d61588b3dc75d7911dc94eaa2b696d0f10b6..c0cd0039be4978d4bca68c4022a6c175c368aaf4 100644 --- a/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/ATPowerTrain.cs @@ -78,7 +78,7 @@ namespace TUGraz.VectoCore.Tests.Integration bool overspeed = false, KilogramSquareMeter gearBoxInertia = null) { var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(modFileName, FuelData.Diesel, fileWriter) { + var modData = new ModalDataContainer(modFileName, new[] { FuelData.Diesel }, fileWriter) { WriteModalResults = true, HasTorqueConverter = true }; diff --git a/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs b/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs index b0afbc995fc9f62d2272fb32103fc9964eccf8f8..5050d645cc9ee3735c30dd15649f470a7680f143 100644 --- a/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs +++ b/VectoCore/VectoCoreTest/Integration/BusAuxiliaries/AuxDemandTest.cs @@ -134,11 +134,17 @@ namespace TUGraz.VectoCore.Tests.Integration.BusAuxiliaries var fcMap = FuelConsumptionMapReader.ReadFromFile(engineFCMapFilePath); var fld = FullLoadCurveReader.ReadFromFile(engineFLDFilePath); var modelData = new CombustionEngineData() { - ConsumptionMap = fcMap, + Fuels = new List<CombustionEngineFuelData>() { + new CombustionEngineFuelData() { + ConsumptionMap = fcMap, + } + }, FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, fld }, { 1, fld } }, IdleSpeed = 560.SI<PerSecond>() }; - + vehicle.RunData = new VectoRunData() { + EngineData = modelData + }; var engine = new CombustionEngine(vehicle, modelData); //new Vehicle(vehicle, new VehicleData()); driver = new MockDriver(vehicle) { VehicleStopped = false, DriverBehavior = DrivingBehavior.Braking }; diff --git a/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs b/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs index b3196a82bd69e2332e200111f42158624bdf6b74..31444f60e882fb8be40b0658bd74ff545af9847f 100644 --- a/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/CoachAdvancedAuxPowertrain.cs @@ -76,7 +76,7 @@ namespace TUGraz.VectoCore.Tests.Integration bool highEnginePower = true) { var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(modFileName, FuelData.Diesel, fileWriter) { + var modData = new ModalDataContainer(modFileName, new[] { FuelData.Diesel }, fileWriter) { WriteAdvancedAux = true, WriteModalResults = true }; @@ -115,7 +115,7 @@ namespace TUGraz.VectoCore.Tests.Integration .AddComponent(engine); var aux = new BusAuxiliariesAdapter(container, AdvancedAuxFile, "Coach", - vehicleData.TotalVehicleWeight, engineData.ConsumptionMap, engineData.IdleSpeed); + vehicleData.TotalVehicleWeight, engineData.Fuels.First().ConsumptionMap, engineData.IdleSpeed); engine.Connect(aux.Port()); diff --git a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs index 93d4834d58d7398ff6afec87ef7f6862a28928e0..f83b74fe8348629f814b8c45e22be45a72db604e 100644 --- a/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/CoachPowerTrain.cs @@ -76,7 +76,7 @@ namespace TUGraz.VectoCore.Tests.Integration KilogramSquareMeter gearBoxInertia = null, bool engineHighPower = true) { var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(modFileName, FuelData.Diesel, fileWriter) { WriteModalResults = true }; + var modData = new ModalDataContainer(modFileName, new[] { FuelData.Diesel }, fileWriter) { WriteModalResults = true }; var container = new VehicleContainer(ExecutionMode.Engineering, modData); var gearboxData = CreateGearboxData(); diff --git a/VectoCore/VectoCoreTest/Integration/Declaration/ADASVehicleTest.cs b/VectoCore/VectoCoreTest/Integration/Declaration/ADASVehicleTest.cs index 3be16b752bb7e12b7066405717d623e10ed5e861..f0938d236776125778d77010763a35a06b454068 100644 --- a/VectoCore/VectoCoreTest/Integration/Declaration/ADASVehicleTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Declaration/ADASVehicleTest.cs @@ -112,7 +112,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Declaration var modData = modContainer.Data; run.Run(); modContainer.Data = modData; - var cf = modContainer.FuelConsumptionADASPerSecond() / modContainer.FuelConsumptionWHTCPerSecond(); + var cf = modContainer.FuelConsumptionADASPerSecond(modContainer.FuelData.First()) / modContainer.FuelConsumptionWHTCPerSecond(modContainer.FuelData.First()); Assert.AreEqual(expectedCorrectionFactor, cf.Value(), 1e-6); diff --git a/VectoCore/VectoCoreTest/Integration/Declaration/EngineInputDataTests.cs b/VectoCore/VectoCoreTest/Integration/Declaration/EngineInputDataTests.cs index 1d211cf9fed2555b95ca100808afe3cedbed06b6..fdd608aa7b2fffd7eaac2ccedfaeec12b5c796ab 100644 --- a/VectoCore/VectoCoreTest/Integration/Declaration/EngineInputDataTests.cs +++ b/VectoCore/VectoCoreTest/Integration/Declaration/EngineInputDataTests.cs @@ -100,7 +100,7 @@ namespace TUGraz.VectoCore.Tests.Integration.Declaration var modData = ((ModalDataContainer)first.GetContainer().ModalData).Data; first.Run(); - Assert.AreEqual(expectedFc, modData.AsEnumerable().Sum(r => r.Field<SI>((int)ModalResultField.FCFinal).Value()), 1e-3); + Assert.AreEqual(expectedFc, modData.AsEnumerable().Sum(r => r.Field<SI>(ModalResultField.FCFinal.GetName()).Value()), 1e-3); } } diff --git a/VectoCore/VectoCoreTest/Integration/Declaration/ExemptedVehicleTest.cs b/VectoCore/VectoCoreTest/Integration/Declaration/ExemptedVehicleTest.cs index 32150285bb1d8c30b17b4bdf2e84682c2bca2aa0..c3e6d4c4389de4fdadfb8649db9cbf98173597c2 100644 --- a/VectoCore/VectoCoreTest/Integration/Declaration/ExemptedVehicleTest.cs +++ b/VectoCore/VectoCoreTest/Integration/Declaration/ExemptedVehicleTest.cs @@ -112,13 +112,13 @@ namespace TUGraz.VectoCore.Tests.Integration Assert.IsTrue(File.Exists(customerFile)); var validator = new XMLValidator(XmlReader.Create(manufactuerFile)); - Assert.IsTrue(validator.ValidateXML(XmlDocumentType.ManufacturerReport)); + Assert.IsTrue(validator.ValidateXML(XmlDocumentType.ManufacturerReport), validator.ValidationError); var val2 = new XMLValidator(XmlReader.Create(customerFile)); - Assert.IsTrue(val2.ValidateXML(XmlDocumentType.CustomerReport)); + Assert.IsTrue(val2.ValidateXML(XmlDocumentType.CustomerReport), val2.ValidationError); var val3 = new XMLValidator(XmlReader.Create(monitoringFile)); - Assert.IsTrue(val3.ValidateXML(XmlDocumentType.MonitoringReport)); + Assert.IsTrue(val3.ValidateXML(XmlDocumentType.MonitoringReport), val3.ValidationError); } diff --git a/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs b/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs index baaec59f27b3ec62110c91db5d73bef1593fb44a..cfabc0c1a80ac532c73ece0d4aa0b4faddc57e70 100644 --- a/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs +++ b/VectoCore/VectoCoreTest/Integration/EngineOnlyCycle/EngineOnlyCycleTest.cs @@ -95,7 +95,7 @@ namespace TUGraz.VectoCore.Tests.Integration.EngineOnlyCycle var modFile = Path.GetFileNameWithoutExtension(modalResultFile); //Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); // + ".vmod"; var fileWriter = new FileOutputWriter(modFile); - var modData = new ModalDataContainer(modFile, FuelData.Diesel, fileWriter, true) { WriteModalResults = true }; + var modData = new ModalDataContainer(modFile, new[] { FuelData.Diesel }, fileWriter, true) { WriteModalResults = true }; modData.AddAuxiliary(Constants.Auxiliaries.Cycle); port.Initialize(data.Entries.First().Torque, data.Entries.First().AngularVelocity); foreach (var cycleEntry in data.Entries) { diff --git a/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs b/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs index 8671217967db60af05f711c3a7fecb69a240782c..91364e572744f52611ba6917cf817f3cc0d5e602 100644 --- a/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs +++ b/VectoCore/VectoCoreTest/Integration/FuelTypesTest.cs @@ -31,6 +31,7 @@ using System; using System.IO; +using System.Linq; using NUnit.Framework; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; @@ -118,28 +119,32 @@ namespace TUGraz.VectoCore.Tests.Integration var modData = modContainer.Data; var fuelData = FuelData.Instance().Lookup(fuelType, tankSystem); - modContainer.FuelData = fuelData; - ((VehicleContainer)run.Run.GetContainer()).RunData.EngineData.FuelData = fuelData; + + // change the fuel entry in mod data and engine data + var origFuel = modContainer.FuelColumns.Keys.First(); + modContainer.FuelColumns[fuelData] = modContainer.FuelColumns[origFuel]; + modContainer.FuelColumns.Remove(origFuel); + ((VehicleContainer)run.Run.GetContainer()).RunData.EngineData.Fuels.First().FuelData = fuelData; run.Run.Run(); // restore data table before assertions modContainer.Data = modData; - + var fuel = modContainer.FuelData.First(); // Console.WriteLine("FC-Map g/m: {0}, FC-Final g/m {1}, FC-Final l/100km: {2}, CO2 g/m: {3}, Energy J/m: {4}", Console.WriteLine("{0}, {1}, {2}, {3}, {4}", - modContainer.FCMapPerMeter().Value(), - modContainer.FuelConsumptionFinal().Value(), - modContainer.FuelConsumptionFinalVolumePerMeter()?.ConvertToLiterPer100Kilometer().Value ?? double.NaN, + modContainer.FCMapPerMeter(fuel).Value(), + modContainer.FuelConsumptionFinal(fuelData).Value(), + modContainer.FuelConsumptionFinalVolumePerMeter(fuelData)?.ConvertToLiterPer100Kilometer().Value ?? double.NaN, modContainer.CO2PerMeter().Value(), - modContainer.EnergyPerMeter().Value()); + modContainer.EnergyPerMeter(fuelData).Value()); - AssertHelper.AreRelativeEqual(expectedFCMap, modContainer.FCMapPerMeter(), 1e-6); - AssertHelper.AreRelativeEqual(expectedFCFinal, modContainer.FuelConsumptionFinal(), 1e-3); - AssertHelper.AreRelativeEqual(expectedFCperkm, modContainer.FuelConsumptionFinalVolumePerMeter()?.ConvertToLiterPer100Kilometer().Value.SI() ?? null, 1e-6); + AssertHelper.AreRelativeEqual(expectedFCMap, modContainer.FCMapPerMeter(fuel), 1e-6); + AssertHelper.AreRelativeEqual(expectedFCFinal, modContainer.FuelConsumptionFinal(fuelData), 1e-3); + AssertHelper.AreRelativeEqual(expectedFCperkm, modContainer.FuelConsumptionFinalVolumePerMeter(fuelData)?.ConvertToLiterPer100Kilometer().Value.SI() ?? null, 1e-6); AssertHelper.AreRelativeEqual(expectedCo2, modContainer.CO2PerMeter(), 1e-6); - AssertHelper.AreRelativeEqual(expectedMJ, modContainer.EnergyPerMeter(), 1e-3); + AssertHelper.AreRelativeEqual(expectedMJ, modContainer.EnergyPerMeter(fuelData), 1e-3); } } } diff --git a/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs b/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs index f249c9aad9978df0da191fcec382bddf402c5bb5..db6ff301d30f4e026a9f38193f97bde6e896613e 100644 --- a/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs +++ b/VectoCore/VectoCoreTest/Integration/FullCycleDeclarationTest.cs @@ -286,12 +286,12 @@ namespace TUGraz.VectoCore.Tests.Integration // test fuel consumption not negative Assert.IsTrue( modFile1Hz.Rows.Cast<DataRow>() - .All(r => r.ParseDouble(ModalResultField.FCWHTCc.GetShortCaption()).IsGreaterOrEqual(0)), + .All(r => r.ParseDouble(string.Format(ModalResultField.FCWHTCc.GetShortCaption(), "")).IsGreaterOrEqual(0)), "fuel consumption must not be negative."); // last v_act entry must be the same as original - var vAct = modFile.Rows.Cast<DataRow>().Last().ParseDouble((int)ModalResultField.v_act).SI<MeterPerSecond>(); - var vAct1Hz = modFile1Hz.Rows.Cast<DataRow>().Last().ParseDouble((int)ModalResultField.v_act).SI<MeterPerSecond>(); + var vAct = modFile.Rows.Cast<DataRow>().Last().ParseDouble(ModalResultField.v_act.GetName()).SI<MeterPerSecond>(); + var vAct1Hz = modFile1Hz.Rows.Cast<DataRow>().Last().ParseDouble(ModalResultField.v_act.GetName()).SI<MeterPerSecond>(); AssertHelper.AreRelativeEqual(vAct, vAct1Hz, 1e-4, "end velocity is not equal"); } diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs index 4dffc5f8887f19ce59cb79b06ff528aef27d0a1e..772f80e5ac1eaad66304c07ba5e666665f531b65 100644 --- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/FullPowertrain.cs @@ -79,7 +79,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns public void Test_FullPowertrain_SimpleGearbox() { var fileWriter = new FileOutputWriter("Coach_FullPowertrain_SimpleGearbox"); - var modData = new ModalDataContainer("Coach_FullPowertrain_SimpleGearbox", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_FullPowertrain_SimpleGearbox", new[] { FuelData.Diesel }, fileWriter); var container = new VehicleContainer(ExecutionMode.Engineering, modData); container.RunData = new VectoRunData() { SimulationType = SimulationType.DistanceCycle }; @@ -146,7 +146,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns public void Test_FullPowertrain() { var fileWriter = new FileOutputWriter("Coach_FullPowertrain"); - var modData = new ModalDataContainer("Coach_FullPowertrain", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_FullPowertrain", new[] { FuelData.Diesel }, fileWriter); var container = new VehicleContainer(ExecutionMode.Engineering, modData); container.RunData = new VectoRunData() {SimulationType = SimulationType.DistanceCycle }; @@ -227,7 +227,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns public void Test_FullPowertrain_LowSpeed() { var fileWriter = new FileOutputWriter("Coach_FullPowertrain_LowSpeed"); - var modData = new ModalDataContainer("Coach_FullPowertrain_LowSpeed", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_FullPowertrain_LowSpeed", new[] { FuelData.Diesel }, fileWriter); var container = new VehicleContainer(ExecutionMode.Engineering, modData); var gearboxData = CreateGearboxData(); diff --git a/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs b/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs index c25d0e46cf0627a89c6a56090e41ab4ebb841702..66ebc499c176264a50ffaa5946a5b4c8a204b6e8 100644 --- a/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs +++ b/VectoCore/VectoCoreTest/Integration/SimulationRuns/MinimalPowertrain.cs @@ -83,7 +83,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var driverData = CreateDriverData(AccelerationFile); var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload"); - var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", new[] { FuelData.Diesel }, fileWriter); var container = new VehicleContainer(ExecutionMode.Engineering, modData); var driver = new Driver(container, driverData, new DefaultDriverStrategy()); @@ -129,7 +129,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var driverData = CreateDriverData(AccelerationFile); var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_MinimalPowertrain", new[] { FuelData.Diesel }, fileWriter); var container = new VehicleContainer(ExecutionMode.Engineering, modData); var cycle = new DistanceBasedDrivingCycle(container, cycleData); @@ -201,7 +201,7 @@ namespace TUGraz.VectoCore.Tests.Integration.SimulationRuns var driverData = CreateDriverData(AccelerationFile2); var fileWriter = new FileOutputWriter("Coach_MinimalPowertrainOverload"); - var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_MinimalPowertrainOverload", new[] { FuelData.Diesel }, fileWriter); var container = new VehicleContainer(ExecutionMode.Engineering, modData); container.RunData = new VectoRunData() { SimulationType = SimulationType.DistanceCycle }; diff --git a/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs b/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs index cc746a7f1b51e757ca4874c5288e23636504d232..9250412036e10e8de03a2efe5a49c42ffc796595 100644 --- a/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs +++ b/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs @@ -262,13 +262,13 @@ namespace TUGraz.VectoCore.Tests.Integration Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException))); var view = new DataView(sumData.Table, "", SummaryDataContainer.SORT, DataViewRowState.CurrentRows).ToTable(); - Console.WriteLine(string.Join("; ", view.AsEnumerable().Select(x => x[SummaryDataContainer.FCMAP_KM].ToString().ToDouble()))); - Assert.AreEqual(201.39195, view.Rows[0][SummaryDataContainer.FCMAP_KM].ToString().ToDouble(), 1e-3); - Assert.AreEqual(239.50432, view.Rows[1][SummaryDataContainer.FCMAP_KM].ToString().ToDouble(), 1e-3); - Assert.AreEqual(170.18354, view.Rows[2][SummaryDataContainer.FCMAP_KM].ToString().ToDouble(), 1e-3); - Assert.AreEqual(183.06159, view.Rows[3][SummaryDataContainer.FCMAP_KM].ToString().ToDouble(), 1e-3); - Assert.AreEqual(224.78226, view.Rows[4][SummaryDataContainer.FCMAP_KM].ToString().ToDouble(), 1e-3); - Assert.AreEqual(255.02202, view.Rows[5][SummaryDataContainer.FCMAP_KM].ToString().ToDouble(), 1e-3); + Console.WriteLine(string.Join("; ", view.AsEnumerable().Select(x => x[string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble()))); + Assert.AreEqual(201.39195, view.Rows[0][string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble(), 1e-3); + Assert.AreEqual(239.50432, view.Rows[1][string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble(), 1e-3); + Assert.AreEqual(170.18354, view.Rows[2][string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble(), 1e-3); + Assert.AreEqual(183.06159, view.Rows[3][string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble(), 1e-3); + Assert.AreEqual(224.78226, view.Rows[4][string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble(), 1e-3); + Assert.AreEqual(255.02202, view.Rows[5][string.Format(SummaryDataContainer.FCMAP_KM, "")].ToString().ToDouble(), 1e-3); } [TestCase(EngineSpeedLimitJobATDecl)] diff --git a/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs b/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs index 5017397f6a6199c4f462f8668b0dfa7690145c20..754846d894fbf097bcd4a725e7386fc4b87e9d9e 100644 --- a/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs +++ b/VectoCore/VectoCoreTest/Integration/Truck40tPowerTrain.cs @@ -86,7 +86,7 @@ namespace TUGraz.VectoCore.Tests.Integration Kilogram massExtra, Kilogram loading, bool overspeed = false, GearboxType gbxType = GearboxType.AMT) { var fileWriter = new FileOutputWriter(modFileName); - var modData = new ModalDataContainer(Path.GetFileName(modFileName), FuelData.Diesel, fileWriter) { + var modData = new ModalDataContainer(Path.GetFileName(modFileName), new[] { FuelData.Diesel }, fileWriter) { WriteModalResults = true }; var container = new VehicleContainer(ExecutionMode.Engineering, modData); diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs index c1798f4155cbea299405b219805f9763ad617e4d..9e061e63dc831b6c59e77a7551a0151bdac2791e 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs @@ -450,9 +450,12 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var dao = new DeclarationDataAdapter(); var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile); - var engineData = dao.CreateEngineData(new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile), - null, - gearboxData, new List<ITorqueLimitInputData>()); + var engineInput = new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile); + var vehicle = new MockVehicleInputData() { + EngineInputData = engineInput, + GearboxInputData = gearboxData + }; + var engineData = dao.CreateEngineData(vehicle, engineInput.EngineModes.First(), new Mission() {MissionType = MissionType.LongHaul}); var shiftPolygons = new List<ShiftPolygon>(); for (var i = 0; i < gearboxData.Gears.Count; i++) { @@ -499,9 +502,12 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var dao = new DeclarationDataAdapter(); var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile); - var engineData = dao.CreateEngineData(new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile), - null, - gearboxData, new List<ITorqueLimitInputData>()); + var engineInput = new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile); + var vehicle = new MockVehicleInputData() { + EngineInputData = engineInput, + GearboxInputData = gearboxData + }; + var engineData = dao.CreateEngineData(vehicle, engineInput.EngineModes.First(), new Mission() { MissionType = MissionType.LongHaul }); var shiftPolygons = new List<ShiftPolygon>(); for (var i = 0; i < gearboxData.Gears.Count; i++) { @@ -611,10 +617,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var gearboxData = job.JobInputData.Vehicle.Components.GearboxInputData; var idlespeed = VectoMath.Max( - job.JobInputData.Vehicle.EngineIdleSpeed, job.JobInputData.Vehicle.Components.EngineInputData.IdleSpeed); + job.JobInputData.Vehicle.EngineIdleSpeed, job.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().IdleSpeed); var dao = new DeclarationDataAdapter(); - var engineData = dao.CreateEngineData( - job.JobInputData.Vehicle.Components.EngineInputData, idlespeed, gearboxData, job.JobInputData.Vehicle.TorqueLimits); + var engineData = dao.CreateEngineData(job.JobInputData.Vehicle, job.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First(), new Mission() {MissionType = MissionType.LongHaul}); var axlegearRatio = job.JobInputData.Vehicle.Components.AxleGearInputData.Ratio; var rdyn = job.JobInputData.Vehicle.Components.AxleWheels.AxlesDeclaration.Where(x => x.AxleType == AxleType.VehicleDriven) .Select(x => DeclarationData.Wheels.Lookup(x.Tyre.Dimension)).Average(x => x.DynamicTyreRadius.Value()) @@ -869,7 +874,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration var dao = new DeclarationDataAdapter(); var gearboxData = inputData.JobInputData.Vehicle.Components.GearboxInputData; - var engineData = dao.CreateEngineData(inputData.JobInputData.Vehicle.Components.EngineInputData,0.RPMtoRad(), gearboxData, new List<ITorqueLimitInputData>()); + var engineData = dao.CreateEngineData(inputData.JobInputData.Vehicle, inputData.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First(), new Mission() {MissionType = MissionType.LongHaul}); var fullLoadCurves = engineData.FullLoadCurves; diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs index 1d710ad7fb2bbdbd3376de50c9ac946815a3e11d..cb473622df95f8b36f751223c35354c6584c5c07 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs @@ -70,7 +70,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation { var fileWriter = new FileOutputWriter("AuxWriteModFileSumFile"); - var modData = new ModalDataContainer("AuxWriteModFileSumFile", FuelData.Diesel, fileWriter) { + var modData = new ModalDataContainer("AuxWriteModFileSumFile", new[] { FuelData.Diesel }, fileWriter) { WriteModalResults = true }; modData.AddAuxiliary("FAN"); diff --git a/VectoCore/VectoCoreTest/Models/Simulation/DeclarationSimulationFactoryTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/DeclarationSimulationFactoryTest.cs index 0dfced812b57879fc85f964954d79db8bd5b7883..b32b1a339245a13aa8a9047851a849b70dc20b7b 100644 --- a/VectoCore/VectoCoreTest/Models/Simulation/DeclarationSimulationFactoryTest.cs +++ b/VectoCore/VectoCoreTest/Models/Simulation/DeclarationSimulationFactoryTest.cs @@ -106,7 +106,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation for (var i = 0; i < 8; i++) Assert.AreEqual( - expected[i], runs[i].GetContainer().RunData.EngineData.FuelConsumptionCorrectionFactor, 1e-6, + expected[i], runs[i].GetContainer().RunData.EngineData.Fuels.First().FuelConsumptionCorrectionFactor, 1e-6, "correction factor for cycle {0} payload {1} mismatch ({2})", runs[i].CycleName , runs[i].RunSuffix, i); } } diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index 8a1ecbf822edefc667938092c290f7fec9250741..53fa0f2b14f574dbb69306e71d8a03f2310ebf4a 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -517,13 +517,13 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent public void Test_EngineData() { var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(CoachEngine, 0); - var motorway = engineData.WHTCMotorway; + var motorway = engineData.Fuels.First().WHTCMotorway; Assert.AreEqual(motorway, 1); - var rural = engineData.WHTCRural; + var rural = engineData.Fuels.First().WHTCRural; Assert.AreEqual(rural, 1); - var urban = engineData.WHTCUrban; + var urban = engineData.Fuels.First().WHTCUrban; Assert.AreEqual(urban, 1); var displace = engineData.Displacement; diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs index fbf92f816d5495b382198f4a2d1d45bb2d6d5882..f3fc5ab9ffc86e35e5390810d9eb5f7918b2b80a 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/DriverTest.cs @@ -81,7 +81,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var driverData = CreateDriverData(); var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain_Coasting"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain_Coasting", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer( + "Coach_MinimalPowertrain_Coasting", new[] { FuelData.Diesel }, fileWriter); var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); var mockCycle = new MockDrivingCycle(vehicleContainer, null); @@ -138,7 +139,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var driverData = CreateDriverData(); var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain_Coasting"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain_Coasting", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer( + "Coach_MinimalPowertrain_Coasting", new[] { FuelData.Diesel }, fileWriter); var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); var mockCycle = new MockDrivingCycle(vehicleContainer, null); @@ -201,7 +203,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent var driverData = CreateDriverData(); var fileWriter = new FileOutputWriter("Coach_MinimalPowertrain"); - var modData = new ModalDataContainer("Coach_MinimalPowertrain", FuelData.Diesel, fileWriter); + var modData = new ModalDataContainer("Coach_MinimalPowertrain", new[] { FuelData.Diesel }, fileWriter); var vehicleContainer = new VehicleContainer(ExecutionMode.Engineering, modData); var cycle = new MockDrivingCycle(vehicleContainer, null); diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs index 6e63b354eb6e48c613d3846eca242551ffc2081a..e213258271a3248be1fcb56fdc710b3255e86a14 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs @@ -86,11 +86,15 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData Displacement = 6374.SI(Unit.SI.Cubic.Centi.Meter).Cast<CubicMeter>(), IdleSpeed = 560.RPMtoRad(), Inertia = 1.SI<KilogramSquareMeter>(), - WHTCUrban = 1, - WHTCRural = 1, - WHTCMotorway = 1, + Fuels = new List<CombustionEngineFuelData>() { + new CombustionEngineFuelData() { + WHTCUrban = 1, + WHTCRural = 1, + WHTCMotorway = 1, + ConsumptionMap = FuelConsumptionMapReader.Create(fuelConsumption) + } + }, FullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>() { { 0, FullLoadCurveReader.Create(fullLoad) } }, - ConsumptionMap = FuelConsumptionMapReader.Create(fuelConsumption) }; data.FullLoadCurves[0].EngineData = data; @@ -129,7 +133,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData var engineData = dao.CreateEngineData(data, null, new List<ITorqueLimitInputData>(), null); - var results = engineData.Validate(ExecutionMode.Declaration, null, false); + var results = engineData.Validate(ExecutionMode.Engineering, null, false); Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); Assert.IsTrue(engineData.IsValid()); } @@ -169,8 +173,11 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData Type = GearboxType.AMT, Gears = new List<ITransmissionInputData>() }; - - var engineData = dao.CreateEngineData(data, null, dummyGearbox, new List<ITorqueLimitInputData>()); + var vehicle = new MockVehicleInputData() { + EngineInputData = data, + GearboxInputData = dummyGearbox + }; + var engineData = dao.CreateEngineData(vehicle, data.EngineModes.First(), new Mission() {MissionType = MissionType.LongHaul}); var results = engineData.Validate(ExecutionMode.Declaration, null, false); Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage))); diff --git a/VectoCore/VectoCoreTest/Reports/GearshiftCountTest.cs b/VectoCore/VectoCoreTest/Reports/GearshiftCountTest.cs index 3f4c119f822ec0e2bd827c4e05f1244914c5d5f8..c45843298ceac7d25289eb2aaab0b5b1475a0563 100644 --- a/VectoCore/VectoCoreTest/Reports/GearshiftCountTest.cs +++ b/VectoCore/VectoCoreTest/Reports/GearshiftCountTest.cs @@ -29,6 +29,7 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.Linq; using NUnit.Framework; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; @@ -44,7 +45,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruptionShiftup() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel}, null); var entries = new[] { new DummyEntry { v = 34, gear = 4u }, @@ -66,7 +67,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruption() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel }, null); var entries = new[] { new DummyEntry { v = 34, gear = 4u }, @@ -88,7 +89,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruptionShiftDown() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel }, null); var entries = new[] { new DummyEntry { v = 34, gear = 4u }, @@ -111,7 +112,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruptionStop() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel }, null); var entries = new[] { new DummyEntry { v = 4, gear = 4u }, @@ -133,7 +134,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruptionStopDriveOff() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel }, null); var entries = new[] { new DummyEntry { v = 4, gear = 4u }, @@ -157,7 +158,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruptionShiftupAT() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel }, null); var entries = new[] { new DummyEntry { v = 34, gear = 4u }, @@ -180,7 +181,7 @@ namespace TUGraz.VectoCore.Tests.Reports [TestCase()] public void TestGearshiftCountTractionInterruptionShiftDownAT() { - var modData = new ModalDataContainer("GearshiftRun", FuelData.Diesel, null); + var modData = new ModalDataContainer("GearshiftRun", new[] { FuelData.Diesel }, null); var entries = new[] { new DummyEntry { v = 34, gear = 4u }, diff --git a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs index 3189de0ebac72bcafec9d061e9e3fa9ec4a5837c..d938e2173783d6d827bd9a815f834654f0805234 100644 --- a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs +++ b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs @@ -77,7 +77,7 @@ namespace TUGraz.VectoCore.Tests.Reports TestCase(10, 0.1)] public void SumDataTest(double initialSpeedVal, double accVal) { - var modData = new ModalDataContainer("sumDataTest", FuelData.Diesel, null, false); + var modData = new ModalDataContainer("sumDataTest", new[] { FuelData.Diesel}, null, false); var initalSpeed = initialSpeedVal.KMPHtoMeterPerSecond(); var speed = initalSpeed; var dist = 0.SI<Meter>(); @@ -126,7 +126,7 @@ namespace TUGraz.VectoCore.Tests.Reports run.Run(); Assert.IsTrue(run.FinishedWithoutErrors); - AssertModDataIntegrity(modData, auxKeys, cycle.Entries.Last().Distance.Value(), engineData.ConsumptionMap, true); + AssertModDataIntegrity(modData, auxKeys, cycle.Entries.Last().Distance.Value(), engineData.Fuels.First().ConsumptionMap, true); } [Category("LongRunning")] @@ -215,15 +215,15 @@ namespace TUGraz.VectoCore.Tests.Reports Second tracStart = null; foreach (DataRow row in modData.Rows) { - var velocity = (MeterPerSecond)row[(int)ModalResultField.v_act]; + var velocity = row.Field<MeterPerSecond>(ModalResultField.v_act.GetName()); if (velocity.IsEqual(0)) { tracStart = null; continue; } - var gear = (uint)row[(int)ModalResultField.Gear]; - var absTime = (Second)row[(int)ModalResultField.time]; - var dt = (Second)row[(int)ModalResultField.simulationInterval]; + var gear = row.Field<uint>(ModalResultField.Gear.GetName()); + var absTime = row.Field<Second>(ModalResultField.time.GetName()); + var dt = row.Field<Second>(ModalResultField.simulationInterval.GetName()); if (gear == 0 && tracStart == null) { tracStart = absTime - dt / 2.0; } @@ -339,12 +339,12 @@ namespace TUGraz.VectoCore.Tests.Reports FuelConsumptionMap fcMap = null; if (engInput != null) { fcMap = FuelConsumptionMapReader.Create(engInput.JobInputData.Vehicle - .Components.EngineInputData.FuelConsumptionMap); + .Components.EngineInputData.EngineModes.First().Fuels.First().FuelConsumptionMap); } var vtpInput = inputData as IVTPEngineeringInputDataProvider; if (vtpInput != null ) { fcMap = FuelConsumptionMapReader.Create(vtpInput.JobInputData.Vehicle - .Components.EngineInputData.FuelConsumptionMap); + .Components.EngineInputData.EngineModes.First().Fuels.First().FuelConsumptionMap); } var disatanceBased = ((VehicleContainer)(jobContainer.Runs.First().Run.GetContainer())).DrivingCycle is DistanceBasedDrivingCycle; @@ -393,11 +393,11 @@ namespace TUGraz.VectoCore.Tests.Reports var cargoVolume = mode == ExecutionMode.Engineering ? 0.0 : ((ConvertedSI)row[SummaryDataContainer.CARGO_VOLUME]); var loadingValue = ((ConvertedSI)row[SummaryDataContainer.LOADING]) / 1000; - var fcPer100km = distanceBased ? ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]) : null; + var fcPer100km = distanceBased ? ((ConvertedSI)row[string.Format(SummaryDataContainer.FCFINAL_LITERPER100KM, "")]) : null; var fcPerVolume = mode == ExecutionMode.Engineering ? 0.0 - : ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]); - var fcPerLoad = loadingValue > 0 ? ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]) : 0.0; + : ((ConvertedSI)row[string.Format(SummaryDataContainer.FCFINAL_LiterPer100M3KM, "")]); + var fcPerLoad = loadingValue > 0 ? ((ConvertedSI)row[string.Format(SummaryDataContainer.FCFINAL_LITERPER100TKM, "")]) : 0.0; var co2PerKm = distanceBased? ((ConvertedSI)row[SummaryDataContainer.CO2_KM]) : null; var co2PerVolume = mode == ExecutionMode.Engineering ? 0.0 : ((ConvertedSI)row[SummaryDataContainer.CO2_M3KM]); var co2PerLoad = loadingValue > 0 ? ((ConvertedSI)row[SummaryDataContainer.CO2_TKM]) : 0.0; @@ -474,59 +474,59 @@ namespace TUGraz.VectoCore.Tests.Reports ? auxKeys[Constants.Auxiliaries.IDs.PTOConsumer] : null; foreach (DataRow row in modData.Rows) { - if (distanceBased && totalDistance.IsEqual(((Meter)row[(int)ModalResultField.dist]).Value())) { + if (distanceBased && totalDistance.IsEqual(((Meter)row[ModalResultField.dist.GetName()]).Value())) { continue; } - var gear = (uint)row[(int)ModalResultField.Gear]; - var time = (Second)row[(int)ModalResultField.time]; + var gear = (uint)row[ModalResultField.Gear.GetName()]; + var time = (Second)row[ModalResultField.time.GetName()]; Meter distance = 0.SI<Meter>(); if (distanceBased) { - distance = (Meter)row[(int)ModalResultField.dist]; + distance = (Meter)row[ModalResultField.dist.GetName()]; } - var tqEngFcmap = (NewtonMeter)row[(int)ModalResultField.T_eng_fcmap]; - var nEngFcMap = (PerSecond)row[(int)ModalResultField.n_eng_avg]; + var tqEngFcmap = (NewtonMeter)row[ModalResultField.T_eng_fcmap.GetName()]; + var nEngFcMap = (PerSecond)row[ModalResultField.n_eng_avg.GetName()]; // check fuel consumption interpolation - var fuelConsumption = (SI)row[(int)ModalResultField.FCMap]; + var fuelConsumption = (SI)row[ModalResultField.FCMap.GetName()]; Assert.AreEqual(fuelConsumption.Value(), consumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap,true).Value.Value(), 1E-3, "time: {0} distance: {1}", time, distance); // check P_eng_FCmap = T_eng_fcmap * n_eng - var pEngFcmap = (SI)row[(int)ModalResultField.P_eng_fcmap]; + var pEngFcmap = (SI)row[ModalResultField.P_eng_fcmap.GetName()]; Assert.AreEqual(pEngFcmap.Value(), (tqEngFcmap * nEngFcMap).Value(), 1E-3, "time: {0} distance: {1}", time, distance); - var pWheelIn = (Watt)row[(int)ModalResultField.P_wheel_in]; - var pAir = distanceBased ? (Watt)row[(int)ModalResultField.P_air] : 0.SI<Watt>(); - var pRoll = distanceBased ? (Watt)row[(int)ModalResultField.P_roll] : 0.SI<Watt>(); - var pGrad = distanceBased ? (Watt)row[(int)ModalResultField.P_slope] : 0.SI<Watt>(); - var pVehInertia = distanceBased ? (Watt)row[(int)ModalResultField.P_veh_inertia] : 0.SI<Watt>(); - var pTrac = distanceBased ? (Watt)row[(int)ModalResultField.P_trac] : pWheelIn; + var pWheelIn = (Watt)row[ModalResultField.P_wheel_in.GetName()]; + var pAir = distanceBased ? (Watt)row[ModalResultField.P_air.GetName()] : 0.SI<Watt>(); + var pRoll = distanceBased ? (Watt)row[ModalResultField.P_roll.GetName()] : 0.SI<Watt>(); + var pGrad = distanceBased ? (Watt)row[ModalResultField.P_slope.GetName()] : 0.SI<Watt>(); + var pVehInertia = distanceBased ? (Watt)row[ModalResultField.P_veh_inertia.GetName()] : 0.SI<Watt>(); + var pTrac = distanceBased ? (Watt)row[ModalResultField.P_trac.GetName()] : pWheelIn; // P_eng_out = P_wheel + P_lossgearbox + P_lossaxle + P_lossretarder + P_agbx + Pa_eng + P_aux - P_brake_loss - var pEngOut = (Watt)row[(int)ModalResultField.P_eng_out]; - var pLossGbx = (Watt)row[(int)ModalResultField.P_gbx_loss]; - var pGbxIn = (Watt)row[(int)ModalResultField.P_gbx_in]; - var pLossAxle = (Watt)row[(int)ModalResultField.P_axle_loss]; - var pLossAngle = row[(int)ModalResultField.P_angle_loss] is DBNull + var pEngOut = (Watt)row[ModalResultField.P_eng_out.GetName()]; + var pLossGbx = (Watt)row[ModalResultField.P_gbx_loss.GetName()]; + var pGbxIn = (Watt)row[ModalResultField.P_gbx_in.GetName()]; + var pLossAxle = (Watt)row[ModalResultField.P_axle_loss.GetName()]; + var pLossAngle = row[ModalResultField.P_angle_loss.GetName()] is DBNull ? 0.SI<Watt>() - : (Watt)row[(int)ModalResultField.P_angle_loss]; - var pAxleIn = (Watt)row[(int)ModalResultField.P_axle_in]; - var pLossRet = (Watt)row[(int)ModalResultField.P_ret_loss]; - var pRetIn = (Watt)row[(int)ModalResultField.P_retarder_in]; - var pGbxInertia = (Watt)row[(int)ModalResultField.P_gbx_inertia]; - var pShiftLoss = row[(int)ModalResultField.P_gbx_shift_loss] is DBNull + : (Watt)row[ModalResultField.P_angle_loss.GetName()]; + var pAxleIn = (Watt)row[ModalResultField.P_axle_in.GetName()]; + var pLossRet = (Watt)row[ModalResultField.P_ret_loss.GetName()]; + var pRetIn = (Watt)row[ModalResultField.P_retarder_in.GetName()]; + var pGbxInertia = (Watt)row[ModalResultField.P_gbx_inertia.GetName()]; + var pShiftLoss = row[ModalResultField.P_gbx_shift_loss.GetName()] is DBNull ? 0.SI<Watt>() - : (Watt)row[(int)ModalResultField.P_gbx_shift_loss]; - var pEngInertia = (Watt)row[(int)ModalResultField.P_eng_inertia]; + : (Watt)row[ModalResultField.P_gbx_shift_loss.GetName()]; + var pEngInertia = (Watt)row[ModalResultField.P_eng_inertia.GetName()]; var pAux = - (Watt)(row[(int)ModalResultField.P_aux] != DBNull.Value ? row[(int)ModalResultField.P_aux] : 0.SI<Watt>()); - var pBrakeLoss = distanceBased ? (Watt)row[(int)ModalResultField.P_brake_loss] : 0.SI<Watt>(); - var pBrakeIn = distanceBased ? (Watt)row[(int)ModalResultField.P_brake_in] : pWheelIn; + (Watt)(row[ModalResultField.P_aux.GetName()] != DBNull.Value ? row[ModalResultField.P_aux.GetName()] : 0.SI<Watt>()); + var pBrakeLoss = distanceBased ? (Watt)row[ModalResultField.P_brake_loss.GetName()] : 0.SI<Watt>(); + var pBrakeIn = distanceBased ? (Watt)row[ModalResultField.P_brake_in.GetName()] : pWheelIn; - var pWheelInertia = distanceBased ? (Watt)row[(int)ModalResultField.P_wheel_inertia] : 0.SI<Watt>(); + var pWheelInertia = distanceBased ? (Watt)row[ModalResultField.P_wheel_inertia.GetName()] : 0.SI<Watt>(); var pPTOconsumer = ptoConsumerColumn == null || row[ptoConsumerColumn.ColumnName] is DBNull ? 0.SI<Watt>() : (Watt)row[ptoConsumerColumn.ColumnName]; @@ -553,22 +553,22 @@ namespace TUGraz.VectoCore.Tests.Reports Assert.AreEqual(pRetIn.Value(), (pAxleIn + pLossRet).Value(), 1E-3, "time: {0} distance: {1}", time, distance); - var pClutchLoss = (Watt)(row[(int)ModalResultField.P_clutch_loss] != DBNull.Value - ? row[(int)ModalResultField.P_clutch_loss] + var pClutchLoss = (Watt)(row[ModalResultField.P_clutch_loss.GetName()] != DBNull.Value + ? row[ModalResultField.P_clutch_loss.GetName()] : 0.SI<Watt>()); - var pClutchOut = row[(int)ModalResultField.P_clutch_out]; + var pClutchOut = row[ModalResultField.P_clutch_out.GetName()]; if (pClutchOut != DBNull.Value) { Assert.AreEqual(pGbxIn.Value(), (pClutchOut as Watt).Value(), 1E-3, "time: {0} distance: {1}", time, distance); Assert.AreEqual(pEngOut.Value(), (pClutchOut as Watt + pClutchLoss).Value(), 1E-3, "time: {0} distance: {1}", time, distance); } - var pTC_Loss = (Watt)(row[(int)ModalResultField.P_TC_loss] != DBNull.Value - ? row[(int)ModalResultField.P_TC_loss] + var pTC_Loss = (Watt)(row[ModalResultField.P_TC_loss.GetName()] != DBNull.Value + ? row[ModalResultField.P_TC_loss.GetName()] : 0.SI<Watt>()); - var pTCOut = row[(int)ModalResultField.P_clutch_out]; + var pTCOut = row[ModalResultField.P_clutch_out.GetName()]; if (pTCOut != DBNull.Value) { Assert.AreEqual(pGbxIn.Value(), (pTCOut as Watt).Value(), 1E-3, "time: {0} distance: {1}", time, distance); //Assert.AreEqual(pEngOut.Value(), (pTCOut as Watt + pTC_Loss).Value(), 1E-3, "time: {0} distance: {1}", @@ -628,7 +628,7 @@ namespace TUGraz.VectoCore.Tests.Reports foreach (var modalResults in modData) { AssertModDataIntegrityAT(modalResults.Item1, auxKeys, modalResults.Item2, - FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).JobInputData.Vehicle.Components.EngineInputData.FuelConsumptionMap), true); + FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().FuelConsumptionMap), true); } AssertSumDataIntegrity(sumData, ExecutionMode.Engineering, true); @@ -646,57 +646,57 @@ namespace TUGraz.VectoCore.Tests.Reports ? auxKeys[Constants.Auxiliaries.IDs.PTOConsumer] : null; foreach (DataRow row in modData.Rows) { - if (totalDistance.IsEqual(((Meter)row[(int)ModalResultField.dist]))) { + if (totalDistance.IsEqual(((Meter)row[ModalResultField.dist.GetName()]))) { continue; } - var gear = (uint)row[(int)ModalResultField.Gear]; - var time = (Second)row[(int)ModalResultField.time]; + var gear = (uint)row[ModalResultField.Gear.GetName()]; + var time = (Second)row[ModalResultField.time.GetName()]; - var distance = (Meter)row[(int)ModalResultField.dist]; - var tqEngFcmap = (NewtonMeter)row[(int)ModalResultField.T_eng_fcmap]; - var nEngFcMap = (PerSecond)row[(int)ModalResultField.n_eng_avg]; + var distance = (Meter)row[ModalResultField.dist.GetName()]; + var tqEngFcmap = (NewtonMeter)row[ModalResultField.T_eng_fcmap.GetName()]; + var nEngFcMap = (PerSecond)row[ModalResultField.n_eng_avg.GetName()]; // check fuel consumption interpolation - var fuelConsumption = (SI)row[(int)ModalResultField.FCMap]; + var fuelConsumption = (SI)row[ModalResultField.FCMap.GetName()]; Assert.AreEqual(fuelConsumption.Value(), consumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value.Value(), 1E-3, "time: {0} distance: {1}", time, distance); // check P_eng_FCmap = T_eng_fcmap * n_eng - var pEngFcmap = (SI)row[(int)ModalResultField.P_eng_fcmap]; + var pEngFcmap = (SI)row[ModalResultField.P_eng_fcmap.GetName()]; Assert.AreEqual(pEngFcmap.Value(), (tqEngFcmap * nEngFcMap).Value(), 1E-3, "time: {0} distance: {1}", time, distance); - var pWheelIn = (Watt)row[(int)ModalResultField.P_wheel_in]; - var pAir = (Watt)row[(int)ModalResultField.P_air]; - var pRoll = (Watt)row[(int)ModalResultField.P_roll]; - var pGrad = (Watt)row[(int)ModalResultField.P_slope]; - var pVehInertia = (Watt)row[(int)ModalResultField.P_veh_inertia]; - var pTrac = (Watt)row[(int)ModalResultField.P_trac]; + var pWheelIn = (Watt)row[ModalResultField.P_wheel_in.GetName()]; + var pAir = (Watt)row[ModalResultField.P_air.GetName()]; + var pRoll = (Watt)row[ModalResultField.P_roll.GetName()]; + var pGrad = (Watt)row[ModalResultField.P_slope.GetName()]; + var pVehInertia = (Watt)row[ModalResultField.P_veh_inertia.GetName()]; + var pTrac = (Watt)row[ModalResultField.P_trac.GetName()]; // Pe_eng = P_wheel + P_lossgearbox + P_lossaxle + P_lossretarder + P_agbx + Pa_eng + P_aux - P_brake_loss - var pEngOut = (Watt)row[(int)ModalResultField.P_eng_out]; - var pLossGbx = (Watt)row[(int)ModalResultField.P_gbx_loss]; - var pGbxIn = (Watt)row[(int)ModalResultField.P_gbx_in]; - var pLossAxle = (Watt)row[(int)ModalResultField.P_axle_loss]; - var pLossAngle = row[(int)ModalResultField.P_angle_loss] is DBNull + var pEngOut = (Watt)row[ModalResultField.P_eng_out.GetName()]; + var pLossGbx = (Watt)row[ModalResultField.P_gbx_loss.GetName()]; + var pGbxIn = (Watt)row[ModalResultField.P_gbx_in.GetName()]; + var pLossAxle = (Watt)row[ModalResultField.P_axle_loss.GetName()]; + var pLossAngle = row[ModalResultField.P_angle_loss.GetName()] is DBNull ? 0.SI<Watt>() - : (Watt)row[(int)ModalResultField.P_angle_loss]; - var pAxleIn = (Watt)row[(int)ModalResultField.P_axle_in]; - var pLossRet = (Watt)row[(int)ModalResultField.P_ret_loss]; - var pRetIn = (Watt)row[(int)ModalResultField.P_retarder_in]; - var pGbxInertia = (Watt)row[(int)ModalResultField.P_gbx_inertia]; - var pShiftLoss = row[(int)ModalResultField.P_gbx_shift_loss] is DBNull + : (Watt)row[ModalResultField.P_angle_loss.GetName()]; + var pAxleIn = (Watt)row[ModalResultField.P_axle_in.GetName()]; + var pLossRet = (Watt)row[ModalResultField.P_ret_loss.GetName()]; + var pRetIn = (Watt)row[ModalResultField.P_retarder_in.GetName()]; + var pGbxInertia = (Watt)row[ModalResultField.P_gbx_inertia.GetName()]; + var pShiftLoss = row[ModalResultField.P_gbx_shift_loss.GetName()] is DBNull ? 0.SI<Watt>() - : (Watt)row[(int)ModalResultField.P_gbx_shift_loss]; - var pEngInertia = (Watt)row[(int)ModalResultField.P_eng_inertia]; + : (Watt)row[ModalResultField.P_gbx_shift_loss.GetName()]; + var pEngInertia = (Watt)row[ModalResultField.P_eng_inertia.GetName()]; var pAux = - (Watt)(row[(int)ModalResultField.P_aux] != DBNull.Value ? row[(int)ModalResultField.P_aux] : 0.SI<Watt>()); - var pBrakeLoss = (Watt)row[(int)ModalResultField.P_brake_loss]; - var pBrakeIn = (Watt)row[(int)ModalResultField.P_brake_in]; - var pTcLoss = (Watt)row[(int)ModalResultField.P_TC_loss]; - var pTcOut = (Watt)row[(int)ModalResultField.P_TC_out]; - var pWheelInertia = (Watt)row[(int)ModalResultField.P_wheel_inertia]; + (Watt)(row[ModalResultField.P_aux.GetName()] != DBNull.Value ? row[ModalResultField.P_aux.GetName()] : 0.SI<Watt>()); + var pBrakeLoss = (Watt)row[ModalResultField.P_brake_loss.GetName()]; + var pBrakeIn = (Watt)row[ModalResultField.P_brake_in.GetName()]; + var pTcLoss = (Watt)row[ModalResultField.P_TC_loss.GetName()]; + var pTcOut = (Watt)row[ModalResultField.P_TC_out.GetName()]; + var pWheelInertia = (Watt)row[ModalResultField.P_wheel_inertia.GetName()]; var pPTOconsumer = ptoConsumerColumn == null || row[ptoConsumerColumn] is DBNull ? 0.SI<Watt>() : (Watt)row[ptoConsumerColumn]; diff --git a/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs b/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs index 8a70ff010ba6880cc0f5ca037c120b34a4cefac0..59c5abe8caedd2ad567552cd5b2749b76b823140 100644 --- a/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs +++ b/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs @@ -30,6 +30,7 @@ */ using System.IO; +using System.Linq; using System.Xml; using Ninject; using TUGraz.VectoCommon.Models; @@ -72,7 +73,7 @@ namespace TUGraz.VectoCore.Tests.Reports var writer = new FileOutputWriter("testsumcalc_fixed"); var sumWriter = new SummaryDataContainer(writer); - var modData = new ModalDataContainer("testsumcalc_fixed", FuelData.Diesel, writer); + var modData = new ModalDataContainer("testsumcalc_fixed", new [] { FuelData.Diesel}.ToList(), writer); modData.AddAuxiliary("FAN"); @@ -91,6 +92,7 @@ namespace TUGraz.VectoCore.Tests.Reports modData[ModalResultField.P_brake_loss] = 3000.SI<Watt>(); modData[ModalResultField.FCMap] = 1e-4.SI<KilogramPerSecond>(); + modData[ModalResultField.FCFinal] = 1e-4.SI<KilogramPerSecond>(); modData[ModalResultField.altitude] = 0.SI<Meter>(); modData[ModalResultField.acc] = 0.SI<MeterPerSquareSecond>(); @@ -132,7 +134,7 @@ namespace TUGraz.VectoCore.Tests.Reports var writer = new FileOutputWriter("testsumcalc_var"); var sumWriter = new SummaryDataContainer(writer); - var modData = new ModalDataContainer("testsumcalc_var", FuelData.Diesel, writer); + var modData = new ModalDataContainer("testsumcalc_var", new[] {FuelData.Diesel}.ToList(), writer); modData.AddAuxiliary("FAN"); var timeSteps = new[] @@ -159,6 +161,7 @@ namespace TUGraz.VectoCore.Tests.Reports modData[ModalResultField.P_eng_out] = (i % 2 == 0 ? 1 : -1) * powerDemand[i % powerDemand.Length]; modData[ModalResultField.P_eng_fcmap] = 0.SI<Watt>(); + modData[ModalResultField.FCFinal] = 0.SI<KilogramPerSecond>(); modData.CommitSimulationStep(); } @@ -209,7 +212,7 @@ namespace TUGraz.VectoCore.Tests.Reports Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.Manufacturer, sumRow[SummaryDataContainer.ENGINE_MANUFACTURER]); Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.Model, sumRow[SummaryDataContainer.ENGINE_MODEL]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.FuelType.ToXMLFormat(), + Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().FuelType.ToXMLFormat(), sumRow[SummaryDataContainer.ENGINE_FUEL_TYPE]); Assert.AreEqual((dataProvider.JobInputData.Vehicle.Components.EngineInputData.RatedPowerDeclared.ConvertToKiloWatt()), ((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_RATED_POWER])); @@ -224,16 +227,16 @@ namespace TUGraz.VectoCore.Tests.Reports sumRow[SummaryDataContainer.AXLE_MANUFACTURER]); Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.AxleGearInputData.Model, sumRow[SummaryDataContainer.AXLE_MODEL]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.ColdHotBalancingFactor, - sumRow[SummaryDataContainer.ENGINE_BF_COLD_HOT]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.CorrectionFactorRegPer, - sumRow[SummaryDataContainer.ENGINE_CF_REG_PER]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.WHTCRural, - sumRow[SummaryDataContainer.ENGINE_WHTC_RURAL]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.WHTCUrban, - sumRow[SummaryDataContainer.ENGINE_WHTC_URBAN]); - Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.WHTCMotorway, - sumRow[SummaryDataContainer.ENGINE_WHTC_MOTORWAY]); + Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().ColdHotBalancingFactor, + sumRow[SummaryDataContainer.ENGINE_BF_COLD_HOT].ToString().ToDouble()); + Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().CorrectionFactorRegPer, + sumRow[SummaryDataContainer.ENGINE_CF_REG_PER].ToString().ToDouble()); + Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().WHTCRural, + sumRow[SummaryDataContainer.ENGINE_WHTC_RURAL].ToString().ToDouble()); + Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().WHTCUrban, + sumRow[SummaryDataContainer.ENGINE_WHTC_URBAN].ToString().ToDouble()); + Assert.AreEqual(dataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().WHTCMotorway, + sumRow[SummaryDataContainer.ENGINE_WHTC_MOTORWAY].ToString().ToDouble()); } diff --git a/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs b/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs index 101206e872ec8b97fdf54f67b192301e2ba80883..638703b4f835e4b92a7667a11752b4ec3a2abad0 100644 --- a/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs +++ b/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs @@ -29,14 +29,16 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using System.Collections.Generic; using System.Data; +using System.Linq; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; namespace TUGraz.VectoCore.Tests.Utils { - public class MockEngineDataProvider : IEngineEngineeringInputData + public class MockEngineDataProvider : IEngineEngineeringInputData, IEngineModeDeclarationInputData, IEngineFuelDelcarationInputData { public DataSource DataSource { get; set; } public string Source { get; set; } @@ -59,9 +61,17 @@ namespace TUGraz.VectoCore.Tests.Utils public FuelType FuelType { get; set; } public TableData FuelConsumptionMap { get; set; } public TableData FullLoadCurve { get; set; } + + public IList<IEngineFuelDelcarationInputData> Fuels + { + get { return new[] { this }.Cast<IEngineFuelDelcarationInputData>().ToList(); } + } + public Watt RatedPowerDeclared { get; set; } public PerSecond RatedSpeedDeclared { get; set; } public NewtonMeter MaxTorqueDeclared { get; set; } + public IList<IEngineModeDeclarationInputData> EngineModes { get { return new[] { this }.Cast<IEngineModeDeclarationInputData>().ToList(); } } + public KilogramSquareMeter Inertia { get; set; } public double WHTCEngineering { get; set; } } diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 49b76d8f1700e1326a8e550962784a62cdd4696f..d9b4030b492dd0caaf2368433f0f30d0da7d191c 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -33,6 +33,8 @@ using System; using System.Collections.Generic; using System.Data; using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; @@ -46,11 +48,46 @@ namespace TUGraz.VectoCore.Tests.Utils /// </summary> internal class MockModalDataContainer : IModalDataContainer { + protected Dictionary<FuelData.Entry, Dictionary<ModalResultField, DataColumn>> FuelColumns = new Dictionary<FuelData.Entry, Dictionary<ModalResultField, DataColumn>>(); + + public MockModalDataContainer() { Data = new ModalResults(); + foreach (var value in EnumHelper.GetValues<ModalResultField>()) { + if (ModalDataContainer.FuelConsumptionSignals.Contains(value)) { + continue; + } + var col = new DataColumn(value.GetName(), value.GetAttribute().DataType) { Caption = value.GetCaption() }; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.Decimals] = value.GetAttribute().Decimals; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.OutputFactor] = value.GetAttribute().OutputFactor; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.ShowUnit] = value.GetAttribute().ShowUnit; + Data.Columns.Add(col); + } CurrentRow = Data.NewRow(); Auxiliaries = new Dictionary<string, DataColumn>(); + + AddFuels(new[] { VectoCore.Models.Declaration.FuelData.Diesel }.ToList()); + } + + protected void AddFuels(List<FuelData.Entry> fuels) + { + foreach (var entry in fuels) { + if (FuelColumns.ContainsKey(entry)) { + throw new VectoException("Fuel {0} already added!", entry.FuelType.GetLabel()); + } + FuelColumns[entry] = new Dictionary<ModalResultField, DataColumn>(); + foreach (var fcCol in ModalDataContainer.FuelConsumptionSignals) { + var col = Data.Columns.Add(fuels.Count == 1 ? fcCol.GetName() : string.Format("{0}_{1}", fcCol.GetName(), entry.FuelType.GetLabel()), typeof(SI)); + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.Decimals] = + fcCol.GetAttribute().Decimals; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.OutputFactor] = + fcCol.GetAttribute().OutputFactor; + col.ExtendedProperties[ModalResults.ExtendedPropertyNames.ShowUnit] = + fcCol.GetAttribute().ShowUnit; + FuelColumns[entry][fcCol] = col; + } + } } public ModalResults Data { get; set; } @@ -61,6 +98,24 @@ namespace TUGraz.VectoCore.Tests.Utils get { return ""; } } + public object this[ModalResultField key, FuelData.Entry fuel] + { + get { + if (!FuelColumns.ContainsKey(fuel) || !FuelColumns[fuel].ContainsKey(key)) { + throw new VectoException("unknown fuel {0} for key {1}", fuel.GetLabel(), key.GetName()); + } + + return CurrentRow[FuelColumns[fuel][key]]; + } + set { + if (!FuelColumns.ContainsKey(fuel) || !FuelColumns[fuel].ContainsKey(key)) { + throw new VectoException("unknown fuel {0} for key {1}", fuel.GetLabel(), key.GetName()); + } + + CurrentRow[FuelColumns[fuel][key]] = value; + } + } + public object this[string auxId] { get { return CurrentRow[Auxiliaries[auxId]]; } @@ -75,6 +130,8 @@ namespace TUGraz.VectoCore.Tests.Utils CurrentRow = Data.NewRow(); } + IList<FuelData.Entry> IModalDataContainer.FuelData { get { return FuelColumns.Keys.ToList(); } } + public FuelData.Entry FuelData { get { return VectoCore.Models.Declaration.FuelData.Diesel; } @@ -119,6 +176,11 @@ namespace TUGraz.VectoCore.Tests.Utils throw new NotImplementedException(); } + public T TimeIntegral<T>(string field, Func<SI, bool> filter = null) where T : SIBase<T> + { + throw new NotImplementedException(); + } + public Dictionary<string, DataColumn> Auxiliaries { get; set; } public void SetDataValue(string fieldName, object value) @@ -145,6 +207,15 @@ namespace TUGraz.VectoCore.Tests.Utils Data.Rows.Clear(); } + public string GetColumnName(FuelData.Entry fuelData, ModalResultField mrf) + { + if (!FuelColumns.ContainsKey(fuelData) || !FuelColumns[fuelData].ContainsKey(mrf)) { + throw new VectoException("unknown fuel {0} for key {1}", fuelData.GetLabel(), mrf.GetName()); + } + + return FuelColumns[fuelData][mrf].ColumnName; + } + public string RunName { get; set; } public string CycleName { get; set; } public string RunSuffix { get; set; } diff --git a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs index 7a9d507cebb9c3e2f92f1812ee010aa51080fc1d..e862fb3c91b4bb7bdce1bc3cca0c6f7cb2e68247 100644 --- a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs +++ b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs @@ -30,12 +30,14 @@ */ using System.Collections.Generic; +using System.Linq; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.InputData.FileIO.JSON; using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.SimulationComponent.Data; namespace TUGraz.VectoCore.Tests.Utils @@ -55,7 +57,15 @@ namespace TUGraz.VectoCore.Tests.Utils var engineInput = JSONInputDataFactory.ReadEngine(engineFile); if (declarationMode) { var dao = new DeclarationDataAdapter(); - var engineData = dao.CreateEngineData(engineInput, null, gearboxInput, new List<ITorqueLimitInputData>()); + var vehicleInput = new MockVehicleInputData() { + EngineInputData = engineInput, + GearboxInputData = gearboxInput + + }; + var mission = new Mission() { + MissionType = MissionType.LongHaul + }; + var engineData = dao.CreateEngineData(vehicleInput, engineInput.EngineModes.First(), mission);//(engineInput, null, gearboxInput, new List<ITorqueLimitInputData>()); return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>(), VehicleCategory.RigidTruck, (ITorqueConverterDeclarationInputData)gearboxInput); } else { diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleInputData.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleInputData.cs new file mode 100644 index 0000000000000000000000000000000000000000..f5180fedf1da01b186bc33a9869bcfe985c8f18a --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/MockVehicleInputData.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Tests.Utils { + public class MockVehicleInputData : IVehicleDeclarationInputData, IVehicleComponentsDeclaration + { + #region Implementation of IComponentInputData + + public DataSource DataSource { get; } + public bool SavedInDeclarationMode { get; } + public string Manufacturer { get; } + public string Model { get; } + public string Date { get; } + public CertificationMethod CertificationMethod { get; } + public string CertificationNumber { get; } + public DigestData DigestValue { get; } + + #endregion + + #region Implementation of IVehicleDeclarationInputData + + public string Identifier { get; } + public bool ExemptedVehicle { get; } + public string VIN { get; } + public LegislativeClass LegislativeClass { get; } + public VehicleCategory VehicleCategory { get; } + public AxleConfiguration AxleConfiguration { get; } + public Kilogram CurbMassChassis { get; } + public Kilogram GrossVehicleMassRating { get; } + public IList<ITorqueLimitInputData> TorqueLimits { get { return new List<ITorqueLimitInputData>(); } } + public string ManufacturerAddress { get; } + public PerSecond EngineIdleSpeed { get; } + public bool VocationalVehicle { get; } + public bool SleeperCab { get; } + public TankSystem? TankSystem { get; } + public IAdvancedDriverAssistantSystemDeclarationInputData ADAS { get; } + public bool ZeroEmissionVehicle { get; } + public bool HybridElectricHDV { get; } + public bool DualFuelVehicle { get; } + public Watt MaxNetPower1 { get; } + public Watt MaxNetPower2 { get; } + public IVehicleComponentsDeclaration Components { get { return this; } } + + #endregion + + #region Implementation of IVehicleComponentsDeclaration + + public IAirdragDeclarationInputData AirdragInputData { get; set; } + public IGearboxDeclarationInputData GearboxInputData { get; set; } + public ITorqueConverterDeclarationInputData TorqueConverterInputData { get; set; } + public IAxleGearInputData AxleGearInputData { get; set; } + public IAngledriveInputData AngledriveInputData { get; set; } + public IEngineDeclarationInputData EngineInputData { get; set; } + public IAuxiliariesDeclarationInputData AuxiliaryInputData { get; set; } + public IRetarderInputData RetarderInputData { get; set; } + public IPTOTransmissionInputData PTOTransmissionInputData { get; set; } + public IAxlesDeclarationInputData AxleWheels { get; set; } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj index c986de6dbee901e06fecfc4015e5da326c966dbe..5ce84203df8c3d0334d7402264884a8513b60ec2 100644 --- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj +++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj @@ -180,6 +180,7 @@ <Compile Include="Utils\AssertHelper.cs" /> <Compile Include="Utils\MockDriver.cs" /> <Compile Include="Utils\MockVehicle.cs" /> + <Compile Include="Utils\MockVehicleInputData.cs" /> <Compile Include="Utils\ResultFileHelper.cs" /> <Compile Include="Utils\MockPorts.cs" /> <Compile Include="Models\Simulation\SimulationTests.cs" /> @@ -2911,6 +2912,15 @@ <Content Include="TestData\XML\XMLReaderDeclaration\SchemaVersion2.2\vecto_vehicle-sample_LNG.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="TestData\XML\XMLReaderDeclaration\SchemaVersion2.3\engineSample.xml"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="TestData\XML\XMLReaderDeclaration\SchemaVersion2.3\engineSampleDualModeDualFuel.xml"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + <Content Include="TestData\XML\XMLReaderDeclaration\SchemaVersion2.3\vehicle_sampleDualModeDualFuel.xml"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <Content Include="TestData\XML\XMLReaderDeclaration\Tractor_4x2_vehicle-class-5_5_t_0.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> diff --git a/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs b/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs index b1e25edcaff1d0597f168d23a8c1eb8cbb270fea..ef6c2524d1523bc69b0ed39573894df40f0efae6 100644 --- a/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs +++ b/VectoCore/VectoCoreTest/XML/XMLDeclarationInputTest.cs @@ -95,10 +95,10 @@ namespace TUGraz.VectoCore.Tests.XML Assert.AreEqual("Generic 40t Long Haul Truck Engine", engineDataProvider.Model); Assert.AreEqual(0.012730, engineDataProvider.Displacement.Value()); - Assert.AreEqual(1.0097, engineDataProvider.WHTCUrban); + Assert.AreEqual(1.0097, engineDataProvider.EngineModes.First().Fuels.First().WHTCUrban); //AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.Inertia; }); - var fcMapTable = engineDataProvider.FuelConsumptionMap; + var fcMapTable = engineDataProvider.EngineModes.First().Fuels.First().FuelConsumptionMap; Assert.AreEqual(112, fcMapTable.Rows.Count); Assert.AreEqual("engine speed", fcMapTable.Columns[0].Caption); Assert.AreEqual("torque", fcMapTable.Columns[1].Caption); @@ -109,7 +109,7 @@ namespace TUGraz.VectoCore.Tests.XML Assert.AreEqual(1256.SI(Unit.SI.Gramm.Per.Hour).Value(), fcMap.GetFuelConsumption(0.SI<NewtonMeter>(), 560.RPMtoRad()).Value.Value()); - var fldTable = engineDataProvider.FullLoadCurve; + var fldTable = engineDataProvider.EngineModes.First().FullLoadCurve; Assert.AreEqual(10, fldTable.Rows.Count); Assert.AreEqual("engine speed", fldTable.Columns[0].Caption); Assert.AreEqual("full load torque", fldTable.Columns[1].Caption); @@ -151,7 +151,7 @@ namespace TUGraz.VectoCore.Tests.XML var modified = XmlReader.Create(new StringReader(nav.OuterXml)); var inputDataProvider = xmlInputReader.CreateDeclaration(modified); - var fuelTyle = inputDataProvider.JobInputData.Vehicle.Components.EngineInputData.FuelType; + var fuelTyle = inputDataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().FuelType; Assert.AreEqual(fuel, fuelTyle.ToXMLFormat()); var tankSystem = fuelTyle == FuelType.NGPI || fuelTyle == FuelType.NGCI ? TankSystem.Liquefied : (TankSystem?)null; Assert.NotNull(DeclarationData.FuelData.Lookup(fuelTyle, tankSystem)); @@ -183,7 +183,7 @@ namespace TUGraz.VectoCore.Tests.XML var modified = XmlReader.Create(new StringReader(nav.OuterXml)); var inputDataProvider = xmlInputReader.CreateDeclaration(modified); - var fuelTyle = inputDataProvider.JobInputData.Vehicle.Components.EngineInputData.FuelType; + var fuelTyle = inputDataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().FuelType; Assert.AreEqual(fuel, fuelTyle.ToXMLFormat()); AssertHelper.Exception<VectoException>( () => { @@ -1071,7 +1071,7 @@ namespace TUGraz.VectoCore.Tests.XML var inputDataProvider = xmlInputReader.CreateDeclaration(modified); - var fuelType = inputDataProvider.JobInputData.Vehicle.Components.EngineInputData.FuelType; + var fuelType = inputDataProvider.JobInputData.Vehicle.Components.EngineInputData.EngineModes.First().Fuels.First().FuelType; Assert.AreEqual(expectedFuelType, fuelType); } diff --git a/VectoCore/VectoCoreTest/XML/XMLEngineeringInputRefTest.cs b/VectoCore/VectoCoreTest/XML/XMLEngineeringInputRefTest.cs index 223d70b717d65d97a85b3dcb5e0477c1cf8233c7..baec91efdd58cf89b7699e1acde85948fc1f60ec 100644 --- a/VectoCore/VectoCoreTest/XML/XMLEngineeringInputRefTest.cs +++ b/VectoCore/VectoCoreTest/XML/XMLEngineeringInputRefTest.cs @@ -90,11 +90,11 @@ namespace TUGraz.VectoCore.Tests.XML Assert.AreEqual(0.012730, engineDataProvider.Displacement.Value()); Assert.AreEqual(0.77, engineDataProvider.Inertia.Value()); - AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.WHTCMotorway; }); - AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.WHTCRural; }); - AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.WHTCUrban; }); + AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.EngineModes.First().Fuels.First().WHTCMotorway; }); + AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.EngineModes.First().Fuels.First().WHTCRural; }); + AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.EngineModes.First().Fuels.First().WHTCUrban; }); - var fcMapTable = engineDataProvider.FuelConsumptionMap; + var fcMapTable = engineDataProvider.EngineModes.First().Fuels.First().FuelConsumptionMap; Assert.AreEqual(112, fcMapTable.Rows.Count); Assert.AreEqual("engine speed", fcMapTable.Columns[0].Caption); Assert.AreEqual("torque", fcMapTable.Columns[1].Caption); @@ -105,7 +105,7 @@ namespace TUGraz.VectoCore.Tests.XML Assert.AreEqual(1256.SI(Unit.SI.Gramm.Per.Hour).Value(), fcMap.GetFuelConsumption(0.SI<NewtonMeter>(), 560.RPMtoRad()).Value.Value()); - var fldTable = engineDataProvider.FullLoadCurve; + var fldTable = engineDataProvider.EngineModes.First().FullLoadCurve; Assert.AreEqual(10, fldTable.Rows.Count); Assert.AreEqual("engine speed", fldTable.Columns[0].Caption); Assert.AreEqual("full load torque", fldTable.Columns[1].Caption); diff --git a/VectoCore/VectoCoreTest/XML/XMLEngineeringInputSingleTest.cs b/VectoCore/VectoCoreTest/XML/XMLEngineeringInputSingleTest.cs index f53762ea539ddcdc96a32cca0668f218896e48c1..1eba37d4bc6f17fb7c5930259cfaccd6931455bf 100644 --- a/VectoCore/VectoCoreTest/XML/XMLEngineeringInputSingleTest.cs +++ b/VectoCore/VectoCoreTest/XML/XMLEngineeringInputSingleTest.cs @@ -94,11 +94,11 @@ namespace TUGraz.VectoCore.Tests.XML Assert.AreEqual(0.012730, engineDataProvider.Displacement.Value()); Assert.AreEqual(0.77, engineDataProvider.Inertia.Value()); - AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.WHTCMotorway; }); - AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.WHTCRural; }); - AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.WHTCUrban; }); + AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.EngineModes.First().Fuels.First().WHTCMotorway; }); + AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.EngineModes.First().Fuels.First().WHTCRural; }); + AssertHelper.Exception<VectoException>(() => { var tmp = engineDataProvider.EngineModes.First().Fuels.First().WHTCUrban; }); - var fcMapTable = engineDataProvider.FuelConsumptionMap; + var fcMapTable = engineDataProvider.EngineModes.First().Fuels.First().FuelConsumptionMap; Assert.AreEqual(112, fcMapTable.Rows.Count); Assert.AreEqual("engine speed", fcMapTable.Columns[0].Caption); Assert.AreEqual("torque", fcMapTable.Columns[1].Caption); @@ -109,7 +109,7 @@ namespace TUGraz.VectoCore.Tests.XML Assert.AreEqual(1256.SI(Unit.SI.Gramm.Per.Hour).Value(), fcMap.GetFuelConsumption(0.SI<NewtonMeter>(), 560.RPMtoRad()).Value.Value()); - var fldTable = engineDataProvider.FullLoadCurve; + var fldTable = engineDataProvider.EngineModes.First().FullLoadCurve; Assert.AreEqual(10, fldTable.Rows.Count); Assert.AreEqual("engine speed", fldTable.Columns[0].Caption); Assert.AreEqual("full load torque", fldTable.Columns[1].Caption); diff --git a/VectoCore/VectoCoreTest/XML/XMLReportTest.cs b/VectoCore/VectoCoreTest/XML/XMLReportTest.cs index 2c4d0ef59bfa97583e0ce41d4b69cbe3880fc6cd..fb7c3ad93fe0d2fa0eaaac6e8cc81993e735a9a6 100644 --- a/VectoCore/VectoCoreTest/XML/XMLReportTest.cs +++ b/VectoCore/VectoCoreTest/XML/XMLReportTest.cs @@ -95,13 +95,13 @@ namespace TUGraz.VectoCore.Tests.XML var validationMsg1 = new List<string> {customerRecord} ; var validator1 = new XMLValidator(XmlReader.Create(customerRecord), validationErrorAction: (s,e) => { - validationMsg1.Add(e.ValidationEventArgs.Message); + validationMsg1.Add(e?.ValidationEventArgs?.Message ?? "no schema found?"); }); Assert.IsTrue(validator1.ValidateXML(XmlDocumentType.CustomerReport), string.Join("\n", validationMsg1)); var validationMsg2 = new List<string> {manufacturerRecord}; var validator2 = new XMLValidator(XmlReader.Create(manufacturerRecord), validationErrorAction: (s,e) => { - validationMsg2.Add(e.ValidationEventArgs.Message); + validationMsg2.Add(e?.ValidationEventArgs?.Message ?? "no schema found"); }); Assert.IsTrue(validator2.ValidateXML(XmlDocumentType.ManufacturerReport), string.Join("\n", validationMsg2)); }