diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs index 1557949c4a2a338c3a579e26440b098e62d4f589..cdc2711263193905ecd9e733a1f87cf6016e6107 100644 --- a/VectoCommon/VectoCommon/Utils/SI.cs +++ b/VectoCommon/VectoCommon/Utils/SI.cs @@ -512,6 +512,11 @@ namespace TUGraz.VectoCommon.Utils { return SIBase<CubicMeterPerSecond>.Create(m3.Val * ps.Value()); } + + public static CubicMeterPerMeter operator /(CubicMeter m3, Meter m) + { + return SIBase<CubicMeterPerMeter>.Create(m3.Value() / m.Value()); + } } public class CubicMeterPerSecond : SIBase<CubicMeterPerSecond> @@ -533,6 +538,42 @@ namespace TUGraz.VectoCommon.Utils } } + public class CubicMeterPerMeter : SIBase<CubicMeterPerMeter> + { + private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private CubicMeterPerMeter(double value) : base(value, Units) { } + + public static CubicMeterPerKilogramMeter operator /(CubicMeterPerMeter m3pm, Kilogram kg) + { + return SIBase<CubicMeterPerKilogramMeter>.Create(m3pm.Value() / kg.Value()); + } + + public static CubicMeterPerCubicMeterMeter operator /(CubicMeterPerMeter m3pm, CubicMeter m3) + { + return SIBase<CubicMeterPerCubicMeterMeter>.Create(m3pm.Value() / m3.Value()); + } + } + + public class CubicMeterPerKilogramMeter : SIBase<CubicMeterPerKilogramMeter> + { + private static readonly int[] Units = { -1, 2, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private CubicMeterPerKilogramMeter(double value) + : base(value, Units) { } + } + + public class CubicMeterPerCubicMeterMeter : SIBase<CubicMeterPerCubicMeterMeter> + { + private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 }; + + [DebuggerHidden] + private CubicMeterPerCubicMeterMeter(double value) + : base(value, Units) { } + } + /// <summary> /// SI Class for Kilogram Square Meter [kgm^2]. /// </summary> @@ -618,6 +659,39 @@ namespace TUGraz.VectoCommon.Utils { return SIBase<Kilogram>.Create(ws.Val * kpws.Value()); } + + public static WattSecondPerMeter operator /(WattSecond wattSecond, Meter m) + { + return SIBase<WattSecondPerMeter>.Create(wattSecond.Val / m.Value()); + } + + + } + + public class WattSecondPerMeter : SIBase<WattSecondPerMeter> + { + private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private WattSecondPerMeter(double val) : base(val, Units) { } + + public static WattSecondPerMeterKilogram operator /(WattSecondPerMeter wattSecond, Kilogram kg) + { + return SIBase<WattSecondPerMeterKilogram>.Create(wattSecond.Val / kg.Value()); + } + + public static WattSecondPerCubicMeterMeter operator /(WattSecondPerMeter wattSecond, CubicMeter m3) + { + return SIBase<WattSecondPerCubicMeterMeter>.Create(wattSecond.Val / m3.Value()); + } + } + + public class WattSecondPerCubicMeterMeter : SIBase<WattSecondPerCubicMeterMeter> + { + private static readonly int[] Units = { 1, -2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private WattSecondPerCubicMeterMeter(double val) : base(val, Units) { } } public class WattSecondPerCubicMeter : SIBase<WattSecondPerCubicMeter> @@ -628,6 +702,14 @@ namespace TUGraz.VectoCommon.Utils private WattSecondPerCubicMeter(double val) : base(val, Units) { } } + public class WattSecondPerMeterKilogram : SIBase<WattSecondPerMeterKilogram> + { + private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private WattSecondPerMeterKilogram(double val) : base(val, Units) { } + } + public class WattPerKelvinSquareMeter : SIBase<WattPerKelvinSquareMeter> { private static readonly int[] Units = { 1, 0, -3, 0, -1, 0, 0 }; @@ -845,6 +927,36 @@ namespace TUGraz.VectoCommon.Utils { return SIBase<KilogramPerMeter>.Create(jpm.Val / jpkg.Value()); } + + public static JoulePerCubicMeterMeter operator /(JoulePerMeter jpm, CubicMeter m3) + { + return SIBase<JoulePerCubicMeterMeter>.Create(jpm.Val / m3.Value()); + } + + public static JoulePerKilogramMeter operator /(JoulePerMeter jpm, Kilogram kg) + { + return SIBase<JoulePerKilogramMeter>.Create(jpm.Val / kg.Value()); + } + } + + public class JoulePerCubicMeterMeter : SIBase<JoulePerCubicMeterMeter> + { + private static readonly int[] Units = { 1, -2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private JoulePerCubicMeterMeter(double val) : base(val, Units) { } + + public override string UnitString => "J/m³-m"; + } + + public class JoulePerKilogramMeter : SIBase<JoulePerKilogramMeter> + { + private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private JoulePerKilogramMeter(double val) : base(val, Units) { } + + public override string UnitString => "J/kg-m"; } /// <summary> diff --git a/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs b/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs index ab74fef5866b89cca8e603d170a10429fa74b4cb..a8eb5e8a583e86bcbd9e689cee69248f33710254 100644 --- a/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs +++ b/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs @@ -114,8 +114,14 @@ namespace TUGraz.VectoCommon.Utils public static class SIConvertExtensionMethods { private const int Kilo = 1000; + private const double Mega = 1e6; private const int SecondsPerHour = 60 * 60; - + private const int SecondsPerMinute = 60 * 60; + const int CubicMeterToLiter = 10 * 10 * 10; + const int CubicMeterToCubicCentimeter = 100 * 100 * 100; + const int MeterTo100KiloMeter = 100 * Kilo; + const int KilogrammToTon = Kilo; + public static ConvertedSI ConvertToGramm(this Kilogram value) { return new ConvertedSI(value.Value() * Kilo, "g"); @@ -133,20 +139,25 @@ namespace TUGraz.VectoCommon.Utils return value == null ? null : new ConvertedSI(value.Value() * Kilo * Kilo, "g/km"); } + public static ConvertedSI ConvertToGrammPerPassengerKilometer(this KilogramPerMeter value) + { + return value == null ? null : new ConvertedSI(value.Value() * Kilo * Kilo, "g/p-km"); + } + public static ConvertedSI ConvertToKiloWattHourPerKiloMeter(this JoulePerMeter value) { - return new ConvertedSI(value.Value() / 3600, "kWh/km"); + return new ConvertedSI(value.Value() / SecondsPerHour, "kWh/km"); } public static ConvertedSI ConvertToGramPerKiloWattHour(this SpecificFuelConsumption value) { - return new ConvertedSI(value.Value() * 3600e6, "g/kWh"); + return new ConvertedSI(value.Value() * SecondsPerHour * Mega, "g/kWh"); } public static ConvertedSI ConvertToGramPerKiloWattHour(this KilogramPerWattSecond value) { - return new ConvertedSI(value.Value() * 3600e6, "g/kWh"); + return new ConvertedSI(value.Value() * SecondsPerHour *Mega, "g/kWh"); } public static ConvertedSI ConvertToLiterPer100Kilometer(this VolumePerMeter value) @@ -156,17 +167,11 @@ namespace TUGraz.VectoCommon.Utils public static ConvertedSI ConvertToLiterPer100TonKiloMeter(this VolumePerMeterMass value) { - const int CubicMeterToLiter = 10 * 10 * 10; - const int MeterTo100KiloMeter = 100 * Kilo; - const int KilogrammToTon = Kilo; - return value == null ? null : new ConvertedSI(value.Value() * CubicMeterToLiter * (MeterTo100KiloMeter * KilogrammToTon), "l/100tkm"); } public static ConvertedSI ConvertToLiterPerCubicMeter100KiloMeter(this VolumePerMeterVolume value) { - const int CubicMeterToLiter = 10 * 10 * 10; - const int MeterTo100KiloMeter = 100 * Kilo; return new ConvertedSI(value.Value() * CubicMeterToLiter * MeterTo100KiloMeter, "l/100m³-km"); } @@ -182,7 +187,7 @@ namespace TUGraz.VectoCommon.Utils public static ConvertedSI ConvertToCubicCentiMeter(this CubicMeter value) { - return new ConvertedSI(value.Value() * 100 * 100 * 100, "cm³"); + return new ConvertedSI(value.Value() * CubicMeterToCubicCentimeter, "cm³"); } public static ConvertedSI ConvertToGrammPerCubicMeterKiloMeter(this KilogramPerMeterCubicMeter value) @@ -199,6 +204,46 @@ namespace TUGraz.VectoCommon.Utils { return new ConvertedSI(value.Value() / Kilo / SecondsPerHour, "kWh"); } + + public static ConvertedSI ConvertToKiloWattHourPerKiloMeter(this WattSecondPerMeter value) + { + return new ConvertedSI(value.Value() / Kilo / SecondsPerHour * Kilo, "kWh/km"); + } + + public static ConvertedSI ConvertToKiloWattHourPerPassengerKiloMeter(this WattSecondPerMeter value) + { + return new ConvertedSI(value.Value() / Kilo / SecondsPerHour * Kilo, "kWh/p-km"); + } + + public static ConvertedSI ConvertToKiloWattHourPerTonKiloMeter(this WattSecondPerMeterKilogram value) + { + return new ConvertedSI(value.Value() / Kilo / SecondsPerHour * Kilo * KilogrammToTon, "kWh/t-km"); + } + + public static ConvertedSI ConvertToKiloWattHourPerCubicMeterKiloMeter(this WattSecondPerCubicMeterMeter value) + { + return new ConvertedSI(value.Value() / Kilo / SecondsPerHour * Kilo, "kWh/m³-km"); + } + + public static ConvertedSI ConvertToMegaJoulePerKiloMeter(this WattSecondPerMeter value) + { + return new ConvertedSI(value.Value() / Mega * Kilo, "MJ/km"); + } + public static ConvertedSI ConvertToMegaJoulePerPassengerKiloMeter(this WattSecondPerMeter value) + { + return new ConvertedSI(value.Value() / Mega * Kilo, "MJ/p-km"); + } + + public static ConvertedSI ConvertToMegaJoulePerTonKiloMeter(this WattSecondPerMeterKilogram value) + { + return new ConvertedSI(value.Value() / Mega * Kilo * KilogrammToTon, "MJ/t-km"); + } + + public static ConvertedSI ConvertToMegaJoulePerCubicMeterKiloMeter(this WattSecondPerCubicMeterMeter value) + { + return new ConvertedSI(value.Value() / Mega * Kilo , "MJ/m³-km"); + } + public static ConvertedSI ConvertToWattHour(this WattSecond value) { return new ConvertedSI(value.Value() / SecondsPerHour, "Wh"); @@ -225,7 +270,7 @@ namespace TUGraz.VectoCommon.Utils public static ConvertedSI ConvertToCubicDeziMeter(this CubicMeter value) { - return new ConvertedSI(value.Value() * 10 * 10 * 10, "dm^3"); + return new ConvertedSI(value.Value() * CubicMeterToLiter, "dm^3"); } public static ConvertedSI ConvertToMilliMeter(this Meter value) { @@ -244,17 +289,52 @@ namespace TUGraz.VectoCommon.Utils public static ConvertedSI ConvertToMinutes(this Second sec) { - return new ConvertedSI(sec.Value() / 60.0, "min"); + return new ConvertedSI(sec.Value() / SecondsPerMinute, "min"); } public static ConvertedSI ConvertToNlPerMin(this NormLiterPerSecond nlps) { - return new ConvertedSI(nlps.Value() * 60.0, "Nl/min"); + return new ConvertedSI(nlps.Value() * SecondsPerMinute, "Nl/min"); } public static ConvertedSI ConvertToMegaJoulePerKilometer(this JoulePerMeter jpm) { - return new ConvertedSI(jpm.Value() * 1e-3, "MJ/km"); + return new ConvertedSI(jpm.Value() / Mega * Kilo, "MJ/km"); + } + + public static ConvertedSI ConvertToMegaJoulePerPassengerKilometer(this JoulePerMeter jpm) + { + return new ConvertedSI(jpm.Value() / Mega * Kilo, "MJ/p-km"); + } + + public static ConvertedSI ConvertToMegaJoulePerTonKiloMeter(this JoulePerKilogramMeter jpkgm) + { + return new ConvertedSI(jpkgm.Value() /Mega * Kilo * Kilo, "MJ/t-km"); + } + + public static ConvertedSI ConvertToMegaJoulePerCubicMeterKiloMeter(this JoulePerCubicMeterMeter jpm3m) + { + return new ConvertedSI(jpm3m.Value() / Mega * Kilo, "MJ/m³-km"); + } + + public static ConvertedSI ConvertToLiterPer100KiloMeter(this CubicMeterPerMeter jpm3m) + { + return new ConvertedSI(jpm3m.Value() * CubicMeterToLiter * MeterTo100KiloMeter, "l/100km"); + } + + public static ConvertedSI ConvertToLiterPerPassengerKiloMeter(this CubicMeterPerMeter jpm3m) + { + return new ConvertedSI(jpm3m.Value() * CubicMeterToLiter * Kilo, "l/p-km"); + } + + public static ConvertedSI ConvertToLiterPerTonKiloMeter(this CubicMeterPerKilogramMeter m3pkmm) + { + return new ConvertedSI(m3pkmm.Value() * CubicMeterToLiter * Kilo * Kilo, "l/t-km"); + } + + public static ConvertedSI ConvertToLiterPerCubicMeterKiloMeter(this CubicMeterPerCubicMeterMeter m3pm3m) + { + return new ConvertedSI(m3pm3m.Value() * CubicMeterToLiter * Kilo, "l/m³-km"); } public static Meter ConvertToMeter(this ConvertedSI mm) diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 2d35df18df56d9537edc0149d86c7cb2f11054fb..48886119958fd877f586e749c1aa07c328529732 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -52,10 +52,12 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; using TUGraz.VectoCore.Utils; using TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.HVAC; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.OutputData; namespace TUGraz.VectoCore.Models.Declaration { - public static class DeclarationData + public static class DeclarationData { /// <summary> /// The standard acceleration for gravity on earth. @@ -412,19 +414,19 @@ namespace TUGraz.VectoCore.Models.Declaration } } - public static double CalculateCOP(Watt coolingPwrDriver, double copDriver, Watt coolingPwrPass, double copPass) - { - if (coolingPwrDriver.IsGreater(0) && copDriver.IsEqual(0)) { - copDriver = copPass; - } - if (coolingPwrDriver.IsEqual(0) && coolingPwrPass.IsEqual(0)) { - return 1.0; - } - return (coolingPwrDriver * copDriver + coolingPwrPass * copPass) / - (coolingPwrDriver + coolingPwrPass); - } - - public static Meter CorrectionLengthDrivetrainVolume(VehicleCode? vehicleCode, bool? lowEntry, int numAxles, bool articulated) + public static double CalculateCOP(Watt coolingPwrDriver, double copDriver, Watt coolingPwrPass, double copPass) + { + if (coolingPwrDriver.IsGreater(0) && copDriver.IsEqual(0)) { + copDriver = copPass; + } + if (coolingPwrDriver.IsEqual(0) && coolingPwrPass.IsEqual(0)) { + return 1.0; + } + return (coolingPwrDriver * copDriver + coolingPwrPass * copPass) / + (coolingPwrDriver + coolingPwrPass); + } + + public static Meter CorrectionLengthDrivetrainVolume(VehicleCode? vehicleCode, bool? lowEntry, int numAxles, bool articulated) { if ((vehicleCode == VehicleCode.CE || vehicleCode == VehicleCode.CG) && (bool)lowEntry) { switch (numAxles) { @@ -1366,5 +1368,31 @@ namespace TUGraz.VectoCore.Models.Declaration } } } + + public static IWeightedResult CalculateWeightedResult(IResultEntry cdResult, IResultEntry csResult) + { + if (cdResult.Status != VectoRun.Status.Success || csResult.Status != VectoRun.Status.Success) { + return null; + } + // ToDo MQ 2022-12-12: add correct calculation method! + return new WeightedResult(cdResult) { + AverageSpeed = cdResult.AverageSpeed, + FuelConsumption = cdResult.FuelData.Select(x => Tuple.Create(x, + (cdResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected + + csResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected) / 2.0)) + .ToDictionary(x => x.Item1, x => x.Item2), + ElectricEnergyConsumption = (cdResult.ElectricEnergyConsumption + csResult.ElectricEnergyConsumption) / 2.0, + CO2Total = (cdResult.CO2Total + csResult.CO2Total) / 2.0, + ActualChargeDepletingRange = cdResult.Distance, + EquivalentAllElectricRange = cdResult.Distance, + ZeroCO2EmissionsRange = cdResult.Distance, + UtilityFactor = 1 + }; + } + + public static IWeightedResult CalculateWeightedSummary(IList<IResultEntry> entries) + { + throw new NotImplementedException(); + } } } diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index 5db09426dbb81afa29b0a7419a80cfa3fbd61405..c8ae48ad8c4dc8c249f915da9e4a7e4170983a0e 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -101,6 +101,8 @@ namespace TUGraz.VectoCore.OutputData IFuelConsumptionCorrection FuelConsumptionFinal(FuelType fuelType); + WattSecond ElectricEnergyConsumption { get; } + Kilogram CO2Total { get; } Kilogram Payload { get; set; } Kilogram TotalVehicleMass { get; set; } @@ -118,6 +120,45 @@ namespace TUGraz.VectoCore.OutputData string StackTrace { get; } } + public interface IWeightedResult + { + MeterPerSecond AverageSpeed { get; } + + Meter Distance { get; } + + Kilogram Payload { get; } + + CubicMeter CargoVolume { get; } + + double? PassengerCount { get; } + + IDictionary<IFuelProperties, Kilogram> FuelConsumption { get; } + + WattSecond ElectricEnergyConsumption { get; } + + Kilogram CO2Total { get; } + + Meter ActualChargeDepletingRange { get; } + + Meter EquivalentAllElectricRange { get; } + + Meter ZeroCO2EmissionsRange { get; } + + double UtilityFactor { get; } + } + + public interface IOVCResultEntry + { + + IResultEntry ChargeDepletingResult { get; } + + IResultEntry ChargeSustainingResult { get; } + + IWeightedResult Weighted { get; } + + } + + /// <summary> /// Class for creating a declaration report. /// </summary> diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs index 8a46eeec856d9e7b613da9638ff4d68bf255ebc8..f4a9b5e2011541df122c34ba8bbde206f601cfcb 100644 --- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs @@ -176,7 +176,8 @@ namespace TUGraz.VectoCore.OutputData KilogramPerMeter KilogramCO2PerMeter { get; } Dictionary<FuelType, IFuelConsumptionCorrection> FuelCorrection { get; } Kilogram CO2Total { get; } - Joule EnergyConsumptionTotal { get; } + Joule FuelEnergyConsumptionTotal { get; } + WattSecond ElectricEnergyConsumption { get; } } public interface IFuelConsumptionCorrection diff --git a/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs b/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs index 036b17faceccd3dbdcc79bdc5b385dbfaacfd41c..4de8e0946b3cef61c34b29e1ca64953ac6716ce7 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs @@ -392,7 +392,7 @@ namespace TUGraz.VectoCore.OutputData } } - public Joule EnergyConsumptionTotal + public Joule FuelEnergyConsumptionTotal { get { @@ -401,6 +401,8 @@ namespace TUGraz.VectoCore.OutputData } } + public WattSecond ElectricEnergyConsumption { get; } + public Second ICEOffTimeStandstill { get; set; } public WattSecond EnergyAuxICEOffStandstill { get; set; } public WattSecond EnergyAuxICEOffStandstill_UF { @@ -562,7 +564,8 @@ namespace TUGraz.VectoCore.OutputData public KilogramPerMeter KilogramCO2PerMeter => 0.SI<KilogramPerMeter>(); public Dictionary<FuelType, IFuelConsumptionCorrection> FuelCorrection => new Dictionary<FuelType, IFuelConsumptionCorrection>(); public Kilogram CO2Total => 0.SI<Kilogram>(); - public Joule EnergyConsumptionTotal => 0.SI<Joule>(); + public Joule FuelEnergyConsumptionTotal => 0.SI<Joule>(); + public WattSecond ElectricEnergyConsumption => 0.SI<WattSecond>(); #endregion } diff --git a/VectoCore/VectoCore/OutputData/OvcResultEntry.cs b/VectoCore/VectoCore/OutputData/OvcResultEntry.cs new file mode 100644 index 0000000000000000000000000000000000000000..a6ba1c2efdec390c1ac5fce706f701f5a40e1c29 --- /dev/null +++ b/VectoCore/VectoCore/OutputData/OvcResultEntry.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using TUGraz.VectoCommon.BusAuxiliaries; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.OutputData +{ + public class OvcResultEntry : IOVCResultEntry + { + #region Implementation of IOVCResultEntry + + public IResultEntry ChargeDepletingResult { get; internal set; } + public IResultEntry ChargeSustainingResult { get; internal set; } + + public IWeightedResult Weighted { get; internal set; } + + #endregion + } + + public class WeightedResult : IWeightedResult + { + public WeightedResult(IResultEntry cdResult) + { + ChargeDepletingResult = cdResult; + } + + protected IResultEntry ChargeDepletingResult; + + #region Implementation of IWeightedResult + + public Meter Distance => ChargeDepletingResult.Distance; + public Kilogram Payload => ChargeDepletingResult.Payload; + public CubicMeter CargoVolume => ChargeDepletingResult.CargoVolume; + public double? PassengerCount => ChargeDepletingResult.PassengerCount; + public MeterPerSecond AverageSpeed { get; internal set; } + + public IDictionary<IFuelProperties, Kilogram> FuelConsumption { get; internal set; } + public WattSecond ElectricEnergyConsumption { get; internal set; } + public Kilogram CO2Total { get; internal set; } + public Meter ActualChargeDepletingRange { get; internal set; } + public Meter EquivalentAllElectricRange { get; internal set; } + public Meter ZeroCO2EmissionsRange { get; internal set; } + public double UtilityFactor { get; internal set; } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/CIFNinjectModule.cs b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/CIFNinjectModule.cs index 1e093da01f7d0d575d4a5534b9ecfbbd140b2dd7..5028fb0a44afab3dd737fc9f2e2946a3b208dd54 100644 --- a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/CIFNinjectModule.cs +++ b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/CIFNinjectModule.cs @@ -444,6 +444,8 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation Bind<ICifResultsWriterFactory>().ToFactory().InSingletonScope(); + // -- Lorry + Bind<IResultGroupWriter>().To<LorryOVCResultWriter>().When(AccessedViaCIFResultsWriterFactory) .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetLorryOVCSuccessResultWriter()); Bind<IResultGroupWriter>().To<ErrorResultWriter>().When(AccessedViaCIFResultsWriterFactory) @@ -452,19 +454,53 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation Bind<IResultGroupWriter>().To<ResultMissionWriter>().When(AccessedViaCIFResultsWriterFactory) .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetMissionWriter()); Bind<IResultGroupWriter>().To<ResultSimulationParameterLorryWriter>().When(AccessedViaCIFResultsWriterFactory) - .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetSimulationParameterWriter()); + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetLorrySimulationParameterWriter()); Bind<IResultGroupWriter>().To<LorryOVCChargeDepletingWriter>().When(AccessedViaCIFResultsWriterFactory) .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetLorryOVCResultWriterChargeDepleting()); Bind<IResultGroupWriter>().To<LorryOVCChargeSustainingWriter>().When(AccessedViaCIFResultsWriterFactory) .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetLorryOVCResultWriterChargeSustaining()); + Bind<IResultGroupWriter>().To<LorryOVCTotalWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetLorryOVCSummaryWriter()); Bind<IFuelConsumptionWriter>().To<LorryFuelConsumptionWriter>().When(AccessedViaCIFResultsWriterFactory) .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetFuelConsumptionLorry()); - Bind<IResultGroupWriter>().To<LorryElectricEnergyConsumptionWriter>().When(AccessedViaCIFResultsWriterFactory) .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetElectricEnergyConsumptionLorry()); + Bind<ICO2Writer>().To<LorryCO2Writer>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetCO2ResultLorry()); + + Bind<ICifSummaryWriter>().To<LorryOVCCifSummaryWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetLorryOVCCifSummaryWriter()); + + + // -- Bus + + Bind<IResultGroupWriter>().To<BusOVCTotalWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusOVCSuccessResultWriter()); + Bind<IResultGroupWriter>().To<ErrorResultWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusOVCErrorResultWriter()); + + Bind<IResultGroupWriter>().To<ResultSimulationParameterBusWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusSimulationParameterWriter()); + + Bind<IResultGroupWriter>().To<BusOVCChargeDepletingWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusOVCResultWriterChargeDepleting()); + Bind<IResultGroupWriter>().To<BusOVCChargeSustainingWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusOVCResultWriterChargeSustaining()); + Bind<IResultGroupWriter>().To<BusOVCSummaryWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusOVCSummaryWriter()); + + Bind<IFuelConsumptionWriter>().To<BusFuelConsumptionWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetFuelConsumptionBus()); + Bind<IResultGroupWriter>().To<BusElectricEnergyConsumptionWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetElectricEnergyConsumptionBus()); + Bind<ICO2Writer>().To<BusCO2Writer>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetCO2ResultBus()); + + Bind<ICifSummaryWriter>().To<BusOVCCifSummaryWriter>().When(AccessedViaCIFResultsWriterFactory) + .NamedLikeFactoryMethod((ICifResultsWriterFactory c) => c.GetBusOVCCifSummaryWriter()); } diff --git a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/CO2Writer.cs b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/CO2Writer.cs new file mode 100644 index 0000000000000000000000000000000000000000..bcd6e0220413c6f70519da5abefaffae8ecc1659 --- /dev/null +++ b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/CO2Writer.cs @@ -0,0 +1,75 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformationFile.CustomerInformationFile_0_9.ResultWriter +{ + public abstract class CO2WriterBase : AbstractResultWriter, ICO2Writer + { + protected CO2WriterBase(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Implementation of IFuelConsumptionWriter + + public XElement[] GetElement(IResultEntry entry) + { + return GetFuelConsumption(entry.CO2Total, entry.Distance, entry.Payload, entry.CargoVolume, entry.PassengerCount).Select(x => + new XElement(Cif + XMLNames.Report_Results_CO2, XMLHelper.ValueAsUnit(x, 3, 1))).ToArray(); + } + + protected abstract IList<ConvertedSI> GetFuelConsumption(Kilogram co2, Meter distance, Kilogram payload, CubicMeter volume, double? passengers); + + #endregion + + #region Overrides of AbstractResultWriter + + public virtual XElement[] GetElement(IOVCResultEntry ovcEntry) + { + var entry = ovcEntry.Weighted; + return GetFuelConsumption(entry.CO2Total, entry.Distance, entry.Payload, entry.CargoVolume, entry.PassengerCount).Select(x => + new XElement(Cif + XMLNames.Report_Results_CO2, XMLHelper.ValueAsUnit(x, 3, 1))).ToArray(); + } + + #endregion + + } + + public class LorryCO2Writer : CO2WriterBase + { + public LorryCO2Writer(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + + #region Overrides of FuelConsumptionWriterBase + + protected override IList<ConvertedSI> GetFuelConsumption(Kilogram CO2Total, Meter distance, Kilogram payload, CubicMeter volume, double? passengers) + { + return new[] { + (CO2Total / distance).ConvertToGrammPerKiloMeter(), + (CO2Total / distance / payload).ConvertToGrammPerTonKilometer(), + (CO2Total / distance / volume).ConvertToGrammPerCubicMeterKiloMeter(), + }; + } + + #endregion + } + + public class BusCO2Writer : CO2WriterBase + { + public BusCO2Writer(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + + #region Overrides of FuelConsumptionWriterBase + + protected override IList<ConvertedSI> GetFuelConsumption(Kilogram CO2Total, Meter distance, Kilogram payload, CubicMeter volume, double? passengers) + { + return new[] { + (CO2Total / distance).ConvertToGrammPerKiloMeter(), + (CO2Total / distance / passengers.Value).ConvertToGrammPerPassengerKilometer(), + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ElectricEnergyWriter.cs b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ElectricEnergyWriter.cs new file mode 100644 index 0000000000000000000000000000000000000000..8f741e25e17c7d49766f3c06d84b6c27e140874c --- /dev/null +++ b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ElectricEnergyWriter.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformationFile.CustomerInformationFile_0_9. + ResultWriter +{ + + public abstract class ElectricEnergyConsumptionWriterBase : AbstractResultGroupWriter + { + public ElectricEnergyConsumptionWriterBase(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of AbstractResultWriter + + public override XElement GetElement(IResultEntry entry) + { + return new XElement(Cif + "ElectricEnergy", + GetEnergyConsumption(entry.ElectricEnergyConsumption, entry.Distance, entry.Payload, entry.CargoVolume, + entry.PassengerCount).Select(x => + new XElement(Cif + XMLNames.Report_Result_EnergyConsumption, XMLHelper.ValueAsUnit(x, 3, 1))) + ); + } + + public override XElement GetElement(IOVCResultEntry ovcEntry) + { + var entry = ovcEntry.Weighted; + return new XElement(Cif + "ElectricEnergy", + GetEnergyConsumption(entry.ElectricEnergyConsumption, entry.Distance, entry.Payload, entry.CargoVolume, + entry.PassengerCount).Select(x => + new XElement(Cif + XMLNames.Report_Result_EnergyConsumption, XMLHelper.ValueAsUnit(x, 3, 1))) + ); + + } + + protected abstract IList<ConvertedSI> GetEnergyConsumption(WattSecond elEnergy, Meter distance, + Kilogram payload, CubicMeter volume, double? passengers); + + #endregion + } + + public class LorryElectricEnergyConsumptionWriter : ElectricEnergyConsumptionWriterBase + { + public LorryElectricEnergyConsumptionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of ElectricEnergyConsumptionWriterBase + + protected override IList<ConvertedSI> GetEnergyConsumption(WattSecond elEnergy, Meter distance, + Kilogram payload, CubicMeter volume, double? passengers) + { + return new[] { + (elEnergy / distance).ConvertToKiloWattHourPerKiloMeter(), + (elEnergy / distance / payload).ConvertToKiloWattHourPerTonKiloMeter(), + (elEnergy / distance / volume).ConvertToKiloWattHourPerCubicMeterKiloMeter(), + + (elEnergy / distance).ConvertToMegaJoulePerKiloMeter(), + (elEnergy / distance / payload).ConvertToMegaJoulePerTonKiloMeter(), + (elEnergy / distance / volume).ConvertToMegaJoulePerCubicMeterKiloMeter(), + }; + } + + #endregion + } + + public class BusElectricEnergyConsumptionWriter : ElectricEnergyConsumptionWriterBase + { + public BusElectricEnergyConsumptionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of ElectricEnergyConsumptionWriterBase + + protected override IList<ConvertedSI> GetEnergyConsumption(WattSecond elEnergy, Meter distance, + Kilogram payload, CubicMeter volume, double? passengers) + { + return new[] { + (elEnergy / distance).ConvertToKiloWattHourPerKiloMeter(), + (elEnergy / distance / passengers.Value).ConvertToKiloWattHourPerPassengerKiloMeter(), + + (elEnergy / distance).ConvertToMegaJoulePerKiloMeter(), + (elEnergy / distance / passengers.Value).ConvertToMegaJoulePerPassengerKiloMeter(), + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/FuelConsumptionWriter.cs b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/FuelConsumptionWriter.cs new file mode 100644 index 0000000000000000000000000000000000000000..4a805402cf286263cf096569fafe2db6ef759aaf --- /dev/null +++ b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/FuelConsumptionWriter.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using TUGraz.VectoCommon.BusAuxiliaries; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformationFile.CustomerInformationFile_0_9.ResultWriter +{ + public abstract class FuelConsumptionWriterBase : AbstractResultGroupWriter, IFuelConsumptionWriter + { + protected FuelConsumptionWriterBase(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Implementation of IFuelConsumptionWriter + + public XElement GetElement(IResultEntry entry, IFuelConsumptionCorrection fc) + { + return new XElement(Cif + XMLNames.Report_Results_Fuel, + new XAttribute(XMLNames.Report_Results_Fuel_Type_Attr, fc.Fuel.FuelType.ToXMLFormat()), + GetFuelConsumption(fc.TotalFuelConsumptionCorrected, fc.Fuel, entry.Distance, entry.Payload, entry.CargoVolume, entry.PassengerCount).Select(x => new XElement(Cif + XMLNames.Report_Results_FuelConsumption, XMLHelper.ValueAsUnit(x, 3, 1))) + ); + } + + public XElement GetElement(IWeightedResult entry, IFuelProperties fuel, Kilogram consumption) + { + return new XElement(Cif + XMLNames.Report_Results_Fuel, + new XAttribute(XMLNames.Report_Results_Fuel_Type_Attr, fuel.FuelType.ToXMLFormat()), + GetFuelConsumption(consumption, fuel, entry.Distance, entry.Payload, entry.CargoVolume, entry.PassengerCount).Select(x => new XElement(Cif + XMLNames.Report_Results_FuelConsumption, XMLHelper.ValueAsUnit(x, 3, 1))) + ); + } + + protected abstract IList<ConvertedSI> GetFuelConsumption(Kilogram fc, + IFuelProperties fuel, Meter distance, Kilogram payload, CubicMeter volume, + double? passenger); + + #endregion + + #region Overrides of AbstractResultWriter + + public override XElement GetElement(IResultEntry entry) + { + throw new NotImplementedException(); + } + + #endregion + + } + + public class LorryFuelConsumptionWriter : FuelConsumptionWriterBase + { + public LorryFuelConsumptionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + + #region Overrides of FuelConsumptionWriterBase + + protected override IList<ConvertedSI> GetFuelConsumption(Kilogram fc, IFuelProperties fuel, Meter distance, Kilogram payload, CubicMeter volume, double? passenger) + { + var retVal = new List<ConvertedSI> { + (fc / distance).ConvertToGrammPerKiloMeter(), + (fc / distance /payload).ConvertToGrammPerTonKilometer(), + (fc / distance / volume).ConvertToGrammPerCubicMeterKiloMeter(), + + (fc * fuel.LowerHeatingValueVecto / distance).ConvertToMegaJoulePerKilometer(), + (fc * fuel.LowerHeatingValueVecto / distance / payload).ConvertToMegaJoulePerTonKiloMeter(), + (fc * fuel.LowerHeatingValueVecto / distance / volume).ConvertToMegaJoulePerCubicMeterKiloMeter(), + }; + + if (fuel.FuelDensity != null) { + retVal.AddRange(new[] { + (fc / fuel.FuelDensity / distance).ConvertToLiterPer100KiloMeter(), + (fc / fuel.FuelDensity / distance / payload).ConvertToLiterPerTonKiloMeter(), + (fc / fuel.FuelDensity / distance /volume).ConvertToLiterPerCubicMeterKiloMeter(), + }); + } + + return retVal; + } + + #endregion + } + + public class BusFuelConsumptionWriter : FuelConsumptionWriterBase + { + public BusFuelConsumptionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + + #region Overrides of FuelConsumptionWriterBase + + protected override IList<ConvertedSI> GetFuelConsumption(Kilogram fc, IFuelProperties fuel, Meter distance, Kilogram payload, CubicMeter volume, double? passenger) + { + var retVal = new List<ConvertedSI> { + (fc / distance).ConvertToGrammPerKiloMeter(), + (fc / distance / passenger.Value).ConvertToGrammPerPassengerKilometer(), + + (fc * fuel.LowerHeatingValueVecto / distance).ConvertToMegaJoulePerKilometer(), + (fc * fuel.LowerHeatingValueVecto / distance / passenger.Value).ConvertToMegaJoulePerPassengerKilometer(), + }; + + if (fuel.FuelDensity != null) { + retVal.AddRange(new[] { + (fc / fuel.FuelDensity / distance).ConvertToLiterPer100KiloMeter(), + (fc / fuel.FuelDensity / distance / passenger.Value).ConvertToLiterPerPassengerKiloMeter(), + }); + } + + return retVal; + } + + #endregion + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/IResultsWriter.cs b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/IResultsWriter.cs index ccf51c6b4604b0e6a35dccbdc457173ab9b61c16..624cf0dba3c901aeaa3ae79d7cd7762fbf4f7c3f 100644 --- a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/IResultsWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/IResultsWriter.cs @@ -2,12 +2,15 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; +using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformationFile.CustomerInformationFile_0_9.ResultWriter { @@ -20,26 +23,65 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation { XElement GetElement(IResultEntry entry); - XElement GetElement(Tuple<IResultEntry, IResultEntry> entry); + XElement GetElement(IOVCResultEntry entry); } public interface IFuelConsumptionWriter { XElement GetElement(IResultEntry entry, IFuelConsumptionCorrection fuelConsumptionCorrection); + XElement GetElement(IWeightedResult entry, IFuelProperties fuel, Kilogram consumption); + + } + + public interface ICO2Writer + { + XElement[] GetElement(IResultEntry entry); + + XElement[] GetElement(IOVCResultEntry entry); } + + public interface ICifSummaryWriter + { + XElement GetElement(IList<IResultEntry> entries); + + XElement GetElement(IList<IOVCResultEntry> entries); + } + + public interface ICifResultsWriterFactory { + IResultGroupWriter GetLorryOVCSuccessResultWriter(); IResultGroupWriter GetLorryOVCErrorResultWriter(); - IResultGroupWriter GetLorryOVCSuccessResultWriter(); + IResultGroupWriter GetBusOVCSuccessResultWriter(); + IResultGroupWriter GetBusOVCErrorResultWriter(); + IResultGroupWriter GetMissionWriter(); - IResultGroupWriter GetSimulationParameterWriter(); + IResultGroupWriter GetLorrySimulationParameterWriter(); IResultGroupWriter GetLorryOVCResultWriterChargeDepleting(); IResultGroupWriter GetLorryOVCResultWriterChargeSustaining(); + IResultGroupWriter GetLorryOVCSummaryWriter(); IFuelConsumptionWriter GetFuelConsumptionLorry(); IResultGroupWriter GetElectricEnergyConsumptionLorry(); + ICO2Writer GetCO2ResultLorry(); + + ICifSummaryWriter GetLorryOVCCifSummaryWriter(); + + + IResultGroupWriter GetBusSimulationParameterWriter(); + IResultGroupWriter GetBusOVCResultWriterChargeDepleting(); + IResultGroupWriter GetBusOVCResultWriterChargeSustaining(); + IResultGroupWriter GetBusOVCSummaryWriter(); + + IFuelConsumptionWriter GetFuelConsumptionBus(); + IResultGroupWriter GetElectricEnergyConsumptionBus(); + ICO2Writer GetCO2ResultBus(); + + ICifSummaryWriter GetBusOVCCifSummaryWriter(); + } + public abstract class AbstractResultsWriter : IResultsWriter { protected static readonly XNamespace Cif = "urn:tugraz:ivt:VectoAPI:CustomerOutput:v0.9"; @@ -62,56 +104,64 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation #endregion - protected List<Tuple<IResultEntry, IResultEntry>> GetOrderedResultsOVC(List<IResultEntry> results) + protected List<IOVCResultEntry> GetOrderedResultsOVC(List<IResultEntry> results) { if (!results.All(x => x.OVCMode.IsOneOf(VectoRunData.OvcHevMode.ChargeSustaining, VectoRunData.OvcHevMode.ChargeDepleting))) { throw new VectoException( "Simulation runs for OVC vehicles must be either Charge Sustaining or Charge Depleting!"); } - var retVal = new List<Tuple<IResultEntry, IResultEntry>>(results.Count / 2); + var retVal = new List<IOVCResultEntry>(results.Count / 2); var cdEntries = results.Where(x => x.OVCMode == VectoRunData.OvcHevMode.ChargeSustaining) .OrderBy(x => x.VehicleClass) .ThenBy(x => x.FuelMode) .ThenBy(x => x.Mission) .ThenBy(x => x.LoadingType) .ToList(); - foreach (var entry in cdEntries) { - var match = results.FirstOrDefault(x => x.OVCMode != entry.OVCMode && - x.VehicleClass == entry.VehicleClass && - x.FuelMode == entry.FuelMode && - x.Mission == entry.Mission && - x.LoadingType == entry.LoadingType); - if (match == null) { + foreach (var cdEntry in cdEntries) { + var csEntry = results.FirstOrDefault(x => x.OVCMode != cdEntry.OVCMode && + x.VehicleClass == cdEntry.VehicleClass && + x.FuelMode == cdEntry.FuelMode && + x.Mission == cdEntry.Mission && + x.LoadingType == cdEntry.LoadingType); + if (csEntry == null) { throw new VectoException( - $"no matching result for {entry.Mission}, {entry.LoadingType}, {entry.FuelMode} found!"); + $"no matching result for {cdEntry.Mission}, {cdEntry.LoadingType}, {cdEntry.FuelMode} found!"); } - retVal.Add(Tuple.Create(entry, match)); - } - return retVal; - } - protected XElement GetSummary(List<Tuple<IResultEntry, IResultEntry>> orderedResults) - { - var allSuccess = orderedResults.All(x => - x.Item1.Status == VectoRun.Status.Success && x.Item2.Status == VectoRun.Status.Success); - if (!allSuccess) { - // do not write summary unless all simulation runs are successful! - return null; + var combined = new OvcResultEntry() { + ChargeSustainingResult = csEntry, + ChargeDepletingResult = cdEntry, + Weighted = DeclarationData.CalculateWeightedResult(cdEntry, csEntry) + }; + retVal.Add(combined); } - //throw new NotImplementedException(); - return null; + return retVal; } - protected XElement GetSummary(List<IResultEntry> results) - { - var allSuccess = results.All(x => x.Status == VectoRun.Status.Success); - if (!allSuccess) { - // do not write summary unless all simulation runs are successful! - return null; - } - throw new NotImplementedException(); - } + //protected XElement GetSummary(List<IOVCResultEntry> orderedResults) + //{ + // var allSuccess = orderedResults.All(x => + // x.ChargeDepletingResult.Status == VectoRun.Status.Success && x.ChargeSustainingResult.Status == VectoRun.Status.Success); + // if (!allSuccess) { + // // do not write summary unless all simulation runs are successful! + // return null; + // } + + // return null; + // //return new XElement(Cif + "Summary", + // // new XElement(Cif + XMLNames.Report_ResultEntry_AverageSpeed, XMLHelper.ValueAsUnit())) + //} + + //protected XElement GetSummary(List<IResultEntry> results) + //{ + // var allSuccess = results.All(x => x.Status == VectoRun.Status.Success); + // if (!allSuccess) { + // // do not write summary unless all simulation runs are successful! + // return null; + // } + // throw new NotImplementedException(); + //} } public class CIFResultsWriter @@ -137,10 +187,12 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation return new XElement(Cif + "Results", new XElement(Cif + XMLNames.Report_Result_Status, allSuccess ? "success" : "error"), ordered.Select(x => - x.Item1.Status == VectoRun.Status.Success && x.Item2.Status == VectoRun.Status.Success + x.ChargeDepletingResult.Status == VectoRun.Status.Success && + x.ChargeSustainingResult.Status == VectoRun.Status.Success ? _cifFactory.GetLorryOVCSuccessResultWriter().GetElement(x) : _cifFactory.GetLorryOVCErrorResultWriter().GetElement(x)), - GetSummary(ordered)); + _cifFactory.GetLorryOVCCifSummaryWriter().GetElement(ordered) + ); } @@ -168,6 +220,21 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation public class HEVOVCBus : AbstractResultsWriter { public HEVOVCBus(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + public override XElement GenerateResults(List<IResultEntry> results) + { + var ordered = GetOrderedResultsOVC(results); + var allSuccess = results.All(x => x.Status == VectoRun.Status.Success); + return new XElement(Cif + "Results", + new XElement(Cif + XMLNames.Report_Result_Status, allSuccess ? "success" : "error"), + ordered.Select(x => + x.ChargeDepletingResult.Status == VectoRun.Status.Success && + x.ChargeSustainingResult.Status == VectoRun.Status.Success + ? _cifFactory.GetBusOVCSuccessResultWriter().GetElement(x) + : _cifFactory.GetBusOVCErrorResultWriter().GetElement(x)), + _cifFactory.GetBusOVCCifSummaryWriter().GetElement(ordered) + ); + } } public class PEVBus : AbstractResultsWriter diff --git a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ResultGoupWriter.cs b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ResultGoupWriter.cs index 16fb1ba3508d71a97563b24bb1603a1da7c70546..136c2c8a26d9a95dc1e7fc65f36019116ccc2f9c 100644 --- a/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ResultGoupWriter.cs +++ b/VectoCore/VectoCore/OutputData/XML/DeclarationReports/CustomerInformationFile/CustomerInformationFile_0_9/ResultWriter/ResultGoupWriter.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; +using TUGraz.VectoCommon.BusAuxiliaries; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; @@ -13,8 +14,7 @@ using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformationFile.CustomerInformationFile_0_9. ResultWriter { - - public abstract class AbstractResultWriter : IResultGroupWriter + public abstract class AbstractResultWriter { protected static readonly XNamespace Cif = "urn:tugraz:ivt:VectoAPI:CustomerOutput:v0.9"; protected static readonly XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance"; @@ -25,46 +25,33 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation { _cifFactory = cifFactory; } + } + + + + public abstract class AbstractResultGroupWriter : AbstractResultWriter, IResultGroupWriter + { + protected AbstractResultGroupWriter(ICifResultsWriterFactory cifFactory): base(cifFactory) {} #region Implementation of IResultGroupWriter public abstract XElement GetElement(IResultEntry entry); - public virtual XElement GetElement(Tuple<IResultEntry, IResultEntry> entry) + public virtual XElement GetElement(IOVCResultEntry entry) { throw new NotImplementedException(); } - #endregion - - protected XElement[] GetCO2Lorry(IResultEntry entry) - { - return new[] { - new XElement(Cif + XMLNames.Report_Results_CO2, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/km"), - (entry.CO2Total / entry.Distance).ConvertToGrammPerKiloMeter().ToMinSignificantDigits(3, 2)), - new XElement(Cif + XMLNames.Report_Results_CO2, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/km"), - (entry.CO2Total / entry.Distance / entry.Payload).ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 2)), - new XElement(Cif + XMLNames.Report_Results_CO2, - new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/km"), - (entry.CO2Total / entry.Distance / entry.CargoVolume).ConvertToGrammPerCubicMeterKiloMeter().ToMinSignificantDigits(3, 2)), - }; - } + #endregion } - public class ErrorResultWriter : AbstractResultWriter + public class ErrorResultWriter : AbstractResultGroupWriter { public ErrorResultWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } #region Overrides of AbstractResultWriter - // <n1:Mission>longhaul</n1:Mission> - //<n1:SimulationParameters> - //<TotalVehicleMass unit = "kg" > 7800 </ TotalVehicleMass > - //< Payload unit="kg">2300</Payload> - //</n1:SimulationParameters> public override XElement GetElement(IResultEntry entry) { if (entry.Status == VectoRun.Status.Success) { @@ -74,15 +61,15 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation new XAttribute(XMLNames.Report_Result_Status_Attr, "error"), new XAttribute(xsi + "type", "ResultErrorType"), _cifFactory.GetMissionWriter().GetElement(entry), - _cifFactory.GetSimulationParameterWriter().GetElement(entry), + _cifFactory.GetLorrySimulationParameterWriter().GetElement(entry), new XElement(Cif + XMLNames.Report_Results_Error, entry.Error), new XElement(Cif + XMLNames.Report_Results_ErrorDetails, entry.StackTrace) ); } - public override XElement GetElement(Tuple<IResultEntry, IResultEntry> entry) + public override XElement GetElement(IOVCResultEntry entry) { - var errorEntry = new[] {entry.Item1, entry.Item2}.FirstOrDefault(x => x.Status != VectoRun.Status.Success); + var errorEntry = new[] {entry.ChargeSustainingResult, entry.ChargeDepletingResult}.FirstOrDefault(x => x.Status != VectoRun.Status.Success); if (errorEntry == null) { throw new Exception("At least one entry needs to be unsuccessful!"); } @@ -90,7 +77,7 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation new XAttribute(XMLNames.Report_Result_Status_Attr, "error"), new XAttribute(xsi + "type", "ResultErrorType"), _cifFactory.GetMissionWriter().GetElement(errorEntry), - _cifFactory.GetSimulationParameterWriter().GetElement(errorEntry), + _cifFactory.GetLorrySimulationParameterWriter().GetElement(errorEntry), new XElement(Cif + XMLNames.Report_Results_Error, errorEntry.Error), new XElement(Cif + XMLNames.Report_Results_ErrorDetails, errorEntry.StackTrace) ); @@ -99,7 +86,7 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation #endregion } - public class ResultMissionWriter : AbstractResultWriter + public class ResultMissionWriter : AbstractResultGroupWriter { public ResultMissionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } @@ -113,7 +100,7 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation #endregion } - public class ResultSimulationParameterLorryWriter : AbstractResultWriter + public class ResultSimulationParameterLorryWriter : AbstractResultGroupWriter { public ResultSimulationParameterLorryWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } @@ -131,7 +118,7 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation #endregion } - public class LorryOVCResultWriter : AbstractResultWriter + public class LorryOVCResultWriter : AbstractResultGroupWriter { public LorryOVCResultWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } @@ -143,24 +130,24 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation throw new NotImplementedException(); } - public override XElement GetElement(Tuple<IResultEntry, IResultEntry> entry) + public override XElement GetElement(IOVCResultEntry entry) { - var cs = new[] { entry.Item1, entry.Item2 }.FirstOrDefault(x => x.OVCMode == VectoRunData.OvcHevMode.ChargeSustaining); - var cd = new[] { entry.Item1, entry.Item2 }.FirstOrDefault(x => x.OVCMode == VectoRunData.OvcHevMode.ChargeDepleting); return new XElement(Cif + XMLNames.Report_Result_Result, new XAttribute(XMLNames.Report_Result_Status_Attr, "success"), new XAttribute(xsi + "type", "ResultSuccessOVCHEVType"), - _cifFactory.GetMissionWriter().GetElement(entry.Item1), - _cifFactory.GetSimulationParameterWriter().GetElement(entry.Item1), - _cifFactory.GetLorryOVCResultWriterChargeDepleting().GetElement(cd), - _cifFactory.GetLorryOVCResultWriterChargeSustaining().GetElement(cs) + _cifFactory.GetMissionWriter().GetElement(entry.ChargeDepletingResult), + _cifFactory.GetLorrySimulationParameterWriter().GetElement(entry.ChargeDepletingResult), + _cifFactory.GetLorryOVCResultWriterChargeDepleting().GetElement(entry.ChargeDepletingResult), + _cifFactory.GetLorryOVCResultWriterChargeSustaining().GetElement(entry.ChargeSustainingResult), + _cifFactory.GetLorryOVCSummaryWriter().GetElement(entry) ); } #endregion } - public class LorryOVCChargeDepletingWriter : AbstractResultWriter + + public class LorryOVCChargeDepletingWriter : AbstractResultGroupWriter { public LorryOVCChargeDepletingWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } @@ -174,7 +161,7 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation entry.FuelData.Select(f => _cifFactory.GetFuelConsumptionLorry().GetElement(entry, entry.FuelConsumptionFinal(f.FuelType))), _cifFactory.GetElectricEnergyConsumptionLorry().GetElement(entry), - GetCO2Lorry(entry) + _cifFactory.GetCO2ResultLorry().GetElement(entry) ); } @@ -182,7 +169,7 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation #endregion } - public class LorryOVCChargeSustainingWriter : AbstractResultWriter + public class LorryOVCChargeSustainingWriter : AbstractResultGroupWriter { public LorryOVCChargeSustainingWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } @@ -195,64 +182,233 @@ namespace TUGraz.VectoCore.OutputData.XML.DeclarationReports.CustomerInformation new XElement(Cif + XMLNames.Report_ResultEntry_AverageSpeed, XMLHelper.ValueAsUnit(entry.AverageSpeed, XMLNames.Unit_kmph, 1)), entry.FuelData.Select(f => _cifFactory.GetFuelConsumptionLorry().GetElement(entry, entry.FuelConsumptionFinal(f.FuelType))), - GetCO2Lorry(entry) + _cifFactory.GetCO2ResultLorry().GetElement(entry) + //GetCO2Result(entry) ); } #endregion } - public class LorryFuelConsumptionWriter : AbstractResultWriter, IFuelConsumptionWriter + + public abstract class OVCTotalWriterBase : AbstractResultGroupWriter { - public LorryFuelConsumptionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + protected OVCTotalWriterBase(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } - #region Implementation of IFuelConsumptionWriter + #region Overrides of AbstractResultWriter - public XElement GetElement(IResultEntry entry, IFuelConsumptionCorrection fc) + public override XElement GetElement(IResultEntry entry) { - return new XElement(Cif + XMLNames.Report_Results_Fuel, - new XAttribute(XMLNames.Report_Results_Fuel_Type_Attr, fc.Fuel.FuelType.ToXMLFormat()), - new XElement(Cif + XMLNames.Report_Results_FuelConsumption, - XMLHelper.ValueAsUnit( - (fc.TotalFuelConsumptionCorrected / entry.Distance).ConvertToGrammPerKiloMeter(), 3, 1) - ), - new XElement(Cif + XMLNames.Report_Results_FuelConsumption, - XMLHelper.ValueAsUnit( - (fc.TotalFuelConsumptionCorrected / entry.Distance / entry.Payload) - .ConvertToGrammPerTonKilometer(), 3, 1) - ), - new XElement(Cif + XMLNames.Report_Results_FuelConsumption, - XMLHelper.ValueAsUnit( - (fc.TotalFuelConsumptionCorrected / entry.Distance / entry.CargoVolume) - .ConvertToGrammPerCubicMeterKiloMeter(), 3, 1) - ) + throw new NotImplementedException(); + } + + public override XElement GetElement(IOVCResultEntry entry) + { + var total = entry.Weighted; + return new XElement(Cif + "Total", + new XElement(Cif + XMLNames.Report_ResultEntry_AverageSpeed, + XMLHelper.ValueAsUnit(total.AverageSpeed, "km/h", 1)), + GetFuelConsumption(entry), + GetElectricConsumption(entry), + GetCO2(entry), + new XElement(Cif + "ActualChargeDepletingRange", + XMLHelper.ValueAsUnit(total.ActualChargeDepletingRange.ConvertToKiloMeter())), + new XElement(Cif + "EquivalentAllElectricRange", + XMLHelper.ValueAsUnit(total.EquivalentAllElectricRange.ConvertToKiloMeter())), + new XElement(Cif + "ZeroCO2EmissionsRange", + XMLHelper.ValueAsUnit(total.ZeroCO2EmissionsRange.ConvertToKiloMeter())), + new XElement(Cif + "UtilityFactor", total.UtilityFactor.ToXMLFormat(3)) ); } + protected abstract XElement[] GetFuelConsumption(IOVCResultEntry entry); + #endregion - #region Overrides of AbstractResultWriter + protected abstract XElement GetElectricConsumption(IOVCResultEntry entry); + + protected abstract XElement[] GetCO2(IOVCResultEntry entry); + + } + + public class LorryOVCTotalWriter : OVCTotalWriterBase + { + public LorryOVCTotalWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of OVCSummaryWriterBase + + protected override XElement[] GetFuelConsumption(IOVCResultEntry entry) + { + return entry.Weighted.FuelConsumption.Select(e => + _cifFactory.GetFuelConsumptionLorry().GetElement(entry.Weighted, e.Key, e.Value)).ToArray(); + } + + protected override XElement GetElectricConsumption(IOVCResultEntry entry) + { + return _cifFactory.GetElectricEnergyConsumptionLorry().GetElement(entry); + } + + protected override XElement[] GetCO2(IOVCResultEntry entry) + { + return _cifFactory.GetCO2ResultLorry().GetElement(entry); + } + + #endregion + } + + + public abstract class CifSummaryWriterBase : AbstractResultWriter, ICifSummaryWriter + { + protected CifSummaryWriterBase(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Implementation of ICifSummaryWriter + + public XElement GetElement(IList<IResultEntry> entries) + { + var weighted = DeclarationData.CalculateWeightedSummary(entries); + //return new XElement( + // GetSummary(weighted), + // weighted.FuelConsumption.Select(x => _cifFactory.GetFuelConsumptionLorry().GetElement(weighted, x.Key, x.Value)), + // _cifFactory.GetElectricEnergyConsumptionLorry().GetElement(weighted), + // _cifFactory.GetCO2ResultLorry().GetElement(weighted), + // ); + return null; + } + + public XElement GetElement(IList<IOVCResultEntry> entries) + { + return null; + } + + #endregion + } + + public class LorryOVCCifSummaryWriter : CifSummaryWriterBase + { + public LorryOVCCifSummaryWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + } + + + // ----------------- + // bus + + public class BusOVCTotalWriter : AbstractResultGroupWriter + { + + public BusOVCTotalWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Implementation of IResultGroupWriter public override XElement GetElement(IResultEntry entry) { throw new NotImplementedException(); } + public override XElement GetElement(IOVCResultEntry entry) + { + return new XElement(Cif + XMLNames.Report_Result_Result, + new XAttribute(XMLNames.Report_Result_Status_Attr, "success"), + new XAttribute(xsi + "type", "ResultSuccessOVCHEVType"), + _cifFactory.GetMissionWriter().GetElement(entry.ChargeDepletingResult), + _cifFactory.GetBusSimulationParameterWriter().GetElement(entry.ChargeDepletingResult), + _cifFactory.GetBusOVCResultWriterChargeDepleting().GetElement(entry.ChargeDepletingResult), + _cifFactory.GetBusOVCResultWriterChargeSustaining().GetElement(entry.ChargeSustainingResult), + _cifFactory.GetBusOVCSummaryWriter().GetElement(entry) + ); + } + #endregion } - public class LorryElectricEnergyConsumptionWriter : AbstractResultWriter + public class ResultSimulationParameterBusWriter : AbstractResultGroupWriter { - public LorryElectricEnergyConsumptionWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + public ResultSimulationParameterBusWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } #region Overrides of AbstractResultWriter public override XElement GetElement(IResultEntry entry) { - return null; + return new XElement(Cif + XMLNames.Report_ResultEntry_SimulationParameters, + new XElement(Cif + XMLNames.Report_ResultEntry_TotalVehicleMass, + XMLHelper.ValueAsUnit(entry.TotalVehicleMass, XMLNames.Unit_kg)), + new XElement(Cif + XMLNames.Report_Result_MassPassengers, + XMLHelper.ValueAsUnit(entry.Payload, XMLNames.Unit_kg)), + new XElement(Cif + XMLNames.Report_Result_PassengerCount, + (entry.PassengerCount ?? double.NaN).ToXMLFormat(2)) + ); + } + + #endregion + } + + public class BusOVCChargeDepletingWriter : AbstractResultGroupWriter + { + public BusOVCChargeDepletingWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of AbstractResultWriter + + public override XElement GetElement(IResultEntry entry) + { + return new XElement(Cif + "OVCMode", + new XAttribute("type", "charge depleting"), + new XElement(Cif + XMLNames.Report_ResultEntry_AverageSpeed, XMLHelper.ValueAsUnit(entry.AverageSpeed, XMLNames.Unit_kmph, 1)), + entry.FuelData.Select(f => + _cifFactory.GetFuelConsumptionBus().GetElement(entry, entry.FuelConsumptionFinal(f.FuelType))), + _cifFactory.GetElectricEnergyConsumptionBus().GetElement(entry), + _cifFactory.GetCO2ResultBus().GetElement(entry) + ); + } + #endregion + } + + public class BusOVCChargeSustainingWriter : AbstractResultGroupWriter + { + public BusOVCChargeSustainingWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of AbstractResultWriter + + public override XElement GetElement(IResultEntry entry) + { + return new XElement(Cif + "OVCMode", + new XAttribute("type", "charge depleting"), + new XElement(Cif + XMLNames.Report_ResultEntry_AverageSpeed, XMLHelper.ValueAsUnit(entry.AverageSpeed, XMLNames.Unit_kmph, 1)), + entry.FuelData.Select(f => + _cifFactory.GetFuelConsumptionBus().GetElement(entry, entry.FuelConsumptionFinal(f.FuelType))), + _cifFactory.GetCO2ResultBus().GetElement(entry) + ); } #endregion } + + public class BusOVCSummaryWriter : OVCTotalWriterBase + { + public BusOVCSummaryWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + + #region Overrides of OVCSummaryWriterBase + + protected override XElement[] GetFuelConsumption(IOVCResultEntry entry) + { + return entry.Weighted.FuelConsumption.Select(e => + _cifFactory.GetFuelConsumptionBus().GetElement(entry.Weighted, e.Key, e.Value)).ToArray(); + } + + protected override XElement GetElectricConsumption(IOVCResultEntry entry) + { + return _cifFactory.GetElectricEnergyConsumptionBus().GetElement(entry); + } + + protected override XElement[] GetCO2(IOVCResultEntry entry) + { + return _cifFactory.GetCO2ResultBus().GetElement(entry); + } + + #endregion + } + + public class BusOVCCifSummaryWriter : CifSummaryWriterBase + { + public BusOVCCifSummaryWriter(ICifResultsWriterFactory cifFactory) : base(cifFactory) { } + } } diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index 345942aba55d47f911d4a54f88e1e2ea06c871b7..9a9ab06805bf1eb4f45ca4c54d2ce974c114655e 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -100,7 +100,9 @@ namespace TUGraz.VectoCore.OutputData.XML return CorrectedFinalFuelConsumption[fuelType]; } - public Kilogram CO2Total { get; private set; } + public WattSecond ElectricEnergyConsumption { get; private set; } + + public Kilogram CO2Total { get; private set; } public Dictionary<FuelType, IFuelConsumptionCorrection> CorrectedFinalFuelConsumption { get; private set; } @@ -175,9 +177,11 @@ namespace TUGraz.VectoCore.OutputData.XML CorrectedFinalFuelConsumption = data.CorrectedModalData.FuelCorrection; CO2Total = data.CorrectedModalData.CO2Total; - EnergyConsumptionTotal = data.CorrectedModalData.EnergyConsumptionTotal; + EnergyConsumptionTotal = data.CorrectedModalData.FuelEnergyConsumptionTotal; + ElectricEnergyConsumption = data.CorrectedModalData.ElectricEnergyConsumption; + - var gbxOutSignal = runData.Retarder.Type == RetarderType.TransmissionOutputRetarder + var gbxOutSignal = runData.Retarder.Type == RetarderType.TransmissionOutputRetarder ? ModalResultField.P_retarder_in : (runData.AngledriveData == null ? ModalResultField.P_axle_in : ModalResultField.P_angle_in); var eGbxIn = data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_in, x => x > 0); diff --git a/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs b/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs index 96c6afebecf9054745fd5cd6d01ac356b225b4f3..155d37952ae866a3a024ffdb117331494ea26997 100644 --- a/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs +++ b/VectoCore/VectoCoreTest/Reports/TestXMLResultsWriting.cs @@ -110,6 +110,55 @@ public class TestXMLResultsWriting Assert.IsTrue(validator.ValidateXML(XmlDocumentType.CustomerReport), validator.ValidationError); } + + [ + TestCase(VectoSimulationJobType.ParallelHybridVehicle, true, false, false, TestName = "ReportResult_WritingResults: CompletedBus HEV OVC ERROR"), + + TestCase(VectoSimulationJobType.ParallelHybridVehicle, true, false, true, TestName = "ReportResult_WritingResults: CompletedBus HEV OVC"), + TestCase(VectoSimulationJobType.ParallelHybridVehicle, true, true, true, TestName = "ReportResult_WritingResults: CompletedBus HEV exempted"), + ] + public void TestReportResult_WritingResults_CompletedBus(VectoSimulationJobType jobType, bool ovc, bool exempted, bool success) + { + var vehicleCategory = VehicleCategory.HeavyBusCompletedVehicle; + var ovcmode = ovc ? VectoRunData.OvcHevMode.ChargeDepleting : VectoRunData.OvcHevMode.NotApplicable; + var runData = GetMockRunData(vehicleCategory, jobType, ovc, exempted, ovcmode); + var modData = GetMockModData(success ? VectoRun.Status.Success : VectoRun.Status.Aborted); + + var resultEntries = new List<IResultEntry>(); + + var resultEntry = GetResultEntry(runData); + resultEntry.SetResultData(runData, modData, 1); + resultEntries.Add(resultEntry); + + if (ovc) { + var run2 = GetMockRunData(vehicleCategory, jobType, true, exempted, VectoRunData.OvcHevMode.ChargeSustaining); + var res2 = GetResultEntry(run2); + res2.SetResultData(run2, modData, 1); + resultEntries.Add(res2); + } + + var resultsWriter = _reportResultsFactory.GetCIFResultsWriter( + runData.VehicleData.VehicleCategory.GetVehicleType(), + runData.JobType, runData.VehicleData.OffVehicleCharging, runData.Exempted); + + var results = resultsWriter.GenerateResults(resultEntries); + + Assert.NotNull(results); + + var doc = CreateXmlDocument(results); + var validator = GetValidator(doc); + + var m = new MemoryStream(); + var writer = new XmlTextWriter(m, Encoding.UTF8) { Formatting = Formatting.Indented }; + doc.WriteTo(writer); + writer.Flush(); + m.Flush(); + m.Seek(0, SeekOrigin.Begin); + Console.WriteLine(new StreamReader(m).ReadToEnd()); + + Assert.IsTrue(validator.ValidateXML(XmlDocumentType.CustomerReport), validator.ValidationError); + } + private static XMLDeclarationReport.ResultEntry GetResultEntry(VectoRunData runData) { var resultEntry = new XMLDeclarationReport.ResultEntry() { @@ -121,6 +170,7 @@ public class TestXMLResultsWriting TotalVehicleMass = runData.VehicleData.TotalVehicleMass, CargoVolume = runData.VehicleData.CargoVolume, VehicleClass = runData.VehicleData.VehicleClass, + PassengerCount = runData.VehicleData.PassengerCount, }; return resultEntry; } @@ -180,8 +230,10 @@ public class TestXMLResultsWriting fc.Setup(x => x.Fuel).Returns(FuelData.Diesel); fc.Setup(x => x.TotalFuelConsumptionCorrected).Returns(31.SI<Kilogram>()); + fc.Setup(x => x.EnergyDemand).Returns(31.SI<Kilogram>() * FuelData.Diesel.LowerHeatingValueVecto); mc.Setup(x => x.CO2Total).Returns(20.SI<Kilogram>()); - mc.Setup(x => x.EnergyConsumptionTotal).Returns(1e9.SI<Joule>()); + mc.Setup(x => x.FuelEnergyConsumptionTotal).Returns(1e9.SI<Joule>()); + mc.Setup(x => x.ElectricEnergyConsumption).Returns(200.SI(Unit.SI.Mega.Joule).Cast<WattSecond>()); @@ -203,6 +255,7 @@ public class TestXMLResultsWriting CurbMass = 7600.SI<Kilogram>(), Loading = 5000.SI<Kilogram>(), CargoVolume = 20.SI<CubicMeter>(), + PassengerCount = 20, VehicleClass = VehicleClass.Class5, VehicleCategory = vehicleCategory, OffVehicleCharging = offVehicleCharging @@ -219,7 +272,6 @@ public class TestXMLResultsWriting Retarder = new RetarderData() { Type = RetarderType.None, }, - }; } } \ No newline at end of file diff --git a/VectoCore/VectoCoreTest/Utils/ConvertedSITest.cs b/VectoCore/VectoCoreTest/Utils/ConvertedSITest.cs new file mode 100644 index 0000000000000000000000000000000000000000..0e7fde04d63ccdc9dbbc6c0d8be9425e076534c6 --- /dev/null +++ b/VectoCore/VectoCoreTest/Utils/ConvertedSITest.cs @@ -0,0 +1,196 @@ +using NUnit.Framework; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Tests.Utils; + +[TestFixture] +[Parallelizable(ParallelScope.All)] +public class ConvertedSITest +{ + + [Test] + public void ConvertedSITest_ConvertToLiterPer100KiloMeter() + { + var fcLiter = 5.0; + var distanceKm = 100.0; + CubicMeter fc = fcLiter.SI(Unit.SI.Liter).Cast<CubicMeter>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + + var converted = (fc / distance).ConvertToLiterPer100KiloMeter(); + + Assert.AreEqual(fcLiter / distanceKm * 100, converted.Value, 1e-6); + Assert.AreEqual("l/100km", converted.Units); + } + + [Test] + public void ConvertedSITest_ConvertToLiterPerTonKiloMeter() + { + var fcLiter = 5.0; + var distanceKm = 100.0; + var payloadTon = 2; + CubicMeter fc = fcLiter.SI(Unit.SI.Liter).Cast<CubicMeter>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + Kilogram payload = payloadTon.SI(Unit.SI.Ton).Cast<Kilogram>(); + + var converted = (fc / distance / payload).ConvertToLiterPerTonKiloMeter(); + + Assert.AreEqual(fcLiter / distanceKm / payloadTon, converted.Value, 1e-6); + Assert.AreEqual("l/t-km", converted.Units); + } + + [Test] + public void ConvertedSITest_ConvertToLiterPerCubicMeterKiloMeter() + { + var fcLiter = 5.0; + var distanceKm = 100.0; + var cargo = 10; + CubicMeter fc = fcLiter.SI(Unit.SI.Liter).Cast<CubicMeter>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + CubicMeter cargoVolume = cargo.SI(Unit.SI.Cubic.Meter).Cast<CubicMeter>(); + + var converted = (fc / distance / cargoVolume).ConvertToLiterPerCubicMeterKiloMeter(); + + Assert.AreEqual(fcLiter / distanceKm / cargo, converted.Value, 1e-6); + Assert.AreEqual("l/m³-km", converted.Units); + } + + [Test] + public void ConvertedSITest_J_ConvertToMegaJoulePerCubicMeterKiloMeter() + { + var ecMj = 200.0; + var distanceKm = 100.0; + var cargo = 10; + Joule ec = ecMj.SI(Unit.SI.Mega.Joule).Cast<Joule>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + CubicMeter cargoVolume = cargo.SI(Unit.SI.Cubic.Meter).Cast<CubicMeter>(); + + var converted = (ec / distance / cargoVolume).ConvertToMegaJoulePerCubicMeterKiloMeter(); + + Assert.AreEqual(ecMj / distanceKm / cargo, converted.Value, 1e-6); + Assert.AreEqual("MJ/m³-km", converted.Units); + } + + [Test] + public void ConvertedSITest_ConvertToMegaJoulePerTonKiloMeter() + { + var ecMj = 200.0; + var distanceKm = 100.0; + var payloadTon = 2.5; + Joule ec = ecMj.SI(Unit.SI.Mega.Joule).Cast<Joule>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + Kilogram payload = payloadTon.SI(Unit.SI.Ton).Cast<Kilogram>(); + + var converted = (ec / distance / payload).ConvertToMegaJoulePerTonKiloMeter(); + + Assert.AreEqual(ecMj / distanceKm / payloadTon, converted.Value, 1e-6); + Assert.AreEqual("MJ/t-km", converted.Units); + } + + [Test] + public void ConvertedSITest_ConvertToMegaJoulePerKilometer() + { + var ecMj = 200.0; + var distanceKm = 100.0; + Joule ec = ecMj.SI(Unit.SI.Mega.Joule).Cast<Joule>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + + var converted = (ec / distance).ConvertToMegaJoulePerKilometer(); + + Assert.AreEqual(ecMj / distanceKm, converted.Value, 1e-6); + Assert.AreEqual("MJ/km", converted.Units); + } + + + [Test] + public void ConvertedSITest_ConvertToKiloWattHourPerKiloMeter() + { + var ec_kWh = 200.0; + var distanceKm = 100.0; + WattSecond ec = ec_kWh.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + + var converted = (ec / distance).ConvertToKiloWattHourPerKiloMeter(); + + Assert.AreEqual(ec_kWh / distanceKm, converted.Value, 1e-6); + Assert.AreEqual("kWh/km", converted.Units); + } + + [Test] + public void ConvertedSITest_ConvertToKiloWattHourPerTonKiloMeter() + { + var ec_kWh = 200.0; + var distanceKm = 100.0; + var payloadTon = 2.5; + WattSecond ec = ec_kWh.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + Kilogram payload = payloadTon.SI(Unit.SI.Ton).Cast<Kilogram>(); + + var converted = (ec / distance / payload).ConvertToKiloWattHourPerTonKiloMeter(); + + Assert.AreEqual(ec_kWh / distanceKm / payloadTon, converted.Value, 1e-6); + Assert.AreEqual("kWh/t-km", converted.Units); + } + + [Test] + public void ConvertedSITest_ConvertToKiloWattHourPerCubicMeterKiloMeter() + { + var ec_kWh = 200.0; + var distanceKm = 100.0; + var cargo = 10; + WattSecond ec = ec_kWh.SI(Unit.SI.Kilo.Watt.Hour).Cast<WattSecond>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + CubicMeter cargoVolume = cargo.SI(Unit.SI.Cubic.Meter).Cast<CubicMeter>(); + + var converted = (ec / distance / cargoVolume).ConvertToKiloWattHourPerCubicMeterKiloMeter(); + + Assert.AreEqual(ec_kWh / distanceKm / cargo, converted.Value, 1e-6); + Assert.AreEqual("kWh/m³-km", converted.Units); + } + + [Test] + public void ConvertedSITest_Ws_ConvertToMegaJoulePerKiloMeter() + { + var ec_MJ = 200.0; + var distanceKm = 100.0; + WattSecond ec = ec_MJ.SI(Unit.SI.Mega.Joule).Cast<WattSecond>(); + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + + var converted = (ec / distance).ConvertToMegaJoulePerKiloMeter(); + + Assert.AreEqual(ec_MJ / distanceKm, converted.Value, 1e-6); + Assert.AreEqual("MJ/km", converted.Units); + } + + [Test] + public void ConvertedSITest_Ws_ConvertToMegaJoulePerTonKiloMeter() + { + var ec_MJ = 200.0; + var distanceKm = 100.0; + WattSecond ec = ec_MJ.SI(Unit.SI.Mega.Joule).Cast<WattSecond>(); + var payloadTon = 2.5; + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + Kilogram payload = payloadTon.SI(Unit.SI.Ton).Cast<Kilogram>(); + + var converted = (ec / distance / payload).ConvertToMegaJoulePerTonKiloMeter(); + + Assert.AreEqual(ec_MJ / distanceKm / payloadTon, converted.Value, 1e-6); + Assert.AreEqual("MJ/t-km", converted.Units); + } + + [Test] + public void ConvertedSITest_Ws_ConvertToMegaJoulePerCubicMeterKiloMeter() + { + var ec_MJ = 200.0; + var distanceKm = 100.0; + WattSecond ec = ec_MJ.SI(Unit.SI.Mega.Joule).Cast<WattSecond>(); + var cargo = 10; + Meter distance = distanceKm.SI(Unit.SI.Kilo.Meter).Cast<Meter>(); + CubicMeter cargoVolume = cargo.SI(Unit.SI.Cubic.Meter).Cast<CubicMeter>(); + + var converted = (ec / distance / cargoVolume).ConvertToMegaJoulePerCubicMeterKiloMeter(); + + Assert.AreEqual(ec_MJ / distanceKm / cargo, converted.Value, 1e-6); + Assert.AreEqual("MJ/m³-km", converted.Units); + } +} +