diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index 2ef6cc25beda86e4a363a09b5261b64afae7d7ff..8246a337ee1dd4b53a01732a5d30862adbe8d445 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -117,8 +117,9 @@ namespace TUGraz.VectoCore.OutputData Func<Second, Joule, Joule> AuxHeaterDemandCalc { get; set; } - KilogramPerWattSecond VehicleLineCorrectionFactor(IFuelProperties fuel); + KilogramPerWattSecond EngineLineCorrectionFactor(IFuelProperties fuel); void CalculateAggregateValues(); + KilogramPerWattSecond VehicleLineSlope(IFuelProperties fuel); } public static class ModalDataContainerExtensions @@ -332,7 +333,13 @@ namespace TUGraz.VectoCore.OutputData return data.WorkWheelsPos() / data.Duration; } + public static Watt PowerWheel(this IModalDataContainer data) + { + return data.TimeIntegral<WattSecond>(ModalResultField.P_wheel_in) / data.Duration; + } + + public static KilogramPerSecond FuelConsumptionPerSecond(this IModalDataContainer data, ModalResultField mrf, IFuelProperties fuelData) { return data.TimeIntegral<Kilogram>(data.GetColumnName(fuelData, mrf)) / data.Duration; @@ -403,9 +410,12 @@ namespace TUGraz.VectoCore.OutputData public static Watt TotalPowerEnginePositiveAverage(this IModalDataContainer data) { - var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval); - var values = data.GetValues<Watt>(ModalResultField.P_ice_fcmap) - .Zip(simulationIntervals, (value, dt) => new { Dt = dt, Value = value * dt }) + //var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval); + var values = data.GetValues(x => new { + Value = x.Field<Watt>(ModalResultField.P_ice_fcmap.GetName()).DefaultIfNull(0) * x.Field<Second>(ModalResultField.simulationInterval.GetName()) + }) + //.GetValues<Watt>(ModalResultField.P_ice_fcmap) + //.Zip(simulationIntervals, (value, dt) => new { Dt = dt, Value = value * dt }) .Where(v => v.Value > 0).ToList(); if (values.Any()) { return values.Sum(v => v.Value) / data.Duration; @@ -413,6 +423,20 @@ namespace TUGraz.VectoCore.OutputData return 0.SI<Watt>(); } + public static Watt TotalPowerEngineAverage(this IModalDataContainer data) + { + var values = data.GetValues( + x => new { + Value = x.Field<Watt>(ModalResultField.P_ice_fcmap.GetName()).DefaultIfNull(0) * + x.Field<Second>(ModalResultField.simulationInterval.GetName()) + }).ToList(); + if (values.Any()) { + return values.Sum(v => v.Value) / data.Duration; + } + + return 0.SI<Watt>(); + } + public static MeterPerSecond Speed(this IModalDataContainer data) { var distance = data.Distance; diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 49b67df69f16d253fcf2e14a086ab7eacdf305ce..04711cb0e71ff5a10398d9af0fb1b00028417b07 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -67,7 +67,8 @@ namespace TUGraz.VectoCore.OutputData }; private readonly Dictionary<String, SI> _timeIntegrals = new Dictionary<string, SI>(); - private readonly Dictionary<FuelType, KilogramPerWattSecond> _vehicleLine = new Dictionary<FuelType, KilogramPerWattSecond>(); + private readonly Dictionary<FuelType, KilogramPerWattSecond> _engLine = new Dictionary<FuelType, KilogramPerWattSecond>(); + private readonly Dictionary<FuelType, KilogramPerWattSecond> _vehLine = new Dictionary<FuelType, KilogramPerWattSecond>(); public int JobRunId { get; } public string RunName { get; } @@ -166,10 +167,10 @@ namespace TUGraz.VectoCore.OutputData public Func<Second, Joule, Joule> AuxHeaterDemandCalc { get; set; } - public KilogramPerWattSecond VehicleLineCorrectionFactor(IFuelProperties fuel) + public KilogramPerWattSecond EngineLineCorrectionFactor(IFuelProperties fuel) { - if (_vehicleLine.ContainsKey(fuel.FuelType)) { - return _vehicleLine[fuel.FuelType]; + if (_engLine.ContainsKey(fuel.FuelType)) { + return _engLine[fuel.FuelType]; } double k, d, r; @@ -181,9 +182,29 @@ namespace TUGraz.VectoCore.OutputData x.Field<SI>(GetColumnName(fuel, ModalResultField.FCFinal)).Value()) : null).Where(x => x != null && x.Y > 0), out k, out d, out r); - _vehicleLine[fuel.FuelType] = k.SI<KilogramPerWattSecond>(); + _engLine[fuel.FuelType] = k.SI<KilogramPerWattSecond>(); - return _vehicleLine[fuel.FuelType]; + return _engLine[fuel.FuelType]; + } + + public KilogramPerWattSecond VehicleLineSlope(IFuelProperties fuel) + { + if (_vehLine.ContainsKey(fuel.FuelType)) { + return _vehLine[fuel.FuelType]; + } + + double k, d, r; + VectoMath.LeastSquaresFitting( + GetValues( + row => row.Field<bool>(ModalResultField.ICEOn.GetName()) + ? new Point( + row.Field<SI>(ModalResultField.P_wheel_in.GetName()).Value(), + row.Field<SI>(GetColumnName(fuel, ModalResultField.FCFinal)).Value()) + : null) + .Where(x => x != null && x.Y > 0), out k, out d, out r); + + _vehLine[fuel.FuelType] = k.SI<KilogramPerWattSecond>(); + return _vehLine[fuel.FuelType]; } public void CalculateAggregateValues() @@ -195,7 +216,7 @@ namespace TUGraz.VectoCore.OutputData } foreach (var fuel in FuelColumns.Keys) { - VehicleLineCorrectionFactor(fuel); + EngineLineCorrectionFactor(fuel); TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCMap)); TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCNCVc)); TimeIntegral<Kilogram>(GetColumnName(fuel, ModalResultField.FCWHTCc)); diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs index df89f178b4995ecf2b7f0d53f188ba2ebaa87e85..da5b16683c524a04d3a5da695b73e96d08985dc6 100644 --- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs @@ -67,7 +67,7 @@ namespace TUGraz.VectoCore.OutputData Fields.FC_AUXHTR_H_CORR, Fields.FC_AUXHTR_KM_CORR, Fields.FCFINAL_H, Fields.FCFINAL_KM, Fields.FCFINAL_LITERPER100KM, Fields.FCFINAL_LITERPER100TKM, Fields.FCFINAL_LiterPer100M3KM, Fields.FCFINAL_LiterPer100PassengerKM, - Fields.SPECIFIC_FC, Fields.K_VEHLINE + Fields.SPECIFIC_FC, Fields.K_VEHLINE, Fields.K_ENGLINE }; // ReSharper restore InconsistentNaming @@ -175,7 +175,7 @@ namespace TUGraz.VectoCore.OutputData Table.Columns.AddRange( new[] { - Fields.CO2_KM, Fields.CO2_TKM, Fields.CO2_M3KM, Fields.CO2_PKM, Fields.P_WHEEL_POS, Fields.P_FCMAP_POS, + Fields.CO2_KM, Fields.CO2_TKM, Fields.CO2_M3KM, Fields.CO2_PKM, Fields.P_WHEEL, Fields.P_WHEEL_POS, Fields.P_FCMAP, Fields.P_FCMAP_POS, Fields.E_FCMAP_POS, Fields.E_FCMAP_NEG, Fields.E_POWERTRAIN_INERTIA, Fields.E_AUX, Fields.E_CLUTCH_LOSS, Fields.E_TC_LOSS, Fields.E_SHIFT_LOSS, Fields.E_GBX_LOSS, Fields.E_RET_LOSS, Fields.E_ANGLE_LOSS, Fields.E_AXL_LOSS, Fields.E_BRAKE, Fields.E_VEHICLE_INERTIA, Fields.E_WHEEL, Fields.E_AIR, Fields.E_ROLL, Fields.E_GRAD, @@ -328,8 +328,10 @@ namespace TUGraz.VectoCore.OutputData } row[Fields.P_WHEEL_POS] = modData.PowerWheelPositive().ConvertToKiloWatt(); - + row[Fields.P_WHEEL] = modData.PowerWheel().ConvertToKiloWatt(); + row[Fields.P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertToKiloWatt(); + row[Fields.P_FCMAP] = modData.TotalPowerEngineAverage().ConvertToKiloWatt(); WriteAuxiliaries(modData, row, runData.BusAuxiliaries != null); @@ -438,10 +440,12 @@ namespace TUGraz.VectoCore.OutputData var fcModSum = modData.TotalFuelConsumption(ModalResultField.FCFinal, fuel); - var correction = modData.VehicleLineCorrectionFactor(fuel); - - row[FcCol(Fields.K_VEHLINE, suffix)] = correction.ConvertToGramPerKiloWattHour(); + var correction = modData.EngineLineCorrectionFactor(fuel); + row[FcCol(Fields.K_ENGLINE, suffix)] = correction.ConvertToGramPerKiloWattHour(); + + row[FcCol(Fields.K_VEHLINE, suffix)] = modData.VehicleLineSlope(fuel).ConvertToGramPerKiloWattHour(); + var fcEssCorr = fcModSum + correction * workESS; row[FcCol(Fields.FCESS_H_CORR, suffix)] = duration != null ? (fcEssCorr / duration).ConvertToGrammPerHour() : null; @@ -1054,7 +1058,9 @@ namespace TUGraz.VectoCore.OutputData public const string CO2_PKM = "CO2 [g/Pkm]"; public const string P_WHEEL_POS = "P_wheel_in_pos [kW]"; + public const string P_WHEEL = "P_wheel_in [kW]"; public const string P_FCMAP_POS = "P_fcmap_pos [kW]"; + public const string P_FCMAP = "P_fcmap [kW]"; public const string E_FORMAT = "E_{0} [kWh]"; public const string E_AUX_FORMAT = "E_aux_{0} [kWh]"; @@ -1063,6 +1069,7 @@ namespace TUGraz.VectoCore.OutputData public const string E_AUX_ESS_MECH = "E_aux_ess_mech [kWh]"; public const string E_ICE_START = "E_ice_start [kWh]"; public const string NUM_ICE_STARTS = "ice_starts [-]"; + public const string K_ENGLINE = "k_engline{0} [g/kWh]"; public const string K_VEHLINE = "k_vehline{0} [g/kWh]"; public const string E_WHR_EL = "E_WHR_el [kWh]"; diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index c8daa8719d77651195acca2050be83ae42690fd8..43be3f6bae2a7307405baeb39a07f25be02a07ac 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -185,7 +185,7 @@ namespace TUGraz.VectoCore.OutputData.XML var correction = 0.SI<KilogramPerWattSecond>(); if (!(workWHR + workESS + workBusAuxCorr).IsEqual(0)) { - correction = data.VehicleLineCorrectionFactor(entry); + correction = data.EngineLineCorrectionFactor(entry); } var fcAuxHtr = 0.SI<Kilogram>(); if (firstFuel) { diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs index 30907527c2083b3b87410f18c02e7d3b2cf41fd7..54812ad631a74bfab2b2e3f10f47a584bbc0ffec 100644 --- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs +++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs @@ -236,7 +236,7 @@ namespace TUGraz.VectoCore.Tests.Utils public Func<Second, Joule, Joule> AuxHeaterDemandCalc { get; set; } - public KilogramPerWattSecond VehicleLineCorrectionFactor(IFuelProperties fuel) + public KilogramPerWattSecond EngineLineCorrectionFactor(IFuelProperties fuel) { return 0.SI<KilogramPerWattSecond>(); } @@ -246,6 +246,11 @@ namespace TUGraz.VectoCore.Tests.Utils } + public KilogramPerWattSecond VehicleLineSlope(IFuelProperties fuel) + { + return 0.SI<KilogramPerWattSecond>(); + } + public string RunName { get; set; } public string CycleName { get; set; } public string RunSuffix { get; set; }